• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            沒畫完的畫

            喂馬 劈柴 BBQ~
            posts - 37, comments - 55, trackbacks - 0, articles - 0
              C++博客 ::  :: 新隨筆 :: 聯系 :: 聚合  :: 管理

            關于 TrueCrypt 第6集

            Posted on 2008-09-10 12:28 沒畫完的畫 閱讀(1707) 評論(3)  編輯 收藏 引用 所屬分類: Windows Driver
            上一集看 FileDisk 的代碼,沒看出個所以然……
            本集繼續……

            看下 FileDisk 的應用層 Mount 時的實現代碼
            int FileDiskMount(int DeviceNumber, POPEN_FILE_INFORMATION  OpenFileInformation, char DriveLetter, BOOLEAN CdImage)
            {
                
            char    VolumeName[] = "\\\\.\\ :";
                
            char    DeviceName[255];
                HANDLE  Device;
                DWORD   BytesReturned;
                VolumeName[
            4= DriveLetter;
                Device 
            = CreateFile(
                    VolumeName,
                    GENERIC_READ 
            | GENERIC_WRITE,
                    FILE_SHARE_READ 
            | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_NO_BUFFERING,
                    NULL
                    );
                
            if (Device != INVALID_HANDLE_VALUE)
                
            {
                    SetLastError(ERROR_BUSY);
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }


                
            if (CdImage)
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "Cd" "%u", DeviceNumber);
                }

                
            else
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "%u", DeviceNumber);
                }


                
            if (!DefineDosDevice(
                    DDD_RAW_TARGET_PATH,
                    
            &VolumeName[4],
                    DeviceName
                    ))
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }

                
            else
                
            {
                    printf(
            "DefineDosDevice %s %s \n"&VolumeName[4], DeviceName);        
                }

                
                Device 
            = CreateFile(
                    VolumeName,
                    GENERIC_READ 
            | GENERIC_WRITE,
                    FILE_SHARE_READ 
            | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_NO_BUFFERING,
                    NULL
                    );
                
            if (Device == INVALID_HANDLE_VALUE)
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    DefineDosDevice(DDD_REMOVE_DEFINITION, 
            &VolumeName[4], NULL);
                    
            return -1;
                }

                
            if (!DeviceIoControl(
                    Device,
                    IOCTL_FILE_DISK_OPEN_FILE,
                    OpenFileInformation,
                    
            sizeof(OPEN_FILE_INFORMATION) + OpenFileInformation->FileNameLength - 1,
                    NULL,
                    
            0,
                    
            &BytesReturned,
                    NULL
                    ))
                
            {
                    PrintLastError(
            "FileDisk:");
                    DefineDosDevice(DDD_REMOVE_DEFINITION, 
            &VolumeName[4], NULL);
                    
            return -1;
                }

                
            return 0;
            }



            在執行 DefineDosDevice() 時,把 傳入 DefineDosDevice() 的參數打印出來看一下先……
            顯示結果:
            DefineDosDevice e: \Device\FileDisk\FileDisk0

            Mount 成功后,用 Winobj.exe 查看,奇怪的是它并沒有在 設備目錄 \GLOBAL??\   下面生成一個 e: 的別名

            問題:應用層的 DefineDosDevice() 不是相當于 驅動層的 IoCreateSymbolicLink() 函數? 那為何不會生成 e: 這樣的別名,
                    沒有生成別名,在應用層又是怎么能夠直接訪問 e: 的呢?
            --- 迷惘ing

            于是在 FileDiskMount() 函數中增加一些語句嘗試一下

            int
            FileDiskMount(
                
            int                     DeviceNumber,
                POPEN_FILE_INFORMATION  OpenFileInformation,
                
            char                    DriveLetter,
                BOOLEAN                 CdImage
            )
            {
                
            char    VolumeName[] = "\\\\.\\ :";
                
            char    DeviceName[255];
                HANDLE  Device;
                DWORD   BytesReturned;
                VolumeName[
            4= DriveLetter;
             printf(
            "Enter FileDiskMount \n");
             printf(
            "FileDiskMount CreateFile VolumeName = %s\n", VolumeName);
                Device 
            = CreateFile(
                    VolumeName,
                    GENERIC_READ 
            | GENERIC_WRITE,
                    FILE_SHARE_READ 
            | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_NO_BUFFERING,
                    NULL
                    );
                
            if (Device != INVALID_HANDLE_VALUE)
                
            {
                    
            //  這里沒有調用 CloseHandle() 將 Device 關閉 -_-!!
                    SetLastError(ERROR_BUSY);
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }


                
            if (CdImage)
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "Cd" "%u", DeviceNumber);
                }

                
            else
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "%u", DeviceNumber);
                }


             printf(
            "FileDiskMount DefineDosDevice VolumeName = %s DeviceName = %s \n"&VolumeName[4], DeviceName);
                
            if (!DefineDosDevice(
                    DDD_RAW_TARGET_PATH,
                    
            &VolumeName[4],
                    DeviceName
                    ))
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }


             printf(
            "FileDiskMount CreateFile VolumeName = %s\n", VolumeName);
                Device 
            = CreateFile(
                    VolumeName,
                    GENERIC_READ 
            | GENERIC_WRITE,
                    FILE_SHARE_READ 
            | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_NO_BUFFERING,
                    NULL
                    );
                
            if (Device == INVALID_HANDLE_VALUE)
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    DefineDosDevice(DDD_REMOVE_DEFINITION, 
            &VolumeName[4], NULL);
                    
            return -1;
                }

             
            if (!DeviceIoControl(
                    Device,
                    IOCTL_FILE_DISK_OPEN_FILE,
                    OpenFileInformation,
                    
            sizeof(OPEN_FILE_INFORMATION) + OpenFileInformation->FileNameLength - 1,
                    NULL,
                    
            0,
                    
            &BytesReturned,
                    NULL
                    ))
                
            {
                    PrintLastError(
            "FileDisk:");
                    DefineDosDevice(DDD_REMOVE_DEFINITION, 
            &VolumeName[4], NULL);
                    
            return -1;
                }

             
            // 在最后 Device 沒有進行 CloseHandle() ??
                return 0;
            }



            運行 filedisk /mount 之后,輸出結果如下
            Enter FileDiskMount
            FileDiskMount CreateFile VolumeName = \\.\e:
            FileDiskMount DefineDosDevice VolumeName = e: DeviceName = \Device\FileDisk\FileDisk0
            FileDiskMount CreateFile VolumeName = \\.\e:


            FileDiskMount 的函數先是 用 CreateFile 嘗試打開 \\.\e 這個設備,
            確定 e: 這個盤符沒有被占用后,就用 DefineDosDevice() 函數 把 e: 這個盤符指向 \Device\FileDisk\FileDisk0 這個設備
            接下來,再用 CreateFile 打開 \\.\e 這個設備
            然后調用 DeviceIoControl() 給 \\.\e 這個設備發送  IOCTL_FILE_DISK_OPEN_FILE 這個 Control Code

            昨天試過用 DeviceIoControl() 函數,但并未顯示出設備出來
            難道調用 DeviceIoControl() 函數后,還需要向這個設備發 IOCTL_FILE_DISK_OPEN_FILE  這個 Control Code ,
            “虛擬的分區”才會顯示出來?

            于是,決定嘗試下,把后來的向設備發送 IOCTL_FILE_DISK_OPEN_FILE 的相關代碼去掉,
            將 FileDiskMount() 的代碼修改為

            int
            FileDiskMount(
                
            int                     DeviceNumber,
                POPEN_FILE_INFORMATION  OpenFileInformation,
                
            char                    DriveLetter,
                BOOLEAN                 CdImage
            )
            {
                
            char    VolumeName[] = "\\\\.\\ :";
                
            char    DeviceName[255];
                HANDLE  Device;
                DWORD   BytesReturned;
                VolumeName[
            4= DriveLetter;
             printf(
            "Enter FileDiskMount \n");
             printf(
            "FileDiskMount CreateFile VolumeName = %s\n", VolumeName);
                Device 
            = CreateFile(
                    VolumeName,
                    GENERIC_READ 
            | GENERIC_WRITE,
                    FILE_SHARE_READ 
            | FILE_SHARE_WRITE,
                    NULL,
                    OPEN_EXISTING,
                    FILE_FLAG_NO_BUFFERING,
                    NULL
                    );
                
            if (Device != INVALID_HANDLE_VALUE)
                
            {
                    SetLastError(ERROR_BUSY);
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }

                
            if (CdImage)
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "Cd" "%u", DeviceNumber);
                }

                
            else
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "%u", DeviceNumber);
                }

             printf(
            "FileDiskMount DefineDosDevice VolumeName = %s DeviceName = %s \n"&VolumeName[4], DeviceName);
                
            if (!DefineDosDevice(
                    DDD_RAW_TARGET_PATH,
                    
            &VolumeName[4],
                    DeviceName
                    ))
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }

             
            return 0;
            }
              



            運行結果:
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\filediskexe.exe" /mount 0 c:\1.txt 9M e:
            Enter FileDiskMount
            FileDiskMount CreateFile VolumeName = \\.\e:
            FileDiskMount DefineDosDevice VolumeName = e: DeviceName = \Device\FileDisk\File
            Disk0

            仍然可以在我的電腦里顯示 e: 盤這個分區,但雙擊進入時,會有一個錯誤提示“無法訪問 E:\ 設備未就緒。”

            昨天試過調用完 DefineDosDevice() 后,在我的電腦里,還是沒有把那個虛擬分區顯示出來,為什么 FileDisk 就可以?
            將 FileDiskMount() 再修改為

            int
            FileDiskMount(
                
            int                     DeviceNumber,
                POPEN_FILE_INFORMATION  OpenFileInformation,
                
            char                    DriveLetter,
                BOOLEAN                 CdImage
            )
            {
                
            char    VolumeName[] = "\\\\.\\ :";
                
            char    DeviceName[255];
                VolumeName[
            4= DriveLetter;
             printf(
            "Enter FileDiskMount \n");
                
            if (CdImage)
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "Cd" "%u", DeviceNumber);
                }

                
            else
                
            {
                    sprintf(DeviceName, DEVICE_NAME_PREFIX 
            "%u", DeviceNumber);
                }

             printf(
            "FileDiskMount DefineDosDevice VolumeName = %s DeviceName = %s \n"&VolumeName[4], DeviceName);
                
            if (!DefineDosDevice(
                    DDD_RAW_TARGET_PATH,
                    
            &VolumeName[4],
                    DeviceName
                    ))
                
            {
                    PrintLastError(
            &VolumeName[4]);
                    
            return -1;
                }

             
            return 0;
            }



            運行
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\testfilediskexe.exe" /mount 0 c:\1.txt 8M e:
            Enter FileDiskMount
            FileDiskMount DefineDosDevice VolumeName = e: DeviceName = \Device\FileDisk\File
            Disk0

            結果還是可以在我的電腦中顯示 e: 盤
            昨天沒有把虛擬的分區顯示出來,可能性有2個

            1、DefineDosDevice() 的調用有問題
            2、FileDisk .sys 在調用了 IoCreateDevice() 之后,還做了其它一些東西,而我沒有注意到

            于是,決定再次嘗試下用  DefineDosDevice() 能不能把虛擬的分區顯示出來
            .sys 的代碼

            #include <ntddk.h>
            #include 
            <ntdddisk.h>
            #define DEVICE_NAME      L"\\DosDevices\\SimpleDriver"
            #define SECTOR_SIZE             512
            NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
            VOID     DriverUnload(IN PDRIVER_OBJECT DriverObject);
            NTSTATUS DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            NTSTATUS DeviceCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            NTSTATUS DeviceReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            #pragma code_seg(
            "INIT")
            NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
            {   
                NTSTATUS status 
            = STATUS_SUCCESS; 
                UNICODE_STRING uniNameString;
                DEVICE_OBJECT 
            *pCDO = NULL;
                
                KdPrint((
            "SimpleDriver!DriverEntry \n"));
                
                RtlInitUnicodeString(
            &uniNameString, DEVICE_NAME);
                status 
            = IoCreateDevice(DriverObject, 0&uniNameString, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, FALSE, &pCDO);
                
            if!NT_SUCCESS(status) )
                 
            return status; 
                
                DriverObject
            ->DriverUnload = DriverUnload;
                DriverObject
            ->MajorFunction[IRP_MJ_CREATE]         = DeviceCreateClose;
                DriverObject
            ->MajorFunction[IRP_MJ_CLOSE]          = DeviceCreateClose;
                DriverObject
            ->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
                
                DriverObject
            ->MajorFunction[IRP_MJ_READ]           = DeviceReadWrite;
                DriverObject
            ->MajorFunction[IRP_MJ_WRITE]          = DeviceReadWrite;
                
                
            return STATUS_SUCCESS;
            }

            #pragma code_seg(
            "PAGE")
            VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
            {
                PAGED_CODE();
                
                KdPrint((
            "SimpleDriver!DriverUnload \n"));
                IoDeleteDevice(DriverObject
            ->DeviceObject);
            }

            NTSTATUS DeviceCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                PAGED_CODE();
                KdPrint((
            "SimpleDriver!DeviceCreateClose \n"));
                Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                Irp
            ->IoStatus.Information = FILE_OPENED;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                
            return STATUS_SUCCESS;
            }

            NTSTATUS DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                NTSTATUS status 
            = STATUS_SUCCESS;
                ULONG nIoCtrlCodes 
            = 0;  // IO控制碼
                PIO_STACK_LOCATION IrpStack = NULL;   //IRP堆棧
                    
                KdPrint((
            "SimpleDriver!DeviceControl \n"));
                
                
            //得到當前調用者的IRP 
                IrpStack = IoGetCurrentIrpStackLocation(Irp);   
                
                nIoCtrlCodes 
            = IrpStack->Parameters.DeviceIoControl.IoControlCode;
                
                KdPrint((
            "SimpleDriver!DeviceControl IoControlCode = 0x%X\n", nIoCtrlCodes));
                
                
            switch( IrpStack->Parameters.DeviceIoControl.IoControlCode )
                
            {
                    
            case IOCTL_DISK_GET_DRIVE_GEOMETRY:
                    
            {          
                       PDISK_GEOMETRY  disk_geometry;
                        ULONGLONG       length;
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_GET_DRIVE_GEOMETRY \n"));
                        
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        disk_geometry 
            = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
                        
                        
            // #define SECTOR_SIZE             512
                        disk_geometry->Cylinders.QuadPart = 41940668416 / SECTOR_SIZE / 32 / 2;
                        disk_geometry
            ->MediaType = FixedMedia;
                        disk_geometry
            ->TracksPerCylinder = 2;
                        disk_geometry
            ->SectorsPerTrack = 32;
                        disk_geometry
            ->BytesPerSector = SECTOR_SIZE;
                        Irp
            ->IoStatus.Information = sizeof(DISK_GEOMETRY);
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_GET_PARTITION_INFO:
                    
            {
                       PPARTITION_INFORMATION  partition_information;
                        ULONGLONG               length;
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_GET_PARTITION_INFO \n"));
                        
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        partition_information 
            = (PPARTITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
                        partition_information
            ->StartingOffset.QuadPart = 0;
                        partition_information
            ->PartitionLength.QuadPart = 41940668416;
                        partition_information
            ->HiddenSectors = 1;
                        partition_information
            ->PartitionNumber = 0;
                        partition_information
            ->PartitionType = 0;
                        partition_information
            ->BootIndicator = FALSE;
                        partition_information
            ->RecognizedPartition = FALSE;
                        partition_information
            ->RewritePartition = FALSE;
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = sizeof(PARTITION_INFORMATION);
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_IS_WRITABLE:
                    
            {
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_IS_WRITABLE \n"));
                       Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = 0;
                        
            break;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_SET_PARTITION_INFO:
                    
            {
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_SET_PARTITION_INFO \n"));
                        
                        
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION))
                        
            {
                           Irp
            ->IoStatus.Status = STATUS_INVALID_PARAMETER;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = 0;
                    }

                    
            break;
                            
                    
            case IOCTL_DISK_VERIFY:
                    
            {
                       PVERIFY_INFORMATION verify_information;
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_VERIFY \n"));
                        
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_INVALID_PARAMETER;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        verify_information 
            = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = verify_information->Length;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_CHECK_VERIFY:
                    
            {
                       KdPrint((
            "SimpleDriver!DeviceControl IOCTL_DISK_CHECK_VERIFY \n"));
                        Irp
            ->IoStatus.Information = 0;         
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    }

                    
            break;     
               
                }
            ;
                
                status 
            = Irp->IoStatus.Status; 
                IoCompleteRequest(Irp, IO_NO_INCREMENT); 
                
            return status; 
            }

            NTSTATUS DeviceReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                PIO_STACK_LOCATION  io_stack;
                io_stack 
            = IoGetCurrentIrpStackLocation(Irp);
                
            if (io_stack->Parameters.Read.Length == 0)
                
            {
                    Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    Irp
            ->IoStatus.Information = 0;
                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
                    
            return STATUS_SUCCESS;
                }

                IoMarkIrpPending(Irp);
                
            return STATUS_PENDING;
            }

            #pragma code_seg()



            .exe 代碼

            #include <windows.h>
            #include 
            <winioctl.h>
            #include 
            <stdio.h>
              
            void mount()
            {
                
            if (!DefineDosDevice(DDD_RAW_TARGET_PATH, "e:",
                    
            "\\\\.\\SimpleDriver"
                    ))
                
            {
                    printf(
            "DefineDosDevice Error ErrCode = %d", ::GetLastError());
                }

             
            else
             
            {
              printf(
            "DefineDosDevice OK ErrCode = %d", ::GetLastError());
             }

            }
              

            int main(int argc, char *argv[])
            {  
             mount();
                
            return 0;
            }


            運行結果:
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\testDriverTalk.exe"
            DefineDosDevice OK ErrCode = 0

            但很遺憾!!!!! e: 盤就是不顯示出來

            難道跟設備的路徑有關系???
            FileDisk 創建的設備路徑是:                 \Device\FileDisk\File
            而上述的SimpleDriver 創建的設備路徑是  \DosDevices\SimpleDriver

            于是嘗試將將
            .sys 代碼中
            #define DEVICE_NAME      L"\\DosDevices\\SimpleDriver"
            改為:
            #define DEVICE_NAME      L"\\Device\\SimpleDriver"

            編譯……
            用 OSRLOADER.exe 加態完驅動后,再用 Winobj.exe 確定了 SimpleDriver 所在的設備路徑是 \Device\SimpleDriver

            再加 .exe  的
                if (!DefineDosDevice(DDD_RAW_TARGET_PATH, "e:",
                    "\\\\.\\SimpleDriver"
                    ))

            改為
                if (!DefineDosDevice(DDD_RAW_TARGET_PATH, "e:",
                    "\\Device\\SimpleDriver"
                    ))

            編譯……,運行
            運行結果:
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\testDriverTalk.exe"
            DefineDosDevice OK ErrCode = 0

            恭喜,恭喜!!!!!!!!
            在我的電腦中,E: 這個虛擬的分區終于顯示出來了

            如此證明,昨天 調用 DefineDosDevice() 后,E: 盤沒顯示出來,跟 設備的路徑是有關的
            但具體原因未知
            設備路徑:\DosDevices\SimpleDriver   調用 DefineDosDevice() 后, 不顯示 E: 盤
            設備路徑:\Device\SimpleDriver         調用 DefineDosDevice() 后, 顯示 E: 盤

            雙擊 E: 盤
            提示錯誤信息: “無法訪問 E:\ 函數不正確。”
            具體原因不詳, 有可能是 .sys 沒有處理相關 IRP 的原因,需要進一步研究


            接下來,想試一下,直接在加載驅動的時候,調用 IoCreateSymbolicLink

            修改 .sys 代碼為

            #include <ntddk.h>
            #include 
            <ntdddisk.h>
            #define DEVICE_NAME      L"\\Device\\SimpleDriver"
            #define DEVICE_LINK_NAME L"\\\\.\\e"
            #define SECTOR_SIZE             512

            NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
            VOID     DriverUnload(IN PDRIVER_OBJECT DriverObject);
            NTSTATUS DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            NTSTATUS DeviceCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            NTSTATUS DeviceReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
            #pragma code_seg(
            "INIT")
            NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
            {   
                NTSTATUS status 
            = STATUS_SUCCESS; 
                UNICODE_STRING uniNameString;
                UNICODE_STRING uniLinkString;
                DEVICE_OBJECT 
            *pCDO = NULL;
                
                KdPrint((
            "SimpleDriver!DriverEntry \n"));
                
                RtlInitUnicodeString(
            &uniNameString, DEVICE_NAME);
                status 
            = IoCreateDevice(DriverObject, 0&uniNameString, FILE_DEVICE_DISK_FILE_SYSTEM, FILE_DEVICE_SECURE_OPEN, FALSE, &pCDO);
                
            if!NT_SUCCESS(status) )
                 
            return status; 
                
                RtlInitUnicodeString(
            &uniLinkString, DEVICE_LINK_NAME);
                status 
            = IoCreateSymbolicLink(&uniLinkString, &uniNameString);
                
            if(!NT_SUCCESS(status))
                 
            return status;                                          
                DriverObject
            ->DriverUnload = DriverUnload;
                DriverObject
            ->MajorFunction[IRP_MJ_CREATE]         = DeviceCreateClose;
                DriverObject
            ->MajorFunction[IRP_MJ_CLOSE]          = DeviceCreateClose;
                DriverObject
            ->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
                
                DriverObject
            ->MajorFunction[IRP_MJ_READ]           = DeviceReadWrite;
                DriverObject
            ->MajorFunction[IRP_MJ_WRITE]          = DeviceReadWrite;
                
                
            return STATUS_SUCCESS;
            }

            #pragma code_seg(
            "PAGE")
            VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
            {
                UNICODE_STRING uniNameString;
                PAGED_CODE();
                
                KdPrint((
            "SimpleDriver!DriverUnload \n"));
                RtlInitUnicodeString(
            &uniNameString, DEVICE_LINK_NAME);
                IoDeleteSymbolicLink(
            &uniNameString);
                IoDeleteDevice(DriverObject
            ->DeviceObject);
            }

            NTSTATUS DeviceCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                PAGED_CODE();
                KdPrint((
            "SimpleDriver!DeviceCreateClose \n"));
                Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                Irp
            ->IoStatus.Information = FILE_OPENED;
                IoCompleteRequest(Irp, IO_NO_INCREMENT);
                
            return STATUS_SUCCESS;
            }

            NTSTATUS DeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                NTSTATUS status 
            = STATUS_SUCCESS;
                ULONG nIoCtrlCodes 
            = 0;  // IO控制碼
                PIO_STACK_LOCATION IrpStack = NULL;   //IRP堆棧
                    
                KdPrint((
            "SimpleDriver!DeviceControl \n"));
                
                
            //得到當前調用者的IRP 
                IrpStack = IoGetCurrentIrpStackLocation(Irp);   
                
                nIoCtrlCodes 
            = IrpStack->Parameters.DeviceIoControl.IoControlCode;
                
                KdPrint((
            "SimpleDriver!DeviceControl IoControlCode = 0x%X\n", nIoCtrlCodes));
                
                
            switch( IrpStack->Parameters.DeviceIoControl.IoControlCode )
                
            {
                    
            case IOCTL_DISK_GET_DRIVE_GEOMETRY:
                    
            {
                       PDISK_GEOMETRY  disk_geometry;
                        ULONGLONG       length;
                        
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        disk_geometry 
            = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
                        
                        
            // #define SECTOR_SIZE             512
                        disk_geometry->Cylinders.QuadPart = 41940668416 / SECTOR_SIZE / 32 / 2;
                        disk_geometry
            ->MediaType = FixedMedia;
                        disk_geometry
            ->TracksPerCylinder = 2;
                        disk_geometry
            ->SectorsPerTrack = 32;
                        disk_geometry
            ->BytesPerSector = SECTOR_SIZE;
                        Irp
            ->IoStatus.Information = sizeof(DISK_GEOMETRY);
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_GET_PARTITION_INFO:
                    
            {
                       PPARTITION_INFORMATION  partition_information;
                        ULONGLONG               length;
                        
            if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        partition_information 
            = (PPARTITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
                        partition_information
            ->StartingOffset.QuadPart = 0;
                        partition_information
            ->PartitionLength.QuadPart = 41940668416;
                        partition_information
            ->HiddenSectors = 1;
                        partition_information
            ->PartitionNumber = 0;
                        partition_information
            ->PartitionType = 0;
                        partition_information
            ->BootIndicator = FALSE;
                        partition_information
            ->RecognizedPartition = FALSE;
                        partition_information
            ->RewritePartition = FALSE;
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = sizeof(PARTITION_INFORMATION);
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_IS_WRITABLE:
                    
            {
                       Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = 0;
                        
            break;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_SET_PARTITION_INFO:
                    
            {
                        
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION))
                        
            {
                           Irp
            ->IoStatus.Status = STATUS_INVALID_PARAMETER;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = 0;
                    }

                    
            break;
                            
                    
            case IOCTL_DISK_VERIFY:
                    
            {
                       PVERIFY_INFORMATION verify_information;
                        
            if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION))
                        
            {
                            Irp
            ->IoStatus.Status = STATUS_INVALID_PARAMETER;
                            Irp
            ->IoStatus.Information = 0;
                            
            break;
                        }

                        verify_information 
            = (PVERIFY_INFORMATION) Irp->AssociatedIrp.SystemBuffer;
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                        Irp
            ->IoStatus.Information = verify_information->Length;
                    }

                    
            break;
                    
                    
            case IOCTL_DISK_CHECK_VERIFY:
                    
            {
                        Irp
            ->IoStatus.Information = 0;         
                        Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    }

                    
            break;        
                }
            ;
                
                status 
            = Irp->IoStatus.Status; 
                IoCompleteRequest(Irp, IO_NO_INCREMENT); 
                
            return status; 
            }

            NTSTATUS DeviceReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
            {
                PIO_STACK_LOCATION  io_stack;
                io_stack 
            = IoGetCurrentIrpStackLocation(Irp);
                
            if (io_stack->Parameters.Read.Length == 0)
                
            {
                    Irp
            ->IoStatus.Status = STATUS_SUCCESS;
                    Irp
            ->IoStatus.Information = 0;
                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
                    
            return STATUS_SUCCESS;
                }

                IoMarkIrpPending(Irp);
                
            return STATUS_PENDING;
            }

            #pragma code_seg()


            使用 OSRLOADER.exe 加載 .sys 時,提示錯誤信息 “文件名、目錄名或卷標語法不正確”,
            應該是 #define DEVICE_LINK_NAME L"\\\\.\\e" 這個非法了

            嘗試修改為
            #define DEVICE_LINK_NAME L"\\.\\e"
            加載時提示錯誤信息“系統找不到指定的路徑”,暈,這好像是應用層調用的路徑,

            再嘗試修改為
            #define DEVICE_NAME      L"\\Device\\SimpleDriver"
            #define DEVICE_LINK_NAME L"\\DosDevices\\x:"

            加載成功
            用 Winobj.exe 查看

            設備目錄有 \Device\SimpleDriver
            也有 \GLOBAL??\X:

            但在我的電腦中并沒有顯示 x: 出來
            奇怪的地方是 用  DefineDosDevice() 函數不會在 \GLOBAL??\  下面生成分區的別名,但它又怎么訪問得到呢?
            而 使用 IoCreateSymbolicLink() 可以在 \GLOBAL??\ 下生成別名,但在我的電腦中卻又不會顯示

            DefineDosDevice() 函數的作用不是相當于  IoCreateSymbolicLink()?
            -- 未解決


            本集終于可以實現虛擬出一個分區的功能了,但還有很多細節問題需要深入再研究,查找相關資料
            問題
            1、
            設備路徑:\DosDevices\SimpleDriver   調用 DefineDosDevice() 后, 不顯示 E: 盤
            設備路徑:\Device\SimpleDriver         調用 DefineDosDevice() 后, 顯示 E: 盤

            原因是: 未解決

            2、用  DefineDosDevice() 函數不會在 \GLOBAL??\  下面生成分區的別名,但它又怎么訪問得到呢?
            而 使用 IoCreateSymbolicLink() 可以在 \GLOBAL??\ 下生成別名,但在我的電腦中卻又不會顯示

            DefineDosDevice() 函數的作用不是相當于  IoCreateSymbolicLink()?
            -- 未解決


            --- 6集 完 ---

            Feedback

            # re: 關于 TrueCrypt 第6集   回復  更多評論   

            2010-08-28 23:19 by god4
            第一個問題可以回答,\DosDevices\SimpleDriver是符號連接,指向\Device\SimpleDriver,\Device\SimpleDriver才是設備名,DefineDosDevice要用設備名。

            第二個問題我現在正在苦惱中,如果在驅動中或者在處理內核進程向驅動發送的IRP過程中使用IoCreateSymbolicLink創建符號連接,這個連接在Global中就能顯示出來,如果在處理用戶進程想驅動發送的IRP過程中使用IoCreateSymbolicLink創建符號連接或者使用DefineDosDevice,這個連接在Global中就顯示不出來(TrueCrypt居然可以,但是我自己仿照truecrypt寫的也不行,直接編譯TrueCrypt代碼沒成功)。

            這兩種連接是不同的,好像可以同時創建成功,但是前者在內核中可以使用,后者則不可。比如你加載一個驅動,使用J:這個符號連接路徑,前者可以成功啟動,后者則不行。所以,如果你的驅動在映射的遠程盤上,就會加載失敗。

            # re: 關于 TrueCrypt 第6集   回復  更多評論   

            2010-08-28 23:20 by god4
            http://www.cnblogs.com/god4
            我的blog,問題2希望交流。

            # re: 關于 TrueCrypt 第6集   回復  更多評論   

            2010-08-29 12:33 by god4
            哈哈,終于知道了,用DefineDosDevice定義的符號連接在Session下面,用windbg調試truecrypt驅動終于知道了它是在MountManagerMount中用IoBuildDeviceIoControlRequest實現了global和session下面都有符號連接。
            亚洲中文字幕无码久久精品1 | 99久久夜色精品国产网站| 久久久91精品国产一区二区三区 | 97久久精品无码一区二区| 久久精品人人做人人爽电影| 亚洲国产日韩欧美久久| 观看 国产综合久久久久鬼色 欧美 亚洲 一区二区 | 99久久精品免费观看国产| 99国产欧美久久久精品蜜芽| 亚洲中文字幕无码久久2017| 综合人妻久久一区二区精品| 一本色道久久HEZYO无码| 精品熟女少妇AV免费久久| 久久精品国产2020| 777午夜精品久久av蜜臀| 97久久国产综合精品女不卡| 婷婷五月深深久久精品| 少妇内射兰兰久久| AV无码久久久久不卡蜜桃| 久久99国产精品久久99| 日韩精品久久久久久| 国产精品成人99久久久久91gav| 国产成人久久精品二区三区| 久久av高潮av无码av喷吹| 久久久久99精品成人片三人毛片| 久久久久久国产精品免费免费| 久久人人超碰精品CAOPOREN| 2021国产精品久久精品| 99久久国产精品免费一区二区| 国内精品久久久久伊人av| 色综合久久天天综合| 久久综合九色综合欧美就去吻| 欧美激情精品久久久久久| 久久精品国产2020| 久久免费国产精品一区二区| 无码8090精品久久一区| 中文无码久久精品| 97精品国产97久久久久久免费| 欧美日韩成人精品久久久免费看 | 青青草国产精品久久| 中文成人久久久久影院免费观看|