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.

293 lines
7.1 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: w32utils.h
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: LazarI
  10. *
  11. * DATE: 23-Dec-2000
  12. *
  13. * DESCRIPTION: Win32 templates & utilities
  14. *
  15. *****************************************************************************/
  16. #ifndef _W32UTILS_H
  17. #define _W32UTILS_H
  18. // the generic smart pointers & handles
  19. #include "gensph.h"
  20. ////////////////////////////////////////////////
  21. //
  22. // class CSimpleWndSubclass
  23. //
  24. // class implementing simple window subclassing
  25. // (Windows specific classes)
  26. //
  27. typedef LRESULT type_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  28. template <class inheritorClass>
  29. class CSimpleWndSubclass
  30. {
  31. WNDPROC m_wndDefProc;
  32. static LRESULT CALLBACK _ThunkWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  33. public:
  34. CSimpleWndSubclass(): m_hwnd(NULL), m_wndDefProc(NULL) { }
  35. CSimpleWndSubclass(HWND hwnd): m_hwnd(NULL), m_wndDefProc(NULL) { Attach(hwnd); }
  36. ~CSimpleWndSubclass() { Detach(); }
  37. // attach/detach
  38. BOOL IsAttached() const;
  39. BOOL Attach(HWND hwnd);
  40. BOOL Detach();
  41. // default subclass proc
  42. LRESULT WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  43. // default proc(s)
  44. LRESULT DefWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  45. LRESULT DefDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  46. HWND m_hwnd;
  47. };
  48. ////////////////////////////////////////////////
  49. //
  50. // class COleComInitializer
  51. //
  52. // smart OLE2, COM initializer - just declare
  53. // an instance wherever need to use COM, OLE2
  54. //
  55. class COleComInitializer
  56. {
  57. public:
  58. COleComInitializer(BOOL bOleInit = FALSE);
  59. ~COleComInitializer();
  60. operator BOOL () const;
  61. private:
  62. HRESULT m_hr;
  63. BOOL m_bOleInit;
  64. };
  65. ////////////////////////////////////////////////
  66. //
  67. // class CDllLoader
  68. //
  69. // smart DLL loader - calls LoadLibrary
  70. // FreeLibrary for you.
  71. //
  72. class CDllLoader
  73. {
  74. public:
  75. CDllLoader(LPCTSTR pszDllName);
  76. ~CDllLoader();
  77. operator BOOL () const;
  78. FARPROC GetProcAddress( LPCSTR lpProcName );
  79. FARPROC GetProcAddress( WORD wProcOrd );
  80. private:
  81. HMODULE m_hLib;
  82. };
  83. ////////////////////////////////////////////////
  84. // class CCookiesHolder
  85. //
  86. // this a utility class which allows us to pass more
  87. // than one pointer through a single cookie (pointer).
  88. //
  89. class CCookiesHolder
  90. {
  91. public:
  92. // construction/destruction
  93. CCookiesHolder();
  94. CCookiesHolder(UINT nCount);
  95. ~CCookiesHolder();
  96. // sets the count
  97. BOOL SetCount(UINT uCount);
  98. // returns the number of cookies here
  99. UINT GetCount() const
  100. { return m_uCount; }
  101. // returns the cookie at this position
  102. template <class pType>
  103. pType GetCookie(UINT iIndex) const
  104. {
  105. ASSERT(iIndex < m_uCount);
  106. return reinterpret_cast<pType>(m_pCookies[iIndex]);
  107. }
  108. // returns the previous cookie at this position
  109. template <class pType>
  110. pType SetCookie(UINT iIndex, pType pCookie)
  111. {
  112. ASSERT(iIndex < m_uCount);
  113. pType pReturn = reinterpret_cast<pType>(m_pCookies[iIndex]);
  114. m_pCookies[iIndex] = reinterpret_cast<LPVOID>(pCookie);
  115. return pReturn;
  116. }
  117. // const & non-const operators []
  118. LPVOID operator [] (UINT iIndex) const
  119. {
  120. ASSERT(iIndex < m_uCount);
  121. return m_pCookies[iIndex];
  122. }
  123. LPVOID& operator [] (UINT iIndex)
  124. {
  125. ASSERT(iIndex < m_uCount);
  126. return m_pCookies[iIndex];
  127. }
  128. private:
  129. UINT m_uCount;
  130. LPVOID *m_pCookies;
  131. };
  132. ////////////////////////////////////////////////
  133. //
  134. // template class CScopeLocker<TLOCK>
  135. //
  136. template <class TLOCK>
  137. class CScopeLocker
  138. {
  139. public:
  140. CScopeLocker(TLOCK &lock):
  141. m_Lock(lock), m_bLocked(false)
  142. { m_bLocked = (m_Lock && m_Lock.Lock()); }
  143. ~CScopeLocker()
  144. { if (m_bLocked) m_Lock.Unlock(); }
  145. operator bool () const
  146. { return m_bLocked; }
  147. private:
  148. bool m_bLocked;
  149. TLOCK &m_Lock;
  150. };
  151. ////////////////////////////////////////////////
  152. //
  153. // class CCSLock - win32 critical section lock.
  154. //
  155. class CCSLock
  156. {
  157. public:
  158. // CCSLock::Locker should be used as locker class.
  159. typedef CScopeLocker<CCSLock> Locker;
  160. CCSLock(): m_bInitialized(false)
  161. {
  162. for (;;)
  163. {
  164. __try
  165. {
  166. // InitializeCriticalSection may rise STATUS_NO_MEMORY exception
  167. // in low memory conditions (according the SDK)
  168. InitializeCriticalSection(&m_CS);
  169. m_bInitialized = true;
  170. return;
  171. }
  172. __except(EXCEPTION_EXECUTE_HANDLER) {}
  173. Sleep(100);
  174. }
  175. }
  176. ~CCSLock()
  177. {
  178. if (m_bInitialized)
  179. {
  180. // delete the critical section only if initialized successfully
  181. DeleteCriticalSection(&m_CS);
  182. }
  183. }
  184. operator bool () const
  185. {
  186. return m_bInitialized;
  187. }
  188. bool Lock()
  189. {
  190. for (;;)
  191. {
  192. __try
  193. {
  194. // EnterCriticalSection may rise STATUS_NO_MEMORY exception
  195. // in low memory conditions (this may happen if there is contention
  196. // and ntdll can't allocate the wait semaphore)
  197. EnterCriticalSection(&m_CS);
  198. return true;
  199. }
  200. __except(EXCEPTION_EXECUTE_HANDLER) {}
  201. Sleep(100);
  202. }
  203. // we should never end up here either way
  204. return false;
  205. }
  206. void Unlock()
  207. {
  208. // Unlock() should be called *ONLY* if the corresponding
  209. // Lock() call has succeeded.
  210. LeaveCriticalSection(&m_CS);
  211. }
  212. #if DBG
  213. // debug code...
  214. bool bInside() const
  215. {
  216. return (m_bInitialized && m_CS.OwningThread == DWORD2PTR(GetCurrentThreadId(), HANDLE));
  217. }
  218. bool bOutside() const
  219. {
  220. return (m_bInitialized && m_CS.OwningThread != DWORD2PTR(GetCurrentThreadId(), HANDLE));
  221. }
  222. #endif
  223. private:
  224. bool m_bInitialized;
  225. CRITICAL_SECTION m_CS;
  226. };
  227. ////////////////////////////////////////////////
  228. //
  229. // class CSemaphoreLock - simple semaphore lock.
  230. //
  231. class CSemaphoreLock
  232. {
  233. public:
  234. typedef CScopeLocker<CSemaphoreLock> Locker;
  235. CSemaphoreLock() { }
  236. ~CSemaphoreLock() { }
  237. void Lock() { ASSERT(m_shSemaphore); WaitForSingleObject(m_shSemaphore, INFINITE); }
  238. void Unlock() { ASSERT(m_shSemaphore); ReleaseSemaphore(m_shSemaphore, 1, NULL); }
  239. HRESULT Create(
  240. LONG lInitialCount, // initial count
  241. LONG lMaximumCount, // maximum count
  242. LPCTSTR lpName = NULL, // object name
  243. LPSECURITY_ATTRIBUTES lpSemaphoreAttributes = NULL // SD
  244. )
  245. {
  246. m_shSemaphore = CreateSemaphore(lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName);
  247. return m_shSemaphore ? S_OK : E_OUTOFMEMORY;
  248. }
  249. private:
  250. CAutoHandleNT m_shSemaphore;
  251. };
  252. // include the implementation of the template classes here
  253. #include "w32utils.inl"
  254. #endif // endif _W32UTILS_H