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

📄 openclos.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
    BOOLEAN         CreateWithEasSidsOrLongName = FALSE;
    ULONG           DialectFlags;
    PUNICODE_STRING RemainingName = GET_ALREADY_PREFIXED_NAME(SrvOpen,capFcb);

    PNT_CREATE_PARAMETERS CreateParameters = &RxContext->Create.NtCreateParameters;
    ULONG                 Disposition = CreateParameters->Disposition;

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

    ASSERT( NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN );

    RxDbgTrace( 0, Dbg, ("     Attempt to open %wZ\n", RemainingName ));

    if (FlagOn( capFcb->FcbState, FCB_STATE_PAGING_FILE )) {
        return STATUS_NOT_IMPLEMENTED;
    }

    if (!FlagOn(pServerEntry->Server.DialectFlags,DF_NT_STATUS) &&
        MRxSmbIsStreamFile(RemainingName,NULL)) {
        // The Samba server return file system type NTFS but doesn't support stream
        return STATUS_OBJECT_PATH_NOT_FOUND;
    }

    RxContext->Create.NtCreateParameters.CreateOptions &= 0xfffff;

    if( NetRoot->Type == NET_ROOT_PRINT ) {
        return STATUS_OBJECT_NAME_NOT_FOUND;
    }

    // we cannot have a file cached on a write only handle. so we have to behave a little
    // differently if this is a write-only open. remember this in the smbsrvopen

    if (  ((CreateParameters->DesiredAccess & (FILE_EXECUTE  | FILE_READ_DATA)) == 0) &&
          ((CreateParameters->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0)
       ) {

        SetFlag(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_WRITE_ONLY_HANDLE);
        SrvOpen->Flags |= SRVOPEN_FLAG_DONTUSE_WRITE_CACHING;
    }

    //the way that SMBs work, there is no buffering effect if we open for attributes-only
    //so set that up immediately.

    if ((CreateParameters->DesiredAccess
         & ~(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE))
                  == 0 ){
        SetFlag(SrvOpen->Flags,SRVOPEN_FLAG_NO_BUFFERING_STATE_CHANGE);
    }

    if (NetRoot->Type == NET_ROOT_MAILSLOT) {
        return STATUS_NOT_SUPPORTED;
    }

    if (NetRoot->Type == NET_ROOT_PIPE) {
        return STATUS_NOT_SUPPORTED;
    }

    // Get the control struct for the file not found name cache.
    //
    pNetRootEntry = SmbCeGetAssociatedNetRootEntry(NetRoot);

    // assume Reconnection to be trivially successful
    Status = STATUS_SUCCESS;

    CreateWithEasSidsOrLongName = MRxSmbIsCreateWithEasSidsOrLongName(RxContext,&DialectFlags);

    if (!FlagOn(pServerEntry->Server.DialectFlags,DF_NT_SMBS)) {
        CreateWithEasSidsOrLongName = FALSE;
    }

    ReconnectRequired           = IsReconnectRequired((PMRX_SRV_CALL)SrvCall);

    //get rid of nonEA guys right now
    if (RxContext->Create.EaLength && !FlagOn(DialectFlags,DF_SUPPORTEA)) {
         RxDbgTrace(-1, Dbg, ("EAs w/o EA support!\n"));
         Status = STATUS_NOT_SUPPORTED;
         goto FINALLY;
    }

    if (ReconnectRequired || !CreateWithEasSidsOrLongName) {
        Status = __SmbPseCreateOrdinaryExchange(
                               RxContext,
                               SrvOpen->pVNetRoot,
                               SMBPSE_OE_FROM_CREATE,
                               SmbPseExchangeStart_Create,
                               &OrdinaryExchange);

        if (Status != STATUS_SUCCESS) {
            RxDbgTrace(-1, Dbg, ("Couldn't get the smb buf!\n"));
            goto FINALLY;
        }
        OrdinaryExchange->Create.CreateWithEasSidsOrLongName = CreateWithEasSidsOrLongName;

        // For Creates, the resources need to be reacquired after sending an
        // SMB; so, do not hold onto the MIDS till finalization; instead give the MID back
        // right away

        OrdinaryExchange->SmbCeFlags &= ~SMBCE_EXCHANGE_REUSE_MID;
        OrdinaryExchange->SmbCeFlags |= (SMBCE_EXCHANGE_ATTEMPT_RECONNECTS |
                                         SMBCE_EXCHANGE_TIMED_RECEIVE_OPERATION);
        OrdinaryExchange->pSmbCeSynchronizationEvent = &RxContext->SyncEvent;

        // drop the resource before you go in!
        // the start routine will reacquire it on the way out.....
        RxReleaseFcbResourceInMRx( capFcb );

        Status = SmbPseInitiateOrdinaryExchange(OrdinaryExchange);

        ASSERT((Status != STATUS_SUCCESS) || RxIsFcbAcquiredExclusive( capFcb ));

        OrdinaryExchange->pSmbCeSynchronizationEvent = NULL;

        SmbPseFinalizeOrdinaryExchange(OrdinaryExchange);

        if (!RxIsFcbAcquiredExclusive(capFcb)) {
            ASSERT(!RxIsFcbAcquiredShared(capFcb));
            RxAcquireExclusiveFcbResourceInMRx( capFcb );
        }
    }

    if (CreateWithEasSidsOrLongName && (Status == STATUS_SUCCESS)) {
        Status = MRxSmbCreateWithEasSidsOrLongName(RxContext);

    }

    // There are certain downlevel servers(OS/2 servers) that return the error
    // STATUS_OPEN_FAILED. This is a context sensitive error code that needs to
    // be interpreted in conjunction with the disposition specified for the OPEN.

    if (Status == STATUS_OPEN_FAILED) {
        switch (Disposition) {

        //
        //  If we were asked to create the file, and got OPEN_FAILED,
        //  this implies that the file already exists.
        //

        case FILE_CREATE:
            Status = STATUS_OBJECT_NAME_COLLISION;
            break;

        //
        //  If we were asked to open the file, and got OPEN_FAILED,
        //  this implies that the file doesn't exist.
        //

        case FILE_OPEN:
        case FILE_SUPERSEDE:
        case FILE_OVERWRITE:
            Status = STATUS_OBJECT_NAME_NOT_FOUND;
            break;

        //
        //  If there is an error from either FILE_OPEN_IF or
        //  FILE_OVERWRITE_IF, it indicates the user is trying to
        //  open a file on a read-only share, so return the
        //  correct error for that.
        //

        case FILE_OPEN_IF:
        case FILE_OVERWRITE_IF:
            Status = STATUS_NETWORK_ACCESS_DENIED;
            break;

        default:
            break;
        }
    }

FINALLY:
    ASSERT(Status != (STATUS_PENDING));

    if (Status == STATUS_SUCCESS) {
        SetFlag(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_SUCCESSFUL_OPEN);
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbCreate  exit with status=%08lx\n", Status ));
    RxLog(("MRxSmbCreate exits %lx\n", Status));

    return(Status);
}

NTSTATUS
MRxSmbDeferredCreate (
      IN OUT PRX_CONTEXT RxContext
      )
/*++

Routine Description:

   This routine constructs a rxcontext from saved information and then calls
   MRxSmbCreate.

Arguments:

    RxContext - the RDBSS context

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;

    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_SMB_FOBX        smbFobx = MRxSmbGetFileObjectExtension(capFobx);
    PMRX_SRV_OPEN        SrvOpen = capFobx->pSrvOpen;
    PMRX_SMB_SRV_OPEN smbSrvOpen = MRxSmbGetSrvOpenExtension(SrvOpen);
    PMRX_SMB_DEFERRED_OPEN_CONTEXT DeferredOpenContext = smbSrvOpen->DeferredOpenContext;
    PSMBCEDB_SERVER_ENTRY pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

    PRX_CONTEXT OpenRxContext,oc;

    PAGED_CODE();

    if ((!FlagOn(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_NOT_REALLY_OPEN)
          || !FlagOn(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_DEFERRED_OPEN))) {

        Status = STATUS_SUCCESS;
        goto FINALLY;
    }

    if (DeferredOpenContext == NULL) {
        if (FlagOn(SrvOpen->Flags,SRVOPEN_FLAG_CLOSED)) {
            Status = STATUS_FILE_CLOSED;
            goto FINALLY;
        } else {
            DbgBreakPoint();
        }
    }

    ASSERT(RxIsFcbAcquiredExclusive(capFcb));

    SmbCeAcquireResource();

    if (!smbSrvOpen->DeferredOpenInProgress) {
        PLIST_ENTRY pListHead;
        PLIST_ENTRY pListEntry;

        smbSrvOpen->DeferredOpenInProgress = TRUE;
        InitializeListHead(&smbSrvOpen->DeferredOpenSyncContexts);

        SmbCeReleaseResource();

        OpenRxContext = RxAllocatePoolWithTag(NonPagedPool,
                                              sizeof(RX_CONTEXT),
                                              MRXSMB_RXCONTEXT_POOLTAG);
        if (OpenRxContext==NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        } else {
            RtlZeroMemory(
                OpenRxContext,
                sizeof(RX_CONTEXT));

            RxInitializeContext(
                NULL,
                RxContext->RxDeviceObject,
                0,
                OpenRxContext );

            oc = OpenRxContext;
            oc->pFcb = capFcb;
            oc->pFobx = capFobx;
            oc->NonPagedFcb = RxContext->NonPagedFcb;
            oc->MajorFunction = IRP_MJ_CREATE;
            oc->pRelevantSrvOpen = SrvOpen;
            oc->Create.pVNetRoot = SrvOpen->pVNetRoot;
            oc->Create.pNetRoot = oc->Create.pVNetRoot->pNetRoot;
            oc->Create.pSrvCall = oc->Create.pNetRoot->pSrvCall;

            oc->Flags = DeferredOpenContext->RxContextFlags;
            oc->Flags |= RX_CONTEXT_FLAG_MINIRDR_INITIATED|RX_CONTEXT_FLAG_WAIT|RX_CONTEXT_FLAG_BYPASS_VALIDOP_CHECK;
            oc->Create.Flags = DeferredOpenContext->RxContextCreateFlags;
            oc->Create.NtCreateParameters = DeferredOpenContext->NtCreateParameters;

            Status = MRxSmbCreate(oc);

            if (Status==STATUS_SUCCESS) {
                if (FlagOn(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_NOT_REALLY_OPEN)) {
                    MRxSmbIncrementSrvOpenCount(pServerEntry,SrvOpen);
                } else {
                    ASSERT(smbSrvOpen->NumOfSrvOpenAdded);
                }

                ClearFlag(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_NOT_REALLY_OPEN);
            }

            RxLog(("DeferredOpen %lx %lx %lx %lx\n", capFcb, capFobx, RxContext, Status));

            ASSERT(oc->ReferenceCount==1);

            RxFreePool(oc);
        }

        if (FlagOn(SrvOpen->Flags,SRVOPEN_FLAG_CLOSED) ||
            FlagOn(SrvOpen->Flags,SRVOPEN_FLAG_ORPHANED)) {
            RxFreePool(smbSrvOpen->DeferredOpenContext);
            smbSrvOpen->DeferredOpenContext = NULL;
            RxDbgTrace(0, Dbg, ("Free deferred open context for file %wZ %lX\n",GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(RxContext),smbSrvOpen));
        }

        SmbCeAcquireResource();
        smbSrvOpen->DeferredOpenInProgress = FALSE;

        pListHead = &smbSrvOpen->DeferredOpenSyncContexts;
        pListEntry = pListHead->Flink;

        while (pListEntry != pListHead) {
            PDEFERRED_OPEN_SYNC_CONTEXT pWaitingContext;

            pWaitingContext = (PDEFERRED_OPEN_SYNC_CONTEXT)CONTAINING_RECORD(
                                   pListEntry,
                                   DEFERRED_OPEN_SYNC_CONTEXT,
                                   ListHead);

            pListEntry = pListEntry->Flink;
            RemoveHeadList(&pWaitingContext->ListHead);

            pWaitingContext->Status = Status;

            //DbgPrint("Signal RxContext %x after deferred open\n",pWaitingContext->RxContext);
            RxSignalSynchronousWaiter(pWaitingContext->RxContext);
        }

        SmbCeReleaseResource();

    } else {
        DEFERRED_OPEN_SYNC_CONTEXT WaitingContext;
        BOOLEAN AcquireExclusive = RxIsFcbAcquiredExclusive(capFcb);
        BOOLEAN AcquireShare = RxIsFcbAcquiredShared(capFcb) > 0;

        // put the RxContext on the waiting list
        WaitingContext.RxContext = RxContext;
        InitializeListHead(&WaitingContext.ListHead);

        InsertTailList(
            &smbSrvOpen->DeferredOpenSyncContexts,
            &WaitingContext.ListHead);

        SmbCeReleaseResource();

        if (AcquireExclusive || AcquireShare) {
            RxReleaseFcbResourceInMRx( capFcb );
        }

        RxWaitSync(RxContext);

        Status = WaitingContext.Status;

        KeInitializeEvent(
            &RxContext->SyncEvent,
            SynchronizationEvent,
            FALSE);

        if (AcquireExclusive) {
            RxAcquireExclusiveFcbResourceInMRx( capFcb );
        } else if (AcquireShare) {
            RxAcquireSharedFcbResourceInMRx( capFcb );
        }
    }

FINALLY:
    return Status;
}


NTSTATUS
MRxSmbCollapseOpen(
      IN OUT PRX_CONTEXT RxContext
      )
/*++

Routine Description:

   This routine collapses a open locally

Arguments:

    RxContext - the RDBSS context

Return Value:

    NTSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status;

    RxCaptureFcb;

⌨️ 快捷键说明

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