Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

256 lines
4.6 KiB

  1. #ifndef _MISCHLPR_H_
  2. #define _MISCHLPR_H_
  3. #include <objbase.h>
  4. #include "dbg.h"
  5. #include "tfids.h"
  6. #define UNREF_PARAM(a)
  7. #define IID_PPV_ARG(IType, ppType) IID_##IType, reinterpret_cast<void**>(static_cast<IType**>(ppType))
  8. class CRefCounted
  9. {
  10. #ifdef DEBUG
  11. private:
  12. void _TraceHelper(LPCTSTR pszOper, ULONG cRef, LPCTSTR pszObjName,
  13. LPCSTR pszFile, const int iLine)
  14. {
  15. LPTSTR pszFinal;
  16. WCHAR szwBuf[MAX_PATH + 12];
  17. CHAR szBuf[MAX_PATH + 12];
  18. int c = lstrlenA(pszFile);
  19. LPCSTR pszFileName;
  20. while (c && ('\\' != *(pszFile + c)))
  21. {
  22. --c;
  23. }
  24. pszFileName = pszFile + c + 1;
  25. wsprintfA(szBuf, "<%s, %d>", pszFileName, iLine);
  26. #ifdef UNICODE
  27. pszFinal = szwBuf;
  28. MultiByteToWideChar(CP_ACP, 0, szBuf, lstrlenA(szBuf) + 1, szwBuf,
  29. sizeof(szwBuf) / sizeof(WCHAR));
  30. #else
  31. pszFinal = szBuf;
  32. #endif
  33. if (pszObjName)
  34. {
  35. TRACE(TF_RCADDREF | TF_NOFILEANDLINE, TEXT("%s {%s} %s: %d"),
  36. pszFinal, pszObjName, pszOper, cRef);
  37. }
  38. else
  39. {
  40. TRACE(TF_NOFILEANDLINE | TF_RCADDREF, TEXT("%s %s: %d"), pszFinal,
  41. pszOper, cRef);
  42. }
  43. }
  44. protected:
  45. void _RCCreate(LPCSTR pszFile, const int iLine)
  46. {
  47. _TraceHelper(TEXT(" Create"), 1, _pszRCAddRefName, pszFile, iLine);
  48. }
  49. LPTSTR _pszRCAddRefName;
  50. public:
  51. ULONG _RCGetRefCount()
  52. {
  53. return _cRef;
  54. }
  55. virtual ULONG RCAddRef(LPCSTR pszFile, const int iLine)
  56. {
  57. ULONG cRef = ::InterlockedIncrement((LONG*)&_cRef);
  58. _TraceHelper(TEXT(" AddRef"), cRef, _pszRCAddRefName, pszFile, iLine);
  59. return cRef;
  60. }
  61. virtual ULONG RCRelease(LPCSTR pszFile, const int iLine)
  62. {
  63. ULONG cRef = ::InterlockedDecrement((LONG*)&_cRef);
  64. _TraceHelper(TEXT("Release"), cRef, _pszRCAddRefName, pszFile, iLine);
  65. if (!cRef)
  66. {
  67. delete this;
  68. }
  69. return cRef;
  70. }
  71. #define RCAddRef() RCAddRef(__FILE__, __LINE__)
  72. #define RCRelease() RCRelease(__FILE__, __LINE__)
  73. #else
  74. public:
  75. ULONG RCAddRef() { return ::InterlockedIncrement((LONG*)&_cRef); }
  76. ULONG RCRelease()
  77. {
  78. ULONG cRef = ::InterlockedDecrement((LONG*)&_cRef);
  79. if (!cRef)
  80. {
  81. delete this;
  82. }
  83. return cRef;
  84. }
  85. #endif
  86. CRefCounted() : _cRef(1)
  87. #ifdef DEBUG
  88. , _pszRCAddRefName(NULL)
  89. #endif
  90. {}
  91. virtual ~CRefCounted() {}
  92. private:
  93. ULONG _cRef;
  94. };
  95. class CRefCountedCritSect : public CRefCounted, public CRITICAL_SECTION
  96. {};
  97. class CCriticalSection : CRITICAL_SECTION
  98. {
  99. public:
  100. void Init()
  101. {
  102. InitializeCriticalSection(this);
  103. _fInited = TRUE;
  104. #ifdef DEBUG
  105. _iLevel = 0;
  106. #endif
  107. }
  108. void Enter()
  109. {
  110. ASSERT(_fInited);
  111. EnterCriticalSection(this);
  112. #ifdef DEBUG
  113. ++_iLevel;
  114. #endif
  115. }
  116. void Leave()
  117. {
  118. ASSERT(_fInited);
  119. #ifdef DEBUG
  120. --_iLevel;
  121. #endif
  122. LeaveCriticalSection(this);
  123. }
  124. void Delete()
  125. {
  126. if (_fInited)
  127. {
  128. _fInited = FALSE;
  129. DeleteCriticalSection(this);
  130. }
  131. }
  132. BOOL IsInitialized()
  133. {
  134. return _fInited;
  135. }
  136. BOOL _fInited;
  137. #ifdef DEBUG
  138. BOOL IsInside()
  139. {
  140. ASSERT(_fInited);
  141. return _iLevel;
  142. }
  143. DWORD _iLevel;
  144. #endif
  145. };
  146. class CThreadTask
  147. {
  148. public:
  149. virtual ~CThreadTask() {}
  150. public:
  151. // Uses CreateThread, delete 'this' at the end
  152. HRESULT RunWithTimeout(DWORD dwTimeout);
  153. // Uses Thread Pool, delete 'this' at the end
  154. HRESULT Run();
  155. // Run on 'this' thread, does NOT delete 'this' at the end
  156. HRESULT RunSynchronously();
  157. protected:
  158. virtual HRESULT _DoStuff() = 0;
  159. private:
  160. static DWORD WINAPI _ThreadProc(void* pv);
  161. };
  162. template<typename TDataPtr>
  163. HRESULT _AllocMemoryChunk(DWORD cbSize, TDataPtr* pdataOut)
  164. {
  165. HRESULT hr;
  166. *pdataOut = (TDataPtr)LocalAlloc(LPTR, cbSize);
  167. if (*pdataOut)
  168. {
  169. hr = S_OK;
  170. }
  171. else
  172. {
  173. hr = E_OUTOFMEMORY;
  174. }
  175. return hr;
  176. }
  177. template<typename TDataPtr>
  178. HRESULT _DupMemoryChunk(TDataPtr pdata, DWORD cbSize, TDataPtr* pdataOut)
  179. {
  180. HRESULT hr;
  181. *pdataOut = (TDataPtr)LocalAlloc(LPTR, cbSize);
  182. if (*pdataOut)
  183. {
  184. CopyMemory((void*)*pdataOut, pdata, cbSize);
  185. hr = S_OK;
  186. }
  187. else
  188. {
  189. hr = E_OUTOFMEMORY;
  190. }
  191. return hr;
  192. }
  193. template<typename TDataPtr>
  194. HRESULT _FreeMemoryChunk(TDataPtr pdata)
  195. {
  196. HRESULT hr = S_OK;
  197. if (LocalFree((HLOCAL)pdata))
  198. {
  199. hr = E_FAIL;
  200. }
  201. return hr;
  202. }
  203. #endif //_MISCHLPR_H_