From 6971dfcfc21e887e4b5724d4f32e29d012e1b5be Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sun, 8 Mar 2020 14:13:14 -0500 Subject: [PATCH] setupapi: Implement SetupDiGetSelectedDriver(). Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48639 Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/setupapi/devinst.c | 90 +++++++++++++++++++++++++---------- dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/tests/devinst.c | 14 ++++++ 3 files changed, 82 insertions(+), 26 deletions(-) diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 268965f0fed..ce7268a5e80 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4645,16 +4645,42 @@ BOOL WINAPI SetupDiBuildDriverInfoList(HDEVINFO devinfo, SP_DEVINFO_DATA *device return TRUE; } +static BOOL copy_driver_data(SP_DRVINFO_DATA_W *data, const struct driver *driver) +{ + INFCONTEXT ctx; + HINF hinf; + + if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) + return FALSE; + + data->ProviderName[0] = 0; + if (SetupFindFirstLineW(hinf, L"Version", L"Provider", &ctx)) + SetupGetStringFieldW(&ctx, 1, data->ProviderName, ARRAY_SIZE(data->ProviderName), NULL); + wcscpy(data->Description, driver->description); + wcscpy(data->MfgName, driver->manufacturer); + data->DriverType = SPDIT_COMPATDRIVER; + + SetupCloseInfFile(hinf); + + return TRUE; +} + +static void driver_data_wtoa(SP_DRVINFO_DATA_A *a, const SP_DRVINFO_DATA_W *w) +{ + a->DriverType = w->DriverType; + a->Reserved = w->Reserved; + WideCharToMultiByte(CP_ACP, 0, w->Description, -1, a->Description, sizeof(a->Description), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, w->MfgName, -1, a->MfgName, sizeof(a->MfgName), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, w->ProviderName, -1, a->ProviderName, sizeof(a->ProviderName), NULL, NULL); +} + /*********************************************************************** * SetupDiEnumDriverInfoW (SETUPAPI.@) */ BOOL WINAPI SetupDiEnumDriverInfoW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, DWORD type, DWORD index, SP_DRVINFO_DATA_W *driver_data) { - static const WCHAR providerW[] = {'P','r','o','v','i','d','e','r',0}; struct device *device; - INFCONTEXT ctx; - HINF hinf; TRACE("devinfo %p, device_data %p, type %#x, index %u, driver_data %p.\n", devinfo, device_data, type, index, driver_data); @@ -4675,19 +4701,7 @@ BOOL WINAPI SetupDiEnumDriverInfoW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_dat return FALSE; } - if ((hinf = SetupOpenInfFileW(device->drivers[index].inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) - return FALSE; - - driver_data->ProviderName[0] = 0; - if (SetupFindFirstLineW(hinf, Version, providerW, &ctx)) - SetupGetStringFieldW(&ctx, 1, driver_data->ProviderName, ARRAY_SIZE(driver_data->ProviderName), NULL); - lstrcpyW(driver_data->Description, device->drivers[index].description); - lstrcpyW(driver_data->MfgName, device->drivers[index].manufacturer); - driver_data->DriverType = SPDIT_COMPATDRIVER; - - SetupCloseInfFile(hinf); - - return TRUE; + return copy_driver_data(driver_data, &device->drivers[index]); } /*********************************************************************** @@ -4701,14 +4715,7 @@ BOOL WINAPI SetupDiEnumDriverInfoA(HDEVINFO devinfo, SP_DEVINFO_DATA *device_dat driver_dataW.cbSize = sizeof(driver_dataW); ret = SetupDiEnumDriverInfoW(devinfo, device_data, type, index, &driver_dataW); - driver_data->DriverType = driver_dataW.DriverType; - driver_data->Reserved = driver_dataW.Reserved; - WideCharToMultiByte(CP_ACP, 0, driver_dataW.Description, -1, driver_data->Description, - sizeof(driver_data->Description), NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, driver_dataW.MfgName, -1, driver_data->MfgName, - sizeof(driver_data->MfgName), NULL, NULL); - WideCharToMultiByte(CP_ACP, 0, driver_dataW.ProviderName, -1, driver_data->ProviderName, - sizeof(driver_data->ProviderName), NULL, NULL); + driver_data_wtoa(driver_data, &driver_dataW); return ret; } @@ -4738,6 +4745,41 @@ BOOL WINAPI SetupDiSelectBestCompatDrv(HDEVINFO devinfo, SP_DEVINFO_DATA *device return TRUE; } +/*********************************************************************** + * SetupDiGetSelectedDriverW (SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetSelectedDriverW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, SP_DRVINFO_DATA_W *driver_data) +{ + struct device *device; + + TRACE("devinfo %p, device_data %p, driver_data %p.\n", devinfo, device_data, driver_data); + + if (!(device = get_device(devinfo, device_data))) + return FALSE; + + if (!device->selected_driver) + { + SetLastError(ERROR_NO_DRIVER_SELECTED); + return FALSE; + } + + return copy_driver_data(driver_data, device->selected_driver); +} + +/*********************************************************************** + * SetupDiGetSelectedDriverA (SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetSelectedDriverA(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, SP_DRVINFO_DATA_A *driver_data) +{ + SP_DRVINFO_DATA_W driver_dataW; + BOOL ret; + + driver_dataW.cbSize = sizeof(driver_dataW); + if ((ret = SetupDiGetSelectedDriverW(devinfo, device_data, &driver_dataW))) + driver_data_wtoa(driver_data, &driver_dataW); + return ret; +} + /*********************************************************************** * SetupDiInstallDriverFiles (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 33ccc480974..233a02e550c 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -361,8 +361,8 @@ @ stdcall SetupDiGetINFClassA(str ptr ptr long ptr) @ stdcall SetupDiGetINFClassW(wstr ptr ptr long ptr) @ stub SetupDiGetSelectedDevice -@ stub SetupDiGetSelectedDriverA -@ stub SetupDiGetSelectedDriverW +@ stdcall SetupDiGetSelectedDriverA(ptr ptr ptr) +@ stdcall SetupDiGetSelectedDriverW(ptr ptr ptr) @ stub SetupDiGetWizardPage @ stdcall SetupDiInstallClassA(long str long ptr) @ stub SetupDiInstallClassExA diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index a9ac0d849f6..0b1a1fa3814 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -2434,6 +2434,20 @@ static void test_driver_list(void) ok(!ret, "Expected failure.\n"); ok(GetLastError() == ERROR_NO_MORE_ITEMS, "Got unexpected error %#x.\n", GetLastError()); + ret = SetupDiGetSelectedDriverA(set, &device, &driver); + ok(ret /* Win10 1809 */ || GetLastError() == ERROR_NO_DRIVER_SELECTED, + "Got unexpected error %#x.\n", GetLastError()); + + ret = SetupDiSelectBestCompatDrv(set, &device); + ok(ret, "Failed to select driver, error %#x.\n", GetLastError()); + + ret = SetupDiGetSelectedDriverA(set, &device, &driver); + ok(ret, "Failed to get selected driver, error %#x.\n", GetLastError()); + ok(driver.DriverType == SPDIT_COMPATDRIVER, "Got wrong type %#x.\n", driver.DriverType); + ok(!strcmp(driver.Description, "desc1"), "Got wrong description '%s'.\n", driver.Description); + ok(!strcmp(driver.MfgName, wow64 ? "mfg1_wow" : "mfg1"), "Got wrong manufacturer '%s'.\n", driver.MfgName); + ok(!strcmp(driver.ProviderName, ""), "Got wrong provider '%s'.\n", driver.ProviderName); + SetupDiDestroyDeviceInfoList(set); ret = DeleteFileA(inf_path); ok(ret, "Failed to delete %s, error %u.\n", inf_path, GetLastError());