diff --git a/phlib/firmware.c b/phlib/firmware.c index 691a92da7d44..10c3a66e3c8c 100644 --- a/phlib/firmware.c +++ b/phlib/firmware.c @@ -129,27 +129,29 @@ NTSTATUS PhEnumSMBIOS( _In_opt_ PVOID Context ) { - static PH_INITONCE initOnce = PH_INITONCE_INIT; - static NTSTATUS status; - static ULONG length; - static PSYSTEM_FIRMWARE_TABLE_INFORMATION info; + static volatile ULONG cachedLength = sizeof(PSYSTEM_FIRMWARE_TABLE_INFORMATION) + 64; + NTSTATUS status; + ULONG length; + PSYSTEM_FIRMWARE_TABLE_INFORMATION info; - if (PhBeginInitOnce(&initOnce)) - { - SYSTEM_FIRMWARE_TABLE_INFORMATION initInfo; + length = (ULONG)ReadAcquire((volatile LONG*)&cachedLength); - initInfo.ProviderSignature = 'RSMB'; - initInfo.TableID = 0; - initInfo.Action = SystemFirmwareTableGet; - initInfo.TableBufferLength = 0; + info = PhAllocateZero(length); - NtQuerySystemInformation( - SystemFirmwareTableInformation, - &initInfo, - sizeof(SYSTEM_FIRMWARE_TABLE_INFORMATION), - &length - ); + info->ProviderSignature = 'RSMB'; + info->TableID = 0; + info->Action = SystemFirmwareTableGet; + info->TableBufferLength = length - sizeof(PSYSTEM_FIRMWARE_TABLE_INFORMATION); + status = NtQuerySystemInformation( + SystemFirmwareTableInformation, + info, + length, + &length + ); + if (status == STATUS_BUFFER_TOO_SMALL) + { + PhFree(info); info = PhAllocateZero(length); info->ProviderSignature = 'RSMB'; @@ -163,8 +165,8 @@ NTSTATUS PhEnumSMBIOS( length, &length ); - - PhEndInitOnce(&initOnce); + if (NT_SUCCESS(status)) + WriteRelease((volatile LONG*)&cachedLength, (LONG)length); } if (NT_SUCCESS(status))