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

📄 srvcall.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++
Copyright (c) 1987-1999  Microsoft Corporation

Module Name:

    srvcall.c

Abstract:

    This module implements the routines for handling the creation/manipulation of
    server entries in the connection engine database. It also contains the routines
    for parsing the negotiate response from  the server.

--*/

#include "precomp.h"
#pragma hdrstop

#ifdef  ALLOC_PRAGMA
#pragma alloc_text(PAGE, SmbCeCreateSrvCall)
#pragma alloc_text(PAGE, MRxSmbCreateSrvCall)
#pragma alloc_text(PAGE, MRxSmbFinalizeSrvCall)
#pragma alloc_text(PAGE, MRxSmbSrvCallWinnerNotify)
#pragma alloc_text(PAGE, MRxSmbInitializeEchoProbeService)
#pragma alloc_text(PAGE, MRxSmbTearDownEchoProbeService)
#pragma alloc_text(PAGE, BuildNegotiateSmb)
#endif

RXDT_DefineCategory(SRVCALL);
#define Dbg        (DEBUG_TRACE_SRVCALL)

VOID
SmbCeCreateSrvCall(
    PMRX_SRVCALL_CALLBACK_CONTEXT  pCallbackContext)
/*++

Routine Description:

   This routine patches the RDBSS created srv call instance with the information required
   by the mini redirector.

Arguments:

    CallBackContext  - the call back context in RDBSS for continuation.

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS Status;

    PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure;
    PMRX_SRV_CALL pSrvCall;

    PAGED_CODE();

    SrvCalldownStructure =
        (PMRX_SRVCALLDOWN_STRUCTURE)(pCallbackContext->SrvCalldownStructure);

    pSrvCall = SrvCalldownStructure->SrvCall;

    ASSERT( pSrvCall );
    ASSERT( NodeType(pSrvCall) == RDBSS_NTC_SRVCALL );

    SmbCeInitializeServerEntry(
        pSrvCall,
        pCallbackContext,
        SrvCalldownStructure->RxContext->Create.TreeConnectOpenDeferred);
}


NTSTATUS
MRxSmbCreateSrvCall(
    PMRX_SRV_CALL                  pSrvCall,
    PMRX_SRVCALL_CALLBACK_CONTEXT  pCallbackContext)
/*++

Routine Description:

   This routine patches the RDBSS created srv call instance with the information required
   by the mini redirector.

Arguments:

    RxContext        - Supplies the context of the original create/ioctl

    CallBackContext  - the call back context in RDBSS for continuation.

Return Value:

    RXSTATUS - The return status for the operation

Notes:

    Certain transport related interfaces require handle to be passed in. This
    implies that the SRV_CALL instances need to be initialized in the context
    of a well known process, i.e., the RDBSS process.

    In the normal course of event is this request was issued within the context
    of the system process we should continue without having to post. However
    there are cases in MIPS  when stack overflows. In order to avoid such situations
    the request is posted in all cases.

--*/
{
    NTSTATUS Status;
    UNICODE_STRING ServerName;

    PMRX_SRVCALL_CALLBACK_CONTEXT SCCBC = pCallbackContext;
    PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure = (PMRX_SRVCALLDOWN_STRUCTURE)(pCallbackContext->SrvCalldownStructure);

    PAGED_CODE();

    ASSERT( pSrvCall );
    ASSERT( NodeType(pSrvCall) == RDBSS_NTC_SRVCALL );

    // Dispatch the request to a system thread.
    Status = RxDispatchToWorkerThread(
                 MRxSmbDeviceObject,
                 DelayedWorkQueue,
                 SmbCeCreateSrvCall,
                 pCallbackContext);

    if (Status == STATUS_SUCCESS) {
        // Map the return value since the wrapper expects PENDING.
        Status = STATUS_PENDING;
    } else {
        // There was an error in dispatching the SmbCeCreateSrvCall method to
        // a worker thread. Complete the request and return STATUS_PENDING.

        SCCBC->Status = Status;
        SrvCalldownStructure->CallBack(SCCBC);
        Status = STATUS_PENDING;
    }

    return Status;
}

NTSTATUS
MRxSmbFinalizeSrvCall(
    PMRX_SRV_CALL pSrvCall,
    BOOLEAN       Force)
/*++

Routine Description:

   This routine destroys a given server call instance

Arguments:

    pSrvCall  - the server call instance to be disconnected.

    Force     - TRUE if a disconnection is to be enforced immediately.

Return Value:

    RXSTATUS - The return status for the operation

--*/
{
    NTSTATUS              Status = STATUS_SUCCESS;
    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PAGED_CODE();

    // if the server entry is not filled in, then there's nothing to do. this occurs
    // on a srvcall that we never successfuly hooked up to........
    if (pSrvCall->Context == NULL) {
        return(Status);
    }


    pServerEntry = SmbCeGetAssociatedServerEntry(pSrvCall);

    if (pServerEntry != NULL) {
        InterlockedCompareExchangePointer(
            &pServerEntry->pRdbssSrvCall,
            NULL,
            pSrvCall);
        SmbCeDereferenceServerEntry(pServerEntry);
    }

    pSrvCall->Context = NULL;

    return Status;
}

NTSTATUS
MRxSmbSrvCallWinnerNotify(
    IN PMRX_SRV_CALL  pSrvCall,
    IN BOOLEAN        ThisMinirdrIsTheWinner,
    IN OUT PVOID      pSrvCallContext)
/*++

Routine Description:

   This routine finalizes the mini rdr context associated with an RDBSS Server call instance

Arguments:

    pSrvCall               - the Server Call

    ThisMinirdrIsTheWinner - TRUE if this mini rdr is the choosen one.

    pSrvCallContext  - the server call context created by the mini redirector.

Return Value:

    RXSTATUS - The return status for the operation

Notes:

    The two phase construction protocol for Server calls is required because of parallel
    initiation of a number of mini redirectors. The RDBSS finalizes the particular mini
    redirector to be used in communicating with a given server based on quality of
    service criterion.

--*/
{
    NTSTATUS Status = STATUS_SUCCESS;
    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PAGED_CODE();

    pServerEntry = (PSMBCEDB_SERVER_ENTRY)pSrvCallContext;

    if (!ThisMinirdrIsTheWinner) {

        //
        // Some other mini rdr has been choosen to connect to the server. Destroy
        // the data structures created for this mini redirector.
        //
        SmbCeUpdateServerEntryState(pServerEntry,SMBCEDB_MARKED_FOR_DELETION);
        SmbCeDereferenceServerEntry(pServerEntry);
        return STATUS_SUCCESS;
    }

    pSrvCall->Context  = pServerEntry;

    pSrvCall->Flags   |= SRVCALL_FLAG_CASE_INSENSITIVE_NETROOTS |
                         SRVCALL_FLAG_CASE_INSENSITIVE_FILENAMES;

    pSrvCall->MaximumNumberOfCloseDelayedFiles = MRxSmbConfiguration.DormantFileLimit + 1;
    pServerEntry->Server.IsLoopBack = FALSE;

    return STATUS_SUCCESS;
}

//
// The following type defines and data structures are used for parsing negotiate SMB
// responses.
//


typedef enum _SMB_NEGOTIATE_TYPE_ {
    SMB_CORE_NEGOTIATE,
    SMB_EXTENDED_NEGOTIATE,
    SMB_NT_NEGOTIATE
} SMB_NEGOTIATE_TYPE, *PSMB_NEGOTIATE_TYPE;

typedef struct _SMB_DIALECTS_ {
    SMB_NEGOTIATE_TYPE   NegotiateType;
    USHORT               DispatchVectorIndex;
} SMB_DIALECTS, *PSMB_DIALECTS;

SMBCE_SERVER_DISPATCH_VECTOR
s_SmbServerDispatchVectors[] = {
    {BuildSessionSetupSmb,CoreBuildTreeConnectSmb},
    {BuildSessionSetupSmb,LmBuildTreeConnectSmb},
    {BuildSessionSetupSmb,NtBuildTreeConnectSmb},
    };

SMB_DIALECTS
s_SmbDialects[] = {
    { SMB_CORE_NEGOTIATE, 0},
    //{ SMB_CORE_NEGOTIATE, 0 },
    //{ SMB_EXTENDED_NEGOTIATE, 1 },
    { SMB_EXTENDED_NEGOTIATE, 1 },
    { SMB_EXTENDED_NEGOTIATE, 1 },
    { SMB_EXTENDED_NEGOTIATE, 1 },
    { SMB_EXTENDED_NEGOTIATE, 1 },
    { SMB_NT_NEGOTIATE, 2 },
};

CHAR s_DialectNames[] = {
    "\2"  PCNET1 "\0"
    //\2notyet"  XENIXCORE "\0"
    //\2notyet"  MSNET103 "\0"
    "\2"  LANMAN10 "\0"
    "\2"  WFW10 "\0"
    "\2"  LANMAN12
    "\0\2"  LANMAN21
//    "\0\2"  NTLANMAN
    };

#define __second(a,b) (b)
ULONG
MRxSmbDialectFlags[] = {
    __second( PCNET1,    DF_CORE ),

    //__second( XENIXCORE, DF_CORE | DF_MIXEDCASEPW | DF_MIXEDCASE ),

    //__second( MSNET103,  DF_CORE | DF_OLDRAWIO | DF_LOCKREAD | DF_EXTENDNEGOT ),

    __second( LANMAN10,  DF_CORE | DF_NEWRAWIO | DF_LOCKREAD | DF_EXTENDNEGOT |
                    DF_LANMAN10 ),

    __second( WFW10,  DF_CORE | DF_NEWRAWIO | DF_LOCKREAD | DF_EXTENDNEGOT |
                    DF_LANMAN10 | DF_WFW),

    __second( LANMAN12,  DF_CORE | DF_NEWRAWIO | DF_LOCKREAD | DF_EXTENDNEGOT |
                    DF_LANMAN10 | DF_LANMAN20 |
                    DF_MIXEDCASE | DF_LONGNAME | DF_SUPPORTEA ),

    __second( LANMAN21,  DF_CORE | DF_NEWRAWIO | DF_LOCKREAD | DF_EXTENDNEGOT |
                    DF_LANMAN10 | DF_LANMAN20 |
                    DF_MIXEDCASE | DF_LONGNAME | DF_SUPPORTEA |
                    DF_LANMAN21),

    __second( NTLANMAN,  DF_CORE | DF_NEWRAWIO |
                    DF_NTPROTOCOL | DF_NTNEGOTIATE |
                    DF_MIXEDCASEPW | DF_LANMAN10 | DF_LANMAN20 |
                    DF_LANMAN21 | DF_MIXEDCASE | DF_LONGNAME |
                    DF_SUPPORTEA | DF_TIME_IS_UTC )
};

ULONG s_NumberOfDialects = sizeof(s_SmbDialects) / sizeof(s_SmbDialects[0]);

PBYTE s_pNegotiateSmb =  NULL;
ULONG s_NegotiateSmbLength = 0;

PBYTE s_pEchoSmb  = NULL;
BYTE  s_EchoData[] = "JlJmIhClBsr";

#define SMB_ECHO_COUNT (1)

// Number of ticks 100ns ticks in a day.
LARGE_INTEGER s_MaxTimeZoneBias;

extern NTSTATUS
GetNTSecurityParameters(
    PSMB_ADMIN_EXCHANGE pSmbAdminExchange,
    PSMBCE_SERVER       pServer,
    PUNICODE_STRING     pDomainName,
    PRESP_NT_NEGOTIATE  pNtNegotiateResponse,
    ULONG               BytesIndicated,
    ULONG               BytesAvailable,
    PULONG              pBytesTaken,
    PMDL                *pDataBufferPointer,
    PULONG              pDataSize);

extern NTSTATUS
GetLanmanSecurityParameters(
    PSMBCE_SERVER    pServer,
    PRESP_NEGOTIATE  pNegotiateResponse);

extern VOID
GetLanmanTimeBias(
    PSMBCE_SERVER   pServer,
    PRESP_NEGOTIATE pNegotiateResponse);

// Number of 100 ns ticks in one minute
#define ONE_MINUTE_IN_TIME (60 * 1000 * 10000)

NTSTATUS
MRxSmbInitializeEchoProbeService(
    PMRXSMB_ECHO_PROBE_SERVICE_CONTEXT pEchoProbeContext)
/*++

Routine Description:

    This routine builds the echo SMB

Return Value:

    STATUS_SUCCESS if construction of an ECHO smb was successful

    Other Status codes correspond to error situations.

--*/
{
    NTSTATUS    Status = STATUS_SUCCESS;
    ULONG       DialectIndex;

    PSMB_HEADER    pSmbHeader = NULL;
    PREQ_ECHO      pReqEcho   = NULL;

    PAGED_CODE();

    pEchoProbeContext->EchoSmbLength = sizeof(SMB_HEADER) +
                                     FIELD_OFFSET(REQ_ECHO,Buffer) +
                                     sizeof(s_EchoData);

    pEchoProbeContext->pEchoSmb = (PBYTE)RxAllocatePoolWithTag(
                                           NonPagedPool,
                                           pEchoProbeContext->EchoSmbLength,
                                           MRXSMB_ECHO_POOLTAG);

    if (pEchoProbeContext->pEchoSmb != NULL) {
        pSmbHeader = (PSMB_HEADER)pEchoProbeContext->pEchoSmb;
        pReqEcho   = (PREQ_ECHO)((PBYTE)pEchoProbeContext->pEchoSmb + sizeof(SMB_HEADER));

        // Fill in the header
        RtlZeroMemory( pSmbHeader, sizeof( SMB_HEADER ) );

        *(PULONG)(&pSmbHeader->Protocol) = (ULONG)SMB_HEADER_PROTOCOL;

        // By default, paths in SMBs are marked as case insensitive and
        // canonicalized.
        pSmbHeader->Flags =
            SMB_FLAGS_CASE_INSENSITIVE | SMB_FLAGS_CANONICALIZED_PATHS;

        // Get the flags2 field out of the SmbContext
        SmbPutAlignedUshort(
            &pSmbHeader->Flags2,
            (SMB_FLAGS2_KNOWS_LONG_NAMES |
             SMB_FLAGS2_KNOWS_EAS        |
             SMB_FLAGS2_IS_LONG_NAME     |
             SMB_FLAGS2_NT_STATUS        |
             SMB_FLAGS2_UNICODE));

        // Fill in the process id.
        SmbPutUshort(&pSmbHeader->Pid, MRXSMB_PROCESS_ID );
        SmbPutUshort(&pSmbHeader->Tid,0xffff); // Invalid TID

        // Lastly, fill in the smb command code.
        pSmbHeader->Command = (UCHAR) SMB_COM_ECHO;

⌨️ 快捷键说明

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