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.

360 lines
6.0 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* pDME,
  168. int nIncr
  169. )
  170. {
  171. }
  172. private:
  173. CRITICAL_SECTION m_csSerialComplLock;
  174. LONG m_cRefs;
  175. BOOL m_fShutdown;
  176. VOID
  177. SerialComplLock(
  178. VOID
  179. )
  180. {
  181. EnterCriticalSection( &m_csSerialComplLock);
  182. }
  183. VOID
  184. SerialComplUnlock(
  185. VOID
  186. )
  187. {
  188. LeaveCriticalSection( &m_csSerialComplLock);
  189. }
  190. public:
  191. static
  192. VOID
  193. DirMonitorCompletionFunction(
  194. PVOID pCtxt,
  195. DWORD dwBytesWritten,
  196. DWORD dwCompletionStatus,
  197. OVERLAPPED * pOvr
  198. );
  199. static
  200. VOID
  201. OverlappedCompletionRoutine(
  202. DWORD dwErrorCode,
  203. DWORD dwNumberOfBytesTransfered,
  204. LPOVERLAPPED lpOverlapped
  205. );
  206. };
  207. inline
  208. BOOL
  209. CDirMonitorEntry::Release(
  210. VOID
  211. )
  212. {
  213. BOOL fRet = TRUE;
  214. CDirMonitor *pDirMonitor = m_pDirMonitor;
  215. LONG cRefs;
  216. //
  217. // Guard against someone doing a FindEntry on an entry we are releasing
  218. //
  219. if (pDirMonitor != NULL)
  220. {
  221. pDirMonitor->WriteLock();
  222. }
  223. cRefs = InterlockedDecrement(&m_cDirRefCount);
  224. if (cRefs == 0)
  225. {
  226. // When ref count reaches 0, clean up resources
  227. BOOL fDeleteNeeded = Cleanup();
  228. // Cleanup said that we need to handle the deletion,
  229. // probably because there were no Asynch operations outstanding
  230. if (fDeleteNeeded)
  231. {
  232. delete this;
  233. }
  234. fRet = FALSE;
  235. }
  236. if (pDirMonitor != NULL)
  237. {
  238. pDirMonitor->WriteUnlock();
  239. }
  240. return fRet;
  241. }
  242. inline
  243. VOID
  244. CDirMonitorEntry::IOAddRef(
  245. VOID
  246. )
  247. {
  248. // This refcount track how many
  249. // asynch IO requests are oustanding
  250. InterlockedIncrement( &m_cIORefCount );
  251. }
  252. inline
  253. BOOL
  254. CDirMonitorEntry::IORelease(
  255. VOID
  256. )
  257. {
  258. BOOL fRet = TRUE;
  259. CDirMonitor *pDirMonitor = m_pDirMonitor;
  260. //
  261. // Guard against someone doing a FindEntry on an entry we are releasing
  262. //
  263. if (pDirMonitor != NULL)
  264. {
  265. pDirMonitor->WriteLock();
  266. }
  267. InterlockedDecrement(&m_cIORefCount);
  268. // When both IO and external ref counts reaches 0,
  269. // free this object
  270. if (m_cIORefCount == 0 &&
  271. m_cDirRefCount == 0)
  272. {
  273. delete this;
  274. fRet = FALSE;
  275. }
  276. if (pDirMonitor != NULL)
  277. {
  278. pDirMonitor->WriteUnlock();
  279. }
  280. return fRet;
  281. }
  282. inline
  283. DWORD
  284. CDirMonitorEntry::GetBufferSize(
  285. VOID
  286. )
  287. {
  288. return m_cBufferSize;
  289. }
  290. #endif /* _DIRMON_H_ */