From: Zebediah Figura z.figura12@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48639 Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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..69b339e49b3 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); + 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..9eed8e73d87 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, "Expected failure.\n"); + ok(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());
From: Zebediah Figura z.figura12@gmail.com
Needed by the Windows Device Framework co-installer.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 153 ++++++++++++++++++++++++++++++++++ dlls/setupapi/setupapi.spec | 4 +- dlls/setupapi/tests/devinst.c | 96 ++++++++++++++++++++- 3 files changed, 247 insertions(+), 6 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 69b339e49b3..ef1e824ffbb 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -110,6 +110,7 @@ struct driver WCHAR manufacturer[LINE_LEN]; WCHAR mfg_key[LINE_LEN]; WCHAR description[LINE_LEN]; + WCHAR section[LINE_LEN]; };
/* is used to identify if a DeviceInfoSet pointer is @@ -4564,6 +4565,8 @@ static void enum_compat_drivers_from_file(struct device *device, const WCHAR *pa lstrcpyW(device->drivers[count - 1].mfg_key, mfg_key_ext); SetupGetStringFieldW(&ctx, 0, device->drivers[count - 1].description, ARRAY_SIZE(device->drivers[count - 1].description), NULL); + SetupGetStringFieldW(&ctx, 1, device->drivers[count - 1].section, + ARRAY_SIZE(device->drivers[count - 1].section), NULL);
TRACE("Found compatible driver: manufacturer %s, desc %s.\n", debugstr_w(mfg_name), debugstr_w(device->drivers[count - 1].description)); @@ -4659,6 +4662,7 @@ static BOOL copy_driver_data(SP_DRVINFO_DATA_W *data, const struct driver *drive wcscpy(data->Description, driver->description); wcscpy(data->MfgName, driver->manufacturer); data->DriverType = SPDIT_COMPATDRIVER; + data->Reserved = (ULONG_PTR)driver;
SetupCloseInfFile(hinf);
@@ -4780,6 +4784,155 @@ BOOL WINAPI SetupDiGetSelectedDriverA(HDEVINFO devinfo, SP_DEVINFO_DATA *device_ return ret; }
+/*********************************************************************** + * SetupDiGetDriverInfoDetailW (SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetDriverInfoDetailW(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, + SP_DRVINFO_DATA_W *driver_data, SP_DRVINFO_DETAIL_DATA_W *detail_data, const DWORD size, DWORD *ret_size) +{ + struct driver *driver = (struct driver *)driver_data->Reserved; + DWORD size_needed, i, id_size = 1; + WCHAR id[MAX_DEVICE_ID_LEN]; + INFCONTEXT ctx; + HANDLE file; + HINF hinf; + + TRACE("devinfo %p, device_data %p, driver_data %p, detail_data %p, size %u, ret_size %p.\n", + devinfo, device_data, driver_data, detail_data, size, ret_size); + + if ((detail_data || size) && size < sizeof(SP_DRVINFO_DETAIL_DATA_W)) + { + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; + } + + if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) + return FALSE; + + SetupFindFirstLineW(hinf, driver->mfg_key, driver->description, &ctx); + for (i = 2; SetupGetStringFieldW(&ctx, i, id, ARRAY_SIZE(id), NULL); ++i) + id_size += wcslen(id) + 1; + + size_needed = FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_W, HardwareID[id_size]); + if (ret_size) + *ret_size = size_needed; + if (!detail_data) + return TRUE; + + detail_data->CompatIDsLength = detail_data->CompatIDsOffset = 0; + detail_data->HardwareID[0] = 0; + + if (size >= size_needed) + { + id_size = 0; + for (i = 2; SetupGetStringFieldW(&ctx, i, id, ARRAY_SIZE(id), NULL); ++i) + { + wcscpy(&detail_data->HardwareID[id_size], id); + if (i == 3) + detail_data->CompatIDsOffset = id_size; + id_size += wcslen(id) + 1; + } + detail_data->HardwareID[id_size++] = 0; + if (i > 3) + detail_data->CompatIDsLength = id_size - detail_data->CompatIDsOffset; + } + + SetupCloseInfFile(hinf); + + if ((file = CreateFileW(driver->inf_path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) + return FALSE; + GetFileTime(file, NULL, NULL, &detail_data->InfDate); + CloseHandle(file); + + wcscpy(detail_data->SectionName, driver->section); + wcscpy(detail_data->InfFileName, driver->inf_path); + wcscpy(detail_data->DrvDescription, driver->description); + + if (size < size_needed) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + return TRUE; +} + +/*********************************************************************** + * SetupDiGetDriverInfoDetailA (SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetDriverInfoDetailA(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data, + SP_DRVINFO_DATA_A *driver_data, SP_DRVINFO_DETAIL_DATA_A *detail_data, const DWORD size, DWORD *ret_size) +{ + struct driver *driver = (struct driver *)driver_data->Reserved; + DWORD size_needed, i, id_size = 1; + char id[MAX_DEVICE_ID_LEN]; + INFCONTEXT ctx; + HANDLE file; + HINF hinf; + + TRACE("devinfo %p, device_data %p, driver_data %p, detail_data %p, size %u, ret_size %p.\n", + devinfo, device_data, driver_data, detail_data, size, ret_size); + + if ((detail_data || size) && size < sizeof(SP_DRVINFO_DETAIL_DATA_A)) + { + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; + } + + if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) + return FALSE; + + SetupFindFirstLineW(hinf, driver->mfg_key, driver->description, &ctx); + for (i = 2; SetupGetStringFieldA(&ctx, i, id, ARRAY_SIZE(id), NULL); ++i) + id_size += strlen(id) + 1; + + size_needed = FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_A, HardwareID[id_size]); + if (ret_size) + *ret_size = size_needed; + if (!detail_data) + return TRUE; + + detail_data->CompatIDsLength = detail_data->CompatIDsOffset = 0; + detail_data->HardwareID[0] = 0; + + if (size >= size_needed) + { + id_size = 0; + for (i = 2; SetupGetStringFieldA(&ctx, i, id, ARRAY_SIZE(id), NULL); ++i) + { + strcpy(&detail_data->HardwareID[id_size], id); + if (i == 3) + detail_data->CompatIDsOffset = id_size; + id_size += strlen(id) + 1; + } + detail_data->HardwareID[id_size++] = 0; + if (i > 3) + detail_data->CompatIDsLength = id_size - detail_data->CompatIDsOffset; + } + + SetupCloseInfFile(hinf); + + if ((file = CreateFileW(driver->inf_path, 0, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE) + return FALSE; + GetFileTime(file, NULL, NULL, &detail_data->InfDate); + CloseHandle(file); + + WideCharToMultiByte(CP_ACP, 0, driver->section, -1, detail_data->SectionName, + sizeof(detail_data->SectionName), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, driver->inf_path, -1, detail_data->InfFileName, + sizeof(detail_data->InfFileName), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, driver->description, -1, detail_data->DrvDescription, + sizeof(detail_data->InfFileName), NULL, NULL); + + if (size < size_needed) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + return TRUE; +} + /*********************************************************************** * SetupDiInstallDriverFiles (SETUPAPI.@) */ diff --git a/dlls/setupapi/setupapi.spec b/dlls/setupapi/setupapi.spec index 233a02e550c..43b837ca9e5 100644 --- a/dlls/setupapi/setupapi.spec +++ b/dlls/setupapi/setupapi.spec @@ -347,8 +347,8 @@ @ stdcall SetupDiGetDevicePropertyW(ptr ptr ptr ptr ptr long ptr long) @ stdcall SetupDiGetDeviceRegistryPropertyA(long ptr long ptr ptr long ptr) @ stdcall SetupDiGetDeviceRegistryPropertyW(long ptr long ptr ptr long ptr) -@ stub SetupDiGetDriverInfoDetailA -@ stub SetupDiGetDriverInfoDetailW +@ stdcall SetupDiGetDriverInfoDetailA(ptr ptr ptr ptr long ptr) +@ stdcall SetupDiGetDriverInfoDetailW(ptr ptr ptr ptr long ptr) @ stub SetupDiGetDriverInstallParamsA @ stub SetupDiGetDriverInstallParamsW @ stub SetupDiGetHwProfileFriendlyNameA diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c index 9eed8e73d87..bb2cb3452ce 100644 --- a/dlls/setupapi/tests/devinst.c +++ b/dlls/setupapi/tests/devinst.c @@ -2315,13 +2315,18 @@ static void test_get_actual_section(void)
static void test_driver_list(void) { - char inf_dir[MAX_PATH], inf_path[MAX_PATH + 10], inf_path2[MAX_PATH + 10]; + char detail_buffer[1000]; + SP_DRVINFO_DETAIL_DATA_A *detail = (SP_DRVINFO_DETAIL_DATA_A *)detail_buffer; + char short_path[MAX_PATH], inf_dir[MAX_PATH], inf_path[MAX_PATH + 10], inf_path2[MAX_PATH + 10]; static const char hardware_id[] = "bogus_hardware_id\0"; static const char compat_id[] = "bogus_compat_id\0"; SP_DEVINSTALL_PARAMS_A params = {sizeof(params)}; SP_DRVINFO_DATA_A driver = {sizeof(driver)}; SP_DEVINFO_DATA device = {sizeof(device)}; + DWORD size, expect_size; + FILETIME filetime; HDEVINFO set; + HANDLE file; BOOL ret;
static const char inf_data[] = "[Version]\n" @@ -2334,12 +2339,12 @@ static void test_driver_list(void) "mfg2_wow=mfg2_key,NT" WOWEXT "\n" "mfg3=mfg3_key,NT" WRONGEXT "\n" "[mfg1_key.nt" MYEXT "]\n" - "desc1=,bogus_hardware_id\n" + "desc1=install1,bogus_hardware_id\n" "desc2=,bogus_hardware_id\n" "desc3=,wrong_hardware_id\n" "desc4=,wrong_hardware_id,bogus_compat_id\n" "[mfg1_key.nt" WOWEXT "]\n" - "desc1=,bogus_hardware_id\n" + "desc1=install1,bogus_hardware_id\n" "desc2=,bogus_hardware_id\n" "desc3=,wrong_hardware_id\n" "desc4=,wrong_hardware_id,bogus_compat_id\n" @@ -2348,7 +2353,9 @@ static void test_driver_list(void) "[mfg2_key.nt" WOWEXT "]\n" "desc5=,bogus_hardware_id\n" "[mfg3_key.nt" WRONGEXT "]\n" - "desc6=,bogus_hardware_id\n"; + "desc6=,bogus_hardware_id\n" + "[install1.nt" MYEXT "]\n" + "[install1.nt" WRONGEXT "]\n";
static const char inf_data_file1[] = "[Version]\n" "Signature="$Chicago$"\n" @@ -2371,8 +2378,14 @@ static void test_driver_list(void) "desc2=,bogus_hardware_id\n";
GetTempPathA(sizeof(inf_path), inf_path); + GetShortPathNameA(inf_path, short_path, sizeof(short_path)); strcat(inf_path, "setupapi_test.inf"); + strcat(short_path, "setupapi_test.inf"); create_file(inf_path, inf_data); + file = CreateFileA(inf_path, 0, 0, NULL, OPEN_EXISTING, 0, 0); + GetFileTime(file, NULL, NULL, &filetime); + CloseHandle(file); + set = SetupDiCreateDeviceInfoList(NULL, NULL); ok(set != INVALID_HANDLE_VALUE, "Failed to create device list, error %#x.\n", GetLastError()); ret = SetupDiCreateDeviceInfoA(set, "Root\BOGUS\0000", &GUID_NULL, NULL, NULL, 0, &device); @@ -2408,6 +2421,68 @@ static void test_driver_list(void) 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);
+ expect_size = FIELD_OFFSET(SP_DRVINFO_DETAIL_DATA_A, HardwareID[sizeof("bogus_hardware_id\0")]); + + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, NULL, 0, &size); + ok(ret, "Failed to get driver details, error %#x.\n", GetLastError()); + ok(size == expect_size, "Got size %u.\n", size); + + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, NULL, sizeof(SP_DRVINFO_DETAIL_DATA_A) - 1, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == expect_size, "Got size %u.\n", size); + + size = 0xdeadbeef; + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, 0, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == 0xdeadbeef, "Got size %u.\n", size); + + size = 0xdeadbeef; + detail->CompatIDsLength = 0xdeadbeef; + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, sizeof(SP_DRVINFO_DETAIL_DATA_A) - 1, &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INVALID_USER_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == 0xdeadbeef, "Got size %u.\n", size); + ok(detail->CompatIDsLength == 0xdeadbeef, "Got wrong compat IDs length %u.\n", detail->CompatIDsLength); + + memset(detail_buffer, 0xcc, sizeof(detail_buffer)); + detail->cbSize = sizeof(*detail); + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, sizeof(SP_DRVINFO_DETAIL_DATA_A), NULL); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(detail->InfDate.dwHighDateTime == filetime.dwHighDateTime + && detail->InfDate.dwLowDateTime == filetime.dwLowDateTime, + "Expected %#x%08x, got %#x%08x.\n", filetime.dwHighDateTime, filetime.dwLowDateTime, + detail->InfDate.dwHighDateTime, detail->InfDate.dwLowDateTime); + ok(!strcmp(detail->SectionName, "install1"), "Got section name %s.\n", debugstr_a(detail->SectionName)); + ok(!stricmp(detail->InfFileName, short_path), "Got INF file name %s.\n", debugstr_a(detail->InfFileName)); + ok(!strcmp(detail->DrvDescription, "desc1"), "Got description %s.\n", debugstr_a(detail->DrvDescription)); + ok(!detail->CompatIDsOffset, "Got wrong compat IDs offset %u.\n", detail->CompatIDsOffset); + ok(!detail->CompatIDsLength, "Got wrong compat IDs length %u.\n", detail->CompatIDsLength); + ok(!detail->HardwareID[0], "Got wrong ID list.\n"); + + size = 0xdeadbeef; + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, sizeof(SP_DRVINFO_DETAIL_DATA_A), &size); + ok(!ret, "Expected failure.\n"); + ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got unexpected error %#x.\n", GetLastError()); + ok(size == expect_size, "Got size %u.\n", size); + + size = 0xdeadbeef; + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, sizeof(detail_buffer), &size); + ok(ret, "Failed to get driver details, error %#x.\n", GetLastError()); + ok(size == expect_size, "Got size %u.\n", size); + ok(detail->InfDate.dwHighDateTime == filetime.dwHighDateTime + && detail->InfDate.dwLowDateTime == filetime.dwLowDateTime, + "Expected %#x%08x, got %#x%08x.\n", filetime.dwHighDateTime, filetime.dwLowDateTime, + detail->InfDate.dwHighDateTime, detail->InfDate.dwLowDateTime); + ok(!strcmp(detail->SectionName, "install1"), "Got section name %s.\n", debugstr_a(detail->SectionName)); + ok(!stricmp(detail->InfFileName, short_path), "Got INF file name %s.\n", debugstr_a(detail->InfFileName)); + ok(!strcmp(detail->DrvDescription, "desc1"), "Got description %s.\n", debugstr_a(detail->DrvDescription)); + ok(!detail->CompatIDsOffset, "Got wrong compat IDs offset %u.\n", detail->CompatIDsOffset); + ok(!detail->CompatIDsLength, "Got wrong compat IDs length %u.\n", detail->CompatIDsLength); + ok(!memcmp(detail->HardwareID, "bogus_hardware_id\0", sizeof("bogus_hardware_id\0")), "Got wrong ID list.\n"); + ret = SetupDiEnumDriverInfoA(set, &device, SPDIT_COMPATDRIVER, 1, &driver); ok(ret, "Failed to enumerate drivers, error %#x.\n", GetLastError()); ok(driver.DriverType == SPDIT_COMPATDRIVER, "Got wrong type %#x.\n", driver.DriverType); @@ -2421,6 +2496,19 @@ static void test_driver_list(void) ok(!strcmp(driver.Description, "desc4"), "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); + ret = SetupDiGetDriverInfoDetailA(set, &device, &driver, detail, sizeof(detail_buffer), NULL); + ok(ret, "Failed to get driver details, error %#x.\n", GetLastError()); + ok(detail->InfDate.dwHighDateTime == filetime.dwHighDateTime + && detail->InfDate.dwLowDateTime == filetime.dwLowDateTime, + "Expected %#x%08x, got %#x%08x.\n", filetime.dwHighDateTime, filetime.dwLowDateTime, + detail->InfDate.dwHighDateTime, detail->InfDate.dwLowDateTime); + ok(!detail->SectionName[0], "Got section name %s.\n", debugstr_a(detail->SectionName)); + ok(!stricmp(detail->InfFileName, short_path), "Got INF file name %s.\n", debugstr_a(detail->InfFileName)); + ok(!strcmp(detail->DrvDescription, "desc4"), "Got description %s.\n", debugstr_a(detail->DrvDescription)); + ok(detail->CompatIDsOffset == sizeof("wrong_hardware_id"), "Got wrong compat IDs offset %u.\n", detail->CompatIDsOffset); + ok(detail->CompatIDsLength == sizeof("bogus_compat_id\0"), "Got wrong compat IDs length %u.\n", detail->CompatIDsLength); + ok(!memcmp(detail->HardwareID, "wrong_hardware_id\0bogus_compat_id\0", + sizeof("wrong_hardware_id\0bogus_compat_id\0")), "Got wrong ID list.\n");
ret = SetupDiEnumDriverInfoA(set, &device, SPDIT_COMPATDRIVER, 3, &driver); ok(ret, "Failed to enumerate drivers, error %#x.\n", GetLastError());
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=66687
Your paranoid android.
=== w1064v1809 (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809_2scr (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809_ar (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809_he (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809_ja (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809_zh_CN (32 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
=== w1064v1809 (64 bit report) ===
setupapi: devinst.c:2427: Test failed: Failed to get driver details, error 0x6f8. devinst.c:2461: Test failed: Got wrong compat IDs offset 18. devinst.c:2526: Test failed: Expected failure. devinst.c:2527: Test failed: Got unexpected error 0.
From: Zebediah Figura z.figura12@gmail.com
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/setupapi/devinst.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index ef1e824ffbb..b52a13cb176 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -4333,7 +4333,7 @@ CONFIGRET WINAPI CM_Get_DevNode_PropertyW(DEVINST dev, const DEVPROPKEY *key, DE */ BOOL WINAPI SetupDiInstallDeviceInterfaces(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) { - WCHAR section[LINE_LEN], section_ext[LINE_LEN], iface_section[LINE_LEN], refstr[LINE_LEN], guidstr[39]; + WCHAR section_ext[LINE_LEN], iface_section[LINE_LEN], refstr[LINE_LEN], guidstr[39]; UINT install_flags = SPINST_ALL; struct device_iface *iface; struct device *device; @@ -4360,9 +4360,7 @@ BOOL WINAPI SetupDiInstallDeviceInterfaces(HDEVINFO devinfo, SP_DEVINFO_DATA *de if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) return FALSE;
- SetupFindFirstLineW(hinf, driver->mfg_key, driver->description, &ctx); - SetupGetStringFieldW(&ctx, 1, section, ARRAY_SIZE(section), NULL); - SetupDiGetActualSectionToInstallW(hinf, section, section_ext, ARRAY_SIZE(section_ext), NULL, NULL); + SetupDiGetActualSectionToInstallW(hinf, driver->section, section_ext, ARRAY_SIZE(section_ext), NULL, NULL);
if (device->params.Flags & DI_NOFILECOPY) install_flags &= ~SPINST_FILES; @@ -4410,12 +4408,11 @@ BOOL WINAPI SetupDiInstallDeviceInterfaces(HDEVINFO devinfo, SP_DEVINFO_DATA *de BOOL WINAPI SetupDiRegisterCoDeviceInstallers(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) { static const WCHAR coinstallersW[] = {'.','C','o','I','n','s','t','a','l','l','e','r','s',0}; - WCHAR coinst_key[LINE_LEN], coinst_key_ext[LINE_LEN]; + WCHAR coinst_key_ext[LINE_LEN]; struct device *device; struct driver *driver; void *callback_ctx; HKEY driver_key; - INFCONTEXT ctx; HINF hinf; LONG l;
@@ -4434,9 +4431,7 @@ BOOL WINAPI SetupDiRegisterCoDeviceInstallers(HDEVINFO devinfo, SP_DEVINFO_DATA if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) return FALSE;
- SetupFindFirstLineW(hinf, driver->mfg_key, driver->description, &ctx); - SetupGetStringFieldW(&ctx, 1, coinst_key, ARRAY_SIZE(coinst_key), NULL); - SetupDiGetActualSectionToInstallW(hinf, coinst_key, coinst_key_ext, ARRAY_SIZE(coinst_key_ext), NULL, NULL); + SetupDiGetActualSectionToInstallW(hinf, driver->section, coinst_key_ext, ARRAY_SIZE(coinst_key_ext), NULL, NULL); lstrcatW(coinst_key_ext, coinstallersW);
if ((l = create_driver_key(device, &driver_key))) @@ -4998,10 +4993,10 @@ BOOL WINAPI SetupDiInstallDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) static const WCHAR addserviceW[] = {'A','d','d','S','e','r','v','i','c','e',0}; static const WCHAR rootW[] = {'r','o','o','t','\',0}; WCHAR section[LINE_LEN], section_ext[LINE_LEN], subsection[LINE_LEN], inf_path[MAX_PATH], *extptr, *filepart; - WCHAR svc_name[LINE_LEN], field[LINE_LEN]; UINT install_flags = SPINST_ALL; HKEY driver_key, device_key; SC_HANDLE manager, service; + WCHAR svc_name[LINE_LEN]; struct device *device; struct driver *driver; void *callback_ctx; @@ -5024,13 +5019,10 @@ BOOL WINAPI SetupDiInstallDevice(HDEVINFO devinfo, SP_DEVINFO_DATA *device_data) if ((hinf = SetupOpenInfFileW(driver->inf_path, NULL, INF_STYLE_WIN4, NULL)) == INVALID_HANDLE_VALUE) return FALSE;
- SetupFindFirstLineW(hinf, driver->mfg_key, driver->description, &ctx); - - SetupGetStringFieldW(&ctx, 0, field, ARRAY_SIZE(field), NULL); - RegSetValueExW(device->key, L"DeviceDesc", 0, REG_SZ, (BYTE *)field, wcslen(field) * sizeof(WCHAR)); + RegSetValueExW(device->key, L"DeviceDesc", 0, REG_SZ, (BYTE *)driver->description, + wcslen(driver->description) * sizeof(WCHAR));
- SetupGetStringFieldW(&ctx, 1, section, ARRAY_SIZE(section), NULL); - SetupDiGetActualSectionToInstallW(hinf, section, section_ext, ARRAY_SIZE(section_ext), NULL, &extptr); + SetupDiGetActualSectionToInstallW(hinf, driver->section, section_ext, ARRAY_SIZE(section_ext), NULL, &extptr);
if ((l = create_driver_key(device, &driver_key))) {
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=66686
Your paranoid android.
=== w1064v1809 (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809_2scr (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809_ar (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809_he (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809_ja (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809_zh_CN (32 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
=== w1064v1809 (64 bit report) ===
setupapi: devinst.c:2438: Test failed: Expected failure. devinst.c:2439: Test failed: Got unexpected error 0.
On 3/8/20 9:50 AM, Zebediah Figura wrote:
From: Zebediah Figura z.figura12@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48639 Signed-off-by: Zebediah Figura z.figura12@gmail.com
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..69b339e49b3 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);
- ret = SetupDiGetSelectedDriverW(devinfo, device_data, &driver_dataW);
- driver_data_wtoa(driver_data, &driver_dataW);
This need to return early upon failure. Otherwise with driver_dataW containing uninitialized string fields, WideCharToMultiByte() in driver_data_wtoa() could read pass those fields.
- 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..9eed8e73d87 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, "Expected failure.\n");
- ok(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());