Leaked source code of windows server 2003
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.

370 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. dirmon.h
  5. Abstract:
  6. Public header for directory monitor
  7. Author:
  8. Bilal Alam (balam) Jan-24-2000
  9. Revision History:
  10. --*/
  11. #ifndef _DIRMON_H_
  12. #define _DIRMON_H_
  13. #include <thread_pool.h>
  14. #include "lkrhash.h"
  15. class CDirMonitor;
  16. class CDirMonitorEntry
  17. {
  18. friend class CDirMonitor;
  19. public:
  20. CDirMonitorEntry(
  21. VOID
  22. );
  23. virtual
  24. ~CDirMonitorEntry(
  25. VOID
  26. );
  27. virtual
  28. VOID
  29. AddRef()
  30. {
  31. // This ref count tracks how many templates
  32. // and applications are depending on this monitor entry.
  33. InterlockedIncrement(&m_cDirRefCount);
  34. };
  35. virtual
  36. BOOL
  37. Release(
  38. VOID
  39. ); // return FALSE if last release
  40. virtual
  41. BOOL
  42. Init(
  43. DWORD cbBufferSize
  44. );
  45. protected:
  46. DWORD m_cPathLength;
  47. LPWSTR m_pszPath;
  48. BYTE* m_pbBuffer;
  49. LONG m_cDirRefCount; // Ref count for external usage
  50. LONG m_cIORefCount; // Ref count of Asynch IO
  51. HANDLE m_hDir;
  52. BOOL m_fWatchSubdirectories;
  53. DWORD
  54. GetBufferSize(
  55. VOID
  56. );
  57. BOOL
  58. SetBufferSize(
  59. DWORD cbBufferSize
  60. );
  61. BOOL
  62. ResetDirectoryHandle(
  63. VOID
  64. );
  65. private:
  66. DWORD m_dwNotificationFlags;
  67. OVERLAPPED m_ovr;
  68. DWORD m_cBufferSize;
  69. CDirMonitor* m_pDirMonitor;
  70. BOOL m_fInCleanup;
  71. VOID
  72. IOAddRef(
  73. VOID
  74. );
  75. BOOL
  76. IORelease(
  77. VOID
  78. ); // return FALSE if last release
  79. BOOL
  80. RequestNotification(
  81. VOID
  82. );
  83. BOOL
  84. Cleanup(
  85. VOID
  86. );
  87. virtual
  88. BOOL
  89. ActOnNotification(
  90. DWORD dwStatus,
  91. DWORD dwBytesWritten
  92. ) = 0;
  93. } ;
  94. class CDirMonitor : public CTypedHashTable<CDirMonitor, CDirMonitorEntry, const WCHAR*>
  95. {
  96. public:
  97. CDirMonitor(
  98. VOID
  99. );
  100. ~CDirMonitor(
  101. VOID
  102. );
  103. CDirMonitorEntry *
  104. FindEntry(
  105. WCHAR * pszPath
  106. );
  107. BOOL
  108. Monitor(
  109. CDirMonitorEntry * pDME,
  110. WCHAR * pszDirectory,
  111. BOOL fWatchSubDirectories,
  112. DWORD dwFlags
  113. );
  114. VOID
  115. Cleanup(
  116. VOID
  117. );
  118. LK_RETCODE
  119. InsertEntry(
  120. CDirMonitorEntry * pDME
  121. );
  122. LK_RETCODE
  123. RemoveEntry(
  124. CDirMonitorEntry * pDME
  125. );
  126. LONG
  127. AddRef(
  128. VOID
  129. )
  130. {
  131. return InterlockedIncrement( &m_cRefs );
  132. }
  133. LONG Release(
  134. VOID
  135. )
  136. {
  137. return InterlockedDecrement( &m_cRefs);
  138. }
  139. static const
  140. WCHAR *
  141. CDirMonitor::ExtractKey(
  142. const CDirMonitorEntry* pDME
  143. )
  144. {
  145. return pDME->m_pszPath;
  146. };
  147. static
  148. DWORD
  149. CDirMonitor::CalcKeyHash(
  150. const WCHAR* pszKey
  151. )
  152. {
  153. return HashStringNoCase( pszKey );
  154. }
  155. static
  156. bool
  157. CDirMonitor::EqualKeys(
  158. const WCHAR* pszKey1,
  159. const WCHAR* pszKey2
  160. )
  161. {
  162. return _wcsicmp(pszKey1, pszKey2) == 0;
  163. };
  164. static
  165. VOID
  166. CDirMonitor::AddRefRecord(
  167. CDirMonitorEntry*,
  168. int
  169. )
  170. {
  171. }
  172. private:
  173. CRITICAL_SECTION m_csSerialComplLock;
  174. LONG m_cRefs;
  175. BOOL m_fShutdown;
  176. CDirMonitor(
  177. const CDirMonitor &
  178. );
  179. VOID operator=(
  180. const CDirMonitor &
  181. );
  182. VOID
  183. SerialComplLock(
  184. VOID
  185. )
  186. {
  187. EnterCriticalSection( &m_csSerialComplLock);
  188. }
  189. VOID
  190. SerialComplUnlock(
  191. VOID
  192. )
  193. {
  194. LeaveCriticalSection( &m_csSerialComplLock);
  195. }
  196. public:
  197. static
  198. VOID
  199. DirMonitorCompletionFunction(
  200. PVOID pCtxt,
  201. DWORD dwBytesWritten,
  202. DWORD dwCompletionStatus,
  203. OVERLAPPED * pOvr
  204. );
  205. static
  206. VOID
  207. OverlappedCompletionRoutine(
  208. DWORD dwErrorCode,
  209. DWORD dwNumberOfBytesTransfered,
  210. LPOVERLAPPED lpOverlapped
  211. );
  212. };
  213. inline
  214. BOOL
  215. CDirMonitorEntry::Release(
  216. VOID
  217. )
  218. {
  219. BOOL fRet = TRUE;
  220. CDirMonitor *pDirMonitor = m_pDirMonitor;
  221. LONG cRefs;
  222. //
  223. // Guard against someone doing a FindEntry on an entry we are releasing
  224. //
  225. if (pDirMonitor != NULL)
  226. {
  227. pDirMonitor->WriteLock();
  228. }
  229. cRefs = InterlockedDecrement(&m_cDirRefCount);
  230. if (cRefs == 0)
  231. {
  232. // When ref count reaches 0, clean up resources
  233. BOOL fDeleteNeeded = Cleanup();
  234. // Cleanup said that we need to handle the deletion,
  235. // probably because there were no Asynch operations outstanding
  236. if (fDeleteNeeded)
  237. {
  238. delete this;
  239. }
  240. fRet = FALSE;
  241. }
  242. if (pDirMonitor != NULL)
  243. {
  244. pDirMonitor->WriteUnlock();
  245. }
  246. return fRet;
  247. }
  248. inline
  249. VOID
  250. CDirMonitorEntry::IOAddRef(
  251. VOID
  252. )
  253. {
  254. // This refcount track how many
  255. // asynch IO requests are oustanding
  256. InterlockedIncrement( &m_cIORefCount );
  257. }
  258. inline
  259. BOOL
  260. CDirMonitorEntry::IORelease(
  261. VOID
  262. )
  263. {
  264. BOOL fRet = TRUE;
  265. CDirMonitor *pDirMonitor = m_pDirMonitor;
  266. //
  267. // Guard against someone doing a FindEntry on an entry we are releasing
  268. //
  269. if (pDirMonitor != NULL)
  270. {
  271. pDirMonitor->WriteLock();
  272. }
  273. InterlockedDecrement(&m_cIORefCount);
  274. // When both IO and external ref counts reaches 0,
  275. // free this object
  276. if (m_cIORefCount == 0 &&
  277. m_cDirRefCount == 0)
  278. {
  279. delete this;
  280. fRet = FALSE;
  281. }
  282. if (pDirMonitor != NULL)
  283. {
  284. pDirMonitor->WriteUnlock();
  285. }
  286. return fRet;
  287. }
  288. inline
  289. DWORD
  290. CDirMonitorEntry::GetBufferSize(
  291. VOID
  292. )
  293. {
  294. return m_cBufferSize;
  295. }
  296. #endif /* _DIRMON_H_ */