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

📄 ea.c

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

Copyright (c) 1989 - 1999  Microsoft Corporation

Module Name:

    ea.c

Abstract:

    This module implements the mini redirector call down routines pertaining to query/set ea/security.

--*/

#include "precomp.h"
#pragma hdrstop

//
// Forward declarations.
//



#ifdef  ALLOC_PRAGMA
#pragma alloc_text(PAGE, MRxSmbQueryEaInformation)
#pragma alloc_text(PAGE, MRxSmbSetEaInformation)
#pragma alloc_text(PAGE, MRxSmbQuerySecurityInformation)
#pragma alloc_text(PAGE, MRxSmbSetSecurityInformation)
#pragma alloc_text(PAGE, MRxSmbLoadEaList)
#pragma alloc_text(PAGE, MRxSmbNtGeaListToOs2)
#pragma alloc_text(PAGE, MRxSmbNtGetEaToOs2)
#pragma alloc_text(PAGE, MRxSmbQueryEasFromServer)
#pragma alloc_text(PAGE, MRxSmbNtFullEaSizeToOs2)
#pragma alloc_text(PAGE, MRxSmbNtFullListToOs2)
#pragma alloc_text(PAGE, MRxSmbNtFullEaToOs2)
#pragma alloc_text(PAGE, MRxSmbSetEaList)
#endif

////
////  The Bug check file id for this module
////
//
//#define BugCheckFileId                   (RDBSS_BUG_CHECK_LOCAL_CREATE)

//
//  The local debug trace level
//

#define Dbg                              (DEBUG_TRACE_EA)

//this is the largest EAs that could ever be returned!
//this is used to simulate the nt resumable queryEA using the downlevel call
//sigh!
#define EA_QUERY_SIZE 0x0000ffff


//for QueryEA
NTSTATUS
MRxSmbLoadEaList(
    IN PRX_CONTEXT RxContext,
    IN PUCHAR  UserEaList,
    IN ULONG   UserEaListLength,
    OUT PFEALIST *ServerEaList
    );

NTSTATUS
MRxSmbQueryEasFromServer(
    IN PRX_CONTEXT RxContext,
    IN PFEALIST ServerEaList,
    IN PVOID Buffer,
    IN OUT PULONG BufferLengthRemaining,
    IN BOOLEAN ReturnSingleEntry,
    IN BOOLEAN UserEaListSupplied
    );

//for SetEA
NTSTATUS
MRxSmbSetEaList(
//    IN PICB Icb,
//    IN PIRP Irp,
    IN PRX_CONTEXT RxContext,
    IN PFEALIST ServerEaList
    );

VOID MRxSmbExtraEaRoutine(LONG i){
    RxDbgTrace( 0, Dbg, ("MRxSmbExtraEaRoutine i=%08lx\n", i ));
}

NTSTATUS
MRxSmbQueryEaInformation (
    IN OUT PRX_CONTEXT RxContext
    )
{
    NTSTATUS Status;
    RxCaptureFcb;
    RxCaptureFobx;

    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PVOID Buffer = RxContext->Info.Buffer;
    PLONG pLengthRemaining = &RxContext->Info.LengthRemaining;
    PUCHAR  UserEaList = RxContext->QueryEa.UserEaList;
    ULONG   UserEaListLength = RxContext->QueryEa.UserEaListLength;
    ULONG   UserEaIndex = RxContext->QueryEa.UserEaIndex;
    BOOLEAN RestartScan = RxContext->QueryEa.RestartScan;
    BOOLEAN ReturnSingleEntry = RxContext->QueryEa.ReturnSingleEntry;
    BOOLEAN IndexSpecified = RxContext->QueryEa.IndexSpecified;

    PFEALIST ServerEaList = NULL;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbQueryEaInformation\n"));

    pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

    //get rid of nonEA guys right now
    if (!FlagOn(pServerEntry->Server.DialectFlags,DF_SUPPORTEA)) {
        RxDbgTrace(-1, Dbg, ("EAs w/o EA support!\n"));
        return((STATUS_NOT_SUPPORTED));
    }

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

    Status = MRxSmbLoadEaList( RxContext, UserEaList, UserEaListLength, &ServerEaList );

    if (( !NT_SUCCESS( Status ) )||
        ( ServerEaList == NULL )) {
        goto FINALLY;
    }

    if (IndexSpecified) {

        capFobx->OffsetOfNextEaToReturn = UserEaIndex;
        Status = MRxSmbQueryEasFromServer(
                    RxContext,
                    ServerEaList,
                    Buffer,
                    pLengthRemaining,
                    ReturnSingleEntry,
                    (BOOLEAN)(UserEaList != NULL) );

        //
        //  if there are no Ea's on the file, and the user supplied an EA
        //  index, we want to map the error to STATUS_NONEXISTANT_EA_ENTRY.
        //

        if ( Status == STATUS_NO_EAS_ON_FILE ) {
            Status = STATUS_NONEXISTENT_EA_ENTRY;
        }
    } else {

        if ( ( RestartScan == TRUE ) || (UserEaList != NULL) ){

            //
            // Ea Indices start at 1, not 0....
            //

            capFobx->OffsetOfNextEaToReturn = 1;
        }

        Status = MRxSmbQueryEasFromServer(  //it is offensive to have two identical calls but oh, well.....
                    RxContext,
                    ServerEaList,
                    Buffer,
                    pLengthRemaining,
                    ReturnSingleEntry,
                    (BOOLEAN)(UserEaList != NULL) );
    }

FINALLY:

    if ( ServerEaList != NULL) {
        RxFreePool(ServerEaList);
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbQueryEaInformation st=%08lx\n",Status));
    return Status;

}

NTSTATUS
MRxSmbSetEaInformation (
    IN OUT struct _RX_CONTEXT * RxContext
    )
{
    NTSTATUS Status;
    RxCaptureFcb; RxCaptureFobx;
    PSMBCEDB_SERVER_ENTRY pServerEntry;

    PVOID Buffer = RxContext->Info.Buffer;
    ULONG Length = RxContext->Info.Length;

    PFEALIST ServerEaList = NULL;
    ULONG Size;

    PAGED_CODE();

    RxDbgTrace(+1, Dbg, ("MRxSmbSetEaInformation\n"));

    pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

    //get rid of nonEA guys right now
    if (!FlagOn(pServerEntry->Server.DialectFlags,DF_SUPPORTEA)) {
        RxDbgTrace(-1, Dbg, ("EAs w/o EA support!\n"));
        return((STATUS_NOT_SUPPORTED));
    }

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

    //
    //  Convert Nt format FEALIST to OS/2 format
    //
    Size = MRxSmbNtFullEaSizeToOs2 ( Buffer );
    if ( Size > 0x0000ffff ) {
        Status = STATUS_EA_TOO_LARGE;
        goto FINALLY;
    }

    ServerEaList = RxAllocatePool ( PagedPool, EA_QUERY_SIZE );
    if ( ServerEaList == NULL ) {
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto FINALLY;
    }

    MRxSmbNtFullListToOs2 ( Buffer, ServerEaList );

    //
    //  Set EAs on the file/directory; if the error is EA_ERROR then SetEaList
    //     sets iostatus.information to the offset of the offender
    //

    Status = MRxSmbSetEaList( RxContext, ServerEaList);

FINALLY:

    if ( ServerEaList != NULL) {
        RxFreePool(ServerEaList);
    }

    RxDbgTrace(-1, Dbg, ("MRxSmbSetEaInformation st=%08lx\n",Status));
    return Status;

}


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

Routine Description:

    This routine implements the NtQuerySecurityFile api.


Arguments:



Return Value:

    Status - Result of the operation.


--*/

{
   RxCaptureFcb;
   RxCaptureFobx;
   PVOID Buffer = RxContext->Info.Buffer;
   PLONG pLengthRemaining = &RxContext->Info.LengthRemaining;
   PMRX_SMB_SRV_OPEN smbSrvOpen;
   PSMBCEDB_SERVER_ENTRY pServerEntry;

   NTSTATUS Status;

   REQ_QUERY_SECURITY_DESCRIPTOR QuerySecurityRequest;
   RESP_QUERY_SECURITY_DESCRIPTOR QuerySecurityResponse;

   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, ("MRxSmbQuerySecurityInformation...\n"));

   // Turn away this call from those servers which do not support the NT SMBs

   pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

   if (!FlagOn(pServerEntry->Server.DialectFlags,DF_NT_SMBS)) {
       RxDbgTrace(-1, Dbg, ("QuerySecurityDescriptor not supported!\n"));
       return((STATUS_NOT_SUPPORTED));
   }

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

   Status = STATUS_MORE_PROCESSING_REQUIRED;

   smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);
   ASSERT (!FlagOn(smbSrvOpen->Flags,SMB_SRVOPEN_FLAG_NOT_REALLY_OPEN));

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

       TransactionOptions.NtTransactFunction = NT_TRANSACT_QUERY_SECURITY_DESC;
       //TransactionOptions.Flags |= SMB_XACT_FLAGS_COPY_ON_ERROR;

       QuerySecurityRequest.Fid = smbSrvOpen->Fid;
       QuerySecurityRequest.Reserved = 0;
       QuerySecurityRequest.SecurityInformation = RxContext->QuerySecurity.SecurityInformation;

       QuerySecurityResponse.LengthNeeded = 0xbaadbaad;

       //printflag = RxDbgTraceDisableGlobally();//this is debug code anyway!
       //RxDbgTraceEnableGlobally(FALSE);

       Status = SmbCeTransact(
                     RxContext,                    // the RXContext for the transaction
                     &TransactionOptions,          // transaction options
                     NULL,                         // the setup buffer
                     0,                            // input setup buffer length
                     NULL,                         // output setup buffer
                     0,                            // output setup buffer length
                     &QuerySecurityRequest,        // Input Param Buffer
                     sizeof(QuerySecurityRequest), // Input param buffer length
                     &QuerySecurityResponse,       // Output param buffer
                     sizeof(QuerySecurityResponse),// output param buffer length
                     NULL,                         // Input data buffer
                     0,                            // Input data buffer length
                     Buffer,                       // output data buffer
                     *pLengthRemaining,            // output data buffer length
                     &ResumptionContext            // the resumption context
                     );

        //DbgPrint("QSR.len=%x\n", QuerySecurityResponse.LengthNeeded);


        if (NT_SUCCESS(Status) || (Status == STATUS_BUFFER_TOO_SMALL)) {
            ULONG ReturnedDataCount = ResumptionContext.DataBytesReceived;

            RxContext->InformationToReturn = QuerySecurityResponse.LengthNeeded;
            RxDbgTrace(0, Dbg, ("MRxSmbQuerySecurityInformation...ReturnedDataCount=%08lx\n",ReturnedDataCount));
            ASSERT(ResumptionContext.ParameterBytesReceived == sizeof(RESP_QUERY_SECURITY_DESCRIPTOR));

            if (((LONG)(QuerySecurityResponse.LengthNeeded)) > *pLengthRemaining) {
                Status = STATUS_BUFFER_OVERFLOW;
            }

        }

        //RxDbgTraceEnableGlobally(printflag);
    }


FINALLY:

    RxDbgTrace(-1, Dbg, ("MRxSmbQuerySecurityInformation...exit, st=%08lx,info=%08lx\n",
                               Status, RxContext->InformationToReturn));
    return Status;


}

NTSTATUS
MRxSmbSetSecurityInformation (
    IN OUT struct _RX_CONTEXT * RxContext
    )
{
    RxCaptureFcb;
    RxCaptureFobx;

    PMRX_SMB_SRV_OPEN     smbSrvOpen;
    PSMBCEDB_SERVER_ENTRY pServerEntry;

    NTSTATUS Status;

    REQ_SET_SECURITY_DESCRIPTOR SetSecurityRequest;

    PAGED_CODE();

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

    pServerEntry = SmbCeGetAssociatedServerEntry(capFcb->pNetRoot->pSrvCall);

    if (!FlagOn(pServerEntry->Server.DialectFlags,DF_NT_SMBS)) {
        RxDbgTrace(-1, Dbg, ("Set Security Descriptor not supported!\n"));

        return((STATUS_NOT_SUPPORTED));

    }

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

    Status = STATUS_MORE_PROCESSING_REQUIRED;

    smbSrvOpen = MRxSmbGetSrvOpenExtension(capFobx->pSrvOpen);

    if (Status == STATUS_MORE_PROCESSING_REQUIRED) {
        SMB_TRANSACTION_OPTIONS             TransactionOptions = RxDefaultTransactionOptions;
        SMB_TRANSACTION_RESUMPTION_CONTEXT  ResumptionContext;
        ULONG SdLength = RtlLengthSecurityDescriptor(RxContext->SetSecurity.SecurityDescriptor);

        TransactionOptions.NtTransactFunction = NT_TRANSACT_SET_SECURITY_DESC;

        SetSecurityRequest.Fid = smbSrvOpen->Fid;
        SetSecurityRequest.Reserved = 0;
        SetSecurityRequest.SecurityInformation = RxContext->SetSecurity.SecurityInformation;

        Status = SmbCeTransact(
                     RxContext,                    // the RXContext for the transaction
                     &TransactionOptions,          // transaction options
                     NULL,                         // the input setup buffer
                     0,                            // input setup buffer length
                     NULL,                         // the output setup buffer
                     0,                            // output setup buffer length
                     &SetSecurityRequest,          // Input Param Buffer
                     sizeof(SetSecurityRequest),   // Input param buffer length
                     NULL,                         // Output param buffer
                     0,                            // output param buffer length
                     RxContext->SetSecurity.SecurityDescriptor,  // Input data buffer
                     SdLength,                     // Input data buffer length
                     NULL,                         // output data buffer
                     0,                            // output data buffer length
                     &ResumptionContext            // the resumption context
                     );

        //the old rdr doesn't return any info...................
        //RxContext->InformationToReturn = SetSecurityResponse.LengthNeeded;

        if ( NT_SUCCESS(Status) ) {
            ULONG ReturnedDataCount = ResumptionContext.DataBytesReceived;

            RxDbgTrace(0, Dbg, ("MRxSmbSetSecurityInformation...ReturnedDataCount=%08lx\n",ReturnedDataCount));
            ASSERT(ResumptionContext.ParameterBytesReceived == 0);
            ASSERT(ResumptionContext.SetupBytesReceived == 0);
            ASSERT(ResumptionContext.DataBytesReceived == 0);
        }
    }


FINALLY:

    RxDbgTrace(-1, Dbg, ("MRxSmbSetSecurityInformation...exit, st=%08lx,info=%08lx\n",
                               Status, RxContext->InformationToReturn));
    return Status;
}


NTSTATUS
MRxSmbLoadEaList(
    IN PRX_CONTEXT RxContext,
    IN PUCHAR  UserEaList,
    IN ULONG   UserEaListLength,
    OUT PFEALIST *ServerEaList
    )

/*++

Routine Description:

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


Arguments:

⌨️ 快捷键说明

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