阅读:4624回复:16
请问怎样编写支持多个相同设备的驱动程序?用户被禁言,该主题自动屏蔽! |
|
沙发#
发布于:2002-03-01 10:18
既然device相同,那就是一个driver而已。
|
|
|
板凳#
发布于:2002-03-01 10:27
用户被禁言,该主题自动屏蔽! |
|
地板#
发布于:2002-03-01 12:23
那么驱动程序怎样区分多个设备,用户程序又如何区分? 如下代码可能能满足你的需要: #define AVALANCH_MAX_SUPPORTED_DEVICE 16 #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->MajorFunction[IRP_MJ_CREATE] = Avalanch_CreateDispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Avalanch_CloseDispatch; 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; DriverObject->MajorFunction[IRP_MJ_READ] = Avalanch_Read; DriverObject->MajorFunction[IRP_MJ_WRITE} = Avalanch_Write; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Avalanch_DeviceIoControl; 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 ); if(NT_SUCCESS(status)) { AValanch_DeviceInitialize(PhysicalDeviceObject, *FileDeviceObject); } return status; } VOID AValanch_DeviceInitialize(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_OBJECT FileDeviceObject) { NTSTATUS status = STATUS_SUCCESS; PAVALANCH_DEVICE_EXTENSION DeviceExtension = FileDeviceObject->DeviceExtension; RtlZeroMemory(DeviceExtension, sizeof(AVALANCH_DEVICE_EXTENSION)); Avalanch_InterLockedQueue_Initialize(&DeviceExtension->InterLockQueue); DeviceExtension->DeviceObject = FileDeviceObject; DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; DeviceExtension->PnpDeviceWorkState = DEVICE_WORK_STATE_ADD_DEVICE; DeviceExtension->PnpStoppable = FALSE; DeviceExtension->PnpRemovable = FALSE; DeviceExtension->IrpCountNumber = 1; DeviceExtension->PowerSet = TRUE; DeviceExtension->DevicePowerState = PowerDeviceD0; DeviceExtension->SystemPowerState = PowerSystemWorking; DeviceExtension->PowerControlOnOpen = TRUE; InterlockedExchange((PLONG)&DeviceExtension->MarkPnpStopped, TRUE); InterlockedExchange(&DeviceExtension->PowerRestoreState, PowerDeviceD3); InterlockedExchange(&DeviceExtension->PowerSaveState, PowerSystemSleeping3); InterlockedExchange((PLONG)&DeviceExtension->RegistersSaved, FALSE); InterlockedExchange((PLONG)&DeviceExtension->PowerDownAllowed, TRUE); InterlockedExchange((PLONG)&DeviceExtension->SetPoweringDown, FALSE); KeInitializeEvent(&DeviceExtension->IrpCountEvent, SynchronizationEvent, TRUE); DeviceExtension->Dma_Description.ScatterGather = FALSE; DeviceExtension->Dma_Description.InterfaceType = InterfaceTypeUndefined; DeviceExtension->Dma_Description.CommonBufferVirtualAddress = 0; DeviceExtension->Dma_Description.DmaAdapter = NULL; DeviceExtension->Dma_Description.CommonBufferLogicalAddress.QuadPart = 0; DeviceExtension->Dma_Description.Mdl = NULL; DeviceExtension->Dma_Description.HaveMapRegisters = TRUE; DeviceExtension->TopDeviceObject = IoAttachDeviceToDeviceStack(FileDeviceObject, PhysicalDeviceObject); if(DeviceExtension->TopDeviceObject != NULL) { DeviceExtension->DeviceAttatched = TRUE; } Avalanch_CleanupDmaVariables(); DeviceExtension->LastAvMailBoxBuffer.Mailbox = Mail_00; DeviceExtension->LastAvMailBoxBuffer.Value = 0; DeviceExtension->LastAvMailBoxBuffer.RegisterValue = 0; DeviceExtension->PowerControlOnOpen = FALSE; DeviceExtension->WaitMailboxIrp = NULL; } 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; } 应用程序好处里,用createfile()打开不同的设备! |
|
地下室#
发布于:2002-03-01 13:33
实际上,相同的设备只要同一个驱动就可以了,不过配置的USB address不同而已
|
|
|
5楼#
发布于:2002-03-01 16:01
用户被禁言,该主题自动屏蔽! |
|
6楼#
发布于:2002-03-01 22:49
其实如果用Driver Studio 的话,根本就不必做额外的工作,DS产生的框架中有一个成员m_Uint,它是一个计数器,当多块相同卡插在PC上时,枚举器列举设备时,调用设备驱动程序的AddDevice列程时,DS代码会将m_Uint成员++,并创建一个新的KPnpDevice实例,该实例就对应着一块卡。
至于用户端调用,如果有两块卡,设备链接名为DriverDevice的话 如下打开两块卡: HANDLE hDevice0 = CreateFile(\"\\\\\\\\.\\\\DriverDevice0\", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); HANDLE hDevice1 = CreateFile(\"\\\\\\\\.\\\\DriverDevice1\", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 注意两者设备名的区别 \"\\\\\\\\.\\\\DriverDevice0\" ,\"\\\\\\\\.\\\\DriverDevice1\" 有几块卡相应的就是0,1,2,etc. |
|
7楼#
发布于:2002-03-02 09:08
用户被禁言,该主题自动屏蔽! |
|
8楼#
发布于:2002-03-02 13:45
好文章
|
|
|
9楼#
发布于:2002-03-02 22:55
我也正要做相同的东西,多加交流。
|
|
|
10楼#
发布于:2002-03-03 23:04
但我想用设备接口进行标识,是不是得设置多个接口GUID。 GUID是同一个,但是每个device的序号不同。你只要自己做一个试验就都明白了! |
|
|
11楼#
发布于:2002-03-04 10:31
你可以在AddDevice()中每一次都改变一下SymbolLink,那每个设备都有一个不同的对外接口了。
但我觉的难点在于如何并行处理上。 |
|
12楼#
发布于:2002-03-08 16:22
我也很疑惑。但我比较关心硬件的问题。硬件有什么要考虑。
|
|
|
13楼#
发布于:2002-03-08 16:28
PCI设备跟硬件应该没有什么关系
|
|
|
14楼#
发布于:2005-03-24 14:58
xue xi zhong
|
|
驱动老牛
![]() |
15楼#
发布于:2005-03-24 17:15
处理多个相同的设备主要是设备的枚举产生不同的设备ID
不是其他什么的。 |
|
16楼#
发布于:2010-08-05 19:40
我也遇到了这个问题,今天看了你们的讨论,总算进了一步。我使用DS,在驱动的ADDDEVICE中循环创建了4个不同设备名的设备。在应用程序中按照设备0 1 2 3 的格式都可以打开,但是除了0号设备外,其余的只能打开设备,但是不能进行读写操作。我在monitor中除了看见createFIle的包下来外,其余的包都没有下来,应用程序就直接死了!不知是什么原因,望各位高手指点呀,谢谢了!
|
|