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.

236 lines
6.1 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: Change notification
  6. File: dirmon.h
  7. Owner: cgrant
  8. This is the header file for the CDirMonitor and CDirMonitorEntry classes.
  9. ===================================================================*/
  10. #ifndef _DIRMON_H
  11. #define _DIRMON_H
  12. // TODO: We seem to need this pragma to base CDirMonitor on the
  13. // CTypedHashTable template from IISRTL. We should find out
  14. // why the compiler gives us this warning even if CTypedHashTable
  15. // is explcitly declared as __declspec(dlliimport)
  16. #pragma warning(disable:4275)
  17. // These declarations are needed to export the template classes from
  18. // IATQ.DLL and import them into other modules.
  19. // These definitions are used to manage the export/import declarations
  20. // for the classes exported from the DIRMON module of ATQ.
  21. #ifndef IATQ_DLLEXP
  22. # ifdef IATQ_DLL_IMPLEMENTATION
  23. # define IATQ_DLLEXP __declspec(dllexport)
  24. # ifdef IIATQ_MPLEMENTATION_EXPORT
  25. # define IATQ_EXPIMP
  26. # else
  27. # undef IATQ_EXPIMP
  28. # endif
  29. # else // !IATQ_DLL_IMPLEMENTATION
  30. # define IATQ_DLLEXP __declspec(dllimport)
  31. # define IATQ_EXPIMP extern
  32. # endif // !IATQ_DLL_IMPLEMENTATION
  33. #endif // !IATQ_DLLEXP
  34. #include "dbgutil.h"
  35. #include "atq.h"
  36. #include "lkrhash.h"
  37. class CDirMonitor;
  38. class IATQ_DLLEXP CDirMonitorEntry
  39. {
  40. friend class CDirMonitor;
  41. public:
  42. CDirMonitorEntry();
  43. virtual ~CDirMonitorEntry();
  44. virtual VOID AddRef(VOID);
  45. virtual BOOL Release(VOID); // return FALSE if last release
  46. virtual BOOL Init(DWORD);
  47. protected:
  48. DWORD m_dwNotificationFlags;
  49. DWORD m_cPathLength;
  50. LPSTR m_pszPath;
  51. LONG m_cDirRefCount; // Ref count for external usage
  52. LONG m_cIORefCount; // Ref count of Asynch IO
  53. HANDLE m_hDir;
  54. PATQ_CONTEXT m_pAtqCtxt;
  55. OVERLAPPED m_ovr;
  56. DWORD m_cBufferSize;
  57. BYTE* m_pbBuffer;
  58. CDirMonitor* m_pDirMonitor;
  59. BOOL m_fInCleanup;
  60. BOOL m_fWatchSubdirectories;
  61. VOID IOAddRef(VOID);
  62. BOOL IORelease(VOID); // return FALSE if last release
  63. BOOL RequestNotification(VOID);
  64. BOOL Cleanup();
  65. DWORD GetBufferSize(VOID);
  66. BOOL SetBufferSize(DWORD);
  67. BOOL ResetDirectoryHandle(VOID);
  68. virtual BOOL ActOnNotification(DWORD dwStatus, DWORD dwBytesWritten) = 0;
  69. } ;
  70. inline VOID CDirMonitorEntry::AddRef(VOID)
  71. {
  72. // This ref count tracks how many templates
  73. // and applications are depending on this monitor entry.
  74. InterlockedIncrement( &m_cDirRefCount );
  75. #ifdef DBG_NOTIFICATION
  76. DBGPRINTF((DBG_CONTEXT, "[CDirMonitorEntry] After AddRef Ref count %d\n", m_cDirRefCount));
  77. #endif // DBG_NOTIFICATION
  78. }
  79. inline BOOL CDirMonitorEntry::Release(VOID)
  80. {
  81. #ifdef DBG_NOTIFICATION
  82. DBGPRINTF((DBG_CONTEXT, "[CDirMonitorEntry] Before Release Ref count %d.\n", m_cDirRefCount));
  83. #endif // DBG_NOTIFICATION
  84. if ( !InterlockedDecrement( &m_cDirRefCount ) )
  85. {
  86. // When ref count reaches 0, clean up resources
  87. BOOL fDeleteNeeded = Cleanup();
  88. // Cleanup said that we need to handle the deletion,
  89. // probably because there were no Asynch operations outstanding
  90. if (fDeleteNeeded)
  91. {
  92. delete this;
  93. }
  94. return FALSE;
  95. }
  96. return TRUE;
  97. }
  98. inline VOID CDirMonitorEntry::IOAddRef(VOID)
  99. {
  100. // This refcount track how many
  101. // asynch IO requests are oustanding
  102. InterlockedIncrement( &m_cIORefCount );
  103. }
  104. inline BOOL CDirMonitorEntry::IORelease(VOID)
  105. {
  106. if ( !InterlockedDecrement( &m_cIORefCount ) )
  107. {
  108. // When both IO and external ref counts reaches 0,
  109. // free this object
  110. if (m_cDirRefCount == 0)
  111. {
  112. delete this;
  113. }
  114. return FALSE;
  115. }
  116. return TRUE;
  117. }
  118. inline DWORD CDirMonitorEntry::GetBufferSize(VOID)
  119. {
  120. return m_cBufferSize;
  121. }
  122. class IATQ_DLLEXP CDirMonitor : public CTypedHashTable<CDirMonitor, CDirMonitorEntry, const char*>
  123. {
  124. public:
  125. CDirMonitor();
  126. ~CDirMonitor();
  127. VOID Lock(VOID);
  128. VOID Unlock(VOID);
  129. CDirMonitorEntry *FindEntry(LPCSTR pszPath);
  130. BOOL Monitor( CDirMonitorEntry *pDME, LPCSTR pszDirectory, BOOL fWatchSubDirectories, DWORD dwFlags);
  131. BOOL Cleanup(VOID);
  132. LK_RETCODE InsertEntry( CDirMonitorEntry *pDME );
  133. LK_RETCODE RemoveEntry( CDirMonitorEntry *pDME );
  134. LONG AddRef(VOID);
  135. LONG Release(VOID);
  136. static const char* CDirMonitor::ExtractKey(const CDirMonitorEntry* pDME)
  137. {
  138. return pDME->m_pszPath;
  139. };
  140. static DWORD CDirMonitor::CalcKeyHash(const char* pszKey)
  141. {
  142. return HashStringNoCase(pszKey);
  143. };
  144. static bool CDirMonitor::EqualKeys(const char* pszKey1, const char* pszKey2)
  145. {
  146. return _stricmp(pszKey1, pszKey2) == 0;
  147. };
  148. static void CDirMonitor::AddRefRecord(CDirMonitorEntry* pDME, int nIncr)
  149. {
  150. // Don't do automatic ref counting. Handle reference counts explicitly
  151. }
  152. private:
  153. CRITICAL_SECTION m_csLock;
  154. CRITICAL_SECTION m_csSerialComplLock;
  155. LONG m_cRefs;
  156. VOID SerialComplLock();
  157. VOID SerialComplUnlock();
  158. public:
  159. static VOID DirMonitorCompletionFunction( PVOID pCtxt, DWORD dwBytesWritten, DWORD dwCompletionStatus, OVERLAPPED *pOvr );
  160. };
  161. inline LONG CDirMonitor::AddRef()
  162. {
  163. return InterlockedIncrement( &m_cRefs );
  164. }
  165. inline LONG CDirMonitor::Release()
  166. {
  167. return InterlockedDecrement( &m_cRefs);
  168. }
  169. inline VOID CDirMonitor::Lock(VOID)
  170. {
  171. EnterCriticalSection( &m_csLock);
  172. }
  173. inline VOID CDirMonitor::Unlock(VOID)
  174. {
  175. LeaveCriticalSection( &m_csLock);
  176. }
  177. inline VOID CDirMonitor::SerialComplLock(VOID)
  178. {
  179. EnterCriticalSection( &m_csSerialComplLock);
  180. }
  181. inline VOID CDirMonitor::SerialComplUnlock(VOID)
  182. {
  183. LeaveCriticalSection( &m_csSerialComplLock);
  184. }
  185. #endif /* _DIRMON_H */