/*++ Copyright (c) 1995 Microsoft Corporation Module Name : creatflp.cxx Abstract: This module contains internal create file caching routines. Author: ???? --*/ #include "TsunamiP.Hxx" #pragma hdrstop #include #include #include #include #include #include BOOL DisposeOpenFileInfo( IN PVOID pvOldBlock ) /*++ Routine Description Close open file handles Arguments pvOldBlock - pointer to the file information block. Returns TRUE if operation successful. --*/ { LPTS_OPEN_FILE_INFO lpFileInfo; PVOID pvBlob; IF_DEBUG(OPLOCKS) { PBLOB_HEADER pbhBlob; PCACHE_OBJECT pCache; if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) { pbhBlob = (( PBLOB_HEADER )pvOldBlock ) - 1; pCache = pbhBlob->pCache; DBGPRINTF( (DBG_CONTEXT,"DisposeOpenFileInfo(%s) iDemux=%08lx, cache=%08lx, references=%d\n", pCache->szPath, pCache->iDemux, pCache, pCache->references )); } } lpFileInfo = (LPTS_OPEN_FILE_INFO ) pvOldBlock; pvBlob = ( PVOID )lpFileInfo->QueryPhysFileInfo(); #ifdef CHICAGO if (!(lpFileInfo->m_FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { TsCheckInOrFree( pvBlob ); } #else TsCheckInOrFree( pvBlob ); #endif // // The item may never have been added to the cache, don't // count it in this case // if ( BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) { if ( BLOB_IS_UNC( pvOldBlock )) { InterlockedDecrement( (LONG *) &cCachedUNCHandles ); } } return( TRUE ); } // DisposeOpenFileInfo BOOL DisposePhysOpenFileInfo( IN PVOID pvOldBlock ) /*++ Routine Description Close open file handles Arguments pvOldBlock - pointer to the file information block. Returns TRUE if operation successful. --*/ { PPHYS_OPEN_FILE_INFO lpPhysFileInfo; BOOL bSuccess; LIST_ENTRY * pEntry; PBLOB_HEADER pbhBlob; BOOL fDeleted; IF_DEBUG(OPLOCKS) { PCACHE_OBJECT pCache; if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) ) { pbhBlob = (( PBLOB_HEADER )pvOldBlock ) - 1; pCache = pbhBlob->pCache; } DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%08lx)\n", pvOldBlock )); DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%s) iDemux=%08lx, cache=%08lx, references=%d\n", pCache->szPath, pCache->iDemux, pCache, pCache->references )); } lpPhysFileInfo = (PPHYS_OPEN_FILE_INFO ) pvOldBlock; ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE ); TSUNAMI_TRACE( TRACE_PHYS_DISPOSE, lpPhysFileInfo ); if ( lpPhysFileInfo->abSecurityDescriptor != NULL ) { FREE( lpPhysFileInfo->abSecurityDescriptor ); } if ( lpPhysFileInfo->hOpenFile != INVALID_HANDLE_VALUE ) { bSuccess = CloseHandle( lpPhysFileInfo->hOpenFile ); ASSERT( bSuccess ); lpPhysFileInfo->hOpenFile = INVALID_HANDLE_VALUE; if (BLOB_IS_OR_WAS_CACHED( pvOldBlock )) { DEC_COUNTER( BLOB_GET_SVC_ID( pvOldBlock ), CurrentOpenFileHandles ); } } if (!DisableSPUD) { EnterCriticalSection( &CacheTable.CriticalSection ); while ( !IsListEmpty( &lpPhysFileInfo->OpenReferenceList ) ) { pEntry = RemoveHeadList( &lpPhysFileInfo->OpenReferenceList ); InitializeListHead( pEntry ); } LeaveCriticalSection( &CacheTable.CriticalSection ); } #if 0 if (BLOB_IS_OR_WAS_CACHED( pvOldBlock ) && lpPhysFileInfo->fDeleteOnClose ) { fDeleted = ::DeleteFile( pCache->szPath ); ASSERT( fDeleted ); } IF_DEBUG(OPLOCKS) { DBGPRINTF( (DBG_CONTEXT,"DisposePhysOpenFileInfo(%s) Deleted = %08lx\n", pCache->szPath, fDeleted )); } #endif lpPhysFileInfo->Signature = PHYS_OBJ_SIGNATURE_X; return( TRUE ); } // DisposePhysOpenFileInfo BOOL TS_OPEN_FILE_INFO::SetHttpInfo( IN PSTR pszInfo, IN INT InfoLength ) /*++ Routine Description Set the "Last-Modified:" header field in the file structure. Arguments pszDate - pointer to the header value to save InfoLength - length of the header value to save Returns TRUE if information was cached, FALSE if not cached --*/ { if ( !m_ETagIsWeak && InfoLength < sizeof(m_achHttpInfo)-1 ) { CopyMemory( m_achHttpInfo, pszInfo, InfoLength+1 ); // // this MUST be set after updating the array, // as this is checked to know if the array content is valid. // m_cchHttpInfo = InfoLength; return TRUE; } return FALSE; } // TS_OPEN_FILE_INFO::SetHttpInfo BOOL TS_OPEN_FILE_INFO::SetFileInfo( IN PPHYS_OPEN_FILE_INFO lpPhysFileInfo, IN HANDLE hOpeningUser, IN BOOL fAtRoot, IN DWORD cbSecDescMaxCacheSize, IN DWORD dwAttributes ) /*++ Routine Description Gets the file information for a handle. Arguments hFile - Handle of the file to get information on. hOpeningUser - HANDLE of user opening the file fAtRoot - TRUE if this is the root directory cbSecDescMaxCacheSize - size of the memory allocated to cache the security descriptor for this file object dwAttributes - attributes of the file Returns TRUE if information was stored. FALSE otherwise. --*/ { BOOL fReturn; FILETIME ftNow; SYSTEMTIME stNow; if ( lpPhysFileInfo == NULL) { SetLastError( ERROR_INVALID_PARAMETER); fReturn = FALSE; } else if ( lpPhysFileInfo->hOpenFile == BOGUS_WIN95_DIR_HANDLE) { ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE ); m_PhysFileInfo = lpPhysFileInfo; m_hOpeningUser = NULL; m_ETagIsWeak = TRUE; m_FileInfo.dwFileAttributes = dwAttributes; m_cchETag = 0; fReturn = TRUE; } else { MB mb( (IMDCOM*) IIS_SERVICE::QueryMDObject() ); DWORD dwChangeNumber; ASSERT( lpPhysFileInfo->Signature == PHYS_OBJ_SIGNATURE ); ASSERT(dwAttributes == 0); m_PhysFileInfo = lpPhysFileInfo; m_hOpeningUser = hOpeningUser; m_ETagIsWeak = TRUE; fReturn = GetFileInformationByHandle( m_PhysFileInfo->hOpenFile, &m_FileInfo ); dwChangeNumber = 0; mb.GetSystemChangeNumber(&dwChangeNumber); m_cchETag = FORMAT_ETAG(m_achETag, m_FileInfo.ftLastWriteTime, dwChangeNumber); ::GetSystemTime(&stNow); if (::SystemTimeToFileTime((CONST SYSTEMTIME *)&stNow, &ftNow)) { __int64 iNow, iFileTime; iNow = (__int64)*(__int64 UNALIGNED *)&ftNow; iFileTime = (__int64)*(__int64 UNALIGNED *)&m_FileInfo.ftLastWriteTime; if ((iNow - iFileTime) > STRONG_ETAG_DELTA ) { m_ETagIsWeak = FALSE; } } *((__int64 UNALIGNED*)&m_CastratedLastWriteTime) = (*((__int64 UNALIGNED*)&m_FileInfo.ftLastWriteTime) / 10000000) * 10000000; // // Turn off the hidden attribute if this is a root directory listing // (root some times has the bit set for no apparent reason) // if ( fReturn && fAtRoot ) { m_FileInfo.dwFileAttributes &= ~FILE_ATTRIBUTE_HIDDEN; } m_PhysFileInfo->cbSecDescMaxSize = cbSecDescMaxCacheSize; } return ( fReturn); } // TS_OPEN_FILE_INFO::SetFileInfo() VOID TS_OPEN_FILE_INFO::MakeStrongETag( VOID ) /*++ Routine Description Try and make an ETag 'strong'. To do this we see if the difference between now and the last modified date is greater than our strong ETag delta - if so, we mark the ETag strong. Arguments None. Returns Nothing. --*/ { FILETIME ftNow; SYSTEMTIME stNow; __int64 iNow, iFileTime; if ( m_PhysFileInfo == NULL || m_PhysFileInfo->hOpenFile == INVALID_HANDLE_VALUE) { return; } ::GetSystemTime(&stNow); if (::SystemTimeToFileTime((CONST SYSTEMTIME *)&stNow, &ftNow)) { iNow = (__int64)*(__int64 UNALIGNED *)&ftNow; iFileTime = (__int64)*(__int64 UNALIGNED *)&m_FileInfo.ftLastWriteTime; if ((iNow - iFileTime) > STRONG_ETAG_DELTA ) { m_ETagIsWeak = FALSE; } } } #if DBG VOID TS_OPEN_FILE_INFO::Print( VOID) const { char rgchDbg[300]; wsprintf(rgchDbg, "TS_OPEN_FILE_INFO( %08x). FileHandle = %08x." " Opening User = %08x.\n", this, QueryFileHandle(), QueryOpeningUser() ); OutputDebugString( rgchDbg); return; } // TS_OPEN_FILE_INFO::Print() #endif // DBG