bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:1747回复:8

请问下能否在IRP_MJ_CREATE的例程中写文件的加密标识?

楼主#
更多 发布于:2009-02-23 16:57
我的计划是当文件新建的时候就在文件头加上个加密标识,参考了前人的一些文章,使用的函数是IoBuildAsynchronousFsdRequest(.....)。目前在IRP_MJ_CREATE的例程用IoBuildAsynchronousFsdRequest()函数读已有文件中的标识是可以的,但是在文件新建的时候写标识就失败了,我想知道是自己函数处理的问题还是不能用IoBuildAsynchronousFsdRequest(.....)在IRP_MJ_CREATE的例程写标识,先谢谢热心解答的大侠。
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2009-02-25 12:19
    自己re一个.......菜鸟的路真崎岖,也许这个问题太幼稚了,高手都没兴趣回答啊。
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2009-02-26 17:04
谢谢大侠的谢心回复。我写加密标识是在文件新建完成后写的,用的函数是自定义的SfWriteEncryptFlag。
这样贴代码有些凌乱,希望大侠不见怪。由于小弟对这个理解不深,可能会有一些常识性的错误。
NTSTATUS
SfCreate (
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This function filters create/open operations.  It simply establishes an
    I/O completion routine to be invoked if the operation was successful.

Arguments:

    DeviceObject - Pointer to the target device object of the create/open.

    Irp - Pointer to the I/O Request Packet that represents the operation.

Return Value:

    The function value is the status of the call to the file system's entry
    point.

--*/

{
    NTSTATUS status;
    
    //
    //添加部分
    //
        PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
        PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
        PFILE_OBJECT FileObject = IrpSp->FileObject;
        PWSTR FileName = NULL;
        ULONG FileNameLength = 0;
      NTSTATUS Status = STATUS_SUCCESS;
      POST_CREATE_WORKER_CONTEXT WorkerCtx;
     // UNICODE_STRING UNIFileName;
     // ANSI_STRING ANSIFileName;
    //  WCHAR UNIBuf[MAX_PATH];
    //  CHAR ANSIBuf[MAX_PATH];
      
    PAGED_CODE();

    //
    //  If this is for our control device object, don't allow it to be opened.
    //
    
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {

        //
        //  Sfilter doesn't allow for any communication through its control
        //  device object, therefore it fails all requests to open a handle
        //  to its control device object.
        //
        //  See the FileSpy sample for an example of how to allow creates to
        //  the filter's control device object and manage communication via
        //  that handle.
        //

        Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Information = 0;

        IoCompleteRequest( Irp, IO_NO_INCREMENT );

        return STATUS_INVALID_DEVICE_REQUEST;
    }

    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));

    //
    //  If debugging is enabled, do the processing required to see the packet
    //  upon its completion.  Otherwise, let the request go with no further
    //  processing.
    //
    
    //
        // We only care about volume filter device object
        // 我们仅关心卷过滤设备对象
        //
        if (!DevExt->StorageStackDeviceObject)
        {
            IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
        }
        
        #if DBG
        if (DevExt->DriveLetter != DEBUG_VOLUME)
        {
            IoSkipCurrentIrpStackLocation(Irp);
            return IoCallDriver(DevExt->AttachedToDeviceObject, Irp);
        }
        #endif
        
        do
        {
        KEVENT waitEvent;
        //
        //  Initialize an event to wait for the completion routine to occur
        //

        KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );

        //
        //  Copy the stack and set our Completion routine
        //
                
        IoCopyCurrentIrpStackLocationToNext( Irp );
                
        IoSetCompletionRoutine(
            Irp,
            SfCreateCompletion,
            &waitEvent,
            TRUE,
            TRUE,
            TRUE );

        //
        //  Call the next driver in the stack.
        //

        status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );

        //
        //  Wait for the completion routine to be called
        //

        if (STATUS_PENDING == status) {

            NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
            ASSERT(STATUS_SUCCESS == localStatus);
        }

        //
        //  Verify the IoCompleteRequest was called
        //

        ASSERT(KeReadStateEvent(&waitEvent) ||
               !NT_SUCCESS(Irp->IoStatus.Status));

        if (!(IrpSp->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID))
        {
            FileName = ExAllocateFromPagedLookasideList(&gFileNameLookAsideList);
            if (!FileName)
            {
                KdPrint(("sfilter!SfCreate: ExAllocatePoolWithTag failed\n"));

                Status = STATUS_INSUFFICIENT_RESOURCES;
                break;
            }
        
          SfGetFileNameFromFileObject(DevExt, FileObject, &FileNameLength, FileName);
        
            if (0 == _wcsnicmp(&FileName[3], SF_ENCRYPT_INFO_DIR, SF_ENCRYPT_INFOR_DIR_LENGTH))
            {
                //
                // We deny all create request to our encrypt info dir except kernel mode
                //
                if (KernelMode == Irp->RequestorMode)
                {
                    ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName);

                    status = Irp->IoStatus.Status;
                 IoCompleteRequest( Irp, IO_NO_INCREMENT );
              return status;
                }
                else
                {
                    Status = STATUS_NO_SUCH_FILE;
                    break;
                }
            }
            else
            {
                if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
                {
                    //
                    // We don't care about directories
                    //
                    ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName);

                    status = Irp->IoStatus.Status;
          IoCompleteRequest( Irp, IO_NO_INCREMENT );
          return status;
                }
            }
        }
        else
        {
            if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE)
            {
                //
                // We don't care about directories
                //
                  status = Irp->IoStatus.Status;
                  IoCompleteRequest( Irp, IO_NO_INCREMENT );
              return status;
            }
        }
        //Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp);
        //if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status))
        {    
                 if((Irp->IoStatus.Information == FILE_CREATED) || (Irp->IoStatus.Information == FILE_OPENED))
                {
                        
                        FILE_CONTEXT FileCtx;
                        PFILE_CONTEXT FileCtxPtr = NULL;
                        BOOLEAN NewElement = FALSE;
                        
                       FileCtx.FsContext = FileObject->FsContext;

                        ExAcquireFastMutex(&DevExt->FsCtxTableMutex);

                        FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtx);
                        if (FileCtxPtr)
                                ++FileCtxPtr->RefCount;
                        else
                        {
                            FileCtxPtr = RtlInsertElementGenericTable(
                            &DevExt->FsCtxTable,
                            &FileCtx,
                            sizeof(FILE_CONTEXT),
                            &NewElement
                          );

                          FileCtxPtr->RefCount = 1;

                          ASSERT(FileName);
                          wcscpy(FileCtxPtr->Name, FileName);

                          KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE);
                          
                        }
                        ExReleaseFastMutex(&DevExt->FsCtxTableMutex);
                        
                            if(!_wcsnicmp(FileName,L"D:\\Test\\",8))
                            {
                                    
                                   if ((NodeType(FileObject->FsContext) == FAT_NTC_DCB) ||
                                            (NodeType(FileObject->FsContext) == FAT_NTC_ROOT_DCB) ||
                                            (NodeType(FileObject->FsContext) == NTFS_NTC_DCB) ||
                                            (NodeType(FileObject->FsContext) == NTFS_NTC_ROOT_DCB))
                                            {
                                                if (FileName)
                                                        ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName);
                                                status = Irp->IoStatus.Status;
                                                IoCompleteRequest( Irp, IO_NO_INCREMENT );    
                                                return status;
                                  
                                           }
                
                     ExInitializeWorkItem(&WorkerCtx.WorkItem, SfWriteEncryptFlag, &WorkerCtx);
                       WorkerCtx.DeviceObject = DeviceObject;
                       WorkerCtx.FileObject = FileObject;
                       KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE);
                       WorkerCtx.FileContext = FileCtxPtr;
                          if( Irp->IoStatus.Information == FILE_CREATED )
                              {
                          
                                if (KeGetCurrentIrql() == PASSIVE_LEVEL)
                                    SfWriteEncryptFlag(&WorkerCtx);
                                else
                                {
                                    ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue);
                                    KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL);
                                }
            
                              }
                                                 }  
                }
            }    
        }while(FALSE);
    
        //
        //  Save the status and continue processing the IRP
        //
                if (FileName)
                ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName);
        status = Irp->IoStatus.Status;
        
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        
        return status;
}
static NTSTATUS MyIrpComplete(
                              PDEVICE_OBJECT  DeviceObject,
                              PIRP            Irp,
                              PVOID          Context
                              )
{
    UNREFERENCED_PARAMETER( DeviceObject );
    UNREFERENCED_PARAMETER( Context );
   // *Irp->UserIosb = Irp->IoStatus;        // Copy status information to
    // the user
    
    if (Irp->MdlAddress)
    {
        MmUnmapLockedPages(
            MmGetSystemAddressForMdl(Irp->MdlAddress),
            Irp->MdlAddress);
        MmUnlockPages(Irp->MdlAddress);
        IoFreeMdl(Irp->MdlAddress);
        Irp->MdlAddress = NULL;
    }
    KeSetEvent(Irp->UserEvent, 0, FALSE);  // Signal event
    IoFreeIrp(Irp);                        // Free IRP
    return STATUS_MORE_PROCESSING_REQUIRED; // Tell the I/O manager to stop
}

NTSTATUS
SfIssueReadWriteIrpSynchronously(
    IN PDEVICE_OBJECT DeviceObject,
    IN PFILE_OBJECT FileObject,
    IN ULONG MajorFunction,
    IN PIO_STATUS_BLOCK IoStatus,
    IN PVOID Buffer,
    IN ULONG Length,
    IN PLARGE_INTEGER ByteOffset,
    IN ULONG IrpFlags
    )
{
    PIRP Irp = NULL;
    PIO_STACK_LOCATION IrpSp = NULL;
    KEVENT Event;
    NTSTATUS Status;
    //FILE_STANDARD_INFORMATION  StandardInformation;
    UNREFERENCED_PARAMETER( IrpFlags );
    ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE));
    
    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    Irp = IoBuildAsynchronousFsdRequest(
        MajorFunction,
        DeviceObject,
        Buffer,
        Length,
        ByteOffset,
        IoStatus
       );
   if (!Irp)
       return STATUS_INSUFFICIENT_RESOURCES;

            Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );

    if (Irp == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }
  
    Irp->Flags = 0x43;
    Irp->UserEvent = &Event;
    IrpSp = IoGetNextIrpStackLocation(Irp);
    IrpSp->FileObject = FileObject;
    Irp->IoStatus.Information = 0;
    IoSetCompletionRoutine(Irp, &MyIrpComplete, 0, TRUE, TRUE, TRUE);
    Status = IoCallDriver(DeviceObject, Irp);
    if (STATUS_PENDING == Status)
    {
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    }
    //IoCompleteRequest( Irp, IO_NO_INCREMENT );
    KdPrint(("SfIssueReadWriteIrpSynchronously! MajorFunction = %x, Buffer = %s, Length = %d\n",MajorFunction, Buffer, Length));
    return IoStatus->Status;
}

NTSTATUS
SfWriteEncryptFlag(IN PVOID Context)
{
    PPOST_CREATE_WORKER_CONTEXT WorkerCtx = Context;
    NTSTATUS Status;
    IO_STATUS_BLOCK  IoStatus={0};
    UCHAR Buff[13]= "测试用的标记";
    LARGE_INTEGER ByteOffset;
    PFILE_CONTEXT FileCtxPtr = WorkerCtx->FileContext;
    
    KeWaitForSingleObject(&FileCtxPtr->Event, Executive, KernelMode, FALSE, NULL);
        KdPrint(("SfWriteEncryptFlag! WorkerCtx.FileContext->Name = %ws\n", WorkerCtx->FileContext->Name));
    ByteOffset.QuadPart = 0;
    IoStatus.Status = STATUS_SUCCESS;
    IoStatus.Information = 0;
    Status =SfIssueReadWriteIrpSynchronously(WorkerCtx->DeviceObject
        ,WorkerCtx->FileObject,IRP_MJ_WRITE,&IoStatus,Buff,
        12,&ByteOffset,0);
    if (!NT_SUCCESS(Status))
    {      
        KdPrint(("SFilter!SfWriteEncryptFlag ERROR: %s\n\n", Buff));
    }

    KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE);
    KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE);
 
    return Status;
    
}
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
地板#
发布于:2009-02-26 17:09
忘了说一下具体的症状,在SfWriteEncryptFlag这个函数运行之后,是有对应的fileOject进入了我的sfwrite中的,而sfwrite中的buffer也可以看到自己传下来的内容(不过不知道边界有没有处理好),然而运行完sfwrite后文件内容还是空的,什么也没写进去。我也试过去掉自己写的sfwrite程序,结果也一样。
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2009-02-27 18:08
  Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );

    if (Irp == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }
这部分代码贴出来时忘了删掉,这部分是后来用IoBuildAsynchronousFsdRequest()失败后想试下用的,误导了大侠,真是  我决定听从大侠的意见,试一下MiniFilter和ZwWriteFile。非常感谢热心的michaelgz 大侠。
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2009-03-01 20:30
looksail大侠你好,判断文件名有什么特殊含义吗?可否详细讲讲。在我的理解里,在create里面将文件名提出来是给将来read,write和cleanup的函数用的,大侠特意说的判断文件名是有什么我完全没注意到的地方吗?
游客

返回顶部