// //////////////////////////////////////////////////////////////////////////////// // @private StateChange // static BOOL StateChange(DWORD NewState, DWORD SelectedItem,HDEVINFO hDevInfo) { SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)}; SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; if ( !SetupDiEnumDeviceInfo(hDevInfo,SelectedItem,&DeviceInfoData) ) { return FALSE; } PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; PropChangeParams.Scope = DICS_FLAG_GLOBAL; PropChangeParams.StateChange = NewState; if ( !SetupDiSetClassInstallParams( hDevInfo, &DeviceInfoData, (SP_CLASSINSTALL_HEADER *)&PropChangeParams, sizeof(PropChangeParams)) ) { return FALSE; } if ( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData) ) { return TRUE; } return TRUE; }
VOID EnumerateDrivers(PVOID Context, HDEVINFO hList, PSP_DEVINFO_DATA pInfoData) { HSPFILEQ hQueue; SP_DEVINSTALL_PARAMS DeviceInstallParams = {0}; SP_DRVINFO_DATA DriverInfoData; DWORD Result; DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) return; DeviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); if (!SetupDiSetDeviceInstallParams(hList, pInfoData, &DeviceInstallParams)) return; if (!SetupDiBuildDriverInfoList(hList, pInfoData, SPDIT_CLASSDRIVER)) return; DriverInfoData.cbSize = sizeof(DriverInfoData); if (!SetupDiEnumDriverInfoW(hList, pInfoData, SPDIT_CLASSDRIVER, 0, &DriverInfoData)) return; DriverInfoData.cbSize = sizeof(DriverInfoData); if (!SetupDiSetSelectedDriverW(hList, pInfoData, &DriverInfoData)) return; hQueue = SetupOpenFileQueue(); if (hQueue == (HSPFILEQ)INVALID_HANDLE_VALUE) return; DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) { SetupCloseFileQueue(hQueue); return; } DeviceInstallParams.FileQueue = hQueue; DeviceInstallParams.Flags |= DI_NOVCP; if (!SetupDiSetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) { SetupCloseFileQueue(hQueue); return; } if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hList, pInfoData)) { SetupCloseFileQueue(hQueue); return; } /* enumerate the driver files */ SetupScanFileQueueW(hQueue, SPQ_SCAN_USE_CALLBACK, NULL, DriverFilesCallback, Context, &Result); SetupCloseFileQueue(hQueue); }
bool RemoveDevice( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, PCDevProperties pDevProperties, BOOL *pRebootRequired) { if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, pDevInfoData)) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCallClassInstaller(DIF_REMOVE, %s, %s)", pDevProperties->DevId(), pDevProperties->PhObjName()); return FALSE; } Trace("Removed %s %s %s\n", pDevProperties->Location(), pDevProperties->DevId(), pDevProperties->PhObjName()); return UpdateRebootRequired(hDevInfo, pDevInfoData, pRebootRequired); }
static int ti_reset_state(HDEVINFO *hdi, SP_DEVINFO_DATA *did, DWORD state) { SP_PROPCHANGE_PARAMS parm; parm.ClassInstallHeader.cbSize = sizeof(parm.ClassInstallHeader); parm.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; parm.Scope = DICS_FLAG_GLOBAL; parm.StateChange = state; if (!SetupDiSetClassInstallParams(*hdi, did, (SP_CLASSINSTALL_HEADER*) &parm, sizeof(parm))) return -1; if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, *hdi, did)) return -1; return 0; }
static BOOL StopDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data) { SP_PROPCHANGE_PARAMS p; if (info == NULL || dev_info_data == NULL) { return FALSE; } memset(&p, 0, sizeof(p)); p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; p.StateChange = DICS_DISABLE; p.Scope = DICS_FLAG_CONFIGSPECIFIC; if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == FALSE || SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == FALSE) { return FALSE; } return TRUE; }
BOOL CDevice::Restart() { SP_PROPCHANGE_PARAMS params; // initialize the structure memset(¶ms, 0, sizeof(params)); // initialize the SP_CLASSINSTALL_HEADER struct at the beginning // of the SP_PROPCHANGE_PARAMS struct, so that // SetupDiSetClassInstallParams will work params.ClassInstallHeader.cbSize = sizeof(params.ClassInstallHeader); params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; // initialize SP_PROPCHANGE_PARAMS such that the device will be // stopped. params.StateChange = DICS_PROPCHANGE; params.Scope = DICS_FLAG_CONFIGSPECIFIC; params.HwProfile = 0; // current profile if(!SetupDiSetClassInstallParams(m_hDev, &m_hDevInfo, (PSP_CLASSINSTALL_HEADER) ¶ms,sizeof(SP_PROPCHANGE_PARAMS))) { return FALSE; } // we call SetupDiCallClassInstaller() twice for the ECI USB ADSL // modem, maybe because it is 2 USB devices. But this is not // needed for all USB devices, so it's better for the end user to // hit the button "replug" twice. if(!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, m_hDev, &m_hDevInfo)) { return FALSE; } return TRUE; }
BOOL DeleteDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data) { SP_REMOVEDEVICE_PARAMS p; SP_DEVINFO_LIST_DETAIL_DATA detail; char device_id[MAX_PATH]; if (info == NULL || dev_info_data == NULL) { return FALSE; } memset(&detail, 0, sizeof(detail)); detail.cbSize = sizeof(detail); if (SetupDiGetDeviceInfoListDetail(info, &detail) == FALSE || CM_Get_Device_ID_Ex(dev_info_data->DevInst, device_id, sizeof(device_id), 0, detail.RemoteMachineHandle) != CR_SUCCESS) { logError("CM_Get_Device_ID_Ex: %x\n", GetLastError()); return FALSE; } memset(&p, 0, sizeof(p)); p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); p.ClassInstallHeader.InstallFunction = DIF_REMOVE; p.Scope = DI_REMOVEDEVICE_GLOBAL; if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == FALSE) { logError("SetupDiSetClassInstallParams: %x\n", GetLastError()); return FALSE; } if (SetupDiCallClassInstaller(DIF_REMOVE, info, dev_info_data) == FALSE) { logError("SetupDiCallClassInstaller: %x\n", GetLastError()); return FALSE; } return TRUE; }
static bool ChangeState(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, DWORD stateChange) { SP_PROPCHANGE_PARAMS propChangeParams; memset(&propChangeParams, 0, sizeof(propChangeParams)); propChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; propChangeParams.StateChange = stateChange; propChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC; propChangeParams.HwProfile = 0; if (!SetupDiSetClassInstallParams(hDevInfo, pDevInfoData, (SP_CLASSINSTALL_HEADER *)&propChangeParams, sizeof(propChangeParams))) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiSetClassInstallParams()"); return FALSE; } if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, pDevInfoData)) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCallClassInstaller(DIF_PROPERTYCHANGE)"); return FALSE; } return TRUE; }
bool install(const std::wstring& inf, const std::wstring& hardware_id, bool& reboot_required) { TCHAR inf_path[MAX_PATH]; if (GetFullPathName(inf.c_str(), MAX_PATH, inf_path, NULL) >= MAX_PATH) { return false; } std::wcerr << "INF file full path: " << inf_path << std::endl; bool result = false; TCHAR hardware_id_list[LINE_LEN + 4]; ZeroMemory(hardware_id_list, sizeof(hardware_id_list)); if (SUCCEEDED(StringCchCopy(hardware_id_list, LINE_LEN, hardware_id.c_str()))) { std::wcerr << "Hardware identifier list: " << hardware_id_list << std::endl; GUID class_guid; TCHAR class_name[MAX_CLASS_NAME_LEN]; if (SetupDiGetINFClass(inf_path, &class_guid, class_name, sizeof(class_name) / sizeof(class_name[0]), 0)) { std::wcerr << "Class name: " << class_name << std::endl; HDEVINFO device_info_set = INVALID_HANDLE_VALUE; device_info_set = SetupDiCreateDeviceInfoList(&class_guid, 0); if (device_info_set != INVALID_HANDLE_VALUE) { std::wcerr << "Device information set created." << std::endl; SP_DEVINFO_DATA device_info_data; device_info_data.cbSize = sizeof(SP_DEVINFO_DATA); if (SetupDiCreateDeviceInfo(device_info_set, class_name, &class_guid, NULL, 0, DICD_GENERATE_ID, &device_info_data)) { std::wcerr << "Device information element created." << std::endl; if (SetupDiSetDeviceRegistryProperty(device_info_set, &device_info_data, SPDRP_HARDWAREID, (LPBYTE)hardware_id_list, (lstrlen(hardware_id_list) + 1 + 1) * sizeof(TCHAR))) { std::wcerr << "Hardware id set." << std::endl; if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info_set, &device_info_data)) { std::wcerr << "Device registered." << std::endl; result = update(inf, hardware_id, reboot_required); } } } SetupDiDestroyDeviceInfoList(device_info_set); } } } return result; }
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; }
bool WinNetCard::NetCardStateChange(void * NetCardPoint, bool Enabled) { PNetCardStruct NetCard = (PNetCardStruct)NetCardPoint; DWORD DeviceId = NetCard->Id; HDEVINFO hDevInfo = 0; if (INVALID_HANDLE_VALUE == (hDevInfo = SetupDiGetClassDevs(NULL,NULL,0,DIGCF_PRESENT|DIGCF_ALLCLASSES))) { return false; } /* SetupDiGetClassDevs( (LPGUID) &GUID_DEVCLASS_NET, // GUID_DEVCLASS_NET表示仅列出网络设备 NULL, this->m_hWnd, DIGCF_PRESENT); */ SP_DEVINFO_DATA DeviceInfoData = {sizeof(SP_DEVINFO_DATA)}; DWORD Status, Problem; if (!SetupDiEnumDeviceInfo(hDevInfo,DeviceId,&DeviceInfoData)) // return false; if (CM_Get_DevNode_Status(&Status, &Problem, DeviceInfoData.DevInst,0) != CR_SUCCESS) //读取网卡状态 return false; SP_PROPCHANGE_PARAMS PropChangeParams = {sizeof(SP_CLASSINSTALL_HEADER)}; PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; PropChangeParams.Scope = DICS_FLAG_GLOBAL; if (Enabled) { if (!((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem))) { NetCard->Disabled = false; return false; } PropChangeParams.StateChange = DICS_ENABLE; } else { if ((Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem)) { NetCard->Disabled = true; return false; } if (!((Status & DN_DISABLEABLE) && (CM_PROB_HARDWARE_DISABLED != Problem))) return false; PropChangeParams.StateChange = DICS_DISABLE; } if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData,(SP_CLASSINSTALL_HEADER *)&PropChangeParams, sizeof(PropChangeParams))) {//功能:设置网卡有效或无效 return false; } if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData)) { return false; } if (CM_Get_DevNode_Status(&Status, &Problem,DeviceInfoData.DevInst,0) == CR_SUCCESS) { NetCard->Disabled = (Status & DN_HAS_PROBLEM) && (CM_PROB_DISABLED == Problem); } return true; }
VOID DisableNetworkAdapter(INetConnection * pNet, LANSTATUSUI_CONTEXT * pContext, HWND hwndDlg) { HKEY hKey; NETCON_PROPERTIES * pProperties; LPOLESTR pDisplayName; WCHAR szPath[200]; DWORD dwSize, dwType; LPWSTR pPnp; HDEVINFO hInfo; SP_DEVINFO_DATA DevInfo; SP_PROPCHANGE_PARAMS PropChangeParams; BOOL bClose = FALSE; NOTIFYICONDATAW nid; if (FAILED(pNet->GetProperties(&pProperties))) return; hInfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT ); if (!hInfo) { NcFreeNetconProperties(pProperties); return; } if (FAILED(StringFromCLSID((CLSID)pProperties->guidId, &pDisplayName))) { NcFreeNetconProperties(pProperties); SetupDiDestroyDeviceInfoList(hInfo); return; } NcFreeNetconProperties(pProperties); if (FindNetworkAdapter(hInfo, &DevInfo, pDisplayName)) { PropChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; //; PropChangeParams.StateChange = DICS_DISABLE; PropChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC; PropChangeParams.HwProfile = 0; if (SetupDiSetClassInstallParams(hInfo, &DevInfo, &PropChangeParams.ClassInstallHeader, sizeof(SP_PROPCHANGE_PARAMS))) { if (SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hInfo, &DevInfo)) bClose = TRUE; } } SetupDiDestroyDeviceInfoList(hInfo); swprintf(szPath, L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", pDisplayName); CoTaskMemFree(pDisplayName); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return; dwSize = 0; if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_SZ) { RegCloseKey(hKey); return; } pPnp = static_cast<PWSTR>(CoTaskMemAlloc(dwSize)); if (!pPnp) { RegCloseKey(hKey); return; } if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, &dwType, (LPBYTE)pPnp, &dwSize) != ERROR_SUCCESS) { CoTaskMemFree(pPnp); RegCloseKey(hKey); return; } RegCloseKey(hKey); swprintf(szPath, L"System\\CurrentControlSet\\Hardware Profiles\\Current\\System\\CurrentControlSet\\Enum\\%s", pPnp); CoTaskMemFree(pPnp); if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szPath, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS) return; dwSize = 1; /* enable = 0, disable = 1 */ RegSetValueExW(hKey, L"CSConfigFlags", 0, REG_DWORD, (LPBYTE)&dwSize, sizeof(DWORD)); RegCloseKey(hKey); if (!bClose) return; PropSheet_PressButton(GetParent(hwndDlg), PSBTN_CANCEL); ZeroMemory(&nid, sizeof(nid)); nid.cbSize = sizeof(nid); nid.uID = pContext->uID; nid.hWnd = pContext->hwndDlg; nid.uFlags = NIF_STATE; nid.dwState = NIS_HIDDEN; nid.dwStateMask = NIS_HIDDEN; Shell_NotifyIconW(NIM_MODIFY, &nid); }
NDASDI_API BOOL WINAPI NdasDiInstallRootEnumeratedDevice( IN HWND hwndParent, IN LPCTSTR szInfPath, IN LPCTSTR szHardwareId, IN DWORD InstallFlags, IN LPBOOL pbRebootRequired OPTIONAL) { _ASSERTE(NULL == pbRebootRequired || !IsBadWritePtr(pbRebootRequired, sizeof(BOOL))); BOOL fReturn = FALSE; BOOL fSuccess = FALSE; DWORD len; SP_DEVINFO_DATA DeviceInfoData; GUID ClassGuid; TCHAR ClassName[MAX_CLASS_NAME_LEN]; LPTSTR lpszFullInfPath = ResolveFullPath(szInfPath, NULL, NULL, 0); if (NULL == lpszFullInfPath) { goto cleanup; } // // List of hardware ID's must be double zero-terminated // TCHAR hardwareIdList[LINE_LEN+4] = {0}; size_t cchHardwareIdList = RTL_NUMBER_OF(hardwareIdList); size_t cchRemaining = cchHardwareIdList; HRESULT hr = StringCchCopyNEx( hardwareIdList, LINE_LEN + 4, szHardwareId, LINE_LEN, NULL, &cchRemaining, STRSAFE_FILL_BEHIND_NULL); _ASSERTE(SUCCEEDED(hr)); cchHardwareIdList -= cchRemaining - 1; // // Use the INF File to extract the Class GUID. // fSuccess = SetupDiGetINFClass( lpszFullInfPath, &ClassGuid, ClassName, RTL_NUMBER_OF(ClassName), NULL); if (!fSuccess) { goto cleanup; } // // Create the container for the to-be-created Device Information Element. // HDEVINFO DeviceInfoSet = SetupDiCreateDeviceInfoList( &ClassGuid, hwndParent); if(INVALID_HANDLE_VALUE == DeviceInfoSet) { goto cleanup; } // // Now create the element. // Use the Class GUID and Name from the INF file. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); fSuccess = SetupDiCreateDeviceInfo( DeviceInfoSet, ClassName, &ClassGuid, NULL, hwndParent, DICD_GENERATE_ID, &DeviceInfoData); if (!fSuccess) { goto cleanup; } // // Add the HardwareID to the Device's HardwareID property. // fSuccess = SetupDiSetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)hardwareIdList, cchHardwareIdList * sizeof(TCHAR)); if (!fSuccess) { goto cleanup; } // // Transform the registry element into an actual devnode // in the PnP HW tree. // fSuccess = SetupDiCallClassInstaller( DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData); if (!fSuccess) { goto cleanup; } // // The element is now registered. // You must explicitly remove the device using DIF_REMOVE, // if any failure is encountered from now on. // // // update the driver for the device we just created // fSuccess = UpdateDriverForPlugAndPlayDevices( hwndParent, szHardwareId, lpszFullInfPath, InstallFlags, pbRebootRequired); if (!fSuccess) { DWORD err = GetLastError(); fSuccess = SetupDiCallClassInstaller( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData); // // BUGBUG: If it may still require reboot? // SetLastError(err); goto cleanup; } fReturn = TRUE; cleanup: // save the last error DWORD err = GetLastError(); if (INVALID_HANDLE_VALUE != DeviceInfoSet) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } if (NULL != lpszFullInfPath) { LocalFree(lpszFullInfPath); } // restore the last error SetLastError(err); return fReturn; }
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; };
int InstallInf(_TCHAR *inf) { GUID ClassGUID; TCHAR ClassName[256]; HDEVINFO DeviceInfoSet = 0; SP_DEVINFO_DATA DeviceInfoData; TCHAR FullFilePath[1024]; PUpdateDriverForPlugAndPlayDevices pfnUpdateDriverForPlugAndPlayDevices; HMODULE hNewDev = NULL; DWORD Reboot; HWND hwnd = NULL; int ret = -1; if (!GetFullPathName(inf, sizeof(FullFilePath), FullFilePath, NULL)) { logError("GetFullPathName: %x\n", GetLastError()); return ret; } logInfo("Inf file: %s\n", FullFilePath); hNewDev = LoadLibrary(_T("newdev.dll")); if (!hNewDev) { logError("newdev.dll: %x\n", GetLastError()); return ret; } pfnUpdateDriverForPlugAndPlayDevices = (PUpdateDriverForPlugAndPlayDevices) GetProcAddress(hNewDev, (LPCSTR)"UpdateDriverForPlugAndPlayDevicesA"); if (!pfnUpdateDriverForPlugAndPlayDevices) { logError("UpdateDriverForPlugAndPlayDevices: %x\n", GetLastError()); goto FreeLib; } if (!SetupDiGetINFClass(FullFilePath, &ClassGUID, ClassName, sizeof(ClassName), 0)) { logError("SetupDiGetINFClass: %x\n", GetLastError()); goto FreeLib; } #if 0 logPrint("{%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX}\n", ClassGUID.Data1, ClassGUID.Data2, ClassGUID.Data3, ClassGUID.Data4[0], ClassGUID.Data4[1], ClassGUID.Data4[2], ClassGUID.Data4[3], ClassGUID.Data4[4], ClassGUID.Data4[5], ClassGUID.Data4[6], ClassGUID.Data4[7]); #endif if ((DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0)) == INVALID_HANDLE_VALUE) { logError("SetupDiCreateDeviceInfoList: %x\n", GetLastError()); goto FreeLib; } DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData)) { logError("SetupDiCreateDeviceInfo: %x\n", GetLastError()); goto SetupDiCreateDeviceInfoListError; } if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)DRIVER_NAME, (lstrlen(DRIVER_NAME)+2))) { logError("SetupDiSetDeviceRegistryProperty: %x\n", GetLastError()); goto SetupDiCreateDeviceInfoListError; } if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData)) { logError("SetupDiCallClassInstaller: %x\n", GetLastError()); goto SetupDiCreateDeviceInfoListError; } ret = pfnUpdateDriverForPlugAndPlayDevices(NULL, DRIVER_NAME, FullFilePath, 0, &Reboot); if (Reboot == DI_NEEDRESTART || Reboot == DI_NEEDREBOOT) { if (SetupPromptReboot(NULL, hwnd, FALSE) == -1) { ; // ToDo ?? } } ret = 0; SetupDiCreateDeviceInfoListError: SetupDiDestroyDeviceInfoList(DeviceInfoSet); FreeLib: FreeLibrary(hNewDev); return ret; }
BOOL InstallCurrentDriver( IN PDEVINSTDATA DevInstData) { BOOL ret; TRACE("Installing driver %s: %s\n", debugstr_w(DevInstData->drvInfoData.MfgName), debugstr_w(DevInstData->drvInfoData.Description)); ret = SetupDiCallClassInstaller( DIF_SELECTBESTCOMPATDRV, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_ALLOW_INSTALL, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_NEWDEVICEWIZARD_PREANALYZE, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_NEWDEVICEWIZARD_POSTANALYZE, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_INSTALLDEVICEFILES, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_REGISTER_COINSTALLERS, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_INSTALLINTERFACES, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_INSTALLDEVICE, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_NEWDEVICEWIZARD_FINISHINSTALL, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError()); return FALSE; } ret = SetupDiCallClassInstaller( DIF_DESTROYPRIVATEDATA, DevInstData->hDevInfo, &DevInstData->devInfoData); if (!ret) { TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError()); return FALSE; } return TRUE; }
BOOL DumpDeviceDriverFiles(_In_ HDEVINFO Devs, _In_ PSP_DEVINFO_DATA DevInfo) /*++ Routine Description: Dump information about what files were installed for driver package <tab>Installed using OEM123.INF section [abc.NT] <tab><tab>file... Arguments: Devs )_ uniquely identify device DevInfo ) Return Value: none --*/ { // // do this by 'searching' for the current driver // mimmicing a copy-only install to our own file queue // and then parsing that file queue // SP_DEVINSTALL_PARAMS deviceInstallParams; SP_DRVINFO_DATA driverInfoData; SP_DRVINFO_DETAIL_DATA driverInfoDetail; HSPFILEQ queueHandle = INVALID_HANDLE_VALUE; DWORD count; DWORD scanResult; BOOL success = FALSE; ZeroMemory(&driverInfoData,sizeof(driverInfoData)); driverInfoData.cbSize = sizeof(driverInfoData); if(!FindCurrentDriver(Devs,DevInfo,&driverInfoData)) { Padding(1); FormatToStream(stdout, MSG_DUMP_NO_DRIVER); return FALSE; } // // get useful driver information // driverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,&driverInfoData,&driverInfoDetail,sizeof(SP_DRVINFO_DETAIL_DATA),NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { // // no information about driver or section // goto final; } if(!driverInfoDetail.InfFileName[0] || !driverInfoDetail.SectionName[0]) { goto final; } // // pretend to do the file-copy part of a driver install // to determine what files are used // the specified driver must be selected as the active driver // if(!SetupDiSetSelectedDriver(Devs, DevInfo, &driverInfoData)) { goto final; } // // create a file queue so we can look at this queue later // queueHandle = SetupOpenFileQueue(); if ( queueHandle == (HSPFILEQ)INVALID_HANDLE_VALUE ) { goto final; } // // modify flags to indicate we're providing our own queue // ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams)); deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if ( !SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) { goto final; } // // we want to add the files to the file queue, not install them! // deviceInstallParams.FileQueue = queueHandle; deviceInstallParams.Flags |= DI_NOVCP; if ( !SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) { goto final; } // // now fill queue with files that are to be installed // this involves all class/co-installers // if ( !SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, Devs, DevInfo) ) { goto final; } // // we now have a list of delete/rename/copy files // iterate the copy queue twice - 1st time to get # of files // 2nd time to get files // (WinXP has API to get # of files, but we want this to work // on Win2k too) // count = 0; scanResult = 0; // // call once to count // SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,&count,&scanResult); Padding(1); FormatToStream(stdout, count ? MSG_DUMP_DRIVER_FILES : MSG_DUMP_NO_DRIVER_FILES, count, driverInfoDetail.InfFileName, driverInfoDetail.SectionName); // // call again to dump the files // SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,NULL,&scanResult); success = TRUE; final:
static BOOL ChangeStatus( DWORD dwNewStatus, DWORD dwSelectedItem, HDEVINFO hDevInfo ) { BOOL bRet = TRUE; TRY { SP_DEVINFO_DATA DeviceInfoData; ZeroMemory( &DeviceInfoData, sizeof( SP_DEVINFO_DATA ) ); DeviceInfoData.cbSize = sizeof( SP_DEVINFO_DATA ); // Get a handle to the Selected Item if ( !SetupDiEnumDeviceInfo( hDevInfo, dwSelectedItem, &DeviceInfoData ) ) { bRet = FALSE; } else { SP_PROPCHANGE_PARAMS PropChangeParams; ZeroMemory( &PropChangeParams, sizeof( SP_PROPCHANGE_PARAMS ) ); PropChangeParams.ClassInstallHeader.cbSize = sizeof( SP_CLASSINSTALL_HEADER ); // Set the PropChangeParams structure PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; PropChangeParams.Scope = DICS_FLAG_GLOBAL; PropChangeParams.StateChange = dwNewStatus; if ( !SetupDiSetClassInstallParams( hDevInfo, &DeviceInfoData, ( SP_CLASSINSTALL_HEADER* )&PropChangeParams, sizeof( PropChangeParams ) ) ) { bRet = FALSE; } else { // Call the ClassInstaller and perform the change if ( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData ) ) { bRet = FALSE; } else { // // Is Need to restart computer // SP_DEVINSTALL_PARAMS devParams; ZeroMemory( &devParams, sizeof( SP_DEVINSTALL_PARAMS ) ); devParams.cbSize = sizeof( SP_DEVINSTALL_PARAMS ); if ( !SetupDiGetDeviceInstallParams( hDevInfo, &DeviceInfoData, &devParams ) ) { bRet = FALSE; } else { if ( devParams.Flags & ( DI_NEEDRESTART | DI_NEEDREBOOT ) ) { TRACE( _T("\nNeed Restart Computer\n") ); } } } } } } CATCH_ALL( e ) { e->ReportError(); bRet = FALSE; } END_CATCH_ALL return bRet; }
int uninstallCMUDriver() { GUID guid = t1394CmdrGetGUID(); HDEVINFO hDI = SetupDiGetClassDevs(&guid,NULL,NULL,DIGCF_DEVICEINTERFACE); if(hDI != INVALID_HANDLE_VALUE) { SP_DEVINFO_DATA devInfoData; int index = 0; devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); while(SetupDiEnumDeviceInfo(hDI,index,&devInfoData)) { printf(" - Device %d:\n",index); if(index == 0) { // look for OEM inf files if(SetupDiBuildDriverInfoList(hDI,&devInfoData,SPDIT_COMPATDRIVER)) { SP_DRVINFO_DATA drvInfoData; drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA); int driverIndex = 0; while(SetupDiEnumDriverInfo(hDI,&devInfoData,SPDIT_COMPATDRIVER,driverIndex++,&drvInfoData)) { SP_DRVINFO_DETAIL_DATA drvInfoDetail; drvInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA); BOOL ret = SetupDiGetDriverInfoDetail(hDI,&devInfoData,&drvInfoData,&drvInfoDetail,drvInfoDetail.cbSize,NULL); if(ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER) { printf(" - has OEM inf file '%s'\n",drvInfoDetail.InfFileName); if(!DeleteFile(drvInfoDetail.InfFileName)) { printf(" - could not delete '%s' : %d",drvInfoDetail.InfFileName,GetLastError()); } drvInfoDetail.InfFileName[lstrlen(drvInfoDetail.InfFileName) - 3] = 'p'; if(!DeleteFile(drvInfoDetail.InfFileName)) { printf(" - could not delete '%s' : %d",drvInfoDetail.InfFileName,GetLastError()); } } else { printf(" - SetupDiGetDriverInfoDetail: %d\n",GetLastError()); } } if(GetLastError() != ERROR_NO_MORE_ITEMS) { printf(" - SetupDiEnumDriverInfo: %d\n",GetLastError()); } SetupDiDestroyDriverInfoList(hDI,&devInfoData,SPDIT_COMPATDRIVER); } else { printf(" - SetupDiEnumDriverInfo: %d\n",GetLastError()); } } // else already nuked oem inf files if(SetupDiCallClassInstaller(DIF_REMOVE,hDI,&devInfoData)) { printf(" - has been removed!\n"); } else { printf(" - could not be removed: %d\n",GetLastError()); } index++; } if(index == 0) { printf("No Devices Found!\n"); } SetupDiDestroyDeviceInfoList(hDI); } else { printf("Failed to get class devs!\n"); } return 0; }
DWORD InstallSoftwareBusPnpEnumerator(LPWSTR InfPath, LPCWSTR HardwareIdList) { HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; GUID ClassGUID; TCHAR ClassName[50]; int Result = 0; HMODULE hModule = NULL; UpdateDriverForPlugAndPlayDevicesProto UpdateProc; BOOL reboot = FALSE; DWORD flags = 0; if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0)) { return -1; } DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0); if(DeviceInfoSet == INVALID_HANDLE_VALUE) { return -1; } DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData)) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); return -1; } if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)HardwareIdList, (lstrlen(HardwareIdList)+1+1)*sizeof(TCHAR))) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); return -1; } if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData)) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); return -1; } if(GetFileAttributes(InfPath)==(DWORD)(-1)) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); return -1; } flags |= INSTALLFLAG_FORCE; hModule = LoadLibraryW(L"newdev.dll"); if(!hModule) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); return -1; } UpdateProc = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(hModule,UPDATEDRIVERFORPLUGANDPLAYDEVICES); if(!UpdateProc) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); FreeLibrary(hModule); return -1; } if(!UpdateProc(NULL, HardwareIdList, InfPath, flags, &reboot)) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); FreeLibrary(hModule); return -1; } FreeLibrary(hModule); SetupDiDestroyDeviceInfoList(DeviceInfoSet); return Result; }
static int TryInstallDevice( const char *pInfFilePath, const char *pDevId, const char *pDevInstID, PCNC_DEV_CALLBACK pDevCallBack, void *pDevCallBackParam, bool updateDriver, BOOL *pRebootRequired) { GUID classGUID; char className[32]; if (!SetupDiGetINFClass(pInfFilePath, &classGUID, className, sizeof(className)/sizeof(className[0]), 0)) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetINFClass(%s)", pInfFilePath); return IDCANCEL; } //Trace("className=%s\n", className); HDEVINFO hDevInfo; hDevInfo = SetupDiCreateDeviceInfoList(&classGUID, 0); if (hDevInfo == INVALID_HANDLE_VALUE) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCreateDeviceInfoList()"); return IDCANCEL; } int res = IDCONTINUE; SP_DEVINFO_DATA devInfoData; devInfoData.cbSize = sizeof(devInfoData); if (!pDevInstID) { if (StrCmpNI(pDevId, "root\\", 5) == 0) { /* * root\<enumerator-specific-device-ID> */ if (!SetupDiCreateDeviceInfo(hDevInfo, pDevId + 5, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData)) res = IDCANCEL; } else { SetLastError(ERROR_INVALID_DEVINST_NAME); res = IDCANCEL; } } else if (StrChr(pDevInstID, '\\')) { /* * <enumerator>\<enumerator-specific-device-ID>\<instance-specific-ID> */ if (!SetupDiCreateDeviceInfo(hDevInfo, pDevInstID, &classGUID, NULL, 0, 0, &devInfoData)) res = IDCANCEL; if (res != IDCONTINUE && GetLastError() == ERROR_DEVINST_ALREADY_EXISTS) { char *pTmpDevInstID = NULL; if (SetStr(&pTmpDevInstID, pDevInstID)) { char *pSave; char *p; p = STRTOK_R(pTmpDevInstID, "\\", &pSave); if (p && !lstrcmp(p, REGSTR_KEY_ROOTENUM)) { p = STRTOK_R(NULL, "\\", &pSave); if (SetupDiCreateDeviceInfo(hDevInfo, p, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData)) res = IDCONTINUE; } SetStr(&pTmpDevInstID, NULL); } else { SetLastError(ERROR_DEVINST_ALREADY_EXISTS); } } } else { /* * <enumerator-specific-device-ID> */ if (!SetupDiCreateDeviceInfo(hDevInfo, pDevInstID, &classGUID, NULL, 0, DICD_GENERATE_ID, &devInfoData)) res = IDCANCEL; } if (res != IDCONTINUE) { ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCreateDeviceInfo()"); goto exit1; } char hardwareId[MAX_DEVICE_ID_LEN + 1 + 1]; SNPRINTF(hardwareId, sizeof(hardwareId)/sizeof(hardwareId[0]) - 1, "%s", pDevId); int hardwareIdLen; hardwareIdLen = lstrlen(hardwareId) + 1 + 1; hardwareId[hardwareIdLen - 1] = 0; if (!SetupDiSetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_HARDWAREID, (LPBYTE)hardwareId, hardwareIdLen * sizeof(hardwareId[0]))) { res = IDCANCEL; ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiSetDeviceRegistryProperty()"); goto exit1; } if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDevInfo, &devInfoData)) { res = IDCANCEL; ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCallClassInstaller()"); goto exit1; } if (pDevCallBack) { DevProperties devProperties; if (!devProperties.DevId(pDevId)) { res = IDCANCEL; goto exit2; } if (!pDevCallBack(hDevInfo, &devInfoData, &devProperties, NULL, pDevCallBackParam)) { res = IDCANCEL; goto exit2; } } if (updateDriver) res = UpdateDriver(pInfFilePath, pDevId, 0, TRUE, pRebootRequired); exit2: if (res != IDCONTINUE) { if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &devInfoData)) ShowLastError(MB_OK|MB_ICONWARNING, "SetupDiCallClassInstaller()"); } exit1: SetupDiDestroyDeviceInfoList(hDevInfo); return res; }
int InstallRootEnumeratedDriver( IN HWND hWnd, IN LPTSTR HardwareId, IN LPTSTR INFFile ) { HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData; GUID ClassGUID; TCHAR ClassName[MAX_CLASS_NAME_LEN]; DWORD Err = NO_ERROR; BOOL reboot; LPTSTR MultiSzHardwareId = NULL; DWORD cbMultiSzHardwareId; // // SPDRP_HARDWAREID needs to be a multi_sz string so allocate a buffer that is // two characters more than the HardwareId passed in and use that buffer. // cbMultiSzHardwareId = (lstrlen(HardwareId) + 2) * sizeof(TCHAR); MultiSzHardwareId = malloc(cbMultiSzHardwareId); if (!MultiSzHardwareId) { MessageBox(hWnd, "Cannot allocate memory", "Error", MB_OK); Err = ERROR_NOT_ENOUGH_MEMORY; goto clean; } ZeroMemory(MultiSzHardwareId, cbMultiSzHardwareId); StringCbCopy(MultiSzHardwareId, cbMultiSzHardwareId, HardwareId); // // Use the INF File to extract the Class GUID. // if (!SetupDiGetINFClass(INFFile, &ClassGUID, ClassName, sizeof(ClassName), 0)) { Err = GetLastError(); DisplayError(hWnd, TEXT("GetINFClass")); DisplayError(hWnd, TEXT(INFFile)); goto clean; } // // Create the container for the to-be-created Device Information Element. // DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID, 0); if(DeviceInfoSet == INVALID_HANDLE_VALUE) { Err = GetLastError(); DisplayError(hWnd, TEXT("CreateDeviceInfoList")); goto clean; } // // Now create the element. // Use the Class GUID and Name from the INF file. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (!SetupDiCreateDeviceInfo(DeviceInfoSet, ClassName, &ClassGUID, NULL, 0, DICD_GENERATE_ID, &DeviceInfoData)) { Err = GetLastError(); DisplayError(hWnd, TEXT("CreateDeviceInfo")); goto clean; } // // Add the HardwareID to the Device's HardwareID property. // if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_HARDWAREID, (LPBYTE)MultiSzHardwareId, cbMultiSzHardwareId)) { Err = GetLastError(); DisplayError(hWnd, TEXT("SetDeviceRegistryProperty")); goto clean; } // // Transform the registry element into an actual devnode // in the PnP HW tree. // if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, DeviceInfoSet, &DeviceInfoData)) { Err = GetLastError(); DisplayError(hWnd, TEXT("CallClassInstaller(REGISTERDEVICE)")); goto clean; } // // The element is now registered. We must explicitly remove the // device using DIF_REMOVE, if we encounter any failure from now on. // // // Install the Driver. We don't actually care about @reboot, but // supplying it avoids an annoying popup on Windows 2000. // if (!UpdateDriverForPlugAndPlayDevices(hWnd, HardwareId, INFFile, INSTALLFLAG_FORCE, &reboot)) { Err = GetLastError(); DisplayError(hWnd, TEXT("UpdateDriverForPlugAndPlayDevices")); if (!SetupDiCallClassInstaller(DIF_REMOVE, DeviceInfoSet, &DeviceInfoData)) { DisplayError(hWnd, TEXT("CallClassInstaller(REMOVE)")); } } // // Cleanup. // clean: if (DeviceInfoSet != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } if (MultiSzHardwareId) { free(MultiSzHardwareId); } if (Err == NO_ERROR) { return 0; } else { return 1; } }
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; }
/*++ Routine Description: SavePortSettings Read the dlg screen selections for baudrate, parity, etc. If changed from what we started with, then save them Arguments: hDlg: address of the window szComName: which comport we're dealing with Params: contains, baudrate, parity, etc Return Value: ULONG: returns error messages --*/ void SavePortSettings( IN HWND DialogHwnd, IN LPCTSTR ComName, IN PPORT_PARAMS Params ) { TCHAR szBuild[PATHMAX]; ULONG i; PP_PORTSETTINGS pppNewPortSettings; // // Get the baud rate // i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_BAUDRATE, WM_GETTEXT, 18, (LPARAM)szBuild); if (!i) { goto Return; } pppNewPortSettings.BaudRate = myatoi(szBuild); // // Get the parity setting // i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_PARITY, CB_GETCURSEL, 0, 0L); if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; } pppNewPortSettings.Parity = i; StringCchCat(szBuild, ARRAYSIZE(szBuild), m_pszParitySuf[i]); // // Get the word length // i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_DATABITS, CB_GETCURSEL, 0, 0L); if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; } pppNewPortSettings.DataBits = i; StringCchCat(szBuild, ARRAYSIZE(szBuild), m_pszLenSuf[i]); // // Get the stop bits // i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_STOPBITS, CB_GETCURSEL, 0, 0L); if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; } pppNewPortSettings.StopBits = i; StringCchCat(szBuild, ARRAYSIZE(szBuild), m_pszStopSuf[i]); // // Get the flow control // i = (ULONG)SendDlgItemMessage(DialogHwnd, PP_PORT_FLOWCTL, CB_GETCURSEL, 0, 0L); if (i == CB_ERR || i == CB_ERRSPACE) { goto Return; } pppNewPortSettings.FlowControl = i; StringCchCat(szBuild, ARRAYSIZE(szBuild), m_pszFlowSuf[i]); // // if any of the values changed, then save it off // if (Params->PortSettings.BaudRate != pppNewPortSettings.BaudRate || Params->PortSettings.Parity != pppNewPortSettings.Parity || Params->PortSettings.DataBits != pppNewPortSettings.DataBits || Params->PortSettings.StopBits != pppNewPortSettings.StopBits || Params->PortSettings.FlowControl != pppNewPortSettings.FlowControl) { // // Write settings string to [ports] section in win.ini // NT translates this if a translate key is set in registry // and it winds up getting written to // HKLM\Software\Microsoft\Windows NT\CurrentVersion\Ports // WriteProfileString(m_szPorts, ComName, szBuild); // // Send global notification message to all windows // SendWinIniChange(m_szPorts); if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, Params->DeviceInfoSet, Params->DeviceInfoData)) { // // Possibly do something here // } } Return: return; } /* SavePortSettings */
NDASDI_API BOOL WINAPI NdasDiRemoveLegacyDevice( IN HWND hwndParent, IN LPCTSTR ServiceName, IN BOOL PresentOnly, OUT LPDWORD pdwRemovedDeviceCount OPTIONAL, OUT LPBOOL pbRebootRequired OPTIONAL, IN NDASDIREMOVEDEVICEERRCALLBACKPROC ErrorCallbackProc OPTIONAL, IN LPVOID Context OPTIONAL) { _ASSERTE(!IsBadStringPtr(ServiceName, LINE_LEN)); _ASSERTE(NULL == pbRebootRequired || !IsBadWritePtr(pbRebootRequired, sizeof(BOOL))); _ASSERTE(NULL == ErrorCallbackProc || !IsBadCodePtr((FARPROC)ErrorCallbackProc)); BOOL fReturn = FALSE; BOOL fSuccess = FALSE; HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE; SP_DEVINFO_DATA DeviceInfoData = {0}; DWORD Flags = DIGCF_ALLCLASSES; if (PresentOnly) { Flags |= DIGCF_PRESENT; } // // Create a Device Information Set with all present devices. // DeviceInfoSet = SetupDiGetClassDevs( NULL, // All Classes 0, hwndParent, Flags); // All devices present on system if (INVALID_HANDLE_VALUE == DeviceInfoSet) { goto cleanup; } if (NULL != pbRebootRequired) { *pbRebootRequired = FALSE; } // // Enumerate through all Devices. // DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if (NULL != pdwRemovedDeviceCount) { *pdwRemovedDeviceCount = 0; } for (DWORD i = 0; SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData); ++i) { DWORD DataT; LPTSTR buffer = NULL; DWORD buffersize = 0; // // We won't know the size of the HardwareID buffer until we call // this function. So call it with a null to begin with, and then // use the required buffer size to Alloc the nessicary space. // Keep calling we have success or an unknown failure. // while (TRUE) { fSuccess = SetupDiGetDeviceRegistryProperty( DeviceInfoSet, &DeviceInfoData, SPDRP_SERVICE, &DataT, (PBYTE)buffer, buffersize, &buffersize); if (fSuccess) { break; } if (ERROR_INVALID_DATA == GetLastError()) { // // May be a Legacy Device with no HardwareID. Continue. // break; } else if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { // // We need to change the buffer size. // if (buffer) { LocalFree(buffer); } buffer = (LPTSTR) LocalAlloc(LPTR,buffersize); } else { // // Unknown Failure. // if (ErrorCallbackProc) { BOOL fCont = ErrorCallbackProc( NDIRD_ERROR_GetDeviceRegistryProperty, DeviceInfoSet, &DeviceInfoData, GetLastError(), Context); if (fCont) { } fReturn = FALSE; goto cleanup; } } } // // May be a Legacy Device with no HardwareID. Continue. // if (GetLastError() == ERROR_INVALID_DATA) { continue; } // // Service Name is REG_SZ (Not MultiSZ) // LPCTSTR p = buffer; DPNoise(_T("%s\n"), p); if (0 == lstrcmpi(ServiceName,p)) { DPNoise(_T("\n>>> %s <<<\n"), p); // // Worker function to remove device. // fSuccess = SetupDiCallClassInstaller( DIF_REMOVE, DeviceInfoSet, &DeviceInfoData); if (!fSuccess && ErrorCallbackProc) { BOOL fCont = ErrorCallbackProc( NDIRD_ERROR_CallRemoveToClassInstaller, DeviceInfoSet, &DeviceInfoData, GetLastError(), Context); if (buffer) { LocalFree(buffer); } fReturn = FALSE; goto cleanup; } // // Get the installation param // if (NULL != pbRebootRequired) { SP_DEVINSTALL_PARAMS diParams = {0}; diParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); fSuccess = SetupDiGetDeviceInstallParams( DeviceInfoSet, &DeviceInfoData, &diParams); _ASSERTE(fSuccess); *pbRebootRequired |= (diParams.Flags & DI_NEEDREBOOT) || (diParams.Flags & DI_NEEDRESTART); } if (NULL != pdwRemovedDeviceCount) { ++(*pdwRemovedDeviceCount); } break; } if (buffer) { LocalFree(buffer); } } if ((NO_ERROR != GetLastError()) && (ERROR_NO_MORE_ITEMS != GetLastError())) { fReturn = FALSE; } else { fReturn = TRUE; } // // Cleanup. // cleanup: DWORD err = GetLastError(); if (INVALID_HANDLE_VALUE != DeviceInfoSet) { SetupDiDestroyDeviceInfoList(DeviceInfoSet); } SetLastError(err); return fReturn; }
HRESULT xDiEnumDriverFiles( __in_opt HWND Owner, __in LPCWSTR OemInfFullPath, __in DWORD Flags, __in XDI_ENUM_DRIVER_FILE_CALLBACK EnumCallback, __in LPVOID EnumContext) { HRESULT hr; BOOL success; WCHAR infFullPath[MAX_PATH]; DWORD n = GetFullPathNameW(OemInfFullPath, MAX_PATH, infFullPath, NULL); if (0 == n) { hr = HRESULT_FROM_WIN32(GetLastError()); hr = (SUCCEEDED(hr)) ? E_FAIL : hr; goto error0; } HDEVINFO devInfoSet = SetupDiCreateDeviceInfoList(NULL, Owner); if (INVALID_HANDLE_VALUE == devInfoSet) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error0; } SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) }; success = SetupDiCreateDeviceInfoW( devInfoSet, L"XDI_Temporary_Enumerator", &GUID_NULL, NULL, NULL, DICD_GENERATE_ID, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error1; } HSPFILEQ fileQueueHandle = SetupOpenFileQueue(); if (INVALID_HANDLE_VALUE == fileQueueHandle) { // Error from SetupOpenFileQueue is only from out-of-memory situation // without the last error set hr = E_OUTOFMEMORY; goto error2; } SP_DEVINSTALL_PARAMS devInstallParams = {sizeof(SP_DEVINSTALL_PARAMS)}; success = SetupDiGetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } // // Specify the search path // hr = StringCchCopyW( devInstallParams.DriverPath, MAX_PATH, infFullPath); if (FAILED(hr)) { goto error3; } devInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; devInstallParams.FileQueue = fileQueueHandle; devInstallParams.Flags |= DI_NOVCP; devInstallParams.Flags |= DI_ENUMSINGLEINF; success = SetupDiSetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } // // use DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE if possible // to ensure we look at duplicate nodes (which is broken in itself) // #ifndef DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE #define DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE 0x08000000L // Don't remove identical driver nodes from the class list #endif if (xDipWindowsXPOrLater()) { devInstallParams.FlagsEx |= DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE; success = SetupDiSetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { devInstallParams.FlagsEx &= ~DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE; } } // // Build a class driver list with every driver // success = SetupDiBuildDriverInfoList( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } SP_DRVINFO_DATA drvInfoData = { sizeof(SP_DRVINFO_DATA) }; for (DWORD index = 0; ; ++index) { success = SetupDiEnumDriverInfoW( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER, index, &drvInfoData); if (!success) { break; } SP_DRVINFO_DETAIL_DATA drvInfoDetail = { sizeof(SP_DRVINFO_DETAIL_DATA) }; success = SetupDiGetDriverInfoDetailW( devInfoSet, &devInfoData, &drvInfoData, &drvInfoDetail, sizeof(SP_DRVINFO_DETAIL_DATA), NULL); if (!success && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } success = SetupDiSetSelectedDriverW( devInfoSet, &devInfoData, &drvInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } if (Flags & XDI_EDF_NO_CLASS_INSTALLER) { success = SetupDiInstallDriverFiles( devInfoSet, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } } else { success = SetupDiCallClassInstaller( DIF_INSTALLDEVICEFILES, devInfoSet, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } } } // // SPQ_SCAN_USE_CALLBACK_EX checks the digital signature of the file // We do not want to check the signature here. // // SPQ_SCAN_FILE_PRESENCE avoids checking the digital signature of the file // in Windows XP or later. (Not in Windows 2000) when used // with SPQ_SCAN_USE_CALLBACK_EX // XDI_ENUM_FQS_CONTEXT fqsContext = {0}; fqsContext.Callback = EnumCallback; fqsContext.CallbackContext = EnumContext; DWORD scanResult; success = SetupScanFileQueueW( fileQueueHandle, SPQ_SCAN_USE_CALLBACK, // SPQ_SCAN_USE_CALLBACKEX | SPQ_SCAN_FILE_PRESENCE, Owner, xDipEnumFileQueueScanCallback, &fqsContext, &scanResult); if (!success) { // // SetupScanFileQueue may fail using SPQ_SCAN_FILE_PRESENSE flag // Try again without SPQ_SCAN_FILE_PRESENSE // (when using SPQ_SCAN_USE_CALLBACKEX) // hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } hr = S_OK; #pragma warning(disable: 4533) // to use goto in cpp error4: SetupDiDestroyDriverInfoList( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER); error3: SetupCloseFileQueue(fileQueueHandle); error2: SetupDiDeleteDeviceInfo(devInfoSet, &devInfoData); error1: SetupDiDestroyDeviceInfoList(devInfoSet); error0: #pragma warning(default: 4533) return hr; }
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; }
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); }
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; }
bool RemoveModule(const string &m) { HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; // Create a HDEVINFO with all present devices. hDevInfo = SetupDiGetClassDevs(NULL, 0, // Enumerator 0, DIGCF_PRESENT | DIGCF_ALLCLASSES); if (hDevInfo == INVALID_HANDLE_VALUE) { // Insert error handling here. return false; } // Enumerate through all devices in Set. DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &DeviceInfoData); i++) { DWORD dataT; LPTSTR buffer = NULL; DWORD buffersize = 0; while (!SetupDiGetDeviceRegistryProperty( hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, &dataT, (PBYTE)buffer, buffersize, &buffersize)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { // Change the buffer size. if (buffer) LocalFree(buffer); // Double the size to avoid problems on buffer = (LPTSTR)LocalAlloc(LPTR, buffersize * 2); } else { // Insert error handling here. break; } } if (buffersize == 0) continue; // if device found change it's state if (!wcscmp(m.c_str(), buffer)) { // remove the device if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &DeviceInfoData)) { DWORD errorcode = GetLastError(); // error here } } if (buffer) LocalFree(buffer); } if (GetLastError() != NO_ERROR && GetLastError() != ERROR_NO_MORE_ITEMS) { return false; } // Cleanup SetupDiDestroyDeviceInfoList(hDevInfo); return true; }