|
Posted on 2008-09-10 12:28 没画完的画 阅读(1680) 评论(3) 编辑 收藏 引用 所属分类: Windows Driver
上一集看 FileDisk 的代码,没看出个所以然…… 本集继续…… 看下 FileDisk 的应用层 Mount 时的实现代码
int FileDiskMount(int DeviceNumber, POPEN_FILE_INFORMATION OpenFileInformation, char DriveLetter, BOOLEAN CdImage)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
SetLastError(ERROR_BUSY);
PrintLastError(&VolumeName[4]);
return -1;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if (CdImage)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if (!DefineDosDevice(
DDD_RAW_TARGET_PATH,
&VolumeName[4],
DeviceName
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError(&VolumeName[4]);
return -1;
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError("FileDisk:");
DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
return -1;
}
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
在执行 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
)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
// 这里没有调用 CloseHandle() 将 Device 关闭 -_-!!
SetLastError(ERROR_BUSY);
PrintLastError(&VolumeName[4]);
return -1;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
if (CdImage)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "%u", DeviceNumber);
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
printf("FileDiskMount DefineDosDevice VolumeName = %s DeviceName = %s \n", &VolumeName[4], DeviceName);
if (!DefineDosDevice(
DDD_RAW_TARGET_PATH,
&VolumeName[4],
DeviceName
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError(&VolumeName[4]);
return -1;
}
![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError("FileDisk:");
DefineDosDevice(DDD_REMOVE_DEFINITION, &VolumeName[4], NULL);
return -1;
}
// 在最后 Device 没有进行 CloseHandle() ??
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
运行 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
)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
SetLastError(ERROR_BUSY);
PrintLastError(&VolumeName[4]);
return -1;
}
if (CdImage)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError(&VolumeName[4]);
return -1;
}
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
运行结果: 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
)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
char VolumeName[] = "\\\\.\\ :";
char DeviceName[255];
VolumeName[4] = DriveLetter;
printf("Enter FileDiskMount \n");
if (CdImage)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
sprintf(DeviceName, DEVICE_NAME_PREFIX "Cd" "%u", DeviceNumber);
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PrintLastError(&VolumeName[4]);
return -1;
}
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
运行 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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
PAGED_CODE();
KdPrint(("SimpleDriver!DriverUnload \n"));
IoDeleteDevice(DriverObject->DeviceObject);
}
NTSTATUS DeviceCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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 )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PDISK_GEOMETRY disk_geometry;
ULONGLONG length;
KdPrint(("SimpleDriver!DeviceControl IOCTL_DISK_GET_DRIVE_GEOMETRY \n"));
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PPARTITION_INFORMATION partition_information;
ULONGLONG length;
KdPrint(("SimpleDriver!DeviceControl IOCTL_DISK_GET_PARTITION_INFO \n"));
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
KdPrint(("SimpleDriver!DeviceControl IOCTL_DISK_SET_PARTITION_INFO \n"));
if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PVERIFY_INFORMATION verify_information;
KdPrint(("SimpleDriver!DeviceControl IOCTL_DISK_VERIFY \n"));
if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
PIO_STACK_LOCATION io_stack;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.Read.Length == 0)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
.exe 代码
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
void mount()
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
if (!DefineDosDevice(DDD_RAW_TARGET_PATH, "e:",
"\\\\.\\SimpleDriver"
))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
printf("DefineDosDevice Error ErrCode = %d", ::GetLastError());
}
else
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
printf("DefineDosDevice OK ErrCode = %d", ::GetLastError());
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
int main(int argc, char *argv[])
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
mount();
return 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
运行结果: 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
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
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 )
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PDISK_GEOMETRY disk_geometry;
ULONGLONG length;
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PPARTITION_INFORMATION partition_information;
ULONGLONG length;
if (IrpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(PARTITION_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
break;
}
break;
case IOCTL_DISK_SET_PARTITION_INFO:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SET_PARTITION_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PVERIFY_INFORMATION verify_information;
if (IrpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(VERIFY_INFORMATION))
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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:
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif) {
PIO_STACK_LOCATION io_stack;
io_stack = IoGetCurrentIrpStackLocation(Irp);
if (io_stack->Parameters.Read.Length == 0)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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()
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
使用 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下面都有符号连接。
|