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

📄 openclos.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    //proceed with the stuff because we know here that the name fits

    MRxSmbStuffSMB(StufferState,
                   BooleanFlagOn(pServer->DialectFlags,DF_UNICODE)?"u!":"z!",
                   RemainingName);

    MRxSmbDumpStufferState (700,"SMB w/ NTOPEN&X after stuffing",StufferState);

FINALLY:
    RxDbgTraceUnIndent(-1,Dbg);
    return(Status);

}


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

Routine Description:

   This builds an OpenAndX 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:

   RXSTATUS
      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;
    PSMB_EXCHANGE Exchange = StufferState->Exchange;
    RxCaptureFcb;

    PSMBCE_SERVER pServer;

    PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext);

    USHORT smbDisposition;
    USHORT smbSharingMode;
    USHORT smbAttributes;
    ULONG smbFileSize;
    USHORT smbOpenMode;
    USHORT OpenAndXFlags = (SMB_OPEN_QUERY_INFORMATION);

    USHORT SearchAttributes = SMB_FILE_ATTRIBUTE_DIRECTORY | SMB_FILE_ATTRIBUTE_SYSTEM | SMB_FILE_ATTRIBUTE_HIDDEN;
    LARGE_INTEGER CurrentTime;
    ULONG SecondsSince1970;

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

    pServer = SmbCeGetExchangeServer(Exchange);

    smbDisposition = MRxSmbMapDisposition(cp->Disposition);
    smbSharingMode = MRxSmbMapShareAccess(((USHORT)cp->ShareAccess));
    smbAttributes = MRxSmbMapFileAttributes(cp->FileAttributes);
    smbFileSize = cp->AllocationSize.LowPart;
    smbOpenMode = MRxSmbMapDesiredAccess(cp->DesiredAccess);
    smbSharingMode |= smbOpenMode;

    if (cp->CreateOptions & FILE_WRITE_THROUGH) {
        smbSharingMode |= SMB_DA_WRITE_THROUGH;
    }

    //lanman10 servers apparently don't like to get the time passed in.......
    if (FlagOn(pServer->DialectFlags,DF_LANMAN20)) {

        KeQuerySystemTime(&CurrentTime);
        MRxSmbTimeToSecondsSince1970(&CurrentTime,
                                     pServer,
                                     &SecondsSince1970);
    } else {
        SecondsSince1970 = 0;
    }

    COVERED_CALL(MRxSmbStartSMBCommand (StufferState, SetInitialSMB_Never,
                                SMB_COM_OPEN_ANDX, SMB_REQUEST_SIZE(OPEN_ANDX),
                                NO_EXTRA_DATA,SMB_BEST_ALIGNMENT(4,0),RESPONSE_HEADER_SIZE_NOT_SPECIFIED,
                                0,0,0,0 STUFFERTRACE(Dbg,'FC'))
                 );

    MRxSmbStuffSMB (StufferState,
         "XwwwwdwDddB",
                                    //  X         UCHAR WordCount;                    // Count of parameter words = 15
                                    //  .         UCHAR AndXCommand;                  // Secondary (X) command; 0xFF = none
                                    //  .         UCHAR AndXReserved;                 // Reserved (must be 0)
                                    //  .         _USHORT( AndXOffset );              // Offset to next command WordCount
             OpenAndXFlags,         //  w         _USHORT( Flags );                   // Additional information: bit set-
                                    //                                                //  0 - return additional info
                                    //                                                //  1 - set single user total file lock
                                    //                                                //  2 - server notifies consumer of
                                    //                                                //      actions which may change file
             smbSharingMode,        //  w         _USHORT( DesiredAccess );           // File open mode
             SearchAttributes,      //  w         _USHORT( SearchAttributes );
             smbAttributes,         //  w         _USHORT( FileAttributes );
             SecondsSince1970,      //  d         _ULONG( CreationTimeInSeconds );
             smbDisposition,        //  w         _USHORT( OpenFunction );
                                    //  D         _ULONG( AllocationSize );           // Bytes to reserve on create or truncate
             SMB_OFFSET_CHECK(OPEN_ANDX,AllocationSize)
             smbFileSize,
             0xffffffff,            //  d         _ULONG( Timeout );                  // Max milliseconds to wait for resource
             0,                     //  d         _ULONG( Reserved );                 // Reserved (must be 0)
             SMB_WCT_CHECK(15) 0    //  B         _USHORT( ByteCount );               // Count of data bytes; min = 1
                                    //            UCHAR Buffer[1];                    // File name
             );
    //proceed with the stuff because we know here that the name fits

    MRxSmbStuffSMB (StufferState,"z!", RemainingName);

    MRxSmbDumpStufferState (700,"SMB w/ OPEN&X after stuffing",StufferState);

FINALLY:
    RxDbgTraceUnIndent(-1,Dbg);
    return(Status);

}


typedef enum _SMBPSE_CREATE_METHOD {
    CreateAlreadyDone,
    CreateUseCore,
    CreateUseNT
} SMBPSE_CREATE_METHOD;

NTSTATUS
SmbPseExchangeStart_Create(
    SMBPSE_ORDINARY_EXCHANGE_ARGUMENT_SIGNATURE
    )
/*++

Routine Description:

    This is the start routine for net root construction exchanges. This initiates the
    construction of the appropriate SMB's if required.

Arguments:

    pExchange - the exchange instance

Return Value:

    NTSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status = (STATUS_NOT_IMPLEMENTED);
    NTSTATUS SetupStatus = STATUS_SUCCESS;
    PSMBSTUFFER_BUFFER_STATE StufferState = &OrdinaryExchange->AssociatedStufferState;
    SMBPSE_CREATE_METHOD CreateMethod = CreateAlreadyDone;
    PSMBCE_SERVER pServer;
    ULONG DialectFlags;

    RxCaptureFcb;
    PMRX_SMB_FCB      smbFcb     = MRxSmbGetFcbExtension(capFcb);

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

    PBOOLEAN MustRegainExclusiveResource = &OrdinaryExchange->Create.MustRegainExclusiveResource;
    BOOLEAN CreateWithEasSidsOrLongName = OrdinaryExchange->Create.CreateWithEasSidsOrLongName;
    BOOLEAN fRetryCore = FALSE;

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

    ASSERT_ORDINARY_EXCHANGE(OrdinaryExchange);

    pServer = SmbCeGetExchangeServer(OrdinaryExchange);
    DialectFlags = pServer->DialectFlags;

    COVERED_CALL(MRxSmbSetInitialSMB(StufferState STUFFERTRACE(Dbg,0)));

    *MustRegainExclusiveResource = TRUE;

    if (!FlagOn(DialectFlags,DF_NT_SMBS)) {
        OEM_STRING      OemString;
        PUNICODE_STRING PathName = GET_ALREADY_PREFIXED_NAME(SrvOpen,capFcb);

        if (PathName->Length != 0) {
            Status = RtlUnicodeStringToOemString(&OemString, PathName, TRUE);

            if (!NT_SUCCESS(Status)) {
                goto FINALLY;
            }

            //
            //  If we are canonicalizing as FAT, use FAT rules, otherwise use
            //  HPFS rules.
            //

            if (!FlagOn(DialectFlags,DF_LANMAN20)) {
                if (!FsRtlIsFatDbcsLegal(OemString, FALSE, TRUE, TRUE)) {
                    RtlFreeOemString(&OemString);
                    Status = STATUS_OBJECT_NAME_INVALID;
                    goto FINALLY;
                }
            } else if (!FsRtlIsHpfsDbcsLegal(OemString, FALSE, TRUE, TRUE)) {
                RtlFreeOemString(&OemString);
                Status = STATUS_OBJECT_NAME_INVALID;
                goto FINALLY;
            }

            RtlFreeOemString(&OemString);
        }
    }

    if (StufferState->PreviousCommand != SMB_COM_NO_ANDX_COMMAND) {
        // we have a latent session setup /tree connect command

        //the status of the embedded header commands is passed back in the flags.
        SetupStatus = SmbPseOrdinaryExchange(
                          SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS,
                          SMBPSE_OETYPE_LATENT_HEADEROPS
                          );

        if(SetupStatus != STATUS_SUCCESS) {
            Status = SetupStatus;
            goto FINALLY;
        }

        // Turn off reconnect attempts now that we have successfully established
        // the session and net root.
        OrdinaryExchange->SmbCeFlags &= ~(SMBCE_EXCHANGE_ATTEMPT_RECONNECTS);

        COVERED_CALL(MRxSmbSetInitialSMB(StufferState STUFFERTRACE(Dbg,0)));
    }


    if (!CreateWithEasSidsOrLongName) {
        PUNICODE_STRING AlreadyPrefixedName = GET_ALREADY_PREFIXED_NAME(SrvOpen,capFcb);
        PMRXSMB_CREATE_PARAMETERS SmbCp = &OrdinaryExchange->Create.SmbCp;
        PNT_CREATE_PARAMETERS cp = &RxContext->Create.NtCreateParameters;
        USHORT mappedOpenMode;

        MRxSmbAdjustCreateParameters(RxContext,SmbCp);
        mappedOpenMode = MRxSmbMapDesiredAccess(cp->DesiredAccess);

        if ((!MRxSmbForceNoNtCreate)
                        && FlagOn(DialectFlags,DF_NT_SMBS)) {

            BOOLEAN SecurityIsNULL =
                        (cp->SecurityContext == NULL) ||
                        (cp->SecurityContext->AccessState == NULL) ||
                        (cp->SecurityContext->AccessState->SecurityDescriptor == NULL);

            CreateMethod = CreateUseNT;

            //now catch the cases where we want to pseudoopen the file

            if ( MRxSmbDeferredOpensEnabled &&
                 !FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_MINIRDR_INITIATED) &&
                 (capFcb->pNetRoot->Type == NET_ROOT_DISK) &&
                 SecurityIsNULL) {

                ASSERT( RxContext->CurrentIrp != 0 );

                if ((cp->Disposition==FILE_OPEN) &&
                    !BooleanFlagOn(cp->CreateOptions, FILE_OPEN_FOR_BACKUP_INTENT) &&
                    (MustBeDirectory(cp->CreateOptions) ||
                     !(cp->DesiredAccess & ~(SYNCHRONIZE | DELETE | FILE_READ_ATTRIBUTES)))){

                    // NT apps expect that you will not succeed the create and then fail the attribs;
                    // if we had some way of identifying win32 apps then we could defer these (except
                    // for DFS). since we have no way to get that information (and don't even have
                    // a good SMB to send..........)

                    // we don't need to send the open for DELETE and FILE_READ_ATTRIBUTES requests since
                    // there are path basied SMB operations.

                    // we can also pseudoopen directories for file_open at the root of the
                    // share but otherwise we have to at least check that the directory
                    // exists. we might have to push out the open later. BTW, we wouldn't be
                    // in here if the name was too long for a GFA or CheckPath

                    Status = MRxSmbPseudoOpenTailFromFakeGFAResponse(
                                  OrdinaryExchange,
                                  MustBeDirectory(cp->CreateOptions)?FileTypeDirectory:FileTypeFile);

                    if (Status == STATUS_SUCCESS && AlreadyPrefixedName->Length > 0) {
                        // send query path information to make sure the file exists on the server
                        Status = MRxSmbQueryFileInformationFromPseudoOpen(
                                     SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS);

                        if (Status == STATUS_SUCCESS) {
                            if (MustBeDirectory(cp->CreateOptions) &&
                                !OrdinaryExchange->Create.FileInfo.Standard.Directory) {
                                Status = STATUS_NOT_A_DIRECTORY;
                            }
                        }

                        if (Status != STATUS_SUCCESS) {
                            RxFreePool(smbSrvOpen->DeferredOpenContext);
                            smbSrvOpen->DeferredOpenContext = NULL;
                        }
                    }

                    CreateMethod = CreateAlreadyDone;
                }
            }

            //if no pseudoopen case was hit, do a real open

            if (CreateMethod == CreateUseNT) {

               //use NT_CREATE&X
                COVERED_CALL(MRxSmbBuildNtCreateAndX(StufferState,SmbCp));

                Status = SmbPseOrdinaryExchange(
                             SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS,
                             SMBPSE_OETYPE_CREATE
                             );

                if (Status == STATUS_SUCCESS && RxContext->pFobx == NULL) {
                    Status = STATUS_INVALID_NETWORK_RESPONSE;
                }

                if ((Status == STATUS_SUCCESS) && (cp->Disposition == FILE_OPEN)) {
                    MRxSmbAdjustReturnedCreateAction(RxContext);
                }
            }
        } else if (FlagOn(DialectFlags, DF_LANMAN10) &&
                   (mappedOpenMode != ((USHORT)-1)) &&
                   !MustBeDirectory(cp->CreateOptions)) {

            if (MRxSmbDeferredOpensEnabled &&
                capFcb->pNetRoot->Type == NET_ROOT_DISK &&
                !FlagOn(RxContext->Flags,RX_CONTEXT_FLAG_MINIRDR_INITIATED) &&
                (cp->Disposition==FILE_OPEN) &&
                ((cp->DesiredAccess & ~(SYNCHRONIZE | DELETE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES)) == 0) ){

                // we don't need to send the open for DELETE and FILE_READ_ATTRIBUTES requests since
                // there are path basied SMB operations.
                // we should do pseudo open for FILE_WRITE_ATTRIBUTES. Othewise the server will return
                // sharing violation


                // send query path information to make sure the file exists on the server

                Status = MRxSmbPseudoOpenTailFromFakeGFAResponse(
                              OrdinaryExchange,
                              MustBeDirectory(cp->CreateOptions)?FileTypeDirectory:FileTypeFile);

                if (Status == STATUS_SUCCESS && AlreadyPrefixedName->Length > 0) {
                    Status = MRxSmbQueryFileInformationFromPseudoOpen(
                                 SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS);

                    if (Status != STATUS_SUCCESS) {
                        RxFreePool(smbSrvOpen->DeferredOpenContext);
                        smbSrvOpen->DeferredOpenContext = NULL;
                    }
                }

                CreateMethod = CreateAlreadyDone;
            } else {
                //use OPEN&X
                COVERED_CALL(MRxSmbBuildOpenAndX(StufferState,SmbCp));

                Status = SmbPseOrdinaryExchange(
                             SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS,
                             SMBPSE_OETYPE_CREATE
                             );

                if (Status == STATUS_ACCESS_DENIED && !FlagOn(DialectFlags,DF_NT_SMBS)) {
                    CreateMethod = CreateUseCore;
                    fRetryCore = TRUE;
                }
            }
        } else {

            CreateMethod = CreateUseCore;
        }

        if (CreateMethod == CreateUseCore) {

            Status = MRxSmbDownlevelCreate(SMBPSE_ORDINARY_EXCHANGE_ARGUMENTS);

            // put back the real error code if we are retrying open&x
            if ((Status != STATUS_SUCCESS) && fRetryCore)

⌨️ 快捷键说明

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