static void frida_foreach_usb_device (const GUID * guid, FridaEnumerateDeviceFunc func, gpointer user_data) { HANDLE info_set; gboolean carry_on = TRUE; guint member_index; info_set = SetupDiGetClassDevs (guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT); if (info_set == INVALID_HANDLE_VALUE) goto beach; for (member_index = 0; carry_on; member_index++) { SP_DEVICE_INTERFACE_DATA iface_data = { 0, }; SP_DEVINFO_DATA info_data = { 0, }; DWORD detail_size; SP_DEVICE_INTERFACE_DETAIL_DATA_W * detail_data = NULL; BOOL success; FridaDeviceInfo device_info = { 0, }; DWORD instance_id_size; iface_data.cbSize = sizeof (iface_data); if (!SetupDiEnumDeviceInterfaces (info_set, NULL, guid, member_index, &iface_data)) break; info_data.cbSize = sizeof (info_data); success = SetupDiGetDeviceInterfaceDetailW (info_set, &iface_data, NULL, 0, &detail_size, &info_data); if (!success && GetLastError () != ERROR_INSUFFICIENT_BUFFER) goto skip_device; detail_data = (SP_DEVICE_INTERFACE_DETAIL_DATA_W *) g_malloc (detail_size); detail_data->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA_W); success = SetupDiGetDeviceInterfaceDetailW (info_set, &iface_data, detail_data, detail_size, NULL, &info_data); if (!success) goto skip_device; device_info.device_path = detail_data->DevicePath; success = SetupDiGetDeviceInstanceIdW (info_set, &info_data, NULL, 0, &instance_id_size); if (!success && GetLastError () != ERROR_INSUFFICIENT_BUFFER) goto skip_device; device_info.instance_id = (WCHAR *) g_malloc (instance_id_size * sizeof (WCHAR)); success = SetupDiGetDeviceInstanceIdW (info_set, &info_data, device_info.instance_id, instance_id_size, NULL); if (!success) goto skip_device; device_info.friendly_name = frida_read_device_registry_string_property (info_set, &info_data, SPDRP_FRIENDLYNAME); device_info.location = frida_read_device_registry_string_property (info_set, &info_data, SPDRP_LOCATION_INFORMATION); device_info.device_info_set = info_set; device_info.device_info_data = &info_data; carry_on = func (&device_info, user_data); skip_device: g_free (device_info.location); g_free (device_info.friendly_name); g_free (device_info.instance_id); g_free (detail_data); } beach: if (info_set != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList (info_set); }
static DWORD InstallNetDevice( IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, LPCWSTR UuidString, DWORD Characteristics, LPCWSTR BusType) { LPWSTR InstanceId = NULL; LPWSTR DeviceName = NULL; LPWSTR ExportName = NULL; LONG rc; HKEY hKey = NULL; HKEY hNetworkKey = NULL; HKEY hLinkageKey = NULL; HKEY hConnectionKey = NULL; DWORD dwShowIcon, dwLength, dwValue; WCHAR szBuffer[300]; /* Get Instance ID */ if (SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, NULL, 0, &dwLength)) { DPRINT("SetupDiGetDeviceInstanceIdW() returned TRUE. FALSE expected\n"); rc = ERROR_GEN_FAILURE; goto cleanup; } InstanceId = HeapAlloc(GetProcessHeap(), 0, dwLength * sizeof(WCHAR)); if (!InstanceId) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } if (!SetupDiGetDeviceInstanceIdW(DeviceInfoSet, DeviceInfoData, InstanceId, dwLength, NULL)) { rc = GetLastError(); DPRINT("SetupDiGetDeviceInstanceIdW() failed with error 0x%lx\n", rc); goto cleanup; } /* Create device name */ DeviceName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); if (!DeviceName) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } wcscpy(DeviceName, L"\\Device\\"); wcscat(DeviceName, UuidString); /* Create export name */ ExportName = HeapAlloc(GetProcessHeap(), 0, (wcslen(L"\\Device\\Tcpip_") + wcslen(UuidString)) * sizeof(WCHAR) + sizeof(UNICODE_NULL)); if (!ExportName) { DPRINT("HeapAlloc() failed\n"); rc = ERROR_NOT_ENOUGH_MEMORY; goto cleanup; } wcscpy(ExportName, L"\\Device\\Tcpip_"); wcscat(ExportName, UuidString); /* Write Tcpip parameters in new service Key */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; rc = RegCreateKeyExW(hNetworkKey, L"Parameters\\Tcpip", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hNetworkKey); hNetworkKey = NULL; rc = RegSetValueExW(hKey, L"DefaultGateway", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"IPAddress", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"SubnetMask", 0, REG_SZ, (const BYTE*)L"0.0.0.0", (wcslen(L"0.0.0.0") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } dwValue = 1; rc = RegSetValueExW(hKey, L"EnableDHCP", 0, REG_DWORD, (const BYTE*)&dwValue, sizeof(DWORD)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; /* Write 'Linkage' key in hardware key */ #if _WIN32_WINNT >= 0x502 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE); #else hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS); #endif if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); if (hKey == INVALID_HANDLE_VALUE) { hKey = NULL; rc = GetLastError(); DPRINT("SetupDiCreateDevRegKeyW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"NetCfgInstanceId", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hKey, L"Characteristics", 0, REG_DWORD, (const BYTE*)&Characteristics, sizeof(DWORD)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } if (BusType) rc = RegSetValueExW(hKey, L"BusType", 0, REG_SZ, (const BYTE*)BusType, (wcslen(BusType) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, L"Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hLinkageKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"Export", 0, REG_SZ, (const BYTE*)DeviceName, (wcslen(DeviceName) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"RootDevice", 0, REG_SZ, (const BYTE*)UuidString, (wcslen(UuidString) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hLinkageKey, L"UpperBind", 0, REG_SZ, (const BYTE*)L"Tcpip", (wcslen(L"Tcpip") + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } RegCloseKey(hKey); hKey = NULL; /* Write connection information in network subkey */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hNetworkKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hNetworkKey, UuidString, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_CREATE_SUB_KEY, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegCreateKeyExW(hKey, L"Connection", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hConnectionKey, NULL); RegCloseKey(hKey); hKey = NULL; if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } if (!LoadStringW(netcfgx_hInstance, IDS_NET_CONNECT, szBuffer, sizeof(szBuffer)/sizeof(WCHAR))) { wcscpy(szBuffer,L"Network connection"); } rc = RegSetValueExW(hConnectionKey, L"Name", 0, REG_SZ, (const BYTE*)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = RegSetValueExW(hConnectionKey, L"PnpInstanceId", 0, REG_SZ, (const BYTE*)InstanceId, (wcslen(InstanceId) + 1) * sizeof(WCHAR)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } dwShowIcon = 1; rc = RegSetValueExW(hConnectionKey, L"ShowIcon", 0, REG_DWORD, (const BYTE*)&dwShowIcon, sizeof(dwShowIcon)); if (rc != ERROR_SUCCESS) { DPRINT("RegSetValueExW() failed with error 0x%lx\n", rc); goto cleanup; } /* Write linkage information in Tcpip service */ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Linkage", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { DPRINT("RegCreateKeyExW() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Bind", DeviceName); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Export", ExportName); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } rc = AppendStringToMultiSZ(hKey, L"Route", UuidString); if (rc != ERROR_SUCCESS) { DPRINT("AppendStringToMultiSZ() failed with error 0x%lx\n", rc); goto cleanup; } /* Install additionnal services */ rc = InstallAdditionalServices(NULL); if (rc != ERROR_SUCCESS) { DPRINT("InstallAdditionalServices() failed with error 0x%lx\n", rc); goto cleanup; } rc = ERROR_SUCCESS; cleanup: HeapFree(GetProcessHeap(), 0, InstanceId); HeapFree(GetProcessHeap(), 0, DeviceName); HeapFree(GetProcessHeap(), 0, ExportName); if (hKey != NULL) RegCloseKey(hKey); if (hNetworkKey != NULL) RegCloseKey(hNetworkKey); if (hLinkageKey != NULL) RegCloseKey(hLinkageKey); if (hConnectionKey != NULL) RegCloseKey(hConnectionKey); return rc; }
/* * @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; }
//+--------------------------------------------------------------------------- // // Function: HrShowNetAdapters // // Purpose: Display all installed net class devices using Setup API // // Arguments: None // // Returns: S_OK on success, otherwise an error code // // Notes: // HRESULT HrShowNetAdapters() { #define MAX_COMP_INSTID 4096 #define MAX_COMP_DESC 4096 HRESULT hr=S_OK; HDEVINFO hdi; DWORD dwIndex=0; SP_DEVINFO_DATA deid; BOOL fSuccess=FALSE; // DWORD cchRequiredSize; WCHAR szCompInstanceId[MAX_COMP_INSTID]; WCHAR szCompDescription[MAX_COMP_DESC]; DWORD dwRegType; BOOL fFound=FALSE; // get a list of all devices of class 'GUID_DEVCLASS_NET' hdi = SetupDiGetClassDevs((struct _GUID *)&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT); if (INVALID_HANDLE_VALUE != hdi) { // enumerate over each device while (deid.cbSize = sizeof(SP_DEVINFO_DATA), SetupDiEnumDeviceInfo(hdi, dwIndex, &deid)) { dwIndex++; // the right thing to do here would be to call this function // to get the size required to hold the instance ID and then // to call it second time with a buffer large enough for that size. // However, that would tend to obscure the control flow in // the sample code. Lets keep things simple by keeping the // buffer large enough. // get the device instance ID fSuccess = SetupDiGetDeviceInstanceIdW(hdi, &deid, szCompInstanceId, MAX_COMP_INSTID, NULL); if (fSuccess) { // get the description for this instance fSuccess = SetupDiGetDeviceRegistryProperty(hdi, &deid, SPDRP_DEVICEDESC, &dwRegType, (BYTE*) szCompDescription, MAX_COMP_DESC, NULL); if (fSuccess) { if (!fFound) { fFound = TRUE; } } } } // release the device info list SetupDiDestroyDeviceInfoList(hdi); } if (!fSuccess) { DWORD dwError = GetLastError(); hr = HRESULT_FROM_WIN32(dwError); } return hr; }