PageRenderTime 144ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/header/Microsoft SDKs/Windows/v7.0A/Include/Msputils.h

https://github.com/nihon-tc/Rtest
C Header | 700 lines | 324 code | 150 blank | 226 comment | 38 complexity | 9e84f1083badf141713b7f317aa17b6a MD5 | raw file
  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. MSPutils.h
  5. Abstract:
  6. This file defines several utility classes used by the MSP base classes.
  7. --*/
  8. #ifndef __MSPUTILS_H_
  9. #define __MSPUTILS_H_
  10. #include <intsafe.h>
  11. #if _ATL_VER >= 0x0300
  12. //
  13. // ATL 3.0 contains an equivalent of DECLARE_VQI in its END_COM_MAP(), so
  14. // DECLARE_VQI() is not needed
  15. //
  16. #define DECLARE_VQI()
  17. #else
  18. #define DECLARE_VQI() \
  19. STDMETHOD(QueryInterface)(REFIID iid, void ** ppvObject) = 0; \
  20. STDMETHOD_(ULONG, AddRef)() = 0; \
  21. STDMETHOD_(ULONG, Release)() = 0;
  22. #endif
  23. //
  24. // this macro expands to the appropriate MSP_x value, depending on hr.
  25. // this is useful for logging. for instance, the statements:
  26. //
  27. // .....
  28. //
  29. // if (FAILED(hr))
  30. // {
  31. // LOG((MSP_ERROR, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  32. // }
  33. // else
  34. // {
  35. // LOG((MSP_TRACE, "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  36. // }
  37. //
  38. // return hr;
  39. // }
  40. //
  41. // can be replaced with:
  42. //
  43. // ....
  44. //
  45. // LOG((MSP_(hr), "MyClass::MyFunc - exit. hr = 0x%lx", hr));
  46. //
  47. // return hr;
  48. // }
  49. //
  50. #define MSP_(hr) (FAILED(hr)?MSP_ERROR:MSP_TRACE)
  51. //
  52. // return TRUE if the (possibly aggregated) media type that was passed in is valid.
  53. //
  54. // here is the criteria for a valid aggregated media type:
  55. //
  56. // 1. there is one or more bit set
  57. // 2. all bits that are set match the possible media types
  58. // 3. there are no set bits that don't correspond to valid meda types
  59. //
  60. inline BOOL IsValidAggregatedMediaType(DWORD dwAggregatedMediaType)
  61. {
  62. //
  63. // these are all possible media types
  64. //
  65. const DWORD dwAllPossibleMediaTypes = TAPIMEDIATYPE_AUDIO |
  66. TAPIMEDIATYPE_VIDEO |
  67. TAPIMEDIATYPE_DATAMODEM |
  68. TAPIMEDIATYPE_G3FAX |
  69. TAPIMEDIATYPE_MULTITRACK;
  70. //
  71. // return value
  72. //
  73. BOOL bValidMediaType = FALSE;
  74. //
  75. // make sure that there is at least one allowed media type
  76. //
  77. // and
  78. //
  79. // there are no invalid media types
  80. //
  81. if ( (0 == (dwAggregatedMediaType & dwAllPossibleMediaTypes ) ) || // any valid bits set
  82. (0 != (dwAggregatedMediaType & (~dwAllPossibleMediaTypes)) ) ) // no invalid bits are set
  83. {
  84. //
  85. // the media type is invalid.
  86. //
  87. bValidMediaType = FALSE;
  88. }
  89. else
  90. {
  91. //
  92. // the media type is valid.
  93. //
  94. bValidMediaType = TRUE;
  95. }
  96. return bValidMediaType;
  97. }
  98. //
  99. // Make sure we have exactly one media type. That's not the case if
  100. // dwMediaType is 0 or more than one bit is set in dwMediaType. Note
  101. // that DWORD is unsigned so this should be safe.
  102. //
  103. inline BOOL IsSingleMediaType(DWORD dwMediaType)
  104. {
  105. return !((dwMediaType == 0) || ((dwMediaType & (dwMediaType - 1)) != 0));
  106. }
  107. //
  108. // Check to see if the mediatype is a single type and is in the mask.
  109. //
  110. inline BOOL IsValidSingleMediaType(DWORD dwMediaType, DWORD dwMask)
  111. {
  112. return IsSingleMediaType(dwMediaType)
  113. && ((dwMediaType & dwMask) == dwMediaType);
  114. }
  115. /*++
  116. CMSPArray template Description:
  117. Definitions for a simple vector template. The implementaion is borrowed
  118. from CMSPArray in atlapp.h. Modified only the allocation behavior.
  119. This array should only be used to store simple types. It doesn't call the
  120. constructor nor the destructor for each element in the array.
  121. --*/
  122. const DWORD INITIAL = 8;
  123. const DWORD DELTA = 8;
  124. template <class T, DWORD dwInitial = INITIAL, DWORD dwDelta = DELTA>
  125. class CMSPArray
  126. {
  127. protected:
  128. T* m_aT;
  129. int m_nSize;
  130. int m_nAllocSize;
  131. public:
  132. // Construction/destruction
  133. CMSPArray() : m_aT(NULL), m_nSize(0), m_nAllocSize(0)
  134. { }
  135. ~CMSPArray()
  136. {
  137. RemoveAll();
  138. }
  139. // Operations
  140. int GetSize() const
  141. {
  142. return m_nSize;
  143. }
  144. BOOL Grow()
  145. {
  146. T* aT;
  147. DWORD dwTmpSize, cbAllocSize;
  148. int nNewAllocSize;
  149. // get the new number of elements to allocate in nNewAllocSize
  150. if(m_nAllocSize == 0)
  151. {
  152. if(FAILED(DWordToInt(dwInitial, &nNewAllocSize)))
  153. {
  154. return FALSE;
  155. }
  156. }
  157. else
  158. {
  159. if(FAILED(IntToDWord(m_nSize, &dwTmpSize))
  160. || FAILED(DWordAdd(dwTmpSize, DELTA, &dwTmpSize))
  161. || FAILED(DWordToInt(dwTmpSize, &nNewAllocSize))
  162. )
  163. {
  164. return FALSE;
  165. }
  166. }
  167. if( FAILED(IntToDWord(nNewAllocSize, &dwTmpSize))
  168. || FAILED(DWordMult(dwTmpSize, sizeof(T), &cbAllocSize))
  169. )
  170. {
  171. return FALSE;
  172. }
  173. aT = (T*)realloc(m_aT, cbAllocSize);
  174. if(aT == NULL)
  175. return FALSE;
  176. m_nAllocSize = nNewAllocSize;
  177. m_aT = aT;
  178. return TRUE;
  179. }
  180. BOOL Add(T& t)
  181. {
  182. if(m_nSize == m_nAllocSize)
  183. {
  184. if (!Grow()) return FALSE;
  185. }
  186. m_nSize++;
  187. SetAtIndex(m_nSize - 1, t);
  188. return TRUE;
  189. }
  190. BOOL Remove(T& t)
  191. {
  192. int nIndex = Find(t);
  193. if(nIndex == -1)
  194. return FALSE;
  195. return RemoveAt(nIndex);
  196. }
  197. BOOL RemoveAt(int nIndex)
  198. {
  199. if(nIndex != (m_nSize - 1))
  200. memmove((void*)&m_aT[nIndex], (void*)&m_aT[nIndex + 1],
  201. (m_nSize - (nIndex + 1)) * sizeof(T));
  202. m_nSize--;
  203. return TRUE;
  204. }
  205. void RemoveAll()
  206. {
  207. if(m_nAllocSize > 0)
  208. {
  209. free(m_aT);
  210. m_aT = NULL;
  211. m_nSize = 0;
  212. m_nAllocSize = 0;
  213. }
  214. }
  215. T& operator[] (int nIndex) const
  216. {
  217. _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  218. return m_aT[nIndex];
  219. }
  220. T* GetData() const
  221. {
  222. return m_aT;
  223. }
  224. // Implementation
  225. void SetAtIndex(int nIndex, T& t)
  226. {
  227. _ASSERTE(nIndex >= 0 && nIndex < m_nSize);
  228. m_aT[nIndex] = t;
  229. }
  230. int Find(T& t) const
  231. {
  232. for(int i = 0; i < m_nSize; i++)
  233. {
  234. if(m_aT[i] == t)
  235. return i;
  236. }
  237. return -1; // not found
  238. }
  239. };
  240. /*++
  241. CMSPCritSection Description:
  242. Definitions for a auto initialize critical section.
  243. --*/
  244. class CMSPCritSection
  245. {
  246. private:
  247. CRITICAL_SECTION m_CritSec;
  248. public:
  249. CMSPCritSection()
  250. {
  251. InitializeCriticalSection(&m_CritSec);
  252. }
  253. ~CMSPCritSection()
  254. {
  255. DeleteCriticalSection(&m_CritSec);
  256. }
  257. void Lock()
  258. {
  259. EnterCriticalSection(&m_CritSec);
  260. }
  261. BOOL TryLock()
  262. {
  263. return TryEnterCriticalSection(&m_CritSec);
  264. }
  265. void Unlock()
  266. {
  267. LeaveCriticalSection(&m_CritSec);
  268. }
  269. };
  270. /*++
  271. CMSPCritSection Description:
  272. Definitions for a auto lock that unlocks when the variable is out
  273. of scope.
  274. --*/
  275. class CLock
  276. {
  277. private:
  278. CMSPCritSection &m_CriticalSection;
  279. public:
  280. CLock(CMSPCritSection &CriticalSection)
  281. : m_CriticalSection(CriticalSection)
  282. {
  283. m_CriticalSection.Lock();
  284. }
  285. ~CLock()
  286. {
  287. m_CriticalSection.Unlock();
  288. }
  289. };
  290. ///////////////////////////////////////////////////////////////////////////////
  291. //
  292. // CCSLock
  293. //
  294. // a plain old automatic lock that takes a pointer to CRITICAL_SECTION
  295. //
  296. // constructore enters crit section, destructor leaves critical section
  297. //
  298. // class client is responsible for passing a valid critical section
  299. //
  300. class CCSLock
  301. {
  302. private:
  303. CRITICAL_SECTION *m_pCritSec;
  304. public:
  305. CCSLock(CRITICAL_SECTION *pCritSec)
  306. : m_pCritSec(pCritSec)
  307. {
  308. EnterCriticalSection(m_pCritSec);
  309. }
  310. ~CCSLock()
  311. {
  312. LeaveCriticalSection(m_pCritSec);
  313. }
  314. };
  315. /*++
  316. LINK list:
  317. Definitions for a double link list.
  318. --*/
  319. //
  320. // Calculate the address of the base of the structure given its type, and an
  321. // address of a field within the structure.
  322. //
  323. #ifndef CONTAINING_RECORD
  324. #define CONTAINING_RECORD(address, type, field) \
  325. ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field)))
  326. #endif
  327. #ifndef InitializeListHead
  328. //
  329. // VOID
  330. // InitializeListHead(
  331. // PLIST_ENTRY ListHead
  332. // );
  333. //
  334. #define InitializeListHead(ListHead) (\
  335. (ListHead)->Flink = (ListHead)->Blink = (ListHead))
  336. //
  337. // BOOLEAN
  338. // IsListEmpty(
  339. // PLIST_ENTRY ListHead
  340. // );
  341. //
  342. #define IsListEmpty(ListHead) \
  343. ((ListHead)->Flink == (ListHead))
  344. //
  345. // PLIST_ENTRY
  346. // RemoveHeadList(
  347. // PLIST_ENTRY ListHead
  348. // );
  349. //
  350. #define RemoveHeadList(ListHead) \
  351. (ListHead)->Flink;\
  352. {RemoveEntryList((ListHead)->Flink)}
  353. //
  354. // PLIST_ENTRY
  355. // RemoveTailList(
  356. // PLIST_ENTRY ListHead
  357. // );
  358. //
  359. #define RemoveTailList(ListHead) \
  360. (ListHead)->Blink;\
  361. {RemoveEntryList((ListHead)->Blink)}
  362. //
  363. // VOID
  364. // RemoveEntryList(
  365. // PLIST_ENTRY Entry
  366. // );
  367. //
  368. #define RemoveEntryList(Entry) {\
  369. PLIST_ENTRY _EX_Blink;\
  370. PLIST_ENTRY _EX_Flink;\
  371. _EX_Flink = (Entry)->Flink;\
  372. _EX_Blink = (Entry)->Blink;\
  373. _EX_Blink->Flink = _EX_Flink;\
  374. _EX_Flink->Blink = _EX_Blink;\
  375. }
  376. //
  377. // VOID
  378. // InsertTailList(
  379. // PLIST_ENTRY ListHead,
  380. // PLIST_ENTRY Entry
  381. // );
  382. //
  383. #define InsertTailList(ListHead,Entry) {\
  384. PLIST_ENTRY _EX_Blink;\
  385. PLIST_ENTRY _EX_ListHead;\
  386. _EX_ListHead = (ListHead);\
  387. _EX_Blink = _EX_ListHead->Blink;\
  388. (Entry)->Flink = _EX_ListHead;\
  389. (Entry)->Blink = _EX_Blink;\
  390. _EX_Blink->Flink = (Entry);\
  391. _EX_ListHead->Blink = (Entry);\
  392. }
  393. //
  394. // VOID
  395. // InsertHeadList(
  396. // PLIST_ENTRY ListHead,
  397. // PLIST_ENTRY Entry
  398. // );
  399. //
  400. #define InsertHeadList(ListHead,Entry) {\
  401. PLIST_ENTRY _EX_Flink;\
  402. PLIST_ENTRY _EX_ListHead;\
  403. _EX_ListHead = (ListHead);\
  404. _EX_Flink = _EX_ListHead->Flink;\
  405. (Entry)->Flink = _EX_Flink;\
  406. (Entry)->Blink = _EX_ListHead;\
  407. _EX_Flink->Blink = (Entry);\
  408. _EX_ListHead->Flink = (Entry);\
  409. }
  410. BOOL IsNodeOnList(PLIST_ENTRY ListHead, PLIST_ENTRY Entry);
  411. #endif //InitializeListHead
  412. //
  413. // Templates for private addref and release. See Platform SDK documentation.
  414. //
  415. template <class T> ULONG MSPAddRefHelper (T * pMyThis)
  416. {
  417. LOG((MSP_INFO, "MSPAddRefHelper - this = 0x%08x", pMyThis));
  418. typedef CComAggObject<T> AggClass;
  419. AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
  420. return p->AddRef();
  421. }
  422. template <class T> ULONG MSPReleaseHelper (T * pMyThis)
  423. {
  424. LOG((MSP_INFO, "MSPReleaseHelper - this = 0x%08x", pMyThis));
  425. typedef CComAggObject<T> AggClass;
  426. AggClass * p = CONTAINING_RECORD(pMyThis, AggClass, m_contained);
  427. return p->Release();
  428. }
  429. //
  430. // Basic implementation for IObjectSafety.
  431. //
  432. // Derive from this class to make your object safe for scripting on all its
  433. // interfaces
  434. //
  435. #include <Objsafe.h>
  436. class CMSPObjectSafetyImpl : public IObjectSafety
  437. {
  438. public:
  439. CMSPObjectSafetyImpl()
  440. :m_dwSafety(0)
  441. {}
  442. //
  443. // we support the following safety options:
  444. //
  445. enum { SUPPORTED_SAFETY_OPTIONS =
  446. INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA };
  447. STDMETHOD(SetInterfaceSafetyOptions)(REFIID riid, DWORD dwOptionSetMask, DWORD dwEnabledOptions)
  448. {
  449. //
  450. // any options requested that we do not support?
  451. //
  452. if ( (~SUPPORTED_SAFETY_OPTIONS & dwOptionSetMask) != 0 )
  453. {
  454. return E_FAIL;
  455. }
  456. //
  457. // see if the interface is supported at all
  458. //
  459. IUnknown *pUnk = NULL;
  460. HRESULT hr = QueryInterface(riid, (void**)&pUnk);
  461. if (SUCCEEDED(hr))
  462. {
  463. //
  464. // we don't need the interface, just wanted to see if it
  465. // was supported. so release.
  466. //
  467. pUnk->Release();
  468. pUnk = NULL;
  469. //
  470. // the object supports the interface. Set options
  471. //
  472. s_CritSection.Lock();
  473. //
  474. // set the bits specified by the mask to the values specified by
  475. // dwEnabledOptions
  476. //
  477. m_dwSafety = (dwEnabledOptions & dwOptionSetMask) |
  478. (m_dwSafety & ~dwOptionSetMask);
  479. s_CritSection.Unlock();
  480. }
  481. return hr;
  482. }
  483. STDMETHOD(GetInterfaceSafetyOptions)(REFIID riid, DWORD *pdwSupportedOptions, DWORD *pdwEnabledOptions)
  484. {
  485. //
  486. // check caller's pointers
  487. //
  488. if (( !pdwSupportedOptions) ||
  489. ( !pdwEnabledOptions) )
  490. {
  491. return E_POINTER;
  492. }
  493. //
  494. // if we fail, return something meaningful
  495. //
  496. *pdwSupportedOptions = 0;
  497. *pdwEnabledOptions = 0;
  498. //
  499. // see if the interface is supported at all
  500. //
  501. IUnknown *pUnk = NULL;
  502. HRESULT hr = QueryInterface(riid, (void**)&pUnk);
  503. if (SUCCEEDED(hr))
  504. {
  505. //
  506. // we don't need the interface, just wanted to see if it
  507. // was supported. so release.
  508. //
  509. pUnk->Release();
  510. pUnk = NULL;
  511. //
  512. // the object supports the interface. get safe scripting options
  513. //
  514. *pdwSupportedOptions = SUPPORTED_SAFETY_OPTIONS;
  515. s_CritSection.Lock();
  516. *pdwEnabledOptions = m_dwSafety;
  517. s_CritSection.Unlock();
  518. }
  519. return hr;
  520. }
  521. private:
  522. DWORD m_dwSafety;
  523. //
  524. // thread safety
  525. //
  526. // the critical section is shared among all instances of this class
  527. //
  528. static CMSPCritSection s_CritSection;
  529. };
  530. #endif //__MSPUTILS_H_
  531. // eof