/* * New Device installation API * * Copyright 2003 Ulrich Czekalla * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "windef.h" #include "winerror.h" #include "winbase.h" #include "winnls.h" #include "winuser.h" #include "winreg.h" #include "cfgmgr32.h" #include "newdev.h" #include "wine/debug.h" #include "wine/heap.h" WINE_DEFAULT_DEBUG_CHANNEL(setupapi); /*********************************************************************** * InstallNewDevice (NEWDEV.@) */ BOOL WINAPI InstallNewDevice(HWND hwndParent, LPGUID ClassGuid, PDWORD pReboot) { FIXME("Stub!\n"); return TRUE; } /*********************************************************************** * InstallSelectedDriver (NEWDEV.@) */ BOOL WINAPI InstallSelectedDriver(HWND parent, HDEVINFO info, const WCHAR *reserved, BOOL backup, DWORD *reboot) { FIXME("Stub! %p %p %s %u %p\n", parent, info, debugstr_w(reserved), backup, reboot); return TRUE; } /*********************************************************************** * UpdateDriverForPlugAndPlayDevicesA (NEWDEV.@) */ BOOL WINAPI UpdateDriverForPlugAndPlayDevicesA(HWND parent, const char *hardware_id, const char *inf_path, DWORD flags, BOOL *reboot) { WCHAR hardware_idW[MAX_DEVICE_ID_LEN]; WCHAR inf_pathW[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, hardware_id, -1, hardware_idW, ARRAY_SIZE(hardware_idW)); MultiByteToWideChar(CP_ACP, 0, inf_path, -1, inf_pathW, ARRAY_SIZE(inf_pathW)); return UpdateDriverForPlugAndPlayDevicesW(parent, hardware_idW, inf_pathW, flags, reboot); } static BOOL hardware_id_matches(const WCHAR *id, const WCHAR *device_ids) { while (*device_ids) { if (!wcscmp(id, device_ids)) return TRUE; device_ids += lstrlenW(device_ids) + 1; } return FALSE; } /*********************************************************************** * UpdateDriverForPlugAndPlayDevicesW (NEWDEV.@) */ BOOL WINAPI UpdateDriverForPlugAndPlayDevicesW(HWND parent, const WCHAR *hardware_id, const WCHAR *inf_path, DWORD flags, BOOL *reboot) { SP_DEVINSTALL_PARAMS_W params = {sizeof(params)}; SP_DEVINFO_DATA device = {sizeof(device)}; WCHAR *device_ids = NULL; DWORD size = 0, i, j; HDEVINFO set; static const DWORD dif_list[] = { DIF_SELECTBESTCOMPATDRV, DIF_ALLOW_INSTALL, DIF_INSTALLDEVICEFILES, DIF_REGISTER_COINSTALLERS, DIF_INSTALLINTERFACES, DIF_INSTALLDEVICE, DIF_NEWDEVICEWIZARD_FINISHINSTALL, }; TRACE("parent %p, hardware_id %s, inf_path %s, flags %#x, reboot %p.\n", parent, debugstr_w(hardware_id), debugstr_w(inf_path), flags, reboot); if (flags) FIXME("Unhandled flags %#x.\n", flags); if (reboot) *reboot = FALSE; if ((set = SetupDiGetClassDevsW(NULL, NULL, 0, DIGCF_ALLCLASSES)) == INVALID_HANDLE_VALUE) return FALSE; for (i = 0; SetupDiEnumDeviceInfo(set, i, &device); ++i) { if (!SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, (BYTE *)device_ids, size, &size)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) continue; device_ids = heap_realloc(device_ids, size); SetupDiGetDeviceRegistryPropertyW(set, &device, SPDRP_HARDWAREID, NULL, (BYTE *)device_ids, size, NULL); } if (!hardware_id_matches(hardware_id, device_ids)) continue; if (!SetupDiGetDeviceInstallParamsW(set, &device, ¶ms)) continue; lstrcpyW(params.DriverPath, inf_path); params.Flags |= DI_ENUMSINGLEINF; if (!SetupDiSetDeviceInstallParamsW(set, &device, ¶ms)) continue; if (!SetupDiBuildDriverInfoList(set, &device, SPDIT_COMPATDRIVER)) continue; for (j = 0; j < ARRAY_SIZE(dif_list); ++j) { if (!SetupDiCallClassInstaller(dif_list[j], set, &device) && GetLastError() != ERROR_DI_DO_DEFAULT) break; } } SetupDiDestroyDeviceInfoList(set); heap_free(device_ids); return TRUE; } /*********************************************************************** * DiInstallDriverA (NEWDEV.@) */ BOOL WINAPI DiInstallDriverA(HWND parent, const char *inf_path, DWORD flags, BOOL *reboot) { FIXME("parent %p, inf_path %s, flags %#x, reboot %p, stub!\n", parent, debugstr_a(inf_path), flags, reboot); return TRUE; } /*********************************************************************** * DiInstallDriverW (NEWDEV.@) */ BOOL WINAPI DiInstallDriverW(HWND parent, const WCHAR *inf_path, DWORD flags, BOOL *reboot) { FIXME("parent %p, inf_path %s, flags %#x, reboot %p, stub!\n", parent, debugstr_w(inf_path), flags, reboot); return TRUE; }