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

📄 srvcall.c

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

        pReqEcho->WordCount = 1;

        RtlMoveMemory( pReqEcho->Buffer, s_EchoData, sizeof( s_EchoData ) );

        SmbPutUshort(&pReqEcho->EchoCount, SMB_ECHO_COUNT);
        SmbPutUshort(&pReqEcho->ByteCount, (USHORT) sizeof( s_EchoData ) );
    } else {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }

    return Status;
}

VOID
MRxSmbTearDownEchoProbeService(
    PMRXSMB_ECHO_PROBE_SERVICE_CONTEXT pEchoProbeContext)
/*++

Routine Description:

    This routine tears down the echo processing context

--*/
{
    PAGED_CODE();

    if (pEchoProbeContext->pEchoSmb != NULL) {
        RxFreePool(pEchoProbeContext->pEchoSmb);
        pEchoProbeContext->pEchoSmb = NULL;
    }
}



NTSTATUS
BuildNegotiateSmb(
    PVOID    *pSmbBufferPointer,
    PULONG   pSmbBufferLength)
/*++

Routine Description:

    This routine builds the negotiate SMB

Arguments:

    pSmbBufferPointer    - a placeholder for the smb buffer

    pNegotiateSmbLength  - the smb buffer size

Return Value:

    STATUS_SUCCESS - implies that pServer is a valid instnace .

    Other Status codes correspond to error situations.

--*/
{
    NTSTATUS    Status = STATUS_SUCCESS;
    ULONG       DialectIndex;
    PSMB_HEADER    pSmbHeader    = NULL;
    PREQ_NEGOTIATE pReqNegotiate = NULL;

    PAGED_CODE();

    if (s_pNegotiateSmb == NULL) {
        s_NegotiateSmbLength = sizeof(SMB_HEADER) +
                               FIELD_OFFSET(REQ_NEGOTIATE,Buffer) +
                               sizeof(s_DialectNames);

        s_pNegotiateSmb = (PBYTE)RxAllocatePoolWithTag(
                                     PagedPool,
                                     s_NegotiateSmbLength + TRANSPORT_HEADER_SIZE,
                                     MRXSMB_ADMIN_POOLTAG);

        if (s_pNegotiateSmb != NULL) {

            s_pNegotiateSmb += TRANSPORT_HEADER_SIZE;

            pSmbHeader = (PSMB_HEADER)s_pNegotiateSmb;
            pReqNegotiate = (PREQ_NEGOTIATE)(s_pNegotiateSmb + 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;

            // Put our flags2 field. The Ox10 is a temporary flag for SLM
            // corruption detection
            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 );

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

            pReqNegotiate->WordCount = 0;

            RtlMoveMemory(
                pReqNegotiate->Buffer,
                s_DialectNames,
                sizeof( s_DialectNames ) );

            SmbPutUshort(
                &pReqNegotiate->ByteCount,
                (USHORT) sizeof( s_DialectNames ) );

            // Initialize the maximum time zone bias used in negotiate response parsing.
            s_MaxTimeZoneBias.QuadPart = Int32x32To64(24*60*60,1000*10000);
        } else {
            Status = STATUS_INSUFFICIENT_RESOURCES;
        }
    }

    if (NT_SUCCESS(Status)) {
        *pSmbBufferLength  = s_NegotiateSmbLength;
        *pSmbBufferPointer = s_pNegotiateSmb;
    }

    return Status;
}


ULONG MRxSmbSrvWriteBufSize = 0xffff; //use the negotiated size

NTSTATUS
ParseNegotiateResponse(
    IN OUT PSMB_ADMIN_EXCHANGE pSmbAdminExchange,
    IN     ULONG               BytesIndicated,
    IN     ULONG               BytesAvailable,
       OUT PULONG              pBytesTaken,
    IN     PSMB_HEADER         pSmbHeader,
       OUT PMDL                *pDataBufferPointer,
       OUT PULONG              pDataSize)
/*++

Routine Description:

    This routine parses the response from the server

Arguments:

    pServer            - the server instance

    pDomainName        - the domain name string to be extracted from the response

    pSmbHeader         - the response SMB

    BytesAvailable     - length of the response

    pBytesTaken        - response consumed

Return Value:

    STATUS_SUCCESS - the server call construction has been finalized.

    Other Status codes correspond to error situations.

Notes:

    The SMB servers can speak a variety of dialects of the SMB protocol. The initial
    negotiate response can come in one of three possible flavours. Either we get the
    NT negotiate response SMB from a NT server or the extended response from DOS and
    OS/2 servers or the CORE response from other servers.

--*/
{
    NTSTATUS        Status = STATUS_SUCCESS;

    PSMBCEDB_SERVER_ENTRY pServerEntry;
    PSMBCE_SERVER         pServer;
    PUNICODE_STRING       pDomainName;

    USHORT          DialectIndex;
    PRESP_NEGOTIATE pNegotiateResponse;
    ULONG           NegotiateSmbLength;

    ASSERT( pSmbHeader != NULL );

    pServerEntry = SmbCeGetExchangeServerEntry(pSmbAdminExchange);
    pServer = &pServerEntry->Server;

    pDomainName = &pSmbAdminExchange->Negotiate.DomainName;

    pNegotiateResponse = (PRESP_NEGOTIATE) (pSmbHeader + 1);
    NegotiateSmbLength = sizeof(SMB_HEADER);
    *pBytesTaken       = NegotiateSmbLength;

    // Assume that the indicated response is sufficient.
    // The TDI imposed minimum of 128 bytes subsumes the negotiate response.

    *pDataBufferPointer = NULL;
    *pDataSize          = 0;

    DialectIndex = SmbGetUshort( &pNegotiateResponse->DialectIndex );
    if (DialectIndex == (USHORT) -1) {
        // means server cannot accept any requests from
        *pBytesTaken = BytesAvailable;
        pServerEntry->ServerStatus = STATUS_REQUEST_NOT_ACCEPTED;

        return Status;
    }

    if (pNegotiateResponse->WordCount < 1 || DialectIndex > s_NumberOfDialects) {
        *pBytesTaken = BytesAvailable;
        pServerEntry->ServerStatus = STATUS_INVALID_NETWORK_RESPONSE;
        return Status;
    }

    // set the domain name length to zero ( default initialization )
    pDomainName->Length = 0;

    // Fix up the dialect type and the corresponding dispatch vector.
    pServer->Dialect        = (SMB_DIALECT)DialectIndex;
    pServer->DialectFlags   = MRxSmbDialectFlags[DialectIndex];
    pServer->pDispatch      = &s_SmbServerDispatchVectors[s_SmbDialects[DialectIndex].DispatchVectorIndex];

    // Parse the response based upon the type of negotiate response expected.

    switch (s_SmbDialects[DialectIndex].NegotiateType) {
    case SMB_NT_NEGOTIATE:
        {
            ULONG              NegotiateResponseLength;
            LARGE_INTEGER      ZeroTime;
            LARGE_INTEGER      LocalTimeBias;
            LARGE_INTEGER      ServerTimeBias;
            PRESP_NT_NEGOTIATE pNtNegotiateResponse = (PRESP_NT_NEGOTIATE) pNegotiateResponse;

            ASSERT(BytesAvailable > sizeof(RESP_NT_NEGOTIATE));

            if (pNtNegotiateResponse->WordCount != 17) {
                *pBytesTaken = BytesAvailable;
                Status = STATUS_INVALID_NETWORK_RESPONSE;
            } else {
                // parse and map the capabilities.
                ULONG NtCapabilities;

                NegotiateResponseLength = FIELD_OFFSET(RESP_NT_NEGOTIATE,Buffer) +
                                          SmbGetUshort(&pNtNegotiateResponse->ByteCount);
                NegotiateSmbLength += NegotiateResponseLength;

                //Start with a clean slate
                pServer->Capabilities = 0;

                // Initialize server based constants
                pServer->MaximumRequests   = SmbGetUshort( &pNtNegotiateResponse->MaxMpxCount );
                pServer->MaximumVCs        = SmbGetUshort( &pNtNegotiateResponse->MaxNumberVcs );
                pServer->MaximumBufferSize = SmbGetUlong( &pNtNegotiateResponse->MaxBufferSize );

                NtCapabilities = pServer->NtServer.NtCapabilities = SmbGetUlong(&pNtNegotiateResponse->Capabilities);
                if (NtCapabilities & CAP_RAW_MODE) {
                    pServer->Capabilities |= (RAW_READ_CAPABILITY | RAW_WRITE_CAPABILITY);
                }

                if (NtCapabilities & CAP_DFS) {
                    pServer->Capabilities |= CAP_DFS;
                }

                //copy other nt capabilities into the dialog flags

                if (NtCapabilities & CAP_UNICODE) {
                    pServer->DialectFlags |= DF_UNICODE;
                }

                if (NtCapabilities & CAP_LARGE_FILES) {
                    pServer->DialectFlags |= DF_LARGE_FILES;
                }

                if (NtCapabilities & CAP_NT_SMBS) {
                    pServer->DialectFlags |= DF_NT_SMBS | DF_NT_FIND;
                }

                if (NtCapabilities & CAP_NT_FIND) {
                    pServer->DialectFlags |= DF_NT_FIND;
                }

                if (NtCapabilities & CAP_RPC_REMOTE_APIS) {
                    pServer->DialectFlags |= DF_RPC_REMOTE;
                }

                if (NtCapabilities & CAP_NT_STATUS) {
                    pServer->DialectFlags |= DF_NT_STATUS;
                }

                if (NtCapabilities & CAP_LEVEL_II_OPLOCKS) {
                    pServer->DialectFlags |= DF_OPLOCK_LVL2;
                }

                if (NtCapabilities & CAP_LOCK_AND_READ) {
                    pServer->DialectFlags |= DF_LOCKREAD;
                }

                if (NtCapabilities & CAP_INFOLEVEL_PASSTHRU) {
                    pServer->DialectFlags |= DF_NT_INFO_PASSTHROUGH;
                }

                // For non disk files the LARGE_READX capability is not useful.
                pServer->MaximumNonDiskFileReadBufferSize =
                    pServer->MaximumBufferSize -
                    QuadAlign(
                        sizeof(SMB_HEADER) +
                        FIELD_OFFSET(
                            REQ_NT_READ_ANDX,
                            Buffer[0]));

                if (NtCapabilities & CAP_LARGE_READX) {
                    if (NtCapabilities & CAP_LARGE_WRITEX) {
                        pServer->MaximumDiskFileReadBufferSize = 60*1024;
                    } else {
                        // The maximum size for reads to servers which support
                        // large read and x is constrained by the USHORT to record
                        // lengths in the SMB. Thus the maximum length that can be used
                        // is (65536 - 1) . This length should accomodate the header as
                        // well as the rest of the SMB. Actually, tho, we cut back to 60K.
                        pServer->MaximumDiskFileReadBufferSize = 60*1024;
                    }
                } else {
                    pServer->MaximumDiskFileReadBufferSize = pServer->MaximumNonDiskFileReadBufferSize;
                }

                // Specifying a zero local time will give you the time zone bias
                ZeroTime.HighPart = ZeroTime.LowPart = 0;
                ExLocalTimeToSystemTime( &ZeroTime, &LocalTimeBias );

                ServerTimeBias = RtlEnlargedIntegerMultiply(
                                    (LONG)SmbGetUshort(
                                        &pNtNegotiateResponse->ServerTimeZone),
                                    ONE_MINUTE_IN_TIME );

                pServer->TimeZoneBias.QuadPart = ServerTimeBias.QuadPart -
                                                 LocalTimeBias.QuadPart;

                if (!FlagOn(pServer->DialectFlags,DF_NT_SMBS)) {
                    //sigh...........
                    pServer->DialectFlags &= ~(DF_MIXEDCASEPW);
                    pServer->DialectFlags |= DF_W95;
                }

                Status = GetNTSecurityParameters(
                             pSmbAdminExchange,
                             pServer,
                             pDomainName,
                             pNtNegotiateResponse,
                             BytesIndicated,
                             BytesAvailable,
                             pBytesTaken,
                             pDataBufferPointer,
                             pDataSize);

                pServer->MaximumNonDiskFileWriteBufferSize =
                    min(
                        MRxSmbSrvWriteBufSize,
                        pServer->MaximumBufferSize -
                        QuadAlign(
                            sizeof(SMB_HEADER) +
                            FIELD_OFFSET(
                                REQ_NT_WRITE_ANDX,
                                Buffer[0])));
                
                if (NtCapabilities & CAP_LARGE_WRITEX) {
                    pServer->DialectFlags |= DF_LARGE_WRITEX;
                    pServer->MaximumDiskFileWriteBufferSize = 0x10000;
                } else {
                    pServer->MaximumDiskFileWriteBufferSize =
                        pServer->MaximumNonDiskFileWriteBufferSize;
                }
            }
        }
        break;

    case SMB_EXTENDED_NEGOTIATE :
        {
            // An SMB_EXTENDED_NEGOTIATE response is never partially indicated. The response
            // length is ithin the TDI minimum for indication.

            USHORT RawMode;

            // DOS or OS2 server
            if (pNegotiateResponse->WordCount != 13 &&
                pNegotiateResponse->WordCount != 10 &&
                pNegotiateResponse->WordCount != 8) {
                Status = STATUS_INVALID_NETWORK_RESPONSE;
            } else {
                NegotiateSmbLength += FIELD_OFFSET(RESP_NEGOTIATE,Buffer) +
                                      SmbGetUshort(&pNegotiateResponse->ByteCount);

                ASSERT(
                    (BytesIndicated >= NegotiateSmbLength) &&
                    (BytesIndicated == BytesAvailable));

                RawMode = SmbGetUshort( &pNegotiateResponse->RawMode );
                pServer->Capabilities |= ((RawMode & 0x1) != 0
                                          ? RAW_READ_CAPABILITY : 0);
                pServer->Capabilities |= ((RawMode & 0x2) != 0
                                          ? RAW_WRITE_CAPABILITY : 0);

                if (pSmbHeader->Flags & SMB_FLAGS_LOCK_AND_READ_OK) {
                    pServer->DialectFlags |= DF_LOCKREAD;
                }

                pServer->EncryptPasswords = FALSE;
                pServer->MaximumVCs       = 1;

                pServer->MaximumBufferSize     = SmbGetUshort( &pNegotiateResponse->MaxBufferSize );
                pServer->MaximumDiskFileReadBufferSize =
                    pServer->MaximumBufferSize -
                    QuadAlign(
                        sizeof(SMB_HEADER) +
                        FIELD_OFFSET(
                            RESP_READ_ANDX,
                            Buffer[0]));

                pServer->MaximumNonDiskFileReadBufferSize  = pServer->MaximumDiskFileReadBufferSize;
                pServer->MaximumDiskFileWriteBufferSize    = pServer->MaximumDiskFileReadBufferSize;
                pServer->MaximumNonDiskFileWriteBufferSize = pServer->MaximumDiskFileReadBufferSize;

⌨️ 快捷键说明

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