DWORD InstallInfOnDevice( IN HWND hWnd, HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PTSTR Inf, BOOL DelayInstall ) { DWORD Err = NO_ERROR; SP_DEVINSTALL_PARAMS DeviceInstallParams; BOOL Reboot = FALSE; if (!SetupDiSetSelectedDevice(DeviceInfoSet, DeviceInfoData)) { Err = GetLastError(); goto exit; } DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); if (!SetupDiGetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &DeviceInstallParams)) { Err = GetLastError(); goto exit; } // // Set DriverPath to the path of the INF that we want to install from. // Set the DI_ENUMSINGLEINFO so setupapi builds up a driver list just from // this specific INF. // Set DI_DONOTCALLCONFIGMG so that we won't call kernel PnP when installing // the driver. This will do all the install actions except stop/start the // device so it won't start using the new driver until a reboot. // StringCchCopy(DeviceInstallParams.DriverPath, SIZECHARS(DeviceInstallParams.DriverPath), Inf); DeviceInstallParams.hwndParent = hWnd; DeviceInstallParams.Flags |= (DI_ENUMSINGLEINF | DI_QUIETINSTALL); if (DelayInstall) { DeviceInstallParams.Flags |= DI_DONOTCALLCONFIGMG; } DeviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; if (!SetupDiSetDeviceInstallParams(DeviceInfoSet, DeviceInfoData, &DeviceInstallParams)) { Err = GetLastError(); goto exit; } // // Build up a list of drivers from the specified INFs // if (!SetupDiBuildDriverInfoList(DeviceInfoSet, DeviceInfoData, SPDIT_COMPATDRIVER)) { Err = GetLastError(); goto exit; } // // Tell setupapi and the class installers to select the best driver from the // list built from the specified INF. // if (!SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV, DeviceInfoSet, DeviceInfoData)) { Err = GetLastError(); goto exit; } // // Install the selected driver on the selected device without calling kernel mode // if (!InstallSelectedDriver(hWnd, DeviceInfoSet, NULL, FALSE, &Reboot)) { Err = GetLastError(); goto exit; } exit: return Err; }
int removeNetworkInterface(MSIHANDLE hModule, const WCHAR *pwszGUID) { int rc = 1; do { WCHAR wszPnPInstanceId[512] = {0}; /* We have to find the device instance ID through a registry search */ HKEY hkeyNetwork = 0; HKEY hkeyConnection = 0; do /* break-loop */ { WCHAR wszRegLocation[256]; swprintf(wszRegLocation, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s", pwszGUID); LONG lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszRegLocation, 0, KEY_READ, &hkeyNetwork); if ((lStatus != ERROR_SUCCESS) || !hkeyNetwork) SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [1]", wszRegLocation)); lStatus = RegOpenKeyExW(hkeyNetwork, L"Connection", 0, KEY_READ, &hkeyConnection); if ((lStatus != ERROR_SUCCESS) || !hkeyConnection) SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [2]", wszRegLocation)); DWORD len = sizeof(wszPnPInstanceId); DWORD dwKeyType; lStatus = RegQueryValueExW(hkeyConnection, L"PnPInstanceID", NULL, &dwKeyType, (LPBYTE)&wszPnPInstanceId[0], &len); if ((lStatus != ERROR_SUCCESS) || (dwKeyType != REG_SZ)) SetErrBreak((L"VBox HostInterfaces: Host interface network was not found in registry (%s)! [3]", wszRegLocation)); } while (0); if (hkeyConnection) RegCloseKey(hkeyConnection); if (hkeyNetwork) RegCloseKey(hkeyNetwork); /* * Now we are going to enumerate all network devices and * wait until we encounter the right device instance ID */ HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; BOOL fResult; do { DWORD ret = 0; GUID netGuid; SP_DEVINFO_DATA DeviceInfoData; DWORD index = 0; DWORD size = 0; /* initialize the structure size */ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); /* copy the net class GUID */ memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof (GUID_DEVCLASS_NET)); /* return a device info set contains all installed devices of the Net class */ hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT); if (hDeviceInfo == INVALID_HANDLE_VALUE) { logStringW(hModule, L"VBox HostInterfaces: SetupDiGetClassDevs failed (0x%08X)!", GetLastError()); SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!"); } BOOL fFoundDevice = FALSE; /* enumerate the driver info list */ while (TRUE) { WCHAR *pwszDeviceHwid; fResult = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); if (!fResult) { if (GetLastError() == ERROR_NO_MORE_ITEMS) break; else { index++; continue; } } /* try to get the hardware ID registry property */ fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, NULL, 0, &size); if (!fResult) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { index++; continue; } pwszDeviceHwid = (WCHAR *)malloc(size); if (pwszDeviceHwid) { fResult = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)pwszDeviceHwid, size, NULL); if (!fResult) { free(pwszDeviceHwid); pwszDeviceHwid = NULL; index++; continue; } } } else { /* something is wrong. This shouldn't have worked with a NULL buffer */ index++; continue; } for (WCHAR *t = pwszDeviceHwid; t && *t && t < &pwszDeviceHwid[size / sizeof(WCHAR)]; t += wcslen(t) + 1) { if (!_wcsicmp(L"vboxtap", t)) { /* get the device instance ID */ WCHAR wszDevID[MAX_DEVICE_ID_LEN]; if (CM_Get_Device_IDW(DeviceInfoData.DevInst, wszDevID, MAX_DEVICE_ID_LEN, 0) == CR_SUCCESS) { /* compare to what we determined before */ if (!wcscmp(wszDevID, wszPnPInstanceId)) { fFoundDevice = TRUE; break; } } } } if (pwszDeviceHwid) { free(pwszDeviceHwid); pwszDeviceHwid = NULL; } if (fFoundDevice) break; index++; } if (fFoundDevice) { fResult = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); if (!fResult) { logStringW(hModule, L"VBox HostInterfaces: SetupDiSetSelectedDevice failed (0x%08X)!", GetLastError()); SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!"); } fResult = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); if (!fResult) { logStringW(hModule, L"VBox HostInterfaces: SetupDiCallClassInstaller (DIF_REMOVE) failed (0x%08X)!", GetLastError()); SetErrBreak(L"VBox HostInterfaces: Uninstallation failed!"); } } else SetErrBreak(L"VBox HostInterfaces: Host interface network device not found!"); } while (0); /* clean up the device info set */ if (hDeviceInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDeviceInfo); } while (0); return rc; }
extern "C" DWORD InstallLoopBack(LPCTSTR pConnectionName, LPCTSTR ip, LPCTSTR mask) { BOOL ok; DWORD ret = 0; GUID netGuid; HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; SP_DRVINFO_DATA DriverInfoData; SP_DEVINSTALL_PARAMS DeviceInstallParams; TCHAR className[MAX_PATH]; TCHAR temp[MAX_PATH]; DWORD index = 0; BOOL found = FALSE; BOOL registered = FALSE; BOOL destroyList = FALSE; PSP_DRVINFO_DETAIL_DATA pDriverInfoDetail; DWORD detailBuf[2048]; // for our purposes, 8k buffer is more // than enough to obtain the hardware ID // of the loopback driver. HKEY hkey = NULL; DWORD cbSize; DWORD dwValueType; TCHAR pCfgGuidString[40]; // initialize the structure size DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); // copy the net class GUID memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); // create an empty device info set associated with the net class GUID hDeviceInfo = SetupDiCreateDeviceInfoList(&netGuid, NULL); if (hDeviceInfo == INVALID_HANDLE_VALUE) return GetLastError(); // get the class name from GUID ok = SetupDiClassNameFromGuid(&netGuid, className, MAX_PATH, NULL); if (!ok) { ret = GetLastError(); goto cleanup; } // create a device info element and add the new device instance // key to registry ok = SetupDiCreateDeviceInfo(hDeviceInfo, className, &netGuid, NULL, NULL, DICD_GENERATE_ID, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // select the newly created device info to be the currently // selected member ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // build a list of class drivers ok = SetupDiBuildDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); if (!ok) { ret = GetLastError(); goto cleanup; } destroyList = TRUE; // enumerate the driver info list while (TRUE) { BOOL ret; ret = SetupDiEnumDriverInfo(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER, index, &DriverInfoData); // if the function failed and GetLastError() returned // ERROR_NO_MORE_ITEMS, then we have reached the end of the // list. Othewise there was something wrong with this // particular driver. if(!ret) { if(GetLastError() == ERROR_NO_MORE_ITEMS) break; else { index++; continue; } } pDriverInfoDetail = (PSP_DRVINFO_DETAIL_DATA) detailBuf; pDriverInfoDetail->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); // if we successfully find the hardware ID and it turns out to // be the one for the loopback driver, then we are done. if (SetupDiGetDriverInfoDetail(hDeviceInfo, &DeviceInfoData, &DriverInfoData, pDriverInfoDetail, sizeof(detailBuf), NULL)) { TCHAR * t; // pDriverInfoDetail->HardwareID is a MULTISZ string. Go through the // whole list and see if there is a match somewhere. t = pDriverInfoDetail->HardwareID; while (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { if (!_tcsicmp(t, DRIVERHWID)) break; t += _tcslen(t) + 1; } if (t && *t && t < (TCHAR *) &detailBuf[sizeof(detailBuf)/sizeof(detailBuf[0])]) { found = TRUE; break; } } index++; } if (!found) { ret = GetLastError(); ReportMessage(0,"Could not find the driver to install", DRIVER_DESC, NULL, 0); goto cleanup; } // set the loopback driver to be the currently selected ok = SetupDiSetSelectedDriver(hDeviceInfo, &DeviceInfoData, &DriverInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // register the phantom device to repare for install ok = SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // registered, but remove if errors occur in the following code registered = TRUE; // ask the installer if we can install the device ok = SetupDiCallClassInstaller(DIF_ALLOW_INSTALL, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); if (ret != ERROR_DI_DO_DEFAULT) { goto cleanup; } else ret = 0; } // install the files first ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // get the device install parameters and disable filecopy DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); ok = SetupDiGetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (ok) { DeviceInstallParams.Flags |= DI_NOFILECOPY; ok = SetupDiSetDeviceInstallParams(hDeviceInfo, &DeviceInfoData, &DeviceInstallParams); if (!ok) { ret = GetLastError(); goto cleanup; } } // // Register any device-specific co-installers for this device, // ok = SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } // // install any installer-specified interfaces. // and then do the real install // ok = SetupDiCallClassInstaller(DIF_INSTALLINTERFACES, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } PAUSE; ok = SetupDiCallClassInstaller(DIF_INSTALLDEVICE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); PAUSE; goto cleanup; } /* Skip to the end if we aren't setting the name */ if (!pConnectionName) goto cleanup; // Figure out NetCfgInstanceId hkey = SetupDiOpenDevRegKey(hDeviceInfo, &DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); if (hkey == INVALID_HANDLE_VALUE) { ret = GetLastError(); goto cleanup; } cbSize = sizeof(pCfgGuidString); ret = RegQueryValueEx(hkey, _T("NetCfgInstanceId"), NULL, &dwValueType, (LPBYTE)pCfgGuidString, &cbSize); RegCloseKey(hkey); ret = RenameConnection(pCfgGuidString, pConnectionName); if (ret) { ReportMessage(0,"Could not set the connection name", NULL, pConnectionName, 0); goto cleanup; } if (!ip) goto cleanup; ret = SetIpAddress(pCfgGuidString, ip, mask); if (ret) { ReportMessage(0,"Could not set the ip address and network mask",NULL,NULL,ret); goto cleanup; } ret = LoopbackBindings(pCfgGuidString); if (ret) { ReportMessage(0,"Could not properly set the bindings",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "hosts", FALSE ); if (ret) { ReportMessage(0,"Could not update hosts file",NULL,NULL,0); goto cleanup; } ret = !UpdateHostsFile( pConnectionName, ip, "lmhosts", TRUE ); if (ret) { ReportMessage(0,"Could not update lmhosts file",NULL,NULL,0); goto cleanup; } cleanup: // an error has occured, but the device is registered, we must remove it if (ret != 0 && registered) SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); found = SetupDiDeleteDeviceInfo(hDeviceInfo, &DeviceInfoData); // destroy the driver info list if (destroyList) SetupDiDestroyDriverInfoList(hDeviceInfo, &DeviceInfoData, SPDIT_CLASSDRIVER); // clean up the device info set if (hDeviceInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDeviceInfo); return ret; };
extern "C" DWORD UnInstallLoopBack(void) { BOOL ok; DWORD ret = 0; GUID netGuid; HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; DWORD index = 0; BOOL found = FALSE; DWORD size = 0; // initialize the structure size DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); // copy the net class GUID memcpy(&netGuid, &GUID_DEVCLASS_NET, sizeof(GUID_DEVCLASS_NET)); // return a device info set contains all installed devices of the Net class hDeviceInfo = SetupDiGetClassDevs(&netGuid, NULL, NULL, DIGCF_PRESENT); if (hDeviceInfo == INVALID_HANDLE_VALUE) return GetLastError(); // enumerate the driver info list while (TRUE) { TCHAR * deviceHwid; ok = SetupDiEnumDeviceInfo(hDeviceInfo, index, &DeviceInfoData); if(!ok) { if(GetLastError() == ERROR_NO_MORE_ITEMS) break; else { index++; continue; } } // try to get the DeviceDesc registry property ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, NULL, 0, &size); if (!ok) { ret = GetLastError(); if (ret != ERROR_INSUFFICIENT_BUFFER) { index++; continue; } deviceHwid = (TCHAR *)malloc(size); ok = SetupDiGetDeviceRegistryProperty(hDeviceInfo, &DeviceInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)deviceHwid, size, NULL); if (!ok) { free(deviceHwid); deviceHwid = NULL; index++; continue; } } else { // something is wrong. This shouldn't have worked with a NULL buffer ReportMessage(0, "GetDeviceRegistryProperty succeeded with a NULL buffer", NULL, NULL, 0); index++; continue; } for (TCHAR *t = deviceHwid; t && *t && t < &deviceHwid[size / sizeof(TCHAR)]; t += _tcslen(t) + 1) { if(!_tcsicmp(DRIVERHWID, t)) { found = TRUE; break; } } if (deviceHwid) { free(deviceHwid); deviceHwid = NULL; } if (found) break; index++; } if (found == FALSE) { ret = GetLastError(); ReportMessage(0,"Driver does not seem to be installed", DRIVER_DESC, NULL, ret); goto cleanup; } ok = SetupDiSetSelectedDevice(hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } ok = SetupDiCallClassInstaller(DIF_REMOVE, hDeviceInfo, &DeviceInfoData); if (!ok) { ret = GetLastError(); goto cleanup; } ret = 0; cleanup: // clean up the device info set if (hDeviceInfo != INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hDeviceInfo); return ret; }
void InstallDriver( HANDLE DeviceInformation, SP_DEVINFO_DATA* DeviceData ) { SP_DEVINSTALL_PARAMS_W deviceInstallParams; SP_DRVINFO_DATA_V2_W driverData; UINT32 reboot = 0; HANDLE module; DWORD address; BYTE *addr; if (!SetupDiSetSelectedDevice(DeviceInformation, DeviceData)) { Log(L"Set Selected Device fail."); return; } Memory_Clear(&deviceInstallParams, sizeof(SP_DEVINSTALL_PARAMS_W)); if (sizeof(int*) == 8) { deviceInstallParams.cbSize = 584; } else { deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W); } if (!SetupDiGetDeviceInstallParamsW(DeviceInformation, DeviceData, &deviceInstallParams)) { Log(L"Get Device Install Params fail."); return; } String_Copy(deviceInstallParams.DriverPath, L"C:\\mij\\drivers\\MijXinput.inf"); deviceInstallParams.Flags |= 65536; if (!SetupDiSetDeviceInstallParamsW(DeviceInformation, DeviceData, &deviceInstallParams)) { Log(L"Set Device Install Params fail."); return; } if (!SetupDiBuildDriverInfoList(DeviceInformation, DeviceData, SPDIT_COMPATDRIVER)) { Log(L"Building Driver Info List fail."); return; } if (!SetupDiSelectBestCompatDrv(DeviceInformation, DeviceData)) { Log(L"Select Best Compatible Driver fail."); return; } Memory_Clear(&driverData, sizeof(SP_DRVINFO_DATA_V2_W)); driverData.cbSize = sizeof(SP_DRVINFO_DATA_V2_W); if (!SetupDiGetSelectedDriverW(DeviceInformation, DeviceData, &driverData)) { Log(L"Get MotioninJoy Driver fail."); return; } //DiInstallDevice willfully returns 0xE0000235 (ERROR_IN_WOW64) in a WOW64 environment. //I don't know if this was a security restraint but there is no reason why this function //should not work under WOW64. All we have to do is insert one, literally one jmp patch to //skip the WOW64 check and the function succeeds as normal. module = Module_GetHandle(L"newdev.dll"); address = Module_GetProcedureAddress(module, "DiInstallDevice"); address += 0x134; addr = address; if ((*addr) == 0x74) //je { DWORD oldPageProtection = 0; //We firstly have to remove page protection of course. VirtualProtect(addr, 1, PAGE_EXECUTE_READWRITE, &oldPageProtection); //patch to jne *addr = 0x75; //Lastly, make it look like we were never even there by restoring protection VirtualProtect(addr, 1, oldPageProtection, &oldPageProtection); } if (!DiInstallDevice(NULL, DeviceInformation, DeviceData, &driverData, 0, &reboot)) { Log(L"Install MotioninJoy Driver fail."); } }