bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
阅读:1736回复: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一个.......菜鸟的路真崎岖,也许这个问题太幼稚了,高手都没兴趣回答啊。
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
板凳#
发布于:2009-02-26 00:12
Sorry, read your post several times, still don't get what you really want. I'd suggest you describe your CREATE routine in more details, pseudocode will be perfect, and what error your got when 写标识 failed.

By the way, for a new file, before the IRP passed down to lower file system, that file is not exist. How can you write anything into a non-existing file?
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程序,结果也一样。
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
5楼#
发布于:2009-02-26 23:58
Man, I hate read others' code. But following piece from your function SfWriteEncryptFlag  doesn't make any sense:

  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;
    }


Also mostly the reason to construct a customized IRP is to by-pass driver stack. I would suggest you either use ZwWriteFile or use attached device object to build an IRP.

One question, why don't you use MiniFilter which is much more easier to understand and develop for a newcomer?
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2009-02-27 18:08
  Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );

    if (Irp == NULL) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }
这部分代码贴出来时忘了删掉,这部分是后来用IoBuildAsynchronousFsdRequest()失败后想试下用的,误导了大侠,真是  我决定听从大侠的意见,试一下MiniFilter和ZwWriteFile。非常感谢热心的michaelgz 大侠。
looksail
荣誉会员
荣誉会员
  • 注册日期2005-05-22
  • 最后登录2014-03-15
  • 粉丝2
  • 关注0
  • 积分1016分
  • 威望991点
  • 贡献值0点
  • 好评度239点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2009-03-01 12:47
又见michaelgz

可以写的,但是要考虑到此种情况是要判断文件名的
提问归提问,还是只能靠自己
bravery36
驱动牛犊
驱动牛犊
  • 注册日期2008-03-08
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分46分
  • 威望376点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2009-03-01 20:30
looksail大侠你好,判断文件名有什么特殊含义吗?可否详细讲讲。在我的理解里,在create里面将文件名提出来是给将来read,write和cleanup的函数用的,大侠特意说的判断文件名是有什么我完全没注意到的地方吗?
游客

返回顶部