Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:4624回复:16

请问怎样编写支持多个相同设备的驱动程序?

楼主#
更多 发布于:2002-03-01 09:49
用户被禁言,该主题自动屏蔽!

最新喜欢:

juventusjuvent... stoneyrstoney...
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-03-01 10:18
既然device相同,那就是一个driver而已。
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2002-03-01 10:27
用户被禁言,该主题自动屏蔽!
dazzy
驱动中牛
驱动中牛
  • 注册日期2001-03-23
  • 最后登录2008-08-12
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望10点
  • 贡献值1点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于: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()打开不同的设备!
zhuzc
驱动中牛
驱动中牛
  • 注册日期2001-09-01
  • 最后登录2005-04-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-03-01 13:33
实际上,相同的设备只要同一个驱动就可以了,不过配置的USB address不同而已
我是树上的那只鸟,整理着自己的羽毛,看着城市的喧嚣……
Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2002-03-01 16:01
用户被禁言,该主题自动屏蔽!
zgm
zgm
驱动牛犊
驱动牛犊
  • 注册日期2002-01-18
  • 最后登录2002-05-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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.


Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2002-03-02 09:08
用户被禁言,该主题自动屏蔽!
wbsyqm
驱动牛犊
驱动牛犊
  • 注册日期2001-10-15
  • 最后登录2002-03-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-03-02 13:45
好文章
知识领导世界潮流
lvwj
驱动老牛
驱动老牛
  • 注册日期2001-08-21
  • 最后登录2021-01-31
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望181点
  • 贡献值0点
  • 好评度52点
  • 原创分0分
  • 专家分0分
  • 社区居民
9楼#
发布于:2002-03-02 22:55
我也正要做相同的东西,多加交流。
www.bjjcz.com
rayyang2000
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2012-09-13
  • 粉丝3
  • 关注0
  • 积分1036分
  • 威望925点
  • 贡献值3点
  • 好评度823点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-03-03 23:04
但我想用设备接口进行标识,是不是得设置多个接口GUID。
我想其他操作如中断处理,是不是得进行处理。

GUID是同一个,但是每个device的序号不同。你只要自己做一个试验就都明白了!
天天coding-debugging中----超稀饭memory dump file ======================================================== [b]Windows Device Driver Development and Consulting Service[/b] [color=blue][url]http://www.ybwork.com[/url][/color] ========================================================
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-03-04 10:31
你可以在AddDevice()中每一次都改变一下SymbolLink,那每个设备都有一个不同的对外接口了。
但我觉的难点在于如何并行处理上。
julan
驱动小牛
驱动小牛
  • 注册日期2001-11-23
  • 最后登录2005-04-29
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-03-08 16:22
我也很疑惑。但我比较关心硬件的问题。硬件有什么要考虑。
echo
wangbo
驱动牛犊
驱动牛犊
  • 注册日期2001-06-11
  • 最后登录2002-07-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-03-08 16:28
PCI设备跟硬件应该没有什么关系
神仙?妖怪? 谢谢!
tony221
驱动牛犊
驱动牛犊
  • 注册日期2001-12-03
  • 最后登录2013-04-16
  • 粉丝0
  • 关注0
  • 积分187分
  • 威望61点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-03-24 14:58
xue xi zhong
zhangshengyu
驱动老牛
驱动老牛
  • 注册日期2003-10-03
  • 最后登录2016-07-26
  • 粉丝0
  • 关注0
  • 积分792分
  • 威望696点
  • 贡献值41点
  • 好评度499点
  • 原创分0分
  • 专家分0分
  • 社区居民
15楼#
发布于:2005-03-24 17:15
处理多个相同的设备主要是设备的枚举产生不同的设备ID
不是其他什么的。
---内核开发合作或提供基础技术服务QQ:22863668 ---
chaochao1986081
驱动牛犊
驱动牛犊
  • 注册日期2009-10-13
  • 最后登录2011-01-12
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望51点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2010-08-05 19:40
我也遇到了这个问题,今天看了你们的讨论,总算进了一步。我使用DS,在驱动的ADDDEVICE中循环创建了4个不同设备名的设备。在应用程序中按照设备0  1  2  3  的格式都可以打开,但是除了0号设备外,其余的只能打开设备,但是不能进行读写操作。我在monitor中除了看见createFIle的包下来外,其余的包都没有下来,应用程序就直接死了!不知是什么原因,望各位高手指点呀,谢谢了!
游客

返回顶部