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.

400 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name :
  4. creatflp.cxx
  5. Abstract:
  6. This module contains internal create file caching routines.
  7. Author:
  8. ????
  9. --*/
  10. #include "TsunamiP.Hxx"
  11. #pragma hdrstop
  12. #include <ctype.h>
  13. #include <iistypes.hxx>
  14. #include <iisver.h>
  15. #include <iiscnfg.h>
  16. #include <imd.h>
  17. #include <mb.hxx>
  18. BOOL
  19. DisposeOpenFileInfo(
  20. IN PVOID pvOldBlock
  21. )
  22. /*++
  23. Routine Description
  24. Close open file handles
  25. Arguments
  26. pvOldBlock - pointer to the file information block.
  27. Returns
  28. TRUE if operation successful.
  29. --*/
  30. {
  31. LPTS_OPEN_FILE_INFO lpFileInfo;
  32. PVOID pvBlob;
  33. IF_DEBUG(OPLOCKS) {
  34. PBLOB_HEADER pbhBlob;
  35. PCACHE_OBJECT pCache;
  36. if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) {
  37. pbhBlob = (( PBLOB_HEADER )pvOldBlock ) - 1;
  38. pCache = pbhBlob->pCache;
  39. DBGPRINTF( (DBG_CONTEXT,"DisposeOpenFileInfo(%s) iDemux=%08lx, cache=%08lx, references=%d\n",
  40. pCache->szPath, pCache->iDemux, pCache, pCache->references ));
  41. }
  42. }
  43. lpFileInfo = (LPTS_OPEN_FILE_INFO ) pvOldBlock;
  44. pvBlob = ( PVOID )lpFileInfo->QueryPhysFileInfo();
  45. #ifdef CHICAGO
  46. if (!(lpFileInfo->m_FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
  47. TsCheckInOrFree( pvBlob );
  48. }
  49. #else
  50. TsCheckInOrFree( pvBlob );
  51. #endif
  52. //
  53. // The item may never have been added to the cache, don't
  54. // count it in this case
  55. //
  56. if ( BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) {
  57. if ( BLOB_IS_UNC( pvOldBlock )) {
  58. InterlockedDecrement( (LONG *) &cCachedUNCHandles );
  59. }
  60. }
  61. return( TRUE );
  62. } // DisposeOpenFileInfo
  63. BOOL
  64. DisposePhysOpenFileInfo(
  65. IN PVOID pvOldBlock
  66. )
  67. /*++
  68. Routine Description
  69. Close open file handles
  70. Arguments
  71. pvOldBlock - pointer to the file information block.
  72. Returns
  73. TRUE if operation successful.
  74. --*/
  75. {
  76. PPHYS_OPEN_FILE_INFO lpPhysFileInfo;
  77. BOOL bSuccess;
  78. LIST_ENTRY * pEntry;
  79. PBLOB_HEADER pbhBlob;
  80. BOOL fDeleted;
  81. IF_DEBUG(OPLOCKS) {
  82. PCACHE_OBJECT pCache;
  83. if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) {
  84. pbhBlob = (( PBLOB_HEADER )pvOldBlock ) - 1;
  85. pCache = pbhBlob->pCache;
  86. }
  87. DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%08lx)\n", pvOldBlock ));
  88. DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%s) iDemux=%08lx, cache=%08lx, references=%d\n",
  89. pCache->szPath, pCache->iDemux, pCache, pCache->references ));
  90. }
  91. lpPhysFileInfo = (PPHYS_OPEN_FILE_INFO ) pvOldBlock;
  92. ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE );
  93. TSUNAMI_TRACE( TRACE_PHYS_DISPOSE, lpPhysFileInfo );
  94. if ( lpPhysFileInfo->abSecurityDescriptor != NULL ) {
  95. FREE( lpPhysFileInfo->abSecurityDescriptor );
  96. }
  97. if ( lpPhysFileInfo->hOpenFile != INVALID_HANDLE_VALUE ) {
  98. bSuccess = CloseHandle( lpPhysFileInfo->hOpenFile );
  99. ASSERT( bSuccess );
  100. lpPhysFileInfo->hOpenFile = INVALID_HANDLE_VALUE;
  101. if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ))
  102. {
  103. DEC_COUNTER( BLOB_GET_SVC_ID( pvOldBlock ), CurrentOpenFileHandles );
  104. }
  105. }
  106. if (!DisableSPUD) {
  107. EnterCriticalSection( &CacheTable.CriticalSection );
  108. while ( !IsListEmpty( &lpPhysFileInfo->OpenReferenceList ) ) {
  109. pEntry = RemoveHeadList( &lpPhysFileInfo->OpenReferenceList );
  110. InitializeListHead( pEntry );
  111. }
  112. LeaveCriticalSection( &CacheTable.CriticalSection );
  113. }
  114. #if 0
  115. if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) && lpPhysFileInfo->fDeleteOnClose ) {
  116. fDeleted = ::DeleteFile( pCache->szPath );
  117. ASSERT( fDeleted );
  118. }
  119. IF_DEBUG(OPLOCKS) {
  120. DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%s) Deleted = %08lx\n",
  121. pCache->szPath, fDeleted ));
  122. }
  123. #endif
  124. lpPhysFileInfo->Signature = PHYS_OBJ_SIGNATURE_X;
  125. return( TRUE );
  126. } // DisposePhysOpenFileInfo
  127. BOOL
  128. TS_OPEN_FILE_INFO::SetHttpInfo(
  129. IN PSTR pszInfo,
  130. IN INT InfoLength
  131. )
  132. /*++
  133. Routine Description
  134. Set the "Last-Modified:" header field in the file structure.
  135. Arguments
  136. pszDate - pointer to the header value to save
  137. InfoLength - length of the header value to save
  138. Returns
  139. TRUE if information was cached,
  140. FALSE if not cached
  141. --*/
  142. {
  143. if ( !m_ETagIsWeak && InfoLength < sizeof(m_achHttpInfo)-1 ) {
  144. CopyMemory( m_achHttpInfo, pszInfo, InfoLength+1 );
  145. //
  146. // this MUST be set after updating the array,
  147. // as this is checked to know if the array content is valid.
  148. //
  149. m_cchHttpInfo = InfoLength;
  150. return TRUE;
  151. }
  152. return FALSE;
  153. } // TS_OPEN_FILE_INFO::SetHttpInfo
  154. BOOL
  155. TS_OPEN_FILE_INFO::SetFileInfo(
  156. IN PPHYS_OPEN_FILE_INFO lpPhysFileInfo,
  157. IN HANDLE hOpeningUser,
  158. IN BOOL fAtRoot,
  159. IN DWORD cbSecDescMaxCacheSize,
  160. IN DWORD dwAttributes
  161. )
  162. /*++
  163. Routine Description
  164. Gets the file information for a handle.
  165. Arguments
  166. hFile - Handle of the file to get information on.
  167. hOpeningUser - HANDLE of user opening the file
  168. fAtRoot - TRUE if this is the root directory
  169. cbSecDescMaxCacheSize - size of the memory allocated to
  170. cache the security descriptor for this file object
  171. dwAttributes - attributes of the file
  172. Returns
  173. TRUE if information was stored.
  174. FALSE otherwise.
  175. --*/
  176. {
  177. BOOL fReturn;
  178. FILETIME ftNow;
  179. SYSTEMTIME stNow;
  180. if ( lpPhysFileInfo == NULL) {
  181. SetLastError( ERROR_INVALID_PARAMETER);
  182. fReturn = FALSE;
  183. } else if ( lpPhysFileInfo->hOpenFile == BOGUS_WIN95_DIR_HANDLE) {
  184. ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE );
  185. m_PhysFileInfo = lpPhysFileInfo;
  186. m_hOpeningUser = NULL;
  187. m_ETagIsWeak = TRUE;
  188. m_FileInfo.dwFileAttributes = dwAttributes;
  189. m_cchETag = 0;
  190. fReturn = TRUE;
  191. } else {
  192. MB mb( (IMDCOM*) IIS_SERVICE::QueryMDObject() );
  193. DWORD dwChangeNumber;
  194. ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE );
  195. ASSERT(dwAttributes == 0);
  196. m_PhysFileInfo = lpPhysFileInfo;
  197. m_hOpeningUser = hOpeningUser;
  198. m_ETagIsWeak = TRUE;
  199. fReturn = GetFileInformationByHandle(
  200. m_PhysFileInfo->hOpenFile,
  201. &m_FileInfo
  202. );
  203. dwChangeNumber = 0;
  204. mb.GetSystemChangeNumber(&dwChangeNumber);
  205. m_cchETag = FORMAT_ETAG(m_achETag, m_FileInfo.ftLastWriteTime,
  206. dwChangeNumber);
  207. ::GetSystemTime(&stNow);
  208. if (::SystemTimeToFileTime((CONST SYSTEMTIME *)&stNow, &ftNow))
  209. {
  210. __int64 iNow, iFileTime;
  211. iNow = (__int64)*(__int64 UNALIGNED *)&ftNow;
  212. iFileTime =
  213. (__int64)*(__int64 UNALIGNED *)&m_FileInfo.ftLastWriteTime;
  214. if ((iNow - iFileTime) > STRONG_ETAG_DELTA )
  215. {
  216. m_ETagIsWeak = FALSE;
  217. }
  218. }
  219. *((__int64 UNALIGNED*)&m_CastratedLastWriteTime)
  220. = (*((__int64 UNALIGNED*)&m_FileInfo.ftLastWriteTime) / 10000000)
  221. * 10000000;
  222. //
  223. // Turn off the hidden attribute if this is a root directory listing
  224. // (root some times has the bit set for no apparent reason)
  225. //
  226. if ( fReturn && fAtRoot ) {
  227. m_FileInfo.dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN;
  228. }
  229. m_PhysFileInfo->cbSecDescMaxSize = cbSecDescMaxCacheSize;
  230. }
  231. return ( fReturn);
  232. } // TS_OPEN_FILE_INFO::SetFileInfo()
  233. VOID
  234. TS_OPEN_FILE_INFO::MakeStrongETag(
  235. VOID
  236. )
  237. /*++
  238. Routine Description
  239. Try and make an ETag 'strong'. To do this we see if the difference
  240. between now and the last modified date is greater than our strong ETag
  241. delta - if so, we mark the ETag strong.
  242. Arguments
  243. None.
  244. Returns
  245. Nothing.
  246. --*/
  247. {
  248. FILETIME ftNow;
  249. SYSTEMTIME stNow;
  250. __int64 iNow, iFileTime;
  251. if ( m_PhysFileInfo == NULL || m_PhysFileInfo->hOpenFile == INVALID_HANDLE_VALUE)
  252. {
  253. return;
  254. }
  255. ::GetSystemTime(&stNow);
  256. if (::SystemTimeToFileTime((CONST SYSTEMTIME *)&stNow, &ftNow))
  257. {
  258. iNow = (__int64)*(__int64 UNALIGNED *)&ftNow;
  259. iFileTime = (__int64)*(__int64 UNALIGNED *)&m_FileInfo.ftLastWriteTime;
  260. if ((iNow - iFileTime) > STRONG_ETAG_DELTA )
  261. {
  262. m_ETagIsWeak = FALSE;
  263. }
  264. }
  265. }
  266. #if DBG
  267. VOID
  268. TS_OPEN_FILE_INFO::Print( VOID) const
  269. {
  270. char rgchDbg[300];
  271. wsprintf(rgchDbg,
  272. "TS_OPEN_FILE_INFO( %08x). FileHandle = %08x."
  273. " Opening User = %08x.\n",
  274. this,
  275. QueryFileHandle(),
  276. QueryOpeningUser()
  277. );
  278. OutputDebugString( rgchDbg);
  279. return;
  280. } // TS_OPEN_FILE_INFO::Print()
  281. #endif // DBG
  282.