401 lines
9 KiB
C++
401 lines
9 KiB
C++
|
/*++
|
|||
|
|
|||
|
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 <ctype.h>
|
|||
|
|
|||
|
#include <iistypes.hxx>
|
|||
|
#include <iisver.h>
|
|||
|
#include <iiscnfg.h>
|
|||
|
#include <imd.h>
|
|||
|
#include <mb.hxx>
|
|||
|
|
|||
|
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
|
|||
|
|