From: Grigory Vasilyev h0tc0d3@gmail.com
--- dlls/ntdll/unix/system.c | 142 +++++++++++++++++++++++++++++++++++++++ dlls/wow64/system.c | 3 + include/winternl.h | 22 ++++++ 3 files changed, 167 insertions(+)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index bf6f2815021..a3449049553 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2763,6 +2763,65 @@ C_ASSERT( sizeof(struct process_info) <= sizeof(SYSTEM_PROCESS_INFORMATION) ); return ret; }
+/****************************************************************************** + * __wine_hexstr32_to_guid (NTDLL.@) + */ +static inline BOOL __wine_hexstr32_to_guid(const char *s, GUID *id) +{ + int i; + if (!s) { + memset(id, 0, sizeof(*id)); + return FALSE; + } + + id->Data1 = 0; + for (i = 0; i < 8; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data1 = (id->Data1 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + id->Data2 = 0; + for (i = 8; i < 12; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data2 = (id->Data2 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + id->Data3 = 0; + for (i = 12; i < 16; ++i) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')))) + return FALSE; + id->Data3 = (id->Data3 << 4) + | ((s[i] & 0xF) + (s[i] >> 6)) + | ((s[i] >> 3) & 0x8); + } + + for (i = 16; i < 32; i += 2) { + if (!(((s[i] >= '0') && (s[i] <= '9')) + || ((s[i] >= 'a') && (s[i] <= 'f')) + || ((s[i] >= 'A') && (s[i] <= 'F')) + || ((s[i + 1] >= '0') && (s[i + 1] <= '9')) + || ((s[i + 1] >= 'a') && (s[i + 1] <= 'f')) + || ((s[i + 1] >= 'A') && (s[i + 1] <= 'F')))) + return FALSE; + id->Data4[(i - 16) / 2] = ((((s[i] & 0xF) + (s[i] >> 6)) | ((s[i] >> 3) & 0x8)) << 4) + | (((s[i + 1] & 0xF) + (s[i + 1] >> 6)) | ((s[i + 1] >> 3) & 0x8)); + } + + return TRUE; +} + /****************************************************************************** * NtQuerySystemInformation (NTDLL.@) */ @@ -2794,6 +2853,89 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, break; }
+ case SystemBootEnvironmentInformation: /* 90 */ + { + static SYSTEM_BOOT_ENVIRONMENT_INFORMATION boot_info = {0}; + struct stat stat_info = {0}; + ssize_t ssz; + len = sizeof(boot_info); + if (size == len) + { +#if defined(__linux__) || defined(__gnu_linux__) + int fd; + char buffer[32]; + + if (boot_info.FirmwareType == FirmwareTypeUnknown) + { + if (!stat("/sys/firmware/efi", &stat_info)) + boot_info.FirmwareType = FirmwareTypeUefi; + else + boot_info.FirmwareType = FirmwareTypeBios; + } +#else + boot_info.FirmwareType = FirmwareTypeBios; +#endif + if (boot_info.BootIdentifier.Data1 == 0) + { +#if defined(__linux__) || defined(__gnu_linux__) + if (!stat("/etc/machine-id", &stat_info) && stat_info.st_size >= 32) + { + fd = open("/etc/machine-id", O_RDONLY | O_NONBLOCK); + if (fd >= 0) + { + try_read_guid: + ssz = read(fd, &buffer, 32); + if (ssz < 0 && (errno == EAGAIN || errno == EINTR)) + goto try_read_guid; + close(fd); + if (!__wine_hexstr32_to_guid(buffer, &boot_info.BootIdentifier)) + goto try_read_hostid; + } + else goto try_read_hostid; + } + else + { + try_read_hostid: +#endif + if (!stat("/home", &stat_info) || !stat("/usr", &stat_info)) + { + boot_info.BootIdentifier.Data1 = gethostid() & 0xFFFFFFFF; + boot_info.BootIdentifier.Data2 = stat_info.st_dev & 0xFFFF; + boot_info.BootIdentifier.Data3 = stat_info.st_ino & 0xFFFF; + boot_info.BootIdentifier.Data4[0] = 'W' + 136; + boot_info.BootIdentifier.Data4[1] = '1' + 142; + boot_info.BootIdentifier.Data4[2] = 'n' + 136; + boot_info.BootIdentifier.Data4[3] = '3' + 136; + boot_info.BootIdentifier.Data4[4] = 'G' + 128; + boot_info.BootIdentifier.Data4[5] = 'u' + 136; + boot_info.BootIdentifier.Data4[6] = '1' + 128; + boot_info.BootIdentifier.Data4[7] = 'd' + 136; + } + else + { + try_read_random: + ssz = getrandom((void *)&boot_info.BootIdentifier, sizeof(boot_info.BootIdentifier), 0); + if (ssz < 0 && (errno == EAGAIN || errno == EINTR )) + goto try_read_random; + } +#if defined(__linux__) || defined(__gnu_linux__) + } +#endif + boot_info.BootIdentifier.Data3 &= 0x0fff; + boot_info.BootIdentifier.Data3 |= (4 << 12); + /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as + * specified in RFC 4122, section 4.4. + */ + boot_info.BootIdentifier.Data4[0] &= 0x3f; + boot_info.BootIdentifier.Data4[0] |= 0x80; + } + memcpy(info, &boot_info, len); + } + else ret = STATUS_INFO_LENGTH_MISMATCH; + if (ret_size) *ret_size = len; + break; + } + case SystemCpuInformation: /* 1 */ if (size >= (len = sizeof(cpu_info))) memcpy(info, &cpu_info, len); else ret = STATUS_INFO_LENGTH_MISMATCH; diff --git a/dlls/wow64/system.c b/dlls/wow64/system.c index 5f3056a4179..402b53e1eda 100644 --- a/dlls/wow64/system.c +++ b/dlls/wow64/system.c @@ -356,6 +356,9 @@ NTSTATUS WINAPI wow64_NtQuerySystemInformation( UINT *args ) if (retlen) *retlen = sizeof(SYSTEM_BASIC_INFORMATION32); return status;
+ case SystemBootEnvironmentInformation: /* SYSTEM_BOOT_ENVIRONMENT_INFORMATION */ + return NtQuerySystemInformation(class, ptr, len, retlen); + case SystemProcessInformation: /* SYSTEM_PROCESS_INFORMATION */ case SystemExtendedProcessInformation: /* SYSTEM_PROCESS_INFORMATION */ { diff --git a/include/winternl.h b/include/winternl.h index 828fbc6e915..510bba09042 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2724,6 +2724,28 @@ typedef struct _SYSTEM_BASIC_INFORMATION { #endif } SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;
+/* System Information Class 0x90 */ +typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION +{ + GUID BootIdentifier; + FIRMWARE_TYPE FirmwareType; + union + { + ULONGLONG BootFlags; + struct + { + ULONGLONG DbgMenuOsSelection : 1; + ULONGLONG DbgHiberBoot : 1; + ULONGLONG DbgSoftBoot : 1; + ULONGLONG DbgMeasuredLaunch : 1; + ULONGLONG DbgMeasuredLaunchCapable : 1; + ULONGLONG DbgSystemHiveReplace : 1; + ULONGLONG DbgMeasuredLaunchSmmProtections : 1; + ULONGLONG DbgMeasuredLaunchSmmLevel : 7; + }; + }; +} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION; + /* System Information Class 0x01 */
typedef struct _SYSTEM_CPU_INFORMATION {