1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for Keyboard Layouts DLL files
5 * COPYRIGHT: Copyright 2022 Stanislav Motylkov <x86corez@gmail.com>
6 */
7
8 #include "precomp.h"
9 #include <ndk/kbd.h>
10 #include <strsafe.h>
11
12 typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID);
13
testLayout(_In_ LPWSTR szFileName,_In_ LPWSTR szFilePath)14 static void testLayout(
15 _In_ LPWSTR szFileName,
16 _In_ LPWSTR szFilePath)
17 {
18 HMODULE hModule;
19 PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor;
20 PKBDTABLES pKbdTbl;
21 USHORT i, uTableSize;
22
23 trace("Testing '%ls'...\n", szFileName);
24
25 hModule = LoadLibraryW(szFilePath);
26 if (!hModule)
27 {
28 ok(FALSE, "LoadLibraryW failed with code %ld\n", GetLastError());
29 return;
30 }
31
32 pfnKbdLayerDescriptor = (PFN_KBDLAYERDESCRIPTOR)GetProcAddress(hModule, "KbdLayerDescriptor");
33 if (!pfnKbdLayerDescriptor)
34 {
35 ok(FALSE, "KbdLayerDescriptor not found!\n");
36 goto Cleanup;
37 }
38
39 pKbdTbl = pfnKbdLayerDescriptor();
40 if (!pKbdTbl)
41 {
42 ok(FALSE, "PKBDTABLES is NULL!\n");
43 goto Cleanup;
44 }
45
46 if (!pKbdTbl->pusVSCtoVK)
47 {
48 ok(FALSE, "pusVSCtoVK table is NULL!\n");
49 goto Cleanup;
50 }
51
52 if (wcscmp(szFileName, L"kbdnec.dll") == 0)
53 uTableSize = 128; /* Only NEC PC-9800 Japanese keyboard layout has 128 entries. */
54 else
55 uTableSize = 127;
56
57 /* Validate number of entries in pusVSCtoVK array. */
58 ok(pKbdTbl->bMaxVSCtoVK == uTableSize, "pKbdTbl->bMaxVSCtoVK = %u\n", pKbdTbl->bMaxVSCtoVK);
59
60 for (i = 0; i < pKbdTbl->bMaxVSCtoVK; ++i)
61 {
62 /* Make sure there are no Virtual Keys with zero value. */
63 if (pKbdTbl->pusVSCtoVK[i] == 0)
64 ok(FALSE, "Scan Code %u => Virtual Key %u\n", i, pKbdTbl->pusVSCtoVK[i]);
65 }
66
67 Cleanup:
68 if (hModule)
69 FreeLibrary(hModule);
70 }
71
testKeyboardLayouts(void)72 static void testKeyboardLayouts(void)
73 {
74 DWORD dwRet;
75 WCHAR szSysPath[MAX_PATH],
76 szPattern[MAX_PATH],
77 szFilePath[MAX_PATH];
78 HANDLE hFindFile = INVALID_HANDLE_VALUE;
79 WIN32_FIND_DATAW wfd;
80 BOOL bFound = TRUE;
81
82 dwRet = GetSystemDirectoryW(szSysPath, ARRAYSIZE(szSysPath));
83 if (!dwRet)
84 {
85 skip("GetSystemDirectoryW failed with code %ld\n", GetLastError());
86 return;
87 }
88
89 StringCchCopyW(szPattern, ARRAYSIZE(szPattern), szSysPath);
90 StringCchCatW(szPattern, ARRAYSIZE(szPattern), L"\\kbd*.dll");
91
92 for (hFindFile = FindFirstFileW(szPattern, &wfd);
93 bFound && (hFindFile != INVALID_HANDLE_VALUE);
94 bFound = FindNextFileW(hFindFile, &wfd))
95 {
96 if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
97 continue;
98
99 StringCchCopyW(szFilePath, ARRAYSIZE(szFilePath), szSysPath);
100 StringCchCatW(szFilePath, ARRAYSIZE(szFilePath), L"\\");
101 StringCchCatW(szFilePath, ARRAYSIZE(szFilePath), wfd.cFileName);
102
103 testLayout(wfd.cFileName, szFilePath);
104 }
105
106 if (hFindFile != INVALID_HANDLE_VALUE)
107 FindClose(hFindFile);
108 }
109
START_TEST(KbdLayout)110 START_TEST(KbdLayout)
111 {
112 testKeyboardLayouts();
113 }
114