https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8acc68dd986316b59061c…
commit 8acc68dd986316b59061cb2d3e8b8a312a7c93d6
Author: Stanislav Motylkov <x86corez(a)gmail.com>
AuthorDate: Sun Jul 29 17:43:10 2018 +0300
Commit: Mark Jansen <mark.jansen(a)reactos.org>
CommitDate: Thu Aug 2 21:15:28 2018 +0200
[KERNEL32_APITEST] Add SystemFirmware tests
CORE-12105
---
modules/rostests/apitests/kernel32/CMakeLists.txt | 1 +
.../rostests/apitests/kernel32/SystemFirmware.c | 466 +++++++++++++++++++++
modules/rostests/apitests/kernel32/testlist.c | 2 +
3 files changed, 469 insertions(+)
diff --git a/modules/rostests/apitests/kernel32/CMakeLists.txt
b/modules/rostests/apitests/kernel32/CMakeLists.txt
index c329031929..37c5b6adc8 100644
--- a/modules/rostests/apitests/kernel32/CMakeLists.txt
+++ b/modules/rostests/apitests/kernel32/CMakeLists.txt
@@ -28,6 +28,7 @@ list(APPEND SOURCE
SetConsoleWindowInfo.c
SetCurrentDirectory.c
SetUnhandledExceptionFilter.c
+ SystemFirmware.c
TerminateProcess.c
TunnelCache.c
WideCharToMultiByte.c
diff --git a/modules/rostests/apitests/kernel32/SystemFirmware.c
b/modules/rostests/apitests/kernel32/SystemFirmware.c
new file mode 100644
index 0000000000..5ba946d815
--- /dev/null
+++ b/modules/rostests/apitests/kernel32/SystemFirmware.c
@@ -0,0 +1,466 @@
+/*
+ * PROJECT: ReactOS API Tests
+ * LICENSE: GPL-2.0+ (
https://spdx.org/licenses/GPL-2.0+)
+ * PURPOSE: Tests for System Firmware functions
+ * COPYRIGHT: Copyright 2018 Stanislav Motylkov
+ */
+
+#include "precomp.h"
+
+static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, PVOID, DWORD);
+static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, PVOID, DWORD);
+
+typedef struct ENTRY
+{
+ DWORD Signature;
+ DWORD ErrInsuff;
+ DWORD ErrSuccess;
+} ENTRY;
+
+static
+VOID
+test_EnumBuffer(
+ DWORD Signature,
+ PVOID Buffer,
+ DWORD dwSize,
+ UINT * pTableCount,
+ DWORD * pFirstTableID,
+ DWORD ErrInsuff,
+ DWORD ErrSuccess
+)
+{
+ DWORD dwError;
+ DWORD dwBufferSize;
+ DWORD dwException;
+ UINT uResultSize;
+
+ dwException = Buffer && IsBadWritePtr(Buffer, dwSize) ?
STATUS_ACCESS_VIOLATION : STATUS_SUCCESS;
+
+ // Test size = 0
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = 0;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pEnumSystemFirmwareTables(Signature, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(STATUS_SUCCESS);
+
+ if (uResultSize > 0)
+ {
+ ok(dwError == ErrInsuff,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrInsuff);
+ }
+ else
+ {
+ ok(dwError == ErrSuccess,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrSuccess);
+ }
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(uResultSize % sizeof(DWORD) == 0,
+ "uResultSize is %u, expected %% sizeof(DWORD)\n",
+ uResultSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ ok(*(BYTE *)Buffer == 0xFF,
+ "Buffer should be clean at offset 0, got %x\n",
+ *(BYTE *)Buffer);
+ }
+
+ // Test size = 2
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = 2;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pEnumSystemFirmwareTables(Signature, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(STATUS_SUCCESS);
+
+ if (uResultSize > 0)
+ {
+ ok(dwError == ErrInsuff,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrInsuff);
+ }
+ else
+ {
+ ok(dwError == ErrSuccess,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrSuccess);
+ }
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(uResultSize % sizeof(DWORD) == 0,
+ "uResultSize is %u, expected %% sizeof(DWORD)\n",
+ uResultSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ ok(*(WORD *)Buffer == 0xFFFF,
+ "Buffer should be clean at offset 0, got %x\n",
+ *(WORD *)Buffer);
+ }
+
+ // Test full size
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ if (uResultSize > 0)
+ {
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = uResultSize;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pEnumSystemFirmwareTables(Signature, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(ErrSuccess == ERROR_SUCCESS ? dwException : STATUS_SUCCESS);
+ // Windows 7: does not throw exception here
+
+ if (dwException == STATUS_SUCCESS || ErrSuccess == ERROR_INVALID_FUNCTION)
+ {
+ ok(dwError == ErrSuccess,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrSuccess);
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(uResultSize == dwBufferSize,
+ "uResultSize is not equal dwBufferSize, expected %ld\n",
+ dwBufferSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ }
+ else
+ {
+ // Windows 7: returns ERROR_NOACCESS here
+ ok(dwError == 0xbeeffeed,
+ "GetLastError() returned %ld, expected %u\n",
+ dwError, 0xbeeffeed);
+ // Windows 7: returns correct size here
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ }
+
+ if (pTableCount && pFirstTableID)
+ {
+ if (uResultSize > 0)
+ {
+ if (Signature == 'RSMB')
+ {
+ // Raw SMBIOS have only one table with ID 0
+ ok(*(DWORD *)Buffer == 0,
+ "Buffer should be filled at offset 0, got %lx\n",
+ *(DWORD *)Buffer);
+ }
+ else
+ {
+ // In other cases ID can be different
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(*(DWORD *)Buffer != 0xFFFFFFFF,
+ "Buffer should be filled at offset 0\n");
+ }
+ else
+ {
+ ok(*(DWORD *)Buffer == 0xFFFFFFFF,
+ "Buffer should be clean at offset 0\n");
+ }
+ }
+ }
+ *pTableCount = uResultSize / sizeof(DWORD);
+ *pFirstTableID = *(DWORD *)Buffer;
+ }
+}
+
+static
+VOID
+test_GetBuffer(
+ DWORD Signature,
+ DWORD TableID,
+ PVOID Buffer,
+ DWORD dwSize,
+ BOOL TestFakeID,
+ DWORD ErrInsuff,
+ DWORD ErrSuccess
+)
+{
+ DWORD dwError;
+ DWORD dwBufferSize;
+ DWORD dwException;
+ DWORD dwErrCase;
+ UINT uResultSize;
+
+ dwException = Buffer && IsBadWritePtr(Buffer, dwSize) ?
STATUS_ACCESS_VIOLATION : STATUS_SUCCESS;
+ switch (Signature)
+ {
+ case 'ACPI':
+ {
+ dwErrCase = ERROR_NOT_FOUND;
+ break;
+ }
+ case 'FIRM':
+ {
+ dwErrCase = ERROR_INVALID_PARAMETER;
+ break;
+ }
+ default:
+ {
+ dwErrCase = ErrInsuff;
+ }
+ }
+
+ // Test size = 0
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = 0;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pGetSystemFirmwareTable(Signature, TableID, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(STATUS_SUCCESS);
+
+ ok(dwError == (TestFakeID ? dwErrCase : ErrInsuff),
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, (TestFakeID ? dwErrCase : ErrInsuff));
+ if (ErrSuccess == ERROR_SUCCESS && (!TestFakeID || dwErrCase == ErrInsuff))
+ {
+ ok(uResultSize > 0,
+ "uResultSize is %u, expected > 0\n",
+ uResultSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ ok(*(BYTE *)Buffer == 0xFF,
+ "Buffer should be clean at offset 0, got %x\n",
+ *(BYTE *)Buffer);
+ }
+
+ // Test size = 2
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = 2;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pGetSystemFirmwareTable(Signature, TableID, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(STATUS_SUCCESS);
+
+ ok(dwError == (TestFakeID ? dwErrCase : ErrInsuff),
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, (TestFakeID ? dwErrCase : ErrInsuff));
+ if (ErrSuccess == ERROR_SUCCESS && (!TestFakeID || dwErrCase == ErrInsuff))
+ {
+ ok(uResultSize > 0,
+ "uResultSize is %u, expected > 0\n",
+ uResultSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ ok(*(WORD *)Buffer == 0xFFFF,
+ "Buffer should be clean at offset 0, got %x\n",
+ *(WORD *)Buffer);
+ }
+
+ // Test full size
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ FillMemory(Buffer, dwSize, 0xFF);
+ }
+ if (uResultSize == 0)
+ {
+ return;
+ }
+ SetLastError(0xbeeffeed);
+ dwError = GetLastError();
+ dwBufferSize = uResultSize;
+ uResultSize = 0;
+ StartSeh()
+ uResultSize = pGetSystemFirmwareTable(Signature, TableID, Buffer, dwBufferSize);
+ dwError = GetLastError();
+ EndSeh(ErrSuccess == ERROR_SUCCESS ? dwException : STATUS_SUCCESS);
+ // Windows 7: does not throw exception here
+
+ if (dwException == STATUS_SUCCESS || ErrSuccess == ERROR_INVALID_FUNCTION)
+ {
+ ok(dwError == ErrSuccess,
+ "GetLastError() returned %ld, expected %ld\n",
+ dwError, ErrSuccess);
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(uResultSize == dwBufferSize,
+ "uResultSize is not equal dwBufferSize, expected %ld\n",
+ dwBufferSize);
+ }
+ else
+ {
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+ }
+ else
+ {
+ // Windows 7: returns ERROR_NOACCESS here
+ ok(dwError == 0xbeeffeed,
+ "GetLastError() returned %ld, expected %u\n",
+ dwError, 0xbeeffeed);
+ // Windows 7: returns correct size here
+ ok(uResultSize == 0,
+ "uResultSize is %u, expected == 0\n",
+ uResultSize);
+ }
+
+ if (Buffer && dwException == STATUS_SUCCESS)
+ {
+ if (ErrSuccess == ERROR_SUCCESS)
+ {
+ ok(*(DWORD *)Buffer != 0xFFFFFFFF,
+ "Buffer should be filled at offset 0\n");
+ }
+ else
+ {
+ ok(*(DWORD *)Buffer == 0xFFFFFFFF,
+ "Buffer should be clean at offset 0\n");
+ }
+ }
+}
+
+START_TEST(SystemFirmware)
+{
+ static const ENTRY Entries[] =
+ {
+ { 'ACPI', ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS },
+ { 'FIRM', ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS },
+ { 'RSMB', ERROR_INSUFFICIENT_BUFFER, ERROR_SUCCESS },
+ /* This entry should be last */
+ { 0xDEAD, ERROR_INVALID_FUNCTION, ERROR_INVALID_FUNCTION },
+ };
+ HANDLE hKernel;
+ CHAR Buffer[262144]; // 256 KiB should be enough
+ CHAR Sign[sizeof(DWORD) + 1];
+ UINT TableCount[_countof(Entries)];
+ DWORD FirstTableID[_countof(Entries)];
+ int i;
+
+ hKernel = GetModuleHandleW(L"kernel32.dll");
+ if (!hKernel)
+ {
+ skip("kernel32.dll module not found. Can't proceed\n");
+ return;
+ }
+
+ pEnumSystemFirmwareTables = (void *)GetProcAddress(hKernel,
"EnumSystemFirmwareTables");
+ pGetSystemFirmwareTable = (void *)GetProcAddress(hKernel,
"GetSystemFirmwareTable");
+
+ if (!pEnumSystemFirmwareTables)
+ {
+ skip("EnumSystemFirmwareTables not found. Can't proceed\n");
+ return;
+ }
+ if (!pGetSystemFirmwareTable)
+ {
+ skip("GetSystemFirmwareTable not found. Can't proceed\n");
+ return;
+ }
+
+ // Test EnumSystemFirmwareTables
+ for (i = 0; i < _countof(Entries); i++)
+ {
+ // Test with NULL buffer
+ test_EnumBuffer(Entries[i].Signature, NULL, sizeof(Buffer), NULL, NULL,
+ Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with wrong buffer
+ test_EnumBuffer(Entries[i].Signature, (PVOID *)0xbeeffeed, sizeof(Buffer), NULL,
NULL,
+ Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with correct buffer
+ test_EnumBuffer(Entries[i].Signature, &Buffer, sizeof(Buffer),
&TableCount[i], &FirstTableID[i],
+ Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ }
+
+ // Test GetSystemFirmwareTable
+ for (i = 0; i < _countof(Entries); i++)
+ {
+ // Test with fake ID and NULL buffer
+ test_GetBuffer(Entries[i].Signature, 0xbeeffeed, NULL, sizeof(Buffer),
+ TRUE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with fake ID and wrong buffer
+ test_GetBuffer(Entries[i].Signature, 0xbeeffeed, (PVOID *)0xbeeffeed,
sizeof(Buffer),
+ TRUE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with fake ID and correct buffer
+ test_GetBuffer(Entries[i].Signature, 0xbeeffeed, &Buffer, sizeof(Buffer),
+ TRUE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ if (TableCount[i] == 0)
+ {
+ if (i < _countof(Entries) - 1)
+ {
+ ZeroMemory(&Sign, sizeof(Sign));
+ *(DWORD *)&Sign = _byteswap_ulong(Entries[i].Signature);
+ skip("No tables for %s found. Skipping\n",
+ Sign);
+ }
+ continue;
+ }
+ // Test with correct ID and NULL buffer
+ test_GetBuffer(Entries[i].Signature, FirstTableID[i], NULL, sizeof(Buffer),
+ FALSE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with correct ID and wrong buffer
+ test_GetBuffer(Entries[i].Signature, FirstTableID[i], (PVOID *)0xbeeffeed,
sizeof(Buffer),
+ FALSE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ // Test with correct ID and correct buffer
+ test_GetBuffer(Entries[i].Signature, FirstTableID[i], &Buffer,
sizeof(Buffer),
+ FALSE, Entries[i].ErrInsuff, Entries[i].ErrSuccess);
+ }
+}
diff --git a/modules/rostests/apitests/kernel32/testlist.c
b/modules/rostests/apitests/kernel32/testlist.c
index 0bf5e424dc..6364cab804 100644
--- a/modules/rostests/apitests/kernel32/testlist.c
+++ b/modules/rostests/apitests/kernel32/testlist.c
@@ -27,6 +27,7 @@ extern void func_PrivMoveFileIdentityW(void);
extern void func_SetConsoleWindowInfo(void);
extern void func_SetCurrentDirectory(void);
extern void func_SetUnhandledExceptionFilter(void);
+extern void func_SystemFirmware(void);
extern void func_TerminateProcess(void);
extern void func_TunnelCache(void);
extern void func_WideCharToMultiByte(void);
@@ -57,6 +58,7 @@ const struct test winetest_testlist[] =
{ "SetConsoleWindowInfo", func_SetConsoleWindowInfo },
{ "SetCurrentDirectory", func_SetCurrentDirectory },
{ "SetUnhandledExceptionFilter", func_SetUnhandledExceptionFilter },
+ { "SystemFirmware", func_SystemFirmware },
{ "TerminateProcess", func_TerminateProcess },
{ "TunnelCache", func_TunnelCache },
{ "WideCharToMultiByte", func_WideCharToMultiByte },