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 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 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 110 START_TEST(KbdLayout) 111 { 112 testKeyboardLayouts(); 113 } 114