diff --git a/modules/rostests/apitests/user32/CMakeLists.txt b/modules/rostests/apitests/user32/CMakeLists.txt index c7eeefc5db5..ef2e7c1715b 100644 --- a/modules/rostests/apitests/user32/CMakeLists.txt +++ b/modules/rostests/apitests/user32/CMakeLists.txt @@ -23,6 +23,7 @@ list(APPEND SOURCE GetUserObjectInformation.c GetWindowPlacement.c InitializeLpkHooks.c + KbdLayout.c keybd_event.c LoadImage.c LookupIconIdFromDirectoryEx.c diff --git a/modules/rostests/apitests/user32/KbdLayout.c b/modules/rostests/apitests/user32/KbdLayout.c new file mode 100644 index 00000000000..997c97794a6 --- /dev/null +++ b/modules/rostests/apitests/user32/KbdLayout.c @@ -0,0 +1,113 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for Keyboard Layouts DLL files + * COPYRIGHT: Copyright 2022 Stanislav Motylkov + */ + +#include "precomp.h" +#include +#include + +typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID); + +static void testLayout( + _In_ LPWSTR szFileName, + _In_ LPWSTR szFilePath) +{ + HMODULE hModule; + PFN_KBDLAYERDESCRIPTOR pfnKbdLayerDescriptor; + PKBDTABLES pKbdTbl; + USHORT i, uTableSize; + + trace("Testing '%ls'...\n", szFileName); + + hModule = LoadLibraryW(szFilePath); + if (!hModule) + { + ok(FALSE, "LoadLibraryW failed with code %ld\n", GetLastError()); + return; + } + + pfnKbdLayerDescriptor = (PFN_KBDLAYERDESCRIPTOR)GetProcAddress(hModule, "KbdLayerDescriptor"); + if (!pfnKbdLayerDescriptor) + { + ok(FALSE, "KbdLayerDescriptor not found!\n"); + goto Cleanup; + } + + pKbdTbl = pfnKbdLayerDescriptor(); + if (!pKbdTbl) + { + ok(FALSE, "PKBDTABLES is NULL!\n"); + goto Cleanup; + } + + if (!pKbdTbl->pusVSCtoVK) + { + ok(FALSE, "pusVSCtoVK table is NULL!\n"); + goto Cleanup; + } + + if (wcscmp(szFileName, L"kbdnec.dll") == 0) + uTableSize = 128; /* Only NEC PC-9800 Japanese keyboard layout has 128 entries. */ + else + uTableSize = 127; + + /* Validate number of entries in pusVSCtoVK array. */ + ok(pKbdTbl->bMaxVSCtoVK == uTableSize, "pKbdTbl->bMaxVSCtoVK = %u\n", pKbdTbl->bMaxVSCtoVK); + + for (i = 0; i < pKbdTbl->bMaxVSCtoVK; ++i) + { + /* Make sure there are no Virtual Keys with zero value. */ + if (pKbdTbl->pusVSCtoVK[i] == 0) + ok(FALSE, "Scan Code %u => Virtual Key %u\n", i, pKbdTbl->pusVSCtoVK[i]); + } + +Cleanup: + if (hModule) + FreeLibrary(hModule); +} + +static void testKeyboardLayouts(void) +{ + DWORD dwRet; + WCHAR szSysPath[MAX_PATH], + szPattern[MAX_PATH], + szFilePath[MAX_PATH]; + HANDLE hFindFile = INVALID_HANDLE_VALUE; + WIN32_FIND_DATAW wfd; + BOOL bFound = TRUE; + + dwRet = GetSystemDirectoryW(szSysPath, ARRAYSIZE(szSysPath)); + if (!dwRet) + { + skip("GetSystemDirectoryW failed with code %ld\n", GetLastError()); + return; + } + + StringCchCopyW(szPattern, ARRAYSIZE(szPattern), szSysPath); + StringCchCatW(szPattern, ARRAYSIZE(szPattern), L"\\kbd*.dll"); + + for (hFindFile = FindFirstFileW(szPattern, &wfd); + bFound && (hFindFile != INVALID_HANDLE_VALUE); + bFound = FindNextFileW(hFindFile, &wfd)) + { + if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + continue; + + StringCchCopyW(szFilePath, ARRAYSIZE(szFilePath), szSysPath); + StringCchCatW(szFilePath, ARRAYSIZE(szFilePath), L"\\"); + StringCchCatW(szFilePath, ARRAYSIZE(szFilePath), wfd.cFileName); + + testLayout(wfd.cFileName, szFilePath); + } + + if (hFindFile != INVALID_HANDLE_VALUE) + FindClose(hFindFile); +} + +START_TEST(KbdLayout) +{ + testKeyboardLayouts(); +} diff --git a/modules/rostests/apitests/user32/testlist.c b/modules/rostests/apitests/user32/testlist.c index 77a0f4fb343..53d1c8b243d 100644 --- a/modules/rostests/apitests/user32/testlist.c +++ b/modules/rostests/apitests/user32/testlist.c @@ -25,6 +25,7 @@ extern void func_GetSystemMetrics(void); extern void func_GetUserObjectInformation(void); extern void func_GetWindowPlacement(void); extern void func_InitializeLpkHooks(void); +extern void func_KbdLayout(void); extern void func_keybd_event(void); extern void func_LoadImage(void); extern void func_LookupIconIdFromDirectoryEx(void); @@ -78,6 +79,7 @@ const struct test winetest_testlist[] = { "GetUserObjectInformation", func_GetUserObjectInformation }, { "GetWindowPlacement", func_GetWindowPlacement }, { "InitializeLpkHooks", func_InitializeLpkHooks }, + { "KbdLayout", func_KbdLayout }, { "keybd_event", func_keybd_event }, { "LoadImage", func_LoadImage }, { "LookupIconIdFromDirectoryEx", func_LookupIconIdFromDirectoryEx },