您的位置:首页 > 编程语言

VcdRom 虚拟光驱驱动代码分析

2010-09-07 23:49 281 查看
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等函数,这些代码,等以后有时间再做介绍。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: