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

📄 openclos.c

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

    RX_BLOCK_CONDITION FinalSrvOpenCondition;

    PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
    PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
    PMRX_SRV_CALL SrvCall = RxContext->Create.pSrvCall;
    PMRX_NET_ROOT NetRoot = capFcb->pNetRoot;

    PAGED_CODE();

    RxContext->pFobx = (PMRX_FOBX)RxCreateNetFobx( RxContext, SrvOpen);

    if (RxContext->pFobx != NULL) {
       ASSERT  ( RxIsFcbAcquiredExclusive ( capFcb )  );
       RxContext->pFobx->OffsetOfNextEaToReturn = 1;
       Status = STATUS_SUCCESS;
    } else {
       Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    return Status;
}

NTSTATUS
MRxSmbComputeNewBufferingState(
   IN OUT PMRX_SRV_OPEN   pMRxSrvOpen,
   IN     PVOID           pMRxContext,
      OUT PULONG          pNewBufferingState)
/*++

Routine Description:

   This routine maps the SMB specific oplock levels into the appropriate RDBSS
   buffering state flags

Arguments:

   pMRxSrvOpen - the MRX SRV_OPEN extension

   pMRxContext - the context passed to RDBSS at Oplock indication time

   pNewBufferingState - the place holder for the new buffering state

Return Value:


Notes:

--*/
{
    ULONG OplockLevel,NewBufferingState;

    PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(pMRxSrvOpen);
    PMRX_SMB_FCB      smbFcb     = MRxSmbGetFcbExtension(pMRxSrvOpen->pFcb);

    PAGED_CODE();

    ASSERT(pNewBufferingState != NULL);

    OplockLevel = PtrToUlong(pMRxContext);

    if (OplockLevel == SMB_OPLOCK_LEVEL_II) {
        NewBufferingState = (FCB_STATE_READBUFFERING_ENABLED  |
                             FCB_STATE_READCACHING_ENABLED);
    } else {
        NewBufferingState = 0;
    }

    pMRxSrvOpen->BufferingFlags = NewBufferingState;

    MRxSmbMungeBufferingIfWriteOnlyHandles(
        smbFcb->WriteOnlySrvOpenCount,
        pMRxSrvOpen);

    *pNewBufferingState = pMRxSrvOpen->BufferingFlags;

    return STATUS_SUCCESS;
}

NTSTATUS
MRxSmbConstructDeferredOpenContext (
    PRX_CONTEXT RxContext)
/*++

Routine Description:

    This routine saves enough state that we can come back later and really do an
    open if needed. We only do this for NT servers.

Arguments:

    OrdinaryExchange - the exchange instance

Return Value:

    NTSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    RxCaptureFobx;

    PMRX_SRV_OPEN         SrvOpen = RxContext->pRelevantSrvOpen;
    PMRX_SMB_SRV_OPEN     smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
    PSMBCEDB_SERVER_ENTRY pServerEntry = (PSMBCEDB_SERVER_ENTRY)RxContext->Create.pSrvCall->Context;
    PSMBCE_SERVER         pServer = &pServerEntry->Server;

    PMRX_SMB_DEFERRED_OPEN_CONTEXT DeferredOpenContext;
    PDFS_NAME_CONTEXT   pDNC=NULL;
    DWORD       cbSize;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbConstructDeferredOpenContext\n"));

    ASSERT(smbSrvOpen->DeferredOpenContext == NULL);

    cbSize = sizeof(MRX_SMB_DEFERRED_OPEN_CONTEXT);

    // if there is a dfs name context, we need to allocate memory
    // fot aht too, because the name that is included in the
    // context is deallocated by DFS when it returns from the create call

    if(pDNC = RxContext->Create.NtCreateParameters.DfsNameContext)
    {
        cbSize += (sizeof(DFS_NAME_CONTEXT)+pDNC->UNCFileName.MaximumLength+sizeof(DWORD));
    }

    DeferredOpenContext = RxAllocatePoolWithTag(
                              NonPagedPool,
                              cbSize,
                              MRXSMB_DEFROPEN_POOLTAG);

    if (DeferredOpenContext == NULL) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto FINALLY;
    }

    smbSrvOpen->DeferredOpenContext = DeferredOpenContext;
    DeferredOpenContext->NtCreateParameters = RxContext->Create.NtCreateParameters;
    DeferredOpenContext->RxContextCreateFlags = RxContext->Create.Flags;
    DeferredOpenContext->RxContextFlags = RxContext->Flags;
    DeferredOpenContext->NtCreateParameters.SecurityContext = NULL;
    MRxSmbAdjustCreateParameters(RxContext, &DeferredOpenContext->SmbCp);

    SetFlag(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_DEFERRED_OPEN);
    if (pDNC)
    {
        PDFS_NAME_CONTEXT   pDNCDeferred=NULL;

        // point the dfs name context after the rxcontext

        pDNCDeferred = (PDFS_NAME_CONTEXT)((PBYTE)DeferredOpenContext+sizeof(MRX_SMB_DEFERRED_OPEN_CONTEXT));
        DeferredOpenContext->NtCreateParameters.DfsNameContext = pDNCDeferred;

        // copy the info
        *pDNCDeferred = *pDNC;

        if (pDNC->UNCFileName.Length)
        {
            ASSERT(pDNC->UNCFileName.Buffer);

            // point the name buffer after deferredcontext+dfs_name_context

            pDNCDeferred->UNCFileName.Buffer = (PWCHAR)((PBYTE)pDNCDeferred+sizeof(DFS_NAME_CONTEXT));

            memcpy(pDNCDeferred->UNCFileName.Buffer,
                   pDNC->UNCFileName.Buffer,
                   pDNC->UNCFileName.Length);

        }

    }


 FINALLY:
    RxDbgTrace(-1, Dbg, ("MRxSmbConstructDeferredOpenContext, Status=%08lx\n",Status));
    return Status;
}

VOID
MRxSmbAdjustCreateParameters (
    PRX_CONTEXT RxContext,
    PMRXSMB_CREATE_PARAMETERS smbcp
    )
/*++

Routine Description:

   This uses the RxContext as a base to reeach out and get the values of the NT
   create parameters. It also (a) implements the SMB idea that unbuffered is
   translated to write-through and (b) gets the SMB security flags.

Arguments:


Return Value:


Notes:

--*/
{
    PNT_CREATE_PARAMETERS cp = &RxContext->Create.NtCreateParameters;

    PAGED_CODE();
    RxDbgTrace(+1, Dbg, ("MRxSmbAdjustCreateParameters\n"));

    if (!FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_MINIRDR_INITIATED)) {
        cp->CreateOptions = cp->CreateOptions & ~(FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT);

        //the NT SMB spec says we have to change no-intermediate-buffering to write-through
        if (FlagOn(cp->CreateOptions,FILE_NO_INTERMEDIATE_BUFFERING)) {
            ASSERT (RxContext->CurrentIrpSp!=NULL);
            if (RxContext->CurrentIrpSp!=NULL) {
                PFILE_OBJECT capFileObject = RxContext->CurrentIrpSp->FileObject;
                ClearFlag(cp->CreateOptions,FILE_NO_INTERMEDIATE_BUFFERING);
                SetFlag(cp->CreateOptions,FILE_WRITE_THROUGH);
                SetFlag(RxContext->Flags,RX_CONTEXT_FLAG_WRITE_THROUGH);
                SetFlag(capFileObject->Flags,FO_WRITE_THROUGH);
            }
        }

        smbcp->Pid = RxGetRequestorProcessId(RxContext);
        smbcp->SecurityFlags = 0;
        if (cp->SecurityContext != NULL) {
            if (cp->SecurityContext->SecurityQos != NULL) {
                if (cp->SecurityContext->SecurityQos->ContextTrackingMode == SECURITY_DYNAMIC_TRACKING) {
                    smbcp->SecurityFlags |= SMB_SECURITY_DYNAMIC_TRACKING;
                }
                if (cp->SecurityContext->SecurityQos->EffectiveOnly) {
                    smbcp->SecurityFlags |= SMB_SECURITY_EFFECTIVE_ONLY;
                }
            }
        }

    } else {

        //here, we have a defered open!!!

        PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
        PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);

        //the parameters have already been adjusted...BUT null the security context.......
        cp->SecurityContext = NULL;
        *smbcp = smbSrvOpen->DeferredOpenContext->SmbCp;
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbAdjustCreateParameters\n"));
}

INLINE VOID
MRxSmbAdjustReturnedCreateAction(
    IN OUT PRX_CONTEXT RxContext
    )
/*++

Routine Description:

   This routine repairs a bug in NT servers whereby the create action is
   contaminated by an oplock break. Basically, we make sure that if the guy
   asked for FILE_OPEN and it works then he does not get FILE_SUPERCEDED or
   FILE_CREATED as the result.

Arguments:

    RxContext - the context for the operation so as to find the place where
                info is returned

Return Value:

    none

Notes:

--*/
{
    ULONG q = RxContext->Create.ReturnedCreateInformation;

    PAGED_CODE();

    if ((q==FILE_SUPERSEDED)||(q==FILE_CREATED)||(q >FILE_MAXIMUM_DISPOSITION)) {
        RxContext->Create.ReturnedCreateInformation = FILE_OPENED;
    }
}

UNICODE_STRING UnicodeBackslash = {2,4,L"\\"};

NTSTATUS
MRxSmbBuildNtCreateAndX (
    PSMBSTUFFER_BUFFER_STATE StufferState,
    PMRXSMB_CREATE_PARAMETERS smbcp
    )
/*++

Routine Description:

   This builds an NtCreateAndX SMB. we don't have to worry about login id and such
   since that is done by the connection engine....pretty neat huh? all we have to do
   is to format up the bits

Arguments:

   StufferState - the state of the smbbuffer from the stuffer's point of view

Return Value:

   NTSTATUS
      SUCCESS
      NOT_IMPLEMENTED  something has appeared in the arguments that i can't handle

Notes:

--*/
{
    NTSTATUS Status;

    PRX_CONTEXT RxContext = StufferState->RxContext;
    PNT_CREATE_PARAMETERS cp = &RxContext->Create.NtCreateParameters;

    RxCaptureFcb;

    ACCESS_MASK DesiredAccess;
    ULONG       OplockFlags;

    PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);

    PSMBCE_SERVER pServer;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbBuildNtCreateAndX\n", 0 ));

    pServer = SmbCeGetExchangeServer(StufferState->Exchange);

    if (!(cp->CreateOptions & FILE_DIRECTORY_FILE) &&
        (cp->DesiredAccess & (FILE_READ_DATA | FILE_WRITE_DATA | FILE_EXECUTE )) &&
        !MRxSmbOplocksDisabled) {

       DesiredAccess = cp->DesiredAccess & ~SYNCHRONIZE;
       OplockFlags   = (NT_CREATE_REQUEST_OPLOCK | NT_CREATE_REQUEST_OPBATCH);

    } else {

       DesiredAccess = cp->DesiredAccess;
       OplockFlags   = 0;

    }

    if ((RemainingName->Length==0)
           && (FlagOn(RxContext->Create.Flags,RX_CONTEXT_CREATE_FLAG_STRIPPED_TRAILING_BACKSLASH)) ) {
        RemainingName = &UnicodeBackslash;
    }
    COVERED_CALL(MRxSmbStartSMBCommand (StufferState, SetInitialSMB_Never,
                                SMB_COM_NT_CREATE_ANDX, SMB_REQUEST_SIZE(NT_CREATE_ANDX),
                                NO_EXTRA_DATA,SMB_BEST_ALIGNMENT(4,0),RESPONSE_HEADER_SIZE_NOT_SPECIFIED,
                                0,0,0,0 STUFFERTRACE(Dbg,'FC'))
                 );
    SmbCeSetFullProcessIdInHeader(
        StufferState->Exchange,
        smbcp->Pid,
        ((PNT_SMB_HEADER)StufferState->BufferBase));

    MRxSmbStuffSMB (StufferState,
       "XmwdddDdddDddyB",
                                  //  X         UCHAR WordCount;                    // Count of parameter words = 24
                                  //  .         UCHAR AndXCommand;                  // Secondary command; 0xFF = None
                                  //  .         UCHAR AndXReserved;                 // MBZ
                                  //  .         _USHORT( AndXOffset );              // Offset to next command wordcount
                                  //  m         UCHAR Reserved;                     // MBZ
           BooleanFlagOn(pServer->DialectFlags,DF_UNICODE)?
               RemainingName->Length:RtlxUnicodeStringToOemSize(RemainingName),
                                  //  w         _USHORT( NameLength );              // Length of Name[] in bytes
           OplockFlags,           //  d         _ULONG( Flags );                    // Create flags
           0, //not used          //  d         _ULONG( RootDirectoryFid );         // If non-zero, open is relative to this directory
           DesiredAccess,         //  d         ACCESS_MASK DesiredAccess;          // NT access desired
                                  //  Dd        LARGE_INTEGER AllocationSize;       // Initial allocation size
           SMB_OFFSET_CHECK(NT_CREATE_ANDX,AllocationSize)
           cp->AllocationSize.LowPart, cp->AllocationSize.HighPart,
           cp->FileAttributes,    //  d         _ULONG( FileAttributes );           // File attributes for creation
           cp->ShareAccess,       //  d         _ULONG( ShareAccess );              // Type of share access
                                  //  D         _ULONG( CreateDisposition );        // Action to take if file exists or not
           SMB_OFFSET_CHECK(NT_CREATE_ANDX,CreateDisposition)
           cp->Disposition,
           cp->CreateOptions,     //  d         _ULONG( CreateOptions );            // Options to use if creating a file
           cp->ImpersonationLevel,//  d         _ULONG( ImpersonationLevel );       // Security QOS information
           smbcp->SecurityFlags,  //  y         UCHAR SecurityFlags;                // Security QOS information
           SMB_WCT_CHECK(24) 0    //  B         _USHORT( ByteCount );               // Length of byte parameters
                                  //  .         UCHAR Buffer[1];
                                  //  .         //UCHAR Name[];                       // File to open or create
           );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -