• <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>
            posts - 37, comments - 55, trackbacks - 0, articles - 0
              C++博客 ::  :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
            上一集看 FileDisk 的代碼,沒(méi)看出個(gè)所以然……
            本集繼續(xù)……

            看下 FileDisk 的應(yīng)用層 Mount 時(shí)的實(shí)現(xiàn)代碼
            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;
            }



            在執(zhí)行 DefineDosDevice() 時(shí),把 傳入 DefineDosDevice() 的參數(shù)打印出來(lái)看一下先……
            顯示結(jié)果:
            DefineDosDevice e: \Device\FileDisk\FileDisk0

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

            問(wèn)題:應(yīng)用層的 DefineDosDevice() 不是相當(dāng)于 驅(qū)動(dòng)層的 IoCreateSymbolicLink() 函數(shù)? 那為何不會(huì)生成 e: 這樣的別名,
                    沒(méi)有生成別名,在應(yīng)用層又是怎么能夠直接訪問(wèn) e: 的呢?
            --- 迷惘ing

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

            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)
                
            {
                    
            //  這里沒(méi)有調(diào)用 CloseHandle() 將 Device 關(guān)閉 -_-!!
                    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 沒(méi)有進(jìn)行 CloseHandle() ??
                return 0;
            }



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


            FileDiskMount 的函數(shù)先是 用 CreateFile 嘗試打開(kāi) \\.\e 這個(gè)設(shè)備,
            確定 e: 這個(gè)盤(pán)符沒(méi)有被占用后,就用 DefineDosDevice() 函數(shù) 把 e: 這個(gè)盤(pán)符指向 \Device\FileDisk\FileDisk0 這個(gè)設(shè)備
            接下來(lái),再用 CreateFile 打開(kāi) \\.\e 這個(gè)設(shè)備
            然后調(diào)用 DeviceIoControl() 給 \\.\e 這個(gè)設(shè)備發(fā)送  IOCTL_FILE_DISK_OPEN_FILE 這個(gè) Control Code

            昨天試過(guò)用 DeviceIoControl() 函數(shù),但并未顯示出設(shè)備出來(lái)
            難道調(diào)用 DeviceIoControl() 函數(shù)后,還需要向這個(gè)設(shè)備發(fā) IOCTL_FILE_DISK_OPEN_FILE  這個(gè) Control Code ,
            “虛擬的分區(qū)”才會(huì)顯示出來(lái)?

            于是,決定嘗試下,把后來(lái)的向設(shè)備發(fā)送 IOCTL_FILE_DISK_OPEN_FILE 的相關(guān)代碼去掉,
            將 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;
            }
              



            運(yùn)行結(jié)果:
            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: 盤(pán)這個(gè)分區(qū),但雙擊進(jìn)入時(shí),會(huì)有一個(gè)錯(cuò)誤提示“無(wú)法訪問(wèn) E:\ 設(shè)備未就緒。”

            昨天試過(guò)調(diào)用完 DefineDosDevice() 后,在我的電腦里,還是沒(méi)有把那個(gè)虛擬分區(qū)顯示出來(lái),為什么 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;
            }



            運(yùn)行
            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

            結(jié)果還是可以在我的電腦中顯示 e: 盤(pán)
            昨天沒(méi)有把虛擬的分區(qū)顯示出來(lái),可能性有2個(gè)

            1、DefineDosDevice() 的調(diào)用有問(wèn)題
            2、FileDisk .sys 在調(diào)用了 IoCreateDevice() 之后,還做了其它一些東西,而我沒(méi)有注意到

            于是,決定再次嘗試下用  DefineDosDevice() 能不能把虛擬的分區(qū)顯示出來(lái)
            .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"));
                
                
            //得到當(dāng)前調(diào)用者的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;
            }


            運(yùn)行結(jié)果:
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\testDriverTalk.exe"
            DefineDosDevice OK ErrCode = 0

            但很遺憾!!!!! e: 盤(pán)就是不顯示出來(lái)

            難道跟設(shè)備的路徑有關(guān)系???
            FileDisk 創(chuàng)建的設(shè)備路徑是:                 \Device\FileDisk\File
            而上述的SimpleDriver 創(chuàng)建的設(shè)備路徑是  \DosDevices\SimpleDriver

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

            編譯……
            用 OSRLOADER.exe 加態(tài)完驅(qū)動(dòng)后,再用 Winobj.exe 確定了 SimpleDriver 所在的設(shè)備路徑是 \Device\SimpleDriver

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

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

            編譯……,運(yùn)行
            運(yùn)行結(jié)果:
            C:\Documents and Settings\test>"C:\Documents and Settings\test\桌面\testDriverTalk.exe"
            DefineDosDevice OK ErrCode = 0

            恭喜,恭喜!!!!!!!!
            在我的電腦中,E: 這個(gè)虛擬的分區(qū)終于顯示出來(lái)了

            如此證明,昨天 調(diào)用 DefineDosDevice() 后,E: 盤(pán)沒(méi)顯示出來(lái),跟 設(shè)備的路徑是有關(guān)的
            但具體原因未知
            設(shè)備路徑:\DosDevices\SimpleDriver   調(diào)用 DefineDosDevice() 后, 不顯示 E: 盤(pán)
            設(shè)備路徑:\Device\SimpleDriver         調(diào)用 DefineDosDevice() 后, 顯示 E: 盤(pán)

            雙擊 E: 盤(pán)
            提示錯(cuò)誤信息: “無(wú)法訪問(wèn) E:\ 函數(shù)不正確。”
            具體原因不詳, 有可能是 .sys 沒(méi)有處理相關(guān) IRP 的原因,需要進(jìn)一步研究


            接下來(lái),想試一下,直接在加載驅(qū)動(dòng)的時(shí)候,調(diào)用 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"));
                
                
            //得到當(dāng)前調(diào)用者的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 時(shí),提示錯(cuò)誤信息 “文件名、目錄名或卷標(biāo)語(yǔ)法不正確”,
            應(yīng)該是 #define DEVICE_LINK_NAME L"\\\\.\\e" 這個(gè)非法了

            嘗試修改為
            #define DEVICE_LINK_NAME L"\\.\\e"
            加載時(shí)提示錯(cuò)誤信息“系統(tǒng)找不到指定的路徑”,暈,這好像是應(yīng)用層調(diào)用的路徑,

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

            加載成功
            用 Winobj.exe 查看

            設(shè)備目錄有 \Device\SimpleDriver
            也有 \GLOBAL??\X:

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

            DefineDosDevice() 函數(shù)的作用不是相當(dāng)于  IoCreateSymbolicLink()?
            -- 未解決


            本集終于可以實(shí)現(xiàn)虛擬出一個(gè)分區(qū)的功能了,但還有很多細(xì)節(jié)問(wèn)題需要深入再研究,查找相關(guān)資料
            問(wèn)題
            1、
            設(shè)備路徑:\DosDevices\SimpleDriver   調(diào)用 DefineDosDevice() 后, 不顯示 E: 盤(pán)
            設(shè)備路徑:\Device\SimpleDriver         調(diào)用 DefineDosDevice() 后, 顯示 E: 盤(pán)

            原因是: 未解決

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

            DefineDosDevice() 函數(shù)的作用不是相當(dāng)于  IoCreateSymbolicLink()?
            -- 未解決


            --- 6集 完 ---

            Feedback

            # re: 關(guān)于 TrueCrypt 第6集   回復(fù)  更多評(píng)論   

            2010-08-28 23:19 by god4
            第一個(gè)問(wèn)題可以回答,\DosDevices\SimpleDriver是符號(hào)連接,指向\Device\SimpleDriver,\Device\SimpleDriver才是設(shè)備名,DefineDosDevice要用設(shè)備名。

            第二個(gè)問(wèn)題我現(xiàn)在正在苦惱中,如果在驅(qū)動(dòng)中或者在處理內(nèi)核進(jìn)程向驅(qū)動(dòng)發(fā)送的IRP過(guò)程中使用IoCreateSymbolicLink創(chuàng)建符號(hào)連接,這個(gè)連接在Global中就能顯示出來(lái),如果在處理用戶進(jìn)程想驅(qū)動(dòng)發(fā)送的IRP過(guò)程中使用IoCreateSymbolicLink創(chuàng)建符號(hào)連接或者使用DefineDosDevice,這個(gè)連接在Global中就顯示不出來(lái)(TrueCrypt居然可以,但是我自己仿照truecrypt寫(xiě)的也不行,直接編譯TrueCrypt代碼沒(méi)成功)。

            這兩種連接是不同的,好像可以同時(shí)創(chuàng)建成功,但是前者在內(nèi)核中可以使用,后者則不可。比如你加載一個(gè)驅(qū)動(dòng),使用J:這個(gè)符號(hào)連接路徑,前者可以成功啟動(dòng),后者則不行。所以,如果你的驅(qū)動(dòng)在映射的遠(yuǎn)程盤(pán)上,就會(huì)加載失敗。

            # re: 關(guān)于 TrueCrypt 第6集   回復(fù)  更多評(píng)論   

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

            # re: 關(guān)于 TrueCrypt 第6集   回復(fù)  更多評(píng)論   

            2010-08-29 12:33 by god4
            哈哈,終于知道了,用DefineDosDevice定義的符號(hào)連接在Session下面,用windbg調(diào)試truecrypt驅(qū)動(dòng)終于知道了它是在MountManagerMount中用IoBuildDeviceIoControlRequest實(shí)現(xiàn)了global和session下面都有符號(hào)連接。
            一级a性色生活片久久无少妇一级婬片免费放 | 国产精品久久久福利| 欧美麻豆久久久久久中文| 国产精品久久久久…| 久久99精品久久久久久秒播| 97精品伊人久久大香线蕉app | 久久精品中文騷妇女内射| 偷窥少妇久久久久久久久| 国产精品九九久久精品女同亚洲欧美日韩综合区 | 五月丁香综合激情六月久久| 狠狠色婷婷久久综合频道日韩| 少妇熟女久久综合网色欲| 91精品国产91久久综合| 合区精品久久久中文字幕一区| 欧洲人妻丰满av无码久久不卡| 人妻无码αv中文字幕久久琪琪布| 久久精品国产只有精品2020| 久久香蕉国产线看观看乱码| 久久精品国产亚洲麻豆| 99久久香蕉国产线看观香| 青青草原综合久久大伊人精品| 久久天天躁狠狠躁夜夜2020一| 色欲久久久天天天综合网精品| 国产高潮国产高潮久久久91| 欧洲成人午夜精品无码区久久| 看全色黄大色大片免费久久久| 久久亚洲精品国产精品婷婷| 日本精品久久久久久久久免费| 久久国产高清字幕中文| 久久久久久久久久久精品尤物| 99久久精品这里只有精品| 久久一区二区三区免费| 狠狠干狠狠久久| 人妻精品久久久久中文字幕一冢本| 欧美精品福利视频一区二区三区久久久精品 | 久久综合给合久久狠狠狠97色| 一本色道久久88综合日韩精品| 国产精品亚洲综合专区片高清久久久 | 亚洲国产精品狼友中文久久久 | 色悠久久久久久久综合网| 亚洲欧美日韩精品久久|