阅读:2250回复:18
为什么仅能安装第一个设备?(50分)
UNICODE_STRING deviceName, linkName, itos;
RtlInitUnicodeString(&itos,L\"\\\\Device\\\\VC\"); deviceName.Length = 100; deviceName.MaximumLength = 120; deviceName.Buffer = (PWSTR) ExAllocatePoolWithTag(PagedPool, deviceName.MaximumLength, 1633); RtlCopyUnicodeString(&deviceName, &itos); status = RtlIntegerToUnicodeString(lPortInstance,10,&itos); RtlAppendUnicodeStringToString(&deviceName, &itos); RtlInitUnicodeString(&itos,L\"\\\\DosDevices\\\\C\"); linkName.Length = 100; linkName.MaximumLength = 120; linkName.Buffer = (PWSTR) ExAllocatePoolWithTag(PagedPool, linkName.MaximumLength, 1633); RtlCopyUnicodeString(&linkName, &itos); RtlIntegerToUnicodeString(lPortInstance+3,10,&itos); RtlAppendUnicodeStringToString(&linkName, &itos); IoCreateDevice{.................} IoCreateSymbolicLink(..............) RtlFreeUnicodeString(&linkName); RtlFreeUnicodeString(&deviceName); 安装第一个设备是成功的,但是安装第二个设备时,linkName,itos,deviceName内容都不对了。 怎么回事? |
|
最新喜欢:dregs
|
沙发#
发布于:2002-08-15 14:38
IoCreateDevice的第五个参数是不是FILE_AUTOGENERATED_DEVICE_NAME?
|
|
|
板凳#
发布于:2002-08-15 14:45
IoCreateDevice的第五个参数是不是FILE_AUTOGENERATED_DEVICE_NAME? 不是,是0,看DDK的文档所FILE_AUTOGENERATED_DEVICE_NAME是由系统指定一个名称,而不用用户指定的deviceName。 我觉得问题还是处在unicodestring上,为什么第二次调用RtlInitUnicodeString(&itos,L\"\\\\Device\\\\VC\"); itos的内容就对了呢? 还有什么地方要初始化或重新分配的我没有做? |
|
|
地板#
发布于:2002-08-15 14:51
你错了。FILE_AUTOGENERATED_DEVICE_NAME的意思是在你的\\\\Device\\\\VC 当有两个以上设备时在后面自动加上\\\\Device\\\\VC0、
\\\\Device\\\\VC1的区别。 否则就需要你自己在驱动程序中自己添加来分别它们。 |
|
|
地下室#
发布于:2002-08-15 14:54
你的比较麻烦,我实现过你说的需求
WCHAR DName[] = L\"\\\\Device\\\\DrvPnP0\"; WCHAR LName[] = L\"\\\\??\\\\DrvPnP0\"; int instance = 0; do { DName[14] = (USHORT)(\'0\' + instance); LName[10] = (USHORT)(\'0\' + instance); RtlInitUnicodeString(&DvcName, DName); status = IoCreateDevice(p_DrvObj, sizeof(DrvPnP_Extension), &DvcName, FILE_DEVICE_UNKNOWN, 0, FALSE, &p_LowDvcObj); instance++; } while (!NT_SUCCESS(status) && (instance < MAX_DEVICES_NUM)); |
|
|
5楼#
发布于:2002-08-15 14:55
斑竹说的很好,又学了一招 :D :P
|
|
|
6楼#
发布于:2002-08-15 16:02
你错了。FILE_AUTOGENERATED_DEVICE_NAME的意思是在你的\\\\Device\\\\VC 当有两个以上设备时在后面自动加上\\\\Device\\\\VC0、 IoCreateDevice{.................}对了, 但是IoCreateSymbolicLink(..............)就不对了,linkName没有变。所以安装失败了。 怎么办? |
|
|
7楼#
发布于:2002-08-15 16:35
奇怪哦,应该是先IoCreateSymbolicLink(..............)然后再IoCreateDevice的哦。
|
|
|
8楼#
发布于:2002-08-15 16:36
你错了。FILE_AUTOGENERATED_DEVICE_NAME的意思是在你的\\\\Device\\\\VC 当有两个以上设备时在后面自动加上\\\\Device\\\\VC0、我认为你说的不对。加上此参数时,PnP Manager重新生成一个DeviceName,系统可以保证是唯一的,但与原先的name没有关系。下面是DDK文档:Directs the I/O Manager to generate a name for the device, instead of the caller specifying a DeviceName when calling this routine. The I/O Manager ensures that the name is unique. This characteristic is typically specified by a PnP bus driver to generate a name for a physical device object (PDO) for a child device on its bus. This characteristic is new for Windows 2000 and Windows 98. TO:beaveror 你的问题是安装第二个设备时,此时使用的名字在系统中已经存在,所以创建不成功。 你可以这样写:(这个方法比较笨,但有效) static int devcount=0; if(devcount==0) { ..RtlInitUnicodeString(&DvcName, L\"\"\\\\Device\\\\Drv0\"); ..RtlInitUnicodeString(&linkName, L\"\"\\\\DosDevices\\\\link0\"); } else if(devcount==1) { ..RtlInitUnicodeString(&DvcName, L\"\"\\\\Device\\\\Drv1\"); ..RtlInitUnicodeString(&linkName, L\"\"\\\\DosDevices\\\\link1\"); } devcount++; ... ... |
|
9楼#
发布于:2002-08-15 16:39
[quote]你错了。FILE_AUTOGENERATED_DEVICE_NAME的意思是在你的\\\\Device\\\\VC 当有两个以上设备时在后面自动加上\\\\Device\\\\VC0、我认为你说的不对。加上此参数时,PnP Manager重新生成一个DeviceName,系统可以保证是唯一的,但与原先的name没有关系。下面是DDK文档:Directs the I/O Manager to generate a name for the device, instead of the caller specifying a DeviceName when calling this routine. The I/O Manager ensures that the name is unique. This characteristic is typically specified by a PnP bus driver to generate a name for a physical device object (PDO) for a child device on its bus. This characteristic is new for Windows 2000 and Windows 98. TO:beaveror 你的问题是安装第二个设备时,此时使用的名字在系统中已经存在,所以创建不成功。 你可以这样写:(这个方法比较笨,但有效) static int devcount=0; if(devcount==0) { ..RtlInitUnicodeString(&DvcName, L\"\"\\\\Device\\\\Drv0\"); ..RtlInitUnicodeString(&linkName, L\"\"\\\\DosDevices\\\\link0\"); } else if(devcount==1) { ..RtlInitUnicodeString(&DvcName, L\"\"\\\\Device\\\\Drv1\"); ..RtlInitUnicodeString(&linkName, L\"\"\\\\DosDevices\\\\link1\"); } devcount++; ... ... [/quote] 我以前就是这么做的,可是我要加100个设备,代码要写多长呀。 |
|
|
10楼#
发布于:2002-08-15 16:41
你的比较麻烦,我实现过你说的需求 好像有问题,当instance>10的时候对吗? 我得到的结果是asiic字符,有“:”“=”之类的东东。 |
|
|
11楼#
发布于:2002-08-15 16:53
那就用这个:
sprintf(aName,\"\\\\Device\\\\Scanner%d\",n); RtlInitAnsiString(&ansiName, aName); RtlAnsiStringToUnicodeString(&uName, &ansiName, TRUE); [编辑 - 8/15/02 by tigerzd] |
|
|
12楼#
发布于:2002-08-15 17:05
奇怪哦,应该是先IoCreateSymbolicLink(..............)然后再IoCreateDevice的哦。 先createdevice,在是symlink吧。 |
|
13楼#
发布于:2002-08-15 17:23
[quote]奇怪哦,应该是先IoCreateSymbolicLink(..............)然后再IoCreateDevice的哦。 先createdevice,在是symlink吧。 [/quote] 握手。 |
|
|
14楼#
发布于:2002-08-15 17:39
[quote]你的比较麻烦,我实现过你说的需求 好像有问题,当instance>10的时候对吗? 我得到的结果是asiic字符,有“:”“=”之类的东东。 [/quote] 你把他的DName[14] = (USHORT)(\'0\' + instance); LName[10] = (USHORT)(\'0\' + instance); 改成UNCODE的看看。就是RtlIntegerToUnicode(..instance..)。 怎么能这样做,unicode呀。 |
|
15楼#
发布于:2002-08-15 17:57
请看一看我的代码的相关部分吧!
#include <wdm.h> #include \"Avalanch.h\" #if defined(USING_GUIDS) // drivers interface GUID (valid when using GUID interface) CONST GUID guid_class_Avalanch = { 0x0ec25560L, 0xee9f, 0x11df,{ 0x9b, 0x77, 0x20, 0x00, 0xc0, 0xd4, 0xc3, 0xbf } }; #endif NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING pRegistryPath ) { DriverObject->DriverExtension->AddDevice = Avalanch_AddDevice; DriverObject->DriverStartIo = Avalanch_StartIo; DriverObject->MajorFunction[IRP_MJ_CREATE] = Avalanch_CreateDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Avalanch_CloseDispatch; DriverObject->MajorFunction[IRP_MJ_READ] = Avalanch_Read; DriverObject->MajorFunction[IRP_MJ_WRITE] = Avalanch_Write; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Avalanch_DeviceIoControl; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Avalanch_CleanupDispatch; DriverObject->MajorFunction[IRP_MJ_POWER] = Avalanch_PowerDispatch; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = Avalanch_SystemControlDispatch; DriverObject->MajorFunction[IRP_MJ_PNP] = Avalanch_PnpDispatch; return STATUS_SUCCESS; } NTSTATUS Avalanch_AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS status; ULONG InstanceNumber = 0; PDEVICE_OBJECT FileDeviceObject = NULL; PAVALANCH_DEVICE_EXTENSION DeviceExtension = NULL; #if defined(USING_GUIDS) status = Avalanch_CreateDevice( DriverObject, PhysicalDeviceObject, NULL, AVALANCH_DEVICE_TYPE, 0, &FileDeviceObject ); if(NT_SUCCESS(status)) { DeviceExtension = FileDeviceObject->DeviceExtension; status = IoRegisterDeviceInterface( PhysicalDeviceObject, &guid_class_Avalanch, NULL, &DeviceExtension->SymbolicLinkName if(NT_SUCCESS(status)) ); DeviceExtension->RegisterDeviceInterface = TRUE; } #else for(InstanceNumber = 0; InstanceNumber < AVALANCH_MAX_SUPPORTED_DEVICE; InstanceNumber++) { status = Avalanch_CreateDevice( DriverObject, PhysicalDeviceObject, (PWSTR)AVALANCH_DEVICE_NAME_PREFIX, AVALANCH_DEVICE_TYPE, InstanceNumber, &FileDeviceObject ); if(status != STATUS_OBJECT_NAME_COLLISION) break; } #endif if(NT_SUCCESS(status)) { FileDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; FileDeviceObject->Flags |= DO_DIRECT_IO; FileDeviceObject->Flags |= DO_POWER_PAGABLE; } return STATUS_SUCCESS; } NTSTATUS Avalanch_CreateDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PWSTR DeviceNamePrefix, IN ULONG DeviceType, IN ULONG DeviceNumber, OUT PDEVICE_OBJECT *FileDeviceObject ) { NTSTATUS status; status = Avalanch_CreateDeviceObject( DriverObject, DeviceNamePrefix, DeviceType, DeviceNumber, FileDeviceObject ); return status; } NTSTATUS Avalanch_CreateDeviceObject( IN PDRIVER_OBJECT DriverObject, IN PWSTR DeviceNamePrefix, IN ULONG DeviceType, IN ULONG DeviceNumber, OUT PDEVICE_OBJECT *FileDeviceObject ) { UNICODE_STRING DeviceName = {0, 0, NULL}; //UNICODE_STRING DosDeviceName = {0, 0, NULL}; NTSTATUS status; PAVALANCH_DEVICE_EXTENSION DeviceExtension = NULL; #if defined(USING_GUIDS) status = IoCreateDevice( DriverObject, sizeof(AVALANCH_DEVICE_EXTENSION), NULL, AVALANCH_DEVICE_TYPE, 0, FALSE, FileDeviceObject ); #else status = Avalanch_BuildUnicodeString(&DeviceName, DeviceNamePrefix, DeviceNumber); if(NT_SUCCESS(status)) { status = IoCreateDevice( DriverObject, sizeof(AVALANCH_DEVICE_EXTENSION), &DeviceName, AVALANCH_DEVICE_TYPE, 0, FALSE, FileDeviceObject ); if(NT_SUCCESS(status)) { DeviceExtension = (*FileDeviceObject)->DeviceExtension; status = Avalanch_BuildUnicodeString(&DeviceExtension->SymbolicLinkName, (PWSTR)AVALANCH_DOS_DEVICE_NAME_PREFIX, DeviceNumber); if(NT_SUCCESS(status)) { status = IoCreateSymbolicLink(&DeviceExtension->SymbolicLinkName, &DeviceName); if(!NT_SUCCESS(status)) { IoDeleteDevice(*FileDeviceObject); } } } } #endif RtlFreeUnicodeString(&DeviceName); return status; } NTSTATUS Avalanch_BuildUnicodeString(OUT PUNICODE_STRING DeviceName, IN PWSTR DeviceNamePrefix, IN ULONG InstanceNumber) { WCHAR wcInstanceNumber[16]; UNICODE_STRING uniInstanceNumberString; UNICODE_STRING uniDeviceNamePrefixString; NTSTATUS status; RtlInitUnicodeString(DeviceName, NULL); RtlInitUnicodeString(&uniDeviceNamePrefixString, DeviceNamePrefix); uniInstanceNumberString.Length = 0; uniInstanceNumberString.MaximumLength = sizeof(wcInstanceNumber); uniInstanceNumberString.Buffer = wcInstanceNumber; status = RtlIntegerToUnicodeString(InstanceNumber, 10, &uniInstanceNumberString); if(NT_SUCCESS(status)) { DeviceName->MaximumLength = (USHORT)(uniDeviceNamePrefixString.Length + uniInstanceNumberString.Length + sizeof(UNICODE_NULL)); DeviceName->Buffer = ExAllocatePool(PagedPool, DeviceName->MaximumLength); if(DeviceName->Buffer != NULL) { RtlZeroMemory( DeviceName->Buffer, DeviceName->MaximumLength ); RtlAppendUnicodeStringToString(DeviceName, &uniDeviceNamePrefixString); RtlAppendUnicodeStringToString(DeviceName, &uniInstanceNumberString); } else { status = STATUS_INSUFFICIENT_RESOURCES; } } return status; } |
|
16楼#
发布于:2002-08-15 22:04
[quote][quote]奇怪哦,应该是先IoCreateSymbolicLink(..............)然后再IoCreateDevice的哦。 先createdevice,在是symlink吧。 [/quote] 握手。 [/quote] 本来就是吗。。。 :) |
|
|
17楼#
发布于:2002-08-16 08:26
[quote]你的比较麻烦,我实现过你说的需求 好像有问题,当instance>10的时候对吗? 我得到的结果是asiic字符,有“:”“=”之类的东东。 [/quote] >10没试过,我做的是8个设备。这因该好解决呀!你把14、10该成比较小得数试试,或者使用Rtlxxx类的函数都可以。 |
|
|
18楼#
发布于:2002-08-16 09:43
我搞定了,大于10或100的就用一个算法把它一个位一个位的弄出来加一下就可以了。
多谢各位了。 |
|
|