|
|
/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
infocach.c
Abstract:
This module implements the name cache for file basic and standard information.
Author:
Yun Lin [YunLin] 13-Feburary-2001
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include "webdav.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, MRxDAVCacheFileNotFound)
#pragma alloc_text(PAGE, MRxDAVCacheFileNotFoundWithName)
#pragma alloc_text(PAGE, MRxDAVIsFileNotFoundCached)
#pragma alloc_text(PAGE, MRxDAVIsFileNotFoundCachedWithName)
#pragma alloc_text(PAGE, MRxDAVCreateFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVCreateFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVIsFileInfoCacheFound)
#pragma alloc_text(PAGE, MRxDAVInvalidateFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVInvalidateFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVCreateBasicFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVCreateBasicFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVUpdateFileInfoCacheStatus)
#pragma alloc_text(PAGE, MRxDAVCreateStandardFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVCreateStandardFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVUpdateFileInfoCacheFileSize)
#pragma alloc_text(PAGE, MRxDAVUpdateStandardFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVInvalidateFileNotFoundCache)
#pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCacheAll)
#pragma alloc_text(PAGE, MRxDAVInvalidateBasicFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVInvalidateBasicFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVUpdateBasicFileInfoCacheStatus)
#pragma alloc_text(PAGE, MRxDAVInvalidateStandardFileInfoCache)
#pragma alloc_text(PAGE, MRxDAVInvalidateStandardFileInfoCacheWithName)
#pragma alloc_text(PAGE, MRxDAVUpdateStandardFileInfoCacheStatus)
#endif
extern FAST_MUTEX MRxDAVFileInfoCacheLock; MRX_DAV_STATISTICS MRxDAVStatistics;
VOID MRxDAVCreateFileInfoCache( PRX_CONTEXT RxContext, PDAV_USERMODE_CREATE_RETURNED_FILEINFO FileInfo, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for both file basic and standard information.
Arguments:
RxContext - the RDBSS context FileInfo - the file information package including basic and standard information Status - the status returned from server response of query file information
Return Value:
none
--*/ { PAGED_CODE();
MRxDAVCreateBasicFileInfoCache(RxContext,&FileInfo->BasicInformation,Status); MRxDAVCreateStandardFileInfoCache(RxContext,&FileInfo->StandardInformation,Status); DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVCreateFileInfoCache %wZ\n",GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext))); }
VOID MRxDAVCreateFileInfoCacheWithName( PUNICODE_STRING FileName, PMRX_NET_ROOT NetRoot, PFILE_BASIC_INFORMATION Basic, PFILE_STANDARD_INFORMATION Standard, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for both file basic and standard information.
Arguments:
RxContext - the RDBSS context FileInfo - the file information package including basic and standard information Status - the status returned from server response of query file information
Return Value:
none
--*/ { PAGED_CODE();
MRxDAVCreateBasicFileInfoCacheWithName(FileName,NetRoot,Basic,Status); MRxDAVCreateStandardFileInfoCacheWithName(FileName,NetRoot,Standard,Status); DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVCreateFileInfoCacheWithName %wZ\n",FileName)); }
VOID MRxDAVCreateBasicFileInfoCache( PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION Basic, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for the file basic information.
Arguments:
RxContext - the RDBSS context Basic - the file basic information package Status - the status returned from server response of query file information
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot;
PAGED_CODE();
if (RxContext->MajorFunction == IRP_MJ_CREATE) { NetRoot = RxContext->Create.pNetRoot; } else { ASSERT(capFcb != NULL); NetRoot = capFcb->pNetRoot; }
MRxDAVCreateBasicFileInfoCacheWithName(OriginalFileName,NetRoot,Basic,Status); }
VOID MRxDAVCreateBasicFileInfoCacheWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot, PFILE_BASIC_INFORMATION Basic, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for the file basic information.
Arguments:
OriginalFileName - the name of the file to cache the basic information NetRoot - the Net Root that the file belongs to Basic - the file basic information package Status - the status returned from server response of query file information
Return Value:
none
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot; PNAME_CACHE_CONTROL NameCacheCtl; PFILE_BASIC_INFORMATION FileInfoCache = NULL;
PAGED_CODE();
DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache == NULL) { NameCache = RxNameCacheCreateEntry ( NameCacheCtl, OriginalFileName, TRUE); // case insensitive match
}
if (NameCache != NULL) { FileInfoCache = (PFILE_BASIC_INFORMATION)NameCache->ContextExtension;
*FileInfoCache = *Basic; NameCache->PriorStatus = Status;
if (FileInfoCache->FileAttributes & ~FILE_ATTRIBUTE_NORMAL) { FileInfoCache->FileAttributes &= ~FILE_ATTRIBUTE_NORMAL; }
RxNameCacheActivateEntry( NameCacheCtl, NameCache, FileInformationCacheLifeTimeInSec, MRxDAVStatistics.SmbsReceived.LowPart);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Create File Attrib cache : %x %wZ\n",Basic->FileAttributes,OriginalFileName)); DavDbgTrace(DAV_TRACE_INFOCACHE, (" Create File Attrib cache : %I64X %I64X %wZ\n",Basic->CreationTime,Basic->LastAccessTime,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVCreateStandardFileInfoCache( PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION Standard, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context Standard - the file standard information package Status - the status returned from server response of query file information
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PAGED_CODE(); MRxDAVCreateStandardFileInfoCacheWithName(OriginalFileName,NetRoot,Standard,Status); }
VOID MRxDAVCreateStandardFileInfoCacheWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot, PFILE_STANDARD_INFORMATION Standard, NTSTATUS Status ) /*++
Routine Description:
This routine creates name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context Standard - the file standard information package Status - the status returned from server response of query file information
Return Value:
none
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard; PFILE_STANDARD_INFORMATION FileInfoCache = NULL;
PAGED_CODE(); ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache == NULL) { NameCache = RxNameCacheCreateEntry ( NameCacheCtl, OriginalFileName, TRUE); // case insensitive match
}
if (NameCache != NULL) { FileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
*FileInfoCache = *Standard;
NameCache->PriorStatus = Status;
RxNameCacheActivateEntry( NameCacheCtl, NameCache, FileInformationCacheLifeTimeInSec, MRxDAVStatistics.SmbsReceived.LowPart);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Create Standard cache : %I64x %I64x %I64x %wZ\n", ((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile, Standard->AllocationSize, Standard->EndOfFile, OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVUpdateFileInfoCacheFromDelete( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine updates the status of the name cache entry as STATUS_OBJECT_NAME_NOT_FOUND for both file basic and standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { MRxDAVUpdateBasicFileInfoCacheStatus(RxContext,STATUS_OBJECT_NAME_NOT_FOUND); MRxDAVUpdateStandardFileInfoCacheStatus(RxContext,STATUS_OBJECT_NAME_NOT_FOUND); }
VOID MRxDAVUpdateFileInfoCacheStatus( PRX_CONTEXT RxContext, NTSTATUS Status ) /*++
Routine Description:
This routine updates the status of the name cache entry for both file basic and standard information.
Arguments:
RxContext - the RDBSS context Status - the status needs to be put on the cache
Return Value:
none
--*/ { MRxDAVUpdateBasicFileInfoCacheStatus(RxContext,Status); MRxDAVUpdateStandardFileInfoCacheStatus(RxContext,Status); }
VOID MRxDAVUpdateBasicFileInfoCacheStatus( PRX_CONTEXT RxContext, NTSTATUS Status ) /*++
Routine Description:
This routine updates the status of the name cache entry for the file basic information.
Arguments:
RxContext - the RDBSS context Status - the status needs to be put on the cache
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { NameCache->PriorStatus = Status; RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, ("Update status basic : %x %wZ\n",Status,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVUpdateStandardFileInfoCacheStatus( PRX_CONTEXT RxContext, NTSTATUS Status ) /*++
Routine Description:
This routine updates the status of the name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context Status - the status needs to be put on the cache
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { NameCache->PriorStatus = Status; RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVInvalidateFileInfoCache( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine invalidates the name cache entry for both file basic and standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { PAGED_CODE();
MRxDAVInvalidateBasicFileInfoCache(RxContext); MRxDAVInvalidateStandardFileInfoCache(RxContext); }
VOID MRxDAVInvalidateFileInfoCacheWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot ) /*++
Routine Description:
This routine invalidates the name cache entry for both file basic and standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { PAGED_CODE();
MRxDAVInvalidateBasicFileInfoCacheWithName(OriginalFileName,NetRoot); MRxDAVInvalidateStandardFileInfoCacheWithName(OriginalFileName,NetRoot); }
VOID MRxDAVInvalidateBasicFileInfoCache( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine invalidates the name cache entry for file basic information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PAGED_CODE();
MRxDAVInvalidateBasicFileInfoCacheWithName(OriginalFileName,NetRoot); }
VOID MRxDAVInvalidateBasicFileInfoCacheWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot ) /*++
Routine Description:
This routine invalidates the name cache entry for file basic information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { RxNameCacheExpireEntry(NameCacheCtl, NameCache);
DavDbgTrace(DAV_TRACE_INFOCACHE, ("Invalid Baisc cache : %wZ\n",OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVInvalidateStandardFileInfoCache( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine invalidates the name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PAGED_CODE();
MRxDAVInvalidateStandardFileInfoCacheWithName(OriginalFileName,NetRoot); }
VOID MRxDAVInvalidateStandardFileInfoCacheWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot ) /*++
Routine Description:
This routine invalidates the name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { RxNameCacheExpireEntry(NameCacheCtl, NameCache); DavDbgTrace(DAV_TRACE_INFOCACHE, ("Invalid Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVUpdateFileInfoCacheFileSize( PRX_CONTEXT RxContext, PLARGE_INTEGER FileSize ) /*++
Routine Description:
This routine updates file size on the name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard; PFILE_STANDARD_INFORMATION FileInfoCache = NULL;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { FileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
FileInfoCache->AllocationSize.QuadPart = FileSize->QuadPart; FileInfoCache->EndOfFile.QuadPart = FileSize->QuadPart;
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, ("Update File size cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVUpdateBasicFileInfoCache( PRX_CONTEXT RxContext, ULONG FileAttributes, PLARGE_INTEGER pLastWriteTime ) /*++
Routine Description:
This routine updates file attributs and last write time on the name cache entry for the file basic information.
Arguments:
RxContext - the RDBSS context FileAttributes - new file attributes pLastWriteTime - address of file last write time
Return Value:
none
--*/ { FILE_BASIC_INFORMATION Basic;
Basic.ChangeTime.QuadPart = 0; Basic.CreationTime.QuadPart = 0; Basic.LastWriteTime.QuadPart = 0; Basic.LastAccessTime.QuadPart = 0;
if (pLastWriteTime != NULL && pLastWriteTime->QuadPart != 0) { Basic.LastWriteTime = *pLastWriteTime; }
Basic.FileAttributes = FileAttributes;
MRxDAVUpdateBasicFileInfoCacheAll(RxContext,&Basic); }
VOID MRxDAVUpdateBasicFileInfoCacheAll( PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION Basic ) /*++
Routine Description:
This routine updates the name cache entry for the file basic information.
Arguments:
RxContext - the RDBSS context Basic - file basic information
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic; PFILE_BASIC_INFORMATION BasicFileInfoCache = NULL;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { BasicFileInfoCache = (PFILE_BASIC_INFORMATION)NameCache->ContextExtension;
if (Basic->CreationTime.QuadPart != 0) { BasicFileInfoCache->CreationTime = Basic->CreationTime; }
if (Basic->LastAccessTime.QuadPart != 0) { BasicFileInfoCache->LastAccessTime = Basic->LastAccessTime; }
if (Basic->LastWriteTime.QuadPart != 0) { BasicFileInfoCache->LastWriteTime = Basic->LastWriteTime; }
DavDbgTrace(DAV_TRACE_INFOCACHE, ("Update File Attrib cache 2: %x %wZ\n",BasicFileInfoCache->FileAttributes,OriginalFileName));
BasicFileInfoCache->FileAttributes = Basic->FileAttributes;
if (BasicFileInfoCache->FileAttributes & ~FILE_ATTRIBUTE_NORMAL) { BasicFileInfoCache->FileAttributes &= ~FILE_ATTRIBUTE_NORMAL; }
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, ("Update File Attrib cache 3: %x %wZ\n",BasicFileInfoCache->FileAttributes,OriginalFileName)); DavDbgTrace(DAV_TRACE_INFOCACHE, ("Update File Attrib cache : %I64X %I64X %wZ\n",BasicFileInfoCache->CreationTime,BasicFileInfoCache->LastAccessTime,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVUpdateStandardFileInfoCache( PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION Standard, BOOLEAN IsDirectory ) /*++
Routine Description:
This routine updates the name cache entry for the file standard information.
Arguments:
RxContext - the RDBSS context Standard - file standard information IsDirectory - file is a directory
Return Value:
none
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard; PFILE_STANDARD_INFORMATION StandardFileInfoCache = NULL;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { StandardFileInfoCache = (PFILE_STANDARD_INFORMATION)NameCache->ContextExtension;
if (Standard != NULL) { *StandardFileInfoCache = *Standard; } else { StandardFileInfoCache->Directory = IsDirectory; }
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Update Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
BOOLEAN MRxDAVIsFileInfoCacheFound( PRX_CONTEXT RxContext, PDAV_USERMODE_CREATE_RETURNED_FILEINFO FileInfo, NTSTATUS *Status, PUNICODE_STRING OriginalFileName ) /*++
Routine Description:
This routine looks for the name cache entry of both file basic and standard information.
Arguments:
RxContext - the RDBSS context FileInfo - buffer to return file basic and standard information Status - status retured on the last reponse from server
Return Value:
BOOLEAN - name cache found
--*/ { BOOLEAN CacheFound = FALSE;
if (MRxDAVIsBasicFileInfoCacheFound(RxContext,&FileInfo->BasicInformation,Status,OriginalFileName)) { if (*Status == STATUS_SUCCESS) { if (MRxDAVIsStandardFileInfoCacheFound(RxContext,&FileInfo->StandardInformation,Status,OriginalFileName)) { CacheFound = TRUE; } } else {
// if an error stored on the file basic information cache, return cache found
CacheFound = TRUE; } } DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVIsFileInfoCacheFound %x %x %wZ\n",*Status,CacheFound,GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext)));
return CacheFound; }
BOOLEAN MRxDAVIsBasicFileInfoCacheFound( PRX_CONTEXT RxContext, PFILE_BASIC_INFORMATION Basic, NTSTATUS *Status, PUNICODE_STRING OriginalFileName ) /*++
Routine Description:
This routine looks for the name cache entry of the file basic information.
Arguments:
RxContext - the RDBSS context Basic - buffer to return file basic information Status - status retured on the last reponse from server
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb;
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot; PWEBDAV_NET_ROOT DavNetRoot; PNAME_CACHE_CONTROL NameCacheCtl; RX_NC_CHECK_STATUS NameCacheStatus;
BOOLEAN CacheFound = FALSE; BOOLEAN RootFound = FALSE; ULONG RootAttributes = 0; NTSTATUS RootStatus = STATUS_SUCCESS;
PAGED_CODE();
if (OriginalFileName == NULL) { OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); }
if (RxContext->MajorFunction == IRP_MJ_CREATE) { NetRoot = RxContext->Create.pNetRoot; } else { ASSERT(capFcb != NULL); NetRoot = capFcb->pNetRoot; }
DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; NameCacheCtl = &DavNetRoot->NameCacheCtlGFABasic; ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { //
// Found it. Now check entry for not expired.
// Note - The NameCache entry has been pulled off the active list.
//
NameCacheStatus = RxNameCacheCheckEntry( NameCache, NameCache->Context);
if (NameCacheStatus == RX_NC_SUCCESS && (!RootFound || *Status == RootStatus)) {
// The name cache matches if it is not expired and the attributes matches the one of
// the root file if it is a stream file. If this is a match, return the old status,
// file info and reactivate the entry but leave expiration time unchanged.
*Status = NameCache->PriorStatus; RxNameCacheOpSaved(NameCacheCtl);
*Basic = *((PFILE_BASIC_INFORMATION)NameCache->ContextExtension);
CacheFound = TRUE;
// put the entry back to the active list without changing the expire time
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Found Basic cache : %x %wZ\n",Basic->FileAttributes,OriginalFileName)); DavDbgTrace(DAV_TRACE_INFOCACHE, (" Get File Attrib cache : %I64X %I64X %wZ\n",Basic->CreationTime,Basic->LastAccessTime,OriginalFileName)); } else { // put the entry back to the expire list
RxNameCacheExpireEntry(NameCacheCtl, NameCache); } } else { DavDbgTrace(DAV_TRACE_INFOCACHE, (" No Basic cache : %wZ\n",OriginalFileName)); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
return CacheFound; }
BOOLEAN MRxDAVIsStandardFileInfoCacheFound( PRX_CONTEXT RxContext, PFILE_STANDARD_INFORMATION Standard, NTSTATUS *Status, PUNICODE_STRING OriginalFileName ) /*++
Routine Description:
This routine looks for the name cache entry of the file standard information.
Arguments:
RxContext - the RDBSS context Standard - buffer to return file standard information Status - status retured on the last reponse from server
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; RxCaptureFobx;
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlGFAStandard; RX_NC_CHECK_STATUS NameCacheStatus;
BOOLEAN CacheFound = FALSE; BOOLEAN RootFound = FALSE; NTSTATUS RootStatus = STATUS_SUCCESS;
PAGED_CODE();
if (OriginalFileName == NULL) { OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); } ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { //
// Found it. Now check entry for not expired.
// Note - The NameCache entry has been pulled off the active list.
//
NameCacheStatus = RxNameCacheCheckEntry( NameCache, NameCache->Context);
if (NameCacheStatus == RX_NC_SUCCESS && (!RootFound || *Status == RootStatus)) {
// The name cache matches if it is not expired and the status matches the one of
// the root file if it is a stream file. If this is a match, return the old status,
// file info and reactivate the entry but leave expiration time unchanged.
*Status = NameCache->PriorStatus; RxNameCacheOpSaved(NameCacheCtl);
*Standard = *((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension);
CacheFound = TRUE;
// put the entry back to the active list without changing the expire time
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Get Standard cache : %I64x %wZ\n",((PFILE_STANDARD_INFORMATION)NameCache->ContextExtension)->EndOfFile,OriginalFileName)); } else { // put the entry back to the expire list
RxNameCacheExpireEntry(NameCacheCtl, NameCache); } }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
return CacheFound; }
NTSTATUS MRxDAVGetFileInfoCacheStatus( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine looks for the status of the name cache entry of either file basic or standard information.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - statu of the name cache if found, otherwise, STATUS_SUCCESS
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtlBasic = &DavNetRoot->NameCacheCtlGFABasic; PNAME_CACHE_CONTROL NameCacheCtlStandard = &DavNetRoot->NameCacheCtlGFAStandard; NTSTATUS Status = STATUS_MORE_PROCESSING_REQUIRED;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtlBasic,OriginalFileName);
if (NameCache != NULL) { RX_NC_CHECK_STATUS NameCacheStatus; //
// Found it. Now check entry for not expired
//
NameCacheStatus = RxNameCacheCheckEntry(NameCache,NameCache->Context);
if (NameCacheStatus == RX_NC_SUCCESS) { //
// If the cache has not expired, return the previous status.
//
Status = NameCache->PriorStatus; RxNameCacheOpSaved(NameCacheCtlBasic);
// put the entry back to the active list without changing the expire time
RxNameCacheActivateEntry(NameCacheCtlBasic, NameCache, 0, 0);
DavDbgTrace(DAV_TRACE_INFOCACHE, (" Get Basic Status : %x %wZ\n",Status,OriginalFileName)); } else { // put the entry back to the expire list
RxNameCacheExpireEntry(NameCacheCtlBasic, NameCache); } } else { NameCache = RxNameCacheFetchEntry(NameCacheCtlStandard,OriginalFileName);
if (NameCache != NULL) { RX_NC_CHECK_STATUS NameCacheStatus; //
// Found it. Now check entry for not expired
//
NameCacheStatus = RxNameCacheCheckEntry(NameCache,NameCache->Context);
if (NameCacheStatus == RX_NC_SUCCESS) { //
// If the cache has not expired, return the previous status.
//
Status = NameCache->PriorStatus; RxNameCacheOpSaved(NameCacheCtlStandard);
// put the entry back to the active list without changing the expire time
RxNameCacheActivateEntry(NameCacheCtlStandard, NameCache, 0, 0); } else { // put the entry back to the expire list
RxNameCacheExpireEntry(NameCacheCtlStandard, NameCache); } } }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
return Status; }
BOOLEAN MRxDAVIsFileNotFoundCached( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine checks if the name cache entry exists as File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PAGED_CODE();
return MRxDAVIsFileNotFoundCachedWithName(OriginalFileName,NetRoot); }
BOOLEAN MRxDAVIsFileNotFoundCachedWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot ) /*++
Routine Description:
This routine checks if the name cache entry exists as File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
BOOLEAN CacheFound = FALSE;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { RX_NC_CHECK_STATUS NameCacheStatus; //
// Found it. Now check entry for not expired.
// Note - The NameCache entry has been pulled off the active list.
//
NameCacheStatus = RxNameCacheCheckEntry( NameCache, //MRxDAVStatistics.SmbsReceived.LowPart
NameCache->Context);
if ((NameCacheStatus == RX_NC_SUCCESS) && (NameCache->PriorStatus == STATUS_OBJECT_NAME_NOT_FOUND)) { //
// This is a match. Return the old status, file info and
// reactivate the entry but leave expiration time unchanged.
//
CacheFound = TRUE; DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVIsFileNotFoundCached %wZ\n",OriginalFileName));
// put the entry back to the active list without changing the expire time
RxNameCacheActivateEntry(NameCacheCtl, NameCache, 0, 0); } else { // put the entry back to the expire list
RxNameCacheExpireEntry(NameCacheCtl, NameCache); } }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock);
return CacheFound; }
VOID MRxDAVCacheFileNotFound( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine creates the name cache entry for File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PAGED_CODE();
MRxDAVCacheFileNotFoundWithName(OriginalFileName,NetRoot); }
VOID MRxDAVCacheFileNotFoundWithName( PUNICODE_STRING OriginalFileName, PMRX_NET_ROOT NetRoot ) /*++
Routine Description:
This routine creates the name cache entry for File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { PNAME_CACHE NameCache = NULL; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND; RxNameCacheActivateEntry( NameCacheCtl, NameCache, FileNotFoundCacheLifeTimeInSec, MRxDAVStatistics.SmbsReceived.LowPart); } else { NameCache = RxNameCacheCreateEntry ( NameCacheCtl, OriginalFileName, TRUE); // case insensitive match
if (NameCache != NULL) { NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND; RxNameCacheActivateEntry( NameCacheCtl, NameCache, FileNotFoundCacheLifeTimeInSec, MRxDAVStatistics.SmbsReceived.LowPart); } }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVCacheFileNotFound %wZ\n",OriginalFileName)); }
VOID MRxDAVCacheFileNotFoundFromQueryDirectory( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine creates the name cache entry for File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; RxCaptureFobx; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext); PUNICODE_STRING Template = &capFobx->UnicodeQueryTemplate; UNICODE_STRING FileName;
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,&FileName);
if (NameCache != NULL) { if ((NameCache == NULL) && (OriginalFileName->Length > sizeof(WCHAR))) { //
// Do lookup now since we may have skipped it at entry.
//
NameCache = RxNameCacheFetchEntry(NameCacheCtl,&FileName); if (NameCache == NULL) { NameCache = RxNameCacheCreateEntry ( NameCacheCtl, OriginalFileName, TRUE); // case insensitive match
} } if (NameCache != NULL) { NameCache->PriorStatus = STATUS_OBJECT_NAME_NOT_FOUND; RxNameCacheActivateEntry( NameCacheCtl, NameCache, FileNotFoundCacheLifeTimeInSec, MRxDAVStatistics.SmbsReceived.LowPart); } }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
VOID MRxDAVInvalidateFileNotFoundCache( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine invalidates the name cache entry as File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; PUNICODE_STRING OriginalFileName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,OriginalFileName);
if (NameCache != NULL) { RxNameCacheExpireEntry(NameCacheCtl, NameCache); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); DavDbgTrace(DAV_TRACE_INFOCACHE, ("MRxDAVInvalidateFileNotFoundCache %wZ\n",OriginalFileName)); }
VOID MRxDAVInvalidateFileNotFoundCacheForRename( PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine invalidates the name cache entry as File Not Found.
Arguments:
RxContext - the RDBSS context
Return Value:
BOOLEAN - name cache found
--*/ { RxCaptureFcb; UNICODE_STRING RenameName;
PNAME_CACHE NameCache = NULL; PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PWEBDAV_NET_ROOT DavNetRoot = (PWEBDAV_NET_ROOT)NetRoot->Context; PNAME_CACHE_CONTROL NameCacheCtl = &DavNetRoot->NameCacheCtlFNF;
PFILE_RENAME_INFORMATION RenameInformation = RxContext->Info.Buffer;
RenameName.Buffer = &RenameInformation->FileName[0]; RenameName.Length = (USHORT)RenameInformation->FileNameLength;
DavDbgTrace(DAV_TRACE_DETAIL, ("Invalidate FNF cache from rename %wZ\n", &RenameName));
PAGED_CODE();
ExAcquireFastMutex(&MRxDAVFileInfoCacheLock);
NameCache = RxNameCacheFetchEntry(NameCacheCtl,&RenameName);
if (NameCache != NULL) { RxNameCacheExpireEntry(NameCacheCtl, NameCache); }
ExReleaseFastMutex(&MRxDAVFileInfoCacheLock); }
|