static WCHAR * frida_read_device_registry_string_property (HANDLE info_set, SP_DEVINFO_DATA * info_data, DWORD prop_id) { gboolean success = FALSE; WCHAR * value_buffer = NULL; DWORD value_size; BOOL ret; ret = SetupDiGetDeviceRegistryPropertyW (info_set, info_data, prop_id, NULL, NULL, 0, &value_size); if (!ret && GetLastError () != ERROR_INSUFFICIENT_BUFFER) goto beach; value_buffer = (WCHAR *) g_malloc (value_size); if (!SetupDiGetDeviceRegistryPropertyW (info_set, info_data, prop_id, NULL, (PBYTE) value_buffer, value_size, NULL)) goto beach; success = TRUE; beach: if (!success) { g_free (value_buffer); value_buffer = NULL; } return value_buffer; }
void GetDeviceDetail( HANDLE DeviceInformation, SP_DEVINFO_DATA* DeviceData ) { wchar_t propertyBuffer[1000]; DWORD propertyDataType = 1; DWORD requiredSize = 0; SetupDiGetDeviceRegistryPropertyW( DeviceInformation, DeviceData, SPDRP_DEVICEDESC, &propertyDataType, &propertyBuffer, 1000 * sizeof(wchar_t), &requiredSize ); if (String_Compare(propertyBuffer, L"MotioninJoy Virtual Xinput device for Windows") == 0) { Log(L"Driver already installed for this device"); } else { Log(L"Installing driver..."); InstallDriver(DeviceInformation, DeviceData); } }
// Code for enumerating hardware devices that use the XINPUT device driver. // The MSDN recommended code suffers from massive performance problems when using language packs, // if the system and user languages differ then WMI Queries become incredibly slow (multiple // seconds). This is more or less equivalent and much faster. std::unordered_set<DWORD> GetXInputGUIDS() { static const GUID s_GUID_devclass_HID = { 0x745a17a0, 0x74d3, 0x11d0, {0xb6, 0xfe, 0x00, 0xa0, 0xc9, 0x0f, 0x57, 0xda} }; std::unordered_set<DWORD> guids; // Enumerate everything under the "Human Interface Devices" tree in the Device Manager // NOTE: Some devices show up multiple times due to sub-devices, we rely on the set to // prevent duplicates. HDEVINFO setup_enum = SetupDiGetClassDevsW(&s_GUID_devclass_HID, nullptr, nullptr, DIGCF_PRESENT); if (setup_enum == INVALID_HANDLE_VALUE) return guids; std::vector<wchar_t> buffer(128); SP_DEVINFO_DATA dev_info; dev_info.cbSize = sizeof(SP_DEVINFO_DATA); for (DWORD i = 0; SetupDiEnumDeviceInfo(setup_enum, i, &dev_info); ++i) { // Need to find the size of the data and set the buffer appropriately DWORD buffer_size = 0; while (!SetupDiGetDeviceRegistryPropertyW(setup_enum, &dev_info, SPDRP_HARDWAREID, nullptr, reinterpret_cast<BYTE*>(buffer.data()), static_cast<DWORD>(buffer.size()), &buffer_size)) { if (buffer_size > buffer.size()) buffer.resize(buffer_size); else break; } if (GetLastError() != ERROR_SUCCESS) continue; // HARDWAREID is a REG_MULTI_SZ // There are multiple strings separated by NULs, the list is ended by an empty string. for (std::size_t j = 0; buffer[j]; j += std::wcslen(&buffer[j]) + 1) { // XINPUT devices have "IG_xx" embedded in their IDs which is what we look for. if (!std::wcsstr(&buffer[j], L"IG_")) continue; unsigned int vid = 0; unsigned int pid = 0; // Extract Vendor and Product IDs for matching against DirectInput's device list. wchar_t* pos = std::wcsstr(&buffer[j], L"VID_"); if (!pos || !std::swscanf(pos, L"VID_%4X", &vid)) continue; pos = std::wcsstr(&buffer[j], L"PID_"); if (!pos || !std::swscanf(pos, L"PID_%4X", &pid)) continue; guids.insert(MAKELONG(vid, pid)); break; } } SetupDiDestroyDeviceInfoList(setup_enum); return guids; }
static void SetDeviceDetails(HWND * hDlgCtrls, LPCGUID classGUID, LPGUID * deviceGUID) { HDEVINFO hInfo; DWORD dwIndex = 0; SP_DEVINFO_DATA InfoData; WCHAR szText[100]; /* 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 (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_DEVICEDESC, NULL, (PBYTE)szText, sizeof(szText), NULL)) SendMessageW(hDlgCtrls[0], WM_SETTEXT, 0, (LPARAM)szText); /* set the manufacturer name */ if (SetupDiGetDeviceRegistryPropertyW(hInfo, &InfoData, SPDRP_MFG, NULL, (PBYTE)szText, sizeof(szText), NULL)) SendMessageW(hDlgCtrls[1], WM_SETTEXT, 0, (LPARAM)szText); /* FIXME * we currently enumerate only the first adapter */ EnumerateDrivers(&hDlgCtrls[2], hInfo, &InfoData); break; } if (GetLastError() == ERROR_NO_MORE_ITEMS) break; dwIndex++; }while(TRUE); /* destroy the setup list */ SetupDiDestroyDeviceInfoList(hInfo); }
static BOOL RenameHostOnlyConnectionsCallback(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDev, PVOID pContext) { WCHAR DevName[256]; DWORD winEr; if (SetupDiGetDeviceRegistryPropertyW(hDevInfo, pDev, SPDRP_FRIENDLYNAME , /* IN DWORD Property,*/ NULL, /*OUT PDWORD PropertyRegDataType, OPTIONAL*/ (PBYTE)DevName, /*OUT PBYTE PropertyBuffer,*/ sizeof(DevName), /* IN DWORD PropertyBufferSize,*/ NULL /*OUT PDWORD RequiredSize OPTIONAL*/ )) { HKEY hKey = SetupDiOpenDevRegKey(hDevInfo, pDev, DICS_FLAG_GLOBAL, /* IN DWORD Scope,*/ 0, /*IN DWORD HwProfile, */ DIREG_DRV, /* IN DWORD KeyType, */ KEY_READ /*IN REGSAM samDesired*/ ); NonStandardAssert(hKey != INVALID_HANDLE_VALUE); if (hKey != INVALID_HANDLE_VALUE) { WCHAR guid[50]; DWORD cbGuid=sizeof(guid); winEr = RegQueryValueExW(hKey, L"NetCfgInstanceId", /*__in_opt LPCTSTR lpValueName,*/ NULL, /*__reserved LPDWORD lpReserved,*/ NULL, /*__out_opt LPDWORD lpType,*/ (LPBYTE)guid, /*__out_opt LPBYTE lpData,*/ &cbGuid /*guid__inout_opt LPDWORD lpcbData*/ ); NonStandardAssert(winEr == ERROR_SUCCESS); if (winEr == ERROR_SUCCESS) { WCHAR ConnectoinName[128]; ULONG cbName = sizeof(ConnectoinName); HRESULT hr = VBoxNetCfgWinGenHostonlyConnectionName (DevName, ConnectoinName, &cbName); NonStandardAssert(hr == S_OK); if (SUCCEEDED(hr)) { hr = VBoxNetCfgWinRenameConnection(guid, ConnectoinName); NonStandardAssert(hr == S_OK); } } } RegCloseKey(hKey); } else { NonStandardAssert(0); } return TRUE; }
QStringList QPCSC::drivers() const { #ifdef Q_OS_WIN HDEVINFO h = SetupDiGetClassDevs( 0, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT ); if( !h ) return QStringList(); SP_DEVINFO_DATA info = { sizeof(SP_DEVINFO_DATA) }; QStringList list; for( DWORD i = 0; SetupDiEnumDeviceInfo( h, i, &info ); i++ ) { DWORD size = 0; WCHAR data[1024]; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_CLASS, 0, LPBYTE(data), sizeof(data), &size ); if( _wcsicmp( data, L"SmartCardReader" ) != 0 ) continue; DWORD conf = 0; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_CONFIGFLAGS, 0, LPBYTE(&conf), sizeof(conf), &size ); if( conf & CONFIGFLAG_DISABLED ) continue; SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_DEVICEDESC, 0, LPBYTE(data), sizeof(data), &size ); QString name( (QChar*)data ); SetupDiGetDeviceRegistryPropertyW( h, &info, SPDRP_HARDWAREID, 0, LPBYTE(data), sizeof(data), &size ); list << QString( "%1 (%2)").arg( name, QString( (QChar*)data ) ); } SetupDiDestroyDeviceInfoList( h ); return list; #else return readers(); #endif }
BOOL FindNetworkAdapter(HDEVINFO hInfo, SP_DEVINFO_DATA *pDevInfo, LPWSTR pGuid) { DWORD dwIndex, dwSize; HKEY hSubKey; WCHAR szNetCfg[50]; WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\"; dwIndex = 0; do { ZeroMemory(pDevInfo, sizeof(SP_DEVINFO_DATA)); pDevInfo->cbSize = sizeof(SP_DEVINFO_DATA); /* get device info */ if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, pDevInfo)) break; /* get device software registry path */ if (!SetupDiGetDeviceRegistryPropertyW(hInfo, pDevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize)) break; /* open device registry key */ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hSubKey) != ERROR_SUCCESS) break; /* query NetCfgInstanceId for current device */ dwSize = sizeof(szNetCfg); if (RegQueryValueExW(hSubKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS) { RegCloseKey(hSubKey); break; } RegCloseKey(hSubKey); if (!_wcsicmp(pGuid, szNetCfg)) { return TRUE; } } while (TRUE); return FALSE; }
static LPWSTR get_registry_property(HDEVINFO hDevInfo, DWORD index, DWORD property, BOOL *iterate) { /* Get the property specified by `property` from the registry for the * device enumerated by `index` in the collection `hDevInfo`. `iterate` * will be set to `FALSE` if `index` points outside `hDevInfo`. * :return: A string allocated on the heap containing the property or * `NULL` if an error occurred. */ SP_DEVINFO_DATA DeviceInfoData; DWORD DataT; LPWSTR buffer = NULL; DWORD buffersize = 0; DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) { *iterate = FALSE; return NULL; } while(!SetupDiGetDeviceRegistryPropertyW( hDevInfo, &DeviceInfoData, property, &DataT, (PBYTE)buffer, buffersize, &buffersize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (buffer != NULL) { PyMem_Free(buffer); buffer = NULL; } buffer = (LPWSTR)PyMem_Malloc(2*buffersize); // Twice for bug in Win2k } else { if (buffer != NULL) { PyMem_Free(buffer); buffer = NULL; } PyErr_SetFromWindowsErr(0); break; } } //while return buffer; }
static DWORD InstallSerialPort(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData) { WCHAR szDeviceDescription[256]; WCHAR szFriendlyName[256]; WCHAR szPortName[8]; DWORD dwPortNumber = 0; DWORD dwSize; HCOMDB hComDB = HCOMDB_INVALID_HANDLE_VALUE; HKEY hKey; LONG lError; TRACE("InstallSerialPort(%p, %p)\n", DeviceInfoSet, DeviceInfoData); /* Open the com port database */ ComDBOpen(&hComDB); /* Try to read the 'PortName' value and determine the port number */ hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); if (hKey != INVALID_HANDLE_VALUE) { dwSize = sizeof(szPortName); lError = RegQueryValueEx(hKey, L"PortName", NULL, NULL, (PBYTE)szPortName, &dwSize); if (lError == ERROR_SUCCESS) { if (_wcsnicmp(szPortName, pszCom, wcslen(pszCom)) == 0) { dwPortNumber = _wtoi(szPortName + wcslen(pszCom)); TRACE("COM port number found: %lu\n", dwPortNumber); } } RegCloseKey(hKey); } /* Determine the port number from its resources ... */ if (dwPortNumber == 0) dwPortNumber = GetSerialPortNumber(DeviceInfoSet, DeviceInfoData); if (dwPortNumber != 0) { /* ... and claim the port number in the database */ ComDBClaimPort(hComDB, dwPortNumber, FALSE, NULL); } else { /* ... or claim the next free port number */ ComDBClaimNextFreePort(hComDB, &dwPortNumber); } /* Build the name of the port device */ swprintf(szPortName, L"%s%u", pszCom, dwPortNumber); /* Close the com port database */ if (hComDB != HCOMDB_INVALID_HANDLE_VALUE) ComDBClose(hComDB); /* Set the 'PortName' value */ hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); if (hKey != INVALID_HANDLE_VALUE) { RegSetValueExW(hKey, L"PortName", 0, REG_SZ, (LPBYTE)szPortName, (wcslen(szPortName) + 1) * sizeof(WCHAR)); RegCloseKey(hKey); } /* Install the device */ if (!SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData)) { return GetLastError(); } /* Get the device description... */ if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC, NULL, (LPBYTE)szDeviceDescription, 256 * sizeof(WCHAR), NULL)) { /* ... and use it to build a new friendly name */ swprintf(szFriendlyName, L"%s (%s)", szDeviceDescription, szPortName); } else { /* ... or build a generic friendly name */ swprintf(szFriendlyName, L"Serial Port (%s)", szPortName); } /* Set the friendly name for the device */ SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, (LPBYTE)szFriendlyName, (wcslen(szFriendlyName) + 1) * sizeof(WCHAR)); return ERROR_SUCCESS; }
GList * ks_enumerate_devices (const GUID * category) { GList *result = NULL; HDEVINFO devinfo; gint i; devinfo = SetupDiGetClassDevsW (category, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); if (!ks_is_valid_handle (devinfo)) return NULL; /* no devices */ for (i = 0;; i++) { BOOL success; SP_DEVICE_INTERFACE_DATA if_data = { 0, }; SP_DEVICE_INTERFACE_DETAIL_DATA_W *if_detail_data; DWORD if_detail_data_size; SP_DEVINFO_DATA devinfo_data = { 0, }; DWORD req_size; if_data.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); success = SetupDiEnumDeviceInterfaces (devinfo, NULL, category, i, &if_data); if (!success) /* all devices enumerated? */ break; if_detail_data_size = (MAX_PATH - 1) * sizeof (gunichar2); if_detail_data = g_malloc0 (if_detail_data_size); if_detail_data->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA_W); devinfo_data.cbSize = sizeof (SP_DEVINFO_DATA); success = SetupDiGetDeviceInterfaceDetailW (devinfo, &if_data, if_detail_data, if_detail_data_size, &req_size, &devinfo_data); if (success) { KsDeviceEntry *entry; WCHAR buf[512]; entry = g_new0 (KsDeviceEntry, 1); entry->index = i; entry->path = g_utf16_to_utf8 (if_detail_data->DevicePath, -1, NULL, NULL, NULL); if (SetupDiGetDeviceRegistryPropertyW (devinfo, &devinfo_data, SPDRP_FRIENDLYNAME, NULL, (BYTE *) buf, sizeof (buf), NULL)) { entry->name = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); } if (entry->name == NULL) { if (SetupDiGetDeviceRegistryPropertyW (devinfo, &devinfo_data, SPDRP_DEVICEDESC, NULL, (BYTE *) buf, sizeof (buf), NULL)) { entry->name = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); } } if (entry->name != NULL) result = g_list_prepend (result, entry); else ks_device_entry_free (entry); } g_free (if_detail_data); } SetupDiDestroyDeviceInfoList (devinfo); return g_list_reverse (result); }
BOOL WINAPI InstallDevInst( IN HWND hWndParent, IN LPCWSTR InstanceId, IN BOOL bUpdate, OUT LPDWORD lpReboot) { PDEVINSTDATA DevInstData = NULL; BOOL ret; BOOL retval = FALSE; TRACE("InstllDevInst(%p, %s, %d, %p)\n", hWndParent, debugstr_w(InstanceId), bUpdate, lpReboot); DevInstData = HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA)); if (!DevInstData) { TRACE("HeapAlloc() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } /* Clear devinst data */ ZeroMemory(DevInstData, sizeof(DEVINSTDATA)); DevInstData->devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */ DevInstData->bUpdate = bUpdate; /* Fill devinst data */ DevInstData->hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); if (DevInstData->hDevInfo == INVALID_HANDLE_VALUE) { TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError()); goto cleanup; } DevInstData->devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); ret = SetupDiOpenDeviceInfoW( DevInstData->hDevInfo, InstanceId, NULL, 0, /* Open flags */ &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n", GetLastError(), debugstr_w(InstanceId)); DevInstData->devInfoData.cbSize = 0; goto cleanup; } SetLastError(ERROR_GEN_FAILURE); ret = SetupDiGetDeviceRegistryProperty( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDRP_DEVICEDESC, &DevInstData->regDataType, NULL, 0, &DevInstData->requiredSize); if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData->regDataType == REG_SZ) { DevInstData->buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData->requiredSize); if (!DevInstData->buffer) { TRACE("HeapAlloc() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { ret = SetupDiGetDeviceRegistryPropertyW( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDRP_DEVICEDESC, &DevInstData->regDataType, DevInstData->buffer, DevInstData->requiredSize, &DevInstData->requiredSize); } } if (!ret) { TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n", GetLastError(), debugstr_w(InstanceId)); goto cleanup; } /* Prepare the wizard, and display it */ TRACE("Need to show install wizard\n"); retval = DisplayWizard(DevInstData, hWndParent, IDD_WELCOMEPAGE); cleanup: if (DevInstData) { if (DevInstData->devInfoData.cbSize != 0) { if (!SetupDiDestroyDriverInfoList(DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER)) TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError()); } if (DevInstData->hDevInfo != INVALID_HANDLE_VALUE) { if (!SetupDiDestroyDeviceInfoList(DevInstData->hDevInfo)) TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError()); } HeapFree(GetProcessHeap(), 0, DevInstData->buffer); HeapFree(GetProcessHeap(), 0, DevInstData); } return retval; }
/* * @implemented */ BOOL WINAPI DevInstallW( IN HWND hWndParent, IN HINSTANCE hInstance, IN LPCWSTR InstanceId, IN INT Show) { PDEVINSTDATA DevInstData = NULL; BOOL ret; DWORD config_flags; BOOL retval = FALSE; TRACE("(%p, %p, %s, %d)\n", hWndParent, hInstance, debugstr_w(InstanceId), Show); if (!IsUserAdmin()) { /* XP kills the process... */ ExitProcess(ERROR_ACCESS_DENIED); } DevInstData = HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA)); if (!DevInstData) { TRACE("HeapAlloc() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } /* Clear devinst data */ ZeroMemory(DevInstData, sizeof(DEVINSTDATA)); DevInstData->devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */ /* Fill devinst data */ DevInstData->hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL); if (DevInstData->hDevInfo == INVALID_HANDLE_VALUE) { TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError()); goto cleanup; } DevInstData->devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); ret = SetupDiOpenDeviceInfoW( DevInstData->hDevInfo, InstanceId, NULL, 0, /* Open flags */ &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n", GetLastError(), debugstr_w(InstanceId)); DevInstData->devInfoData.cbSize = 0; goto cleanup; } SetLastError(ERROR_GEN_FAILURE); ret = SetupDiGetDeviceRegistryProperty( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDRP_DEVICEDESC, &DevInstData->regDataType, NULL, 0, &DevInstData->requiredSize); if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData->regDataType == REG_SZ) { DevInstData->buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData->requiredSize); if (!DevInstData->buffer) { TRACE("HeapAlloc() failed\n"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); } else { ret = SetupDiGetDeviceRegistryPropertyW( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDRP_DEVICEDESC, &DevInstData->regDataType, DevInstData->buffer, DevInstData->requiredSize, &DevInstData->requiredSize); } } if (!ret) { TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n", GetLastError(), debugstr_w(InstanceId)); goto cleanup; } if (SetupDiGetDeviceRegistryPropertyW( DevInstData->hDevInfo, &DevInstData->devInfoData, SPDRP_CONFIGFLAGS, NULL, (BYTE *)&config_flags, sizeof(config_flags), NULL)) { if (config_flags & CONFIGFLAG_FAILEDINSTALL) { /* The device is disabled */ TRACE("Device is disabled\n"); retval = TRUE; goto cleanup; } } TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR)DevInstData->buffer), debugstr_w(InstanceId)); /* Search driver in default location and removable devices */ if (!PrepareFoldersToScan(DevInstData, FALSE, FALSE, NULL)) { TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError()); goto cleanup; } if (ScanFoldersForDriver(DevInstData)) { /* Driver found ; install it */ retval = InstallCurrentDriver(DevInstData); TRACE("InstallCurrentDriver() returned %d\n", retval); if (retval && Show != SW_HIDE) { /* Should we display the 'Need to reboot' page? */ SP_DEVINSTALL_PARAMS installParams; installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if (SetupDiGetDeviceInstallParams( DevInstData->hDevInfo, &DevInstData->devInfoData, &installParams)) { if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT)) { TRACE("Displaying 'Reboot' wizard page\n"); retval = DisplayWizard(DevInstData, hWndParent, IDD_NEEDREBOOT); } } } goto cleanup; } else if (Show == SW_HIDE) { /* We can't show the wizard. Fail the install */ TRACE("No wizard\n"); goto cleanup; } /* Prepare the wizard, and display it */ TRACE("Need to show install wizard\n"); retval = DisplayWizard(DevInstData, hWndParent, IDD_WELCOMEPAGE); cleanup: if (DevInstData) { if (DevInstData->devInfoData.cbSize != 0) { if (!SetupDiDestroyDriverInfoList(DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER)) TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError()); } if (DevInstData->hDevInfo != INVALID_HANDLE_VALUE) { if (!SetupDiDestroyDeviceInfoList(DevInstData->hDevInfo)) TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError()); } HeapFree(GetProcessHeap(), 0, DevInstData->buffer); HeapFree(GetProcessHeap(), 0, DevInstData); } return retval; }
/* * @implemented */ BOOL WINAPI UpdateDriverForPlugAndPlayDevicesW( IN HWND hwndParent, IN LPCWSTR HardwareId, IN LPCWSTR FullInfPath, IN DWORD InstallFlags, OUT PBOOL bRebootRequired OPTIONAL) { DEVINSTDATA DevInstData; DWORD i; LPWSTR Buffer = NULL; DWORD BufferSize; LPCWSTR CurrentHardwareId; /* Pointer into Buffer */ BOOL FoundHardwareId, FoundAtLeastOneDevice = FALSE; BOOL ret = FALSE; DevInstData.hDevInfo = INVALID_HANDLE_VALUE; TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n", hwndParent, debugstr_w(HardwareId), debugstr_w(FullInfPath), InstallFlags, bRebootRequired); /* FIXME: InstallFlags bRebootRequired ignored! */ /* Check flags */ if (InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE)) { TRACE("Unknown flags: 0x%08lx\n", InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE)); SetLastError(ERROR_INVALID_FLAGS); goto cleanup; } /* Enumerate all devices of the system */ DevInstData.hDevInfo = SetupDiGetClassDevsW(NULL, NULL, hwndParent, DIGCF_ALLCLASSES | DIGCF_PRESENT); if (DevInstData.hDevInfo == INVALID_HANDLE_VALUE) goto cleanup; DevInstData.devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; ; i++) { if (!SetupDiEnumDeviceInfo(DevInstData.hDevInfo, i, &DevInstData.devInfoData)) { if (GetLastError() != ERROR_NO_MORE_ITEMS) { TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError()); goto cleanup; } /* This error was expected */ break; } /* Get Hardware ID */ HeapFree(GetProcessHeap(), 0, Buffer); Buffer = NULL; BufferSize = 0; while (!SetupDiGetDeviceRegistryPropertyW( DevInstData.hDevInfo, &DevInstData.devInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)Buffer, BufferSize, &BufferSize)) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { Buffer = NULL; break; } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError()); goto cleanup; } /* This error was expected */ HeapFree(GetProcessHeap(), 0, Buffer); Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize); if (!Buffer) { TRACE("HeapAlloc() failed\n", GetLastError()); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } } if (Buffer == NULL) continue; /* Check if we match the given hardware ID */ FoundHardwareId = FALSE; for (CurrentHardwareId = Buffer; *CurrentHardwareId != UNICODE_NULL; CurrentHardwareId += wcslen(CurrentHardwareId) + 1) { if (wcscmp(CurrentHardwareId, HardwareId) == 0) { FoundHardwareId = TRUE; break; } } if (!FoundHardwareId) continue; /* We need to try to update the driver of this device */ /* Get Instance ID */ HeapFree(GetProcessHeap(), 0, Buffer); Buffer = NULL; if (SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, NULL, 0, &BufferSize)) { /* Error, as the output buffer should be too small */ SetLastError(ERROR_GEN_FAILURE); goto cleanup; } else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError()); goto cleanup; } else if ((Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize * sizeof(WCHAR))) == NULL) { TRACE("HeapAlloc() failed\n", GetLastError()); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; } else if (!SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, Buffer, BufferSize, NULL)) { TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError()); goto cleanup; } TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer)); /* Search driver in the specified .inf file */ if (!SearchDriver(&DevInstData, NULL, FullInfPath)) { TRACE("SearchDriver() failed with error 0x%x\n", GetLastError()); continue; } /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */ //if (!InstallCurrentDriver(&DevInstData)) if (!InstallCurrentDriver(&DevInstData) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD) { TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError()); continue; } FoundAtLeastOneDevice = TRUE; } if (FoundAtLeastOneDevice) { SetLastError(NO_ERROR); ret = TRUE; } else { TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId)); SetLastError(ERROR_NO_SUCH_DEVINST); } cleanup: if (DevInstData.hDevInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(DevInstData.hDevInfo); HeapFree(GetProcessHeap(), 0, Buffer); return ret; }
static DWORD InstallParallelPort(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData) { WCHAR szDeviceDescription[256]; WCHAR szFriendlyName[256]; WCHAR szPortName[8]; DWORD dwPortNumber = 0; DWORD dwSize; LONG lError; HKEY hKey; TRACE("InstallParallelPort(%p, %p)\n", DeviceInfoSet, DeviceInfoData); /* Try to read the 'PortName' value and determine the port number */ hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); if (hKey != INVALID_HANDLE_VALUE) { dwSize = sizeof(szPortName); lError = RegQueryValueEx(hKey, L"PortName", NULL, NULL, (PBYTE)szPortName, &dwSize); if (lError == ERROR_SUCCESS) { if (_wcsnicmp(szPortName, pszLpt, wcslen(pszLpt)) == 0) { dwPortNumber = _wtoi(szPortName + wcslen(pszLpt)); TRACE("LPT port number found: %lu\n", dwPortNumber); } } RegCloseKey(hKey); } /* ... try to determine the port number from its resources */ if (dwPortNumber == 0) { dwPortNumber = GetParallelPortNumber(DeviceInfoSet, DeviceInfoData); TRACE("GetParallelPortNumber() returned port number: %lu\n", dwPortNumber); } if (dwPortNumber == 0) { /* FIXME */ FIXME("Got no valid port numer!\n"); } if (dwPortNumber != 0) { swprintf(szPortName, L"%s%u", pszLpt, dwPortNumber); } else { wcscpy(szPortName, L"LPTx"); } if (dwPortNumber != 0) { /* Set the 'PortName' value */ hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, NULL, NULL); if (hKey != INVALID_HANDLE_VALUE) { RegSetValueExW(hKey, L"PortName", 0, REG_SZ, (LPBYTE)szPortName, (wcslen(szPortName) + 1) * sizeof(WCHAR)); RegCloseKey(hKey); } } /* Install the device */ if (!SetupDiInstallDevice(DeviceInfoSet, DeviceInfoData)) { return GetLastError(); } /* Get the device description... */ if (SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC, NULL, (LPBYTE)szDeviceDescription, 256 * sizeof(WCHAR), NULL)) { /* ... and use it to build a new friendly name */ swprintf(szFriendlyName, L"%s (%s)", szDeviceDescription, szPortName); } else { /* ... or build a generic friendly name */ swprintf(szFriendlyName, L"Parallel Port (%s)", szPortName); } TRACE("Friendly name: %S\n", szFriendlyName); /* Set the friendly name for the device */ SetupDiSetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, SPDRP_FRIENDLYNAME, (LPBYTE)szFriendlyName, (wcslen(szFriendlyName) + 1) * sizeof(WCHAR)); return ERROR_SUCCESS; }
/* * sapiCreateSetupDBSnapshot * * Purpose: * * Collects Setup API information to the linked list. * * Returned buffer must be freed with sapiFreeSnapshot after usage. * */ PVOID sapiCreateSetupDBSnapshot( VOID ) { BOOL cond = FALSE; PSAPIDBOBJ sObj; SP_DEVINFO_DATA DeviceInfoData; DWORD i, DataType = 0; DWORD DataSize, ReturnedDataSize = 0; PSAPIDBENTRY Entry; sObj = VirtualAlloc(NULL, sizeof(SAPIDBOBJ), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (sObj == NULL) return NULL; sObj->hDevInfo = NULL; sObj->sapiDBHead.Blink = NULL; sObj->sapiDBHead.Flink = NULL; InitializeCriticalSection(&sObj->objCS); do { sObj->hDevInfo = SetupDiGetClassDevsW(NULL, NULL, NULL, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (sObj->hDevInfo == INVALID_HANDLE_VALUE) break; InitializeListHead(&sObj->sapiDBHead); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (i = 0; SetupDiEnumDeviceInfo(sObj->hDevInfo, i, &DeviceInfoData); i++) { Entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(SAPIDBENTRY)); if (Entry == NULL) break; // first query lpDeviceName DataSize = MAX_PATH * sizeof(WCHAR); Entry->lpDeviceName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DataSize); if (Entry->lpDeviceName != NULL) { SetupDiGetDeviceRegistryPropertyW(sObj->hDevInfo, &DeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &DataType, (PBYTE)Entry->lpDeviceName, DataSize, &ReturnedDataSize); // not enough memory for call, reallocate if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { HeapFree(GetProcessHeap(), 0, Entry->lpDeviceName); Entry->lpDeviceName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ReturnedDataSize); if (Entry->lpDeviceName != NULL) { SetupDiGetDeviceRegistryPropertyW(sObj->hDevInfo, &DeviceInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, &DataType, (PBYTE)Entry->lpDeviceName, ReturnedDataSize, &ReturnedDataSize); } } } DataSize = MAX_PATH * sizeof(WCHAR); Entry->lpDeviceDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DataSize); if (Entry->lpDeviceDesc != NULL) { SetupDiGetDeviceRegistryPropertyW(sObj->hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, &DataType, (PBYTE)Entry->lpDeviceDesc, DataSize, &ReturnedDataSize); // not enough memory for call, reallocate if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { HeapFree(GetProcessHeap(), 0, Entry->lpDeviceDesc); Entry->lpDeviceDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ReturnedDataSize); if (Entry->lpDeviceDesc != NULL) { SetupDiGetDeviceRegistryPropertyW(sObj->hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, &DataType, (PBYTE)Entry->lpDeviceDesc, ReturnedDataSize, &ReturnedDataSize); } } } InsertHeadList(&sObj->sapiDBHead, &Entry->ListEntry); } //for } while (cond); return sObj; }
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); }
VOID Mij_EnumerateDevices() { HANDLE deviceInfo = NULL; deviceInfo = SetupDiGetClassDevsW(NULL, L"USB", NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); if (deviceInfo != INVALID_HANDLE_VALUE) { BOOLEAN flag = TRUE; unsigned int num = 0; while (flag) { SP_DEVINFO_DATA deviceData; Memory_Clear(&deviceData, sizeof(SP_DEVINFO_DATA)); deviceData.cbSize = sizeof(SP_DEVINFO_DATA); deviceData.DevInst = NULL; deviceData.Reserved = 0; flag = SetupDiEnumDeviceInfo(deviceInfo, num, &deviceData); if (flag) { wchar_t propertyBuffer[1000]; DWORD requiredSize = 0; DWORD propertyDataType = 1; if (SetupDiGetDeviceRegistryPropertyW( deviceInfo, &deviceData, SPDRP_HARDWAREID, &propertyDataType, &propertyBuffer, 1000 * sizeof(wchar_t), &requiredSize)) { BOOLEAN flag2 = FALSE; int i; // Direct Match, definitely a device we recognize for (i = 0; i < sizeof(KnownDevices) / sizeof(KnownDevices[0]); i++) { if (String_CompareIgnoreCaseN(propertyBuffer, KnownDevices[i].RegistryId, 22)) { flag2 = TRUE; Log(L"found %s [%s]", KnownDevices[i].FriendlyName, propertyBuffer); break; } } // Possible devices that could work if (!flag2 && SetupDiGetDeviceRegistryPropertyW( deviceInfo, &deviceData, SPDRP_COMPATIBLEIDS, &propertyDataType, &propertyBuffer, 1000 * sizeof(wchar_t), &requiredSize)) { //Bluetooth Device //BaseClass[0xE0] = Wireless Controller, //SubClass[0x01] = Wireless Radio, //Protocol[0x01] = Bluetooth Programming Interface //https://web.archive.org/web/20070626033649/http://www.usb.org/developers/defined_class/#BaseClassE0h if (String_CompareIgnoreCaseN(propertyBuffer, L"usb\\Class_e0&subClass_01&Prot_01", 33)) { Log(L"found Bluetooth device %s", propertyBuffer); flag2 = TRUE; } //Controller else if (String_CompareIgnoreCaseN(propertyBuffer, L"usb\\Class_58&subClass_42", 25)) { Log(L"found Controller %s", propertyBuffer); flag2 = TRUE; } } if (flag2) { //Callback(&deviceData); //GetDeviceDetail(deviceInfo, &deviceData); Log(L"Installing driver..."); InstallDriver(deviceInfo, &deviceData); Log(L"Finished Installing driver..."); } } } num += 1; } } }