From a54452c0aa065067f59baf59108c22a63d3449ca Mon Sep 17 00:00:00 2001 From: Johnny Shaw Date: Tue, 7 Jan 2025 12:57:53 -0700 Subject: [PATCH] phlib firmware --- phlib/firmware.c | 205 +++++++++++++++++++++++++++ phlib/include/phfirmware.h | 103 ++++++++++++++ phlib/phlib.vcxproj | 2 + phlib/phlib.vcxproj.filters | 6 + tools/CustomBuildTool/BuildConfig.cs | 1 + 5 files changed, 317 insertions(+) create mode 100644 phlib/firmware.c create mode 100644 phlib/include/phfirmware.h diff --git a/phlib/firmware.c b/phlib/firmware.c new file mode 100644 index 000000000000..a9de7df616d7 --- /dev/null +++ b/phlib/firmware.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2022 Winsider Seminars & Solutions, Inc. All rights reserved. + * + * This file is part of System Informer. + * + * Authors: + * + * jxy-s 2025 + * + */ + +#include + +#include +#include + +typedef struct _PH_SMBIOS_STRINGREF +{ + UCHAR Length; + PSTR Buffer; +} PH_SMBIOS_STRINGREF, *PPH_SMBIOS_STRINGREF; + +typedef struct _PH_SMBIOS_PARSE_CONTEXT +{ + PRAW_SMBIOS_DATA Data; + PVOID End; + PH_SMBIOS_STRINGREF Strings[256]; +} PH_SMBIOS_PARSE_CONTEXT, *PPH_SMBIOS_PARSE_CONTEXT; + +NTSTATUS PhpParseSMBIOS( + _In_ PPH_SMBIOS_PARSE_CONTEXT Context, + _In_ PSMBIOS_HEADER Current, + _Out_ PSMBIOS_HEADER* Next + ) +{ + NTSTATUS status; + PSTR pointer; + PSTR string; + UCHAR nulls; + UCHAR length; + UCHAR count; + + *Next = NULL; + + memset(Context->Strings, 0, sizeof(Context->Strings)); + + pointer = SMBIOS_STRING_TABLE(Current); + string = pointer; + + if ((ULONG_PTR)pointer >= (ULONG_PTR)Context->End) + return STATUS_BUFFER_OVERFLOW; + + nulls = 0; + length = 0; + count = 0; + + while ((ULONG_PTR)pointer < (ULONG_PTR)Context->End) + { + if (*pointer++ != ANSI_NULL) + { + if (!NT_SUCCESS(status = RtlUInt8Add(length, 1, &length))) + return status; + + nulls = 0; + continue; + } + + if (nulls++) + break; + + Context->Strings[count].Length = length; + Context->Strings[count].Buffer = string; + + count++; + string = pointer; + length = 0; + } + + if (nulls != 2) + return STATUS_INVALID_ADDRESS; + + if (Current->Type != SMBIOS_END_OF_TABLE_TYPE) + *Next = (PSMBIOS_HEADER)pointer; + + return STATUS_SUCCESS; +} + +NTSTATUS PhpEnumSMBIOS( + _In_ PRAW_SMBIOS_DATA Data, + _In_ PPH_ENUM_SMBIOS_CALLBACK Callback, + _In_opt_ PVOID Context + ) +{ + NTSTATUS status; + PH_SMBIOS_PARSE_CONTEXT context; + PSMBIOS_HEADER current; + PSMBIOS_HEADER next; + + memset(&context, 0, sizeof(context)); + + context.Data = Data; + context.End = PTR_ADD_OFFSET(Data->SMBIOSTableData, Data->Length); + + current = (PSMBIOS_HEADER)Data->SMBIOSTableData; + next = NULL; + + while (NT_SUCCESS(status = PhpParseSMBIOS(&context, current, &next))) + { + if (Callback( + (ULONG_PTR)&context, + Data->SMBIOSMajorVersion, + Data->SMBIOSMinorVersion, + (PPH_SMBIOS_ENTRY)current, + Context + )) + break; + + if (!next) + break; + + current = next; + } + + return status; +} + +NTSTATUS PhEnumSMBIOS( + _In_ PPH_ENUM_SMBIOS_CALLBACK Callback, + _In_opt_ PVOID Context + ) +{ + NTSTATUS status; + ULONG length; + PSYSTEM_FIRMWARE_TABLE_INFORMATION info; + + length = 1024; + info = PhAllocateZero(length); + + info->ProviderSignature = 'RSMB'; + info->TableID = 0; + info->Action = SystemFirmwareTableGet; + info->TableBufferLength = length - sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION); + + status = NtQuerySystemInformation( + SystemFirmwareTableInformation, + info, + length, + &length + ); + if (status == STATUS_BUFFER_TOO_SMALL) + { + PhFree(info); + info = PhAllocateZero(length); + + info->ProviderSignature = 'RSMB'; + info->TableID = 0; + info->Action = SystemFirmwareTableGet; + info->TableBufferLength = length - sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION); + + status = NtQuerySystemInformation( + SystemFirmwareTableInformation, + info, + length, + &length + ); + } + + if (NT_SUCCESS(status)) + { + status = PhpEnumSMBIOS( + (PRAW_SMBIOS_DATA)info->TableBuffer, + Callback, + Context + ); + } + + PhFree(info); + + return status; +} + +NTSTATUS PhGetSMBIOSString( + _In_ ULONG_PTR EnumHandle, + _In_ UCHAR Index, + _Out_ PPH_STRING* String + ) +{ + PPH_SMBIOS_PARSE_CONTEXT context; + PPH_SMBIOS_STRINGREF string; + + context = (PPH_SMBIOS_PARSE_CONTEXT)EnumHandle; + + *String = NULL; + + if (Index == SMBIOS_INVALID_STRING) + return STATUS_INVALID_PARAMETER; + + string = &context->Strings[Index - 1]; + if (!string->Buffer) + return STATUS_INVALID_PARAMETER; + + *String = PhConvertUtf8ToUtf16Ex(string->Buffer, string->Length); + + return STATUS_SUCCESS; +} diff --git a/phlib/include/phfirmware.h b/phlib/include/phfirmware.h new file mode 100644 index 000000000000..5e0075065f30 --- /dev/null +++ b/phlib/include/phfirmware.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Winsider Seminars & Solutions, Inc. All rights reserved. + * + * This file is part of System Informer. + * + * Authors: + * + * jxy-s 2025 + * + */ + +#ifndef _PH_PHSMBIOS_H +#define _PH_PHSMBIOS_H + +#include + +EXTERN_C_START + +typedef union _PH_SMBIOS_ENTRY +{ + SMBIOS_HEADER Header; + SMBIOS_FIRMWARE_INFORMATION Firmware; + SMBIOS_SYSTEM_INFORMATION System; + SMBIOS_BASEBOARD_INFORMATION Baseboard; + SMBIOS_CHASSIS_INFORMATION Chassis; + SMBIOS_PROCESSOR_INFORMATION Processor; + SMBIOS_MEMORY_CONTROLLER_INFORMATION MemoryController; + SMBIOS_MEMORY_MODULE_INFORMATION MemoryModule; + SMBIOS_CACHE_INFORMATION Cache; + SMBIOS_PORT_CONNECTOR_INFORMATION PortConnector; + SMBIOS_SYSTEM_SLOT_INFORMATION SystemSlot; + SMBIOS_ON_BOARD_DEVICE_INFORMATION OnBoardDevice; + SMBIOS_OEM_STRING_INFORMATION OEMString; + SMBIOS_FIRMWARE_LANGUAGE_INFORMATION FirmwareLanguage; + SMBIOS_GROUP_ASSOCIATION_INFORMATION GroupAssociation; + SMBIOS_SYSTEM_EVENT_LOG_INFORMATION EventLog; + SMBIOS_PHYSICAL_MEMORY_ARRAY_INFORMATION PhysicalMemoryArray; + SMBIOS_MEMORY_DEVICE_INFORMATION MemoryDevice; + SMBIOS_32_BIT_MEMORY_ERROR_INFORMATION MemoryError32; + SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS_INFORMATION MemoryArrayMappedAddress; + SMBIOS_MEMORY_DEVICE_MAPPED_DATA_INFORMATION MemoryDeviceMappedData; + SMBIOS_BUILT_IN_POINTING_DEVICE_INFORMATION BuiltInPointingDevice; + SMBIOS_PORTABLE_BATTERY_INFORMATION PortableBattery; + SMBIOS_SYSTEM_RESET_INFORMATION SystemReset; + SMBIOS_HARDWARE_SECURITY_INFORMATION HardwareSecurity; + SMBIOS_SYSTEM_POWER_CONTROLS_INFORMATION SystemPowerControls; + SMBIOS_VOLTAGE_PROBE_INFORMATION VoltageProbe; + SMBIOS_COOLING_DEVICE_INFORMATION CoolingDevice; + SMBIOS_TEMPERATURE_PROBE_INFORMATION TemperatureProbe; + SMBIOS_ELECTRICAL_CURRENT_PROBE_INFORMATION ElectricalCurrentProbe; + SMBIOS_OUT_OF_BAND_REMOTE_ACCESS_INFORMATION OutOfBandRemoteAccess; + SMBIOS_SYSTEM_BOOT_INFORMATION SystemBoot; + SMBIOS_64_BIT_MEMORY_ERROR_INFORMATION MemoryError64; + SMBIOS_MANAGEMENT_DEVICE_INFORMATION ManagementDevice; + SMBIOS_MANAGEMENT_DEVICE_COMPONENT_INFORMATION ManagementDeviceComponent; + SMBIOS_MANAGEMENT_DEVICE_THRESHOLD_INFORMATION ManagementDeviceThreshold; + SMBIOS_MEMORY_CHANNEL_INFORMATION MemoryChannel; + SMBIOS_IPMI_DEVICE_INFORMATION IPMIDevice; + SMBIOS_SYSTEM_POWER_SUPPLY_INFORMATION SystemPowerSupply; + SMBIOS_ADDITIONAL_INFORMATION AdditionalInformation; + SMBIOS_ONBOARD_DEVICE_INFORMATION OnboardDevice; + SMBIOS_MCHI_INFORMATION MCHInterface; + SMBIOS_TPM_DEVICE_INFORMATION TPMDevice; + SMBIOS_PROCESSOR_ADDITIONAL_INFORMATION ProcessorAdditional; + SMBIOS_FIRMWARE_INVENTORY_INFORMATION FirmwareInventory; + SMBIOS_STRING_PROPERTY StringProperty; + SMBIOS_INACTIVE Inactive; + SMBIOS_END_OF_TABLE EndOfTable; +} PH_SMBIOS_ENTRY, *PPH_SMBIOS_ENTRY; + +typedef +_Function_class_(PH_ENUM_SMBIOS_CALLBACK) +BOOLEAN +NTAPI +PH_ENUM_SMBIOS_CALLBACK( + _In_ ULONG_PTR EnumHandle, + _In_ UCHAR MajorVersion, + _In_ UCHAR MinorVersion, + _In_ PPH_SMBIOS_ENTRY Entry, + _In_opt_ PVOID Context + ); +typedef PH_ENUM_SMBIOS_CALLBACK* PPH_ENUM_SMBIOS_CALLBACK; + +PHLIBAPI +NTSTATUS +NTAPI +PhEnumSMBIOS( + _In_ PPH_ENUM_SMBIOS_CALLBACK Callback, + _In_opt_ PVOID Context + ); + +PHLIBAPI +NTSTATUS +NTAPI +PhGetSMBIOSString( + _In_ ULONG_PTR EnumHandle, + _In_ UCHAR Index, + _Out_ PPH_STRING* String + ); + +EXTERN_C_END + +#endif diff --git a/phlib/phlib.vcxproj b/phlib/phlib.vcxproj index 10407ddab113..01b811b000e2 100644 --- a/phlib/phlib.vcxproj +++ b/phlib/phlib.vcxproj @@ -324,6 +324,7 @@ + @@ -378,6 +379,7 @@ + diff --git a/phlib/phlib.vcxproj.filters b/phlib/phlib.vcxproj.filters index d1b1b72ace55..5044ce7b27d8 100644 --- a/phlib/phlib.vcxproj.filters +++ b/phlib/phlib.vcxproj.filters @@ -203,6 +203,9 @@ Source Files + + Source Files + @@ -421,5 +424,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/tools/CustomBuildTool/BuildConfig.cs b/tools/CustomBuildTool/BuildConfig.cs index c0c2e1ec036a..91f38d06afde 100644 --- a/tools/CustomBuildTool/BuildConfig.cs +++ b/tools/CustomBuildTool/BuildConfig.cs @@ -122,6 +122,7 @@ public static class BuildConfig "phconfig.h", "phconsole.h", "phdata.h", + "phfirmware.h", "phnative.h", "phnativeinl.h", "phnet.h",