⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 openclos.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

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 + -