如何在Win98下实现对USB设备的枚举? 高分求解,要求得到设备的PID和VID等信息 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 DDK中有一个USBView的例子,可以得到USB设备信息 那个例子我看过了,但想要获得U盘的路径,像这样的:\\?\usbstor#disk&ven_mykey&prod_110&rev_1.89#83f150411c34df2f&0#{53fa4307-b2bf-11d0-94d2-00a0cc1efb不知下一步该如何做,请指教 #include "winioctl.h"#include "INITGUID.h"//DEFINE_GUID(guidHID_1, //0x27d732d0, 0x979d, 0x4330, 0xb9, 0xd8, 0x7a, 0x2f, 0x23, 0x6b, 0x71, 0x8c);static const GUID guidHID_1 = {0x18457c9f, 0xa3d8, 0x4fa3,{ 0x8f, 0x10, 0x11, 0x45, 0xcd, 0x1a, 0xa3, 0x67}};// GUID你自己找一下你所要找的设备的GUID#include <setupapi.h>extern "C" int PASCAL SearchUSBDevice(){ HANDLE hUsb; int nCount;//标记同一设备个数 HDEVINFO hDevInfoSet; BOOL bResult; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL; // 取得一个该GUID相关的设备信息集句柄 hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUID NULL, // 无关键字 NULL, // 不指定父窗口句柄 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备 // 失败... if (hDevInfoSet == INVALID_HANDLE_VALUE) { return NULL; } // 申请设备接口数据空间 nCount = 0; bResult = TRUE; SP_DEVICE_INTERFACE_DATA ifdata; // 设备序号=0,1,2... 逐一测试设备接口,到失败为止 while (bResult) { ifdata.cbSize = sizeof(ifdata); // 枚举符合该GUID的设备接口 bResult = ::SetupDiEnumDeviceInterfaces( hDevInfoSet, // 设备信息集句柄 NULL, // 不需额外的设备描述 (LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID (ULONG)nCount, // 设备信息集里的设备序号 &ifdata); // 设备接口信息 if (bResult) { ULONG predictedLength = 0; ULONG requiredLength = 0; // 取得该设备接口的细节(设备路径) bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, // 设备信息集句柄 &ifdata, // 设备接口信息 NULL, // 设备接口细节(设备路径) 0, // 输出缓冲区大小 &requiredLength, // 不需计算输出缓冲区大小(直接用设定值) NULL); // 不需额外的设备描述 // 取得该设备接口的细节(设备路径) predictedLength=requiredLength; // if(pDetail) // { // pDetail =NULL; // } pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength); pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, // 设备信息集句柄 &ifdata, // 设备接口信息 pDetail, // 设备接口细节(设备路径) predictedLength, // 输出缓冲区大小 &requiredLength, // 不需计算输出缓冲区大小(直接用设定值) NULL); // 不需额外的设备描述 if (bResult) { // 复制设备路径到输出缓冲区 //::strcpy(pszDevicePath[nCount], pDetail->DevicePath); char ch[18]; for(int i=0;i<17;i++){ ch[i]=*(pDetail->DevicePath+8+i); } ch[17]='\0'; if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错 { memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ; memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL ) ; // no name if (READ_OS.hEvent == NULL) { break; } WRITE_OS.hEvent = CreateEvent( NULL, // no security TRUE, // explicit reset req FALSE, // initial event reset NULL ) ; // no name if (NULL == WRITE_OS.hEvent) { CloseHandle( READ_OS.hEvent ); break; } hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,// GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_OVERLAPPED, NULL); if (hUsb != NULL) { memset(m_DeviceDesc[nCount], 0, 256); sprintf(m_DeviceDesc[nCount], "%s", pDetail->DevicePath); CloseHandle(hUsb); break; } } } } nCount++; } // 释放设备接口数据空间 ::GlobalFree(pDetail); // 关闭设备信息集句柄 ::SetupDiDestroyDeviceInfoList(hDevInfoSet); return nCount+1;} 我用如下的代码枚举,但SetupDiEnumDeviceInterfaces函数在2000下可以成功查询,但在Win98下就总是失败。代码如下: HDEVINFO hDevInfoSet; SP_DEVICE_INTERFACE_DATA ifdata; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail; int nCount; BOOL bResult; // 取得一个该GUID相关的设备信息集句柄 hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID 0, // 无关键字 0, // 不指定父窗口句柄 //DIGCF_DEVICEINTERFACE); DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备 // 失败... if(hDevInfoSet == INVALID_HANDLE_VALUE) { return 0; } // 申请设备接口数据空间 pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE); pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); nCount = 0; bResult = TRUE; // 设备序号=0,1,2... 逐一测试设备接口,到失败为止 while (bResult) { ifdata.cbSize=sizeof(ifdata); // 枚举符合该GUID的设备接口 bResult = ::SetupDiEnumDeviceInterfaces( hDevInfoSet, // 设备信息集句柄 NULL, // 不需额外的设备描述 lpGuid, // GUID (ULONG)nCount, // 设备信息集里的设备序号 &ifdata); // 设备接口信息 if(bResult) { MessageBox(NULL, "SetupDiEnumDeviceInterfaces ok", "test 1", MB_OK); // 取得该设备接口的细节(设备路径) bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, // 设备信息集句柄 &ifdata, // 设备接口信息 pDetail, // 设备接口细节(设备路径) INTERFACE_DETAIL_SIZE, // 输出缓冲区大小 NULL, // 不需计算输出缓冲区大小(直接用设定值) NULL); // 不需额外的设备描述 if(bResult) { // 复制设备路径到输出缓冲区 ::strcpy(pszDevicePath[nCount], pDetail->DevicePath); MessageBox(NULL, "Desc ok","test 2", MB_OK); // 调整计数值 nCount++; } else MessageBox(NULL, "Desc failed", "test 2", MB_OK); } else { MessageBox(NULL, "SetupDiEnumDeviceInterfaces failed", "test 1", MB_OK); } } // 释放设备接口数据空间 ::GlobalFree(pDetail); // 关闭设备信息集句柄 ::SetupDiDestroyDeviceInfoList(hDevInfoSet); 你的错误应该是GUID号的问题。USB设备(在Win2K下不需要驱动,98下要安装驱动的那种U盘)在Win2K和Win98下显示的GUID号是不一样的,你可以根据你设备的ID号查找注册表,找到在Win98下的GUID号,然后替换你原来的GUID号,你就可以了。好运!!! 我在98注册表下找到了一个GUID,可以得到设备路径,但是这个路径中不包含VID和PID信息,也没有别的信息 在98下通过这种方法是无法得到VID/PID的 98下读注册表,2000下用DDK,狂faint.... 为什么2000不用注册表呢. guid是一样的,zhangnanonnet(鱼欢)的代码可以枚举usb设备 2000用setup函数族,这个函数族就是访问注册表,只不过可以在非管理员权限下。 guid不一样的,98下如果还用2000下用的guid,根本就不能得到设备路径的。 不对啊,小希,98下和2000下使用同一个GUID应该是都可以找到Device的,只不过查找的结果不一样。 你的错误应该是GUID号的问题。USB设备(在Win2K下不需要驱动,98下要安装驱动的那种U盘)在Win2K和Win98下显示的GUID号是不一样的,你可以根据你设备的ID号查找注册表,找到在Win98下的GUID号,然后替换你原来的GUID号,你就可以了。好运!!!thanks!!!!!! Cdialogbar 不显示 InstallShield静默卸载? MFC创建类时遇到的问题 求助:帮助解决带FixedCol的ListCtrl,重分酬谢! 关于DLL编译调用的问题(再不安装VC的环境下,VB调用VC生成的DLL) 如何或取BMP图像中,某一行的数据么?图像是黑白的,如果某点象素是黑的就为1,白为零。程序如下:(需要补充) 请大家帮帮忙,急!!!在线等待!! dll中的dialog如何才能成为模式窗口? 怎样做一个好的程序员! 在规则DLL中创建窗口问题?????? 哪个详细解释一下这两句的意思和区别: 有关LVCOLUMN的fmt
\\?\usbstor#disk&ven_mykey&prod_110&rev_1.89#83f150411c34df2f&0#{53fa4307-b2bf-11d0-94d2-00a0cc1efb不知下一步该如何做,请指教
#include "INITGUID.h"
//DEFINE_GUID(guidHID_1,
//0x27d732d0, 0x979d, 0x4330, 0xb9, 0xd8, 0x7a, 0x2f, 0x23, 0x6b, 0x71, 0x8c);
static const GUID guidHID_1 =
{0x18457c9f, 0xa3d8, 0x4fa3,{ 0x8f, 0x10, 0x11, 0x45, 0xcd, 0x1a, 0xa3, 0x67}};
// GUID你自己找一下你所要找的设备的GUID#include <setupapi.h>extern "C" int PASCAL SearchUSBDevice()
{
HANDLE hUsb; int nCount;//标记同一设备个数
HDEVINFO hDevInfoSet;
BOOL bResult; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail =NULL;
// 取得一个该GUID相关的设备信息集句柄
hDevInfoSet = ::SetupDiGetClassDevs((LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // class GUID
NULL, // 无关键字
NULL, // 不指定父窗口句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
// 失败...
if (hDevInfoSet == INVALID_HANDLE_VALUE)
{
return NULL;
}
// 申请设备接口数据空间
nCount = 0;
bResult = TRUE;
SP_DEVICE_INTERFACE_DATA ifdata;
// 设备序号=0,1,2... 逐一测试设备接口,到失败为止
while (bResult)
{
ifdata.cbSize = sizeof(ifdata);
// 枚举符合该GUID的设备接口
bResult = ::SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 设备信息集句柄
NULL, // 不需额外的设备描述
(LPGUID)&guidHID_1,//GUID_CLASS_USB_DEVICE, // GUID
(ULONG)nCount, // 设备信息集里的设备序号
&ifdata); // 设备接口信息
if (bResult)
{
ULONG predictedLength = 0;
ULONG requiredLength = 0;
// 取得该设备接口的细节(设备路径)
bResult = SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 设备信息集句柄
&ifdata, // 设备接口信息
NULL, // 设备接口细节(设备路径)
0, // 输出缓冲区大小
&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
NULL); // 不需额外的设备描述
// 取得该设备接口的细节(设备路径)
predictedLength=requiredLength; // if(pDetail)
// {
// pDetail =NULL;
// }
pDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, predictedLength);
pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
bResult = SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 设备信息集句柄
&ifdata, // 设备接口信息
pDetail, // 设备接口细节(设备路径)
predictedLength, // 输出缓冲区大小
&requiredLength, // 不需计算输出缓冲区大小(直接用设定值)
NULL); // 不需额外的设备描述
if (bResult)
{
// 复制设备路径到输出缓冲区
//::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
char ch[18];
for(int i=0;i<17;i++){
ch[i]=*(pDetail->DevicePath+8+i);
}
ch[17]='\0';
if (strcmp(ch,"vid_0471&pid_0666")==0)//比较版本号,防止意外出错
{
memset( &READ_OS, 0, sizeof( OVERLAPPED ) ) ;
memset( &WRITE_OS, 0, sizeof( OVERLAPPED ) ) ; READ_OS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (READ_OS.hEvent == NULL)
{
break;
}
WRITE_OS.hEvent = CreateEvent( NULL, // no security
TRUE, // explicit reset req
FALSE, // initial event reset
NULL ) ; // no name
if (NULL == WRITE_OS.hEvent)
{
CloseHandle( READ_OS.hEvent );
break;
}
hUsb=CreateFile(pDetail->DevicePath,//&guidHID_1,//
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|
FILE_FLAG_OVERLAPPED,
NULL);
if (hUsb != NULL)
{
memset(m_DeviceDesc[nCount], 0, 256);
sprintf(m_DeviceDesc[nCount], "%s", pDetail->DevicePath);
CloseHandle(hUsb);
break;
}
}
}
}
nCount++;
}
// 释放设备接口数据空间
::GlobalFree(pDetail);
// 关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet); return nCount+1;
}
HDEVINFO hDevInfoSet;
SP_DEVICE_INTERFACE_DATA ifdata;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
int nCount;
BOOL bResult; // 取得一个该GUID相关的设备信息集句柄
hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID
0, // 无关键字
0, // 不指定父窗口句柄
//DIGCF_DEVICEINTERFACE);
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备 // 失败...
if(hDevInfoSet == INVALID_HANDLE_VALUE)
{
return 0;
} // 申请设备接口数据空间
pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); nCount = 0;
bResult = TRUE;
// 设备序号=0,1,2... 逐一测试设备接口,到失败为止
while (bResult)
{
ifdata.cbSize=sizeof(ifdata);
// 枚举符合该GUID的设备接口
bResult = ::SetupDiEnumDeviceInterfaces(
hDevInfoSet, // 设备信息集句柄
NULL, // 不需额外的设备描述
lpGuid, // GUID
(ULONG)nCount, // 设备信息集里的设备序号
&ifdata); // 设备接口信息
if(bResult)
{
MessageBox(NULL, "SetupDiEnumDeviceInterfaces ok", "test 1", MB_OK); // 取得该设备接口的细节(设备路径)
bResult = SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 设备信息集句柄
&ifdata, // 设备接口信息
pDetail, // 设备接口细节(设备路径)
INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
NULL, // 不需计算输出缓冲区大小(直接用设定值)
NULL); // 不需额外的设备描述 if(bResult)
{
// 复制设备路径到输出缓冲区
::strcpy(pszDevicePath[nCount], pDetail->DevicePath);
MessageBox(NULL, "Desc ok","test 2", MB_OK); // 调整计数值
nCount++;
}
else
MessageBox(NULL, "Desc failed", "test 2", MB_OK);
}
else
{
MessageBox(NULL, "SetupDiEnumDeviceInterfaces failed", "test 1", MB_OK);
}
} // 释放设备接口数据空间
::GlobalFree(pDetail); // 关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);
USB设备(在Win2K下不需要驱动,98下要安装驱动的那种U盘)在Win2K和Win98下显示的GUID号是不一样的,你可以根据你设备的ID号查找注册表,找到在Win98下的GUID号,然后替换你原来的GUID号,你就可以了。好运!!!
USB设备(在Win2K下不需要驱动,98下要安装驱动的那种U盘)在Win2K和Win98下显示的GUID号是不一样的,你可以根据你设备的ID号查找注册表,找到在Win98下的GUID号,然后替换你原来的GUID号,你就可以了。好运!!!
thanks!!!!!!