jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
阅读:2001回复:14

D12TEST的应用程序中两次打开的设备句柄有什么区别吗?(附源代码)

楼主#
更多 发布于:2003-06-20 09:51
在应用程序中同时打开了两个设备句柄,不太明白这是什么意思。
难道第一次打开只是为了验证设备是否能打开吗?但也不太象。

hFile = open_file(threadParam->pipe_name);
hDevice = open_dev();//读去数据用的是这个句柄。
bResult = DeviceIoControl(hDevice,
      IOCTL_WRITE_REGISTERS,
   (PVOID)&ioBlock,
    sizeof(IO_BLOCK),
    NULL,
    0,
    &nBytes,
    NULL);

下面是几个函数的定义和源代码:
HANDLE
open_file( char *filename)
{

HANDLE h;

if ( !GetUsbDeviceFileName(
(LPGUID) &GUID_CLASS_D12_BULK,
completeDeviceName) )
{
return  INVALID_HANDLE_VALUE;
}

    strcat (completeDeviceName,
\"\\\\\"
);

    strcat (completeDeviceName,
filename
);

h = CreateFile(completeDeviceName,
GENERIC_WRITE,// | GENERIC_READ,
FILE_SHARE_WRITE,// | FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);

return h;
}

HANDLE
open_dev()
{

HANDLE hDEV = OpenUsbDevice( (LPGUID)&GUID_CLASS_D12_BULK, completeDeviceName);

return hDEV;
}


BOOL
GetUsbDeviceFileName( LPGUID  pGuid, char *outNameBuf)
{
HANDLE hDev = OpenUsbDevice( pGuid, outNameBuf );
if ( hDev != INVALID_HANDLE_VALUE )
{
CloseHandle( hDev );
return TRUE;
}
return FALSE;

}


HANDLE
OpenUsbDevice( LPGUID  pGuid, char *outNameBuf)
{
   ULONG NumberDevices;
   HANDLE hOut = INVALID_HANDLE_VALUE;
   HDEVINFO                 hardwareDeviceInfo;
   SP_INTERFACE_DEVICE_DATA deviceInfoData;
   ULONG                    i;
   BOOLEAN                  done;
   PUSB_DEVICE_DESCRIPTOR   usbDeviceInst;
   PUSB_DEVICE_DESCRIPTOR *UsbDevices = &usbDeviceInst;

   *UsbDevices = NULL;
   NumberDevices = 0;

   //
   // Open a handle to the plug and play dev node.
   // SetupDiGetClassDevs() returns a device information set that contains info on all
   // installed devices of a specified class.
   //
   hardwareDeviceInfo = SetupDiGetClassDevs (
                           pGuid,
                           NULL, // Define no enumerator (global)
                           NULL, // Define no
                           (DIGCF_PRESENT | // Only Devices present
                            DIGCF_INTERFACEDEVICE)); // Function class devices.

   //
   // Take a wild guess at the number of devices we have;
   // Be prepared to realloc and retry if there are more than we guessed
   //
   NumberDevices = 4;
   done = FALSE;
   deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

   i=0;
   while (!done)
   {
      NumberDevices *= 2;

      if (*UsbDevices)
 {
         *UsbDevices =
               (PUSB_DEVICE_DESCRIPTOR)realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR)));
      }
 else
 {
         *UsbDevices = (PUSB_DEVICE_DESCRIPTOR)calloc (NumberDevices, sizeof (USB_DEVICE_DESCRIPTOR));
      }

      if (NULL == *UsbDevices)
 {

         // SetupDiDestroyDeviceInfoList destroys a device information set
         // and frees all associated memory.

         SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
         return INVALID_HANDLE_VALUE;
      }

      usbDeviceInst = *UsbDevices + i;

      for (; i < NumberDevices; i++)
 {

         // SetupDiEnumDeviceInterfaces() returns information about device interfaces
         // exposed by one or more devices. Each call returns information about one interface;
         // the routine can be called repeatedly to get information about several interfaces
         // exposed by one or more devices.

         if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
                                         0, // We don\'t care about specific PDOs
pGuid,
                                         i,
                                         &deviceInfoData))
{

            hOut = OpenOneDevice (hardwareDeviceInfo, &deviceInfoData, outNameBuf);
if ( hOut != INVALID_HANDLE_VALUE )
{
               done = TRUE;
               break;
}
         }
else
{
            if (ERROR_NO_MORE_ITEMS == GetLastError())
{
               done = TRUE;
               break;
            }
         }
      }
   }

   NumberDevices = i;

   // SetupDiDestroyDeviceInfoList() destroys a device information set
   // and frees all associated memory.

   SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);

   if (*UsbDevices)
  free(*UsbDevices);

   return hOut;
}

HANDLE
OpenOneDevice (
    IN       HDEVINFO                    HardwareDeviceInfo,
    IN       PSP_INTERFACE_DEVICE_DATA   DeviceInfoData,
IN char *devName
    )
{
    PSP_INTERFACE_DEVICE_DETAIL_DATA     functionClassDeviceData = NULL;
    ULONG                                predictedLength = 0;
    ULONG                                requiredLength = 0;
HANDLE hOut = INVALID_HANDLE_VALUE;

    //
    // allocate a function class device data structure to receive the
    // goods about this particular device.
    //
    SetupDiGetInterfaceDeviceDetail (
            HardwareDeviceInfo,
            DeviceInfoData,
            NULL, // probing so no output buffer yet
            0, // probing so output buffer length of zero
            &requiredLength,
            NULL); // not interested in the specific dev-node


    predictedLength = requiredLength;
    // sizeof (SP_FNCLASS_DEVICE_DATA) + 512;

    functionClassDeviceData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc (predictedLength);
    functionClassDeviceData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA);

    //
    // Retrieve the information from Plug and Play.
    //
    if (! SetupDiGetInterfaceDeviceDetail (
               HardwareDeviceInfo,
               DeviceInfoData,
               functionClassDeviceData,
               predictedLength,
               &requiredLength,
               NULL)) {
        return INVALID_HANDLE_VALUE;
    }

strcpy( devName,functionClassDeviceData->DevicePath) ;

    hOut = CreateFile (
                  functionClassDeviceData->DevicePath,
                  GENERIC_READ | GENERIC_WRITE,
                  FILE_SHARE_READ | FILE_SHARE_WRITE,
                  NULL, // no SECURITY_ATTRIBUTES structure
                  OPEN_EXISTING, // No special create flags
                  0, // No special attributes
                  NULL); // No template file

    if (INVALID_HANDLE_VALUE == hOut) {
    }

free(functionClassDeviceData);

return hOut;
}



附件名称/大小 下载次数 最后更新
2003-06-20_D12tst.rar (80KB)  11

最新喜欢:

lhaihlhaih
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-06-20 16:00
没人理我 :(
drivermaster
驱动中牛
驱动中牛
  • 注册日期2003-02-26
  • 最后登录2004-06-24
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-06-20 18:19
太深奥了!
菩提本无树,明镜亦非台, 本来无一物,何处染尘埃? 身似菩提树,心如明镜台, 愿将勤拂拭,勿使染尘埃。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-06-21 15:39
应该有很多人用过这个app才对呀
里面打开设备句柄的历程和ddk里的例子bulkusb是一样的!偶就是不明白为什么要打开两个设备句柄,这两个设备句柄有什么区别,能同时使用吗?
BigHeadMonk
驱动牛犊
驱动牛犊
  • 注册日期2001-03-23
  • 最后登录2003-08-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-06-22 15:38
    既然没人回答,我来做做好心人!
    两个设备句柄 hDev 与 hFile 作用是不一样的,hDev 事实上
是打开的控制端点( Endpoint0) 的句柄, hFile 是 Bulk 端点
的句柄!你应该读过 D12 的相关文档,事实上 hFile 对应的实际
上就是 D12 中的两个 Main Endpoint( Bulk 类型 ), hDev 对应两个 Control Point, 还有两个 Generic Endpoint 这里未用。
    之所以这么做,是因为 D12 支持 DMA 传输方式,而 DMA 传输方式的启用是通过先从控制端点发 IOCTL_WRITE_REGISTERS 的一个
DeviceIoCtrl() 调用,然后再向 Bulk Endpoint 发送要传输的数据
来实现的。这在 Philips 关于 D12 的相应评估包的文档中有说明。
    两个句柄在 Setup DMA request 时是同时配合使用的。

热心的大头和尚 上

[编辑 -  6/22/03 by  BigHeadMonk]
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-22 17:11
多谢大头和尚了,关于d12的文档我没有看过。不过据我的理解,设备句柄是不分控制端点和bulk端点的,只要你打开了设备句柄,就可以对这个设备进行任何操作,而且我看了打开设备句柄的历程了,这两个句柄打开的方式是完全一样的,而且用他们操作驱动效果也是一样的。

正因为这样我才疑惑为什么会有两个句柄的出现,而且有一个是没有使用的(hfile),它好像只是显示设备是否能打开而已,真不明白philips那些程序员是怎么想的,不明白 :(
xjLegend
驱动小牛
驱动小牛
  • 注册日期2002-11-04
  • 最后登录2005-06-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-06-23 10:15
大头和尚说得没错。
hFile对应于bulk/iso端点,hDev对应于控制端点, hFile的打开参数是管道名 。
一般地,发送厂商请求通过hDev,而ReadFile/WriteFile则是调用hFile. 二者根据情况使用,并不是没有用。这在D12TEST程序中都是用了的。如果hDev出错,那么hFile一般也不会正确。我是这样理解的:)
我想要点分,这样才有成就感嘛!
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-06-23 12:23
看来我是多虑了,我已经把驱动里read_write函数修改成了deviceiocontrol的函数,所以我想应用程序里用两个句柄就没什么意义了,因此就只用了一个,而且我把打开句柄的函数也都进行了修改,不过好像也没什么问题。

多谢各位大虾!
Always!978
驱动小牛
驱动小牛
  • 注册日期2002-05-09
  • 最后登录2005-04-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-06-24 11:16
  jinghuiren真够细心的,我也看过这个文件但是没有发现有两次打开句柄,有够粗心。
Tomorrow Never Die
eyeszhu
驱动牛犊
驱动牛犊
  • 注册日期2003-05-14
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-06-24 15:08
的确长见识!
但是好像有个地方写错了open_dev()中
HANDLE hDEV = OpenUsbDevice(
    (LPGUID)&GUID_DEVCLASS_USB,
    completeDeviceName);

也就是说open_dev()和open_file()
guid不同,一个是classguid,一个是interfaceclassguid
是吗?
但如果这样,open_dev()应该打不开呀,因为
  hardwareDeviceInfo = SetupDiGetClassDevs (
                           pGuid,
                           NULL, // Define no enumerator
                           NULL, // Define no
                     DIGCF_PRESENT | // Only Devices present
         DIGCF_INTERFACEDEVICE)); // Function class devices
最后一个参数定义了接口guid,
请教!
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2003-06-24 15:34
没有呀
我在我的源代码里搜遍了也没找到你说的GUID_DEVCLASS_USB!
两个函数用的是同一个guid:GUID_CLASS_D12_BULK
这个guid是在guid.h里定义的,估计你的问题就出在这里吧
eyeszhu
驱动牛犊
驱动牛犊
  • 注册日期2003-05-14
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2003-06-24 16:00
我的问题是出在这里。
但是我仍不知道用什么interface guid读写闪盘。
你的guid是d12提供的吗?

我下载的xugy提供的源代码,里面就是用了两个guid,如上所述。
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2003-06-24 16:08
我不是在有个贴子里回答你了吗?
你可以直接用vc自带的一个guidgen.exe产生一个就可以用,附件是这个文件。
附件名称/大小 下载次数 最后更新
2003-06-24_GUIDGEN.EXE (25KB)  2
eyeszhu
驱动牛犊
驱动牛犊
  • 注册日期2003-05-14
  • 最后登录2003-08-22
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2003-06-24 16:31
谢谢你。

但是guid除了define_guid宏定义,#include \"initguid.h\"
外,好像好需要在驱动设计中定义IoRegisterDeviceInterface
,使能 IoSetDeviceInterfaceState。

我要访问的闪盘我不知道他内部定义的接口guid,这样的情况可以自己生成吗?

下面是guid的两类区分

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/install/hh/install/setup-cls_8vs7.asp
jinghuiren
驱动巨牛
驱动巨牛
  • 注册日期2002-06-01
  • 最后登录2008-10-27
  • 粉丝0
  • 关注0
  • 积分291分
  • 威望460点
  • 贡献值0点
  • 好评度428点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2003-06-24 16:47
这个我就不大明白了,也许你在注册表里能找到你想要的东西,或者有其它的一些函数可以得到u盘的guid,这些我就不大懂了。
祝你好运!
游客

返回顶部