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.

230 lines
5.3 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. DWORD cch = 0;
  35. HANDLE hDir;
  36. BOOL fContinueMonitoring = TRUE;
  37. HRESULT hr = NO_ERROR;
  38. //
  39. // If there was an error monitoring directory, then flush the entire
  40. // directory
  41. //
  42. if ( dwStatus != ERROR_SUCCESS )
  43. {
  44. //
  45. // Access denied means directory either was deleted or secured
  46. // Stop monitoring in that case
  47. //
  48. if ( dwStatus == ERROR_ACCESS_DENIED )
  49. {
  50. fContinueMonitoring = FALSE;
  51. }
  52. else
  53. {
  54. _cNotificationFailures++;
  55. if ( _cNotificationFailures > MAX_NOTIFICATION_FAILURES )
  56. {
  57. fContinueMonitoring = FALSE;
  58. }
  59. }
  60. }
  61. else
  62. {
  63. _cNotificationFailures = 0;
  64. }
  65. //
  66. // If no bytes were written, then take the conservative approach and flush
  67. // everything for this physical prefix
  68. //
  69. if ( dwBytesWritten == 0 )
  70. {
  71. FileChanged( L"", TRUE );
  72. }
  73. else
  74. {
  75. pNextNotify = (FILE_NOTIFY_INFORMATION *) m_pbBuffer;
  76. while ( pNextNotify != NULL )
  77. {
  78. BOOL bDoFlush = TRUE;
  79. pNotify = pNextNotify;
  80. pNextNotify = (FILE_NOTIFY_INFORMATION*) ((PCHAR) pNotify + pNotify->NextEntryOffset);
  81. //
  82. // Get the unicode file name from the notification struct
  83. // pNotify->FileNameLength returns the wstr's length in **bytes** not wchars
  84. //
  85. hr = strFileChanged.Copy( pNotify->FileName,
  86. pNotify->FileNameLength / 2 );
  87. if ( FAILED( hr ) )
  88. {
  89. SetLastError( WIN32_FROM_HRESULT( hr ) );
  90. return FALSE;
  91. }
  92. // Take the appropriate action for the directory change
  93. switch (pNotify->Action)
  94. {
  95. case FILE_ACTION_MODIFIED:
  96. //
  97. // Since this change won't change the pathname of
  98. // any files, we don't have to do a flush.
  99. //
  100. bDoFlush = FALSE;
  101. case FILE_ACTION_REMOVED:
  102. case FILE_ACTION_RENAMED_OLD_NAME:
  103. FileChanged(strFileChanged.QueryStr(), bDoFlush);
  104. break;
  105. case FILE_ACTION_ADDED:
  106. case FILE_ACTION_RENAMED_NEW_NAME:
  107. default:
  108. break;
  109. }
  110. if( pNotify == pNextNotify )
  111. {
  112. break;
  113. }
  114. }
  115. }
  116. return fContinueMonitoring;
  117. }
  118. VOID
  119. CacheDirMonitorEntry::FileChanged(
  120. const WCHAR * pszScriptName,
  121. BOOL bDoFlush
  122. )
  123. /*++
  124. Routine Description:
  125. An existing file has been modified or deleted
  126. Flush scripts from cache or mark application as expired
  127. Arguments:
  128. pszScriptName - Name of file that changed
  129. bDoFlush - Should we flush all entries prefixed wih pszScriptName
  130. Return Value:
  131. None
  132. --*/
  133. {
  134. STACK_STRU( strLongName, MAX_PATH );
  135. STACK_STRU( strFullPath, MAX_PATH );
  136. const WCHAR * pszLongName;
  137. DWORD cchLongName;
  138. HRESULT hr;
  139. //
  140. // Convert any short file names
  141. //
  142. if ( wcschr( pszScriptName, L'~' ) != NULL )
  143. {
  144. cchLongName = GetLongPathName( pszScriptName,
  145. strLongName.QueryStr(),
  146. MAX_PATH );
  147. if ( cchLongName == 0 || cchLongName > MAX_PATH )
  148. {
  149. pszLongName = L"";
  150. }
  151. else
  152. {
  153. pszLongName = strLongName.QueryStr();
  154. }
  155. }
  156. else
  157. {
  158. pszLongName = pszScriptName;
  159. }
  160. //
  161. // Create full path of file changed
  162. //
  163. hr = strFullPath.Copy( m_pszPath );
  164. if ( FAILED( hr ) )
  165. {
  166. return;
  167. }
  168. hr = strFullPath.Append( L"\\", 1 );
  169. if ( FAILED( hr ) )
  170. {
  171. return;
  172. }
  173. hr = strFullPath.Append( pszLongName );
  174. if ( FAILED( hr ) )
  175. {
  176. return;
  177. }
  178. _wcsupr( strFullPath.QueryStr() );
  179. //
  180. // Now call the caches
  181. //
  182. g_pCacheManager->HandleDirMonitorInvalidation( strFullPath.QueryStr(),
  183. bDoFlush );
  184. }