[KERNEL32_APITEST] Add SystemFirmware tests

CORE-12105
This commit is contained in:
Stanislav Motylkov 2018-07-29 17:43:10 +03:00 committed by Mark Jansen
parent a9f20984cd
commit 8acc68dd98
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
3 changed files with 469 additions and 0 deletions

View file

@ -28,6 +28,7 @@ list(APPEND SOURCE
SetConsoleWindowInfo.c
SetCurrentDirectory.c
SetUnhandledExceptionFilter.c
SystemFirmware.c
TerminateProcess.c
TunnelCache.c
WideCharToMultiByte.c

View file

@ -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);
}
}

View file

@ -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 },