Signed-off-by: Alex Henrie alexhenrie24@gmail.com --- dlls/kernel32/cpu.c | 135 ++++++++++++++++++++++++++++++++++++++++ dlls/kernel32/process.c | 10 --- 2 files changed, 135 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c index ec1fd0f90d..4dd9bb628a 100644 --- a/dlls/kernel32/cpu.c +++ b/dlls/kernel32/cpu.c @@ -46,8 +46,37 @@
WINE_DEFAULT_DEBUG_CHANNEL(reg);
+#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 manufacturer; + BYTE version; + WORD start; + BYTE date; + BYTE size; + UINT64 characteristics; +}; + +#include "poppack.h" + #define SHARED_DATA ((KSHARED_USER_DATA*)0x7ffe0000)
+/* Firmware table providers */ +#define ACPI 0x41435049 +#define FIRM 0x4649524D +#define RSMB 0x52534D42 + /**************************************************************************** * QueryPerformanceCounter (KERNEL32.@) * @@ -336,3 +365,109 @@ DWORD64 WINAPI GetEnabledXStateFeatures(void) FIXME("\n"); return 0; } + +static inline void copy_smbios_string(void **buffer, char *string, size_t string_size) +{ + if (!string) return; + strcpy(*buffer, string); + *buffer = (char*)(*buffer) + string_size; +} + +#ifdef linux +static char* get_smbios_string(const char *path, size_t *string_size) +{ + FILE *file = fopen(path, "r"); + char *ret = NULL; + *string_size = 0; + if (file) + { + *string_size = getline(&ret, string_size, file) + 1; + fclose(file); + if (*string_size >= 2 && ret[*string_size - 2] == '\n') + { + ret[*string_size - 2] = 0; + (*string_size)--; + } + if (*string_size == 1) + { + free(ret); + ret = NULL; + *string_size = 0; + } + } + return ret; +} +#endif + +/*********************************************************************** + * GetSystemFirmwareTable (KERNEL32.@) + */ +UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, void *buffer, DWORD size) +{ + FIXME("(%08x %08x %p %d): semi-stub\n", provider, id, buffer, size); + switch (provider) + { + case RSMB: + { +#ifdef linux + char *bios_manufacturer, *bios_version, *bios_date; + size_t bios_manufacturer_size, bios_version_size, bios_date_size; + size_t required_size = sizeof(struct smbios_prologue); + BYTE string_count; + struct smbios_prologue *prologue; + struct smbios_bios *bios; + + bios_manufacturer = get_smbios_string("/sys/class/dmi/id/bios_vendor", &bios_manufacturer_size); + bios_version = get_smbios_string("/sys/class/dmi/id/bios_version", &bios_version_size); + bios_date = get_smbios_string("/sys/class/dmi/id/bios_date", &bios_date_size); + + required_size += sizeof(struct smbios_bios); + required_size += max(bios_manufacturer_size + bios_version_size + bios_date_size + 1, 2); + + if (required_size > size) + return required_size; + + prologue = (struct smbios_prologue*)buffer; + prologue->calling_method = 0; + prologue->major_version = 2; + prologue->minor_version = 0; + prologue->revision = 0; + prologue->length = required_size - sizeof(struct smbios_prologue); + buffer = (char*)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->manufacturer = bios_manufacturer ? ++string_count : 0; + bios->version = bios_version ? ++string_count : 0; + bios->start = 0; + bios->date = bios_date ? ++string_count : 0; + bios->size = 0; + bios->characteristics = 0x4; /* not supported */ + buffer = (char*)buffer + sizeof(struct smbios_bios); + + if (string_count) + { + copy_smbios_string(&buffer, bios_manufacturer, bios_manufacturer_size); + copy_smbios_string(&buffer, bios_version, bios_version_size); + copy_smbios_string(&buffer, bios_date, bios_date_size); + memset(buffer, 0, 1); + } + else + { + memset(buffer, 0, 2); + } + + free(bios_manufacturer); + free(bios_version); + free(bios_date); + + return required_size; +#endif + } + } + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} 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;