📄 openclos.c
字号:
/*++
Copyright (c) 1989 - 1999 Microsoft Corporation
Module Name:
openclos.c
Abstract:
This module implements the mini redirector call down routines pertaining to opening/
closing of file/directories.
--*/
#include "precomp.h"
#pragma hdrstop
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, MRxSmbMungeBufferingIfWriteOnlyHandles)
#pragma alloc_text(PAGE, IsReconnectRequired)
#pragma alloc_text(PAGE, MRxSmbIsCreateWithEasSidsOrLongName)
#pragma alloc_text(PAGE, MRxSmbShouldTryToCollapseThisOpen)
#pragma alloc_text(PAGE, MRxSmbCreate)
#pragma alloc_text(PAGE, MRxSmbDeferredCreate)
#pragma alloc_text(PAGE, MRxSmbCollapseOpen)
#pragma alloc_text(PAGE, MRxSmbComputeNewBufferingState)
#pragma alloc_text(PAGE, MRxSmbConstructDeferredOpenContext)
#pragma alloc_text(PAGE, MRxSmbAdjustCreateParameters)
#pragma alloc_text(PAGE, MRxSmbAdjustReturnedCreateAction)
#pragma alloc_text(PAGE, MRxSmbBuildNtCreateAndX)
#pragma alloc_text(PAGE, MRxSmbBuildOpenAndX)
#pragma alloc_text(PAGE, SmbPseExchangeStart_Create)
#pragma alloc_text(PAGE, MRxSmbSetSrvOpenFlags)
#pragma alloc_text(PAGE, MRxSmbCreateFileSuccessTail)
#pragma alloc_text(PAGE, MRxSmbFinishNTCreateAndX)
#pragma alloc_text(PAGE, MRxSmbFinishOpenAndX)
#pragma alloc_text(PAGE, MRxSmbFinishT2OpenFile)
#pragma alloc_text(PAGE, MRxSmbT2OpenFile)
#pragma alloc_text(PAGE, MRxSmbFinishLongNameCreateFile)
#pragma alloc_text(PAGE, MRxSmbCreateWithEasSidsOrLongName)
#pragma alloc_text(PAGE, MRxSmbZeroExtend)
#pragma alloc_text(PAGE, MRxSmbTruncate)
#pragma alloc_text(PAGE, MRxSmbCleanupFobx)
#pragma alloc_text(PAGE, MRxSmbForcedClose)
#pragma alloc_text(PAGE, MRxSmbCloseSrvOpen)
#pragma alloc_text(PAGE, MRxSmbBuildClose)
#pragma alloc_text(PAGE, MRxSmbBuildFindClose)
#pragma alloc_text(PAGE, SmbPseExchangeStart_Close)
#pragma alloc_text(PAGE, MRxSmbFinishClose)
#endif
//
// The debug trace level
//
#define Dbg (DEBUG_TRACE_CREATE)
// forwards
NTSTATUS
SmbPseExchangeStart_Create(
SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE
);
NTSTATUS
SmbPseExchangeStart_Close(
SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE
);
NTSTATUS
MRxSmbCreateWithEasSidsOrLongName(
IN OUT PRX_CONTEXT RxContext
);
NTSTATUS
MRxSmbDownlevelCreate(
SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE
);
ULONG MRxSmbInitialSrvOpenFlags = 0;
BOOLEAN MRxSmbDeferredOpensEnabled = TRUE; //this is regedit-able
BOOLEAN MRxSmbOplocksDisabled = FALSE; //this is regedit-able
extern LIST_ENTRY MRxSmbPagingFilesSrvOpenList;
#ifndef FORCE_NO_NTCREATE
#define MRxSmbForceNoNtCreate FALSE
#else
BOOLEAN MRxSmbForceNoNtCreate = TRUE;
#endif
#ifdef RX_PRIVATE_BUILD
//#define FORCE_SMALL_BUFFERS
#endif //#ifdef RX_PRIVATE_BUILD
#ifndef FORCE_SMALL_BUFFERS
//use size calculated from the negotiated size
ULONG MrxSmbLongestShortName = 0xffff;
//use the negotiated size
ULONG MrxSmbCreateTransactPacketSize = 0xffff;
#else
ULONG MrxSmbLongestShortName = 0;
ULONG MrxSmbCreateTransactPacketSize = 100;
#endif
LONG MRxSmbNumberOfSrvOpens = 0;
INLINE VOID
MRxSmbIncrementSrvOpenCount(
PSMBCEDB_SERVER_ENTRY pServerEntry,
PMRX_SRV_OPEN SrvOpen)
{
LONG NumberOfSrvOpens;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
if (!FlagOn(smbSrvOpen->FileInfo.Basic.FileAttributes,
FILE_ATTRIBUTE_DIRECTORY)) {
ASSERT(!smbSrvOpen->NumOfSrvOpenAdded);
smbSrvOpen->NumOfSrvOpenAdded = TRUE;
InterlockedIncrement(&pServerEntry->Server.NumberOfSrvOpens);
NumberOfSrvOpens = InterlockedIncrement(&MRxSmbNumberOfSrvOpens);
if (NumberOfSrvOpens == 1) {
PoRegisterSystemState(
MRxSmbPoRegistrationState,
(ES_SYSTEM_REQUIRED | ES_CONTINUOUS));
}
}
}
VOID
MRxSmbDecrementSrvOpenCount(
PSMBCEDB_SERVER_ENTRY pServerEntry,
LONG SrvOpenServerVersion,
PMRX_SRV_OPEN SrvOpen)
{
LONG NumberOfSrvOpens;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
if (!FlagOn(smbSrvOpen->FileInfo.Basic.FileAttributes,
FILE_ATTRIBUTE_DIRECTORY)) {
ASSERT(smbSrvOpen->NumOfSrvOpenAdded);
smbSrvOpen->NumOfSrvOpenAdded = FALSE;
if (SrvOpenServerVersion == (LONG)pServerEntry->Server.Version) {
ASSERT(pServerEntry->Server.NumberOfSrvOpens > 0);
InterlockedDecrement(&pServerEntry->Server.NumberOfSrvOpens);
}
NumberOfSrvOpens = InterlockedDecrement(&MRxSmbNumberOfSrvOpens);
if (NumberOfSrvOpens == 0) {
PoRegisterSystemState(
MRxSmbPoRegistrationState,
ES_CONTINUOUS);
}
}
}
INLINE VOID
MRxSmbMungeBufferingIfWriteOnlyHandles (
ULONG WriteOnlySrvOpenCount,
PMRX_SRV_OPEN SrvOpen
)
/*++
Routine Description:
This routine modifies the buffering flags on a srvopen so that
no cacheing will be allowed if there are any write-only handles
to the file.
Arguments:
WriteOnlySrvOpenCount - the number of writeonly srvopens
SrvOpen - the srvopen whose buffring flags are to be munged
Return Value:
RXSTATUS - The return status for the operation
--*/
{
BOOLEAN IsLoopBack = FALSE;
PMRX_SRV_CALL pSrvCall;
PSMBCEDB_SERVER_ENTRY pServerEntry;
PAGED_CODE();
pSrvCall = SrvOpen->pVNetRoot->pNetRoot->pSrvCall;
pServerEntry = SmbCeGetAssociatedServerEntry(pSrvCall);
IsLoopBack = pServerEntry->Server.IsLoopBack;
if (IsLoopBack || (WriteOnlySrvOpenCount != 0)) {
SrvOpen->BufferingFlags &=
~( FCB_STATE_WRITECACHING_ENABLED |
FCB_STATE_FILESIZECACHEING_ENABLED |
FCB_STATE_FILETIMECACHEING_ENABLED |
FCB_STATE_LOCK_BUFFERING_ENABLED |
FCB_STATE_READCACHING_ENABLED |
FCB_STATE_COLLAPSING_ENABLED
);
}
}
INLINE BOOLEAN
IsReconnectRequired(
PMRX_SRV_CALL SrvCall)
/*++
Routine Description:
This routine determines if a reconnect is required to a given server
Arguments:
SrvCall - the SRV_CALL instance
Return Value:
TRUE if a reconnect is required
--*/
{
BOOLEAN ReconnectRequired = FALSE;
PSMBCEDB_SERVER_ENTRY pServerEntry;
PAGED_CODE();
pServerEntry = SmbCeGetAssociatedServerEntry(SrvCall);
if (pServerEntry != NULL) {
ReconnectRequired = (pServerEntry->Header.State != SMBCEDB_ACTIVE);
}
return ReconnectRequired;
}
BOOLEAN
MRxSmbIsCreateWithEasSidsOrLongName(
IN OUT PRX_CONTEXT RxContext,
OUT PULONG DialectFlags
)
/*++
Routine Description:
This routine determines if the create operation involves EA's or security
desriptors. In such cases a separate protocol is required
Arguments:
RxContext - the RX_CONTEXT instance
DialectFlags - the dialect flags associated with the server
Return Value:
TRUE if a reconnect is required
--*/
{
RxCaptureFcb;
ULONG LongestShortName,LongestShortNameFromSrvBufSize;
PMRX_SRV_CALL SrvCall = (PMRX_SRV_CALL)RxContext->Create.pSrvCall;
PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);
PSMBCEDB_SERVER_ENTRY pServerEntry;
PAGED_CODE();
pServerEntry = SmbCeGetAssociatedServerEntry(SrvCall);
ASSERT(pServerEntry != NULL);
*DialectFlags = pServerEntry->Server.DialectFlags;
// DOWN.LEVEL if the server takes OEM names or we use a different protocol
// this would have to be different. maybe a switch or a precompute.
LongestShortNameFromSrvBufSize =
MAXIMUM_SMB_BUFFER_SIZE -
QuadAlign(sizeof(NT_SMB_HEADER) +
FIELD_OFFSET(REQ_NT_CREATE_ANDX,Buffer[0])
);
LongestShortName = min(MrxSmbLongestShortName,LongestShortNameFromSrvBufSize);
return (RxContext->Create.EaLength ||
RxContext->Create.SdLength ||
RemainingName->Length > LongestShortName);
}
NTSTATUS
MRxSmbShouldTryToCollapseThisOpen (
IN PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine determines if the mini knows of a good reason not
to try collapsing on this open.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
SUCCESS --> okay to try collapse
other (MORE_PROCESSING_REQUIRED) --> dont collapse
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
RxCaptureFcb;
PAGED_CODE();
if (SrvOpen)
{
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
PSMBCEDB_SERVER_ENTRY pServerEntry = (PSMBCEDB_SERVER_ENTRY)(RxContext->Create.pSrvCall->Context);
if (smbSrvOpen->Version != pServerEntry->Server.Version)
{
return STATUS_MORE_PROCESSING_REQUIRED;
}
}
return Status;
}
NTSTATUS
MRxSmbCreate (
IN OUT PRX_CONTEXT RxContext
)
/*++
Routine Description:
This routine opens a file across the network
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
--*/
{
NTSTATUS Status;
RxCaptureFcb;
PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
PMRX_SRV_CALL SrvCall = RxContext->Create.pSrvCall;
PSMBCEDB_SERVER_ENTRY pServerEntry = (PSMBCEDB_SERVER_ENTRY)SrvCall->Context;
PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;
PSMBCEDB_NET_ROOT_ENTRY pNetRootEntry;
PMRX_V_NET_ROOT pVNetRoot = SrvOpen->pVNetRoot;
PSMBCE_V_NET_ROOT_CONTEXT pVNetRootContext;
PSMBCEDB_SESSION_ENTRY pSessionEntry ;
PSMB_PSE_ORDINARY_EXCHANGE OrdinaryExchange = NULL;
BOOLEAN ReconnectRequired;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -