[转]获取U盘PID、VID、序列号
原文地址:http://blog.csdn.net/nicoc/article/details/1487042
因为工作需要,要写一个读取U盘PID,VID信息的程序,在网上找了很久都没有发现有相关的资料.相关的工作也搁置了很久,真是亏对公司^_^
还好终于让我慢慢揣摩出来一点端倪,在这分享一下.其实用DDK会比较容易得到.但是DDK编译设置又比较麻烦,而且我是要用BCB开发,所以也先不往那方面发展了.现在就开始讲讲.
1.获取U盘盘符.
这个比较简单,首先列举一下系统的磁盘.如果属性是DRIVE_REMOVABLE那么就是可移动磁盘.排除软盘,那么剩下的就是U盘咯.
int __fastcall C_BA580_PATH::GetUsbDevice(AnsiString* strUsbDriverName) { char lpBuffer[MAX_DRIVER_STRING_LENGHT]; char*lpSingleDevice; DWORD nBufferLength = MAX_DRIVER_STRING_LENGHT; DWORD dwSignleDeviceBufferIndex =0, dwDeviceNum =0; lpSingleDevice = (char*)malloc(sizeof(char)* MAX_DRIVER_STRING_LENGHT); if(lpSingleDevice == NULL) { ShowMessage("系统分配内存错误"); return 0; } memset(lpSingleDevice,0x0,MAX_DRIVER_STRING_LENGHT); memset(lpBuffer,0x0,MAX_DRIVER_STRING_LENGHT); nBufferLength = GetLogicalDriveStrings(nBufferLength,lpBuffer); //列举盘符 for(DWORD i =0; i< nBufferLength; i++) { if(lpBuffer[i] != 0x00) //分离各个离盘符 { lpSingleDevice[dwSignleDeviceBufferIndex] = lpBuffer[i]; dwSignleDeviceBufferIndex++; continue; } lpSingleDevice[dwSignleDeviceBufferIndex] = 0x0; dwSignleDeviceBufferIndex = 0; if(*lpSingleDevice == 'A') //A盘 不需要 continue; if(GetDriveType(lpSingleDevice) == DRIVE_REMOVABLE) //获取移动磁盘 { strUsbDriverName[dwDeviceNum] = lpSingleDevice ; dwDeviceNum++; } } free(lpSingleDevice); return dwDeviceNum; } 2.获取PID,UID,序列号信息 int CUSBPortDlg::GetDevicePath(LPGUID lpGuid, LPTSTR* pszDevicePath) { HDEVINFO hDevInfoSet; //设备信息集句柄; SP_DEVICE_INTERFACE_DATA ifdata; PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail; int nCount; BOOL bResult; LPGUID UsbClassGuid; CHANGER_PRODUCT_DATA ProductBuffer; unsigned long BytesReturned; UsbClassGuid = (LPGUID)malloc(sizeof(GUID)); UsbClassGuid->Data1 = 0xa5dcbf10L; UsbClassGuid->Data2 = 0x6530; UsbClassGuid->Data3 = 0x11d2; UsbClassGuid->Data4[0] = 0x90; UsbClassGuid->Data4[1] = 0x1F; UsbClassGuid->Data4[2] = 0x00; UsbClassGuid->Data4[3] = 0xC0; UsbClassGuid->Data4[4] = 0x4F; UsbClassGuid->Data4[5] = 0xB9; UsbClassGuid->Data4[6] = 0x51; UsbClassGuid->Data4[7] = 0xED; // 取得一个该GUID相关的设备信息集句柄 hDevInfoSet = SetupDiGetClassDevs(UsbClassGuid, // class GUID NULL, // 无关键字 NULL, // 不指定父窗口句柄 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, // 不需额外的设备描述 UsbClassGuid, // GUID (ULONG)nCount, // 设备信息集里的设备序号 &ifdata); // 设备接口信息 if (bResult) { // 取得该设备接口的细节(设备路径) bResult = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, // 设备信息集句柄 &ifdata, // 设备接口信息 pDetail, // 设备接口细节(设备路径) INTERFACE_DETAIL_SIZE, // 输出缓冲区大小 NULL, // 不需计算输出缓冲区大小(直接用设定值) NULL); // 不需额外的设备描述 if (bResult) { // 复制设备路径到输出缓冲区 ::strcpy(pszDevicePath[nCount], pDetail->DevicePath); // 调整计数值 nCount++; } } } // 释放设备接口数据空间 ::GlobalFree(pDetail); // 关闭设备信息集句柄 ::SetupDiDestroyDeviceInfoList(hDevInfoSet); return nCount; } pDetail->DevicePath 将是一串像"//?/usb#vid_0537&pid_a703#192b0c00048a#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"的字符串,看到没有VID=0537,PID=A703,serial=192b0c00048a
所以分离这串字符串就可以得到你想要的信息了.至于要与盘符相对应上的PID VID我还没有找到在SDK实现的方法
不过慢慢会找到的.
參考: