HANDLE OpenUsbDevice( _In_ LPGUID pGuid, _In_ PSTR outNameBuf ) /*++ Routine Description: Do the required PnP things in order to find the next available proper device in the system at this time. Arguments: pGuid: ptr to GUID registered by the driver itself outNameBuf: the generated name for this device Return Value: return HANDLE if the open and initialization was successful, else INVLAID_HANDLE_VALUE. --*/ { ULONG NumberDevices; HANDLE hOut = INVALID_HANDLE_VALUE; HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInfoData; ULONG i; BOOLEAN done; PUSB_DEVICE_DESCRIPTOR usbDeviceInst; PUSB_DEVICE_DESCRIPTOR *UsbDevices = &usbDeviceInst; PUSB_DEVICE_DESCRIPTOR tempDevDesc; *UsbDevices = NULL; tempDevDesc = 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_DEVICEINTERFACE)); // Function class devices. if (hardwareDeviceInfo == INVALID_HANDLE_VALUE) { return INVALID_HANDLE_VALUE ; } // // 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_DEVICE_INTERFACE_DATA); i=0; while (!done) { NumberDevices *= 2; if (*UsbDevices) { tempDevDesc = (PUSB_DEVICE_DESCRIPTOR) realloc (*UsbDevices, (NumberDevices * sizeof (USB_DEVICE_DESCRIPTOR))); if(tempDevDesc) { *UsbDevices = tempDevDesc; tempDevDesc = NULL; } else { free(*UsbDevices); *UsbDevices = NULL; } } 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; } 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; } } } } // SetupDiDestroyDeviceInfoList() destroys a device information set // and frees all associated memory. SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free ( *UsbDevices ); return hOut; }
void CEnumSerial::EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi) { CString strErr; // Create a device information set that will be the container for // the device interfaces. GUID *guidDev; guidDev = (GUID*) &GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR; HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData; hDevInfo = INVALID_HANDLE_VALUE; pDetData = NULL; try { hDevInfo = SetupDiGetClassDevs( NULL, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES); if (hDevInfo == INVALID_HANDLE_VALUE) { strErr.Format(_T("SetupDiGetClassDevs failed. (err=%lx)"), GetLastError()); throw strErr; } // Enumerate the serial ports BOOL bOk; SP_DEVICE_INTERFACE_DATA ifcData; DWORD dwDetDataSize; bOk = TRUE; dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize]; // This is required, according to the documentation. Yes, it's weird. DWORD ii; ii = 0; do { SP_DEVINFO_DATA devdata; memset(&devdata, 0, sizeof(SP_DEVINFO_DATA)); devdata.cbSize = sizeof(SP_DEVINFO_DATA); memset(&ifcData, 0, sizeof(SP_DEVICE_INTERFACE_DATA)); ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bOk = SetupDiEnumDeviceInfo(hDevInfo, ii, &devdata); if (bOk) { if ( memcmp(&devdata.ClassGuid, guidDev, sizeof(GUID)) == 0) { bOk = SetupDiEnumDeviceInterfaces(hDevInfo, &devdata, guidDev, 0, &ifcData); CString strDevPath; if (bOk) { // Got a device. Get the details. memset(pDetData, 0, dwDetDataSize); pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, NULL); strDevPath = pDetData->DevicePath; } else { TRACE(_T("SetupDiEnumDeviceInterfaces. (err=%lx)\n"), GetLastError()); } // Got a path to the device. Try to get some more info. TCHAR fname[1024]; TCHAR desc[1024]; BOOL bSuccess; bSuccess = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname)/sizeof(TCHAR), NULL); if (bSuccess) bSuccess = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL, (PBYTE)desc, sizeof(desc)/sizeof(TCHAR), NULL); BOOL bUsbDevice; CString locInfo; BOOL bRet; bUsbDevice = FALSE; bRet = SetupDiGetDeviceRegistryProperty(hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE) locInfo.GetBuffer(1024), 1024, NULL); locInfo.ReleaseBuffer(); if (bRet) { // Just check the first three characters to determine // if the port is connected to the USB bus. This isn't // an infallible method; it would be better to use the // BUS GUID. Currently, Windows doesn't let you query // that though (SPDRP_BUSTYPEGUID seems to exist in // documentation only). if (locInfo.Right(sizeof(_T("USB"))) == _T("USB")) bUsbDevice = TRUE; else bUsbDevice = FALSE; } if (bSuccess) { // Add an entry to the array SSerInfo si; si.strDevPath = strDevPath; si.strFriendlyName = fname; si.strPortDesc = desc; si.bUsbDevice = bUsbDevice; asi.Add(si); } } } else { DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS) { strErr.Format(_T("SetupDiEnumDeviceInterfaces failed. (err=%lx)"), err); throw strErr; } } ii++; } while (bOk); } catch (CString strCatchErr) { strErr = strCatchErr; } if (pDetData != NULL) delete [] (char*)pDetData; if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); if (!strErr.IsEmpty()) throw strErr; }
HANDLE CUSBDevice::ConnectToIthDevice (DWORD deviceIndex) { GUID hidGUID; HDEVINFO hardwareDeviceInfoSet; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_INTERFACE_DEVICE_DETAIL_DATA deviceDetail; ULONG requiredSize; HANDLE deviceHandle = INVALID_HANDLE_VALUE; DWORD result; //Get the HID GUID value - used as mask to get list of devices HidD_GetHidGuid (&hidGUID); //Get a list of devices matching the criteria (hid interface, present) hardwareDeviceInfoSet = SetupDiGetClassDevs (&hidGUID, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE)); // Function class devices. deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); //Go through the list and get the interface data result = SetupDiEnumDeviceInterfaces (hardwareDeviceInfoSet, NULL, //infoData, &hidGUID, //interfaceClassGuid, deviceIndex, &deviceInterfaceData); /* Failed to get a device - possibly the index is larger than the number of devices */ if (result == FALSE) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); return INVALID_HANDLE_VALUE; } //Get the details with null values to get the required size of the buffer SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet, &deviceInterfaceData, NULL, //interfaceDetail, 0, //interfaceDetailSize, &requiredSize, 0); //infoData)) //Allocate the buffer deviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(requiredSize); deviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); //Fill the buffer with the device details if (!SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfoSet, &deviceInterfaceData, deviceDetail, requiredSize, &requiredSize, NULL)) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); free (deviceDetail); return INVALID_HANDLE_VALUE; } //Open file on the device deviceHandle = CreateFile (deviceDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, // no SECURITY_ATTRIBUTES structure OPEN_EXISTING, // No special create flags FILE_FLAG_OVERLAPPED, NULL); // No template file SetupDiDestroyDeviceInfoList (hardwareDeviceInfoSet); free (deviceDetail); return deviceHandle; }
BOOL OpenPortalHandleFromGUID(GUID guid, PHANDLE phPortalHandle) { int memberIndex = 0; BOOL bResult = TRUE; HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL; HIDD_ATTRIBUTES attributes; ULONG requiredLength=0; hDevInfo = SetupDiGetClassDevs(&guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); *phPortalHandle = NULL; for(memberIndex = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &guid, memberIndex, &deviceInterfaceData); memberIndex++) { SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL); //we got the size, allocate buffer pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength); assert(pInterfaceDetailData); //get the interface detailed data pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &deviceInterfaceData, pInterfaceDetailData, requiredLength, &requiredLength, NULL)) { continue; } *phPortalHandle = CreateFile ( pInterfaceDetailData->DevicePath, GENERIC_EXECUTE | GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); LocalFree(pInterfaceDetailData); pInterfaceDetailData = NULL; if(guid == xbox_guid) { break; // we are done. xbox_guid does not have HID attributes } if (*phPortalHandle != INVALID_HANDLE_VALUE) { if (HidD_GetAttributes(*phPortalHandle , &attributes)) { if (((attributes.VendorID == 0x12ba) || (attributes.VendorID == 0x54c)) || (attributes.VendorID == 0x1430)) { if ((attributes.ProductID == 0x150) || (attributes.ProductID == 0x967)) { break; // found the portal. leave the handle open } } } CloseHandle(*phPortalHandle); *phPortalHandle = NULL; } } SetupDiDestroyDeviceInfoList(hDevInfo); return (*phPortalHandle != NULL); }
HRESULT CNdasServiceDeviceEventHandler::pRegisterLogicalUnit( __in HDEVINFO DevInfoSet, __in LPCGUID InterfaceGuid) { HRESULT hr; BOOL success; DWORD index = 0; SP_DEVICE_INTERFACE_DATA devIntfData; DWORD devIntfDetailSize = offsetof(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath) + sizeof(TCHAR) * MAX_PATH; PSP_DEVICE_INTERFACE_DETAIL_DATA devIntfDetail = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(devIntfDetailSize)); if (NULL == devIntfDetail) { hr = E_OUTOFMEMORY; XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "Memory allocation failed, size=0x%X\n", devIntfDetailSize); return hr; } for (DWORD index = 0; ; ++index) { devIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); success = SetupDiEnumDeviceInterfaces( DevInfoSet, NULL, InterfaceGuid, index, &devIntfData); if (!success) { if (ERROR_NO_MORE_ITEMS == GetLastError()) { if (0 == index) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_WARNING, "No devices\n"); } hr = S_OK; } else { hr = HRESULT_FROM_SETUPAPI(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiEnumDeviceInterfaces failed, hr=0x%X\n", hr); } break; } devIntfDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); success = SetupDiGetDeviceInterfaceDetail( DevInfoSet, &devIntfData, devIntfDetail, devIntfDetailSize, &devIntfDetailSize, NULL); if (!success) { if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiGetDeviceInterfaceDetail failed, hr=0x%X\n", hr); continue; } PVOID p = realloc(devIntfDetail, devIntfDetailSize); if (NULL == p) { hr = E_OUTOFMEMORY; XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "Memory allocation failed, size=0x%X\n", devIntfDetailSize); continue; } devIntfDetail = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(p); success = SetupDiGetDeviceInterfaceDetail( DevInfoSet, &devIntfData, devIntfDetail, devIntfDetailSize, &devIntfDetailSize, NULL); } if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiGetDeviceInterfaceDetail2 failed, hr=0x%X\n", hr); continue; } // // Now we have devIntfDetail->DevicePath // HANDLE h = CreateFile( devIntfDetail->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL); if (INVALID_HANDLE_VALUE == h) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "CreateFile(%ls) failed, hr=0x%X\n", devIntfDetail->DevicePath, hr); continue; } NDAS_LOGICALUNIT_ADDRESS luAddress; hr = pNdasPortGetLogicalUnitAddress(h, &luAddress); if (FAILED(hr)) { XTLVERIFY( CloseHandle(h) ); continue; } NDAS_LOCATION ndasLocation = NdasLogicalUnitAddressToLocation(luAddress); RegisterDeviceHandleNotification( h, ndasLocation, devIntfDetail->DevicePath); XTLVERIFY( CloseHandle(h) ); } free(devIntfDetail); return S_OK; }
int emokit_open_win32(emokit_device* dev, int VID, int PID, unsigned int device_index, int get_count) { //Use a series of API calls to find a HID with a specified Vendor IF and Product ID. HIDD_ATTRIBUTES Attributes; SP_DEVICE_INTERFACE_DATA devInfoData; BOOL LastDevice = FALSE; int MemberIndex = 0; LONG Result; int device_count = 0; Length = 0; detailData = NULL; dev->_dev = NULL; /* API function: HidD_GetHidGuid Get the GUID for all system HIDs. Returns: the GUID in HidGuid. */ HidD_GetHidGuid(&HidGuid); /* API function: SetupDiGetClassDevs Returns: a handle to a device information set for all installed devices. Requires: the GUID returned by GetHidGuid. */ hDevInfo=SetupDiGetClassDevs (&HidGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); devInfoData.cbSize = sizeof(devInfoData); //Step through the available devices looking for the one we want. //Quit on detecting the desired device or checking all available devices without success. MemberIndex = 0; LastDevice = FALSE; do { /* API function: SetupDiEnumDeviceInterfaces On return, MyDeviceInterfaceData contains the handle to a SP_DEVICE_INTERFACE_DATA structure for a detected device. Requires: The DeviceInfoSet returned in SetupDiGetClassDevs. The HidGuid returned in GetHidGuid. An index to specify a device. */ Result=SetupDiEnumDeviceInterfaces (hDevInfo, 0, &HidGuid, MemberIndex, &devInfoData); if (Result != 0) { //A device has been detected, so get more information about it. /* API function: SetupDiGetDeviceInterfaceDetail Returns: an SP_DEVICE_INTERFACE_DETAIL_DATA structure containing information about a device. To retrieve the information, call this function twice. The first time returns the size of the structure in Length. The second time returns a pointer to the data in DeviceInfoSet. Requires: A DeviceInfoSet returned by SetupDiGetClassDevs The SP_DEVICE_INTERFACE_DATA structure returned by SetupDiEnumDeviceInterfaces. The final parameter is an optional pointer to an SP_DEV_INFO_DATA structure. This application doesn't retrieve or use the structure. If retrieving the structure, set MyDeviceInfoData.cbSize = length of MyDeviceInfoData. and pass the structure's address. */ //Get the Length value. //The call will return with a "buffer too small" error which can be ignored. Result = SetupDiGetDeviceInterfaceDetail (hDevInfo, &devInfoData, NULL, 0, &Length, NULL); //Allocate memory for the hDevInfo structure, using the returned Length. detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length); //Set cbSize in the detailData structure. detailData -> cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //Call the function again, this time passing it the returned buffer size. Result = SetupDiGetDeviceInterfaceDetail (hDevInfo, &devInfoData, detailData, Length, &Required, NULL); // Open a handle to the device. // To enable retrieving information about a system mouse or keyboard, // don't request Read or Write access for this handle. /* API function: CreateFile Returns: a handle that enables reading and writing to the device. Requires: The DevicePath in the detailData structure returned by SetupDiGetDeviceInterfaceDetail. */ dev->_dev =CreateFile (detailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES)NULL, OPEN_EXISTING, 0, NULL); /* API function: HidD_GetAttributes Requests information from the device. Requires: the handle returned by CreateFile. Returns: a HIDD_ATTRIBUTES structure containing the Vendor ID, Product ID, and Product Version Number. Use this information to decide if the detected device is the one we're looking for. */ //Set the Size to the number of bytes in the structure. Attributes.Size = sizeof(Attributes); Result = HidD_GetAttributes (dev->_dev, &Attributes); //Is it the desired device? MyDeviceDetected = FALSE; if ((Attributes.VendorID == VID && Attributes.ProductID == PID)) { if(get_count || device_count != device_index) { CloseHandle(dev->_dev); } else if (device_count == device_index) { MyDeviceDetected = TRUE; MyDevicePathName = detailData->DevicePath; GetDeviceCapabilities(dev->_dev); break; } ++device_count; } else { CloseHandle(dev->_dev); } free(detailData); } //if (Result != 0) else { LastDevice=TRUE; } //If we haven't found the device yet, and haven't tried every available device, //try the next one. MemberIndex = MemberIndex + 1; } while (!LastDevice); SetupDiDestroyDeviceInfoList(hDevInfo); if(get_count) return device_count; if(MyDeviceDetected) return 0; return -1; }
// Find and connect Wiimotes. // Does not replace already found Wiimotes even if they are disconnected. // wm is an array of max_wiimotes Wiimotes // Returns the total number of found and connected Wiimotes. void WiimoteScanner::FindWiimotes(std::vector<Wiimote*> & found_wiimotes, Wiimote* & found_board) { if (!s_loaded_ok) return; ProcessWiimotes(true, [](HANDLE hRadio, const BLUETOOTH_RADIO_INFO& rinfo, BLUETOOTH_DEVICE_INFO_STRUCT& btdi) { ForgetWiimote(btdi); AttachWiimote(hRadio, rinfo, btdi); }); // Get the device id GUID device_id; pHidD_GetHidGuid(&device_id); // Get all hid devices connected HDEVINFO const device_info = SetupDiGetClassDevs(&device_id, nullptr, nullptr, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); SP_DEVICE_INTERFACE_DATA device_data; device_data.cbSize = sizeof(device_data); PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = nullptr; for (int index = 0; SetupDiEnumDeviceInterfaces(device_info, nullptr, &device_id, index, &device_data); ++index) { // Get the size of the data block required DWORD len; SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &len, nullptr); detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(len); detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Query the data for this device if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, nullptr, nullptr)) { std::basic_string<TCHAR> device_path(detail_data->DevicePath); Wiimote* wm = new WiimoteWindows(device_path); bool real_wiimote = false, is_bb = false; CheckDeviceType(device_path, real_wiimote, is_bb); if (is_bb) { found_board = wm; } else if (real_wiimote) { found_wiimotes.push_back(wm); } else { delete wm; } } free(detail_data); } SetupDiDestroyDeviceInfoList(device_info); // Don't mind me, just a random sleep to fix stuff on Windows //if (!wiimotes.empty()) // SLEEP(2000); }
//------------------------------------------------------------------------------ HANDLE DNAUSB::openDevice( const int vid, const int pid, const char* vendor, char* product ) { HANDLE handle = INVALID_HANDLE_VALUE; // from DDK const GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; for( int tries = 0; (tries < 10) && (handle == INVALID_HANDLE_VALUE) ; tries++ ) { HANDLE deviceSet = SetupDiGetClassDevs( &GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE ); if ( deviceSet == INVALID_HANDLE_VALUE ) { break; } SP_INTERFACE_DEVICE_DATA interfaceInfo; SP_DEVINFO_DATA deviceInfoData; interfaceInfo.cbSize = sizeof( interfaceInfo ); deviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA ); BYTE buf[1024]; DWORD size; int i=0; if( SetupDiEnumDeviceInfo(deviceSet, i++, &deviceInfoData) ) { DWORD interfaceNumber = 0; while ( SetupDiEnumDeviceInterfaces( deviceSet, 0, &GUID_DEVINTERFACE_HID, interfaceNumber++, &interfaceInfo) ) { SP_DEVICE_INTERFACE_DETAIL_DATA *details = (SP_DEVICE_INTERFACE_DETAIL_DATA *)buf; details->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); size = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; if ( !SetupDiGetDeviceInterfaceDetail( deviceSet, &interfaceInfo, details, size, 0, 0 ) ) { Log( "SetupDiGetDeviceInterfaceDetail failed [%d]", GetLastError() ); continue; } Cstr temp; temp.toChar( details->DevicePath ); temp.toLower(); Log( "Considering [%s]", temp.c_str() ); const char* vidStr = strstr( temp.c_str(), "vid" ); if ( !vidStr ) { Log( "vid not found [%s]", temp.c_str() ); continue; } vidStr += 3; for( ; *vidStr && !isxdigit(*vidStr); vidStr++ ); if ( !vidStr ) { Log( "could not find valid vid [%s]", temp.c_str() ); continue; } if ( strtol(vidStr, 0, 16) != vid ) { continue; } const char* pidStr = strstr( temp.c_str(), "pid" ); if ( !pidStr ) { Log( "pid not found [%s]", temp.c_str() ); continue; } pidStr += 3; for( ; *pidStr && !isxdigit(*pidStr); pidStr++ ); if ( !pidStr ) { Log( "could not find valid pid [%s]", temp.c_str() ); continue; } if ( strtol(pidStr, 0, 16) != pid ) { continue; } int openFlag = 0; // may be FILE_FLAG_OVERLAPPED handle = CreateFile( details->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL ); if ( handle == INVALID_HANDLE_VALUE ) { Log( "could not open device" ); continue; } if( !HidD_GetManufacturerString(handle, buf, 1024) ) { CloseHandle( handle ); handle = INVALID_HANDLE_VALUE; Log( "could not fetch manufacturer string" ); continue; } temp.toChar( (wchar_t*)buf ); Log( "manufacturer [%s]", temp.c_str() ); if ( !temp.isMatch(vendor, false) ) { CloseHandle( handle ); handle = INVALID_HANDLE_VALUE; continue; } Sleep(10); if ( product ) { HidD_GetProductString( handle, buf, 1024 ); temp.toChar( (wchar_t*)buf ); strcpy( product, temp.c_str() ); } break; } } SetupDiDestroyDeviceInfoList( deviceSet ); if ( handle == INVALID_HANDLE_VALUE ) { Arch::sleep( 2000 ); } } return handle; }
HANDLE OpenBleService(BLUETOOTH_ADDRESS *btha, GUID *guid) { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0, bytes=0; WCHAR szBda[13] = {0}; HANDLE hService = INVALID_HANDLE_VALUE; DWORD err; if ((hardwareDeviceInfo = SetupDiGetClassDevs ((LPGUID)guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE))) == INVALID_HANDLE_VALUE) { ods("OpenBleServiceSetupDiGetClassDevs failed: %x\n", GetLastError()); return hService; } deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); // Enumerate devices of LE_DEVICE interface class for (int i = 0; ; i++) { if (!SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, guid, i, &deviceInterfaceData)) { if ((err = GetLastError()) == ERROR_NO_MORE_ITEMS) ods("OpenBleService device not found\n"); else ods ("OpenBleService:ERROR SetupDiEnumDeviceInterfaces failed:%d\n", err); break; } SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL); if ((err = GetLastError()) != ERROR_INSUFFICIENT_BUFFER) { ods("OpenBleService:ERROR SetupDiGetDeviceInterfaceDetail failed %d\n", err); break; } predictedLength = requiredLength; deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new CHAR[predictedLength + 2]; if (deviceInterfaceDetailData == NULL) { ods("OpenBleService:ERROR Couldn't allocate %d bytes for device interface details.\n", predictedLength); break; } RtlZeroMemory (deviceInterfaceDetailData, predictedLength + 2); deviceInterfaceDetailData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail (hardwareDeviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, predictedLength, &requiredLength, NULL)) { ods("OpenBleService :ERROR SetupDiGetDeviceInterfaceDetail\n"); delete deviceInterfaceDetailData; break; } _wcsupr_s (deviceInterfaceDetailData->DevicePath, wcslen(deviceInterfaceDetailData->DevicePath) + 1); BdaToString (szBda, btha); if (wcsstr (deviceInterfaceDetailData->DevicePath, szBda) != NULL) { ods("OpenBleService Opening interface:%S\n", deviceInterfaceDetailData->DevicePath); hService = CreateFile ( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hService == INVALID_HANDLE_VALUE) ods("OpenBleService (hService == INVALID_HANDLE_VALUE) GetLastError() = %d\n", GetLastError()); delete deviceInterfaceDetailData; break; } delete deviceInterfaceDetailData; } SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return hService; }
USBDevice *usb_keyboard_init(void) { USBKeyboardState *s; s = (USBKeyboardState *)malloc(sizeof(USBKeyboardState)); if (!s) return NULL; memset(s,0,sizeof(USBKeyboardState)); s->dev.speed = USB_SPEED_FULL; s->dev.handle_packet = usb_generic_handle_packet; s->dev.handle_reset = usb_keyboard_handle_reset; s->dev.handle_control = usb_keyboard_handle_control; s->dev.handle_data = usb_keyboard_handle_data; s->dev.handle_destroy = usb_keyboard_handle_destroy; strncpy(s->dev.devname, "Generic USB Keyboard", sizeof(s->dev.devname)); int i=0; DWORD needed=0; unsigned char buf[8]; HDEVINFO devInfo; GUID guid; SP_DEVICE_INTERFACE_DATA diData; PSP_DEVICE_INTERFACE_DETAIL_DATA didData; HIDD_ATTRIBUTES attr; readData=CreateEvent(0, 0, 0, 0); memset(&ovl, 0, sizeof(OVERLAPPED)); ovl.hEvent=readData; ovl.Offset=0; ovl.OffsetHigh=0; HidD_GetHidGuid(&guid); devInfo=SetupDiGetClassDevs(&guid, 0, 0, DIGCF_DEVICEINTERFACE); if(!devInfo)return 0; diData.cbSize=sizeof(diData); while(SetupDiEnumDeviceInterfaces(devInfo, 0, &guid, i, &diData)){ if(usb_buzzer!=INVALID_HANDLE_VALUE)CloseHandle(usb_buzzer); SetupDiGetDeviceInterfaceDetail(devInfo, &diData, 0, 0, &needed, 0); didData=(PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(needed); didData->cbSize=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(!SetupDiGetDeviceInterfaceDetail(devInfo, &diData, didData, needed, 0, 0)){ free(didData); break; } usb_buzzer=CreateFile(didData->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); if(usb_buzzer==INVALID_HANDLE_VALUE){ printf("Could not open device %i\n", i); free(didData); i++; continue; } HidD_GetAttributes(usb_buzzer, &attr); printf("Device %i : VID %04X PID %04X\n", i, attr.VendorID, attr.ProductID); if((attr.VendorID==BUZZER_VID) && (attr.ProductID==BUZZER_PID || attr.ProductID==BUZZER_PID2)){ //We've found our buzzers !!! free(didData); printf("Buzzers found !!!\n"); memset(buf, 0, 8); buf[2]=0xFF; WriteFile(usb_buzzer, buf, 8, 0, &ovl); Sleep(100); memset(buf, 0, 8); buf[3]=0xFF; WriteFile(usb_buzzer, buf, 8, 0, &ovl); Sleep(100); memset(buf, 0, 8); buf[4]=0xFF; WriteFile(usb_buzzer, buf, 8, 0, &ovl); Sleep(100); memset(buf, 0, 8); buf[5]=0xFF; WriteFile(usb_buzzer, buf, 8, 0, &ovl); Sleep(100); memset(buf, 0, 8); WriteFile(usb_buzzer, buf, 8, 0, &ovl); break; } i++; } if(usb_buzzer==INVALID_HANDLE_VALUE) printf("Could not find buzzers\n"); return (USBDevice *)s; }
BOOL ProcessExistingDevices() { SP_DEVICE_INTERFACE_DATA interface_data; SP_DEVINFO_DATA device_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_W detail_data; HDEVINFO dev_info; DWORD length; int index = 0; const GUID category_guid = {STATIC_KSCATEGORY_AUDIO}; dev_info = SetupDiGetClassDevsExW(&category_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE, NULL, NULL, NULL); /* printf("%s:\n", ClassString); */ interface_data.cbSize = sizeof(interface_data); interface_data.Reserved = 0; /* Enumerate the devices within the category */ index = 0; length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR)); detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, length); if ( ! detail_data ) { logmsg("ProcessExistingDevices() failed to allocate detail_data\n"); return TRUE; } while ( SetupDiEnumDeviceInterfaces(dev_info, NULL, &category_guid, index, &interface_data) ) { PnP_AudioDevice* list_node; ZeroMemory(detail_data, length); /* NOTE: We don't actually use device_data... */ detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W); device_data.cbSize = sizeof(device_data); device_data.Reserved = 0; SetupDiGetDeviceInterfaceDetailW(dev_info, &interface_data, detail_data, length, NULL, &device_data); list_node = CreateDeviceDescriptor(detail_data->DevicePath, TRUE); AppendAudioDeviceToList(list_node); DestroyDeviceDescriptor(list_node); /* TODO: Cleanup the device we enumerated? */ index ++; }; HeapFree(GetProcessHeap(), 0, detail_data); SetupDiDestroyDeviceInfoList(dev_info); return TRUE; }
/* * Use a series of API calls to find a HID with * a specified Vendor IF and Product ID. */ HID_API_EXPORT HID_API_CALL hid_device *hid_open ( unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) { GUID hidguid; HANDLE hidclass; SP_DEVICE_INTERFACE_DATA iface; HANDLE dev; int i; HidD_GetHidGuid (&hidguid); hidclass = SetupDiGetClassDevs (&hidguid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); iface.cbSize = sizeof(iface); i = 0; dev = NULL; while (SetupDiEnumDeviceInterfaces (hidclass, 0, &hidguid, i, &iface)) { ULONG unused, nbytes = 0; PSP_DEVICE_INTERFACE_DETAIL_DATA detail; HIDD_ATTRIBUTES devinfo; SetupDiGetDeviceInterfaceDetail (hidclass, &iface, NULL, 0, &nbytes, NULL); detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (nbytes); detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); SetupDiGetDeviceInterfaceDetail (hidclass, &iface, detail, nbytes, &unused, NULL); dev = CreateFile (detail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, 0, NULL); free (detail); devinfo.Size = sizeof(devinfo); HidD_GetAttributes (dev, &devinfo); if (devinfo.VendorID == vendor_id && devinfo.ProductID == product_id) { // Both the Vendor ID and Product ID match. break; } // The Vendor ID doesn't match. // Free the memory used by the detailData structure (no longer needed). CloseHandle (dev); dev = NULL; // If we haven't found the device yet, and haven't tried every // available device, try the next one. i++; } // Free the memory reserved for hidclass by SetupDiClassDevs. SetupDiDestroyDeviceInfoList (hidclass); return (hid_device*) dev; }
BOOL GetDeviceHandle (GUID guidDeviceInterface, PHANDLE hDeviceHandle) { BOOL bResult = TRUE; HDEVINFO hDeviceInfo; SP_DEVINFO_DATA DeviceInfoData; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL; ULONG requiredLength=0; LPTSTR lpDevicePath = NULL; DWORD index = 0; if (guidDeviceInterface == GUID_NULL) { return FALSE; } // Get information about all the installed devices for the specified // device interface class. hDeviceInfo = SetupDiGetClassDevs( &guidDeviceInterface, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDeviceInfo == INVALID_HANDLE_VALUE) { // ERROR printf("Error SetupDiGetClassDevs: %d.\n", GetLastError()); goto done; } //Enumerate all the device interfaces in the device information set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (index = 0; SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); index++) { //Reset for this iteration if (lpDevicePath) { LocalFree(lpDevicePath); } if (pInterfaceDetailData) { LocalFree(pInterfaceDetailData); } deviceInterfaceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); //Get information about the device interface. bResult = SetupDiEnumDeviceInterfaces( hDeviceInfo, &DeviceInfoData, &guidDeviceInterface, index, &deviceInterfaceData); // Check if last item if (GetLastError () == ERROR_NO_MORE_ITEMS) { break; } bResult = SetupDiEnumDeviceInterfaces( hDeviceInfo, &DeviceInfoData, &guidDeviceInterface, index , &deviceInterfaceData); // Check if last item if (GetLastError () == ERROR_NO_MORE_ITEMS) { break; } //Check for some other error if (!bResult) { printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError()); goto done; } //Interface data is returned in SP_DEVICE_INTERFACE_DETAIL_DATA //which we need to allocate, so we have to call this function twice. //First to get the size so that we know how much to allocate //Second, the actual call with the allocated buffer bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo, &deviceInterfaceData, NULL, 0, &requiredLength, NULL); //Check for some other error if (!bResult) { if ((ERROR_INSUFFICIENT_BUFFER==GetLastError()) && (requiredLength>0)) { //we got the size, allocate buffer pInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, requiredLength); if (!pInterfaceDetailData) { // ERROR printf("Error allocating memory for the device detail buffer.\n"); goto done; } } else { printf("Error SetupDiEnumDeviceInterfaces: %d.\n", GetLastError()); goto done; } } //get the interface detailed data pInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //Now call it with the correct size and allocated buffer bResult = SetupDiGetDeviceInterfaceDetail( hDeviceInfo, &deviceInterfaceData, pInterfaceDetailData, requiredLength, NULL, &DeviceInfoData); //Check for some other error if (!bResult) { printf("Error SetupDiGetDeviceInterfaceDetail: %d.\n", GetLastError()); goto done; } //copy device path size_t nLength = wcslen (pInterfaceDetailData->DevicePath) + 1; lpDevicePath = (TCHAR *) LocalAlloc (LPTR, nLength * sizeof(TCHAR)); StringCchCopy(lpDevicePath, nLength, pInterfaceDetailData->DevicePath); lpDevicePath[nLength-1] = 0; printf("Device path: %s\n", lpDevicePath); } if (!lpDevicePath) { //Error. printf("Error %d.", GetLastError()); goto done; } //Open the device *hDeviceHandle = CreateFile ( lpDevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (*hDeviceHandle == INVALID_HANDLE_VALUE) { //Error. printf("Error %d.", GetLastError()); goto done; } done: LocalFree(lpDevicePath); LocalFree(pInterfaceDetailData); bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo); return bResult; } // End of GetDeviceHandle()
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) { BOOL res; struct hid_device_info *root = NULL; // return object struct hid_device_info *cur_dev = NULL; #ifndef HIDAPI_USE_DDK if (!initialized) lookup_functions(); #endif // Windows objects for interacting with the driver. GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; SP_DEVINFO_DATA devinfo_data; SP_DEVICE_INTERFACE_DATA device_interface_data; SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; // Initialize the Windows objects. devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // Get information for all the devices belonging to the HID class. device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // Iterate over each device in the HID class, looking for the right one. int device_index = 0; for (;;) { HANDLE write_handle = INVALID_HANDLE_VALUE; DWORD required_size = 0; res = SetupDiEnumDeviceInterfaces(device_info_set, NULL, &InterfaceClassGuid, device_index, &device_interface_data); if (!res) { // A return of FALSE from this function means that // there are no more devices. break; } // Call with 0-sized detail size, and let the function // tell us how long the detail struct needs to be. The // size is put in &required_size. res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, NULL, 0, &required_size, NULL); // Allocate a long enough structure for device_interface_detail_data. device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); // Get the detailed data for this device. The detail data gives us // the device path for this device, which is then passed into // CreateFile() to get a handle to the device. res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, device_interface_detail_data, required_size, NULL, NULL); if (!res) { //register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); // Continue to the next device. goto cont; } //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); // Open a handle to the device write_handle = CreateFileA(device_interface_detail_data->DevicePath, GENERIC_WRITE |GENERIC_READ, 0x0, /*share mode*/ NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED,//FILE_ATTRIBUTE_NORMAL, 0); // Check validity of write_handle. if (write_handle == INVALID_HANDLE_VALUE) { // Unable to open the device. //register_error(dev, "CreateFile"); goto cont_close; } // Get the Vendor ID and Product ID for this device. HIDD_ATTRIBUTES attrib; attrib.Size = sizeof(HIDD_ATTRIBUTES); HidD_GetAttributes(write_handle, &attrib); //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); // Check the VID/PID to see if we should add this // device to the enumeration list. if ((vendor_id == 0x0 && product_id == 0x0) || (attrib.VendorID == vendor_id && attrib.ProductID == product_id)) { #define WSTR_LEN 512 const char *str; struct hid_device_info *tmp; HIDP_PREPARSED_DATA *pp_data = NULL; HIDP_CAPS caps; BOOLEAN res; NTSTATUS nt_res; wchar_t wstr[WSTR_LEN]; // TODO: Determine Size size_t len; /* VID/PID match. Create the record. */ tmp = (hid_device_info*) calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; // Get the Usage Page and Usage for this device. res = HidD_GetPreparsedData(write_handle, &pp_data); if (res) { nt_res = HidP_GetCaps(pp_data, &caps); if (nt_res == HIDP_STATUS_SUCCESS) { cur_dev->usage_page = caps.UsagePage; cur_dev->usage = caps.Usage; } HidD_FreePreparsedData(pp_data); } /* Fill out the record */ cur_dev->next = NULL; str = device_interface_detail_data->DevicePath; if (str) { len = strlen(str); cur_dev->path = (char*) calloc(len+1, sizeof(char)); strncpy(cur_dev->path, str, len+1); cur_dev->path[len] = '\0'; } else cur_dev->path = NULL; /* Serial Number */ res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->serial_number = _wcsdup(wstr); } /* Manufacturer String */ res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->manufacturer_string = _wcsdup(wstr); } /* Product String */ res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->product_string = _wcsdup(wstr); } /* VID/PID */ cur_dev->vendor_id = attrib.VendorID; cur_dev->product_id = attrib.ProductID; /* Release Number */ cur_dev->release_number = attrib.VersionNumber; /* Interface Number (Unsupported on Windows)*/ cur_dev->interface_number = -1; } cont_close: CloseHandle(write_handle); cont: // We no longer need the detail data. It can be freed free(device_interface_detail_data); device_index++; } // Close the device information handle. SetupDiDestroyDeviceInfoList(device_info_set); return root; }
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id) { BOOL res; struct hid_device_info *root = NULL; /* return object */ struct hid_device_info *cur_dev = NULL; /* Windows objects for interacting with the driver. */ GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, {0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30} }; SP_DEVINFO_DATA devinfo_data; SP_DEVICE_INTERFACE_DATA device_interface_data; SP_DEVICE_INTERFACE_DETAIL_DATA_A *device_interface_detail_data = NULL; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; int device_index = 0; int i; if (hid_init() < 0) return NULL; /* Initialize the Windows objects. */ memset(&devinfo_data, 0x0, sizeof(devinfo_data)); devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); device_interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); /* Get information for all the devices belonging to the HID class. */ device_info_set = SetupDiGetClassDevsA(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); /* Iterate over each device in the HID class, looking for the right one. */ for (;;) { HANDLE write_handle = INVALID_HANDLE_VALUE; DWORD required_size = 0; HIDD_ATTRIBUTES attrib; res = SetupDiEnumDeviceInterfaces(device_info_set, NULL, &InterfaceClassGuid, device_index, &device_interface_data); if (!res) { /* A return of FALSE from this function means that there are no more devices. */ break; } /* Call with 0-sized detail size, and let the function tell us how long the detail struct needs to be. The size is put in &required_size. */ res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, NULL, 0, &required_size, NULL); /* Allocate a long enough structure for device_interface_detail_data. */ device_interface_detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*) malloc(required_size); device_interface_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); /* Get the detailed data for this device. The detail data gives us the device path for this device, which is then passed into CreateFile() to get a handle to the device. */ res = SetupDiGetDeviceInterfaceDetailA(device_info_set, &device_interface_data, device_interface_detail_data, required_size, NULL, NULL); if (!res) { /* register_error(dev, "Unable to call SetupDiGetDeviceInterfaceDetail"); Continue to the next device. */ goto cont; } /* Make sure this device is of Setup Class "HIDClass" and has a driver bound to it. */ for (i = 0; ; i++) { char driver_name[256]; /* Populate devinfo_data. This function will return failure when there are no more interfaces left. */ res = SetupDiEnumDeviceInfo(device_info_set, i, &devinfo_data); if (!res) goto cont; res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_CLASS, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); if (!res) goto cont; if (strcmp(driver_name, "HIDClass") == 0) { /* See if there's a driver bound. */ res = SetupDiGetDeviceRegistryPropertyA(device_info_set, &devinfo_data, SPDRP_DRIVER, NULL, (PBYTE)driver_name, sizeof(driver_name), NULL); if (res) break; } } //wprintf(L"HandleName: %s\n", device_interface_detail_data->DevicePath); /* Open a handle to the device */ write_handle = open_device(device_interface_detail_data->DevicePath, TRUE); /* Check validity of write_handle. */ if (write_handle == INVALID_HANDLE_VALUE) { /* Unable to open the device. */ //register_error(dev, "CreateFile"); goto cont_close; } /* Get the Vendor ID and Product ID for this device. */ attrib.Size = sizeof(HIDD_ATTRIBUTES); HidD_GetAttributes(write_handle, &attrib); //wprintf(L"Product/Vendor: %x %x\n", attrib.ProductID, attrib.VendorID); /* Check the VID/PID to see if we should add this device to the enumeration list. */ if ((vendor_id == 0x0 || attrib.VendorID == vendor_id) && (product_id == 0x0 || attrib.ProductID == product_id)) { #define WSTR_LEN 512 const char *str; struct hid_device_info *tmp; PHIDP_PREPARSED_DATA pp_data = NULL; HIDP_CAPS caps; BOOLEAN res; NTSTATUS nt_res; wchar_t wstr[WSTR_LEN]; /* TODO: Determine Size */ size_t len; /* VID/PID match. Create the record. */ tmp = (struct hid_device_info*) calloc(1, sizeof(struct hid_device_info)); if (cur_dev) { cur_dev->next = tmp; } else { root = tmp; } cur_dev = tmp; /* Get the Usage Page and Usage for this device. */ res = HidD_GetPreparsedData(write_handle, &pp_data); if (res) { nt_res = HidP_GetCaps(pp_data, &caps); if (nt_res == HIDP_STATUS_SUCCESS) { cur_dev->usage_page = caps.UsagePage; cur_dev->usage = caps.Usage; } HidD_FreePreparsedData(pp_data); } /* Fill out the record */ cur_dev->next = NULL; str = device_interface_detail_data->DevicePath; if (str) { len = strlen(str); cur_dev->path = (char*) calloc(len+1, sizeof(char)); strncpy(cur_dev->path, str, len+1); cur_dev->path[len] = '\0'; } else cur_dev->path = NULL; /* Serial Number */ res = HidD_GetSerialNumberString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->serial_number = _wcsdup(wstr); } /* Manufacturer String */ res = HidD_GetManufacturerString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->manufacturer_string = _wcsdup(wstr); } /* Product String */ res = HidD_GetProductString(write_handle, wstr, sizeof(wstr)); wstr[WSTR_LEN-1] = 0x0000; if (res) { cur_dev->product_string = _wcsdup(wstr); } /* VID/PID */ cur_dev->vendor_id = attrib.VendorID; cur_dev->product_id = attrib.ProductID; /* Release Number */ cur_dev->release_number = attrib.VersionNumber; /* Interface Number. It can sometimes be parsed out of the path on Windows if a device has multiple interfaces. See http://msdn.microsoft.com/en-us/windows/hardware/gg487473 or search for "Hardware IDs for HID Devices" at MSDN. If it's not in the path, it's set to -1. */ cur_dev->interface_number = -1; if (cur_dev->path) { char *interface_component = strstr(cur_dev->path, "&mi_"); if (interface_component) { char *hex_str = interface_component + 4; char *endptr = NULL; cur_dev->interface_number = strtol(hex_str, &endptr, 16); if (endptr == hex_str) { /* The parsing failed. Set interface_number to -1. */ cur_dev->interface_number = -1; } } } } cont_close: CloseHandle(write_handle); cont: /* We no longer need the detail data. It can be freed */ free(device_interface_detail_data); device_index++; } /* Close the device information handle. */ SetupDiDestroyDeviceInfoList(device_info_set); return root; }
static HANDLE OpenBusInterface( VOID ) { HDEVINFO hardwareDeviceInfo; SP_INTERFACE_DEVICE_DATA deviceInterfaceData; HANDLE file; PSP_INTERFACE_DEVICE_DETAIL_DATA deviceInterfaceDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; hardwareDeviceInfo = SetupDiGetClassDevs ( (LPGUID)&GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_INTERFACEDEVICE) // Function class devices. ); if(INVALID_HANDLE_VALUE == hardwareDeviceInfo) { DebugPrint(1, ("[LanscsiLib]OpenBusInterface: SetupDiGetClassDevs failed: 0x%x\n", GetLastError())); return NULL; } deviceInterfaceData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA); if (SetupDiEnumDeviceInterfaces ( hardwareDeviceInfo, 0, // No care about specific PDOs (LPGUID)&GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS, 0, // &deviceInterfaceData)) { } else if (ERROR_NO_MORE_ITEMS == GetLastError()) { DebugPrint(1, ("[LanscsiLib]OpenBusInterface: Interface GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS is not registered\n")); return NULL; } SetupDiGetInterfaceDeviceDetail ( hardwareDeviceInfo, &deviceInterfaceData, 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; deviceInterfaceDetailData = HeapAlloc(GetProcessHeap(), 0, predictedLength); deviceInterfaceDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); if (! SetupDiGetInterfaceDeviceDetail ( hardwareDeviceInfo, &deviceInterfaceData, deviceInterfaceDetailData, predictedLength, &requiredLength, NULL)) { DebugPrint(1, ("[LanscsiLib]OpenBusInterface: SetupDiGetInterfaceDeviceDetail Error.\n")); HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return NULL; } DebugPrint(3, ("[LanscsiLib]OpenBusInterface: Opening %s\n", deviceInterfaceDetailData->DevicePath)); file = CreateFile ( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, // 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 == file) { DebugPrint(1, ("[LanscsiLib]OpenBusInterface: Device not ready: 0x%x", GetLastError())); HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return NULL; } DebugPrint(3, ("[LanscsiLib]OpenBusInterface: Bus interface opened!!! %s\n", deviceInterfaceDetailData->DevicePath)); // Clean up. HeapFree(GetProcessHeap(), 0, deviceInterfaceDetailData); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return file; }
int main( int argc, char* argv[] ) { int SerialNo; bool fPlugin, fUnplug, fEject; HDEVINFO hdevinfo; SP_DEVICE_INTERFACE_DATA devIntData; BOOL bresult; unique_handle hfile = INVALID_HANDLE_VALUE; fPlugin = fUnplug = fEject = false; if( argc < 3 ) { usage(); } char* arg1 = argv[1]; if( arg1[0] == '-' ) { SerialNo = std::atoi( argv[2] ); char opt = arg1[1]; switch( opt ) { case 'p': fPlugin = true; break; case 'u': fUnplug = true; break; case 'e': fEject = true; break; default: usage(); break; } } else { usage(); } hdevinfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_RoboBus, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if( hdevinfo == INVALID_HANDLE_VALUE ) { throw std::exception( "SetupDiGetClassDevs failed" ); } memset( &devIntData, 0, sizeof(devIntData) ); devIntData.cbSize = sizeof(devIntData); bresult = SetupDiEnumDeviceInterfaces( hdevinfo, 0, &GUID_DEVINTERFACE_RoboBus, 0, &devIntData ); if( !bresult ) { throw std::exception( "SetupDiEnumDeviceInterface failed", GetLastError() ); } hfile = openBusInterface( hdevinfo, &devIntData ); if( fPlugin ) { ULONG bytes = sizeof(BUSENUM_PLUGIN_HARDWARE) + sizeof(BUS_HARDWARE_IDS); std::unique_ptr<BYTE> buffer( new BYTE[bytes] ); BUSENUM_PLUGIN_HARDWARE* pplugin = (BUSENUM_PLUGIN_HARDWARE*)buffer.get(); pplugin->Size = sizeof(BUSENUM_PLUGIN_HARDWARE); pplugin->SerialNo = SerialNo; memcpy( pplugin->HardwareIDs, BUS_HARDWARE_IDS, sizeof(BUS_HARDWARE_IDS) ); bresult = DeviceIoControl( hfile, IOCTL_BUSENUM_PLUGIN_HARDWARE, pplugin, bytes, NULL, 0, &bytes, NULL ); if( !bresult ) { throw std::exception( "Failed DeviceIoControl", GetLastError() ); } } if( fUnplug ) { BUSENUM_UNPLUG_HARDWARE unplug; ULONG bytes; unplug.Size = bytes = sizeof(unplug); unplug.SerialNo = SerialNo; bresult = DeviceIoControl( hfile, IOCTL_BUSENUM_UNPLUG_HARDWARE, &unplug, bytes, NULL, 0, &bytes, NULL ); if( !bresult ) { throw std::exception( "Failed DeviceIoControl", GetLastError() ); } } if( fEject ) { BUSENUM_EJECT_HARDWARE eject; ULONG bytes; eject.Size = bytes = sizeof(eject); eject.SerialNo = SerialNo; bresult = DeviceIoControl( hfile, IOCTL_BUSENUM_EJECT_HARDWARE, &eject, bytes, NULL, 0, &bytes, NULL ); if( !bresult ) { throw std::exception( "Failed DeviceIoControl", GetLastError() ); } } SetupDiDestroyDeviceInfoList( hdevinfo ); if( hfile != INVALID_HANDLE_VALUE ) { CloseHandle( hfile ); } return 0; }
PTCHAR CDevice::GetDevicePath( IN LPGUID InterfaceGuid ) { HDEVINFO HardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; ULONG Length, RequiredLength = 0; BOOL bResult; HardwareDeviceInfo = SetupDiGetClassDevs( InterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) ); if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { printf("Cannot get class devices.\n"); return NULL; } DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, InterfaceGuid, 0, &DeviceInterfaceData ); if (bResult == FALSE) { printf("Cannot get enumerate device interfaces.\n"); SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); return NULL; } SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, NULL, 0, &RequiredLength, NULL ); DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength); if (DeviceInterfaceDetailData == NULL) { printf("Cannot allocate memory.\n"); SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); return NULL; } DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); Length = RequiredLength; bResult = SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, Length, &RequiredLength, NULL ); if (bResult == FALSE) { printf("Cannot get device interface details.\n"); SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); LocalFree(DeviceInterfaceDetailData); return NULL; } return DeviceInterfaceDetailData->DevicePath; }
int main() { HANDLE hDevice = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { 0 }; deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); DWORD memberIndex = 0; DWORD requiredSize = 0; GUID hidClass; HidD_GetHidGuid(&hidClass); HMODULE cerberus = LoadLibrary(L"HidCerberus.Lib.dll"); HidGuardianOpen_t fpOpen = reinterpret_cast<HidGuardianOpen_t>(GetProcAddress(cerberus, "HidGuardianOpen")); HidGuardianOpen_t fpClose = reinterpret_cast<HidGuardianOpen_t>(GetProcAddress(cerberus, "HidGuardianClose")); if (!fpOpen || !fpClose) { printf("Exports not found, is HidCerberus.Lib.dll in my directory?\n"); return -1; } fpOpen(); auto deviceInfoSet = SetupDiGetClassDevs(&hidClass, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); while (SetupDiEnumDeviceInterfaces(deviceInfoSet, nullptr, &hidClass, memberIndex++, &deviceInterfaceData)) { printf("Found one!\n"); // get required target buffer size SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, nullptr, 0, &requiredSize, nullptr); // allocate target buffer auto detailDataBuffer = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(requiredSize)); detailDataBuffer->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // get detail buffer if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, &deviceInterfaceData, detailDataBuffer, requiredSize, &requiredSize, nullptr)) { SetupDiDestroyDeviceInfoList(deviceInfoSet); free(detailDataBuffer); continue; } printf("%ls\n", detailDataBuffer->DevicePath); if (hDevice != INVALID_HANDLE_VALUE) { CloseHandle(hDevice); } // device found, open it hDevice = CreateFile(detailDataBuffer->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr); printf("hDevice = 0x%p, error = %d\n", hDevice, GetLastError()); free(detailDataBuffer); } SetupDiDestroyDeviceInfoList(deviceInfoSet); printf("Done\n"); getchar(); fpClose(); return 0; }
int usb_find_devices(void) { GUID hGuid=WEATHER_DEVICE_GUID ; //HidD_GetHidGuid(&hGuid); // Get the set of device interfaces that have been matched by our INF HDEVINFO deviceInfo = SetupDiGetClassDevs(&hGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (!deviceInfo) { return 0; } // Iterate over all interfaces int ndevs = 0; int devidx = 0; while (ndevs < MAX_USB_DEVICES) { // Get interface data for next interface and attempt to init it SP_DEVICE_INTERFACE_DATA interfaceData; interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces( deviceInfo, NULL, &hGuid, devidx++, &interfaceData)) { break; } // Determine required size for interface detail data ULONG requiredLength = 0; if (!SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, NULL, 0, &requiredLength, NULL)) return 0; // Allocate storage for interface detail data PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredLength); if (!detailData) return 0; detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // Fetch interface detail data if (!SetupDiGetDeviceInterfaceDetail( deviceInfo, &interfaceData, detailData, requiredLength, &requiredLength, NULL)) { free(detailData); continue; } // Populate device structure struct usb_device *dev = devices+ndevs; memset(dev, 0, sizeof(*dev)); strncpy(dev->filename, detailData->DevicePath, sizeof(dev->filename)); dev->bus = &bus; if (ndevs) { dev->prev = devices + ndevs - 1; dev->prev->next = dev; } // Fetch device descriptor structure if (usb_get_device_desc(dev) == 0) ndevs++; free(detailData); } SetupDiDestroyDeviceInfoList(deviceInfo); return ndevs; }
PSP_DEVICE_INTERFACE_DETAIL_DATA GetDeviceInterfaceDetailData( _In_ LPGUID InterfaceGuid ) { HDEVINFO HardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL; ULONG Length, RequiredLength = 0; BOOL bResult; HardwareDeviceInfo = SetupDiGetClassDevs( InterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (HardwareDeviceInfo == INVALID_HANDLE_VALUE) { printf("SetupDiGetClassDevs failed!\n"); exit(1); } DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bResult = SetupDiEnumDeviceInterfaces(HardwareDeviceInfo, 0, InterfaceGuid, 0, &DeviceInterfaceData); if (bResult == FALSE) { LPVOID lpMsgBuf = NULL; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL )) { printf("Error: %s", (LPSTR)lpMsgBuf); LocalFree(lpMsgBuf); } printf("SetupDiEnumDeviceInterfaces failed.\n"); SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); exit(1); } SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, NULL, 0, &RequiredLength, NULL ); DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LMEM_FIXED, RequiredLength); if (DeviceInterfaceDetailData == NULL) { SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); printf("Failed to allocate memory.\n"); exit(1); } DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); Length = RequiredLength; bResult = SetupDiGetDeviceInterfaceDetail( HardwareDeviceInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, Length, &RequiredLength, NULL); if (bResult == FALSE) { LPVOID lpMsgBuf = NULL; if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &lpMsgBuf, 0, NULL)) { MessageBox(NULL, (LPCTSTR) lpMsgBuf, "Error", MB_OK); LocalFree(lpMsgBuf); } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); printf("Error in SetupDiGetDeviceInterfaceDetail\n"); LocalFree(DeviceInterfaceDetailData); DeviceInterfaceDetailData = NULL; exit(1); } SetupDiDestroyDeviceInfoList(HardwareDeviceInfo); return DeviceInterfaceDetailData; }
void EnumPortsWdm(CArray<SSerInfo,SSerInfo&> &asi) { CString strErr; // Create a device information set that will be the container for // the device interfaces. GUID *guidDev = (GUID*) &GUID_CLASS_COMPORT; HDEVINFO hDevInfo = INVALID_HANDLE_VALUE; SP_DEVICE_INTERFACE_DETAIL_DATA *pDetData = NULL; try { hDevInfo = SetupDiGetClassDevs( guidDev, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if(hDevInfo == INVALID_HANDLE_VALUE) { strErr.Format(_T("SetupDiGetClassDevs failed. (err=%lx)"), GetLastError()); throw strErr; } // Enumerate the serial ports BOOL bOk = TRUE; SP_DEVICE_INTERFACE_DATA ifcData; DWORD dwDetDataSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + 256; pDetData = (SP_DEVICE_INTERFACE_DETAIL_DATA*) new char[dwDetDataSize]; // This is required, according to the documentation. Yes, // it's weird. ifcData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); pDetData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); for (DWORD ii=0; bOk; ii++) { bOk = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guidDev, ii, &ifcData); if (bOk) { // Got a device. Get the details. SP_DEVINFO_DATA devdata = {sizeof(SP_DEVINFO_DATA)}; bOk = SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifcData, pDetData, dwDetDataSize, NULL, &devdata); if (bOk) { CString strDevPath(pDetData->DevicePath); // Got a path to the device. Try to get some more info. TCHAR fname[256]; TCHAR desc[256]; BOOL bSuccess = SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_FRIENDLYNAME, NULL, (PBYTE)fname, sizeof(fname), NULL); bSuccess = bSuccess && SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_DEVICEDESC, NULL, (PBYTE)desc, sizeof(desc), NULL); BOOL bUsbDevice = FALSE; TCHAR locinfo[256]; if (SetupDiGetDeviceRegistryProperty( hDevInfo, &devdata, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)locinfo, sizeof(locinfo), NULL)) { // Just check the first three characters to determine // if the port is connected to the USB bus. This isn't // an infallible method; it would be better to use the // BUS GUID. Currently, Windows doesn't let you query // that though (SPDRP_BUSTYPEGUID seems to exist in // documentation only). bUsbDevice = (strncmp((char *)locinfo, "USB", 3)==0); } if (bSuccess) { // Add an entry to the array SSerInfo si; si.strDevPath = strDevPath; si.strFriendlyName = fname; si.strPortDesc = desc; si.bUsbDevice = bUsbDevice; asi.Add(si); } } else { strErr.Format(L"SetupDiGetDeviceInterfaceDetail failed. (err=%lx)", GetLastError()); throw strErr; } } else { DWORD err = GetLastError(); if (err != ERROR_NO_MORE_ITEMS) { strErr.Format(L"SetupDiEnumDeviceInterfaces failed. (err=%lx)", err); throw strErr; } } } } catch (CString strCatchErr) { strErr = strCatchErr; } if (pDetData != NULL) delete [] (char*)pDetData; if (hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDevInfo); if (!strErr.IsEmpty()) throw strErr; }
HRESULT CNdasServiceDeviceEventHandler::pRegisterNdasScsiPorts() { HRESULT hr = S_OK; HDEVINFO hDevInfoSet = SetupDiGetClassDevs( &GUID_DEVINTERFACE_STORAGEPORT, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (static_cast<HDEVINFO>(INVALID_HANDLE_VALUE) == hDevInfoSet) { hr = HRESULT_FROM_WIN32(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiCreateDeviceInfoList failed, hr=%x\n", hr); return hr; } for (DWORD index = 0; ; ++index) { SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { sizeof(SP_DEVICE_INTERFACE_DATA) }; BOOL success = SetupDiEnumDeviceInterfaces( hDevInfoSet, NULL, &GUID_DEVINTERFACE_STORAGEPORT, index, &deviceInterfaceData); if (!success) { if (ERROR_NO_MORE_ITEMS != GetLastError()) { hr = HRESULT_FROM_WIN32(GetLastError()); XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiEnumDeviceInterfaces failed, hr=%X\n", hr); } break; } DWORD requiredSize = 0; success = SetupDiGetDeviceInterfaceDetail( hDevInfoSet, &deviceInterfaceData, NULL, 0, &requiredSize, NULL); if (success || ERROR_INSUFFICIENT_BUFFER != GetLastError()) { if (success) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiGetDeviceInterfaceDetail failed, no interface details\n"); } else { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiGetDeviceInterfaceDetail failed, error=0x%X\n", GetLastError()); } continue; } PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = static_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA>(malloc(requiredSize)); if (NULL == deviceInterfaceDetailData) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "malloc failed, bytes=%d\n", requiredSize); continue; } ZeroMemory(deviceInterfaceDetailData, requiredSize); deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); success = SetupDiGetDeviceInterfaceDetail( hDevInfoSet, &deviceInterfaceData, deviceInterfaceDetailData, requiredSize, NULL, NULL); if (!success) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "SetupDiGetDeviceInterfaceDetail failed, error=0x%X\n", GetLastError()); free(deviceInterfaceDetailData); continue; } XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_INFORMATION, "StoragePort found, device=%ls\n", deviceInterfaceDetailData->DevicePath); HANDLE hDevice = CreateFile( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL); if (INVALID_HANDLE_VALUE == hDevice) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_ERROR, "CreateFile failed, device=%ls, error=0x%X\n", deviceInterfaceDetailData->DevicePath, GetLastError()); free(deviceInterfaceDetailData); continue; } DWORD slotNo = 0; HRESULT hr2 = pGetNdasSlotNumberFromDeviceHandle(hDevice, &slotNo); if (S_OK != hr2) { XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_WARNING, "StoragePort is not an NDAS Storage Port, hr=%x\n", hr2); XTLVERIFY( CloseHandle(hDevice) ); free(deviceInterfaceDetailData); continue; } XTLTRACE2(NDASSVC_PNP, TRACE_LEVEL_INFORMATION, "NdasSlotNumber=%d\n", slotNo); // // As the ownership of the handler goes to the vector, // do not close the device handle here // RegisterDeviceHandleNotification( hDevice, slotNo, deviceInterfaceDetailData->DevicePath); XTLVERIFY( CloseHandle(hDevice) ); free(deviceInterfaceDetailData); } XTLVERIFY( SetupDiDestroyDeviceInfoList(hDevInfoSet) ); return hr; }
/* * Refresh the list of USB devices */ BOOL GetUSBDevices(DWORD devnum) { // The first two are standard Microsoft drivers (including the Windows 8 UASP one). // The rest are the vendor UASP drivers I know of so far - list may be incomplete! const char* storage_name[] = { "USBSTOR", "UASPSTOR", "VUSBSTOR", "ETRONSTOR", "ASUSSTPT" }; const char* scsi_name = "SCSI"; const char* usb_speed_name[USB_SPEED_MAX] = { "USB", "USB 1.0", "USB 1.1", "USB 2.0", "USB 3.0" }; // Hash table and String Array used to match a Device ID with the parent hub's Device Interface Path htab_table htab_devid = HTAB_EMPTY; StrArray dev_if_path; char letter_name[] = " (?:)"; char uefi_togo_check[] = "?:\\EFI\\Rufus\\ntfs_x64.efi"; BOOL r = FALSE, found = FALSE, is_SCSI, post_backslash; HDEVINFO dev_info = NULL; SP_DEVINFO_DATA dev_info_data; SP_DEVICE_INTERFACE_DATA devint_data; PSP_DEVICE_INTERFACE_DETAIL_DATA_A devint_detail_data; DEVINST parent_inst, grandparent_inst, device_inst; DWORD size, i, j, k, l, datatype, drive_index; ULONG list_size[ARRAYSIZE(storage_name)] = { 0 }, list_start[ARRAYSIZE(storage_name)] = { 0 }, full_list_size, ulFlags; HANDLE hDrive; LONG maxwidth = 0; int s, score, drive_number, remove_drive; char drive_letters[27], *device_id, *devid_list = NULL, entry_msg[128]; char *label, *entry, buffer[MAX_PATH], str[MAX_PATH], *method_str; usb_device_props props; IGNORE_RETVAL(ComboBox_ResetContent(hDeviceList)); StrArrayClear(&DriveID); StrArrayClear(&DriveLabel); StrArrayCreate(&dev_if_path, 128); // Add a dummy for string index zero, as this is what non matching hashes will point to StrArrayAdd(&dev_if_path, ""); device_id = (char*)malloc(MAX_PATH); if (device_id == NULL) goto out; // Build a hash table associating a CM Device ID of an USB device with the SetupDI Device Interface Path // of its parent hub - this is needed to retrieve the device speed dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_USB_HUB, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (dev_info != INVALID_HANDLE_VALUE) { if (htab_create(DEVID_HTAB_SIZE, &htab_devid)) { dev_info_data.cbSize = sizeof(dev_info_data); for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { uuprintf("Processing Hub %d:", i + 1); devint_detail_data = NULL; devint_data.cbSize = sizeof(devint_data); // Only care about the first interface (MemberIndex 0) if ( (SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_USB_HUB, 0, &devint_data)) && (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER) && ((devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size)) != NULL) ) { devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); if (SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { // Find the Device IDs for all the children of this hub if (CM_Get_Child(&device_inst, dev_info_data.DevInst, 0) == CR_SUCCESS) { device_id[0] = 0; s = StrArrayAdd(&dev_if_path, devint_detail_data->DevicePath); uuprintf(" Hub[%d] = '%s'", s, devint_detail_data->DevicePath); if ((s>= 0) && (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS)) { if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; } uuprintf(" Found ID[%03d]: %s", k, device_id); while (CM_Get_Sibling(&device_inst, device_inst, 0) == CR_SUCCESS) { device_id[0] = 0; if (CM_Get_Device_IDA(device_inst, device_id, MAX_PATH, 0) == CR_SUCCESS) { if ((k = htab_hash(device_id, &htab_devid)) != 0) { htab_devid.table[k].data = (void*)(uintptr_t)s; } uuprintf(" Found ID[%03d]: %s", k, device_id); } } } } } free(devint_detail_data); } } } SetupDiDestroyDeviceInfoList(dev_info); } free(device_id); // Build a single list of Device IDs from all the storage enumerators we know of full_list_size = 0; ulFlags = CM_GETIDLIST_FILTER_SERVICE; if (nWindowsVersion >= WINDOWS_7) ulFlags |= CM_GETIDLIST_FILTER_PRESENT; for (s=0; s<ARRAYSIZE(storage_name); s++) { // Get a list of device IDs for all USB storage devices // This will be used to find if a device is UASP if (CM_Get_Device_ID_List_SizeA(&list_size[s], storage_name[s], ulFlags) != CR_SUCCESS) list_size[s] = 0; if (list_size[s] != 0) full_list_size += list_size[s]-1; // remove extra NUL terminator } devid_list = NULL; if (full_list_size != 0) { full_list_size += 1; // add extra NUL terminator devid_list = (char*)malloc(full_list_size); if (devid_list == NULL) { uprintf("Could not allocate Device ID list\n"); return FALSE; } for (s=0, i=0; s<ARRAYSIZE(storage_name); s++) { list_start[s] = i; if (list_size[s] > 1) { if (CM_Get_Device_ID_ListA(storage_name[s], &devid_list[i], list_size[s], ulFlags) != CR_SUCCESS) continue; if (usb_debug) { uprintf("Processing IDs belonging to %s:", storage_name[s]); for (device_id = &devid_list[i]; *device_id != 0; device_id += strlen(device_id) + 1) uprintf(" %s", device_id); } // The list_size is sometimes larger than required thus we need to find the real end for (i += list_size[s]; i > 2; i--) { if ((devid_list[i-2] != '\0') && (devid_list[i-1] == '\0') && (devid_list[i] == '\0')) break; } } } } // Now use SetupDi to enumerate all our storage devices dev_info = SetupDiGetClassDevsA(&_GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (dev_info == INVALID_HANDLE_VALUE) { uprintf("SetupDiGetClassDevs (Interface) failed: %s\n", WindowsErrorString()); goto out; } dev_info_data.cbSize = sizeof(dev_info_data); for (i=0; SetupDiEnumDeviceInfo(dev_info, i, &dev_info_data); i++) { memset(buffer, 0, sizeof(buffer)); method_str = ""; if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_ENUMERATOR_NAME, &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Enumerator Name) failed: %s\n", WindowsErrorString()); continue; } // UASP drives are listed under SCSI (along with regular SYSTEM drives => "DANGER, WILL ROBINSON!!!") is_SCSI = (safe_stricmp(buffer, scsi_name) == 0); if ((safe_stricmp(buffer, storage_name[0]) != 0) && (!is_SCSI)) continue; // We can't use the friendly name to find if a drive is a VHD, as friendly name string gets translated // according to your locale, so we poke the Hardware ID memset(&props, 0, sizeof(props)); memset(buffer, 0, sizeof(buffer)); props.is_VHD = SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_HARDWAREID, &datatype, (LPBYTE)buffer, sizeof(buffer), &size) && IsVHD(buffer); uuprintf("Processing Device: '%s'", buffer); memset(buffer, 0, sizeof(buffer)); if (!SetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_FRIENDLYNAME, &datatype, (LPBYTE)buffer, sizeof(buffer), &size)) { uprintf("SetupDiGetDeviceRegistryProperty (Friendly Name) failed: %s\n", WindowsErrorString()); // We can afford a failure on this call - just replace the name with "USB Storage Device (Generic)" safe_strcpy(buffer, sizeof(buffer), lmprintf(MSG_045)); } else if ((!props.is_VHD) && (devid_list != NULL)) { // Get the properties of the device. We could avoid doing this lookup every time by keeping // a lookup table, but there shouldn't be that many USB storage devices connected... // NB: Each of these Device IDs have an _only_ child, from which we get the Device Instance match. for (device_id = devid_list; *device_id != 0; device_id += strlen(device_id) + 1) { if ( (CM_Locate_DevNodeA(&parent_inst, device_id, 0) == CR_SUCCESS) && (CM_Get_Child(&device_inst, parent_inst, 0) == CR_SUCCESS) && (device_inst == dev_info_data.DevInst) ) { post_backslash = FALSE; method_str = ""; // If we're not dealing with the USBSTOR part of our list, then this is an UASP device props.is_UASP = ((((uintptr_t)device_id)+2) >= ((uintptr_t)devid_list)+list_start[1]); // Now get the properties of the device, and its Device ID, which we need to populate the properties j = htab_hash(device_id, &htab_devid); uuprintf(" Matched with ID[%03d]: %s", j, device_id); // Try to parse the current device_id string for VID:PID // We'll use that if we can't get anything better for (k = 0, l = 0; (k<strlen(device_id)) && (l<2); k++) { // The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\... if (device_id[k] == '\\') post_backslash = TRUE; if (!post_backslash) continue; if (device_id[k] == '_') { props.pid = (uint16_t)strtoul(&device_id[k + 1], NULL, 16); if (l++ == 0) props.vid = props.pid; } } if (props.vid != 0) method_str = "[ID]"; // If the hash didn't match a populated string in dev_if_path[] (htab_devid.table[j].data > 0), // we might have an extra vendor driver in between (e.g. "ASUS USB 3.0 Boost Storage Driver" // for UASP devices in ASUS "Turbo Mode" or "Apple Mobile Device USB Driver" for iPods) // so try to see if we can match the grandparent. if ( ((uintptr_t)htab_devid.table[j].data == 0) && (CM_Get_Parent(&grandparent_inst, parent_inst, 0) == CR_SUCCESS) && (CM_Get_Device_IDA(grandparent_inst, str, MAX_PATH, 0) == CR_SUCCESS) ) { device_id = str; method_str = "[GP]"; j = htab_hash(device_id, &htab_devid); uuprintf(" Matched with (GP) ID[%03d]: %s", j, device_id); } if ((uintptr_t)htab_devid.table[j].data > 0) { uuprintf(" Matched with Hub[%d]: '%s'", (uintptr_t)htab_devid.table[j].data, dev_if_path.String[(uintptr_t)htab_devid.table[j].data]); if (GetUSBProperties(dev_if_path.String[(uintptr_t)htab_devid.table[j].data], device_id, &props)) method_str = ""; #ifdef FORCED_DEVICE props.vid = FORCED_VID; props.pid = FORCED_PID; safe_strcpy(buffer, sizeof(buffer), FORCED_NAME); #endif } break; } } } if (props.is_VHD) { uprintf("Found VHD device '%s'", buffer); } else { if ((props.vid == 0) && (props.pid == 0)) { if (is_SCSI) { // If we have an SCSI drive and couldn't get a VID:PID, we are most likely // dealing with a system drive => eliminate it! uuprintf(" Non USB => Eliminated"); continue; } safe_strcpy(str, sizeof(str), "????:????"); // Couldn't figure VID:PID } else { static_sprintf(str, "%04X:%04X", props.vid, props.pid); } if (props.speed >= USB_SPEED_MAX) props.speed = 0; uprintf("Found %s%s%s device '%s' (%s) %s\n", props.is_UASP?"UAS (":"", usb_speed_name[props.speed], props.is_UASP?")":"", buffer, str, method_str); if (props.is_LowerSpeed) uprintf("NOTE: This device is an USB 3.0 device operating at lower speed..."); } devint_data.cbSize = sizeof(devint_data); hDrive = INVALID_HANDLE_VALUE; devint_detail_data = NULL; for (j=0; ;j++) { safe_closehandle(hDrive); safe_free(devint_detail_data); if (!SetupDiEnumDeviceInterfaces(dev_info, &dev_info_data, &_GUID_DEVINTERFACE_DISK, j, &devint_data)) { if(GetLastError() != ERROR_NO_MORE_ITEMS) { uprintf("SetupDiEnumDeviceInterfaces failed: %s\n", WindowsErrorString()); } else { uprintf("A device was eliminated because it didn't report itself as a disk\n"); } break; } if (!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, NULL, 0, &size, NULL)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { devint_detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA_A)calloc(1, size); if (devint_detail_data == NULL) { uprintf("Unable to allocate data for SP_DEVICE_INTERFACE_DETAIL_DATA\n"); continue; } devint_detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A); } else { uprintf("SetupDiGetDeviceInterfaceDetail (dummy) failed: %s\n", WindowsErrorString()); continue; } } if (devint_detail_data == NULL) { uprintf("SetupDiGetDeviceInterfaceDetail (dummy) - no data was allocated\n"); continue; } if(!SetupDiGetDeviceInterfaceDetailA(dev_info, &devint_data, devint_detail_data, size, &size, NULL)) { uprintf("SetupDiGetDeviceInterfaceDetail (actual) failed: %s\n", WindowsErrorString()); continue; } hDrive = CreateFileA(devint_detail_data->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if(hDrive == INVALID_HANDLE_VALUE) { uprintf("Could not open '%s': %s\n", devint_detail_data->DevicePath, WindowsErrorString()); continue; } drive_number = GetDriveNumber(hDrive, devint_detail_data->DevicePath); if (drive_number < 0) continue; drive_index = drive_number + DRIVE_INDEX_MIN; if (!IsMediaPresent(drive_index)) { uprintf("Device eliminated because it appears to contain no media\n"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } if (GetDriveLabel(drive_index, drive_letters, &label)) { if ((!enable_HDDs) && (!props.is_VHD) && ((score = IsHDD(drive_index, (uint16_t)props.vid, (uint16_t)props.pid, buffer)) > 0)) { uprintf("Device eliminated because it was detected as an USB Hard Drive (score %d > 0)\n", score); uprintf("If this device is not an USB Hard Drive, please e-mail the author of this application\n"); uprintf("NOTE: You can enable the listing of USB Hard Drives in 'Advanced Options' (after clicking the white triangle)"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } // The empty string is returned for drives that don't have any volumes assigned if (drive_letters[0] == 0) { entry = lmprintf(MSG_046, label, drive_number, SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units)); } else { // Find the UEFI:TOGO partition(s) (and eliminate them form our listing) for (k=0; drive_letters[k]; k++) { uefi_togo_check[0] = drive_letters[k]; if (PathFileExistsA(uefi_togo_check)) { for (l=k; drive_letters[l]; l++) drive_letters[l] = drive_letters[l+1]; k--; } } // We have multiple volumes assigned to the same device (multiple partitions) // If that is the case, use "Multiple Volumes" instead of the label safe_strcpy(entry_msg, sizeof(entry_msg), (((drive_letters[0] != 0) && (drive_letters[1] != 0))? lmprintf(MSG_047):label)); for (k=0, remove_drive=0; drive_letters[k] && (!remove_drive); k++) { // Append all the drive letters we detected letter_name[2] = drive_letters[k]; if (right_to_left_mode) safe_strcat(entry_msg, sizeof(entry_msg), RIGHT_TO_LEFT_MARK); safe_strcat(entry_msg, sizeof(entry_msg), letter_name); if (drive_letters[k] == (PathGetDriveNumberU(app_dir) + 'A')) remove_drive = 1; if (drive_letters[k] == (PathGetDriveNumberU(system_dir) + 'A')) remove_drive = 2; } // Make sure that we don't list any drive that should not be listed if (remove_drive) { uprintf("Removing %C: from the list: This is the %s!", drive_letters[--k], (remove_drive==1)?"disk from which " APPLICATION_NAME " is running":"system disk"); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } safe_sprintf(&entry_msg[strlen(entry_msg)], sizeof(entry_msg) - strlen(entry_msg), "%s [%s]", (right_to_left_mode)?RIGHT_TO_LEFT_MARK:"", SizeToHumanReadable(GetDriveSize(drive_index), FALSE, use_fake_units)); entry = entry_msg; } // Must ensure that the combo box is UNSORTED for indexes to be the same StrArrayAdd(&DriveID, buffer); StrArrayAdd(&DriveLabel, label); IGNORE_RETVAL(ComboBox_SetItemData(hDeviceList, ComboBox_AddStringU(hDeviceList, entry), drive_index)); maxwidth = max(maxwidth, GetEntryWidth(hDeviceList, entry)); safe_closehandle(hDrive); safe_free(devint_detail_data); break; } } } SetupDiDestroyDeviceInfoList(dev_info); // Adjust the Dropdown width to the maximum text size SendMessage(hDeviceList, CB_SETDROPPEDWIDTH, (WPARAM)maxwidth, 0); if (devnum >= DRIVE_INDEX_MIN) { for (i=0; i<ComboBox_GetCount(hDeviceList); i++) { if ((DWORD)ComboBox_GetItemData(hDeviceList, i) == devnum) { found = TRUE; break; } } } if (!found) i = 0; IGNORE_RETVAL(ComboBox_SetCurSel(hDeviceList, i)); SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_DEVICE, 0); SendMessage(hMainDialog, WM_COMMAND, (CBN_SELCHANGE<<16) | IDC_FILESYSTEM, ComboBox_GetCurSel(hFileSystem)); r = TRUE; out: // Set 'Start' as the selected button, so that tab selection works SendMessage(hMainDialog, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hMainDialog, IDC_START), TRUE); safe_free(devid_list); StrArrayDestroy(&dev_if_path); htab_destroy(&htab_devid); return r; }
int hidOpenDevice( unsigned short vendor, unsigned short product, hidlib_t *outHidhandle ) { HDEVINFO deviceInfoList; SP_DEVICE_INTERFACE_DATA deviceInfo; SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; DWORD size; int i; HANDLE handle = INVALID_HANDLE_VALUE; char matchName[64]; int matchLength; int matchOffset = 4; int error = HIDLIB_OK; *outHidhandle = (hidlib_t)INVALID_HANDLE_VALUE; sprintf( matchName, "hid#vid_%04x&pid_%04x", vendor, product ); matchLength = strlen( matchName ); deviceInfoList = SetupDiGetClassDevs( &hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE ); if( deviceInfoList == NULL ) { return HIDLIB_ERR_INTERNAL; } deviceInfo.cbSize = sizeof(deviceInfo); for( i=0; ; i++ ) { if( handle != INVALID_HANDLE_VALUE ) { CloseHandle( handle ); handle = INVALID_HANDLE_VALUE; } if( !SetupDiEnumDeviceInterfaces( deviceInfoList, 0, &hidGuid, i, &deviceInfo ) ) { error = HIDLIB_ERR_NOT_FOUND; break; } size = 0; if( !SetupDiGetDeviceInterfaceDetail( deviceInfoList, &deviceInfo, NULL, 0, &size, NULL ) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { error = HIDLIB_ERR_INTERNAL; break; } deviceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA *)malloc( size ); if( deviceDetails == NULL ) { error = HIDLIB_ERR_OUT_OF_MEMORY; } deviceDetails->cbSize = sizeof(*deviceDetails); if( SetupDiGetDeviceInterfaceDetail( deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL ) ) { if( strlen( deviceDetails->DevicePath ) > matchOffset + matchLength && memcmp( deviceDetails->DevicePath+4, matchName, matchLength ) == 0 ) { handle = CreateFile( deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); } } free( deviceDetails ); if( handle == INVALID_HANDLE_VALUE ) { // Cannot open device. Probably a standard HID device, in which // case Windows already has the device open. continue; } // We found the device we are looking for! error = HIDLIB_OK; break; } SetupDiDestroyDeviceInfoList( deviceInfoList ); if( handle != INVALID_HANDLE_VALUE ) { *outHidhandle = (hidlib_t)handle; return 0; } else { return error; } }
bool HidDevice::connect(const QString& DeviceID) //example DeviceID: "Vid_04d8&Pid_003F" { WriteHandle = INVALID_HANDLE_VALUE; ReadHandle = INVALID_HANDLE_VALUE; /* Before we can "connect" our application to our USB embedded device, we must first find the device. A USB bus can have many devices simultaneously connected, so somehow we have to find our device, and only our device. This is done with the Vendor ID (VID) and Product ID (PID). Each USB product line should have a unique combination of VID and PID. Microsoft has created a number of functions which are useful for finding plug and play devices. Documentation for each function used can be found in the MSDN library. We will be using the following functions: SetupDiGetClassDevs() //provided by setupapi.dll, which comes with Windows SetupDiEnumDeviceInterfaces() //provided by setupapi.dll, which comes with Windows GetLastError() //provided by kernel32.dll, which comes with Windows SetupDiDestroyDeviceInfoList() //provided by setupapi.dll, which comes with Windows SetupDiGetDeviceInterfaceDetail() //provided by setupapi.dll, which comes with Windows SetupDiGetDeviceRegistryProperty() //provided by setupapi.dll, which comes with Windows malloc() //part of C runtime library, msvcrt.dll? CreateFile() //provided by kernel32.dll, which comes with Windows We will also be using the following unusual data types and structures. Documentation can also be found in the MSDN library: PSP_DEVICE_INTERFACE_DATA PSP_DEVICE_INTERFACE_DETAIL_DATA SP_DEVINFO_DATA HDEVINFO HANDLE GUID The ultimate objective of the following code is to call CreateFile(), which opens a communications pipe to a specific device (such as a HID class USB device endpoint). CreateFile() returns a "handle" which is needed later when calling ReadFile() or WriteFile(). These functions are used to actually send and receive application related data to/from the USB peripheral device. However, in order to call CreateFile(), we first need to get the device path for the USB device with the correct VID and PID. Getting the device path is a multi-step round about process, which requires calling several of the SetupDixxx() functions provided by setupapi.dll. */ //Globally Unique Identifier (GUID) for HID class devices. Windows uses GUIDs to identify things. GUID InterfaceClassGuid = {0x4d1e55b2, 0xf16f, 0x11cf, 0x88, 0xcb, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30}; HDEVINFO DeviceInfoTable = INVALID_HANDLE_VALUE; PSP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA; PSP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA; SP_DEVINFO_DATA DevInfoData; DWORD InterfaceIndex = 0; DWORD dwRegType; DWORD dwRegSize; DWORD StructureSize = 0; bool success = false; //First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID. DeviceInfoTable = SetupDiGetClassDevs(&InterfaceClassGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); //Now look through the list we just populated. We are trying to see if any of them match our device. while(true) { InterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); SetupDiEnumDeviceInterfaces(DeviceInfoTable, NULL, &InterfaceClassGuid, InterfaceIndex, InterfaceDataStructure); //ErrorStatus = GetLastError(); if(ERROR_NO_MORE_ITEMS == GetLastError()) //Did we reach the end of the list of matching devices in the DeviceInfoTable? { //Cound not find the device. Must not have been attached. SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. return false; } //Now retrieve the hardware ID from the registry. The hardware ID contains the VID and PID, which we will then //check to see if it is the correct device or not. //Initialize an appropriate SP_DEVINFO_DATA structure. We need this structure for SetupDiGetDeviceRegistryProperty(). DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, &DevInfoData); //First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data. SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, NULL, 0, &dwRegSize); //Allocate a buffer for the hardware ID. QByteArray byteArrayBuffer(dwRegSize, 0); //Retrieve the hardware IDs for the current device we are looking at. PropertyValueBuffer gets filled with a //REG_MULTI_SZ (array of null terminated strings). To find a device, we only care about the very first string in the //buffer, which will be the "device ID". The device ID is a string which contains the VID and PID, in the example //format "Vid_04d8&Pid_003f". QString DeviceIDFromRegistry = ""; if(SetupDiGetDeviceRegistryProperty(DeviceInfoTable, &DevInfoData, SPDRP_HARDWAREID, &dwRegType, (BYTE*)(byteArrayBuffer.data()), dwRegSize, NULL)){ DeviceIDFromRegistry = QString((const QChar*)(byteArrayBuffer.constData()), byteArrayBuffer.size() / 2 - 1).toLower(); qDebug(DeviceIDFromRegistry.toAscii()); } //Now check if the hardware ID we are looking at contains the correct VID/PID if(DeviceIDFromRegistry.contains(DeviceID.toLower())) { //Device must have been found. Open read and write handles. In order to do this, we will need the actual device path first. //We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice: The first //time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually //get the structure (after we have allocated enough memory for the structure.) DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //First call populates "StructureSize" with the correct value SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure, NULL, NULL, &StructureSize, NULL); DetailedInterfaceDataStructure = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(malloc(StructureSize)); //Allocate enough memory if(DetailedInterfaceDataStructure == NULL) //if null, error, couldn't allocate enough memory { //Can't really recover from this situation, just exit instead. SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. return false; } DetailedInterfaceDataStructure->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); //Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the goods. SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, InterfaceDataStructure, DetailedInterfaceDataStructure, StructureSize, NULL, NULL); //We now have the proper device path, and we can finally open read and write handles to the device. //We store the handles in the global variables "WriteHandle" and "ReadHandle", which we will use later to actually communicate. WriteHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if(GetLastError() == ERROR_SUCCESS){ ReadHandle = CreateFile((DetailedInterfaceDataStructure->DevicePath), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if(GetLastError() == ERROR_SUCCESS){ success = true; qDebug("HID Connect OK"); } } SetupDiDestroyDeviceInfoList(DeviceInfoTable); //Clean up the old structure we no longer need. return success; } InterfaceIndex++; //Keep looping until we either find a device with matching VID and PID, or until we run out of items. }//end of while(true) return false; }
HANDLE SearchMatchingHwID ( USAGE myUsagePage, USAGE myUsage ) { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; SP_DEVINFO_DATA devInfoData; GUID hidguid; int i; HidD_GetHidGuid(&hidguid); hardwareDeviceInfo = SetupDiGetClassDevs ((LPGUID)&hidguid, NULL, NULL, // Define no (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE)); if (INVALID_HANDLE_VALUE == hardwareDeviceInfo) { printf("SetupDiGetClassDevs failed: %x\n", GetLastError()); return INVALID_HANDLE_VALUE; } deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); // // Enumerate devices of this interface class // printf("\n....looking for our HID device (with UP=0x%x " "and Usage=0x%x)\n", myUsagePage, myUsage); for (i = 0; SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs (LPGUID)&hidguid, i, // &deviceInterfaceData); i++) { // // Open the device interface and Check if it is our device // by matching the Usage page and Usage from Hid_Caps. // If this is our device then send the hid request. // HANDLE file = OpenDeviceInterface(hardwareDeviceInfo, &deviceInterfaceData, myUsagePage, myUsage); if (file != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return file; } // //device was not found so loop around. // } printf("Failure: Could not find our HID device \n"); SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return INVALID_HANDLE_VALUE; }
int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout) { GUID device_id; HANDLE dev; HDEVINFO device_info; int i, index; DWORD len; SP_DEVICE_INTERFACE_DATA device_data; PSP_DEVICE_INTERFACE_DETAIL_DATA detail_data = NULL; HIDD_ATTRIBUTES attr; int found = 0; (void) timeout; /* unused */ device_data.cbSize = sizeof(device_data); index = 0; /* get the device id */ HidD_GetHidGuid(&device_id); /* get all hid devices connected */ device_info = SetupDiGetClassDevs(&device_id, NULL, NULL, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT)); for (;; ++index) { if (detail_data) { free(detail_data); detail_data = NULL; } /* query the next hid device info */ if (!SetupDiEnumDeviceInterfaces(device_info, NULL, &device_id, index, &device_data)) break; /* get the size of the data block required */ i = SetupDiGetDeviceInterfaceDetail(device_info, &device_data, NULL, 0, &len, NULL); detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_A*)malloc(len); detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); /* query the data for this device */ if (!SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, len, NULL, NULL)) continue; /* open the device */ dev = CreateFile(detail_data->DevicePath, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (dev == INVALID_HANDLE_VALUE) continue; /* get device attributes */ attr.Size = sizeof(attr); i = HidD_GetAttributes(dev, &attr); if ((attr.VendorID == WM_VENDOR_ID) && (attr.ProductID == WM_PRODUCT_ID)) { /* this is a wiimote */ wm[found]->dev_handle = dev; wm[found]->hid_overlap.hEvent = CreateEvent(NULL, 1, 1, ""); wm[found]->hid_overlap.Offset = 0; wm[found]->hid_overlap.OffsetHigh = 0; WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_DEV_FOUND); WIIMOTE_ENABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); /* try to set the output report to see if the device is actually connected */ if (!wiiuse_set_report_type(wm[found])) { WIIMOTE_DISABLE_STATE(wm[found], WIIMOTE_STATE_CONNECTED); continue; } /* do the handshake */ wiiuse_handshake(wm[found], NULL, 0); WIIUSE_INFO("Connected to wiimote [id %i].", wm[found]->unid); ++found; if (found >= max_wiimotes) break; } else { /* not a wiimote */ CloseHandle(dev); } } if (detail_data) free(detail_data); SetupDiDestroyDeviceInfoList(device_info); return found; }
const T_HID_HDL* HidOpen( const char* const my_manufacturer, const char* const my_product ) { int f = 0; int i = 0; ULONG Needed, l; GUID HidGuid; HDEVINFO DeviceInfoSet; HIDD_ATTRIBUTES DeviceAttributes; SP_DEVICE_INTERFACE_DATA DevData; PSP_INTERFACE_DEVICE_DETAIL_DATA DevDetail; //SP_DEVICE_INTERFACE_DETAIL_DATA *MyDeviceInterfaceDetailData; HANDLE hHID = NULL; // USB-IO dev handle T_HID_HDL_LOCAL* libhid_handle = NULL; const int my_product_id = MY_PID; if( !hHID_DLL ) { return NULL; } DeviceAttributes.Size = sizeof(HIDD_ATTRIBUTES); DevData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); HidD_GetHidGuid( &HidGuid ); DeviceInfoSet = SetupDiGetClassDevs( &HidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); while( SetupDiEnumDeviceInterfaces( DeviceInfoSet, 0, &HidGuid, i++, &DevData ) ) { SetupDiGetDeviceInterfaceDetail( DeviceInfoSet, &DevData, NULL, 0, &Needed, 0 ); l = Needed; DevDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA *) GlobalAlloc( GPTR, l + 4 ); DevDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); SetupDiGetDeviceInterfaceDetail( DeviceInfoSet, &DevData, DevDetail, l, &Needed, 0 ); hHID = CreateFile( DevDetail->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, // FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, 0, NULL ); GlobalFree( DevDetail ); if( hHID == INVALID_HANDLE_VALUE ) { // Can't open a device continue; } HidD_GetAttributes( hHID, &DeviceAttributes ); // HIDaspかどうか調べる. if( (DeviceAttributes.VendorID == MY_VID) && (DeviceAttributes.ProductID == my_product_id) && (check_product_string( hHID, my_manufacturer, my_product ) == 1) ) { f = 1; // 発見された. libhid_handle = malloc( sizeof(T_HID_HDL_LOCAL) ); if( libhid_handle ) { libhid_handle->handle = hHID; } else { CloseHandle( hHID ); hHID = NULL; } break; } else { // 違ったら閉じる CloseHandle( hHID ); hHID = NULL; } } SetupDiDestroyDeviceInfoList( DeviceInfoSet ); return (T_HID_HDL*)libhid_handle; }
void build_volumes_v2(t_volumes & volumes) { HDEVINFO di = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE); if (di != INVALID_HANDLE_VALUE) { SP_DEVINFO_DATA did; memset(&did, 0, sizeof(did)); did.cbSize = sizeof(did); DWORD i; for (i=0; SetupDiEnumDeviceInfo(di, i, &did); i++) { if (did.ClassGuid == GUID_DEVCLASS_DISKDRIVE) { ULONG DevLen = 0, DevDiskLen=0; pfc::array_t<WCHAR> Dev, DevDisk, DevRoot; DEVINST pParent = NULL, ppParent = NULL; CM_Get_Parent_Ex(&pParent, did.DevInst, NULL, NULL); CM_Get_Parent_Ex(&ppParent, pParent, NULL, NULL); CM_Get_Device_ID_Size(&DevLen, pParent, NULL); CM_Get_Device_ID_Size(&DevDiskLen, did.DevInst, NULL); Dev.set_size(DevLen+1); Dev.fill_null(); DevDisk.set_size(DevDiskLen+1); DevDisk.fill_null(); CM_Get_Device_ID(pParent, Dev.get_ptr(), Dev.get_size(), NULL); CM_Get_Device_ID(did.DevInst, DevDisk.get_ptr(), DevDisk.get_size(), NULL); { ULONG len = 0; CM_Get_Device_ID_Size(&len, ppParent, NULL); DevRoot.set_size(len+1); DevRoot.fill_null(); CM_Get_Device_ID(ppParent, DevRoot.get_ptr(), len, NULL); } bool b_shuffle; t_ipod_model model; if (g_check_devid_is_ipod(Dev.get_ptr(), model, b_shuffle)) { pfc::array_t<WCHAR> DriverSymbolicPath; if (!wcsncmp(Dev.get_ptr(), DevRoot.get_ptr(), 7)) { ULONG len=0; CM_Get_Device_Interface_List_Size(&len, (LPGUID)&GUID_DEVINTERFACE_USBAPPL_DEVICE, DevRoot.get_ptr(), CM_GET_DEVICE_INTERFACE_LIST_PRESENT); DriverSymbolicPath.set_size(len+1); DriverSymbolicPath.fill_null(); CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_USBAPPL_DEVICE, DevRoot.get_ptr(), DriverSymbolicPath.get_ptr(), len, CM_GET_DEVICE_INTERFACE_LIST_PRESENT); //console::formatter() << pfc::stringcvt::string_utf8_from_os(buff.get_ptr()); } else { DriverSymbolicPath.set_size(1); DriverSymbolicPath.fill_null(); } { ULONG DevRemovalListSize = NULL, DevBusListSize = NULL; pfc::array_t<WCHAR> DevRemovalList, DevBusList; CM_Get_Device_ID_List_Size_Ex(&DevRemovalListSize, DevDisk.get_ptr(), CM_GETIDLIST_FILTER_REMOVALRELATIONS, NULL); CM_Get_Device_ID_List_Size_Ex(&DevBusListSize, DevDisk.get_ptr(), CM_GETIDLIST_FILTER_BUSRELATIONS, NULL); DevRemovalList.set_size(DevRemovalListSize); DevBusList.set_size(DevBusListSize); CM_Get_Device_ID_List_Ex(DevDisk.get_ptr(), DevRemovalList.get_ptr(), DevRemovalListSize, CM_GETIDLIST_FILTER_REMOVALRELATIONS, NULL); CM_Get_Device_ID_List_Ex(DevDisk.get_ptr(), DevBusList.get_ptr(), DevBusListSize, CM_GETIDLIST_FILTER_BUSRELATIONS, NULL); WCHAR * ptr = DevRemovalList.get_ptr(), *pvolume=NULL; { t_size ptrlen= NULL; while (ptr && (ptrlen = wcslen(ptr))) { if (!wcsicmp_partial(ptr, L"STORAGE\\")) { pvolume = ptr; break; } ptr+=ptrlen; ptr++; } } if (!pvolume) { ptr = DevBusList.get_ptr(); t_size ptrlen= NULL; while (ptr && (ptrlen = wcslen(ptr))) { if (!wcsicmp_partial(ptr, L"STORAGE\\")) { pvolume = ptr; break; } ptr+=ptrlen; ptr++; } } if (pvolume) { SP_DEVINFO_DATA pdid; memset(&pdid, 0, sizeof(pdid)); pdid.cbSize = sizeof(pdid); HDEVINFO pdi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);; SetupDiOpenDeviceInfo(pdi, pvolume, NULL, NULL, &pdid); { { DWORD j; SP_DEVICE_INTERFACE_DATA dia; memset(&dia, 0, sizeof(dia)); dia.cbSize = sizeof(dia); for (j=0; SetupDiEnumDeviceInterfaces(pdi, &pdid, &GUID_DEVINTERFACE_VOLUME, j, &dia); j++) { DWORD required_size = 0; pfc::array_t<t_uint8> data; SetupDiGetDeviceInterfaceDetail(pdi, &dia, NULL, NULL, &required_size, &pdid); data.set_size(required_size); data.fill_null(); if (required_size >= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)) { SP_DEVICE_INTERFACE_DETAIL_DATA * didd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)data.get_ptr(); didd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (SetupDiGetDeviceInterfaceDetail(pdi, &dia, didd, required_size, NULL, &pdid)) { pfc::array_t<WCHAR> path; t_size len = wcslen(didd->DevicePath); path.append_fromptr(didd->DevicePath, len); path.grow_size (len + sizeof(WCHAR)*2); path[len] = '\\'; path[len+1] = 0; WCHAR volumename[129]; memset(&volumename, 0, sizeof(volumename)); if (GetVolumeNameForVolumeMountPoint(path.get_ptr(), volumename, 128)) { volumes.add_item(t_volume(volumename, Dev.get_ptr(), model, b_shuffle, pParent, DriverSymbolicPath.get_ptr())); } } } } } } SetupDiDestroyDeviceInfoList(pdi); } } } } } SetupDiDestroyDeviceInfoList(di); } }