In 71aba33f, GetSystemFirmwareTable was moved from kernel32 to kernelbase. In the process, its error handling was refactored to use NtQuerySystemInformation, and it began to return zero whenever NtQuerySystemInformation failed. This prevents software from being able to make 'preflight' calls to determine how large their buffer should be.
This patch simply restores the old behavior.
Signed-off-by: John Chadwick john@jchw.io --- dlls/kernelbase/memory.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/memory.c b/dlls/kernelbase/memory.c index 6be399bc97..c93d490e74 100644 --- a/dlls/kernelbase/memory.c +++ b/dlls/kernelbase/memory.c @@ -1161,13 +1161,10 @@ UINT WINAPI GetSystemFirmwareTable( DWORD provider, DWORD id, void *buffer, DWOR info->Action = SystemFirmwareTable_Get; info->TableID = id;
- if (set_ntstatus( NtQuerySystemInformation( SystemFirmwareTableInformation, - info, buffer_size, &buffer_size ))) - { - buffer_size -= offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer ); - if (buffer_size <= size) memcpy( buffer, info->TableBuffer, buffer_size ); - } - else buffer_size = 0; + set_ntstatus( NtQuerySystemInformation( SystemFirmwareTableInformation, + info, buffer_size, &buffer_size )); + buffer_size -= offsetof( SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer ); + if (buffer_size <= size) memcpy( buffer, info->TableBuffer, buffer_size );
HeapFree( GetProcessHeap(), 0, info ); return buffer_size;
This adds a test to ensure that a typical usage of GetSystemFirmwareTable with a preflight call works correctly.
Signed-off-by: John Chadwick john@jchw.io --- dlls/kernelbase/tests/Makefile.in | 1 + dlls/kernelbase/tests/memory.c | 56 +++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 dlls/kernelbase/tests/memory.c
diff --git a/dlls/kernelbase/tests/Makefile.in b/dlls/kernelbase/tests/Makefile.in index 22e4a17a58..f269147733 100644 --- a/dlls/kernelbase/tests/Makefile.in +++ b/dlls/kernelbase/tests/Makefile.in @@ -1,5 +1,6 @@ TESTDLL = kernelbase.dll
C_SRCS = \ + memory.c \ path.c \ sync.c diff --git a/dlls/kernelbase/tests/memory.c b/dlls/kernelbase/tests/memory.c new file mode 100644 index 0000000000..e6b8d7da04 --- /dev/null +++ b/dlls/kernelbase/tests/memory.c @@ -0,0 +1,56 @@ +/* + * Memory tests for kernelbase.dll + * + * Copyright 2019 John Chadwick + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> +#include <windef.h> +#include <winbase.h> +#include <stdlib.h> +#include <winerror.h> + +#include "wine/test.h" + +#define RSMB 0x52534D42 + +static UINT (WINAPI *pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD); + +static void test_GetSystemFirmwareTable(void) +{ + DWORD size, bytes_returned; + void *data; + + size = pGetSystemFirmwareTable(RSMB, 0, NULL, 0); + ok(size > 0, "got %d", size); + + data = HeapAlloc(GetProcessHeap(), 0, size); + ok(data != NULL, "alloc failed"); + + bytes_returned = pGetSystemFirmwareTable(RSMB, 0, data, size); + ok(bytes_returned == size, "expect %d, got %d\n", size, bytes_returned); +} + +START_TEST(memory) +{ + HMODULE hmod; + + hmod = LoadLibraryA("kernelbase.dll"); + pGetSystemFirmwareTable = (void *)GetProcAddress(hmod, "GetSystemFirmwareTable"); + + test_GetSystemFirmwareTable(); +}
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=60501
Your paranoid android.
=== wxppro (32 bit report) ===
kernelbase: 09dc:memory: unhandled exception c0000005 at 00000000
=== w2003std (32 bit report) ===
kernelbase: 01e8:memory: unhandled exception c0000005 at 00000000
=== wvistau64 (32 bit report) ===
kernelbase: 0910:memory: unhandled exception c0000005 at 00000000
=== w2008s64 (32 bit report) ===
kernelbase: 05f8:memory: unhandled exception c0000005 at 00000000
=== w7u (32 bit report) ===
kernelbase: 0d7c:memory: unhandled exception c0000005 at 00000000
=== wvistau64 (64 bit report) ===
kernelbase: 06ec:memory: unhandled exception c0000005 at 0000000000000000
=== w2008s64 (64 bit report) ===
kernelbase: 0390:memory: unhandled exception c0000005 at 0000000000000000