最近发现了FileDisk这个好东东,于是就想把它改成一个虚拟目录软件.与SUBST不同的是,我想把所有写操作都映射到另一个目录,这样无论对虚拟磁盘做什么操作,都不会影响到原目录的内容.可是现在第一步就不知道如何处理了-----FileDisk需要一个文件,如何才能让它可以直接映射一个目录呢?我认为焦点是在FileDiskThread过程里,但不知道如何改.....系统读取一个文件时(上层API为ReadFile时),对于目录到底是如何处理的呢?有没有什么书详细讲到文件操作与管理呢?附上FileDiskThread过程代码:VOID
FileDiskThread (
    IN PVOID Context
    )
{
    PDEVICE_OBJECT      device_object;
    PDEVICE_EXTENSION   device_extension;
    PLIST_ENTRY         request;
    PIRP                irp;
    PIO_STACK_LOCATION  io_stack;
    PUCHAR              system_buffer;
    PUCHAR              buffer;    ASSERT(Context != NULL);    device_object = (PDEVICE_OBJECT) Context;    device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);    for (;;)
    {
        KeWaitForSingleObject(
            &device_extension->request_event,
            Executive,
            KernelMode,
            FALSE,
            NULL
            );        if (device_extension->terminate_thread)
        {
            PsTerminateSystemThread(STATUS_SUCCESS);
        }        while (request = ExInterlockedRemoveHeadList(
            &device_extension->list_head,
            &device_extension->list_lock
            ))
        {
            irp = CONTAINING_RECORD(request, IRP, Tail.Overlay.ListEntry);            io_stack = IoGetCurrentIrpStackLocation(irp);            switch (io_stack->MajorFunction)
            {
            case IRP_MJ_READ:
                system_buffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority);
                if (system_buffer == NULL)
                {
                    irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    irp->IoStatus.Information = 0;
                    break;
                }
                buffer = (PUCHAR) ExAllocatePool(PagedPool, io_stack->Parameters.Read.Length);
                if (buffer == NULL)
                {
                    irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
                    irp->IoStatus.Information = 0;
                    break;
                }
                ZwReadFile(
                    device_extension->file_handle,
                    NULL,
                    NULL,
                    NULL,
                    &irp->IoStatus,
                    buffer,
                    io_stack->Parameters.Read.Length,
                    &io_stack->Parameters.Read.ByteOffset,
                    NULL
                    );
                RtlCopyMemory(system_buffer, buffer, io_stack->Parameters.Read.Length);
                ExFreePool(buffer);
                break;            case IRP_MJ_WRITE:
                if ((io_stack->Parameters.Write.ByteOffset.QuadPart +
                     io_stack->Parameters.Write.Length) >
                     device_extension->file_size.QuadPart)
                {
                    irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
                    irp->IoStatus.Information = 0;
                }
                ZwWriteFile(
                    device_extension->file_handle,
                    NULL,
                    NULL,
                    NULL,
                    &irp->IoStatus,
                    MmGetSystemAddressForMdlSafe(irp->MdlAddress, NormalPagePriority),
                    io_stack->Parameters.Write.Length,
                    &io_stack->Parameters.Write.ByteOffset,
                    NULL
                    );
                break;            case IRP_MJ_DEVICE_CONTROL:
                switch (io_stack->Parameters.DeviceIoControl.IoControlCode)
                {
                case IOCTL_FILE_DISK_OPEN_FILE:                    //SeImpersonateClient(device_extension->security_client_context, NULL);                    //irp->IoStatus.Status = FileDiskOpenFile(device_object, irp);                    //PsRevertToSelf();                    break;                case IOCTL_FILE_DISK_CLOSE_FILE:
                    //irp->IoStatus.Status = FileDiskCloseFile(device_object, irp);
                    break;                default:
                    irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
                }
                break;            default:
                irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
            }            IoCompleteRequest(
                irp,
                (CCHAR) (NT_SUCCESS(irp->IoStatus.Status) ?
                IO_DISK_INCREMENT : IO_NO_INCREMENT)
                );
        }
    }
}

解决方案 »

  1.   

    我后来又想了一下,IOCTL_FILE_DISK_OPEN_FILE/IOCTL_FILE_DISK_CLOSE_FILE这两个消息分别是打开一个文件/关闭一个文件,而以后的读写都是基于这个文件的。我能否在这两个消息里面给一个目录的句柄呢?
      

  2.   

    谢谢楼上朋友那么为什么不可以呢?正确的做法是什么?Subst后面的那个驱动是如何做到的?
      

  3.   

    FileDisk只是处理磁盘操作行为,可以在IRP_MJ_WRITE 和IRP_MJ_READ 中实现磁盘数据加密之类的工作。你说的同时包含了对文件系统的过滤过程。建议看看文件过滤系统开发
      

  4.   

    文件系统过滤.......应该也是处理这些IRP请求吧?能否整合到一起来呢?具体是哪些的请求?有没有相应的书可以参考?
      

  5.   

    直接使用subst不就得了?subst没有用到什么驱动。
      

  6.   

    .text:0100147B ; int __stdcall ?AddSubst(LPCWSTR lpDeviceName,wchar_t *,int,int)
    .text:0100147B ?AddSubst@@YGEPAG0KPAVMESSAGE@@@Z proc near ; CODE XREF: _main+626p
    .text:0100147B
    .text:0100147B TargetPath      = word ptr -234h
    .text:0100147B var_1C          = dword ptr -1Ch
    .text:0100147B var_8           = dword ptr -8
    .text:0100147B lpTargetPath    = dword ptr -4
    .text:0100147B lpDeviceName    = dword ptr  8
    .text:0100147B arg_4           = dword ptr  0Ch
    .text:0100147B arg_C           = dword ptr  14h
    .text:0100147B
    .text:0100147B                 push    ebp
    .text:0100147C                 mov     ebp, esp
    .text:0100147E                 sub     esp, 234h
    .text:01001484                 push    ebx
    .text:01001485                 push    esi
    .text:01001486                 push    edi
    .text:01001487                 lea     ecx, [ebp+var_1C]
    .text:0100148A                 call    ds:__imp_??0FSTRING@@QAE@XZ ; FSTRING::FSTRING(void)
    .text:01001490                 lea     eax, [ebp+lpTargetPath]
    .text:01001493                 push    eax             ; int
    .text:01001494                 push    10Ch            ; ucchMax
    .text:01001499                 lea     eax, [ebp+TargetPath]
    .text:0100149F                 push    eax             ; lpTargetPath
    .text:010014A0                 mov     eax, [ebp+lpDeviceName]
    .text:010014A3                 movzx   eax, word ptr [eax]
    .text:010014A6                 sub     eax, 40h
    .text:010014A9                 push    eax             ; int
    .text:010014AA                 call    ?QuerySubstedDrive@@YGEKPAGKPAK@Z ; QuerySubstedDrive(ulong,ushort *,ulong,ulong *)
    .text:010014AF                 mov     edi, [ebp+arg_4]
    .text:010014B2                 xor     ebx, ebx
    .text:010014B4                 test    al, al
    .text:010014B6                 jnz     loc_100154F
    .text:010014BC                 mov     esi, [ebp+lpTargetPath]
    .text:010014BF                 cmp     esi, 2
    .text:010014C2                 jnz     loc_1001554
    .text:010014C8                 push    edi             ; wchar_t *
    .text:010014C9                 call    ds:__imp__wcslen
    .text:010014CF                 cmp     eax, 3
    .text:010014D2                 pop     ecx
    .text:010014D3                 jnz     short loc_1001532
    .text:010014D5                 cmp     word ptr [edi+2], 3Ah
    .text:010014DA                 jnz     short loc_1001532
    .text:010014DC                 cmp     word ptr [edi+4], 5Ch
    .text:010014E1                 jnz     short loc_1001532
    .text:010014E3                 cmp     [edi+6], bx
    .text:010014E7                 jnz     short loc_1001532
    .text:010014E9                 push    ebx
    .text:010014EA                 push    ebx
    .text:010014EB                 lea     eax, [ebp+var_8]
    .text:010014EE                 push    eax
    .text:010014EF                 push    edi
    .text:010014F0                 call    ds:__imp__RtlDosPathNameToNtPathName_U@16 ; RtlDosPathNameToNtPathName_U(x,x,x,x)
    .text:010014F6                 test    al, al
    .text:010014F8                 jz      short loc_1001541
    .text:010014FA                 movzx   eax, word ptr [ebp+var_8]
    .text:010014FE                 mov     ecx, [ebp+lpTargetPath]
    .text:01001501                 shr     eax, 1
    .text:01001503                 mov     [ecx+eax*2-2], bx
    .text:01001508                 push    [ebp+lpTargetPath] ; lpTargetPath
    .text:0100150B                 push    [ebp+lpDeviceName] ; lpDeviceName
    .text:0100150E                 push    1               ; dwFlags
    .text:01001510                 call    ds:__imp__DefineDosDeviceW@12 ; DefineDosDeviceW(x,x,x)
    .text:01001516                 test    eax, eax
    .text:01001518                 jnz     short loc_1001524
    .text:0100151A                 call    ds:__imp__GetLastError@0 ; GetLastError()
    .text:01001520                 mov     esi, eax
    .text:01001522                 jmp     short loc_1001526
    .text:01001524 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:01001524
    .text:01001524 loc_1001524:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+9Dj
    .text:01001524                 xor     esi, esi
    .text:01001526
    .text:01001526 loc_1001526:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+A7j
    .text:01001526                 lea     eax, [ebp+var_8]
    .text:01001529                 push    eax
    .text:0100152A                 call    ds:__imp__RtlFreeUnicodeString@4 ; RtlFreeUnicodeString(x)
    .text:01001530                 jmp     short loc_1001554
    .text:01001532 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:01001532
    .text:01001532 loc_1001532:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+58j
    .text:01001532                                         ; AddSubst(ushort *,ushort *,ulong,MESSAGE *)+5Fj ...
    .text:01001532                 push    edi             ; lpTargetPath
    .text:01001533                 push    [ebp+lpDeviceName] ; lpDeviceName
    .text:01001536                 push    ebx             ; dwFlags
    .text:01001537                 call    ds:__imp__DefineDosDeviceW@12 ; DefineDosDeviceW(x,x,x)
    .text:0100153D                 test    eax, eax
    .text:0100153F                 jnz     short loc_100154B
    .text:01001541
    .text:01001541 loc_1001541:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+7Dj
    .text:01001541                 call    ds:__imp__GetLastError@0 ; GetLastError()
    .text:01001547                 mov     esi, eax
    .text:01001549                 jmp     short loc_1001554
    .text:0100154B ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:0100154B
    .text:0100154B loc_100154B:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+C4j
    .text:0100154B                 xor     esi, esi
    .text:0100154D                 jmp     short loc_1001554
    .text:0100154F ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
      

  7.   

    .text:0100154F
    .text:0100154F loc_100154F:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+3Bj
    .text:0100154F                 mov     esi, 87h
    .text:01001554
    .text:01001554 loc_1001554:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+47j
    .text:01001554                                         ; AddSubst(ushort *,ushort *,ulong,MESSAGE *)+B5j ...
    .text:01001554                 cmp     esi, ebx
    .text:01001556                 jz      loc_10015E7
    .text:0100155C                 cmp     esi, 87h
    .text:01001562                 jnz     short loc_1001586
    .text:01001564                 mov     esi, [ebp+arg_C]
    .text:01001567                 mov     eax, [esi]
    .text:01001569                 push    3
    .text:0100156B                 push    ebx
    .text:0100156C                 push    772Ch
    .text:01001571                 mov     ecx, esi
    .text:01001573                 call    dword ptr [eax+0Ch]
    .text:01001576                 push    offset dword_100115C
    .text:0100157B                 push    esi
    .text:0100157C                 call    ds:__imp_?Display@MESSAGE@@QAAEPBDZZ ; MESSAGE::Display(char const *,...)
    .text:01001582                 pop     ecx
    .text:01001583                 pop     ecx
    .text:01001584                 jmp     short loc_10015E9
    .text:01001586 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:01001586
    .text:01001586 loc_1001586:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+E7j
    .text:01001586                 cmp     esi, 2
    .text:01001589                 lea     ecx, [ebp+var_1C]
    .text:0100158C                 push    0FFFFFFFFh
    .text:0100158E                 jnz     short loc_10015A1
    .text:01001590                 push    edi
    .text:01001591                 call    ds:__imp_?Initialize@FSTRING@@QAEPAVWSTRING@@PAGK@Z ; FSTRING::Initialize(ushort *,ulong)
    .text:01001597                 push    3
    .text:01001599                 push    ebx
    .text:0100159A                 push    7731h
    .text:0100159F                 jmp     short loc_10015C8
    .text:010015A1 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:010015A1
    .text:010015A1 loc_10015A1:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+113j
    .text:010015A1                 cmp     esi, 5
    .text:010015A4                 jnz     short loc_10015B7
    .text:010015A6                 push    edi
    .text:010015A7                 call    ds:__imp_?Initialize@FSTRING@@QAEPAVWSTRING@@PAGK@Z ; FSTRING::Initialize(ushort *,ulong)
    .text:010015AD                 push    3
    .text:010015AF                 push    ebx
    .text:010015B0                 push    7732h
    .text:010015B5                 jmp     short loc_10015C8
    .text:010015B7 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:010015B7
    .text:010015B7 loc_10015B7:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+129j
    .text:010015B7                 push    [ebp+lpDeviceName]
    .text:010015BA                 call    ds:__imp_?Initialize@FSTRING@@QAEPAVWSTRING@@PAGK@Z ; FSTRING::Initialize(ushort *,ulong)
    .text:010015C0                 push    3
    .text:010015C2                 push    ebx
    .text:010015C3                 push    772Fh
    .text:010015C8
    .text:010015C8 loc_10015C8:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+124j
    .text:010015C8                                         ; AddSubst(ushort *,ushort *,ulong,MESSAGE *)+13Aj
    .text:010015C8                 mov     esi, [ebp+arg_C]
    .text:010015CB                 mov     eax, [esi]
    .text:010015CD                 mov     ecx, esi
    .text:010015CF                 call    dword ptr [eax+0Ch]
    .text:010015D2                 lea     eax, [ebp+var_1C]
    .text:010015D5                 push    eax
    .text:010015D6                 push    offset asc_100117C ; "%"
    .text:010015DB                 push    esi
    .text:010015DC                 call    ds:__imp_?Display@MESSAGE@@QAAEPBDZZ ; MESSAGE::Display(char const *,...)
    .text:010015E2                 add     esp, 0Ch
    .text:010015E5                 jmp     short loc_10015E9
    .text:010015E7 ; 哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
    .text:010015E7
    .text:010015E7 loc_10015E7:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+DBj
    .text:010015E7                 mov     bl, 1
    .text:010015E9
    .text:010015E9 loc_10015E9:                            ; CODE XREF: AddSubst(ushort *,ushort *,ulong,MESSAGE *)+109j
    .text:010015E9                                         ; AddSubst(ushort *,ushort *,ulong,MESSAGE *)+16Aj
    .text:010015E9                 lea     ecx, [ebp+var_1C]
    .text:010015EC                 call    ds:__imp_??1OBJECT@@UAE@XZ ; OBJECT::~OBJECT(void)
    .text:010015F2                 pop     edi
    .text:010015F3                 pop     esi
    .text:010015F4                 mov     al, bl
    .text:010015F6                 pop     ebx
    .text:010015F7                 leave
    .text:010015F8                 retn    10h
    .text:010015F8 ?AddSubst@@YGEPAG0KPAVMESSAGE@@@Z endp
      

  8.   

    来了一位老大~~~HOHO^O^SUBST里面调用了DefineDosDevice这个API.而这个API后面应该是有一个驱动的.就如FILEDISK后面的那个驱动一样.....我现在想实现的,除了映射目录到硬盘外,还想对文件读写进行分离.比如,有CDEF四个盘,我虚拟个X:盘出来,然后让读X:上文件时实际是读到E:\Read\,写时写到F:\Write\,同时建立一个数据库,记录这个写的内容;当下次读到这个内容时,就从数据库里查询,如果在F:\Write\里面有,就从那里读取,否则就从E:\Read\目录读取.有点类似冰点那种虚拟还原技术.由于我现在想实现的不止SUBST的功能,所以这个API不可以满足我的要求我问了N多的前辈,发现就只有写过滤驱动了(APIHOOK好象有点低效率).不知道我上面的那种功能,在这个FILEDISK的基础上,能否实现?或者得另外写?谢谢
      

  9.   

    背后的驱动?DefineDosDevice是API啊,如果你要追查它的具体实现恐怕有难度。
    要实现硬盘保护不是那么容易的,单独的过滤驱动不能解决问题。如果用户用启动盘启动,怎么保护?
      

  10.   

    不是不是....不是那意思这个软件不是开发的用户软件,呵呵是我自己用来学习的所以不需要考虑那些细节我现在由于一点都不会写驱动,急需要一个写成的软件来壮壮胆~~~~~~因为我不是做软件方面工作的(我现在是在一公司做电路设计),学软件编写是业余爱好...在这之前只有一点VB方面的知识,直接跳到驱动来我也觉得太快了点....因此还是采用以前学VB的老办法-----先写个程序出来,再慢慢消化另外关于这个API,我在另外哪个帖子里见到有人说过,有个啥啥啥啥驱动的.......不过刚刚找了半天,没找到那个帖子.好象你也在那帖子里回复过呢~~刚刚我一直在看楚狂人的文件系统过滤驱动教程,大致觉得,也是在处理IRP,只是还有个FASTIO...(还没看完,才一半)那么驱动其实就是实现这些函数吧?
      

  11.   

    呵呵,是呀........都不知道吃不吃得下这个大胖子说正题....现在我看完了楚狂人的教程了,看来(至少从这篇文章里面)写文件过滤驱动就是实现N多不同的函数的过程.从这一点上面来看,我完成它的可能性还是蛮大的.在那教程里面有说到文件的读写:"IRP下有一个FileObject指针.这个东西指向一个文件对象.你可以得到文件对象的名字,这个名字是没有盘符的文件全路径"可是看起来,这个指针是在上面某处已经打开了文件后,才发送过来的.那么,我应该在哪里做这一个工作呢?另外,对于一个目录下的已有文件,我是不是直接读一下,判断返回值就可以了(而不用写数据库)?比如,我之前已经写了一个文件到F盘里,现在要读这个文件,是不是应该用这样的流程:一,读F盘里面相应的文件二,如果成功,返回;三,如果失败,就读E盘里的文件;四,如果成功,返回;五,如果失败,返回错误.因为突然想到,如果读一个不存在的文件时,会产生错误,我只需要捕捉这个错误就行了,而不需要去写个数据库去保存之前已经写入的数据,这样也就不会效率低了(我认为在数据库里查询时,也许在文件很多时会变得很低的效率).