|
Posted on 2008-09-10 12:28 没画完的画 阅读(1694) 评论(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
第一个问题可以回答,\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
# re: 关于 TrueCrypt 第6集 回复 更多评论
2010-08-29 12:33 by
哈哈,终于知道了,用DefineDosDevice定义的符号连接在Session下面,用windbg调试truecrypt驱动终于知道了它是在MountManagerMount中用IoBuildDeviceIoControlRequest实现了global和session下面都有符号连接。
|