[PATCH 9/9] setupapi/tests: properties and enumerators for display devices

Donat Enikeev donat at enikeev.net
Mon Apr 24 15:53:41 CDT 2017


Signed-off-by: Donat Enikeev <donat at enikeev.net>
---
 dlls/setupapi/tests/devinst.c | 211 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 211 insertions(+)

diff --git a/dlls/setupapi/tests/devinst.c b/dlls/setupapi/tests/devinst.c
index 6ca0e92..0fc99b8 100644
--- a/dlls/setupapi/tests/devinst.c
+++ b/dlls/setupapi/tests/devinst.c
@@ -28,6 +28,8 @@
 #include "winreg.h"
 #include "guiddef.h"
 #include "setupapi.h"
+#include "initguid.h"
+#include "devguid.h"
 
 #include "wine/test.h"
 
@@ -61,6 +63,8 @@ static BOOL     (WINAPI *pSetupDiGetDeviceRegistryPropertyW)(HDEVINFO, PSP_DEVIN
 static BOOL     (WINAPI *pSetupDiRemoveDevice)(HDEVINFO, PSP_DEVINFO_DATA);
 static BOOL     (WINAPI *pSetupDiRemoveDeviceInterface)(HDEVINFO, PSP_DEVICE_INTERFACE_DATA);
 static BOOL     (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
+static BOOL     (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,LPDISPLAY_DEVICEA,DWORD);
+static BOOL     (WINAPI *pEnumDisplayDevicesW)(LPCWSTR,DWORD,LPDISPLAY_DEVICEW,DWORD);
 
 /* This is a unique guid for testing purposes */
 static GUID guid = {0x6a55b5a4, 0x3f65, 0x11db, {0xb7,0x04,0x00,0x11,0x95,0x5c,0x2b,0xdb}};
@@ -69,6 +73,7 @@ static void init_function_pointers(void)
 {
     HMODULE hSetupAPI = GetModuleHandleA("setupapi.dll");
     HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
+    HMODULE hUser32 = GetModuleHandleA("user32.dll");
 
     pSetupDiCreateDeviceInfoA = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoA");
     pSetupDiCreateDeviceInfoW = (void *)GetProcAddress(hSetupAPI, "SetupDiCreateDeviceInfoW");
@@ -97,6 +102,8 @@ static void init_function_pointers(void)
     pSetupDiRemoveDeviceInterface = (void *)GetProcAddress(hSetupAPI, "SetupDiRemoveDeviceInterface");
     pSetupDiRemoveDevice = (void *)GetProcAddress(hSetupAPI, "SetupDiRemoveDevice");
     pIsWow64Process = (void *)GetProcAddress(hKernel32, "IsWow64Process");
+    pEnumDisplayDevicesA = (void *)GetProcAddress(hUser32, "EnumDisplayDevicesA");
+    pEnumDisplayDevicesW = (void *)GetProcAddress(hUser32, "EnumDisplayDevicesW");
 }
 
 static LSTATUS devinst_RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
@@ -1347,6 +1354,208 @@ static void testSetupDiGetINFClassA(void)
     }
 }
 
+static BOOL check_driver_date(const char *driver, DWORD devnum)
+{
+    const SYSTEMTIME date2000_01_01 = {2000, 1, 6, 1, 0, 0, 0, 0};
+    const char class_path[] = "System\\CurrentControlSet\\Control\\Class\\%s";
+    const char driver_date_data[] = "DriverDateData";
+    char driver_path[MAX_PATH];
+    HKEY key;
+    DWORD type, cb;
+    FILETIME driver_date, cmp_date;
+    LONG l;
+
+    sprintf(driver_path, class_path, driver);
+    l = RegOpenKeyExA(HKEY_LOCAL_MACHINE, driver_path, 0, KEY_READ, &key);
+    ok(!l, "Failed to open driver path (%s) in registry for device %d: %08x\n", driver_path, devnum, GetLastError());
+    if (l) return FALSE;
+
+    cb = sizeof(driver_date);
+    l = RegQueryValueExA(key, driver_date_data, 0, &type, (PBYTE)&driver_date, &cb);
+    ok(!l && type == REG_BINARY, "Failed to get %s binary value at %s of device %d: %08x\n", driver_date_data, driver_path, devnum, GetLastError());
+    if (l) return FALSE;
+
+    RegCloseKey(key);
+
+    ok(cb==sizeof(driver_date), "Unexpected size of data in buffer.\n");
+    if (cb==sizeof(driver_date))
+    {
+        SystemTimeToFileTime(&date2000_01_01, &cmp_date);
+        l = CompareFileTime(&driver_date, &cmp_date);
+        ok (l == 1, "Unexpectly old driver date at %s of device %d\n", driver_path, devnum);
+        if (l == 1)
+            return TRUE;
+    }
+
+    return FALSE;
+ }
+
+
+static void testDisplayDevsPropertiesA(void)
+{
+    const char displ_class_guid[] = "{4d36e968-e325-11ce-bfc1-08002be10318}";
+    const char displ_class[] = "Display";
+
+    SP_DEVINFO_DATA devinfo;
+    DISPLAY_DEVICEA disp;
+    HDEVINFO set;
+    BOOL ret;
+    DWORD devnum = -1;
+
+    if (!pEnumDisplayDevicesA)
+    {
+        win_skip("EnumDisplayDevicesA() is not available\n");
+        return;
+    }
+
+    disp.cb = sizeof(disp);
+    SetLastError(0xdeadbeef);
+    while (pEnumDisplayDevicesA(NULL, ++devnum, &disp, 0))
+    {
+        if (disp.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER
+            || !(disp.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) continue;
+
+        set = pSetupDiGetClassDevsA(&GUID_DEVCLASS_DISPLAY, disp.DeviceID, 0, DIGCF_PRESENT);
+        ok(set != INVALID_HANDLE_VALUE
+            /* wxppro */ || GetLastError() == ERROR_INVALID_DATA ,
+                "SetupDiGetClassDevsA failed for device %d (%s, state %08x): %08x\n",
+                devnum, disp.DeviceID, disp.StateFlags, GetLastError());
+
+        if (set == INVALID_HANDLE_VALUE) continue;
+
+        devinfo.cbSize = sizeof(devinfo);
+        ret = pSetupDiEnumDeviceInfo(set, 0, &devinfo);
+        ok(ret, "SetupDiEnumDeviceInfo failed for device %d: %08x\n", devnum, GetLastError());
+        if (ret)
+        {
+            char buffer[MAX_PATH];
+
+            ok(IsEqualGUID(&devinfo.ClassGuid,&GUID_DEVCLASS_DISPLAY),
+                "Expected display GUID in SP_DEVINFO_DATA for device %d\n", devnum);
+
+            ret = pSetupDiGetDeviceRegistryPropertyA(set, &devinfo,
+                    SPDRP_CLASSGUID, NULL, (PBYTE)buffer, MAX_PATH, NULL);
+            ok(ret, "Failed to get CLASSGUID property for device %d: %08x\n", devnum, GetLastError());
+            if (ret)
+                ok(!lstrcmpiA((LPSTR)buffer, displ_class_guid),
+                    "Unexpected GUID value (%s) for device %d: %s\n", buffer, devnum, buffer);
+
+            ret = pSetupDiGetDeviceRegistryPropertyA(set, &devinfo,
+                    SPDRP_CLASS, NULL, (PBYTE)buffer, MAX_PATH, NULL);
+            todo_wine ok(ret, "Failed to get CLASS property for device %d: %08x\n", devnum, GetLastError());
+            if (ret)
+                ok(!lstrcmpiA((LPSTR)buffer, displ_class),
+                    "Unexpected CLASS value (%s) for device %d: %s\n", buffer, devnum, buffer);
+
+            ret = pSetupDiGetDeviceRegistryPropertyA(set, &devinfo,
+                    SPDRP_DRIVER, NULL, (PBYTE)buffer, MAX_PATH, NULL);
+            ok(ret, "Failed to get DRIVER property for device %d: %08x\n", devnum, GetLastError());
+            if (ret)
+                check_driver_date(buffer, devnum);
+        }
+        pSetupDiDestroyDeviceInfoList(set);
+    }
+
+    if (!devnum)
+        skip("No display device available for the test: %08x\n", GetLastError());
+}
+
+static const struct
+{
+    const GUID *classguid;
+    WCHAR enumerator[10]; /* {0} -> use actual display's DeviceID as enumerator, eg PCI\\DEV0000&VEN0000 */
+    DWORD flags;
+    BOOL expect_set;
+    int guid_in_set;
+} displ_enum_tests[] = {
+    { &GUID_DEVCLASS_DISPLAY,  {'P','C','I',0}, 0, TRUE, -1 },
+    { &GUID_DEVCLASS_DISPLAY,  {'P','C','I','\\','B','O','G','U','S',0}, DIGCF_PRESENT, TRUE, 0 },
+    { NULL, {'P','C','I','\\','B','O','G','U','S',0}, DIGCF_PRESENT | DIGCF_ALLCLASSES, TRUE, 0 },
+    { NULL, {'P','C','I',0}, DIGCF_PRESENT | DIGCF_ALLCLASSES, TRUE, -1 },
+    { NULL, {'P','C','I',0}, DIGCF_PRESENT, FALSE, 0 },
+    { &GUID_DEVCLASS_DISPLAY, {0}, DIGCF_PRESENT, TRUE, -1},
+    { NULL, {0}, DIGCF_PRESENT | DIGCF_ALLCLASSES, TRUE, -1},
+    { NULL, {0}, DIGCF_PRESENT, FALSE, 0},
+    { &GUID_DEVCLASS_DISPLAY, {'I','D','E',0}, 0, TRUE, 0 },
+    { &GUID_DEVCLASS_FLOPPYDISK, {'P','C','I',0}, 0 , TRUE, 0 },
+    { &GUID_DEVCLASS_FLOPPYDISK, {0}, 0, TRUE, 0 },
+};
+
+static void testDisplayDevsEnumeratorsW(void)
+{
+    DISPLAY_DEVICEW disp;
+    HDEVINFO set;
+    BOOL ret;
+    DWORD devnum = -1;
+    int i;
+
+    if (!pEnumDisplayDevicesW)
+    {
+        win_skip("EnumDisplayDevicesW() is not available\n");
+        return;
+    }
+
+    disp.cb = sizeof(disp);
+    SetLastError(0xdeadbeef);
+    while (pEnumDisplayDevicesW(NULL, ++devnum, &disp, 0))
+    {
+        if (disp.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER
+            || !(disp.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP)) continue;
+
+        for (i = 0; i < sizeof(displ_enum_tests) / sizeof(displ_enum_tests[0]); i++)
+        {
+            DWORD member_idx;
+            BOOL displ_guid_found;
+
+            set = pSetupDiGetClassDevsW(displ_enum_tests[i].classguid,
+                displ_enum_tests[i].enumerator[0] ? displ_enum_tests[i].enumerator : NULL,
+                0, displ_enum_tests[i].flags);
+
+            if (set == INVALID_HANDLE_VALUE)
+            {
+                ok(!displ_enum_tests[i].expect_set
+                    /* wxppro .. w7pro */ || GetLastError() == ERROR_INVALID_DATA,
+                    "Unexpected set for device %d (state %08x) at %d: %08x\n",
+                    devnum, disp.StateFlags, i, GetLastError());
+                continue;
+            }
+
+            member_idx = 0;
+            displ_guid_found = FALSE;
+            do
+            {
+                SP_DEVINFO_DATA devinfo;
+
+                devinfo.cbSize = sizeof(devinfo);
+                ret = pSetupDiEnumDeviceInfo(set, member_idx, &devinfo);
+                ok (ret || GetLastError() == ERROR_NO_MORE_ITEMS,
+                    "Failed to get %d member of deivce %d info set at %d: %08x\n",
+                    member_idx, devnum, i, GetLastError());
+
+                if (ret && IsEqualGUID(&devinfo.ClassGuid,&GUID_DEVCLASS_DISPLAY))
+                {
+                    displ_guid_found = TRUE;
+                    break;
+                }
+                member_idx++;
+            } while (ret);
+
+            ok( displ_guid_found || !displ_enum_tests[i].guid_in_set
+                /* Some tests fail on testbot's wxppro VM, skipping it */ ||
+                displ_enum_tests[i].guid_in_set == -1,
+                "No display GUID found in device %d set among %d entries at %d\n", devnum, member_idx-1, i);
+
+            if (!displ_guid_found && displ_enum_tests[i].guid_in_set == -1)
+                win_skip("No display GUID found in device %d set among %d entries at %d;"
+                 " expected for some wxppro VM only\n",devnum, member_idx-1, i);
+
+            pSetupDiDestroyDeviceInfoList(set);
+        }
+    }
+    if (!devnum)
+        skip("No display device available for the test: %08x\n", GetLastError());
+}
+
 START_TEST(devinst)
 {
     HKEY hkey;
@@ -1384,4 +1593,6 @@ START_TEST(devinst)
     testDeviceRegistryPropertyA();
     testDeviceRegistryPropertyW();
     testSetupDiGetINFClassA();
+    testDisplayDevsPropertiesA();
+    testDisplayDevsEnumeratorsW();
 }
-- 
2.7.4




More information about the wine-patches mailing list