2013-05-22 10 views
7

szukam sposób, aby niezawodnie wykrywać kiedy uruchomi się WinPE 4 (PowerShell) (lub WinPE 3 (VBS) jako alternatywnego) ja uruchamiany z UEFI BIOS lub System? (bez uruchamiania exe trzeciej partii, jak jestem w ograniczonym środowisku)Jak wykryć, czy WinPE (4) został uruchomiony z UEFI lub BIOS?

to znacząco zmienia sposób będę partycjonowanie wdrażania systemu Windows jako zmiany układu partycji i format. (GPT kontra MBR, etc)

mam jeden roboczy, który jest adaptacją kodu w PowerShell v3 this C++ ale czuje się dość hack-owski:

## 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() 
} 

To wydaje się całkiem na wierzchu tylko aby uzyskać prostą flagę.

Czy ktoś wie, czy istnieje lepszy sposób na zrobienie tego?

Odpowiedz

-1

Wygląda na to, że środowisko PE ma folder, który jest specyficzny dla środowiska PE. Ponadto zmienna% TargetDir% jest opisana tutaj, TARGETDIR property.

Na koniec, możesz sprawdzić, czy korzystasz z X: Powinien też istnieć folder z obrazem boot.wim, który możesz sprawdzić. Wierzę, że ścieżka byłaby X: \ Sources \ Boot.wim, ale sprawdź jeszcze raz.

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

    Write-host "You're in Windows PE" 

} 
+0

to nie jest to, czy jestem w WinPE na początku. Właśnie wtedy, gdy jestem w PE, zostałem uruchomiony przez UEFI lub Legacy BIOS. – RogerWilco

1

To nie mniej hacky jest w tym sensie, to nadal wymaga współdziałanie z PowerShell, ale kod współdziałanie może być neater jeśli używasz (lub można nazwać): GetFirmwareType().

Powoduje to wyliczenie FIRMWARE_TYPE udokumentowane here. Nie mogę uwierzyć, że obie funkcje zostały wprowadzone w systemie Windows 8 i wyeksportowane przez kernel32.dll, którego własna dokumentacja Microsoft wskazuje na "używanie zmiennej dummy"!

Wewnętrznie, GetFirmwareType dzwoni NtQuerySystemInformation. Wkopię się w to, co robi, ale nie sądzę, żeby to miało być oświeceniem.

Niestety, działa to tylko dla PE4 (Windows 8), ponieważ te funkcje zostały tylko wtedy dodane.

-1

Nie wiem, czy to pomoże (w oparciu o C# roztworu), ale:

Win32_DiskPartition ma właściwości "startowy" (bool), "BootPartition" (bool), i "typ" (string). Dla mojego systemu UEFI "Typ" powraca jako ciąg "GPT: System".

Teraz, dla wszystkich Win32_DiskPartitions, które są bootowalne, są partycją rozruchową i mają określony typ, określić, czy któryś z nich jest wewnętrzny.

Mam nadzieję, że to pomoże.

+0

To nie pomoże. Środowisko WinPE (instalator) prawdopodobnie działa na pustych dyskach twardych, a obecność określonych typów partycji na dysku nie gwarantuje, że bieżący system może się z nich uruchomić (napęd mógł zostać przeszczepiony z innego systemu). –

1

To może być trochę za późno, ale jeśli ktoś wie, są one uruchomione w środowisku WinPE, następujący kod powinien działać:

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