如何根据驱动程序及其安装文件来访问该设备呢(Visual C++ or C++ Builder均可以)

原创 2003年07月22日 08:00:00

First of all,我要讲一下Windows对每检测到一个新设备的处理过程:
1.首先Windows将各种设备分成不同的设备类,比如说USB Storage存储类设备,而这些类设备都有一个GUID,它们位于注册表中HKEY_LOCAL_MACHINE/ControlSet001/Control/Class下,在这个键下你看到的以128位长度结点名称为结点都是设备类。
2.当检测到一个新设备时,Windows OS就会到KEY_LOCAL_MACHINE/ControlSet001下去搜索,如果此类设备已经注册,那么就此子键下增加一个子键,这个子键的名称是顺序递增的,如果当前该类设备中最大子键名称为0005,那么新设备的就是0006,0000,0001等就是设备的序列号。如果发现这个设备没有注册,那么OS就会以该设备对应的驱动程序安装文件.inf中的ClassGuid为名称来创建一个键,并将此被检测到的设备的序列号为0,在该键下创建一个子键,并且命名为0000来存储该设备的相关信息,之所以命名为0000,因为该设备是该类设备的第一个。
3.有些设备,如我们常用的COM1,COM2,当我们要访问它时可以用CreateFile("COM1"。。。)就可以打开串口,这里的COM1,COM2是符号名,有些设备也用到了符号名,比如说有些USB设备虚拟成一个COM口,如COM3,COM4,COM5等,在程序中我们只需要对COM3,COM4,COM5进行访问,就相当对该设备进行访问。
在没有符号名的情况下,我们如何根据设备驱动程序以及设备安装文件.inf来对设备进行访问呢?我们可以这样:
1.首先,我们在这个设备的符号名中找到设备类的ClassGuid,这是一定可以找到的。
2.然后我们到HKEY_LOCAL_MACHINE/ControlSet001/Control/Class下去找这个设备类,在找到后,我们再找它的子键,找到该设备对应的序列号,如它到底是0000还是0001,在得到这两个数据即ClassGuid和设备序列号后,就好办了。
下面我写一段代码,用来访问我机器上的一USB设备,并在listbox中列出当前机器上此设备类下的所有设备。

extern "C"
{
#include "setupapi.h"
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   //First of all,I will enumurate all the devices under the specified deviceclass
   HKEY m_hKey,m_hSubKey;
   long m_lResult=0;//using for return value
   int m_nKeyIndex=0,m_nValueIndex=0;
   char cKeyName[255],cValue[255];
   unsigned char pbData[255];
   BOOL bOutter=TRUE,bInter=TRUE;
   char *cRoot="SYSTEM//ControlSet001//Control//Class//{4D36E96D-E325-11CE-BFC1-08002BE10318}";
   AnsiString m_sAttached("");
   m_lResult=::RegOpenKeyEx(HKEY_LOCAL_MACHINE,cRoot,0,KEY_ALL_ACCESS,&m_hKey);
   if(m_lResult!=ERROR_SUCCESS) return FALSE;
   //Enum Keys
   while(bOutter){
   m_lResult=::RegEnumKey(m_hKey,m_nKeyIndex,cKeyName,255);
   bInter=TRUE;
   if(m_lResult!=ERROR_SUCCESS) bOutter=FALSE;
   else{
   m_lResult=::RegOpenKeyEx(m_hKey,cKeyName,0,KEY_ALL_ACCESS,&m_hSubKey);
   if(m_lResult!=ERROR_SUCCESS){
   ::RegCloseKey(m_hKey);
   return FALSE;}
   while(bInter){
   unsigned long m_nDataSize=255;
   unsigned long m_nValueNameSize=255;
   unsigned long m_nType;
   m_lResult=::RegEnumValue(m_hSubKey,m_nValueIndex,cValue,&m_nValueNameSize,0,&m_nType,pbData,&m_nDataSize);
   if(m_lResult!=ERROR_SUCCESS)  bInter=FALSE;
    else{
     if(!strcmp(cValue,"AttachedTo")){
      m_sAttached=(AnsiString)(char*)pbData;
     }
     if(!strcmp(cValue,"DriverDesc")){
      m_lstDevice->Items->Add((AnsiString)(char*)pbData+"  "+m_sAttached);
     }
     m_nValueIndex++;
    }
   }
   m_nValueIndex=0;
   m_nKeyIndex++;
   
  }
 }
 ::RegCloseKey(m_hKey);
 ::RegCloseKey(m_hSubKey);
   
  file://Next Step,I will access one of the device.I know its device serialno:0001
  DWORD ReqLength;
  DWORD Flags=DIGCF_PRESENT|DIGCF_DEVICEINTERFACE;
  GUID CardGuid={4D36E96D-E325-11CE-BFC1-08002BE10318};
  HANDLE hCard=0;
  PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceDetailData;
     SP_DEVICE_INTERFACE_DATA        DeviceInterfaceData;
     DeviceInterfaceData.cbSize=sizeof(SP_DEVICE_INTERFACE_DATA);
     hCard=SetupDiGetClassDevs(&CardGuid,NULL,NULL,Flags);
     if(hCard==INVALID_HANDLE_VALUE){
     ::MessageBox(0,"Invalid Parameters!","Error",MB_OK|MB_ICONERROR);
         return;}
     BOOL status=SetupDiEnumDeviceInterfaces(hCard,NULL,&CardGuid,Index,&DeviceInterfaceData,&ReqLength,
 NULL);//Index即设备的序号,这里的Index为1.
 if(!status){
  ::MessageBox(0,"Failed to enumurate the specified
 device!","Error",MB_OK+MB_ICONERROR);
         ::CloseHandle(hCard);
         return;}
 SetupDiGetInterfaceDeviceDetail(hCard,&DeviceInterfaceData,NULL,0,&ReqLength,NULL);
 DeviceDetailData=(PSP_INTERFACE_DEVICE_DETAIL_DATA)new char[ReqLength];
 if(DeviceDetailData){
  ::MessageBox("ERROR NOT ENOUGH MEMORY!","Error",MB_OK+MB_ICONERROR);
         ::CloseHandle(hCard);
         return;}
         status=SetupDiGetInterfaceDeviceDetail(hCard,&DeviceInterfaceData,DeviceDetailData,ReqLength,&ReqLength,NULL);
         if(!status){
  ::MessageBox(0,"Failed to get interface detailed data","Error",MB_OK+MB_ICONERROR);
         delete DeviceDetailData;
         DeviceDetailData=NULL;
         return;}
        ShowMessage(DeviceDetailData->DevicePath());//在这里得到DevicePath就像得到符号名一样,那么接着下来,你你就可以象对串口操作一样来写程序,即是说:
        HANDLE hUSB=::CreateFile(DeviceDetailData.DevicePath(),..............);
        file://ReadFile,WriteFile and so on.....
}

所有以file:为前缀的地方都是注释部分,特此声明,以免误解,这是CSDN文档编辑器自动加的。
因最近一直在忙于学习驱动开发,现正在用DriverStudio进行开发一个USB Modem的驱动程序,有一点学习心得,特此交流一下。

Linux应用程序访问字符设备驱动详细过程解析

在linux下对上面的文件进行静态编译(考虑到前面开发板上移植的某些库还没有添加进去)生成read-mem目标文件,然后进行反汇编并将反汇编生成的文件导入到当前目录下的dump上去。 这里红箭头指向的...
  • coding__madman
  • coding__madman
  • 2016年05月08日 18:52
  • 4834

C语言竟是如何调用硬件的

大家都知道我们可以使用C语言写一段程序来控制硬件工作,但你知道其工作原理吗? 网友北极 C语言在实际运行中,都是以汇编指令的方式运行的,由编译器把C语言编译成汇编指令,CPU直接执行汇...
  • xujingzhong0077
  • xujingzhong0077
  • 2016年10月10日 09:56
  • 2036

在Visual Studio 2013 中编写C语言、C++程序

1、打开Visual Studio 2013 ,文件-->新建-->项目: 2、选择Visual C++,记得选择空项目,填写名称-->确定: 3、新建后的项目大概架构: ...
  • u011596810
  • u011596810
  • 2015年11月11日 19:47
  • 7854

Visual C++ .NET 开发驱动程序详解

  • 2009年10月06日 11:14
  • 10.02MB
  • 下载

Linux设备驱动程序安装fatal error: linux/module.h: No such file or directory

在做Linux设备驱动程序安装实验时,执行gcc -c mydev.c产生fatal error: linux/module.h: No such file or directory错误信息 编程时...
  • Coy993055697
  • Coy993055697
  • 2016年10月16日 20:18
  • 1404

Visual C++ 2008 无法启动程序,系统找不到指定的文件

用Visual C++ 2008 新建C++项目后,运行时报错, 代码如下:只是简单的打印helloworld HelloWorld.cpp#include using namespace st...
  • w690333243
  • w690333243
  • 2017年11月12日 15:31
  • 129

vc6.0 打开文件的时候出现Microsoft Visual C++:MSDEV.EXE 应用程序错误

使用过Microsoft Visual C++6.0的朋友可能有过这样的经历:用VC6.0可以新建文件和工程,也能打开工作空间,但就是不能打开文件。打开文件时会弹出MSDEV.EXE 应用程序错误的对...
  • Candy1232009
  • Candy1232009
  • 2012年01月04日 11:06
  • 14947

Platform Builder和Embedded visual C++简介

1 Platform Builder 介绍 Platform Builder 是微软公司提供给Windows CE 开发人员进行基于Windows CE 平台下嵌入式操作系统定制的集成开发环境。它提供...
  • feiskyer
  • feiskyer
  • 2012年09月29日 09:54
  • 513

基于Visual C++之Windows核心编程代码分析(3)实现程序自动安装

我们进行Windows编程的时候,经常需要开发程序,使程序进行自动安装。 具体如何实现呢,请见代码实现与注释分析。 [cpp] view plain copy ...
  • flyingleo1981
  • flyingleo1981
  • 2016年12月08日 21:41
  • 212

演练:使用安装项目部署 Visual C++ 应用程序

演练:使用安装项目部署 Visual C++ 应用程序此内容是人工翻译的。 将光标移到内容窗格中的文本上,以查看原文。 译文原文演练:使用安装项目部署 Visual C++ 应用程序Visual St...
  • shoushui2009
  • shoushui2009
  • 2011年05月15日 23:10
  • 872
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何根据驱动程序及其安装文件来访问该设备呢(Visual C++ or C++ Builder均可以)
举报原因:
原因补充:

(最多只允许输入30个字)