VcdRom 是网上一个爱好者模拟微软虚拟驱动编写一个虚拟光驱程序,近日在研究虚拟磁盘驱动时,无意中看到了VcdRom的虚拟光驱的代码,不禁就开始研究了起来,希望以后能有用武之地。
VcdRom驱动的入口点函数
在Windows 驱动中,不管是wdm还是WDF驱动开发模型,驱动的入口点函数一定是DriverEntry该函数的原型如下;
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
由于VcdRom驱动是传统的NT驱动程序,这个函数的主要目的是为了建立驱动对象和分发函数例程,例如IRP_MJ_CREATE等IRP,同时也负责建立驱动名称映射和连接,如下代码所示;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VCDRomCreateClose;
DriverObject->MajorFunction[IRP_MJ_READ] = VCDRomRead;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VCDRomDeviceControl;
DriverObject->DriverUnload = VCDRomUnload;
RtlInitUnicodeString(&device_name, DEVICE_DIR_NAME);
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name,
FILE_DEVICE_CD_ROM, //0x02
FILE_REMOVABLE_MEDIA | FILE_READ_ONLY_DEVICE, //0x03
FALSE,
&device_object
);
......
status = IoCreateSymbolicLink(
&device_extension->SymbolicLinkName,
&device_name);
在这个函数当中还有另外一个函数起到了很关键的作用,这个函数就是VCDRomQueryDevice,查询已经存在光驱,当发现A~Z中有一个字符没有被占用则依据这个字符创建一个虚拟光驱,代码如下;
for(Index = 'A'; Index <= 'Z'; Index++)
{
RtlZeroMemory(QueryTable, sizeof(QueryTable));
RtlZeroMemory(wszQueryName, sizeof(wszQueryName))
QueryTableName.Buffer = wszQueryName;
QueryTableName.Length = 0;
QueryTableName.MaximumLength = sizeof(wszQueryName); //0xC8
RtlAppendUnicodeToString(&QueryTableName, L"Parameters//Device");
wszDriveName[0] = Index;
wszDriveName[1] = L'/0';
RtlAppendUnicodeToString(&QueryTableName, wszDriveName);
FileName.Buffer = wszFileName;
FileName.Length = 0;
FileName.MaximumLength = sizeof(wszFileName); //0xC8
QueryTable[0].Name = QueryTableName.Buffer;
QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY; //0x01
QueryTable[1].Name = L"IMAGE";
QueryTable[1].EntryContext = (PVOID)&FileName;
QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; //0x01
status = RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE, //0x00
RegistryPath,
&QueryTable[0],
NULL,
NULL);
if (NT_SUCCESS(status))
{
VCDRomCreate(DriverObject, Index, FileName.Buffer);
}
在这个函数中,其中VCDRomCreate又扮演着重要的最重要的角色,创建VCDRom虚拟光驱,第一步穿件虚拟光驱设备,第二步穿件文件操作对象即文件(HANDLE),如下代码;
ULONG
VCDRomCreate(
IN PDRIVER_OBJECT DriverObject,
IN ULONG Index,
IN PWSTR NameBuffer
)
{
PDEVICE_OBJECT DeviceObject;
UNICODE_STRING FileName;
RtlInitUnicodeString(&FileName, NameBuffer);
DeviceObject = NULL;
VCDRomCreateDevice(DriverObject, Index, &NameBuffer[1], &DeviceObject);
VCDRomCreateFile(DeviceObject, &FileName);
return 1;
}
完成上一步之后,入口函数的操作基本完成,接下来就是读写操作了。
接下来就是处理VCDRomRead、VCDRomUnload等函数,这些代码,等以后有时间再做介绍。