BOOL CEnumerateSerial::EnumeratePorts() { int SPDRPlist[] = { SPDRP_HARDWAREID, SPDRP_DEVICEDESC, SPDRP_FRIENDLYNAME, SPDRP_MFG, SPDRP_LOCATION_INFORMATION, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, -1}; // Clear anything from previous enumerate... ResetPortList(); // First need to convert the name "Ports" to a GUID using SetupDiClassGuidsFromName... DWORD dwGuids = 0; SetupDiClassGuidsFromName(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) return FALSE; // Allocate the needed memory... CHeapPtr<GUID> GuidArray; GUID *pGuids = (GUID*)GuidArray.Allocate(sizeof(GUID) * dwGuids); if (pGuids==NULL) { SetLastError(ERROR_OUTOFMEMORY); return FALSE; } // Call the function again... if (!SetupDiClassGuidsFromName(_T("Ports"), pGuids, dwGuids, &dwGuids)) return FALSE; // Now create a "device information set" which is required to enumerate all the ports... HDEVINFO hDevInfoSet = SetupDiGetClassDevs(pGuids, NULL, NULL, DIGCF_PRESENT); if (hDevInfoSet == INVALID_HANDLE_VALUE) return FALSE; // Finally do the enumeration... int nIndex = 0; SP_DEVINFO_DATA devInfo; CHeapPtr<TCHAR> tempstr(1000); CSerialPortInfo *portinfo = NULL; // Enumerate the current device... devInfo.cbSize = sizeof(SP_DEVINFO_DATA); while (SetupDiEnumDeviceInfo(hDevInfoSet, nIndex, &devInfo)) { portinfo = NULL; // Get the registry key which stores the ports settings... HKEY hDeviceKey = SetupDiOpenDevRegKey(hDevInfoSet, &devInfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; // Read name of port. If formatted as "COMxx" then allocate a port slot... if ((RegQueryValueEx(hDeviceKey, _T("PortName"), NULL, &dwType, reinterpret_cast<LPBYTE>((TCHAR*)tempstr), &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) if (_tcslen(tempstr) > 3) if ((_tcsnicmp(tempstr, _T("COM"), 3) == 0) && IsNumber(&(tempstr[3]))) portinfo = AddPort(_ttoi(&(tempstr[3]))); // Close the key now that we are finished with it... RegCloseKey(hDeviceKey); } // If a serial port, then try getting additional useful descriptive info... if (portinfo) { for (int i=0; SPDRPlist[i]>=0; i++) { tempstr.FillZero(); DWORD dwSize = tempstr.SizeOf(); DWORD dwType = 0; if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &devInfo, SPDRPlist[i], &dwType, reinterpret_cast<PBYTE>((TCHAR*)tempstr), dwSize, &dwSize) && ((dwType == REG_SZ) || (dwType == REG_MULTI_SZ))) switch (SPDRPlist[i]) { case SPDRP_MFG : portinfo->SetManufacturer(tempstr); break; case SPDRP_HARDWAREID : portinfo->SetHardwareID(tempstr); break; case SPDRP_DEVICEDESC : portinfo->SetDeviceDesc(tempstr); break; case SPDRP_FRIENDLYNAME : portinfo->SetFriendlyName(tempstr); break; case SPDRP_LOCATION_INFORMATION : portinfo->SetLocationInfo(tempstr); break; case SPDRP_PHYSICAL_DEVICE_OBJECT_NAME : portinfo->SetPhysLocation(tempstr); break; } } // Get COM port properties... HANDLE hPort = ::CreateFile(portinfo->GetPortDeviceName(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hPort != INVALID_HANDLE_VALUE) { COMMPROP cp; GetCommProperties(hPort, &cp); portinfo->SetCommProp(cp); TRACE ("Port %d: CommProp: maxbaud=%08x settablebaud=%08x\n",portinfo->GetPortNum(),cp.dwMaxBaud,cp.dwSettableBaud); CloseHandle(hPort); } } ++nIndex; } // Free up the "device information set" now that we are finished with it SetupDiDestroyDeviceInfoList(hDevInfoSet); // Return the success indicator return TRUE; }
static PyObject * winutil_get_removable_drives(PyObject *self, PyObject *args) { HDEVINFO hDevInfo; BOOL iterate = TRUE, ddebug = FALSE; PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetailData; DWORD i; unsigned int j; size_t length; WCHAR volume[BUFSIZE]; struct tagDrives g_drives[MAX_DRIVES]; PyObject *volumes, *key, *candidates, *pdebug = Py_False, *temp; if (!PyArg_ParseTuple(args, "|O", &pdebug)) { return NULL; } // Find all removable drives for (j = 0; j < MAX_DRIVES; j++) g_drives[j].letter = 0; if (!get_all_removable_disks(g_drives)) return NULL; volumes = PyDict_New(); if (volumes == NULL) return PyErr_NoMemory(); ddebug = PyObject_IsTrue(pdebug); hDevInfo = create_device_info_set((LPGUID)&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { Py_DECREF(volumes); return NULL; } // Enumerate through the set for (i=0; iterate; i++) { candidates = PyList_New(0); if (candidates == NULL) { Py_DECREF(volumes); return PyErr_NoMemory();} interfaceDetailData = get_device_ancestors(hDevInfo, i, candidates, &iterate, ddebug); if (interfaceDetailData == NULL) { PyErr_Print(); Py_DECREF(candidates); candidates = NULL; continue; } length = wcslen(interfaceDetailData->DevicePath); interfaceDetailData->DevicePath[length] = L'\\'; interfaceDetailData->DevicePath[length+1] = 0; if (ddebug) console_out(L"Device path: %s\n", interfaceDetailData->DevicePath); // On Vista+ DevicePath contains the information we need. temp = PyUnicode_FromWideChar(interfaceDetailData->DevicePath, length); if (temp == NULL) return PyErr_NoMemory(); PyList_Append(candidates, temp); Py_DECREF(temp); if(GetVolumeNameForVolumeMountPointW(interfaceDetailData->DevicePath, volume, BUFSIZE)) { if (ddebug) console_out(L"Volume: %s\n", volume); for(j = 0; j < MAX_DRIVES; j++) { if(g_drives[j].letter != 0 && wcscmp(g_drives[j].volume, volume)==0) { if (ddebug) printf("Found drive: %c\n", (char)g_drives[j].letter); fflush(stdout); key = PyBytes_FromFormat("%c", (char)g_drives[j].letter); if (key == NULL) return PyErr_NoMemory(); PyDict_SetItem(volumes, key, candidates); Py_DECREF(key); key = NULL; break; } } } Py_XDECREF(candidates); candidates = NULL; PyMem_Free(interfaceDetailData); } //for SetupDiDestroyDeviceInfoList(hDevInfo); return volumes; }
irecv_error_t mobiledevice_connect(irecv_client_t* client) { irecv_error_t ret; SP_DEVICE_INTERFACE_DATA currentInterface; HDEVINFO usbDevices; DWORD i; LPSTR path; irecv_client_t _client = (irecv_client_t) malloc(sizeof(struct irecv_client)); memset(_client, 0, sizeof(struct irecv_client)); // Get DFU paths usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DFU, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(!usbDevices) { return IRECV_E_UNABLE_TO_CONNECT; } currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_DFU, i, ¤tInterface); i++) { DWORD requiredSize = 0; PSP_DEVICE_INTERFACE_DETAIL_DATA details; SetupDiGetDeviceInterfaceDetail(usbDevices, ¤tInterface, NULL, 0, &requiredSize, NULL); details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize); details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(!SetupDiGetDeviceInterfaceDetail(usbDevices, ¤tInterface, details, requiredSize, NULL, NULL)) { irecv_close(_client); free(details); SetupDiDestroyDeviceInfoList(usbDevices); return IRECV_E_UNABLE_TO_CONNECT; } else { LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD)); memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD)); free(details); path = (LPSTR) malloc(requiredSize - sizeof(DWORD)); memcpy((void*) path, (void*) result, requiredSize - sizeof(DWORD)); TCHAR* pathEnd = strstr(path, "#{"); *pathEnd = '\0'; _client->DfuPath = result; break; } } SetupDiDestroyDeviceInfoList(usbDevices); // Get iBoot path usbDevices = SetupDiGetClassDevs(&GUID_DEVINTERFACE_IBOOT, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if(!usbDevices) { irecv_close(_client); return IRECV_E_UNABLE_TO_CONNECT; } currentInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for(i = 0; SetupDiEnumDeviceInterfaces(usbDevices, NULL, &GUID_DEVINTERFACE_IBOOT, i, ¤tInterface); i++) { DWORD requiredSize = 0; PSP_DEVICE_INTERFACE_DETAIL_DATA details; SetupDiGetDeviceInterfaceDetail(usbDevices, ¤tInterface, NULL, 0, &requiredSize, NULL); details = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(requiredSize); details->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(!SetupDiGetDeviceInterfaceDetail(usbDevices, ¤tInterface, details, requiredSize, NULL, NULL)) { irecv_close(_client); free(details); SetupDiDestroyDeviceInfoList(usbDevices); return IRECV_E_UNABLE_TO_CONNECT; } else { LPSTR result = (LPSTR) malloc(requiredSize - sizeof(DWORD)); memcpy((void*) result, details->DevicePath, requiredSize - sizeof(DWORD)); free(details); if(strstr(result, path) == NULL) { free(result); continue; } _client->iBootPath = result; break; } } SetupDiDestroyDeviceInfoList(usbDevices); free(path); ret = mobiledevice_openpipes(_client); if (ret != IRECV_E_SUCCESS) return ret; *client = _client; return IRECV_E_SUCCESS; }
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; }
/** * Install the VBox video driver. * * @returns TRUE on success. * @returns FALSE on failure. * @param szDriverDir The base directory where we find the INF. */ BOOL installVideoDriver(TCHAR* szDriverDir) { HDEVINFO hDevInfo; SP_DEVINSTALL_PARAMS DeviceInstallParams={0}; SP_DRVINFO_DATA drvInfoData={0}; SP_DRVINFO_DETAIL_DATA DriverInfoDetailData={0}; DWORD cbReqSize; /* Vars used for reading the INF */ HINF hInf; TCHAR szServiceSection[LINE_LEN]; INFCONTEXT serviceContext; TCHAR szServiceData[LINE_LEN]; TCHAR deviceRegStr[1000];//I'm lazy here. 1000 ought to be enough for everybody... SP_DEVINFO_DATA deviceInfoData; DWORD configFlags; HKEY hkey; DWORD disp; TCHAR regKeyName[LINE_LEN]; BOOL rc; /* Create an empty list */ hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DEVCLASS_DISPLAY, NULL); if (hDevInfo == INVALID_HANDLE_VALUE) return FALSE; memset(&DeviceInstallParams, 0, sizeof(SP_DEVINSTALL_PARAMS)); DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); rc=SetupDiGetDeviceInstallParams(hDevInfo, NULL, &DeviceInstallParams); if(!rc) return FALSE; DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); DeviceInstallParams.Flags |= DI_NOFILECOPY | /* We did our own file copying */ DI_DONOTCALLCONFIGMG | DI_ENUMSINGLEINF; /* .DriverPath specifies an inf file */ /* Path to inf file */ wsprintf(DeviceInstallParams.DriverPath, TEXT("%ws\\%ws"), szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME)); rc=SetupDiSetDeviceInstallParams(hDevInfo, NULL, &DeviceInstallParams); if(!rc) return FALSE; /* Read the drivers from the inf file */ if (!SetupDiBuildDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER)) { SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; } /* Get the first found driver. Our Inf file only contains one so this is fine */ drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); if(FALSE==SetupDiEnumDriverInfo(hDevInfo, NULL, SPDIT_CLASSDRIVER, 0, &drvInfoData)){ SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; } /* Get necessary driver details */ DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); if (!(!SetupDiGetDriverInfoDetail(hDevInfo, NULL, &drvInfoData, &DriverInfoDetailData, DriverInfoDetailData.cbSize, &cbReqSize) &&GetLastError()== ERROR_INSUFFICIENT_BUFFER) ) { SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER); SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; } hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName, NULL, INF_STYLE_WIN4, NULL); if (hInf == INVALID_HANDLE_VALUE) { SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER); SetupDiDestroyDeviceInfoList(hDevInfo); return FALSE; } /* First install the service */ wsprintf(szServiceSection, TEXT("%ws.Services"), DriverInfoDetailData.SectionName); if(!SetupFindFirstLine(hInf, szServiceSection, NULL, &serviceContext)) { /* No service line?? Can't be... */ closeAndDestroy(hDevInfo, hInf); return FALSE; } /* Get the name */ SetupGetStringField(&serviceContext, 1, szServiceData, sizeof(szServiceData), NULL); wsprintf(deviceRegStr, TEXT("Root\\LEGACY_%ws\\0000"), szServiceData); memset(&deviceInfoData, 0, sizeof(SP_DEVINFO_DATA)); deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (SetupDiOpenDeviceInfo(hDevInfo, deviceRegStr, NULL, 0, &deviceInfoData) //Check for existing ||(SetupDiCreateDeviceInfo(hDevInfo, deviceRegStr, //Create new (LPGUID) &GUID_DEVCLASS_DISPLAY, NULL, //Do we need a description here? NULL, //No user interface 0, &deviceInfoData) && SetupDiRegisterDeviceInfo(hDevInfo, &deviceInfoData, 0, NULL, NULL, NULL)) ) { /* We created a new key in the registry */ memset(&DeviceInstallParams, 0,sizeof(SP_DEVINSTALL_PARAMS)); DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); SetupDiGetDeviceInstallParams(hDevInfo, &deviceInfoData, &DeviceInstallParams); DeviceInstallParams.Flags |= DI_NOFILECOPY | //We already copied the files DI_DONOTCALLCONFIGMG | DI_ENUMSINGLEINF; //Use our INF file only /* Path to inf file */ wsprintf(DeviceInstallParams.DriverPath, TEXT("%ws\\%ws"), szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME)); SetupDiSetDeviceInstallParams(hDevInfo, &deviceInfoData, &DeviceInstallParams); if(!SetupDiBuildDriverInfoList(hDevInfo, &deviceInfoData, SPDIT_CLASSDRIVER)) { closeAndDestroy(hDevInfo, hInf); return FALSE; } drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); if (!SetupDiEnumDriverInfo(hDevInfo, &deviceInfoData, SPDIT_CLASSDRIVER, 0, &drvInfoData)) { closeAndDestroy(hDevInfo, hInf); return FALSE; } if(!SetupDiSetSelectedDriver(hDevInfo, &deviceInfoData, &drvInfoData)) { closeAndDestroy(hDevInfo, hInf); return FALSE; } if(!SetupDiInstallDevice(hDevInfo, &deviceInfoData)) { closeAndDestroy(hDevInfo, hInf); return FALSE; } } /* Make sure the device is enabled */ if (SetupDiGetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_CONFIGFLAGS, NULL, (LPBYTE) &configFlags, sizeof(DWORD), NULL) && (configFlags & CONFIGFLAG_DISABLED)) { configFlags &= ~CONFIGFLAG_DISABLED; SetupDiSetDeviceRegistryProperty(hDevInfo, &deviceInfoData, SPDRP_CONFIGFLAGS, (LPBYTE) &configFlags, sizeof(DWORD)); } wsprintf(regKeyName, TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"), szServiceData, 0); //We only have one device if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, regKeyName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hkey, &disp) == ERROR_SUCCESS) { /* Insert description */ RegSetValueEx(hkey, TEXT("Device Description"), 0, REG_SZ, (LPBYTE) DriverInfoDetailData.DrvDescription, (lstrlen(DriverInfoDetailData.DrvDescription) + 1) * sizeof(TCHAR) ); TCHAR szSoftwareSection[LINE_LEN]; wsprintf(szSoftwareSection, TEXT("%ws.SoftwareSettings"), szServiceData); if (!SetupInstallFromInfSection(NULL, hInf, szSoftwareSection, SPINST_REGISTRY, hkey, NULL, 0, NULL, NULL, NULL, NULL)) { RegCloseKey(hkey); closeAndDestroy(hDevInfo, hInf); return FALSE; } RegCloseKey(hkey); } /* Install OpenGL stuff */ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hkey, &disp) == ERROR_SUCCESS) { /* Do installation here if ever necessary. Currently there is no OpenGL stuff */ RegCloseKey(hkey); } /* Cleanup */ closeAndDestroy(hDevInfo, hInf); #if 0 /* If this key is inserted into the registry, windows will show the desktop applet on next boot. We decide in the installer if we want that so the code is disabled here. */ /* Set registry keys so windows picks up the changes */ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\NewDisplay"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hkey, &disp) == ERROR_SUCCESS) { RegCloseKey(hkey); } #endif /* We must reboot at some point */ if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\RebootNecessary"), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ | KEY_WRITE, NULL, &hkey, &disp) == ERROR_SUCCESS) { RegCloseKey(hkey); } return TRUE; }
/* * Finds information about USB HID devices using setup class API. * * The sequence of entries in array must match with what java layer expect. If a particular USB * attribute is not set in descriptor or can not be obtained "---" is placed in its place. * * The array returned will be in following sequence; transport, device node, vendor ID, * product ID, serial, product, manufacturer, USB bus number, USB device number, location. * * For an HID interface in a USB device, Windows create a device instance for the USB interface * (GUID_DEVINTERFACE_HID_DEVICE) and another device instance for the HID collection (GUID_DEVINTERFACE_HID). * This function relate HID collection device instance to its USB interface (physical USB device) through * HardwareID. A hardware ID is a vendor-defined identification string that Windows uses to match a * device to an INF file. In most cases, a device has associated with it a list of hardware IDs. * (However, there are exceptions − see Identifiers for 1394 Devices). When an enumerator reports a * list of hardware IDs for a device, the hardware IDs should be listed in order of decreasing suitability. * * This key contains symbolic links to HID device instances : * HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses\{4d1e55b2-f16f-11cf-88cb-001111000030} * * This function basically collect information from USB and HID subsystems and relate them to identify a device * and then create a unified information to be sent to java application. */ jobjectArray enumerate_usb_hid_devices(JNIEnv *env, jint vendor_to_match) { int q = 0; int i = 0; int x = 0; BOOL ret = FALSE; LONG status = 0; DWORD error_code = 0; DWORD errorVal = 0; DWORD size = 0; DWORD charbuffer_size = 0; DWORD driver_name_size = 0; ULONG buffer_size = 0; ULONG devprop_buffer_size = 0; DEVPROPTYPE proptype; DWORD regproptype; CONFIGRET cmret = 0; DEVINST firstchild = 0; DEVINST next_sibling = 0; DEVINST current_sibling = 0; struct hiddev_inst_cont_id *instidinfo; struct hiddev_instance_list hiddevinst_list = { 0 }; struct jstrarray_list list = { 0 }; DWORD hid_member_index = 0; HDEVINFO hid_dev_info_set; SP_DEVINFO_DATA hid_dev_instance; DWORD usb_member_index = 0; HDEVINFO usb_dev_info_set; SP_DEVINFO_DATA usb_dev_instance; /* size of these buffers is hardcoded in functions using them */ TCHAR buffer[1024]; TCHAR devprop_buffer[1024]; TCHAR keybuf[1024]; TCHAR charbuffer[512]; TCHAR tmpbuf[128]; char cmerror[256]; jstring usb_dev_info; jclass strClass = NULL; jobjectArray usbHidDevicesFound = NULL; /* allocate memory to hold information used during processing and returning information to caller. */ x = init_hiddev_instance_list(&hiddevinst_list, 25); if (x < 0) { return clean_throw_exp_usbenumeration(env, 0, 1, 0, E_CALLOCSTR, NULL, NULL, NULL, NULL); } /* ~~~~~~~~~~~~~ ENUMERATE ALL HID DEVICES ~~~~~~~~~~~~~ */ /* get information set for all HID devices matching the GUID. It an array of structures containing information about all attached and enumerated HID devices. */ hid_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_HID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hid_dev_info_set == INVALID_HANDLE_VALUE) { return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set); } /* enumerate all devices in this information set starting from 0th index */ hid_member_index = 0; while (1) { ZeroMemory(&hid_dev_instance, sizeof(hid_dev_instance)); hid_dev_instance.cbSize = sizeof(hid_dev_instance); /* from information set, get device by index */ ret = SetupDiEnumDeviceInfo(hid_dev_info_set, hid_member_index, &hid_dev_instance); if (ret == FALSE) { error_code = GetLastError(); if (error_code == ERROR_NO_MORE_ITEMS) { break; }else { return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set); } } /* for this device find its instance ID, for example; HID\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000 * this is variable 'Device Instance Path' in device manager. */ memset(buffer, '\0', 1024); ret = SetupDiGetDeviceInstanceId(hid_dev_info_set, &hid_dev_instance, buffer, 1024, &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 1, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set); } /* get HardwareID of this device; HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\HID\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */ memset(keybuf, '\0', 1024); _stprintf_s(keybuf, 1024, TEXT("SYSTEM\\CurrentControlSet\\Enum\\%s"), buffer); charbuffer_size = sizeof(charbuffer); memset(charbuffer, '\0', 512); status = RegGetValue(HKEY_LOCAL_MACHINE, keybuf, TEXT("HardwareID"), RRF_RT_REG_MULTI_SZ, NULL, (PVOID)charbuffer, &charbuffer_size); if (status != ERROR_SUCCESS) { return clean_throw_exp_usbenumeration(env, 1, 2, GetLastError(), NULL, NULL, &hiddevinst_list, NULL, &hid_dev_info_set); } /* save device instance and hardware id (including terminating null character) in the list for later comparision */ instidinfo = NULL; instidinfo = (struct hiddev_inst_cont_id *) malloc(sizeof(struct hiddev_inst_cont_id)); if (instidinfo == NULL) { return clean_throw_exp_usbenumeration(env, 1, 1, 0, E_MALLOCSTR, NULL, &hiddevinst_list, NULL, &hid_dev_info_set); } _tcscpy_s(instidinfo->instance, 512, buffer); _tcscpy_s(instidinfo->hwid, 512, charbuffer); insert_hiddev_instance_list(&hiddevinst_list, instidinfo); /* increment to get the next HID device instance */ hid_member_index++; } /* release HID info set as it is no longer needed */ SetupDiDestroyDeviceInfoList(hid_dev_info_set); /* allocate memory to hold information used during processing and returning information to caller. */ x = init_jstrarraylist(&list, 100); if (x < 0) { return clean_throw_exp_usbenumeration(env, 2, 1, 0, E_CALLOCSTR, NULL, &hiddevinst_list, NULL, NULL); } /* From here onwards, enumerate over all USB interfaces looking for HID interface and try to associate with its device instance and then create information that will be passed to application. */ /* ~~~~~~~~~~~~~ ENUMERATE ALL USB DEVICES ~~~~~~~~~~~~~ */ /* get information set for all usb devices matching the GUID */ usb_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (usb_dev_info_set == INVALID_HANDLE_VALUE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* enumerate all devices in this information set */ usb_member_index = 0; while (1) { ZeroMemory(&usb_dev_instance, sizeof(usb_dev_instance)); usb_dev_instance.cbSize = sizeof(usb_dev_instance); /* from information set, get device by index */ ret = SetupDiEnumDeviceInfo(usb_dev_info_set, usb_member_index, &usb_dev_instance); if (ret == FALSE) { error_code = GetLastError(); if (error_code == ERROR_NO_MORE_ITEMS) { break; }else { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } /* for this device find its instance ID (USB\VID_04D8&PID_00DF\000098037) * this is the variable 'Device Instance Path' in device manager. */ memset(buffer, '\0', sizeof(buffer)); ret = SetupDiGetDeviceInstanceId(usb_dev_info_set, &usb_dev_instance, buffer, 1024, &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* fetch and examine USB interface */ cmret = CM_Get_Child(&firstchild, usb_dev_instance.DevInst, 0); if (cmret != CR_SUCCESS) { if (cmret == CR_NO_SUCH_DEVNODE) { /* this device does not have any child, so check if this is a HID class device or not */ memset(devprop_buffer, '\0', 1024); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_CLASSGUID, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* check if this is a HID device interface, if it is not than loop back to examine next USB device */ ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}")); if (ret != 0) { usb_member_index++; continue; } /* reaching here means that the device is a HID device, so create all the information that will be passed to java layer. */ /* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however we use only 1st string from multi-string HardwareID for our matching. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID The buffer contains device instance path of USB device */ memset(keybuf, '\0', 1024); _stprintf_s(keybuf, 1024, TEXT("SYSTEM\\CurrentControlSet\\Enum\\%s"), buffer); charbuffer_size = sizeof(charbuffer); memset(charbuffer, '\0', 512); /* USB\VID_04D8&PID_00DF&REV_0101 and USB\VID_04D8&PID_00DF and so on */ status = RegGetValue(HKEY_LOCAL_MACHINE, keybuf, TEXT("HardwareID"), RRF_RT_REG_MULTI_SZ, NULL, (PVOID)charbuffer, &charbuffer_size); if (status != ERROR_SUCCESS) { return clean_throw_exp_usbenumeration(env, 3, 2, GetLastError(), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* charbuffer now contains hardwareID, cook it a little bit to enable suitable matching */ if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) { charbuffer[0] = 'H'; charbuffer[1] = 'I'; charbuffer[2] = 'D'; } for (q = 0; q < hiddevinst_list.index; q++) { /* check association between HID collection device instance and USB device instance */ ret = _tcsicmp(charbuffer, hiddevinst_list.base[q]->hwid); if (ret != 0) { continue; } /* reaching here means this HID collection belongs to this USB HID device, so glean information to be passed to java layer. */ /* TRANSPORT */ usb_dev_info = (*env)->NewStringUTF(env, "USB"); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* DEVICE NODE */ usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB-IF VENDOR ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 0; while (buffer[x] != '\0') { if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '&') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB product ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 6; while (buffer[x] != '\0') { if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '\\') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* SERIAL NUMBER */ x++; i = 0; while (buffer[x] != '\0') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* PRODUCT (iProduct field of USB device descriptor) */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { /* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */ ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { /* if second attempt fails, throw error, we need to investigate drivers/firmware etc */ return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); /* MANUFACTURER */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); /* LOCATION (Location paths + Location info, get separately and then create a single string) */ // PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3) memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } // Port_#0003.Hub_#0001 memset(charbuffer, '\0', sizeof(charbuffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, ®proptype, (BYTE *)charbuffer, sizeof(charbuffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } i = 0; x = (int)_tcslen(devprop_buffer); devprop_buffer[x] = '-'; x++; for (i = 0; i < (int)_tcslen(charbuffer); i++) { devprop_buffer[x] = charbuffer[i]; x++; } devprop_buffer[x] = '\0'; usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); } /* loop back to get next USB device */ usb_member_index++; continue; }else { /* error happend when getting child of USB device */ _snprintf_s(cmerror, 256, 256, "CM_Get_Child failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } /* reaching here means that this USB device has at-least one child device node, examine first child now */ devprop_buffer_size = sizeof(devprop_buffer); memset(devprop_buffer, '\0', 1024); cmret = CM_Get_DevNode_Registry_Property(firstchild, CM_DRP_CLASSGUID, &proptype, (PVOID)devprop_buffer, &devprop_buffer_size, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_DevNode_Registry_Property failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* check if first child is a HID device interface */ ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}")); if (ret == 0) { /* reaching here means that this sibling (interface) is a HID type, get its device instance path */ memset(devprop_buffer, '\0', 1024); cmret = CM_Get_Device_ID(firstchild, devprop_buffer, 1024, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however we use only 1st string from multi-string HardwareID for our matching. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */ memset(charbuffer, '\0', 512); buffer_size = sizeof(charbuffer); cmret = CM_Get_DevNode_Registry_Property(firstchild, CM_DRP_HARDWAREID, NULL, (PVOID)charbuffer, &buffer_size, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) { charbuffer[0] = 'H'; charbuffer[1] = 'I'; charbuffer[2] = 'D'; } for (q = 0; q < hiddevinst_list.index; q++) { /* check association between HID collection device instance and USB interface device instance */ ret = _tcsncicmp(charbuffer, hiddevinst_list.base[q]->hwid, 512); if (ret != 0) { continue; } /* reaching here means this HID collection belongs to this USB HID interface, so glean information to be passed to java layer. */ /* TRANSPORT */ usb_dev_info = (*env)->NewStringUTF(env, "USB"); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* DEVICE NODE */ usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB-IF VENDOR ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 0; while (buffer[x] != '\0') { if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '&') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB product ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 6; while (buffer[x] != '\0') { if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '\\') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* SERIAL NUMBER */ x++; i = 0; while (buffer[x] != '\0') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* PRODUCT (iProduct field of USB device descriptor) */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { /* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */ ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { /* if second attempt fails, throw error, we need to investigate drivers/firmware etc */ return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); /* MANUFACTURER */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); /* LOCATION (Location paths + Location info, get separately and then create a single string) */ // PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3) memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } // Port_#0003.Hub_#0001 memset(charbuffer, '\0', sizeof(charbuffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, ®proptype, (BYTE *)charbuffer, sizeof(charbuffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } i = 0; x = (int)_tcslen(devprop_buffer); devprop_buffer[x] = '-'; x++; for (i = 0; i < (int)_tcslen(charbuffer); i++) { devprop_buffer[x] = charbuffer[i]; x++; } devprop_buffer[x] = '\0'; usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); } } /* check if this usb device has more than one interface. if it has enumerate over each one by one and collecting information for every HID interface found and sending it to java layer. */ current_sibling = firstchild; while (1) { cmret = CM_Get_Sibling(&next_sibling, current_sibling, 0); if (cmret != CR_SUCCESS) { if (cmret == CR_NO_SUCH_DEVNODE) { /* done iterating over all interfaces, move to next examine next USB device */ break; }else { _snprintf_s(cmerror, 256, 256, "CM_Get_Sibling failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } /* reaching here means USB device has more than 1 interfaces, get class of this interface (sibling) */ devprop_buffer_size = sizeof(devprop_buffer); memset(devprop_buffer, '\0', sizeof(devprop_buffer)); cmret = CM_Get_DevNode_Registry_Property(next_sibling, CM_DRP_CLASSGUID, &proptype, (VOID *)devprop_buffer, &devprop_buffer_size, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_DevNode_Registry_Property failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* check if this is a HID device interface */ ret = _tcsicmp(devprop_buffer, TEXT("{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}")); if (ret != 0) { /* this is not HID interface, move to check next interface */ current_sibling = next_sibling; continue; } /* reaching here means that this sibling (interface) is a HID type, get its device instance path */ memset(devprop_buffer, '\0', 1024); cmret = CM_Get_Device_ID(next_sibling, devprop_buffer, 1024, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } /* get the HardwareID of this USB HID interface. HardwareID is multi-sz, however we use only 1st string from multi-string HardwareID for our matching. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_04D8&PID_00DF&MI_02\7&33842C3F&0&0000\HardwareID */ memset(charbuffer, '\0', 512); buffer_size = sizeof(charbuffer); cmret = CM_Get_DevNode_Registry_Property(next_sibling, CM_DRP_HARDWAREID, NULL, (PVOID)charbuffer, &buffer_size, 0); if (cmret != CR_SUCCESS) { _snprintf_s(cmerror, 256, 256, "CM_Get_Device_ID failed with CR_xxxx error code : 0x%X\0", cmret); return clean_throw_exp_usbenumeration(env, 3, 1, 0, cmerror, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } if ((charbuffer[0] == 'U') && (charbuffer[1] == 'S') && (charbuffer[2] == 'B')) { charbuffer[0] = 'H'; charbuffer[1] = 'I'; charbuffer[2] = 'D'; } for (q = 0; q < hiddevinst_list.index; q++) { /* check association between HID collection device instance and USB interface device instance */ ret = _tcsncicmp(charbuffer, hiddevinst_list.base[q]->hwid, 512); if (ret != 0) { continue; } /* reaching here means this HID collection belongs to this USB HID interface, so glean information to be passed to java layer. */ /* TRANSPORT */ usb_dev_info = (*env)->NewStringUTF(env, "USB"); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* DEVICE NODE */ usb_dev_info = (*env)->NewString(env, hiddevinst_list.base[q]->instance, (jsize)_tcslen(hiddevinst_list.base[q]->instance)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB-IF VENDOR ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 0; while (buffer[x] != '\0') { if ((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '&') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* USB product ID (extracted from USB device instance for example: USB\VID_04D8&PID_00DF\000098037) */ x = 6; while (buffer[x] != '\0') { if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '\\') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; /* indicate end of string */ usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* SERIAL NUMBER */ x++; i = 0; while (buffer[x] != '\0') { tmpbuf[i] = buffer[x]; i++; x++; } tmpbuf[i] = '\0'; usb_dev_info = (*env)->NewString(env, tmpbuf, (jsize)_tcslen(tmpbuf)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWSTRUTFSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } insert_jstrarraylist(&list, usb_dev_info); /* PRODUCT (iProduct field of USB device descriptor) */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { /* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */ ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { /* if second attempt fails, throw error, we need to investigate drivers/firmware etc */ return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); }else { usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); } /* MANUFACTURER */ memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size, 0); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); /* LOCATION (Location paths + Location info, get separately and then create a single string) */ // PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(3) memset(devprop_buffer, '\0', sizeof(devprop_buffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, ®proptype, (BYTE *)devprop_buffer, sizeof(devprop_buffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } // Port_#0003.Hub_#0001 memset(charbuffer, '\0', sizeof(charbuffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, ®proptype, (BYTE *)charbuffer, sizeof(charbuffer), &size); if (ret == FALSE) { return clean_throw_exp_usbenumeration(env, 3, 2, HRESULT_FROM_SETUPAPI(GetLastError()), NULL, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } i = 0; x = (int)_tcslen(devprop_buffer); devprop_buffer[x] = '-'; x++; for (i = 0; i < (int)_tcslen(charbuffer); i++) { devprop_buffer[x] = charbuffer[i]; x++; } devprop_buffer[x] = '\0'; usb_dev_info = (*env)->NewString(env, devprop_buffer, (jsize)_tcslen(devprop_buffer)); insert_jstrarraylist(&list, usb_dev_info); } /* set this sibling as base sibling for fetching next sibling, loop over to get and check next interface (sibling) */ current_sibling = next_sibling; } /* increment to get and examine the next usb device for HID class */ usb_member_index++; } strClass = (*env)->FindClass(env, JAVALSTRING); if ((strClass == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_FINDCLASSSSTRINGSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } usbHidDevicesFound = (*env)->NewObjectArray(env, (jsize)list.index, strClass, NULL); if ((usbHidDevicesFound == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_NEWOBJECTARRAYSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } for (x = 0; x < list.index; x++) { (*env)->SetObjectArrayElement(env, usbHidDevicesFound, x, list.base[x]); if ((*env)->ExceptionOccurred(env)) { return clean_throw_exp_usbenumeration(env, 3, 1, 0, E_SETOBJECTARRAYSTR, &list, &hiddevinst_list, &usb_dev_info_set, NULL); } } /* clean up and return result to java layer application */ free_jstrarraylist(&list); free_hiddev_instance_list(&hiddevinst_list); SetupDiDestroyDeviceInfoList(usb_dev_info_set); return usbHidDevicesFound; }
ULONG GetSymbolicLink(void) { //OutputDebugString("GetSymbolicLink\r\n"); int found_index = 0; HDEVINFO hDevInfo; // obtain a handle to device information set for all // kernel streaming audio devices present on the system hDevInfo = SetupDiGetClassDevs( &CamacGuid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (hDevInfo == INVALID_HANDLE_VALUE) { // function returned 0 // No audio devices are present on the system return 0; } else { TCHAR HardwareID[512]; USHORT found_index = 0; // Enumerate first device of our class. SP_DEVICE_INTERFACE_DATA ifdata; ifdata.cbSize = sizeof(ifdata); for ( DWORD devindex = 0; SetupDiEnumInterfaceDevice(hDevInfo, NULL,&CamacGuid, devindex, &ifdata); ++devindex ) { // Determine the symbolic link name for this device instance. Since // this is variable in length, make an initial call to determine // the required length. DWORD needed; SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifdata, NULL, 0, &needed, NULL); // this call determines the size of memory to allocate PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed); // zero the structure memset (detail,0,needed); // set the size of the structure without the string at the end detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); SP_DEVINFO_DATA did = {sizeof(SP_DEVINFO_DATA)}; SetupDiGetDeviceInterfaceDetail(hDevInfo, &ifdata, detail, needed, NULL, &did); // Determine the device's link name SetupDiGetDeviceRegistryProperty(hDevInfo, &did,SPDRP_HARDWAREID, NULL, (PBYTE) HardwareID, sizeof(HardwareID), NULL); memset(symbolic_link, 0, sizeof(symbolic_link)); strncpy(symbolic_link, detail->DevicePath, sizeof(symbolic_link)); free((PVOID) detail); ifdata.cbSize = sizeof(ifdata); // reinitialize for next use } SetupDiDestroyDeviceInfoList(hDevInfo); } return found_index; }
/** @brief detect devices based on usb pid / vid. * @return list with usb VID / PID values. */ QMap<uint32_t, QString> System::listUsbDevices(void) { QMap<uint32_t, QString> usbids; // usb pid detection LOG_INFO() << "Searching for USB devices"; #if defined(Q_OS_LINUX) #if defined(LIBUSB1) libusb_device **devs; if(libusb_init(NULL) != 0) { LOG_ERROR() << "Initializing libusb-1 failed."; return usbids; } if(libusb_get_device_list(NULL, &devs) < 1) { LOG_ERROR() << "Error getting device list."; return usbids; } libusb_device *dev; int i = 0; while((dev = devs[i++]) != NULL) { QString name; unsigned char buf[256]; uint32_t id; struct libusb_device_descriptor descriptor; if(libusb_get_device_descriptor(dev, &descriptor) == 0) { id = descriptor.idVendor << 16 | descriptor.idProduct; libusb_device_handle *dh; if(libusb_open(dev, &dh) == 0) { libusb_get_string_descriptor_ascii(dh, descriptor.iManufacturer, buf, 256); name += QString::fromLatin1((char*)buf) + " "; libusb_get_string_descriptor_ascii(dh, descriptor.iProduct, buf, 256); name += QString::fromLatin1((char*)buf); libusb_close(dh); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO("USB: 0x%08x, %s", id, name.toLocal8Bit().data()); } } } libusb_free_device_list(devs, 1); libusb_exit(NULL); #else usb_init(); usb_find_busses(); usb_find_devices(); struct usb_bus *b; b = usb_busses; while(b) { if(b->devices) { struct usb_device *u; u = b->devices; while(u) { uint32_t id; id = u->descriptor.idVendor << 16 | u->descriptor.idProduct; // get identification strings usb_dev_handle *dev; QString name; char string[256]; int res; dev = usb_open(u); if(dev) { if(u->descriptor.iManufacturer) { res = usb_get_string_simple(dev, u->descriptor.iManufacturer, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string) + " "; } if(u->descriptor.iProduct) { res = usb_get_string_simple(dev, u->descriptor.iProduct, string, sizeof(string)); if(res > 0) name += QString::fromLatin1(string); } usb_close(dev); } if(name.isEmpty()) name = tr("(no description available)"); if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } u = u->next; } } b = b->next; } #endif #endif #if defined(Q_OS_MACX) kern_return_t result = KERN_FAILURE; CFMutableDictionaryRef usb_matching_dictionary; io_iterator_t usb_iterator = IO_OBJECT_NULL; usb_matching_dictionary = IOServiceMatching(kIOUSBDeviceClassName); result = IOServiceGetMatchingServices(kIOMasterPortDefault, usb_matching_dictionary, &usb_iterator); if(result) { LOG_ERROR() << "USB: IOKit: Could not get matching services."; return usbids; } io_object_t usbCurrentObj; while((usbCurrentObj = IOIteratorNext(usb_iterator))) { uint32_t id; QString name; /* get vendor ID */ CFTypeRef vidref = NULL; int vid = 0; vidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idVendor"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)vidref, kCFNumberIntType, &vid); CFRelease(vidref); /* get product ID */ CFTypeRef pidref = NULL; int pid = 0; pidref = IORegistryEntryCreateCFProperty(usbCurrentObj, CFSTR("idProduct"), kCFAllocatorDefault, 0); CFNumberGetValue((CFNumberRef)pidref, kCFNumberIntType, &pid); CFRelease(pidref); id = vid << 16 | pid; /* get product vendor */ char vendor_buf[256]; CFIndex vendor_buflen = 256; CFTypeRef vendor_name_ref = NULL; vendor_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Vendor Name"), kCFAllocatorDefault, 0); if(vendor_name_ref != NULL) { CFStringGetCString((CFStringRef)vendor_name_ref, vendor_buf, vendor_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(vendor_buf) + " "; CFRelease(vendor_name_ref); } else { name += QObject::tr("(unknown vendor name) "); } /* get product name */ char product_buf[256]; CFIndex product_buflen = 256; CFTypeRef product_name_ref = NULL; product_name_ref = IORegistryEntrySearchCFProperty(usbCurrentObj, kIOServicePlane, CFSTR("USB Product Name"), kCFAllocatorDefault, 0); if(product_name_ref != NULL) { CFStringGetCString((CFStringRef)product_name_ref, product_buf, product_buflen, kCFStringEncodingUTF8); name += QString::fromUtf8(product_buf); CFRelease(product_name_ref); } else { name += QObject::tr("(unknown product name)"); } if(id) { usbids.insertMulti(id, name); LOG_INFO() << "USB:" << QString("0x%1").arg(id, 8, 16) << name; } } IOObjectRelease(usb_iterator); #endif #if defined(Q_OS_WIN32) HDEVINFO deviceInfo; SP_DEVINFO_DATA infoData; DWORD i; // Iterate over all devices // by doing it this way it's unneccessary to use GUIDs which might be not // present in current MinGW. It also seemed to be more reliably than using // a GUID. // See KB259695 for an example. deviceInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); infoData.cbSize = sizeof(SP_DEVINFO_DATA); for(i = 0; SetupDiEnumDeviceInfo(deviceInfo, i, &infoData); i++) { DWORD data; LPTSTR buffer = NULL; DWORD buffersize = 0; QString description; // get device desriptor first // for some reason not doing so results in bad things (tm) while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_DEVICEDESC, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } description = QString::fromWCharArray(buffer); // now get the hardware id, which contains PID and VID. while(!SetupDiGetDeviceRegistryProperty(deviceInfo, &infoData, SPDRP_HARDWAREID, &data, (PBYTE)buffer, buffersize, &buffersize)) { if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if(buffer) free(buffer); // double buffer size to avoid problems as per KB888609 buffer = (LPTSTR)malloc(buffersize * 2); } else { break; } } unsigned int vid, pid; // convert buffer text to upper case to avoid depending on the case of // the keys (W7 uses different casing than XP at least). int len = _tcslen(buffer); while(len--) buffer[len] = _totupper(buffer[len]); if(_stscanf(buffer, _TEXT("USB\\VID_%x&PID_%x"), &vid, &pid) == 2) { uint32_t id; id = vid << 16 | pid; usbids.insert(id, description); LOG_INFO("USB VID: %04x, PID: %04x", vid, pid); } if(buffer) free(buffer); } SetupDiDestroyDeviceInfoList(deviceInfo); #endif return usbids; }
/// <summary> /// Get physical device paths. /// </summary> /// <param name="drives">Found drives</param> /// <returns>Error code</returns> DWORD PhysicalDisk::GetPhysicalPaths( std::vector<std::wstring>& drives ) { HDEVINFO diskClassDevices = nullptr; GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK; SP_DEVICE_INTERFACE_DATA deviceInterfaceData = { 0 }; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = nullptr; DWORD requiredSize = 0; DWORD deviceIndex = 0; HANDLE disk = INVALID_HANDLE_VALUE; STORAGE_DEVICE_NUMBER diskNumber = { 0 }; DWORD bytesReturned = 0; // // Get the handle to the device information set for installed // disk class devices. Returns only devices that are currently // present in the system and have an enabled disk device // interface. // diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); if (diskClassDevices == INVALID_HANDLE_VALUE) return GetLastError(); ZeroMemory( &deviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA) ); deviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (; SetupDiEnumDeviceInterfaces( diskClassDevices, NULL, &diskClassDeviceInterfaceGuid, deviceIndex, &deviceInterfaceData ); ++deviceIndex) { SetupDiGetDeviceInterfaceDetailW( diskClassDevices, &deviceInterfaceData, NULL, 0, &requiredSize, NULL ); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Exit; deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc( requiredSize ); ZeroMemory( deviceInterfaceDetailData, requiredSize ); deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail( diskClassDevices, &deviceInterfaceData, deviceInterfaceDetailData, requiredSize, NULL, NULL )) goto Exit; disk = CreateFile( deviceInterfaceDetailData->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (disk == INVALID_HANDLE_VALUE) goto Exit; if (!DeviceIoControl( disk, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &diskNumber, sizeof(STORAGE_DEVICE_NUMBER), &bytesReturned, NULL )) goto Exit; CloseHandle( disk ); disk = INVALID_HANDLE_VALUE; drives.emplace_back( L"\\\\?\\PhysicalDrive" + std::to_wstring( diskNumber.DeviceNumber ) ); if (deviceInterfaceDetailData) { free( deviceInterfaceDetailData ); deviceInterfaceDetailData = nullptr; } } Exit: if (INVALID_HANDLE_VALUE != diskClassDevices) SetupDiDestroyDeviceInfoList( diskClassDevices ); if (INVALID_HANDLE_VALUE != disk) CloseHandle( disk ); if (deviceInterfaceDetailData) free( deviceInterfaceDetailData ); return GetLastError(); }
__declspec(dllexport) BOOL __stdcall GetDeviceHandle ( CONST 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; // 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++) if(SetupDiEnumDeviceInfo(hDeviceInfo, 0, &DeviceInfoData)) { //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, 0, &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_ATTRIBUTE_NORMAL, NULL); if (*hDeviceHandle == INVALID_HANDLE_VALUE) { //Error. printf("Error %d.", GetLastError()); goto done; } done: LocalFree(lpDevicePath); LocalFree(pInterfaceDetailData); bResult = SetupDiDestroyDeviceInfoList(hDeviceInfo); return bResult; }
int battery_init() { #define GBS_HASBATTERY 0x1 #define GBS_ONBATTERY 0x2 DWORD dwResult = GBS_ONBATTERY; HDEVINFO hdev = NULL; int idev = 0; BOOL b; DWORD cbRequired = 0; SP_DEVICE_INTERFACE_DATA did; hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (INVALID_HANDLE_VALUE == hdev) { //return hdev; printf("GUID_DEVCLASS_BATTERY error\n"); return -1; } for (idev = 0; idev < 100; idev++) { printf("for\n"); memset(&did, 0, sizeof(did)); did.cbSize = sizeof(did); b = SetupDiEnumDeviceInterfaces(hdev, 0, &GUID_DEVCLASS_BATTERY, idev, &did); if (!b) { break; } SetupDiGetDeviceInterfaceDetail(hdev, &did, 0, 0, &cbRequired, 0); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA) LocalAlloc(LPTR, cbRequired); if (!pdidd) { log_err("battery_init: LocalAlloc failed, size %d", cbRequired); SetupDiDestroyDeviceInfoList(hdev); return -1; } pdidd->cbSize = sizeof(*pdidd); if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0)) { // Enumerated a battery. Ask it for information. HANDLE hBattery = CreateFile(pdidd->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE != hBattery) { //printf("battery handle: %d\n", hBattery); //_bat[idev] = hBattery; _bathandle = hBattery; LocalFree(pdidd); break; } else { log_warn("battery_init: failed to open device file: %s", pdidd->DevicePath); } } else { log_warn("battery_init:SetupDiGetDeviceInterfaceDetail failed"); } LocalFree(pdidd); } // end if ERROR_INSUFFICIENT_BUFFER } // end for SetupDiDestroyDeviceInfoList(hdev); if (_bathandle != 0) { BATTERY_INFORMATION BatteryInfo; memset(&BatteryInfo, 0, sizeof(BATTERY_INFORMATION)); if (BatteryQueryInformation(_bathandle, BatteryInformation, (LPVOID)&BatteryInfo, sizeof(BatteryInfo))) { _max_capacity = (float) BatteryInfo.FullChargedCapacity; } else { log_err("battery_info: failed to retrieve the maximum capacity of the battery"); CloseHandle(_bathandle); _bathandle = 0; return -1; } battery_print_info(_bathandle); } printf("battery_init end \n"); return 0; }
BOOLEAN FindKnownHidDevices ( OUT PHID_DEVICE * HidDevices, // A array of struct _HID_DEVICE OUT PULONG NumberDevices // the length of this array. ) /*++ Routine Description: Do the required PnP things in order to find all the HID devices in the system at this time. --*/ { HDEVINFO hardwareDeviceInfo; SP_DEVICE_INTERFACE_DATA deviceInfoData; ULONG i; BOOLEAN done; PHID_DEVICE hidDeviceInst; GUID hidGuid; PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; PHID_DEVICE newHidDevices; HidD_GetHidGuid (&hidGuid); *HidDevices = NULL; *NumberDevices = 0; // // Open a handle to the plug and play dev node. // hardwareDeviceInfo = SetupDiGetClassDevs ( &hidGuid, NULL, // Define no enumerator (global) NULL, // Define no (DIGCF_PRESENT | // Only Devices present DIGCF_DEVICEINTERFACE)); // Function class devices. if (INVALID_HANDLE_VALUE == hardwareDeviceInfo) { return FALSE; } // // Take a wild guess to start // *NumberDevices = 4; done = FALSE; deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); i=0; while (!done) { *NumberDevices *= 2; if (*HidDevices) { newHidDevices = realloc (*HidDevices, (*NumberDevices * sizeof (HID_DEVICE))); if (NULL == newHidDevices) { free(*HidDevices); } *HidDevices = newHidDevices; } else { *HidDevices = calloc (*NumberDevices, sizeof (HID_DEVICE)); } if (NULL == *HidDevices) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } hidDeviceInst = *HidDevices + i; for (; i < *NumberDevices; i++, hidDeviceInst++) { if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo, 0, // No care about specific PDOs &hidGuid, i, &deviceInfoData)) { // // allocate a function class device data structure to receive the // goods about this particular device. // SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInfoData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL); // not interested in the specific dev-node predictedLength = requiredLength; functionClassDeviceData = malloc (predictedLength); if (functionClassDeviceData) { functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); ZeroMemory(functionClassDeviceData->DevicePath, sizeof(functionClassDeviceData->DevicePath)); } else { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); return FALSE; } // // Retrieve the information from Plug and Play. // if (! SetupDiGetDeviceInterfaceDetail ( hardwareDeviceInfo, &deviceInfoData, functionClassDeviceData, predictedLength, &requiredLength, NULL)) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return FALSE; } // // Open device with just generic query abilities to begin with // if (! OpenHidDevice (functionClassDeviceData -> DevicePath, FALSE, // ReadAccess - none FALSE, // WriteAccess - none FALSE, // Overlapped - no FALSE, // Exclusive - no hidDeviceInst)) { SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return FALSE; } } else { if (ERROR_NO_MORE_ITEMS == GetLastError()) { done = TRUE; break; } } } } *NumberDevices = i; SetupDiDestroyDeviceInfoList (hardwareDeviceInfo); free(functionClassDeviceData); return TRUE; }
/* * 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; 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++) { if (usb_debug) uprintf("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); 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; } if (usb_debug) uprintf(" 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; } if (usb_debug) uprintf(" 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); if (usb_debug) uprintf("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) ) { // 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); if (usb_debug) uprintf(" Matched with ID[%03d]: %s", j, device_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 ( ((uint32_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); if (usb_debug) uprintf(" Matched with (GP) ID[%03d]: %s", j, device_id); } if ((uint32_t)htab_devid.table[j].data > 0) GetUSBProperties(dev_if_path.String[(uint32_t)htab_devid.table[j].data], device_id, &props); if (usb_debug) uprintf(" Props VID:PID = %04X:%04X", props.vid, props.pid); // If previous calls still didn't succeed, try reading the VID:PID from the device_id if ((props.vid == 0) && (props.pid == 0)) { BOOL post_backslash = FALSE; method_str = "[ID]"; for (j=0, k=0; (j<strlen(device_id))&&(k<2); j++) { // The ID is in the form USB_VENDOR_BUSID\VID_xxxx&PID_xxxx\... if (device_id[j] == '\\') post_backslash = TRUE; if (!post_backslash) continue; if (device_id[j] == '_') { props.pid = (uint16_t)strtoul(&device_id[j+1], NULL, 16); if (k++==0) props.vid = props.pid; } } } } } } 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! if (usb_debug) uprintf(" 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; }
void DetectAlreadyConnectedDevices(ThreadObject* tpThreads[]) { HDEVINFO hDevInfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); SP_DEVINFO_DATA spDeviceInfoData; ZeroMemory(&spDeviceInfoData, sizeof(SP_DEVINFO_DATA)); spDeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); LPTSTR pszPropertyBuffer[BUFFER]; DWORD dwRequiredSize; DWORD dwRequiredBufferSize; DWORD dwProperyDatatype; BOOL bResult; for (DWORD dwDeviceInfoIndex = 0; SetupDiEnumDeviceInfo( hDevInfo, dwDeviceInfoIndex, &spDeviceInfoData ); dwDeviceInfoIndex++) { bResult = SetupDiGetDeviceRegistryProperty( hDevInfo, &spDeviceInfoData, SPDRP_ENUMERATOR_NAME, &dwProperyDatatype, (LPBYTE)pszPropertyBuffer, BUFFER, &dwRequiredBufferSize); if (_tcscmp((LPTSTR)pszPropertyBuffer, TEXT("USBSTOR")) == 0) { SP_DEVICE_INTERFACE_DATA spDeviceInterfaceData; ZeroMemory(&spDeviceInterfaceData, sizeof(spDeviceInterfaceData)); spDeviceInterfaceData.cbSize = sizeof(spDeviceInterfaceData); PSP_DEVICE_INTERFACE_DETAIL_DATA pspDeviceInterfaceDetailData = NULL; for (DWORD dwDeviceInterfacesIndex = 0; bResult = SetupDiEnumDeviceInterfaces( hDevInfo, &spDeviceInfoData, &GUID_DEVINTERFACE_DISK, dwDeviceInterfacesIndex++, &spDeviceInterfaceData ); dwDeviceInterfacesIndex++) { DWORD dwError = GetLastError(); if (!bResult) { if (dwError == ERROR_NO_MORE_DEVICES || dwError == ERROR_NO_MORE_ITEMS) break; } /* Get the required size for the PSP_DEVICE_INTERFACE_DETAIL_DATA structure */ bResult = SetupDiGetDeviceInterfaceDetail( hDevInfo, &spDeviceInterfaceData, NULL, 0, &dwRequiredSize, NULL ); /* Allocate that required size */ if (!bResult) { if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { pspDeviceInterfaceDetailData = new SP_DEVICE_INTERFACE_DETAIL_DATA[dwRequiredSize];//(PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, dwRequiredSize); pspDeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); } else break; } /* Get the details on that device */ bResult = SetupDiGetDeviceInterfaceDetail( hDevInfo, &spDeviceInterfaceData, pspDeviceInterfaceDetailData, dwRequiredSize, NULL, NULL ); if (bResult) { STORAGE_DEVICE_NUMBER storageDeviceNumber; ZeroMemory(&storageDeviceNumber, sizeof(STORAGE_DEVICE_NUMBER)); storageDeviceNumber.DeviceNumber = 0; DWORD dwSize = 0; /* Get the device handle */ HANDLE hDrive = CreateFile( pspDeviceInterfaceDetailData->DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (hDrive != INVALID_HANDLE_VALUE) { /* Get the device number */ bResult = DeviceIoControl( hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &storageDeviceNumber, sizeof(storageDeviceNumber), &dwSize, NULL ); if (bResult) { char cDrive = GetVolumeLabelByDiskNumber(storageDeviceNumber.DeviceNumber); if (cDrive) { int iIndex = cDrive - 'A'; printf("%c:\\ will be watched\n", cDrive); tpThreads[iIndex] = new ThreadObject(Inspection, (LPVOID)cDrive); tpThreads[iIndex]->Start(); } } } CloseHandle(hDrive); } delete pspDeviceInterfaceDetailData; } } } SetupDiDestroyDeviceInfoList(hDevInfo); }
// 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)) { auto const wm = new Wiimote; wm->devicepath = detail_data->DevicePath; bool real_wiimote = false, is_bb = false; CheckDeviceType(wm->devicepath, 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); }
DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, char* szDosDeviceName) { bool IsFloppy = (strstr(szDosDeviceName, "\\Floppy") != NULL); // who knows a better way? GUID* guid; switch (DriveType) { case DRIVE_REMOVABLE: if ( IsFloppy ) { guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY; } else { guid = (GUID*)&GUID_DEVINTERFACE_DISK; } break; case DRIVE_FIXED: guid = (GUID*)&GUID_DEVINTERFACE_DISK; break; case DRIVE_CDROM: guid = (GUID*)&GUID_DEVINTERFACE_CDROM; break; default: return 0; } // Get device interface info set handle for all devices attached to system HDEVINFO hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { return 0; } // Retrieve a context structure for a device interface of a device information set DWORD dwIndex = 0; long res; BYTE Buf[1024]; PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf; SP_DEVICE_INTERFACE_DATA spdid; SP_DEVINFO_DATA spdd; DWORD dwSize; spdid.cbSize = sizeof(spdid); while ( true ) { res = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid); if ( !res ) { break; } dwSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); // check the buffer size if ( dwSize!=0 && dwSize<=sizeof(Buf) ) { pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes! ZeroMemory(&spdd, sizeof(spdd)); spdd.cbSize = sizeof(spdd); long res = SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, pspdidd, dwSize, &dwSize, &spdd); if ( res ) { // open the disk or cdrom or floppy HANDLE hDrive = CreateFile(pspdidd->DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if ( hDrive != INVALID_HANDLE_VALUE ) { // get its device number STORAGE_DEVICE_NUMBER sdn; DWORD dwBytesReturned = 0; res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL); if ( res ) { if ( DeviceNumber == (long)sdn.DeviceNumber ) { // match the given device number with the one of the current device CloseHandle(hDrive); SetupDiDestroyDeviceInfoList(hDevInfo); return spdd.DevInst; } } CloseHandle(hDrive); } } } dwIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); return 0; }
int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int usesReportIDs) { GUID hidGuid; /* GUID for HID driver */ HDEVINFO deviceInfoList; SP_DEVICE_INTERFACE_DATA deviceInfo; SP_DEVICE_INTERFACE_DETAIL_DATA *deviceDetails = NULL; DWORD size; int i, openFlag = 0; /* may be FILE_FLAG_OVERLAPPED */ int errorCode = USB_ERROR_NOTFOUND; HANDLE handle = INVALID_HANDLE_VALUE; HIDD_ATTRIBUTES deviceAttributes; HidD_GetHidGuid(&hidGuid); deviceInfoList = SetupDiGetClassDevs(&hidGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); 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)) break; /* no more entries */ /* first do a dummy call just to determine the actual size required */ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, NULL, 0, &size, NULL); if(deviceDetails != NULL) free(deviceDetails); deviceDetails = malloc(size); deviceDetails->cbSize = sizeof(*deviceDetails); /* this call is for real: */ SetupDiGetDeviceInterfaceDetail(deviceInfoList, &deviceInfo, deviceDetails, size, &size, NULL); DEBUG_PRINT(("checking HID path \"%s\"\n", deviceDetails->DevicePath)); /* attempt opening for R/W -- we don't care about devices which can't be accessed */ handle = CreateFile(deviceDetails->DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, openFlag, NULL); if(handle == INVALID_HANDLE_VALUE){ DEBUG_PRINT(("opening failed: %d\n", (int)GetLastError())); /* errorCode = USB_ERROR_ACCESS; opening will always fail for mouse -- ignore */ continue; } deviceAttributes.Size = sizeof(deviceAttributes); HidD_GetAttributes(handle, &deviceAttributes); DEBUG_PRINT(("device attributes: vid=%d pid=%d\n", deviceAttributes.VendorID, deviceAttributes.ProductID)); if(deviceAttributes.VendorID != vendor || deviceAttributes.ProductID != product) continue; /* ignore this device */ errorCode = USB_ERROR_NOTFOUND; if(vendorName != NULL && productName != NULL){ char buffer[512]; if(!HidD_GetManufacturerString(handle, buffer, sizeof(buffer))){ DEBUG_PRINT(("error obtaining vendor name\n")); errorCode = USB_ERROR_IO; continue; } convertUniToAscii(buffer); DEBUG_PRINT(("vendorName = \"%s\"\n", buffer)); if(strcmp(vendorName, buffer) != 0) continue; if(!HidD_GetProductString(handle, buffer, sizeof(buffer))){ DEBUG_PRINT(("error obtaining product name\n")); errorCode = USB_ERROR_IO; continue; } convertUniToAscii(buffer); DEBUG_PRINT(("productName = \"%s\"\n", buffer)); if(strcmp(productName, buffer) != 0) continue; } break; /* we have found the device we are looking for! */ } SetupDiDestroyDeviceInfoList(deviceInfoList); if(deviceDetails != NULL) free(deviceDetails); if(handle != INVALID_HANDLE_VALUE){ *device = (usbDevice_t *)handle; errorCode = 0; } return errorCode; }
void * _ykusb_open_device(int vendor_id, int *product_ids, size_t pids_len) { HDEVINFO hi; SP_DEVICE_INTERFACE_DATA di; PSP_DEVICE_INTERFACE_DETAIL_DATA pi; int i, numDev = 0; LPTSTR path = 0; DWORD len, rc; HANDLE ret_handle = NULL; yk_errno = YK_EUSBERR; hi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_KEYBOARD, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hi == INVALID_HANDLE_VALUE) return NULL; di.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); for (i = 0; i < 1000; i++) { if (!SetupDiEnumDeviceInterfaces(hi, 0, &GUID_DEVINTERFACE_KEYBOARD, i, &di)) break; if (SetupDiGetDeviceInterfaceDetail(hi, &di, 0, 0, &len, 0) || GetLastError() != ERROR_INSUFFICIENT_BUFFER) break; pi = malloc (len); if (!pi) { yk_errno = YK_ENOMEM; goto done; } pi->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); rc = SetupDiGetDeviceInterfaceDetail(hi, &di, pi, len, &len, 0); if (rc) { HANDLE m_handle; m_handle = CreateFile(pi->DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); if (m_handle != INVALID_HANDLE_VALUE) { HIDD_ATTRIBUTES devInfo; if (HidD_GetAttributes(m_handle, &devInfo)) { if (devInfo.VendorID == vendor_id) { size_t j; for (j = 0; j < pids_len; j++) { if (devInfo.ProductID == product_ids[j]) { if(ret_handle == NULL) { ret_handle = m_handle; break; } else { yk_errno = YK_EMORETHANONE; ret_handle = NULL; CloseHandle (m_handle); goto done; } } } } } } if(ret_handle == NULL) { CloseHandle (m_handle); } } free (pi); } if(ret_handle != NULL) { goto done; } yk_errno = YK_ENOKEY; done: SetupDiDestroyDeviceInfoList(hi); return ret_handle; }
/* * The sequence of entries in array must match with what java layer expect (6 informations * per USB device). If a particular USB attribute is not set in descriptor or can not be * obtained "---" is placed in its place. * * Returns array of USB device's information found, empty array if no USB device is found, * NULL if an error occurs (additionally throws exception). */ jobjectArray list_usb_devices(JNIEnv *env, jint vendor_to_match) { int x = 0; int i = 0; int vid = 0; BOOL ret = FALSE; DWORD error_code = 0; DWORD size = 0; TCHAR *ptrend; DWORD usb_member_index = 0; HDEVINFO usb_dev_info_set; SP_DEVINFO_DATA usb_dev_instance; DEVPROPTYPE proptype; DWORD regproptype; TCHAR buffer[1024]; TCHAR charbuffer[1024]; struct jstrarray_list list = { 0 }; jstring usb_dev_info; jclass strClass = NULL; jobjectArray usbDevicesFound = NULL; init_jstrarraylist(&list, 50); /* get information set for all usb devices matching the GUID */ usb_dev_info_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (usb_dev_info_set == INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } /* enumerate all devices in this information set */ usb_member_index = 0; while (1) { ZeroMemory(&usb_dev_instance, sizeof(usb_dev_instance)); usb_dev_instance.cbSize = sizeof(usb_dev_instance); /* from information set, get device by index */ ret = SetupDiEnumDeviceInfo(usb_dev_info_set, usb_member_index, &usb_dev_instance); if (ret == FALSE) { error_code = GetLastError(); if (error_code == ERROR_NO_MORE_ITEMS) { break; } else { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(error_code), NULL); return NULL; } } /* for this device find its instance ID (USB\VID_04D8&PID_00DF\000098037) * this is the variable 'Device Instance Path' in device manager. */ memset(buffer, '\0', sizeof(buffer)); ret = SetupDiGetDeviceInstanceId(usb_dev_info_set, &usb_dev_instance, buffer, sizeof(buffer), &size); if (ret == FALSE) { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } /* USB-IF vendor ID, extract and match, if matched continue further otherwise loop back */ x = 0; while (buffer[x] != '\0') { if((buffer[x] == 'V') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '&') { charbuffer[i] = buffer[x]; i++; x++; } charbuffer[i] = '\0'; /* indicate end of string */ vid = (int)_tcstol(charbuffer, &ptrend, 16); if(vendor_to_match != 0) { /* we need to apply filter for identify specific vendor */ if(vid != vendor_to_match) { usb_member_index++; continue; } } usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer)); if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { (*env)->ExceptionClear(env); SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR); return NULL; } insert_jstrarraylist(&list, usb_dev_info); /* USB product ID */ x = 6; while (buffer[x] != '\0') { if ((buffer[x] == 'P') && (buffer[x + 1] == 'I') && (buffer[x + 2] == 'D') && (buffer[x + 3] == '_')) { break; } x++; } x = x + 4; i = 0; while (buffer[x] != '\\') { charbuffer[i] = buffer[x]; i++; x++; } charbuffer[i] = '\0'; usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { (*env)->ExceptionClear(env); SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR); return NULL; } insert_jstrarraylist(&list, usb_dev_info); /* SERIAL NUMBER */ x++; i = 0; while (buffer[x] != '\0') { charbuffer[i] = buffer[x]; i++; x++; } charbuffer[i] = '\0'; usb_dev_info = (*env)->NewString(env, charbuffer, (jsize) _tcslen(charbuffer)); if ((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { (*env)->ExceptionClear(env); SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_NEWSTRSTR); return NULL; } insert_jstrarraylist(&list, usb_dev_info); /* PRODUCT (idProduct field of USB device descriptor) */ memset(buffer, '\0', sizeof(buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_BusReportedDeviceDesc, &proptype, (BYTE *)buffer, sizeof(buffer), &size, 0); if (ret == FALSE) { /* fallback to SPDRP_DEVICEDESC if DEVPKEY_Device_BusReportedDeviceDesc fails */ ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_DEVICEDESC, ®proptype, (BYTE *)buffer, sizeof(buffer), &size); if (ret == FALSE) { /* if second attempt fails, throw error, we need to investigate drivers/firmware etc */ SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer)); insert_jstrarraylist(&list, usb_dev_info); }else { usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer)); insert_jstrarraylist(&list, usb_dev_info); } /* MANUFACTURER */ memset(buffer, '\0', sizeof(buffer)); ret = SetupDiGetDeviceProperty(usb_dev_info_set, &usb_dev_instance, &DEVPKEY_Device_Manufacturer, &proptype, (BYTE *)buffer, sizeof(buffer), &size, 0); if (ret == FALSE) { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } usb_dev_info = (*env)->NewString(env, buffer, (jsize) _tcslen(buffer)); insert_jstrarraylist(&list, usb_dev_info); /* LOCATION (Location paths + Location info, get separately and then create a single string) */ memset(buffer, '\0', sizeof(buffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_PATHS, ®proptype, (BYTE *)buffer, sizeof(buffer), &size); if (ret == FALSE) { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } memset(charbuffer, '\0', sizeof(charbuffer)); ret = SetupDiGetDeviceRegistryProperty(usb_dev_info_set, &usb_dev_instance, SPDRP_LOCATION_INFORMATION, ®proptype, (BYTE *)charbuffer, sizeof(charbuffer), &size); if (ret == FALSE) { SetupDiDestroyDeviceInfoList(usb_dev_info_set); free_jstrarraylist(&list); throw_serialcom_exception(env, 4, HRESULT_FROM_SETUPAPI(GetLastError()), NULL); return NULL; } i = 0; x = (int)_tcslen(buffer); buffer[x] = '-'; x++; for (i = 0; i < (int)_tcslen(charbuffer); i++) { buffer[x] = charbuffer[i]; x++; } buffer[x] = '\0'; usb_dev_info = (*env)->NewString(env, buffer, (jsize)_tcslen(buffer)); insert_jstrarraylist(&list, usb_dev_info); /* loop to get next USB device */ usb_member_index++; } SetupDiDestroyDeviceInfoList(usb_dev_info_set); strClass = (*env)->FindClass(env, JAVALSTRING); if((strClass == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { (*env)->ExceptionClear(env); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_FINDCLASSSSTRINGSTR); return NULL; } usbDevicesFound = (*env)->NewObjectArray(env, (jsize)list.index, strClass, NULL); if((usbDevicesFound == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) { (*env)->ExceptionClear(env); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_NEWOBJECTARRAYSTR); return NULL; } for (x = 0; x < list.index; x++) { (*env)->SetObjectArrayElement(env, usbDevicesFound, x, list.base[x]); if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); free_jstrarraylist(&list); throw_serialcom_exception(env, 3, 0, E_SETOBJECTARRAYSTR); return NULL; } } free_jstrarraylist(&list); return usbDevicesFound; }
//////////////////////////////////////////////////////////////////////////////// // O p e n U S B D e v i c e //////////////////////////////////////////////////////////////////////////////// HANDLE OpenUSBDevice( LPCSTR lpMfg, LPCSTR lpPdt, USB_ERROR_INFO *lpUsbErrorInfo ) { int ii; DWORD dwBytes; BOOL bFoundMfg; BOOL bFoundPdt; LPTSTR lpToken, lpWorkToken; int nDeviceIndex; HDEVINFO hDevInfo; HANDLE hUsbPrinter; char szUsb1284[1024]; GUID guidUSBDeviceSupport; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData; HINSTANCE pSetupAPI = NULL; FAR HDEVINFO ( FAR WINAPI *SetupDiGetClassDevs )(CONST GUID *, PCTSTR, HWND, DWORD); FAR BOOL ( FAR WINAPI *SetupDiEnumDeviceInterfaces )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA); FAR BOOL ( FAR WINAPI *SetupDiGetDeviceInterfaceDetail )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA); FAR BOOL ( FAR WINAPI *SetupDiDestroyDeviceInfoList )(HDEVINFO); // // The functions SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces , // SetupDiGetDeviceInterfaceDetail, SetupDiDestroyDeviceInfoList // are supported only on Windows 2000 and above and Windows 98 and above. // So link them dynamically to avoid windows errors. // pSetupAPI = LoadLibrary( "Setupapi" ); if ( pSetupAPI != NULL ) { SetupDiGetClassDevs = ( HDEVINFO ( WINAPI * )(CONST GUID *, PCTSTR, HWND, DWORD)) GetProcAddress( pSetupAPI, "SetupDiGetClassDevsA" ); if ( SetupDiGetClassDevs == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetClassDevs"); FreeLibrary( pSetupAPI ); return 0; } SetupDiEnumDeviceInterfaces = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA)) GetProcAddress( pSetupAPI, "SetupDiEnumDeviceInterfaces" ); if ( SetupDiEnumDeviceInterfaces == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiEnumDeviceInterfaces"); FreeLibrary( pSetupAPI ); return 0; } SetupDiGetDeviceInterfaceDetail = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA)) GetProcAddress( pSetupAPI, "SetupDiGetDeviceInterfaceDetailA" ); if ( SetupDiGetDeviceInterfaceDetail == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetDeviceInterfaceDetailA"); FreeLibrary( pSetupAPI ); return 0; } SetupDiDestroyDeviceInfoList = ( BOOL ( WINAPI * )(HDEVINFO)) GetProcAddress( pSetupAPI, "SetupDiDestroyDeviceInfoList" ); if ( SetupDiDestroyDeviceInfoList == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiDestroyDeviceInfoList"); FreeLibrary( pSetupAPI ); return 0; } } else { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_HANDLE; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to load Setupapi!"); return 0; } // // get a handle to the set of device information returned by the Win32 API // functions. This handle points to an object that is then operated on // by the SetupDiEnumDeviceInterfaces function. // InitError( lpUsbErrorInfo ); guidUSBDeviceSupport = GUID_CLASS_USB_DEVICE; hDevInfo = SetupDiGetClassDevs( &guidUSBDeviceSupport, NULL, NULL, 0x12 ); // TODO : Determine the constant if ( INVALID_HANDLE_VALUE == hDevInfo ) { if ( NULL != lpUsbErrorInfo ) { // get the last error from system lpUsbErrorInfo->dwSysLastError = GetLastError(); // get the system defined message FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lpUsbErrorInfo->dwSysLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpUsbErrorInfo->szSysErrorMsg, sizeof(lpUsbErrorInfo->szSysErrorMsg) / sizeof(lpUsbErrorInfo->szSysErrorMsg[0]), NULL ); } } // // // nDeviceIndex = 0; bFoundMfg = bFoundPdt = FALSE; hUsbPrinter = INVALID_HANDLE_VALUE; deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); for ( nDeviceIndex = 0; SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &guidUSBDeviceSupport, nDeviceIndex, &deviceInterfaceData ); nDeviceIndex++ ) { // // determine the amout of memory we need to allocate for the next // call to this function // dwBytes= 0; ii = SetupDiGetDeviceInterfaceDetail( hDevInfo, &deviceInterfaceData, NULL, 0, &dwBytes, NULL ); if ( 0 == dwBytes ) { // // Reinitialize the data for next pass // through this loop. // deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(dwBytes); deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // // get the device path for the current device we are enumerating over. // ii = SetupDiGetDeviceInterfaceDetail( hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData, dwBytes, &dwBytes, NULL ); if ( 0 == ii ) { // // Free DetailData struct and reinitialize the data for next pass //through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } // // get handle to the device so that we can // hUsbPrinter = CreateFile( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); // // // if ( INVALID_HANDLE_VALUE == hUsbPrinter ) { // // Free DetailData struct and reinitialize the data for next pass // through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } // // // dwBytes = 0; memset( szUsb1284, 0, sizeof(szUsb1284) ); ii = DeviceIoControl( hUsbPrinter, IOCTL_USBPRINT_GET_1284_ID, NULL, 0, szUsb1284, sizeof(szUsb1284), &dwBytes, NULL ); // // parse the PNP string returned from the device. // lpToken = strtok( szUsb1284, PNP_DELIMITOR ); while ( NULL != lpToken ) { // have the manfacturer. lpWorkToken = strstr(lpToken,MFG_TOKEN); if ( lpWorkToken != NULL ) { RTrim(lpWorkToken); if ( strcmp( lpMfg, lpWorkToken + MFG_TOKEN_LEN ) == 0 ) bFoundMfg = TRUE; } // model of the printer lpWorkToken = strstr(lpToken,MDL_TOKEN); if ( lpWorkToken != NULL ) { RTrim(lpWorkToken); if ( strcmp( lpPdt, lpWorkToken + MDL_TOKEN_LEN ) == 0 ) bFoundPdt = TRUE; } // next token lpToken = strtok( NULL, PNP_DELIMITOR ); } // // // if ( bFoundMfg && bFoundPdt ) { free(deviceInterfaceDetailData); break; } // // // CloseHandle( hUsbPrinter ); hUsbPrinter = INVALID_HANDLE_VALUE; // // Free DetailData struct and reinitialize the data for next pass // through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); } // //Destroy device information set and free all associated memory. // SetupDiDestroyDeviceInfoList(hDevInfo); // //Free setupapi library // FreeLibrary( pSetupAPI ); // // // return hUsbPrinter; }
static void SetDeviceDetails(HWND hwndDlg, LPCGUID classGUID, LPCWSTR lpcstrDescription) { HDEVINFO hInfo; DWORD dwIndex = 0; SP_DEVINFO_DATA InfoData; WCHAR szText[30]; HWND hDlgCtrls[3]; WAVEOUTCAPSW waveOut; UINT numDev; MMRESULT errCode; /* enumerate waveout devices */ numDev = waveOutGetNumDevs(); if (numDev) { do { ZeroMemory(&waveOut, sizeof(waveOut)); errCode = waveOutGetDevCapsW(dwIndex++, &waveOut, sizeof(waveOut)); if (!wcsncmp(lpcstrDescription, waveOut.szPname, min(MAXPNAMELEN, wcslen(waveOut.szPname)))) { /* set the product id */ SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_PRODUCTID, waveOut.wPid, FALSE); /* set the vendor id */ SetDlgItemInt(hwndDlg, IDC_STATIC_DSOUND_VENDORID, waveOut.wMid, FALSE); /* check if its a wdm audio driver */ if (waveOut.wPid == MM_MSFT_WDMAUDIO_WAVEOUT) SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_TYPE, WM_SETTEXT, 0, (LPARAM)L"WDM"); /* check if device is default device */ szText[0] = L'\0'; if (dwIndex - 1 == 0) /* FIXME assume default playback device is device 0 */ LoadStringW(hInst, IDS_OPTION_YES, szText, sizeof(szText)/sizeof(WCHAR)); else LoadStringW(hInst, IDS_OPTION_NO, szText, sizeof(szText)/sizeof(WCHAR)); szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; /* set default device info */ SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_STANDARD, WM_SETTEXT, 0, (LPARAM)szText); break; } }while(errCode == MMSYSERR_NOERROR && dwIndex < numDev); } dwIndex = 0; /* create the setup list */ hInfo = SetupDiGetClassDevsW(classGUID, NULL, NULL, DIGCF_PRESENT|DIGCF_PROFILE); if (hInfo == INVALID_HANDLE_VALUE) return; do { ZeroMemory(&InfoData, sizeof(InfoData)); InfoData.cbSize = sizeof(InfoData); if (SetupDiEnumDeviceInfo(hInfo, dwIndex, &InfoData)) { /* set device name */ if (SetupDiGetDeviceInstanceId(hInfo, &InfoData, szText, sizeof(szText)/sizeof(WCHAR), NULL)) SendDlgItemMessageW(hwndDlg, IDC_STATIC_DSOUND_DEVICEID, WM_SETTEXT, 0, (LPARAM)szText); /* set the manufacturer name */ if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL)) SendDlgItemMessageW(hwndDlg, IDC_STATIC_ADAPTER_PROVIDER, WM_SETTEXT, 0, (LPARAM)szText); /* FIXME * we currently enumerate only the first adapter */ hDlgCtrls[0] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DRIVER); hDlgCtrls[1] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_VERSION); hDlgCtrls[2] = GetDlgItem(hwndDlg, IDC_STATIC_DSOUND_DATE); EnumerateDrivers(hDlgCtrls, hInfo, &InfoData); break; } if (GetLastError() == ERROR_NO_MORE_ITEMS) break; dwIndex++; }while(TRUE); /* destroy the setup list */ SetupDiDestroyDeviceInfoList(hInfo); }
//////////////////////////////////////////////////////////////////////////////// // G e t U S B D e v i c e s //////////////////////////////////////////////////////////////////////////////// INT GetUSBDevices( INT nMaxDevices, USB_DEVICE_NAME *lpUsbDevices, USB_ERROR_INFO *lpUsbErrorInfo ) { int ii; DWORD dwBytes; INT nDeviceFound; HDEVINFO hDevInfo; LPTSTR lpToken, lpWorkToken; GUID guidUSBDeviceSupport; HANDLE hUsbPrinter; SP_DEVICE_INTERFACE_DATA deviceInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData; char szUsb1284[1024]; int nDeviceIndex; HINSTANCE pSetupAPI = NULL; FAR HDEVINFO ( FAR WINAPI *SetupDiGetClassDevs )(CONST GUID *, PCTSTR, HWND, DWORD); FAR BOOL ( FAR WINAPI *SetupDiEnumDeviceInterfaces )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA); FAR BOOL ( FAR WINAPI *SetupDiGetDeviceInterfaceDetail )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA); FAR BOOL ( FAR WINAPI *SetupDiDestroyDeviceInfoList )(HDEVINFO); // // The functions SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces , // SetupDiGetDeviceInterfaceDetail, SetupDiDestroyDeviceInfoList // are supported only on Windows 2000 and above and Windows 98 and above. // So link them dynamically to avoid windows errors. // pSetupAPI = LoadLibrary( "Setupapi" ); if ( pSetupAPI != NULL ) { SetupDiGetClassDevs = ( HDEVINFO ( WINAPI * )(CONST GUID *, PCTSTR, HWND, DWORD)) GetProcAddress( pSetupAPI, "SetupDiGetClassDevsA" ); if ( SetupDiGetClassDevs == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetClassDevs"); FreeLibrary( pSetupAPI ); return 0; } SetupDiEnumDeviceInterfaces = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVINFO_DATA, CONST GUID *,DWORD, PSP_DEVICE_INTERFACE_DATA)) GetProcAddress( pSetupAPI, "SetupDiEnumDeviceInterfaces" ); if ( SetupDiEnumDeviceInterfaces == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiEnumDeviceInterfaces"); FreeLibrary( pSetupAPI ); return 0; } SetupDiGetDeviceInterfaceDetail = ( BOOL ( WINAPI * )(HDEVINFO, PSP_DEVICE_INTERFACE_DATA, PSP_DEVICE_INTERFACE_DETAIL_DATA, DWORD, PDWORD, PSP_DEVINFO_DATA)) GetProcAddress( pSetupAPI, "SetupDiGetDeviceInterfaceDetailA" ); if ( SetupDiGetDeviceInterfaceDetail == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiGetDeviceInterfaceDetailA"); FreeLibrary( pSetupAPI ); return 0; } SetupDiDestroyDeviceInfoList = ( BOOL ( WINAPI * )(HDEVINFO)) GetProcAddress( pSetupAPI, "SetupDiDestroyDeviceInfoList" ); if ( SetupDiDestroyDeviceInfoList == NULL ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_FUNCTION; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to get a pointer to SetupDiDestroyDeviceInfoList"); FreeLibrary( pSetupAPI ); return 0; } } else { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_HANDLE; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : Unable to load Setupapi!"); return 0; } // // initialize local variables and initialize error // struct if a non NULL pointer was passed. // nDeviceFound = 0; if ( NULL != lpUsbErrorInfo ) InitError( lpUsbErrorInfo ); // // validate that the user passed in the number of // available USE_DEVICE_NAMES to fill with inofrmation. // if ( 0 == nMaxDevices ) { if ( NULL != lpUsbErrorInfo ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_DATA; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : nMaxDevices has a value of zero!"); } return 0; }; // // check that we can pass information back to the calling application! // if ( NULL == lpUsbDevices ) { if ( NULL != lpUsbErrorInfo ) { lpUsbErrorInfo->dwSysLastError = ERROR_INVALID_DATA; strcpy( lpUsbErrorInfo->szSysErrorMsg, "ERROR : lpUsbDevices is NULL!" ); } return 0; } // // get a handle to the set of device information returned by the Win32 API // functions. This handle points to an object that is then operated on // by the SetupDiEnumDeviceInterfaces function. // guidUSBDeviceSupport = GUID_CLASS_USB_DEVICE; hDevInfo = SetupDiGetClassDevs( &guidUSBDeviceSupport, 0, 0, 0x12); // TODO : Determine the constant if ( INVALID_HANDLE_VALUE == hDevInfo ) { if ( NULL != lpUsbErrorInfo ) { // get the last error from system lpUsbErrorInfo->dwSysLastError = GetLastError(); // get the system defined message FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lpUsbErrorInfo->dwSysLastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), lpUsbErrorInfo->szSysErrorMsg, sizeof(lpUsbErrorInfo->szSysErrorMsg) / sizeof(lpUsbErrorInfo->szSysErrorMsg[0]), NULL ); } } // // // nDeviceFound = nDeviceIndex = 0; deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); for (nDeviceIndex = 0; SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &guidUSBDeviceSupport, nDeviceIndex, &deviceInterfaceData ); nDeviceIndex++) { // // determine the amout of memory we need to allocate for the next // call to this function // dwBytes= 0; ii = SetupDiGetDeviceInterfaceDetail( hDevInfo, &deviceInterfaceData, NULL, 0, &dwBytes, NULL ); if ( 0 == dwBytes ) { // // Reinitialize the data for next pass // through this loop. // deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } //Set cbSize in the detailData structure. deviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc (dwBytes); deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); // // get the device path for the current device we are enumerating over. // ii = SetupDiGetDeviceInterfaceDetail( hDevInfo, &deviceInterfaceData, deviceInterfaceDetailData, dwBytes, &dwBytes, NULL ); if ( 0 == ii ) { // // Free DetailData struct and reinitialize the data for next pass // through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } // // get handle to the device so that we can // hUsbPrinter = CreateFile( deviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); // // // if ( INVALID_HANDLE_VALUE == hUsbPrinter ) { // // Free DetailData struct and reinitialize the data for next pass // through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); continue; } // // // dwBytes = 0; memset( szUsb1284, 0, sizeof(szUsb1284) ); ii = DeviceIoControl( hUsbPrinter, IOCTL_USBPRINT_GET_1284_ID, NULL, 0, szUsb1284, sizeof(szUsb1284), &dwBytes, NULL ); // // // CloseHandle( hUsbPrinter ); // // parse the PNP string returned from the device. // lpToken = strtok( szUsb1284, PNP_DELIMITOR ); while ( NULL != lpToken ) { // have the manfacturer. lpWorkToken = strstr(lpToken, MFG_TOKEN); if (lpWorkToken != NULL) { strcpy( lpUsbDevices[nDeviceFound].szDeviceMfg, lpWorkToken + MFG_TOKEN_LEN); RTrim( lpUsbDevices[nDeviceFound].szDeviceMfg ); } // model of the printer lpWorkToken = strstr(lpToken, MDL_TOKEN); if (lpWorkToken != NULL) { strcpy( lpUsbDevices[nDeviceFound].szDevicePdt, lpWorkToken + MDL_TOKEN_LEN ); RTrim( lpUsbDevices[nDeviceFound].szDevicePdt ); } // next token lpToken = strtok( NULL, PNP_DELIMITOR ); } // // if the we don't manage to get BOTH the manufacturer and the product // of the USB printer then don't return information back the calling code. // if ( strlen(lpUsbDevices[nDeviceFound].szDeviceMfg) + strlen(lpUsbDevices[nDeviceFound].szDevicePdt) > 1 ) { nDeviceFound++; //break after getting the number of devices requested. if (nMaxDevices == nDeviceFound) { free(deviceInterfaceDetailData); break; } } else { lpUsbDevices[nDeviceFound].szDeviceMfg[0] = lpUsbDevices[nDeviceFound].szDevicePdt[0] = 0; } // // Free DetailData struct and reinitialize the data for next pass // through this loop. // free(deviceInterfaceDetailData); deviceInterfaceData.cbSize = sizeof(deviceInterfaceData); } // //Destroy device information set and free all associated memory. // SetupDiDestroyDeviceInfoList(hDevInfo); // //Free setupapi library // FreeLibrary( pSetupAPI ); return nDeviceFound; }
/** * Do some cleanup of data we used. Called by installVideoDriver() */ void closeAndDestroy(HDEVINFO hDevInfo, HINF hInf) { SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER); SetupDiDestroyDeviceInfoList(hDevInfo); SetupCloseInfFile(hInf); }
void ofSerial::enumerateWin32Ports(){ // thanks joerg for fixes... if (bPortsEnumerated == true) return; HDEVINFO hDevInfo = NULL; SP_DEVINFO_DATA DeviceInterfaceData; int i = 0; DWORD dataType, actualSize = 0; unsigned char dataBuf[MAX_PATH + 1]; // Reset Port List nPorts = 0; // Search device set hDevInfo = SetupDiGetClassDevs((struct _GUID *)&GUID_SERENUM_BUS_ENUMERATOR,0,0,DIGCF_PRESENT); if ( hDevInfo ){ while (TRUE){ ZeroMemory(&DeviceInterfaceData, sizeof(DeviceInterfaceData)); DeviceInterfaceData.cbSize = sizeof(DeviceInterfaceData); if (!SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInterfaceData)){ // SetupDiEnumDeviceInfo failed break; } if (SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInterfaceData, SPDRP_FRIENDLYNAME, &dataType, dataBuf, sizeof(dataBuf), &actualSize)){ sprintf(portNamesFriendly[nPorts], "%s", dataBuf); portNamesShort[nPorts][0] = 0; // turn blahblahblah(COM4) into COM4 char * begin = NULL; char * end = NULL; begin = strstr((char *)dataBuf, "COM"); if (begin) { end = strstr(begin, ")"); if (end) { *end = 0; // get rid of the )... strcpy(portNamesShort[nPorts], begin); } if (nPorts++ > MAX_SERIAL_PORTS) break; } } i++; } } SetupDiDestroyDeviceInfoList(hDevInfo); bPortsEnumerated = false; }
static DEVINST GetDrivesDevInstByDeviceNumber(long DeviceNumber, UINT DriveType, LPWSTR szDosDeviceName) { GUID *guid; HDEVINFO hDevInfo; DWORD dwIndex, dwBytesReturned; BOOL bRet, IsFloppy; BYTE Buf[1024]; PSP_DEVICE_INTERFACE_DETAIL_DATA pspdidd; long res; HANDLE hDrive; STORAGE_DEVICE_NUMBER sdn; SP_DEVICE_INTERFACE_DATA spdid; SP_DEVINFO_DATA spdd; DWORD dwSize; IsFloppy = (wcsstr(szDosDeviceName, L"\\Floppy") != NULL); // is there a better way? switch (DriveType) { case DRIVE_REMOVABLE: if ( IsFloppy ) { guid = (GUID*)&GUID_DEVINTERFACE_FLOPPY; } else { guid = (GUID*)&GUID_DEVINTERFACE_DISK; } break; case DRIVE_FIXED: guid = (GUID*)&GUID_DEVINTERFACE_DISK; break; case DRIVE_CDROM: guid = (GUID*)&GUID_DEVINTERFACE_CDROM; break; default: PyErr_SetString(PyExc_ValueError, "Invalid drive type"); return 0; } // Get device interface info set handle // for all devices attached to system hDevInfo = SetupDiGetClassDevs(guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (hDevInfo == INVALID_HANDLE_VALUE) { PyErr_SetString(PyExc_ValueError, "Invalid handle value"); return 0; } // Retrieve a context structure for a device interface // of a device information set. dwIndex = 0; bRet = FALSE; pspdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buf; spdid.cbSize = sizeof(spdid); while ( TRUE ) { bRet = SetupDiEnumDeviceInterfaces(hDevInfo, NULL, guid, dwIndex, &spdid); if ( !bRet ) { break; } dwSize = 0; SetupDiGetDeviceInterfaceDetail(hDevInfo, &spdid, NULL, 0, &dwSize, NULL); if ( dwSize!=0 && dwSize<=sizeof(Buf) ) { pspdidd->cbSize = sizeof(*pspdidd); // 5 Bytes! ZeroMemory((PVOID)&spdd, sizeof(spdd)); spdd.cbSize = sizeof(spdd); res = SetupDiGetDeviceInterfaceDetail(hDevInfo, & spdid, pspdidd, dwSize, &dwSize, &spdd); if ( res ) { hDrive = CreateFile(pspdidd->DevicePath,0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if ( hDrive != INVALID_HANDLE_VALUE ) { dwBytesReturned = 0; res = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL); if ( res ) { if ( DeviceNumber == (long)sdn.DeviceNumber ) { CloseHandle(hDrive); SetupDiDestroyDeviceInfoList(hDevInfo); return spdd.DevInst; } } CloseHandle(hDrive); } } } dwIndex++; } SetupDiDestroyDeviceInfoList(hDevInfo); PyErr_SetString(PyExc_ValueError, "Invalid device number"); return 0; }
///////////////////////////////////////////////////////////////////////////////// // FindAC97Device ///////////////////////////////////////////////////////////////////////////////// // This function stores the device info and device data of the "ac97smpl" driver. // It first creates a list of all devices that have a topology filter exposed // and then searches through the list to find the device with the service // "ac97smpl". The information is stored in pspRequest. // // For simplicity we search for the service name "ac97smpl". // Alternately, one could get more information about the device or driver, // then decide if it is suitable (regardless of its name). // // Arguments: // pspRequest pointer to Property sheet page request structure. // DeviceInfoData pointer to Device info data structure. // // Return Value: // TRUE on success, otherwise FALSE. // Note: on success that we have the device list still open - we have to destroy // the list later. The handle is stored at pspRequest->DeviceInfoSet. // BOOL FindAC97Device (PSP_PROPSHEETPAGE_REQUEST pspRequest, PSP_DEVINFO_DATA DeviceInfoData) { TCHAR szServiceName[128]; // // Prepare the pspRequest structure... // pspRequest->cbSize = sizeof (SP_PROPSHEETPAGE_REQUEST); pspRequest->DeviceInfoData = DeviceInfoData; pspRequest->PageRequested = SPPSR_ENUM_ADV_DEVICE_PROPERTIES; // ...and the DeviceInfoData structure. DeviceInfoData->cbSize = sizeof (SP_DEVINFO_DATA); // Create a list of devices with Topology interface. pspRequest->DeviceInfoSet = SetupDiGetClassDevs (&KSCATEGORY_TOPOLOGY, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // None found? if (pspRequest->DeviceInfoSet == INVALID_HANDLE_VALUE) { dbgError (TEXT("Test: SetupDiGetClassDevs: ")); return FALSE; } // // Go through the list of all devices found. // int nIndex = 0; while (SetupDiEnumDeviceInfo (pspRequest->DeviceInfoSet, nIndex, DeviceInfoData)) { // // Get the service name for that device. // if (!SetupDiGetDeviceRegistryProperty (pspRequest->DeviceInfoSet, DeviceInfoData, SPDRP_SERVICE, NULL, (PBYTE)szServiceName, sizeof (szServiceName), NULL)) { dbgError (TEXT("Test: SetupDiGetDeviceRegistryProperty: ")); SetupDiDestroyDeviceInfoList (pspRequest->DeviceInfoSet); return FALSE; } // // We only care about service "ac97smpl" // DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT); if (CompareString (lcid, NORM_IGNORECASE, szServiceName, -1, TEXT("AC97SMPL"), -1) == CSTR_EQUAL) { // // We found it! The information is already stored, just return. // Note that we have the device list still open - we have to destroy // the list later. // return TRUE; } // Take the next in the list. nIndex++; } // // We did not find the service. // SetupDiDestroyDeviceInfoList (pspRequest->DeviceInfoSet); return FALSE; }
HRESULT RetrieveDevicePath(OUT LPTSTR DevicePath, IN ULONG BufLen, OUT PBOOL FailureDeviceNotFound) { HRESULT hr; ULONG length; HDEVINFO deviceInfo; SP_DEVICE_INTERFACE_DATA interfaceData; ULONG requiredLength = 0; BOOL bResult = FALSE; PSP_DEVICE_INTERFACE_DETAIL_DATA detailData = NULL; if (NULL != FailureDeviceNotFound) *FailureDeviceNotFound = FALSE; // Enumerate all devices exposing the interface if (INVALID_HANDLE_VALUE == (deviceInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_iOS_USB_Capture, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE))) { hr = HRESULT_FROM_WIN32(GetLastError()); return hr; } interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); // Get the first interface (index 0) in the result set if (FALSE == (bResult = SetupDiEnumDeviceInterfaces(deviceInfo, NULL, &GUID_DEVINTERFACE_iOS_USB_Capture, 0, &interfaceData))) { // We would see this error if no devices were found if ((ERROR_NO_MORE_ITEMS == GetLastError()) && (NULL != FailureDeviceNotFound)) *FailureDeviceNotFound = TRUE; hr = HRESULT_FROM_WIN32(GetLastError()); SetupDiDestroyDeviceInfoList(deviceInfo); return hr; } // Get the size of the path string We expect to get a failure with insufficient buffer bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, NULL, 0, &requiredLength, NULL); if (FALSE == bResult && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { hr = HRESULT_FROM_WIN32(GetLastError()); SetupDiDestroyDeviceInfoList(deviceInfo); return hr; } // Allocate temporary space for SetupDi structure if (NULL == (detailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredLength))) { hr = E_OUTOFMEMORY; SetupDiDestroyDeviceInfoList(deviceInfo); return hr; } detailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); length = requiredLength; // Get the interface's path string if (FALSE == (bResult = SetupDiGetDeviceInterfaceDetail(deviceInfo, &interfaceData, detailData, length, &requiredLength, NULL))) { hr = HRESULT_FROM_WIN32(GetLastError()); LocalFree(detailData); SetupDiDestroyDeviceInfoList(deviceInfo); return hr; } // Give path to the caller. SetupDiGetDeviceInterfaceDetail ensured DevicePath is NULL-terminated. hr = StringCbCopy(DevicePath, BufLen, detailData->DevicePath); LocalFree(detailData); SetupDiDestroyDeviceInfoList(deviceInfo); return hr; }
///////////////////////////////////////////////////////////////////////////////// // DisplayPropertySheet ///////////////////////////////////////////////////////////////////////////////// // This function displays the property dialog. // It is called by CPlApplet when the ac97cpl icon gets a double click. // // Arguments: // hWnd parent window handle // // Return Value: // None. // void DisplayPropertySheet (HWND hWnd) { SP_PROPSHEETPAGE_REQUEST pspRequest; // structure passed to ac97prop SP_DEVINFO_DATA DeviceInfoData; // pspRequest points to it. HMODULE hDLL; // Module handle of library LPFNADDPROPSHEETPAGES AC97PropPageProvider; // function to be called. PROPSHEETHEADER psh; WCHAR wszFormat[128]; size_t iRes; // You could move this to CPL_INIT, then it would be called // before the control panel window appears. // In case of an failure the icon would not be displayed. In our sample // however, the icon will be displayed and when the user clicks on it he // gets the error message. if (!FindAC97Device(&pspRequest, &DeviceInfoData)) { iRes = LoadString(ghInstance, IDS_AC97_WARNING_MUST_INSTALL_DRIVER, wszFormat, ARRAYSIZE(wszFormat)); if (iRes >0) { MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK); } return; } // Load the library and get the function pointer. if (!GetDLLInfo (&hDLL, &AC97PropPageProvider)) { iRes = LoadString(ghInstance, IDS_AC97_WARNING_PROPERTYPAGE_DLL_COULD_NOT_LOAD, wszFormat, ARRAYSIZE(wszFormat)); if (iRes >0) { MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK); } SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet); return; } // // Prepare the header for the property sheet. // psh.nStartPage = 0; psh.dwSize = sizeof(psh); psh.dwFlags = PSH_PROPTITLE | PSH_NOAPPLYNOW; psh.hwndParent = hWnd; psh.hInstance = ghInstance; psh.pszIcon = NULL; psh.pszCaption = MAKEINTRESOURCE(IDS_AC97CPL); psh.nPages = 1; // Call the function to request the property sheet page. if (!(*AC97PropPageProvider) ((LPVOID)&pspRequest, AddPropSheet, (LPARAM)&psh.phpage)) { iRes = LoadString(ghInstance, IDS_AC97_WARNING_PROPERTYPAGEPROVIDER_FAILURE, wszFormat, ARRAYSIZE(wszFormat)); if (iRes >0) { MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK); } FreeLibrary (hDLL); SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet); return; } // Create the dialog. The function returns when the dialog is closed. if (PropertySheet (&psh) < 0) { // // Dialog closed abnormally. This might be a system failure. // iRes = LoadString(ghInstance, IDS_AC97_WARNING_REINSTALL_DRIVER, wszFormat, ARRAYSIZE(wszFormat)); if (iRes >0) { MessageBox (hWnd, wszFormat, AppletName, MB_ICONSTOP | MB_OK); } } // Clean up. FreeLibrary (hDLL); LocalFree (psh.phpage); SetupDiDestroyDeviceInfoList (pspRequest.DeviceInfoSet); }
bool cmtScanPorts( List<CmtPortInfo>& ports, uint32_t baudrate, uint32_t singleScanTimeout, uint32_t scanTries) { CmtPortInfo current; ports.clear(); // clear the list #ifdef _WIN32 HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; DWORD i; // Create a HDEVINFO with all present devices. // GUID for Ports: 4D36E978-E325-11CE-BFC1-08002BE10318 GUID portGuid = {0x4D36E978, 0xE325, 0x11CE, {0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18}}; // "4D36E978-E325-11CE-BFC1-08002BE10318" hDevInfo = SetupDiGetClassDevs(&portGuid, 0, 0, DIGCF_PRESENT | DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) return false; // Enumerate through all devices in Set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; !abortScan && SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); ++i) { DWORD DataT; char buffer[256]; bool isBT = false; // // Call function with null to begin with, // then use the returned buffer size // to Alloc the buffer. Keep calling until // success or an unknown failure. // #if 1 if (SetupDiGetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_MFG, &DataT, (PBYTE)buffer, 256, nullptr)) { // on failure, this is not an Xsens Device // on success, we need to check if the device is an Xsens Device // if (_strnicmp(buffer,"xsens",5)) // scan = true; // else if (!_strnicmp( buffer, "(Standard port types)", strlen("(Standard port types)"))) continue; if (_strnicmp(buffer, "xsens", 5)) // if this is NOT an xsens // device, treat it as a BT // device { isBT = true; if (_strnicmp(buffer, "WIDCOMM", 7)) // if this is NOT a // WIDCOMM (Ezureo / TDK // stack), skip it continue; } } #endif // we found an Xsens Device, add its port nr to the list // Get the registry key which stores the ports settings HKEY hDeviceKey = SetupDiOpenDevRegKey( hDevInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE); if (hDeviceKey != INVALID_HANDLE_VALUE) { // Read in the name of the port char pszPortName[256]; DWORD dwSize = 256; DWORD dwType = 0; if ((RegQueryValueExA( hDeviceKey, "PortName", nullptr, &dwType, (LPBYTE)pszPortName, &dwSize) == ERROR_SUCCESS) && (dwType == REG_SZ)) { // If it looks like "COMX" then // add it to the array which will be returned int32_t nLen = (int32_t)strlen(pszPortName); if (nLen > 3) { if (_strnicmp(pszPortName, "COM", 3)) continue; int32_t nPort = atoi(&pszPortName[3]); if (nPort) { current.m_portNr = (uint8_t)nPort; if (isBT) current.m_baudrate = CMT_BAUD_RATE_460K8; else current.m_baudrate = baudrate; ports.append(current); } } } } // Close the key now that we are finished with it RegCloseKey(hDeviceKey); } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); // Now sort the list by ascending port nr ports.sortAscending(); // Add the standard com ports 1 and 2 unless they are already in the list bool add1 = true, add2 = true; if ((ports.length() > 0) && (ports[0].m_portNr == 1)) add1 = false; if (ports.length() > 0) { if (ports[0].m_portNr == 2) add2 = false; else if (ports.length() > 1) if (ports[1].m_portNr == 2) add2 = false; } if (add1) { current.m_portNr = 1; current.m_baudrate = baudrate; ports.append(current); } if (add2) { current.m_portNr = 2; current.m_baudrate = baudrate; ports.append(current); } #else DIR* dir; struct dirent* entry; if ((dir = opendir("/dev/")) == nullptr) return false; while ((entry = readdir(dir))) if (strncmp("ttyS", entry->d_name, 4) == 0 || strncmp("ttyUSB", entry->d_name, 6) == 0) { sprintf(current.m_portName, "/dev/%s", entry->d_name); current.m_baudrate = baudrate; ports.append(current); } closedir(dir); ports.sortAscending(); #endif // try to connect so we can detect if there really is an MT / XM attached unsigned p = 0; while (!abortScan && p < ports.length()) { if (cmtScanPort( ports[p], ports[p].m_baudrate, singleScanTimeout, scanTries)) ++p; else ports.remove(p); } if (abortScan) return abortScan = false; // Now sort the final list by ascending port nr ports.sortAscending(); abortScan = false; return true; }
// // If succeeded, returns the device file of the LANSCSI Bus Enumerator // If failed, return INVALID_HANDLE_VALUE // static HANDLE OpenBusInterface(VOID) { BOOL fSuccess = FALSE; DWORD err = ERROR_SUCCESS; HANDLE hDevice = INVALID_HANDLE_VALUE; HDEVINFO hDevInfoSet = INVALID_HANDLE_VALUE; SP_INTERFACE_DEVICE_DATA devIntfData = {0}; PSP_INTERFACE_DEVICE_DETAIL_DATA devIntfDetailData = NULL; ULONG predictedLength = 0; ULONG requiredLength = 0; hDevInfoSet = 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 == hDevInfoSet) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetClassDevs failed: ")); goto cleanup; } devIntfData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA); fSuccess = SetupDiEnumDeviceInterfaces ( hDevInfoSet, 0, // No care about specific PDOs (LPGUID)&GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS, 0, // &devIntfData); if (!fSuccess) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiEnumDeviceInterfaces failed: ")); if (ERROR_NO_MORE_ITEMS == GetLastError()) { DebugPrint(1, _T("OpenBusInterface: Interface") _T(" GUID_LANSCSI_BUS_ENUMERATOR_INTERFACE_CLASS is not registered.\n")); } goto cleanup; } fSuccess = SetupDiGetInterfaceDeviceDetail ( hDevInfoSet, &devIntfData, NULL, // probing so no output buffer yet 0, // probing so output buffer length of zero &requiredLength, NULL // not interested in the specific dev-node ); if (!fSuccess && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: ")); goto cleanup; } predictedLength = requiredLength; devIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, predictedLength); devIntfDetailData->cbSize = sizeof (SP_INTERFACE_DEVICE_DETAIL_DATA); fSuccess = SetupDiGetInterfaceDeviceDetail( hDevInfoSet, &devIntfData, devIntfDetailData, predictedLength, &requiredLength, NULL); if (!fSuccess) { DebugPrintErrEx(_T("OpenBusInterface: SetupDiGetInterfaceDeviceDetail failed: ")); goto cleanup; } DebugPrint(3, _T("OpenBusInterface: Opening %s\n"), devIntfDetailData->DevicePath); hDevice = CreateFile ( devIntfDetailData->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 == hDevice) { DebugPrintErrEx(_T("OpenBusInterface: Device not ready: ")); goto cleanup; } DebugPrint(3, _T("OpenBusInterface: Device file %s opened successfully.\n"), devIntfDetailData->DevicePath); cleanup: err = GetLastError(); if (INVALID_HANDLE_VALUE != hDevInfoSet) { SetupDiDestroyDeviceInfoList(hDevInfoSet); } if (NULL != devIntfDetailData) { HeapFree(GetProcessHeap(), 0, devIntfDetailData); } SetLastError(err); return hDevice; }