Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/tests/info.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 6c93c3cd58..b18f0d39d9 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -1789,6 +1789,10 @@ static void test_mapprotection(void) } ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status); status = pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &flags, sizeof(flags) ); + if (status == STATUS_ACCESS_DENIED) { + skip("Access to set ProcessExecuteFlags denied\n"); + return; + } ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
size.u.LowPart = 0x2000;
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- include/winternl.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/include/winternl.h b/include/winternl.h index 58c475dfff..6e0bd987b6 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1579,6 +1579,23 @@ typedef struct _SYSTEM_TIME_ADJUSTMENT { BOOLEAN TimeAdjustmentDisabled; } SYSTEM_TIME_ADJUSTMENT, *PSYSTEM_TIME_ADJUSTMENT;
+typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION +{ + SystemFirmwareTable_Enumerate = 0, + SystemFirmwareTable_Get = 1 +} SYSTEM_FIRMWARE_TABLE_ACTION, *PSYSTEM_FIRMWARE_TABLE_ACTION; + +/* System Information Class 0x4C */ + +typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION +{ + ULONG ProviderSignature; + SYSTEM_FIRMWARE_TABLE_ACTION Action; + ULONG TableID; + ULONG TableBufferLength; + UCHAR TableBuffer[1]; +} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION; + typedef struct _TIME_FIELDS { CSHORT Year; CSHORT Month;
Signed-off-by: Huw Davies huw@codeweavers.com
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index b18f0d39d9..9e12a013cf 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -54,6 +54,11 @@ static DWORD one_before_last_pid = 0; } \ } while(0)
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42 + static BOOL InitFunctionPtrs(void) { /* All needed functions are NT based, so using GetModuleHandle is a good check */ @@ -826,6 +831,57 @@ static void test_query_logicalprocex(void) } }
+static void test_query_firmware(void) +{ + ULONG len1, len2; + NTSTATUS status; + SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti; + int i; + + sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16); + ok(!!sfti, "Failed to allocate memory\n"); + + status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1); +todo_wine + ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */, + "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); + if (len1 == 0) /* xp, 2003 */ + { + skip("SystemFirmwareTableInformation is not available\n"); + HeapFree(GetProcessHeap(), 0, sfti); + return; + } + ok(len1 == 16, "Expected length 16, got %u\n", len1); + + status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1); + ok(status == STATUS_NOT_IMPLEMENTED, "Expected STATUS_NOT_IMPLEMENTED, got %08x\n", status); + ok(len1 == 0, "Expected length 0, got %u\n", len1); + + sfti->ProviderSignature = RSMB; + sfti->Action = SystemFirmwareTable_Get; + sfti->TableID = 0; + + status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1); + ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status); + ok(len1 >= 16, "Expected length >= 16, got %u\n", len1); + ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength); + + sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, len1); + ok(!!sfti, "Failed to allocate memory\n"); + + for (i = 0; i < 100; i++) + { + sfti->TableID = i; + status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2); + ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status); + ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2); + ok(sfti->TableBufferLength == len1 - 16, + "Table %u: Expected length %u, got %u\n", i, len1 - 16, sfti->TableBufferLength); + } + + HeapFree(GetProcessHeap(), 0, sfti); +} + static void test_query_processor_power_info(void) { NTSTATUS status; @@ -2271,6 +2327,10 @@ START_TEST(info) trace("Starting test_process_debug_flags()\n"); test_query_process_debug_flags(argc, argv);
+ /* 0x4C SystemFirmwareTableInformation */ + trace("Starting test_query_firmware()\n"); + test_query_firmware(); + /* belongs to its own file */ trace("Starting test_readvirtualmemory()\n"); test_readvirtualmemory();
I think we're making progress. Hopefully this will be the final iteration...
On Wed, Jun 20, 2018 at 11:18:46PM -0600, Alex Henrie wrote:
Signed-off-by: Alex Henrie alexhenrie24@gmail.com
dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index b18f0d39d9..9e12a013cf 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -54,6 +54,11 @@ static DWORD one_before_last_pid = 0; } \ } while(0)
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42
static BOOL InitFunctionPtrs(void) { /* All needed functions are NT based, so using GetModuleHandle is a good check */ @@ -826,6 +831,57 @@ static void test_query_logicalprocex(void) } }
+static void test_query_firmware(void) +{
- ULONG len1, len2;
- NTSTATUS status;
- SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
- int i;
- sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
I'd rather not use HEAP_ZERO_MEMORY and explicitly initialise each element - you already do that later on anyway.
- ok(!!sfti, "Failed to allocate memory\n");
- status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
+todo_wine
- ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */,
"Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
- if (len1 == 0) /* xp, 2003 */
- {
skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
- }
- ok(len1 == 16, "Expected length 16, got %u\n", len1);
- status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
- ok(status == STATUS_NOT_IMPLEMENTED, "Expected STATUS_NOT_IMPLEMENTED, got %08x\n", status);
- ok(len1 == 0, "Expected length 0, got %u\n", len1);
- sfti->ProviderSignature = RSMB;
- sfti->Action = SystemFirmwareTable_Get;
- sfti->TableID = 0;
- status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
- ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
- ok(len1 >= 16, "Expected length >= 16, got %u\n", len1);
- ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength);
- sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, len1);
- ok(!!sfti, "Failed to allocate memory\n");
- for (i = 0; i < 100; i++)
- {
I don't think this loop is very useful. Let's just get the 0th table.
sfti->TableID = i;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2);
ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status);
ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2);
ok(sfti->TableBufferLength == len1 - 16,
"Table %u: Expected length %u, got %u\n", i, len1 - 16, sfti->TableBufferLength);
- }
- HeapFree(GetProcessHeap(), 0, sfti);
+}
static void test_query_processor_power_info(void) { NTSTATUS status; @@ -2271,6 +2327,10 @@ START_TEST(info) trace("Starting test_process_debug_flags()\n"); test_query_process_debug_flags(argc, argv);
- /* 0x4C SystemFirmwareTableInformation */
- trace("Starting test_query_firmware()\n");
- test_query_firmware();
- /* belongs to its own file */ trace("Starting test_readvirtualmemory()\n"); test_readvirtualmemory();
-- 2.17.1
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/kernel32/tests/version.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c index eb78a383d2..08e8f0fb58 100644 --- a/dlls/kernel32/tests/version.c +++ b/dlls/kernel32/tests/version.c @@ -26,11 +26,17 @@ #include "winternl.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *); +static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *); static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
#define GET_PROC(func) \ p##func = (void *)GetProcAddress(hmod, #func);
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42 + static void init_function_pointers(void) { HMODULE hmod; @@ -41,6 +47,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("ntdll.dll");
+ GET_PROC(NtQuerySystemInformation); GET_PROC(RtlGetVersion); }
@@ -697,6 +704,39 @@ static void test_VerifyVersionInfo(void) ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); }
+void test_GetSystemFirmwareTable(void) +{ + ULONG expected_len, i; + UINT len; + SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16); + UCHAR *smbios_table = NULL; + + ok(!!sfti, "Failed to allocate memory\n"); + sfti->ProviderSignature = RSMB; + sfti->Action = SystemFirmwareTable_Get; + pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len); + if (expected_len == 0) /* xp, 2003 */ + { + skip("SystemFirmwareTableInformation is not available\n"); + HeapFree(GetProcessHeap(), 0, sfti); + return; + } + sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len); + ok(!!sfti, "Failed to allocate memory\n"); + pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len); + + expected_len -= 16; + smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len); + for (i = 0; i < 100; i++) + { + len = GetSystemFirmwareTable(RSMB, i, smbios_table, expected_len); + ok(len == expected_len, "Table %u: Expected length %u, got %u\n", i, expected_len, len); + } + + HeapFree(GetProcessHeap(), 0, sfti); + HeapFree(GetProcessHeap(), 0, smbios_table); +} + START_TEST(version) { init_function_pointers(); @@ -704,4 +744,5 @@ START_TEST(version) test_GetProductInfo(); test_GetVersionEx(); test_VerifyVersionInfo(); + test_GetSystemFirmwareTable(); }
On Wed, Jun 20, 2018 at 11:18:47PM -0600, Alex Henrie wrote:
Signed-off-by: Alex Henrie alexhenrie24@gmail.com
dlls/kernel32/tests/version.c | 41 +++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c index eb78a383d2..08e8f0fb58 100644 --- a/dlls/kernel32/tests/version.c +++ b/dlls/kernel32/tests/version.c @@ -26,11 +26,17 @@ #include "winternl.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *); +static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *); static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
#define GET_PROC(func) \ p##func = (void *)GetProcAddress(hmod, #func);
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42
static void init_function_pointers(void) { HMODULE hmod; @@ -41,6 +47,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("ntdll.dll");
- GET_PROC(NtQuerySystemInformation); GET_PROC(RtlGetVersion);
}
@@ -697,6 +704,39 @@ static void test_VerifyVersionInfo(void) ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError()); }
+void test_GetSystemFirmwareTable(void) +{
- ULONG expected_len, i;
- UINT len;
- SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
Same as the last patch, let's explicitly initialise the elements.
- UCHAR *smbios_table = NULL;
- ok(!!sfti, "Failed to allocate memory\n");
- sfti->ProviderSignature = RSMB;
- sfti->Action = SystemFirmwareTable_Get;
- pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len);
- if (expected_len == 0) /* xp, 2003 */
- {
skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
- }
- sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
- ok(!!sfti, "Failed to allocate memory\n");
- pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
- expected_len -= 16;
- smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len);
- for (i = 0; i < 100; i++)
Again, ditch the loop.
- {
len = GetSystemFirmwareTable(RSMB, i, smbios_table, expected_len);
ok(len == expected_len, "Table %u: Expected length %u, got %u\n", i, expected_len, len);
I'd hoped for a memcmp between smbios_table and sfti->TableBuffer here.
- }
- HeapFree(GetProcessHeap(), 0, sfti);
- HeapFree(GetProcessHeap(), 0, smbios_table);
+}
START_TEST(version) { init_function_pointers(); @@ -704,4 +744,5 @@ START_TEST(version) test_GetProductInfo(); test_GetVersionEx(); test_VerifyVersionInfo();
- test_GetSystemFirmwareTable();
}
2.17.1
On Wed, Jul 11, 2018 at 10:23 AM Huw Davies huw@codeweavers.com wrote:
On Wed, Jun 20, 2018 at 11:18:47PM -0600, Alex Henrie wrote:
- {
len = GetSystemFirmwareTable(RSMB, i, smbios_table, expected_len);
ok(len == expected_len, "Table %u: Expected length %u, got %u\n", i, expected_len, len);
I'd hoped for a memcmp between smbios_table and sfti->TableBuffer here.
I didn't want to memcmp the entire buffer because some SMBIOS values change over time. However, we can reliably memcmp the SMBIOS prologue that Windows adds, which is the first 6 bytes. My next revision will have this change.
Thanks for the feedback!
-Alex
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/nt.c | 171 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/tests/info.c | 11 ++- 2 files changed, 180 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index dc0ce04f42..c46c3cd01d 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -66,6 +66,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#include "pshpack1.h" + +struct smbios_prologue { + BYTE calling_method; + BYTE major_version; + BYTE minor_version; + BYTE revision; + DWORD length; +}; + +struct smbios_bios { + BYTE type; + BYTE length; + WORD handle; + BYTE vendor; + BYTE version; + WORD start; + BYTE date; + BYTE size; + UINT64 characteristics; +}; + +#include "poppack.h" + +/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42 + /* * Token */ @@ -1850,6 +1879,126 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** } #endif
+static inline void copy_smbios_string(char **buffer, char *s, size_t len) +{ + if (!len) return; + strcpy(*buffer, s); + *buffer += len + 1; +} + +#ifdef linux + +static size_t get_smbios_string(const char *path, char *str, size_t size) +{ + FILE *file; + size_t len; + + if (!(file = fopen(path, "r"))) + return 0; + + len = fread(str, 1, size - 1, file); + fclose(file); + + if (len >= 1 && str[len - 1] == '\n') + { + str[len - 1] = 0; + len--; + } + else + { + str[len] = 0; + } + + return len; +} + +static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, + ULONG available_len, ULONG *required_len) +{ + switch (sfti->ProviderSignature) + { + case RSMB: + { + char bios_vendor[128], bios_version[128], bios_date[128]; + size_t bios_vendor_len, bios_version_len, bios_date_len; + char *buffer = (char*)sfti->TableBuffer; + BYTE string_count; + struct smbios_prologue *prologue; + struct smbios_bios *bios; + +#define S(s) s, sizeof(s) + bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor)); + bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version)); + bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date)); +#undef S + + *required_len = sizeof(struct smbios_prologue); + + *required_len += sizeof(struct smbios_bios); + *required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2); + + sfti->TableBufferLength = *required_len; + + *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); + + if (available_len < *required_len) + return STATUS_BUFFER_TOO_SMALL; + + prologue = (struct smbios_prologue*)buffer; + prologue->calling_method = 0; + prologue->major_version = 2; + prologue->minor_version = 0; + prologue->revision = 0; + prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue); + buffer += sizeof(struct smbios_prologue); + + string_count = 0; + bios = (struct smbios_bios*)buffer; + bios->type = 0; + bios->length = sizeof(struct smbios_bios); + bios->handle = 0; + bios->vendor = bios_vendor_len ? ++string_count : 0; + bios->version = bios_version_len ? ++string_count : 0; + bios->start = 0; + bios->date = bios_date_len ? ++string_count : 0; + bios->size = 0; + bios->characteristics = 0x4; /* not supported */ + buffer += sizeof(struct smbios_bios); + + if (string_count) + { + copy_smbios_string(&buffer, bios_vendor, bios_vendor_len); + copy_smbios_string(&buffer, bios_version, bios_version_len); + copy_smbios_string(&buffer, bios_date, bios_date_len); + memset(buffer, 0, 1); + } + else + { + memset(buffer, 0, 2); + } + + return STATUS_SUCCESS; + } + default: + { + FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n"); + return STATUS_NOT_IMPLEMENTED; + } + } +} + +#else + +static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti, + ULONG available_len, ULONG *required_len) +{ + FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n"); + sfti->TableBufferLength = 0; + return STATUS_NOT_IMPLEMENTED; +} + +#endif + /****************************************************************************** * NtQuerySystemInformation [NTDLL.@] * ZwQuerySystemInformation [NTDLL.@] @@ -2359,6 +2508,28 @@ NTSTATUS WINAPI NtQuerySystemInformation( else ret = STATUS_INFO_LENGTH_MISMATCH; } break; + case SystemFirmwareTableInformation: + { + SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = (SYSTEM_FIRMWARE_TABLE_INFORMATION*)SystemInformation; + len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); + if (Length < len) + { + ret = STATUS_INFO_LENGTH_MISMATCH; + break; + } + + switch (sfti->Action) + { + case SystemFirmwareTable_Get: + ret = get_firmware_info(sfti, Length, &len); + break; + default: + len = 0; + ret = STATUS_NOT_IMPLEMENTED; + FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n"); + } + } + break; default: FIXME("(0x%08x,%p,0x%08x,%p) stub\n", SystemInformationClass,SystemInformation,Length,ResultLength); diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 9e12a013cf..29af0e3d90 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -59,6 +59,12 @@ static DWORD one_before_last_pid = 0; #define FIRM 0x4649524D #define RSMB 0x52534D42
+#ifdef linux +static const int firmware_todo = 0; +#else +static const int firmware_todo = 1; +#endif + static BOOL InitFunctionPtrs(void) { /* All needed functions are NT based, so using GetModuleHandle is a good check */ @@ -842,12 +848,11 @@ static void test_query_firmware(void) ok(!!sfti, "Failed to allocate memory\n");
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1); -todo_wine ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); if (len1 == 0) /* xp, 2003 */ { - skip("SystemFirmwareTableInformation is not available\n"); + win_skip("SystemFirmwareTableInformation is not available\n"); HeapFree(GetProcessHeap(), 0, sfti); return; } @@ -862,6 +867,7 @@ todo_wine sfti->TableID = 0;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1); +todo_wine_if(firmware_todo) ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status); ok(len1 >= 16, "Expected length >= 16, got %u\n", len1); ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength); @@ -873,6 +879,7 @@ todo_wine { sfti->TableID = i; status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2); +todo_wine_if(firmware_todo) ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status); ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2); ok(sfti->TableBufferLength == len1 - 16,
Hi,
While running your changed tests on Windows, 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=39269
Your paranoid android.
=== wxppro (32 bit info) === The task timed out
On Wed, Jun 20, 2018 at 11:59 PM Marvin testbot@winehq.org wrote:
Hi,
While running your changed tests on Windows, 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=39269
Your paranoid android.
=== wxppro (32 bit info) === The task timed out
This is an intermittent failure which could not have been caused by this patch's minor changes to the tests: https://testbot.winehq.org/JobDetails.pl?Key=39279
-Alex
On Wed, Jun 20, 2018 at 11:18:48PM -0600, Alex Henrie wrote:
Signed-off-by: Alex Henrie alexhenrie24@gmail.com
dlls/ntdll/nt.c | 171 ++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/tests/info.c | 11 ++- 2 files changed, 180 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index dc0ce04f42..c46c3cd01d 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -66,6 +66,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#include "pshpack1.h"
+struct smbios_prologue {
- BYTE calling_method;
- BYTE major_version;
- BYTE minor_version;
- BYTE revision;
- DWORD length;
+};
+struct smbios_bios {
- BYTE type;
- BYTE length;
- WORD handle;
- BYTE vendor;
- BYTE version;
- WORD start;
- BYTE date;
- BYTE size;
- UINT64 characteristics;
+};
+#include "poppack.h"
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42
/*
- Token
*/ @@ -1850,6 +1879,126 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** } #endif
+static inline void copy_smbios_string(char **buffer, char *s, size_t len)
This needs to go inside the #ifdef linux
+{
- if (!len) return;
- strcpy(*buffer, s);
Since we're passing the length, this would be better as a memcpy( , , len + 1).
- *buffer += len + 1;
+}
+#ifdef linux
+static size_t get_smbios_string(const char *path, char *str, size_t size) +{
- FILE *file;
- size_t len;
- if (!(file = fopen(path, "r")))
return 0;
- len = fread(str, 1, size - 1, file);
- fclose(file);
- if (len >= 1 && str[len - 1] == '\n')
- {
str[len - 1] = 0;
len--;
- }
- else
- {
str[len] = 0;
- }
This would be cleaner as:
if (len >= 1 && str[len - 1] == '\n') len--;
str[len] = 0;
(basically avoid the code duplication of str[len] = 0).
- return len;
+}
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
ULONG available_len, ULONG *required_len)
Don't use inline on this big function. These days compilers are pretty good at this sort of thing anyway.
+{
- switch (sfti->ProviderSignature)
- {
- case RSMB:
{
char bios_vendor[128], bios_version[128], bios_date[128];
size_t bios_vendor_len, bios_version_len, bios_date_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
+#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version));
bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
+#undef S
*required_len = sizeof(struct smbios_prologue);
*required_len += sizeof(struct smbios_bios);
*required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
if (available_len < *required_len)
return STATUS_BUFFER_TOO_SMALL;
prologue = (struct smbios_prologue*)buffer;
prologue->calling_method = 0;
prologue->major_version = 2;
prologue->minor_version = 0;
prologue->revision = 0;
prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue);
buffer += sizeof(struct smbios_prologue);
string_count = 0;
bios = (struct smbios_bios*)buffer;
bios->type = 0;
bios->length = sizeof(struct smbios_bios);
bios->handle = 0;
bios->vendor = bios_vendor_len ? ++string_count : 0;
bios->version = bios_version_len ? ++string_count : 0;
bios->start = 0;
bios->date = bios_date_len ? ++string_count : 0;
bios->size = 0;
bios->characteristics = 0x4; /* not supported */
buffer += sizeof(struct smbios_bios);
if (string_count)
{
copy_smbios_string(&buffer, bios_vendor, bios_vendor_len);
copy_smbios_string(&buffer, bios_version, bios_version_len);
copy_smbios_string(&buffer, bios_date, bios_date_len);
memset(buffer, 0, 1);
}
else
{
memset(buffer, 0, 2);
}
I dislike this if block, partly because of the use of memsets and partly because of the code duplication in setting the final '\0'. This looks cleaner to me:
copy_smbios_string(&buffer, bios_vendor, bios_vendor_len); copy_smbios_string(&buffer, bios_version, bios_version_len); copy_smbios_string(&buffer, bios_date, bios_date_len);
if (!string_count) *buffer++ = 0; *buffer++ = 0;
(Yes, it calls copy_smbios_string() in the string_count == 0 case, but I can live with that for the sake of simpler code).
Obviously this applies to the other patches too.
return STATUS_SUCCESS;
}
- default:
{
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
Printing the provider signature in the fixme would be a good idea.
return STATUS_NOT_IMPLEMENTED;
}
- }
+}
+#else
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
ULONG available_len, ULONG *required_len)
Again, drop the inline.
+{
- FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
- sfti->TableBufferLength = 0;
- return STATUS_NOT_IMPLEMENTED;
+}
+#endif
/******************************************************************************
- NtQuerySystemInformation [NTDLL.@]
- ZwQuerySystemInformation [NTDLL.@]
@@ -2359,6 +2508,28 @@ NTSTATUS WINAPI NtQuerySystemInformation( else ret = STATUS_INFO_LENGTH_MISMATCH; } break;
- case SystemFirmwareTableInformation:
{
SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = (SYSTEM_FIRMWARE_TABLE_INFORMATION*)SystemInformation;
len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
if (Length < len)
{
ret = STATUS_INFO_LENGTH_MISMATCH;
break;
}
switch (sfti->Action)
{
case SystemFirmwareTable_Get:
ret = get_firmware_info(sfti, Length, &len);
break;
default:
len = 0;
ret = STATUS_NOT_IMPLEMENTED;
FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
Let's print the action here.
}
}
default: FIXME("(0x%08x,%p,0x%08x,%p) stub\n", SystemInformationClass,SystemInformation,Length,ResultLength);break;
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 9e12a013cf..29af0e3d90 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -59,6 +59,12 @@ static DWORD one_before_last_pid = 0; #define FIRM 0x4649524D #define RSMB 0x52534D42
+#ifdef linux +static const int firmware_todo = 0; +#else +static const int firmware_todo = 1; +#endif
static BOOL InitFunctionPtrs(void) { /* All needed functions are NT based, so using GetModuleHandle is a good check */ @@ -842,12 +848,11 @@ static void test_query_firmware(void) ok(!!sfti, "Failed to allocate memory\n");
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
-todo_wine ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status); if (len1 == 0) /* xp, 2003 */ {
skip("SystemFirmwareTableInformation is not available\n");
}win_skip("SystemFirmwareTableInformation is not available\n"); HeapFree(GetProcessHeap(), 0, sfti); return;
@@ -862,6 +867,7 @@ todo_wine sfti->TableID = 0;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+todo_wine_if(firmware_todo) ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status); ok(len1 >= 16, "Expected length >= 16, got %u\n", len1); ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength); @@ -873,6 +879,7 @@ todo_wine { sfti->TableID = i; status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2); +todo_wine_if(firmware_todo) ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status); ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2); ok(sfti->TableBufferLength == len1 - 16, -- 2.17.1
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/kernel32/cpu.c | 29 +++++++++++++++++++++++++++++ dlls/kernel32/process.c | 10 ---------- dlls/kernel32/tests/version.c | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c index ec1fd0f90d..8397fbe729 100644 --- a/dlls/kernel32/cpu.c +++ b/dlls/kernel32/cpu.c @@ -336,3 +336,32 @@ DWORD64 WINAPI GetEnabledXStateFeatures(void) FIXME("\n"); return 0; } + +/*********************************************************************** + * GetSystemFirmwareTable (KERNEL32.@) + */ +UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, void *buffer, DWORD size) +{ + ULONG buffer_size = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer) + size; + SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), 0, buffer_size); + NTSTATUS status; + + if (!sfti) + { + SetLastError(ERROR_OUTOFMEMORY); + return 0; + } + + sfti->ProviderSignature = provider; + sfti->Action = SystemFirmwareTable_Get; + sfti->TableID = id; + + status = NtQuerySystemInformation(SystemFirmwareTableInformation, sfti, buffer_size, &buffer_size); + buffer_size -= FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); + if (buffer_size <= size) + memcpy(buffer, sfti->TableBuffer, buffer_size); + + if (status) SetLastError(RtlNtStatusToDosError(status)); + HeapFree(GetProcessHeap(), 0, sfti); + return buffer_size; +} diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index ff56e9a692..6adf08d257 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -4126,16 +4126,6 @@ HRESULT WINAPI UnregisterApplicationRestart(void) return S_OK; }
-/*********************************************************************** - * GetSystemFirmwareTable (KERNEL32.@) - */ -UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, PVOID buffer, DWORD size) -{ - FIXME("(%d %d %p %d):stub\n", provider, id, buffer, size); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - struct proc_thread_attr { DWORD_PTR attr; diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c index 08e8f0fb58..e33ce9cd42 100644 --- a/dlls/kernel32/tests/version.c +++ b/dlls/kernel32/tests/version.c @@ -717,7 +717,7 @@ void test_GetSystemFirmwareTable(void) pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len); if (expected_len == 0) /* xp, 2003 */ { - skip("SystemFirmwareTableInformation is not available\n"); + win_skip("SystemFirmwareTableInformation is not available\n"); HeapFree(GetProcessHeap(), 0, sfti); return; }
On Wed, Jun 20, 2018 at 11:18:49PM -0600, Alex Henrie wrote:
Signed-off-by: Alex Henrie alexhenrie24@gmail.com
dlls/kernel32/cpu.c | 29 +++++++++++++++++++++++++++++ dlls/kernel32/process.c | 10 ---------- dlls/kernel32/tests/version.c | 2 +- 3 files changed, 30 insertions(+), 11 deletions(-)
Looks good.
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c index ec1fd0f90d..8397fbe729 100644 --- a/dlls/kernel32/cpu.c +++ b/dlls/kernel32/cpu.c @@ -336,3 +336,32 @@ DWORD64 WINAPI GetEnabledXStateFeatures(void) FIXME("\n"); return 0; }
+/***********************************************************************
GetSystemFirmwareTable (KERNEL32.@)
- */
+UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, void *buffer, DWORD size) +{
- ULONG buffer_size = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer) + size;
- SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), 0, buffer_size);
- NTSTATUS status;
- if (!sfti)
- {
SetLastError(ERROR_OUTOFMEMORY);
return 0;
- }
- sfti->ProviderSignature = provider;
- sfti->Action = SystemFirmwareTable_Get;
- sfti->TableID = id;
- status = NtQuerySystemInformation(SystemFirmwareTableInformation, sfti, buffer_size, &buffer_size);
- buffer_size -= FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
- if (buffer_size <= size)
memcpy(buffer, sfti->TableBuffer, buffer_size);
- if (status) SetLastError(RtlNtStatusToDosError(status));
- HeapFree(GetProcessHeap(), 0, sfti);
- return buffer_size;
+} diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index ff56e9a692..6adf08d257 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -4126,16 +4126,6 @@ HRESULT WINAPI UnregisterApplicationRestart(void) return S_OK; }
-/***********************************************************************
GetSystemFirmwareTable (KERNEL32.@)
- */
-UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, PVOID buffer, DWORD size) -{
- FIXME("(%d %d %p %d):stub\n", provider, id, buffer, size);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
struct proc_thread_attr { DWORD_PTR attr; diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c index 08e8f0fb58..e33ce9cd42 100644 --- a/dlls/kernel32/tests/version.c +++ b/dlls/kernel32/tests/version.c @@ -717,7 +717,7 @@ void test_GetSystemFirmwareTable(void) pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len); if (expected_len == 0) /* xp, 2003 */ {
skip("SystemFirmwareTableInformation is not available\n");
}win_skip("SystemFirmwareTableInformation is not available\n"); HeapFree(GetProcessHeap(), 0, sfti); return;
-- 2.17.1
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/nt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index c46c3cd01d..5137b8e5dc 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -88,6 +88,16 @@ struct smbios_bios { UINT64 characteristics; };
+struct smbios_system { + BYTE type; + BYTE length; + WORD handle; + BYTE vendor; + BYTE product; + BYTE version; + BYTE serial; +}; + #include "poppack.h"
/* Firmware table providers */ @@ -1921,15 +1931,22 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti { char bios_vendor[128], bios_version[128], bios_date[128]; size_t bios_vendor_len, bios_version_len, bios_date_len; + char system_vendor[128], system_product[128], system_version[128], system_serial[128]; + size_t system_vendor_len, system_product_len, system_version_len, system_serial_len; char *buffer = (char*)sfti->TableBuffer; BYTE string_count; struct smbios_prologue *prologue; struct smbios_bios *bios; + struct smbios_system *system;
#define S(s) s, sizeof(s) bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor)); bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version)); bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date)); + system_vendor_len = get_smbios_string("/sys/class/dmi/id/sys_vendor", S(system_vendor)); + system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product)); + system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version)); + system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial)); #undef S
*required_len = sizeof(struct smbios_prologue); @@ -1937,6 +1954,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti *required_len += sizeof(struct smbios_bios); *required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
+ *required_len += sizeof(struct smbios_system); + *required_len += max(system_vendor_len + system_product_len + system_version_len + + system_serial_len + 5, 2); + sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); @@ -1971,6 +1992,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti copy_smbios_string(&buffer, bios_version, bios_version_len); copy_smbios_string(&buffer, bios_date, bios_date_len); memset(buffer, 0, 1); + buffer++; + } + else + { + memset(buffer, 0, 2); + buffer += 2; + } + + string_count = 0; + system = (struct smbios_system*)buffer; + system->type = 1; + system->length = sizeof(struct smbios_system); + system->handle = 0; + system->vendor = system_vendor_len ? ++string_count : 0; + system->product = system_product_len ? ++string_count : 0; + system->version = system_version_len ? ++string_count : 0; + system->serial = system_serial_len ? ++string_count : 0; + buffer += sizeof(struct smbios_system); + + if (string_count) + { + copy_smbios_string(&buffer, system_vendor, system_vendor_len); + copy_smbios_string(&buffer, system_product, system_product_len); + copy_smbios_string(&buffer, system_version, system_version_len); + copy_smbios_string(&buffer, system_serial, system_serial_len); + memset(buffer, 0, 1); } else {
On Wed, Jun 20, 2018 at 11:18:50PM -0600, Alex Henrie wrote:
Signed-off-by: Alex Henrie alexhenrie24@gmail.com
dlls/ntdll/nt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
These final three patches should be good if you make the copy_smbios_string block changes I suggested.
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index c46c3cd01d..5137b8e5dc 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -88,6 +88,16 @@ struct smbios_bios { UINT64 characteristics; };
+struct smbios_system {
- BYTE type;
- BYTE length;
- WORD handle;
- BYTE vendor;
- BYTE product;
- BYTE version;
- BYTE serial;
+};
#include "poppack.h"
/* Firmware table providers */ @@ -1921,15 +1931,22 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti { char bios_vendor[128], bios_version[128], bios_date[128]; size_t bios_vendor_len, bios_version_len, bios_date_len;
char system_vendor[128], system_product[128], system_version[128], system_serial[128];
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len; char *buffer = (char*)sfti->TableBuffer; BYTE string_count; struct smbios_prologue *prologue; struct smbios_bios *bios;
struct smbios_system *system;
#define S(s) s, sizeof(s) bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor)); bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version)); bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
system_vendor_len = get_smbios_string("/sys/class/dmi/id/sys_vendor", S(system_vendor));
system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product));
system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version));
system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1937,6 +1954,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti *required_len += sizeof(struct smbios_bios); *required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
*required_len += sizeof(struct smbios_system);
*required_len += max(system_vendor_len + system_product_len + system_version_len +
system_serial_len + 5, 2);
sfti->TableBufferLength = *required_len; *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -1971,6 +1992,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti copy_smbios_string(&buffer, bios_version, bios_version_len); copy_smbios_string(&buffer, bios_date, bios_date_len); memset(buffer, 0, 1);
buffer++;
}
else
{
memset(buffer, 0, 2);
buffer += 2;
}
string_count = 0;
system = (struct smbios_system*)buffer;
system->type = 1;
system->length = sizeof(struct smbios_system);
system->handle = 0;
system->vendor = system_vendor_len ? ++string_count : 0;
system->product = system_product_len ? ++string_count : 0;
system->version = system_version_len ? ++string_count : 0;
system->serial = system_serial_len ? ++string_count : 0;
buffer += sizeof(struct smbios_system);
if (string_count)
{
copy_smbios_string(&buffer, system_vendor, system_vendor_len);
copy_smbios_string(&buffer, system_product, system_product_len);
copy_smbios_string(&buffer, system_version, system_version_len);
copy_smbios_string(&buffer, system_serial, system_serial_len);
memset(buffer, 0, 1); } else {
-- 2.17.1
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/nt.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 5137b8e5dc..e622912d8a 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -98,6 +98,16 @@ struct smbios_system { BYTE serial; };
+struct smbios_board { + BYTE type; + BYTE length; + WORD handle; + BYTE vendor; + BYTE product; + BYTE version; + BYTE serial; +}; + #include "poppack.h"
/* Firmware table providers */ @@ -1933,11 +1943,14 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti size_t bios_vendor_len, bios_version_len, bios_date_len; char system_vendor[128], system_product[128], system_version[128], system_serial[128]; size_t system_vendor_len, system_product_len, system_version_len, system_serial_len; + char board_vendor[128], board_product[128], board_version[128], board_serial[128]; + size_t board_vendor_len, board_product_len, board_version_len, board_serial_len; char *buffer = (char*)sfti->TableBuffer; BYTE string_count; struct smbios_prologue *prologue; struct smbios_bios *bios; struct smbios_system *system; + struct smbios_board *board;
#define S(s) s, sizeof(s) bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor)); @@ -1947,6 +1960,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product)); system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version)); system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial)); + board_vendor_len = get_smbios_string("/sys/class/dmi/id/board_vendor", S(board_vendor)); + board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product)); + board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version)); + board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial)); #undef S
*required_len = sizeof(struct smbios_prologue); @@ -1958,6 +1975,9 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti *required_len += max(system_vendor_len + system_product_len + system_version_len + system_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_board); + *required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2); + sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); @@ -2018,6 +2038,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti copy_smbios_string(&buffer, system_version, system_version_len); copy_smbios_string(&buffer, system_serial, system_serial_len); memset(buffer, 0, 1); + buffer++; + } + else + { + memset(buffer, 0, 2); + buffer += 2; + } + + string_count = 0; + board = (struct smbios_board*)buffer; + board->type = 2; + board->length = sizeof(struct smbios_board); + board->handle = 0; + board->vendor = board_vendor_len ? ++string_count : 0; + board->product = board_product_len ? ++string_count : 0; + board->version = board_version_len ? ++string_count : 0; + board->serial = board_serial_len ? ++string_count : 0; + buffer += sizeof(struct smbios_board); + + if (string_count) + { + copy_smbios_string(&buffer, board_vendor, board_vendor_len); + copy_smbios_string(&buffer, board_product, board_product_len); + copy_smbios_string(&buffer, board_version, board_version_len); + copy_smbios_string(&buffer, board_serial, board_serial_len); + memset(buffer, 0, 1); } else {
Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/ntdll/nt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index e622912d8a..d9fc2e6108 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -108,6 +108,17 @@ struct smbios_board { BYTE serial; };
+struct smbios_chassis { + BYTE type; + BYTE length; + WORD handle; + BYTE vendor; + BYTE shape; + BYTE version; + BYTE serial; + BYTE asset_tag; +}; + #include "poppack.h"
/* Firmware table providers */ @@ -1945,12 +1956,15 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti size_t system_vendor_len, system_product_len, system_version_len, system_serial_len; char board_vendor[128], board_product[128], board_version[128], board_serial[128]; size_t board_vendor_len, board_product_len, board_version_len, board_serial_len; + char chassis_vendor[128], chassis_version[128], chassis_serial[128], chassis_asset_tag[128]; + size_t chassis_vendor_len, chassis_version_len, chassis_serial_len, chassis_asset_tag_len; char *buffer = (char*)sfti->TableBuffer; BYTE string_count; struct smbios_prologue *prologue; struct smbios_bios *bios; struct smbios_system *system; struct smbios_board *board; + struct smbios_chassis *chassis;
#define S(s) s, sizeof(s) bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor)); @@ -1964,6 +1978,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product)); board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version)); board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial)); + chassis_vendor_len = get_smbios_string("/sys/class/dmi/id/chassis_vendor", S(chassis_vendor)); + chassis_version_len = get_smbios_string("/sys/class/dmi/id/chassis_version", S(chassis_version)); + chassis_serial_len = get_smbios_string("/sys/class/dmi/id/chassis_serial", S(chassis_serial)); + chassis_asset_tag_len = get_smbios_string("/sys/class/dmi/id/chassis_tag", S(chassis_asset_tag)); #undef S
*required_len = sizeof(struct smbios_prologue); @@ -1978,6 +1996,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti *required_len += sizeof(struct smbios_board); *required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_chassis); + *required_len += max(chassis_vendor_len + chassis_version_len + chassis_serial_len + + chassis_asset_tag_len + 5, 2); + sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer); @@ -2064,6 +2086,33 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti copy_smbios_string(&buffer, board_version, board_version_len); copy_smbios_string(&buffer, board_serial, board_serial_len); memset(buffer, 0, 1); + buffer++; + } + else + { + memset(buffer, 0, 2); + buffer += 2; + } + + string_count = 0; + chassis = (struct smbios_chassis*)buffer; + chassis->type = 3; + chassis->length = sizeof(struct smbios_chassis); + chassis->handle = 0; + chassis->vendor = chassis_vendor_len ? ++string_count : 0; + chassis->shape = 0x2; /* unknown */ + chassis->version = chassis_version_len ? ++string_count : 0; + chassis->serial = chassis_serial_len ? ++string_count : 0; + chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0; + buffer += sizeof(struct smbios_chassis); + + if (string_count) + { + copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len); + copy_smbios_string(&buffer, chassis_version, chassis_version_len); + copy_smbios_string(&buffer, chassis_serial, chassis_serial_len); + copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len); + memset(buffer, 0, 1); } else {