本集继续……
看下 FileDisk 的应用层 Mount 时的实现代码
{
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() 函数中增加一些语句尝试一下
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() 的代码修改为
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() 再修改为
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 < 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 < 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 < 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集 完 ---