HANDLE OpenBus() { HANDLE hDevice; HDEVINFO DevInfo; SP_DEVICE_INTERFACE_DATA DevInterfaceData; DWORD RequiredSize; PSP_DEVICE_INTERFACE_DETAIL_DATA DevInterfaceDetailData; // Get all devices that support the interface DevInfo = SetupDiGetClassDevsEx(&GUID_DEVINTERFACE_GHOST, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT, NULL, NULL, NULL); if (DevInfo == INVALID_HANDLE_VALUE) { printf("Error: Unable to obtain candidates (0x%x)\n", GetLastError()); return INVALID_HANDLE_VALUE; } // Enumerate the device instances DevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces(DevInfo, NULL, &GUID_DEVINTERFACE_GHOST, 0, &DevInterfaceData)) { printf("Error: Unable to find an instance of the interface (0x%x)\n", GetLastError()); return INVALID_HANDLE_VALUE; } // Obtain details SetupDiGetDeviceInterfaceDetail(DevInfo, &DevInterfaceData, NULL, 0, &RequiredSize, NULL); DevInterfaceDetailData = malloc(RequiredSize); DevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(DevInfo, &DevInterfaceData, DevInterfaceDetailData, RequiredSize, NULL, NULL)) { printf("Error: Unable to obtain details of the interface instance\n"); free(DevInterfaceDetailData); return INVALID_HANDLE_VALUE; } SetupDiDestroyDeviceInfoList(DevInfo); printf("Opening bus device at %s...\n", DevInterfaceDetailData->DevicePath); hDevice = CreateFile(DevInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); free(DevInterfaceDetailData); return hDevice; }
bool GetSizeForDevID(wxString &TargetDevID, int *WidthMm, int *HeightMm) { HDEVINFO devInfo = SetupDiGetClassDevsEx( &GUID_CLASS_MONITOR, //class GUID NULL, //enumerator NULL, //HWND DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| NULL, // device info, create a new one. NULL, // machine name, local machine NULL);// reserved if (NULL == devInfo) return false; bool bRes = false; for (ULONG i=0; ERROR_NO_MORE_ITEMS != GetLastError(); ++i) { SP_DEVINFO_DATA devInfoData; memset(&devInfoData,0,sizeof(devInfoData)); devInfoData.cbSize = sizeof(devInfoData); if (SetupDiEnumDeviceInfo(devInfo,i,&devInfoData)) { wchar_t Instance[80]; SetupDiGetDeviceInstanceId(devInfo, &devInfoData, Instance, MAX_PATH, NULL); wxString instance(Instance); if(instance.Upper().Find( TargetDevID.Upper() ) == wxNOT_FOUND ) continue; HKEY hDevRegKey = SetupDiOpenDevRegKey(devInfo,&devInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if(!hDevRegKey || (hDevRegKey == INVALID_HANDLE_VALUE)) continue; bRes = GetMonitorSizeFromEDID(hDevRegKey, WidthMm, HeightMm); RegCloseKey(hDevRegKey); } } SetupDiDestroyDeviceInfoList(devInfo); return bRes; }
bool remove(const std::wstring& hardware_id, bool& reboot_required) { bool result = false; HDEVINFO devices = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL); if (devices != INVALID_HANDLE_VALUE) { std::wcerr << "Got device information set." << std::endl; SP_DEVINFO_LIST_DETAIL_DATA device_info_list_detail; memset(&device_info_list_detail, 0x00, sizeof(device_info_list_detail)); device_info_list_detail.cbSize = sizeof(device_info_list_detail); if (SetupDiGetDeviceInfoListDetail(devices, &device_info_list_detail)) { std::wcerr << "Got device information list details." << std::endl; SP_DEVINFO_DATA device_info; device_info.cbSize = sizeof(device_info); for (DWORD index = 0; SetupDiEnumDeviceInfo(devices, index, &device_info); ++index) { TCHAR device_id[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_ID_Ex(device_info.DevInst, device_id, MAX_DEVICE_ID_LEN, 0, device_info_list_detail.RemoteMachineHandle) == CR_SUCCESS) { std::list<std::wstring> device_hardware_id_list; if (getDeviceProperty(devices, device_info, SPDRP_HARDWAREID, device_hardware_id_list)) { bool match = false; for (std::list<std::wstring>::const_iterator device_hardware_id = device_hardware_id_list.begin(); device_hardware_id != device_hardware_id_list.end(); ++device_hardware_id) { if (*device_hardware_id == hardware_id) { match = true; break; } } if (match) { std::wstring friendly_name; if (getDeviceProperty(devices, device_info, SPDRP_FRIENDLYNAME, friendly_name) && (friendly_name.length() > 0)) { std::wcerr << "Removing device: " << friendly_name << " (" << device_id << ")" << std::endl; } else { std::wcerr << "Removing device: " << device_id << std::endl; } SP_REMOVEDEVICE_PARAMS remove_device_params; remove_device_params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); remove_device_params.ClassInstallHeader.InstallFunction = DIF_REMOVE; remove_device_params.Scope = DI_REMOVEDEVICE_GLOBAL; remove_device_params.HwProfile = 0; result = true; if (!SetupDiSetClassInstallParams(devices, &device_info, &remove_device_params.ClassInstallHeader, sizeof(remove_device_params)) || !SetupDiCallClassInstaller(DIF_REMOVE, devices, &device_info)) { std::wcerr << "Failed to set the class installer." << std::endl; result = false; } if (result) { reboot_required = false; SP_DEVINSTALL_PARAMS device_params; if (SetupDiGetDeviceInstallParams(devices, &device_info, &device_params)) { if (device_params.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) { reboot_required = true; } } } } } } } } SetupDiDestroyDeviceInfoList(devices); } return result; }
static VOID InitProbeListPage(HWND hwndDlg) { LV_COLUMN Column; LV_ITEM Item; WCHAR szBuffer[MAX_STR_SIZE], szGuid[MAX_STR_SIZE], szTrimGuid[MAX_STR_SIZE], szStatusText[MAX_STR_SIZE]; HWND hList = GetDlgItem(hwndDlg, IDC_PROBELIST); PWSTR pstrStatusText; HDEVINFO hDevInfo; SP_DEVINFO_DATA DevInfoData; ULONG ulStatus, ulProblemNumber; GUID ClassGuid; RECT Rect; DWORD Index; if (!hList) return; ZeroMemory(&Column, sizeof(LV_COLUMN)); GetClientRect(hList, &Rect); Column.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH; Column.fmt = LVCFMT_LEFT; Column.iSubItem = 0; Column.pszText = NULL; Column.cx = Rect.right - GetSystemMetrics(SM_CXVSCROLL); (VOID) ListView_InsertColumn(hList, 0, &Column); ZeroMemory(&Item, sizeof(LV_ITEM)); LoadString(hApplet, IDS_ADDNEWDEVICE, szBuffer, sizeof(szBuffer) / sizeof(WCHAR)); Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.pszText = (LPWSTR) szBuffer; Item.iItem = (INT) ListView_GetItemCount(hList); Item.iImage = -1; (VOID) ListView_InsertItem(hList, &Item); hDevInfo = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, 0); if (hDevInfo == INVALID_HANDLE_VALUE) return; /* Get the device image List */ ImageListData.cbSize = sizeof(ImageListData); SetupDiGetClassImageList(&ImageListData); DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (Index = 0; TRUE; Index++) { szBuffer[0] = L'\0'; if (!SetupDiEnumDeviceInfo(hDevInfo, Index, &DevInfoData)) break; if (CM_Get_DevNode_Status_Ex(&ulStatus, &ulProblemNumber, DevInfoData.DevInst, 0, NULL) == CR_SUCCESS) { if (ulStatus & DN_NO_SHOW_IN_DM) continue; } /* Get the device's friendly name */ if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_FRIENDLYNAME, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL)) { /* If the friendly name fails, try the description instead */ SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_DEVICEDESC, 0, (BYTE*)szBuffer, MAX_STR_SIZE, NULL); } SetupDiGetDeviceRegistryProperty(hDevInfo, &DevInfoData, SPDRP_CLASSGUID, 0, (BYTE*)szGuid, MAX_STR_SIZE, NULL); TrimGuidString(szGuid, szTrimGuid); UuidFromStringW(szTrimGuid, &ClassGuid); SetupDiGetClassImageIndex(&ImageListData, &ClassGuid, &Item.iImage); DeviceProblemTextW(NULL, DevInfoData.DevInst, ulProblemNumber, szStatusText, sizeof(szStatusText) / sizeof(WCHAR)); pstrStatusText = (PWSTR)HeapAlloc(hProcessHeap, 0, sizeof(szStatusText)); lstrcpy(pstrStatusText, szStatusText); if (szBuffer[0] != L'\0') { /* Set device name */ Item.pszText = (LPWSTR) szBuffer; Item.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE | LVIF_IMAGE; Item.lParam = (LPARAM) pstrStatusText; Item.iItem = (INT) ListView_GetItemCount(hList); (VOID) ListView_InsertItem(hList, &Item); } DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); } (VOID) ListView_SetImageList(hList, ImageListData.ImageList, LVSIL_SMALL); (VOID) ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT); SetupDiDestroyDeviceInfoList(hDevInfo); }
static void create_ramdisk_device(std::string full_inf_file_path, std::string hardware_id) { GUID class_guid; WCHAR class_name_w[MAX_CLASS_NAME_LEN]; auto success = SetupDiGetINFClassW(w32util::widen(full_inf_file_path).c_str(), &class_guid, class_name_w, safe::numelementsf(class_name_w), nullptr); if (!success) w32util::throw_windows_error(); /* don't install device if it already exists */ auto create_device = true; { HDEVINFO device_info_set = SetupDiGetClassDevsEx(&class_guid, nullptr, nullptr, 0, nullptr, nullptr, nullptr); if (device_info_set == INVALID_HANDLE_VALUE) { w32util::throw_setupapi_error(); } SP_DEVINFO_DATA device_info_data; zero_object(device_info_data); device_info_data.cbSize = sizeof(device_info_data); for (DWORD idx = 0; create_device && SetupDiEnumDeviceInfo(device_info_set, idx, &device_info_data); ++idx) { /* first get hardware id reg key for this device info */ CHAR buffer[1024]; BOOL success_prop = SetupDiGetDeviceRegistryPropertyA(device_info_set, &device_info_data, SPDRP_HARDWAREID, nullptr, (PBYTE) buffer, sizeof(buffer), nullptr); if (!success_prop) w32util::throw_setupapi_error(); PCHAR bp = buffer; while(*bp) { if (!strcmp(bp, hardware_id.c_str())) { create_device = false; break; } bp += strlen(bp) + 1; } } } // device already exists, no need to create it if (!create_device) return; auto device_info_set = SetupDiCreateDeviceInfoList(&class_guid, NULL); if (device_info_set == INVALID_HANDLE_VALUE) w32util::throw_setupapi_error(); auto _destroy_device_info_set = safe::create_deferred(SetupDiDestroyDeviceInfoList, device_info_set); SP_DEVINFO_DATA device_info_data; zero_object(device_info_data); device_info_data.cbSize = sizeof(device_info_data); auto success_create_device_info = SetupDiCreateDeviceInfoW(device_info_set, class_name_w, &class_guid, nullptr, 0, DICD_GENERATE_ID, &device_info_data); if (!success_create_device_info) w32util::throw_setupapi_error(); // TODO: runtime stack array is a GCC extension auto reg_hardware_id_len = hardware_id.size() + 2; auto reg_hardware_id_size = reg_hardware_id_len * sizeof(WCHAR); auto reg_hardware_id = std::unique_ptr<WCHAR[]>(new WCHAR[reg_hardware_id_len]); memset(reg_hardware_id.get(), 0, reg_hardware_id_size); memcpy(reg_hardware_id.get(), w32util::widen(hardware_id).data(), hardware_id.size() * sizeof(WCHAR)); auto success_set_hardware_id = SetupDiSetDeviceRegistryPropertyW(device_info_set, &device_info_data, SPDRP_HARDWAREID, (BYTE *) reg_hardware_id.get(), reg_hardware_id_size); if (!success_set_hardware_id) w32util::throw_setupapi_error(); auto success_class_installer = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info_set, &device_info_data); if (!success_class_installer) w32util::throw_setupapi_error(); create_ramdisk_hardware_keys(device_info_set, &device_info_data); }
HDEVINFO GetDevInfoFromDeviceId(SP_DEVINFO_DATA *dev_info_data, CHAR *device_id) { HDEVINFO dev_info; SP_DEVINFO_DATA data; UINT i; BOOL found; CHAR *buffer; UINT buffer_size = 8092; DWORD required_size; DWORD data_type; dev_info = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL); if (dev_info == NULL) { return NULL; } #if 0 SP_DEVINFO_LIST_DETAIL_DATA detail_data; memset(&detail_data, 0, sizeof(detail_data)); detail_data.cbSize = sizeof(detail_data); if (SetupDiGetDeviceInfoListDetail(dev_info, &detail_data) == FALSE) { DestroyDevInfo(dev_info); return NULL; } #endif memset(&data, 0, sizeof(data)); data.cbSize = sizeof(data); found = FALSE; buffer = (LPTSTR)LocalAlloc(LPTR, buffer_size); if (!buffer) { printf("Alloc: %x\n", GetLastError()); goto out; } for (i = 0; SetupDiEnumDeviceInfo(dev_info, i, &data); i++) { while (!SetupDiGetDeviceRegistryProperty(dev_info, &data, SPDRP_HARDWAREID, &data_type, (PBYTE)buffer, buffer_size, &required_size)) { if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { // Change the buffer size. if (buffer) { LocalFree(buffer); } // Double the size to avoid problems on // W2k MBCS systems per KB 888609. buffer_size *= 2; buffer = (LPTSTR)LocalAlloc(LPTR, buffer_size); if (!buffer) { printf("LocalAlloc: %x\n", GetLastError()); goto out; } } else { // EnumNext break; } } if (stricmp(buffer, device_id) == 0) { found = TRUE; } if (found) { goto out; } memset(&data, 0, sizeof(data)); data.cbSize = sizeof(data); } out: if (buffer) LocalFree(buffer); if (found == FALSE) { DestroyDevInfo(dev_info); return NULL; } else { memcpy(dev_info_data, &data, sizeof(data)); return dev_info; } }