From: Grigory Vasilyev h0tc0d3@gmail.com
--- dlls/ntdll/unix/system.c | 64 ++++++++++++++++++++++++++++++++++++++++ dlls/wow64/system.c | 3 ++ include/winternl.h | 22 ++++++++++++++ 3 files changed, 89 insertions(+)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 0d3a4f403ef..80975e2c810 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -2794,6 +2794,70 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class, break; }
+ case SystemBootEnvironmentInformation: /* 90 */ + { + static volatile SYSTEM_BOOT_ENVIRONMENT_INFORMATION boot_info = { 0 }; + len = sizeof(boot_info); + if(size == len) + { +#if defined(__linux__) || defined(__gnu_linux__) + int fd; + ssize_t ssz; + struct stat stat_info = { 0 }; + char buffer[32]; + + if( boot_info.FirmwareType == FirmwareTypeUnknown ) + { + if( !stat( "/sys/firmware/efi", &stat_info ) ) + boot_info.FirmwareType = FirmwareTypeUefi; + else + boot_info.FirmwareType = FirmwareTypeBios; + } + + if( boot_info.BootIdentifier.Data1 == 0) + { + 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 ); + sscanf( buffer, "%08lx%04hx%04hx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + &boot_info.BootIdentifier.Data1, &boot_info.BootIdentifier.Data2, + &boot_info.BootIdentifier.Data3, &boot_info.BootIdentifier.Data4[0], + &boot_info.BootIdentifier.Data4[1], &boot_info.BootIdentifier.Data4[2], + &boot_info.BootIdentifier.Data4[3], &boot_info.BootIdentifier.Data4[4], + &boot_info.BootIdentifier.Data4[5], &boot_info.BootIdentifier.Data4[6], + &boot_info.BootIdentifier.Data4[7] ); + } + else goto try_read_random; + } else { + try_read_random: + ssz = getrandom( &boot_info.BootIdentifier, sizeof( boot_info.BootIdentifier ), 0 ); + if ( ssz < 0 && ( errno == EAGAIN || errno == EINTR ) ) + goto try_read_random; + } + + 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; + } +#endif + 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..3835f815072 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 {