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.

376 lines
8.3 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. dirchang.cxx
  5. Abstract:
  6. This module contains the directory change manager routines
  7. Author:
  8. MuraliK
  9. --*/
  10. #include "tsunamip.Hxx"
  11. #pragma hdrstop
  12. #include "dbgutil.h"
  13. #include <mbstring.h>
  14. extern "C" {
  15. #include <lmuse.h>
  16. }
  17. //
  18. // list and cs for the virtual roots
  19. //
  20. LIST_ENTRY GlobalVRootList;
  21. CRITICAL_SECTION csVirtualRoots;
  22. VOID
  23. DcmRemoveItem(
  24. PCACHE_OBJECT pCacheObject
  25. )
  26. /*++
  27. Routine Description
  28. Remove the cache object from the Directory change manager list
  29. Arguments
  30. pCacheObject - Cache object to remove
  31. Returns
  32. None.
  33. --*/
  34. {
  35. ASSERT( !IsListEmpty( &pCacheObject->DirChangeList ) );
  36. RemoveEntryList( &pCacheObject->DirChangeList );
  37. return;
  38. } // DcmRemoveItem
  39. BOOL
  40. DcmAddNewItem(
  41. IN PIIS_SERVER_INSTANCE pInstance,
  42. IN PCHAR pszFileName,
  43. IN PCACHE_OBJECT pCacheObject
  44. )
  45. /*++
  46. Routine Description
  47. Adds a new cache object to the directory change list
  48. Arguments
  49. pCacheObject - Cache object to add
  50. Returns
  51. TRUE, if successful
  52. FALSE, otherwise
  53. --*/
  54. {
  55. PLIST_ENTRY pEntry;
  56. PVIRTUAL_ROOT_MAPPING pVrm;
  57. PDIRECTORY_CACHING_INFO pDci;
  58. BOOLEAN bResult = FALSE;
  59. PIIS_VROOT_TABLE pTable = pInstance->QueryVrootTable();
  60. ASSERT( !DisableTsunamiCaching ); // This should never get called
  61. //
  62. // Must always take the Vroot table lock BEFORE the csVirtualRoots lock
  63. // because DcmAddRoot is called with the vroot table locked then takes
  64. // the csVirtualRoots lock
  65. //
  66. pTable->LockTable();
  67. EnterCriticalSection( &csVirtualRoots );
  68. __try {
  69. for( pEntry = pTable->m_vrootListHead.Flink;
  70. pEntry != &pTable->m_vrootListHead;
  71. pEntry = pEntry->Flink ) {
  72. pVrm = CONTAINING_RECORD(
  73. pEntry,
  74. VIRTUAL_ROOT_MAPPING,
  75. TableListEntry );
  76. //
  77. // If the directory of this virtual root doesn't match the
  78. // beginning of the directory that we are being asked to cache
  79. // within, skip this entry.
  80. //
  81. if ( _mbsnicmp(
  82. (PUCHAR) pszFileName,
  83. (PUCHAR) pVrm->pszDirectoryA,
  84. _mbslen((PUCHAR)pVrm->pszDirectoryA) ) ) {
  85. continue;
  86. }
  87. //
  88. // The virtual root contains the directory of interest.
  89. //
  90. if ( !pVrm->fCachingAllowed ) {
  91. break;
  92. }
  93. pDci = ( PDIRECTORY_CACHING_INFO)( pVrm+1 );
  94. ASSERT( IsListEmpty( &pCacheObject->DirChangeList ) );
  95. InsertHeadList(
  96. &pDci->listCacheObjects,
  97. &pCacheObject->DirChangeList
  98. );
  99. bResult = TRUE;
  100. break;
  101. }
  102. } __finally {
  103. LeaveCriticalSection( &csVirtualRoots );
  104. pTable->UnlockTable();
  105. }
  106. return( bResult );
  107. } // DcmNewItem
  108. BOOL
  109. DcmInitialize(
  110. VOID
  111. )
  112. /*++
  113. Routine Description
  114. Initialize the directory change manager.
  115. Arguments
  116. hQuitEvent - HANDLE to an event which get signalled during
  117. shutdown
  118. hNewItem - HANDLE to an event which gets signalled when a
  119. new item is added.
  120. Returns
  121. TRUE, if successful
  122. FALSE, otherwise
  123. --*/
  124. {
  125. DWORD ThreadId;
  126. InitializeListHead( &GlobalVRootList );
  127. InitializeCriticalSection( &csVirtualRoots );
  128. SET_CRITICAL_SECTION_SPIN_COUNT( &csVirtualRoots,
  129. IIS_DEFAULT_CS_SPIN_COUNT);
  130. //
  131. // If tsunami caching is disabled, don't start the thread
  132. //
  133. if ( DisableTsunamiCaching ) {
  134. return(TRUE);
  135. }
  136. g_hChangeWaitThread = CreateThread( ( LPSECURITY_ATTRIBUTES )NULL,
  137. 0,
  138. ChangeWaitThread,
  139. 0,
  140. 0,
  141. &ThreadId );
  142. if ( g_hChangeWaitThread != NULL ) {
  143. return TRUE;
  144. }
  145. DeleteCriticalSection( &csVirtualRoots );
  146. return( FALSE );
  147. } // DcmInitialize
  148. BOOL
  149. DcmAddRoot(
  150. PVIRTUAL_ROOT_MAPPING pVrm
  151. )
  152. /*++
  153. Routine Description
  154. Adds a virtual root to the DCM list
  155. Arguments
  156. pVrm - pointer to the VR mapping structure describing a VR
  157. Returns
  158. TRUE, if successful
  159. FALSE, otherwise
  160. --*/
  161. {
  162. BOOL bSuccess;
  163. PDIRECTORY_CACHING_INFO pDci;
  164. //
  165. // Check if Caching is disabled
  166. //
  167. if ( DisableTsunamiCaching ) {
  168. return(TRUE);
  169. }
  170. IF_DEBUG( DIRECTORY_CHANGE ) {
  171. DBGPRINTF(( DBG_CONTEXT,
  172. "Opening directory file %s\n", pVrm->pszDirectoryA ));
  173. }
  174. pDci = ( PDIRECTORY_CACHING_INFO)( pVrm+1 );
  175. InitializeListHead( &pDci->listCacheObjects );
  176. //
  177. // Open the file. If this is a UNC path name, we need to
  178. // append a trailing / or the SMB server will barf
  179. //
  180. if ( pVrm->fUNC &&
  181. !IS_CHAR_TERM_A(pVrm->pszDirectoryA, pVrm->cchDirectoryA-1) ) {
  182. pVrm->pszDirectoryA[pVrm->cchDirectoryA++] = '\\';
  183. pVrm->pszDirectoryA[pVrm->cchDirectoryA] = '\0';
  184. }
  185. pDci->hDirectoryFile = CreateFile(
  186. pVrm->pszDirectoryA,
  187. FILE_LIST_DIRECTORY,
  188. FILE_SHARE_READ |
  189. FILE_SHARE_WRITE |
  190. FILE_SHARE_DELETE,
  191. NULL,
  192. OPEN_EXISTING,
  193. FILE_FLAG_BACKUP_SEMANTICS |
  194. FILE_FLAG_OVERLAPPED,
  195. NULL );
  196. //
  197. // remove the trailing slash
  198. //
  199. if ( pVrm->fUNC &&
  200. IS_CHAR_TERM_A(pVrm->pszDirectoryA, pVrm->cchDirectoryA-1) ) {
  201. pVrm->pszDirectoryA[--pVrm->cchDirectoryA] = '\0';
  202. }
  203. if ( pDci->hDirectoryFile == INVALID_HANDLE_VALUE ) {
  204. DBGPRINTF(( DBG_CONTEXT,
  205. "Can't open directory %s, error %lx\n",
  206. pVrm->pszDirectoryA,
  207. GetLastError() ));
  208. if ( GetLastError() == ERROR_FILE_NOT_FOUND ) {
  209. DBGPRINTF(( DBG_CONTEXT,
  210. "[AddRoot] Mapping File Not Found to Path Not Found\n" ));
  211. SetLastError( ERROR_PATH_NOT_FOUND );
  212. }
  213. return FALSE;
  214. }
  215. //
  216. // Now add this to the list
  217. //
  218. EnterCriticalSection( &csVirtualRoots );
  219. InsertTailList( &GlobalVRootList, &pVrm->GlobalListEntry );
  220. LeaveCriticalSection( &csVirtualRoots );
  221. //
  222. // At this point, the entry in the list contains an open directory
  223. // file. This would imply that each contains a valid directory name,
  224. // and is therefore a valid mapping between a "virtual root" and a
  225. // directory name.
  226. //
  227. // The next step is to wait on this directory if we can, and enable
  228. // caching if we succesfully wait.
  229. //
  230. bSuccess = SetEvent( g_hNewItem );
  231. ASSERT( bSuccess );
  232. return( TRUE );
  233. } // DcmAddRoot
  234. VOID
  235. DcmRemoveRoot(
  236. PVIRTUAL_ROOT_MAPPING pVrm
  237. )
  238. {
  239. //
  240. // Remove this from global list
  241. //
  242. EnterCriticalSection( &csVirtualRoots );
  243. RemoveEntryList( &pVrm->GlobalListEntry );
  244. LeaveCriticalSection( &csVirtualRoots );
  245. } // DcmRemoveRoot
  246. /*******************************************************************
  247. NAME: IsCharTermA (DBCS enabled)
  248. SYNOPSIS: check the character in string is terminator or not.
  249. terminator is '/', '\0' or '\\'
  250. ENTRY: lpszString - string
  251. cch - offset for char to check
  252. RETURNS: BOOL - TRUE if it is a terminator
  253. HISTORY:
  254. v-ChiKos 15-May-1997 Created.
  255. ********************************************************************/
  256. BOOL
  257. IsCharTermA(
  258. IN LPCSTR lpszString,
  259. IN INT cch
  260. )
  261. {
  262. CHAR achLast;
  263. achLast = *(lpszString + cch);
  264. if ( achLast == '/' || achLast == '\0' )
  265. {
  266. return TRUE;
  267. }
  268. achLast = *CharPrev(lpszString, lpszString + cch + 1);
  269. return (achLast == '\\');
  270. }
  271.