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.

228 lines
5.5 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name :
  4. cachedir.cxx
  5. Abstract:
  6. Dir monitor for cache manager
  7. Author:
  8. Bilal Alam (balam) 11-Nov-2000
  9. Environment:
  10. Win32 - User Mode
  11. Project:
  12. ULW3.DLL
  13. --*/
  14. #include "precomp.hxx"
  15. #define DIR_CHANGE_FILTER (FILE_NOTIFY_VALID_MASK & ~FILE_NOTIFY_CHANGE_LAST_ACCESS)
  16. BOOL
  17. CacheDirMonitorEntry::ActOnNotification(
  18. DWORD dwStatus,
  19. DWORD dwBytesWritten
  20. )
  21. /*++
  22. Routine Description:
  23. Do any work associated with a change notification, i.e.
  24. Arguments:
  25. dwStatus - Win32 status for dirmon completion
  26. dwBytesWritten - Bytes written in dir change buffer
  27. Return Value:
  28. TRUE if directory should continue to be monitored, otherwise FALSE
  29. --*/
  30. {
  31. FILE_NOTIFY_INFORMATION * pNotify = NULL;
  32. FILE_NOTIFY_INFORMATION * pNextNotify = NULL;
  33. STACK_STRU( strFileChanged, MAX_PATH );
  34. BOOL fContinueMonitoring = TRUE;
  35. HRESULT hr = NO_ERROR;
  36. //
  37. // If there was an error monitoring directory, then flush the entire
  38. // directory
  39. //
  40. if ( dwStatus != ERROR_SUCCESS )
  41. {
  42. //
  43. // Access denied means directory either was deleted or secured
  44. // Stop monitoring in that case
  45. //
  46. if ( dwStatus == ERROR_ACCESS_DENIED )
  47. {
  48. fContinueMonitoring = FALSE;
  49. }
  50. else
  51. {
  52. _cNotificationFailures++;
  53. if ( _cNotificationFailures > MAX_NOTIFICATION_FAILURES )
  54. {
  55. fContinueMonitoring = FALSE;
  56. }
  57. }
  58. }
  59. else
  60. {
  61. _cNotificationFailures = 0;
  62. }
  63. //
  64. // If no bytes were written, then take the conservative approach and flush
  65. // everything for this physical prefix
  66. //
  67. if ( dwBytesWritten == 0 )
  68. {
  69. FileChanged( L"", TRUE );
  70. }
  71. else
  72. {
  73. pNextNotify = (FILE_NOTIFY_INFORMATION *) m_pbBuffer;
  74. while ( pNextNotify != NULL )
  75. {
  76. BOOL bDoFlush = TRUE;
  77. pNotify = pNextNotify;
  78. pNextNotify = (FILE_NOTIFY_INFORMATION*) ((PCHAR) pNotify + pNotify->NextEntryOffset);
  79. //
  80. // Get the unicode file name from the notification struct
  81. // pNotify->FileNameLength returns the wstr's length in **bytes** not wchars
  82. //
  83. hr = strFileChanged.Copy( pNotify->FileName,
  84. pNotify->FileNameLength / 2 );
  85. if ( FAILED( hr ) )
  86. {
  87. SetLastError( WIN32_FROM_HRESULT( hr ) );
  88. return FALSE;
  89. }
  90. // Take the appropriate action for the directory change
  91. switch (pNotify->Action)
  92. {
  93. case FILE_ACTION_MODIFIED:
  94. //
  95. // Since this change won't change the pathname of
  96. // any files, we don't have to do a flush.
  97. //
  98. bDoFlush = FALSE;
  99. case FILE_ACTION_REMOVED:
  100. case FILE_ACTION_RENAMED_OLD_NAME:
  101. FileChanged(strFileChanged.QueryStr(), bDoFlush);
  102. break;
  103. case FILE_ACTION_ADDED:
  104. case FILE_ACTION_RENAMED_NEW_NAME:
  105. default:
  106. break;
  107. }
  108. if( pNotify == pNextNotify )
  109. {
  110. break;
  111. }
  112. }
  113. }
  114. return fContinueMonitoring;
  115. }
  116. VOID
  117. CacheDirMonitorEntry::FileChanged(
  118. const WCHAR * pszScriptName,
  119. BOOL bDoFlush
  120. )
  121. /*++
  122. Routine Description:
  123. An existing file has been modified or deleted
  124. Flush scripts from cache or mark application as expired
  125. Arguments:
  126. pszScriptName - Name of file that changed
  127. bDoFlush - Should we flush all entries prefixed wih pszScriptName
  128. Return Value:
  129. None
  130. --*/
  131. {
  132. STACK_STRU( strLongName, MAX_PATH );
  133. STACK_STRU( strFullPath, MAX_PATH );
  134. const WCHAR * pszLongName;
  135. DWORD cchLongName;
  136. HRESULT hr;
  137. //
  138. // Convert any short file names
  139. //
  140. if ( wcschr( pszScriptName, L'~' ) != NULL )
  141. {
  142. cchLongName = GetLongPathName( pszScriptName,
  143. strLongName.QueryStr(),
  144. MAX_PATH );
  145. if ( cchLongName == 0 || cchLongName > MAX_PATH )
  146. {
  147. pszLongName = L"";
  148. }
  149. else
  150. {
  151. pszLongName = strLongName.QueryStr();
  152. }
  153. }
  154. else
  155. {
  156. pszLongName = pszScriptName;
  157. }
  158. //
  159. // Create full path of file changed
  160. //
  161. hr = strFullPath.Copy( m_pszPath );
  162. if ( FAILED( hr ) )
  163. {
  164. return;
  165. }
  166. hr = strFullPath.Append( L"\\", 1 );
  167. if ( FAILED( hr ) )
  168. {
  169. return;
  170. }
  171. hr = strFullPath.Append( pszLongName );
  172. if ( FAILED( hr ) )
  173. {
  174. return;
  175. }
  176. _wcsupr( strFullPath.QueryStr() );
  177. //
  178. // Now call the caches
  179. //
  180. g_pCacheManager->HandleDirMonitorInvalidation( strFullPath.QueryStr(),
  181. bDoFlush );
  182. }