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

📄 ea.c

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


ULONG
MRxSmbNtFullEaSizeToOs2 (
    IN PFILE_FULL_EA_INFORMATION NtFullEa
    )

/*++

Routine Description:

    Get the number of bytes that would be required to represent the
    NT full EA list in OS/2 1.2 style.  This routine assumes that
    at least one EA is present in the buffer.

Arguments:

    NtFullEa - a pointer to the list of NT EAs.

Return Value:

    ULONG - number of bytes required to hold the EAs in OS/2 1.2 format.

--*/

{
    ULONG size;

    PAGED_CODE();

    //
    // Walk through the EAs, adding up the total size required to
    // hold them in OS/2 format.
    //

    for ( size = FIELD_OFFSET(FEALIST, list[0]);
          NtFullEa->NextEntryOffset != 0;
          NtFullEa = (PFILE_FULL_EA_INFORMATION)(
                         (PCHAR)NtFullEa + NtFullEa->NextEntryOffset ) ) {

        size += SmbGetOs2SizeOfNtFullEa( NtFullEa );
    }

    size += SmbGetOs2SizeOfNtFullEa( NtFullEa );

    return size;

}


VOID
MRxSmbNtFullListToOs2 (
    IN PFILE_FULL_EA_INFORMATION NtEaList,
    IN PFEALIST FeaList
    )
/*++

Routine Description:

    Converts a single NT FULL EA list to OS/2 FEALIST style.  The FEALIST
    need not have any particular alignment.

    It is the callers responsibility to ensure that FeaList is large enough.

Arguments:

    NtEaList - An NT style get EA list to be converted to OS/2 format.

    FeaList - Where to place the OS/2 1.2 style FEALIST.

Return Value:

    none.

--*/
{

    PFEA fea = FeaList->list;

    PFILE_FULL_EA_INFORMATION ntFullEa = NtEaList;

    PAGED_CODE();

    //
    // Copy the Eas up until the last one
    //

    while ( ntFullEa->NextEntryOffset != 0 ) {
        //
        // Copy the NT format EA to OS/2 1.2 format and set the fea
        // pointer for the next iteration.
        //

        fea = MRxSmbNtFullEaToOs2( fea, ntFullEa );

        ntFullEa = (PFILE_FULL_EA_INFORMATION)((PCHAR)ntFullEa + ntFullEa->NextEntryOffset);
    }

    //  Now copy the last entry.

    fea = MRxSmbNtFullEaToOs2( fea, ntFullEa );


    //
    // Set the number of bytes in the FEALIST.
    //

    SmbPutUlong(
        &FeaList->cbList,
        (ULONG)((PCHAR)fea - (PCHAR)FeaList)
        );

}


PVOID
MRxSmbNtFullEaToOs2 (
    OUT PFEA Fea,
    IN PFILE_FULL_EA_INFORMATION NtFullEa
    )

/*++

Routine Description:

    Converts a single NT full EA to OS/2 FEA style.  The FEA need not have
    any particular alignment.  This routine makes no checks on buffer
    overrunning--this is the responsibility of the calling routine.

Arguments:

    Fea - a pointer to the location where the OS/2 FEA is to be written.

    NtFullEa - a pointer to the NT full EA.

Return Value:

    A pointer to the location after the last byte written.

--*/

{
    PCHAR ptr;

    PAGED_CODE();

    Fea->fEA = (UCHAR)NtFullEa->Flags;
    Fea->cbName = NtFullEa->EaNameLength;
    SmbPutUshort( &Fea->cbValue, NtFullEa->EaValueLength );

    ptr = (PCHAR)(Fea + 1);
    RtlCopyMemory( ptr, NtFullEa->EaName, NtFullEa->EaNameLength );

    ptr += NtFullEa->EaNameLength;
    *ptr++ = '\0';

    RtlCopyMemory(
        ptr,
        NtFullEa->EaName + NtFullEa->EaNameLength + 1,
        NtFullEa->EaValueLength
        );

    return (ptr + NtFullEa->EaValueLength);

}


NTSTATUS
MRxSmbSetEaList(
    IN PRX_CONTEXT RxContext,
    IN PFEALIST ServerEaList
    )

/*++

Routine Description:

    This routine implements the NtQueryEaFile api.
    It returns the following information:


Arguments:

    IN PFEALIST ServerEaList - Eas to be sent to the server.

Return Value:

    Status - Result of the operation.


--*/

{
   RxCaptureFobx;

   PMRX_SMB_SRV_OPEN smbSrvOpen;


   NTSTATUS Status;
   USHORT Setup = TRANS2_SET_FILE_INFORMATION;

   REQ_SET_FILE_INFORMATION SetFileInfoRequest;
   RESP_SET_FILE_INFORMATION SetFileInfoResponse;

   PBYTE  pInputParamBuffer       = NULL;
   PBYTE  pOutputParamBuffer      = NULL;
   PBYTE  pInputDataBuffer        = NULL;
   PBYTE  pOutputDataBuffer       = NULL;

   ULONG  InputParamBufferLength  = 0;
   ULONG  OutputParamBufferLength = 0;
   ULONG  InputDataBufferLength   = 0;
   ULONG  OutputDataBufferLength  = 0;

   PAGED_CODE();

   RxDbgTrace(+1, Dbg, ("MRxSmbSetEaList...\n"));

   Status = STATUS_MORE_PROCESSING_REQUIRED;
   SetFileInfoResponse.EaErrorOffset = 0;

   smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);

   if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
      PSMB_TRANSACTION_OPTIONS            pTransactionOptions = &RxDefaultTransactionOptions;
      SMB_TRANSACTION_RESUMPTION_CONTEXT  ResumptionContext;

      SetFileInfoRequest.Fid = smbSrvOpen->Fid;
      SetFileInfoRequest.InformationLevel = SMB_INFO_SET_EAS;
      SetFileInfoRequest.Flags = 0;

      Status = SmbCeTransact(
                     RxContext,                    // the RXContext for the transaction
                     pTransactionOptions,          // transaction options
                     &Setup,                        // the setup buffer
                     sizeof(Setup),                // setup buffer length
                     NULL,                         // the output setup buffer
                     0,                            // output setup buffer length
                     &SetFileInfoRequest,          // Input Param Buffer
                     sizeof(SetFileInfoRequest),   // Input param buffer length
                     &SetFileInfoResponse,         // Output param buffer
                     sizeof(SetFileInfoResponse),  // output param buffer length
                     ServerEaList,                 // Input data buffer
                     SmbGetUlong(&ServerEaList->cbList), // Input data buffer length
                     NULL,                         // output data buffer
                     0,                            // output data buffer length
                     &ResumptionContext            // the resumption context
                     );

   }

   if (!NT_SUCCESS(Status)) {
      USHORT EaErrorOffset = SetFileInfoResponse.EaErrorOffset;
      RxDbgTrace( 0, Dbg, ("MRxSmbSetEaList: Failed .. returning %lx/%lx\n",Status,EaErrorOffset));
      RxContext->InformationToReturn = (EaErrorOffset);
   }

   RxDbgTrace(-1, Dbg, ("MRxSmbSetEaList...exit\n"));
   return Status;
}

NTSTATUS
MRxSmbQueryQuotaInformation(
    IN OUT PRX_CONTEXT RxContext)
{
    RxCaptureFobx;

    PMRX_SMB_SRV_OPEN smbSrvOpen;

    NTSTATUS Status;
    USHORT   Setup = NT_TRANSACT_QUERY_QUOTA;

    PSID   StartSid;
    ULONG  StartSidLength;

    REQ_NT_QUERY_FS_QUOTA_INFO  QueryQuotaInfoRequest;
    RESP_NT_QUERY_FS_QUOTA_INFO  QueryQuotaInfoResponse;

    PBYTE  pInputParamBuffer       = NULL;
    PBYTE  pOutputParamBuffer      = NULL;
    PBYTE  pInputDataBuffer        = NULL;
    PBYTE  pOutputDataBuffer       = NULL;

    ULONG  InputParamBufferLength  = 0;
    ULONG  OutputParamBufferLength = 0;
    ULONG  InputDataBufferLength   = 0;
    ULONG  OutputDataBufferLength  = 0;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbQueryQuotaInformation...\n"));

    Status = STATUS_MORE_PROCESSING_REQUIRED;

    if (capFobx != NULL) {
        smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
    }

    if ((capFobx == NULL) ||
        (smbSrvOpen == NULL)) {
        Status = STATUS_INVALID_PARAMETER;
    }

    if (Status == STATUS_MORE_PROCESSING_REQUIRED) {

        StartSid       = RxContext->QueryQuota.StartSid;

        if (StartSid != NULL) {
            StartSidLength = RtlLengthRequiredSid(((PISID)StartSid)->SubAuthorityCount);
        } else {
            StartSidLength = 0;
        }

        QueryQuotaInfoRequest.Fid = smbSrvOpen->Fid;

        QueryQuotaInfoRequest.ReturnSingleEntry = RxContext->QueryQuota.ReturnSingleEntry;
        QueryQuotaInfoRequest.RestartScan       = RxContext->QueryQuota.RestartScan;

        QueryQuotaInfoRequest.SidListLength = RxContext->QueryQuota.SidListLength;
        QueryQuotaInfoRequest.StartSidOffset =  ROUND_UP_COUNT(
                                                    RxContext->QueryQuota.SidListLength,
                                                    sizeof(ULONG));
        QueryQuotaInfoRequest.StartSidLength = StartSidLength;


        // The input data buffer to be supplied to the server consists of two pieces
        // of information the start sid and the sid list. Currently the I/O
        // subsystem allocates them in contigous memory. In such cases we avoid
        // another allocation by reusing the same buffer. If this condition is
        // not satisfied we allocate a buffer large enough for both the
        // components and copy them over.

        __assume_bound( RxContext->QueryQuota.SidListLength );
        __assume_bound( StartSidLength );

        InputDataBufferLength = ROUND_UP_COUNT(
                                    RxContext->QueryQuota.SidListLength,
                                    sizeof(ULONG)) +
                                StartSidLength;

        QueryQuotaInfoRequest.StartSidLength = StartSidLength;

        if (((PBYTE)RxContext->QueryQuota.SidList +
             ROUND_UP_COUNT(RxContext->QueryQuota.SidListLength,sizeof(ULONG))) !=
            RxContext->QueryQuota.StartSid) {
            pInputDataBuffer = RxAllocatePoolWithTag(
                                   PagedPool,
                                   InputDataBufferLength,
                                   MRXSMB_MISC_POOLTAG);

            if (pInputDataBuffer != NULL) {
                RtlCopyMemory(
                    pInputDataBuffer ,
                    RxContext->QueryQuota.SidList,
                    RxContext->QueryQuota.SidListLength);

                RtlCopyMemory(
                    pInputDataBuffer + QueryQuotaInfoRequest.StartSidOffset,
                    StartSid,
                    StartSidLength);
            } else {
                Status = STATUS_INSUFFICIENT_RESOURCES;
            }
        } else {
            pInputDataBuffer = (PBYTE)RxContext->QueryQuota.SidList;
        }


        if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
           SMB_TRANSACTION_OPTIONS            TransactionOptions = RxDefaultTransactionOptions;
           SMB_TRANSACTION_RESUMPTION_CONTEXT  ResumptionContext;

           TransactionOptions.NtTransactFunction = NT_TRANSACT_QUERY_QUOTA;

           pOutputDataBuffer      = RxContext->Info.Buffer;
           OutputDataBufferLength = RxContext->Info.LengthRemaining;

           Status = SmbCeTransact(
                        RxContext,                       // the RXContext for the transaction
                        &TransactionOptions,             // transaction options
                        &Setup,                          // the setup buffer
                        sizeof(Setup),                   // setup buffer length
                        NULL,                            // the output setup buffer
                        0,                               // output setup buffer length
                        &QueryQuotaInfoRequest,          // Input Param Buffer
                        sizeof(QueryQuotaInfoRequest),   // Input param buffer length
                        &QueryQuotaInfoResponse,         // Output param buffer
                        sizeof(QueryQuotaInfoResponse),  // output param buffer length
                        pInputDataBuffer,                // Input data buffer
                        InputDataBufferLength,           // Input data buffer length
                        pOutputDataBuffer,               // output data buffer
                        OutputDataBufferLength,          // output data buffer length
                        &ResumptionContext               // the resumption context
                        );
        }

        if ((pInputDataBuffer != NULL) &&
            (pInputDataBuffer != (PBYTE)RxContext->QueryQuota.SidList)) {
            RxFreePool(pInputDataBuffer);
        }
    }

    if (!NT_SUCCESS(Status)) {
        RxContext->InformationToReturn = 0;
    } else {
        RxContext->InformationToReturn = QueryQuotaInfoResponse.Length;
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbQueryQuotaInformation...exit\n"));

    return Status;
}

NTSTATUS
MRxSmbSetQuotaInformation(
    IN OUT PRX_CONTEXT RxContext)
{

    RxCaptureFobx;

    PMRX_SMB_SRV_OPEN smbSrvOpen;

    NTSTATUS Status;
    USHORT Setup = NT_TRANSACT_SET_QUOTA;

    REQ_NT_SET_FS_QUOTA_INFO  SetQuotaInfoRequest;

    PBYTE  pInputParamBuffer       = NULL;
    PBYTE  pOutputParamBuffer      = NULL;
    PBYTE  pInputDataBuffer        = NULL;
    PBYTE  pOutputDataBuffer       = NULL;

    ULONG  InputParamBufferLength  = 0;
    ULONG  OutputParamBufferLength = 0;
    ULONG  InputDataBufferLength   = 0;
    ULONG  OutputDataBufferLength  = 0;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbSetQuotaInformation...\n"));

    Status = STATUS_MORE_PROCESSING_REQUIRED;

    if (capFobx != NULL) {
        smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
    }

    if ((capFobx == NULL) ||
        (smbSrvOpen == NULL)) {
        Status = STATUS_INVALID_PARAMETER;
    }

    if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
        SMB_TRANSACTION_OPTIONS             TransactionOptions = RxDefaultTransactionOptions;
        SMB_TRANSACTION_RESUMPTION_CONTEXT  ResumptionContext;

        TransactionOptions.NtTransactFunction = NT_TRANSACT_SET_QUOTA;

        SetQuotaInfoRequest.Fid = smbSrvOpen->Fid;

        pInputDataBuffer      = RxContext->Info.Buffer;
        InputDataBufferLength = RxContext->Info.LengthRemaining;

        Status = SmbCeTransact(
                     RxContext,                       // the RXContext for the transaction
                     &TransactionOptions,             // transaction options
                     &Setup,                          // the setup buffer
                     sizeof(Setup),                   // setup buffer length
                     NULL,                            // the output setup buffer
                     0,                               // output setup buffer length
                     &SetQuotaInfoRequest,            // Input Param Buffer
                     sizeof(SetQuotaInfoRequest),     // Input param buffer length
                     pOutputParamBuffer,              // Output param buffer
                     OutputParamBufferLength,         // output param buffer length
                     pInputDataBuffer,                // Input data buffer
                     InputDataBufferLength,           // Input data buffer length
                     pOutputDataBuffer,               // output data buffer
                     OutputDataBufferLength,          // output data buffer length
                     &ResumptionContext               // the resumption context
                     );
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbSetQuotaInformation...exit\n"));

    return Status;
}

⌨️ 快捷键说明

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