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等函数,这些代码,等以后有时间再做介绍。