Как определить, загрузился ли WinPE(4) из UEFI или BIOS?

Я ищу способ надежного определения, когда я загружаюсь в WinPE 4 (powershell) (или в качестве альтернативы WinPE 3 (vbs)), загрузился ли я из системы UEFI или BIOS? (без запуска стороннего exe-файла, так как я в ограниченной среде)

Это существенно меняет способ разбиения развертывания Windows по мере изменения и форматирования разделов. (GPT против MBR и т. Д.)

У меня есть один рабочий, который является адаптацией этого кода C++ в powershell v3, но он выглядит довольно взломанным:

## Check if we can get a dummy flag from the UEFI via the Kernel
## [Bool] check the result of the kernel's fetch of the dummy GUID from UEFI
## The only way I found to do it was using the C++ compiler in powershell
Function Compile-UEFIDectectionClass{
    $win32UEFICode= @'
    using System;
    using System.Runtime.InteropServices;

    public class UEFI
    {
       [DllImport("kernel32.dll")]
       public static extern UInt32 GetFirmwareEnvironmentVariableA([MarshalAs(UnmanagedType.LPWStr)] string lpName, [MarshalAs(UnmanagedType.LPWStr)] string lpGuid, IntPtr pBuffer, UInt32 nSize); 

       public static UInt32 Detect()
       {
            return GetFirmwareEnvironmentVariableA("", "{00000000-0000-0000-0000-000000000000}", IntPtr.Zero, 0);
       }
    }
    '@

Add-Type $win32UEFICode
}


## A Function added just to check if the assembly for 
## UEFI is loaded as is the name of the class above in C++.
Function Check-IsUEFIClassLoaded{
     return ([System.AppDomain]::CurrentDomain.GetAssemblies() | % { $_.GetTypes()} | ? {$_.FullName -eq "UEFI"}).Count 
}

## Just incase someone was to call my code without running the Compiled code run first
If (!(Check-IsUEFIClassLoaded)){
    Compile-UEFIDectectionClass
}

## The meat of the checking.
## Returns 0 or 1 ([BOOL] if UEFI or not)
Function Get-UEFI{
    return [UEFI]::Detect()
}

Это выглядит довольно просто, просто чтобы получить простой флаг.

Кто-нибудь знает, есть ли лучший способ сделать это?

5 ответов

Он не менее хакерский, в том смысле, что он все еще требует взаимодействия с powershell, но код взаимодействия может быть более аккуратным, если вы используете (или можете вызвать): GetFirmwareType(),

Это возвращает FIRMWARE_TYPE Перечень документирован здесь. Я не могу поверить, учитывая, что обе функции введены в Windows 8 и экспортированы kernel32.dll, что собственная документация Microsoft указывает вам на "использование фиктивной переменной"!

Внутренне GetFirmwareType звонки NtQuerySystemInformation, Я углублюсь в то, что он делает, но я не думаю, что это обязательно будет просветляющим.

К сожалению, это работает только для PE4 (Windows 8), так как эти функции были добавлены только тогда.

Самый простой способ - запустить PowerShell:

$(Get-ComputerInfo).BiosFirmwareType

Это может быть немного поздно, но если кто-то знает, что они работают в WinPE, следующий код должен работать:

$isuefi = (Get-ItemProperty -Path HKLM:\System\CurrentControlSet\Control).PEFirmwareType -eq 2

$env:firmware_type

Не уверен, с какой версией это поддерживается. Возврат UEFI и Legacy в моих тестах.

Однако это при полной установке, обратите внимание на подтверждение существования в WinPE

У меня нет системы UEFI для тестирования, но эта статья, кажется, подразумевает, что есть значение реестра, которое вы можете запросить в PE, чтобы узнать, в каком режиме он был загружен:

http://technet.microsoft.com/en-us/library/dn293283.aspx

Я не знаю, поможет ли это (на основе решения C#), но:

Win32_DiskPartition имеет свойства "Bootable" (bool), "BootPartition" (bool) и "Type" (строка). Для моей системы UEFI "Тип" возвращается как строка "GPT: Система".

Теперь для всех загрузочных разделов Win32_DiskPartition, которые являются загрузочными разделами и имеют указанный тип, определите, являются ли какие-либо из них внутренними.

Надеюсь это поможет.

Похоже, что среда PE имеет папку, специфичную для среды PE. Кроме того, здесь описывается переменная%TargetDir%, свойство TARGETDIR.

Наконец, вы можете проверить, работаете ли вы с X: там также должна быть папка с образом boot.wim, который вы можете проверить. Я считаю, что путь будет X:\Sources\Boot.wim, но с двойной проверкой.

if ( Test-Path "%TargetDir%\Windows\wpeprofiles" ) {

     Write-host "You're in Windows PE"

}
Другие вопросы по тегам