Files

633 lines
21 KiB
Plaintext

' // ***************************************************************************
' //
' // Copyright (c) Microsoft Corporation. All rights reserved.
' //
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File: ZTIBCDUtility.vbs
' //
' // Version: 6.3.8456.1000
' //
' // Purpose: Utility functions for bcd operations
' //
' // Usage: cscript.exe [//nologo] ztibcdutility.vbs
' //
' // Reference: http://technet.microsoft.com/en-us/magazine/2008.07.heyscriptingguy.aspx?pr=blog
' //
' //
' // ***************************************************************************
Option Explicit
'//---------------------------------------------------------------------------
'//
'// Support Routines
'//
'//---------------------------------------------------------------------------
'//
'// Functions that work for both WMI and BCDEdit.exe
'//
Function BCDObjectExists ( sGUID )
BCDObjectExists = BCDObjectExistsEx ( "", sGUID )
End function
Function BCDObjectExistsEx ( sStore, sGUID )
Dim sBuffer
Dim iRetVal
BCDObjectExistsEx = False
iRetVal = RunBCDEditEx("/enum " & sGUID , sStore, sBuffer )
If iRetVal = SUCCESS then
BCDObjectExistsEx = instr( 1, sBuffer, sGUID, vbTextCompare ) <> 0
If not BCDObjectExistsEx then
iRetVal = RunBCDEditEx("/enum " & sGUID & " /v", sStore, sBuffer )
If iRetVal = SUCCESS then
BCDObjectExistsEx = instr( 1, sBuffer, sGUID, vbTextCompare ) <> 0
End if
End if
End if
End function
Function BCDBackupStore( sBackupFile )
BCDBackupStore = RunBCDEdit( "/export """ & sBackupFile & """" ) = SUCCESS
End function
Function BCDGetCurrentGUID
BCDGetCurrentGUID = BCDGetCurrentGUIDEx( "" )
End function
Function BCDGetCurrentGUIDEx ( sStore )
' THis function requires WMI
oBCDUtility.sBCDStore = sStore
BCDGetCurrentGUIDEx = oBCDUtility.GetCurrentGUID
End function
Function GetBCDError
oLogging.CreateEntry "GetBCDError.", LogTypeDeprecated
GetBCDError = ""
End function
'//---------------------------------------------------------------------------
'//
'// Functions that work for both WMI and BCDEdit.exe
'//
Function CreateRamDiskEntry( sDrive )
CreateRamDiskEntry = CreateRamDiskEntryEx( "", sDrive )
End function
Function CreateRamDiskEntryEx( sStore, sDrive )
If BCDObjectExists("{ramdiskoptions}") then
oLogging.CreateEntry "{ramdiskoptions} already present.", LogTypeInfo
exit Function
End if
' Create entry.
RunBCDEditEx "/Create {ramdiskoptions} -d ""Ramdisk Device Options""" , sStore, null
RunBCDEditEx "/Set {ramdiskoptions} ramdisksdidevice partition=" & sDrive , sStore, null
RunBCDEditEx "/Set {ramdiskoptions} ramdisksdipath \Boot\boot.sdi" , sStore, null
CreateRamDiskEntryEx = BCDObjectExistsEx(sStore, "{ramdiskoptions}")
End Function
Const BDD_RAMDISK_GUID = "{d22e7e91-9ee7-46eb-89d7-c5859e4302f0}"
Function CreateNewBCDEntry( byRef sGUID, sDescription, sDrive, sPathToWim )
CreateNewRamDiskEntry = CreateNewRamDiskEntryEx ( sStore, sGUID, sDescription, sDrive, sPathToWim )
End function
Function CreateNewBCDEntryEx ( sStore, byRef sGUID, sDescription, sDrive, sPathToWim )
Dim bResult
'
' Normalize Defaults
'
If sDrive = "" then
oLogging.CreateEntry "sDrive not defined for CreateNewBCDEntryEx. Defaulting to C:", LogTypeWarning
sDrive = "C:"
End if
If sGUID = "" then
sGUID = oStrings.GenerateRandomGUID
End if
'
' Create Entry
'
If sDescription = "" then
bResult = RunBCDEditEx("/Create " & sGUID & " -d ""Custom Entry"" /application OSLOADER" , sStore, null)
Else
bResult = RunBCDEditEx("/Create " & sGUID & " -d """ & sDescription & """ /application OSLOADER" , sStore, null)
End if
'
' Verify Store was created:
'
TEstAndLog BCDObjectExistsEx(sStore, sGUID ), "Create element: " & sGuid
bResult = CreateRamDiskEntryEx( sStore, sDrive )
'
' Fix settings
'
RunBCDEditEx "/Set " & sGUID & " device ramdisk=[" & sDrive & "]" & sPathToWim & ",{ramdiskoptions}" , sStore, null
RunBCDEditEx "/Set " & sGUID & " osdevice ramdisk=[" & sDrive & "]" & sPathToWim & ",{ramdiskoptions}" , sStore, null
If UCase(oEnvironment.Item("IsUEFI")) = "TRUE" then
RunBCDEditEx "/Set " & sGUID & " path \windows\system32\boot\winload.efi" , sStore, null
Else
RunBCDEditEx "/Set " & sGUID & " path \windows\system32\boot\winload.exe" , sStore, null
End if
RunBCDEditEx "/Set " & sGUID & " systemroot \windows" , sStore, null
RunBCDEditEx "/Set " & sGUID & " detecthal yes" , sStore, null
RunBCDEditEx "/Set " & sGUID & " winpe yes" , sStore, null
' RunBCDEditEx "/Set " & sGUID & " inherit {bootloadersettings}" , sStore, null
' RunBCDEditEx "/Set " & sGUID & " ems yes" , sStore, null
' RunBCDEditEx "/Set " & sGUID & " locale en-US" , sStore, null
CreateNewBCDEntryEx = SUCCESS
' programs should call BCDObjectExistsEx(sStore, sGUID ) to verify
End Function
Function AdjustBCDDefaults ( sStore, sGUID )
RunBCDEditEx "/timeout 0" , sStore, null
RunBCDEditEx "/displayorder " & sGUID & " /addfirst" , sStore, null
RunBCDEditEx "/bootsequence " & sGUID , sStore, null
RunBCDEditEx "/default " & sGUID , sStore, null
AdjustBCDDefaults = SUCCESS
End function
'//---------------------------------------------------------------------------
'//
'// BCDEdit functions
'//
Dim g_sBCDEdit
Function isBCDEditReady
Dim iRetVal
If isempty(g_sBCDEdit) then
' Cache the BCDEdit.exe file so we don't have to search each time.
iRetVal = oUtility.FindFile("bcdedit.exe", g_sBCDEdit)
If iRetVal <> SUCCESS then
oLogging.CreateEntry "Missing BCDEdit.exe.", LogTypeInfo
g_sBCDEdit = ""
End if
End if
isBCDEditReady = g_sBCDEdit <> ""
End Function
Function RunBCDEdit(sCommand )
RunBCDEdit = RunBCDEditEx(sCommand, "", null )
End function
Function RunBCDEditEx(sCommand, sStore, ByRef sOutput )
Dim iRetVal
Dim sCmd
Dim oExec
Dim sLine
If isempty(g_sBCDEdit) then
' Cache the BCDEdit.exe file so we don't have to search each time.
iRetVal = oUtility.FindFile("bcdedit.exe", g_sBCDEdit)
If iRetVal <> SUCCESS then
oLogging.CreateEntry "Missing BCDEdit.exe: " & sCommand, LogTypeInfo
g_sBCDEdit = ""
End if
End if
If g_sBCDEdit = "" then
exit function
ElseIf sStore = "" then
sCmd = g_sBCDEdit & " " & sCommand
Else
sCmd = g_sBCDEdit & " /Store """ & sStore & """ " & sCommand
End if
oLogging.CreateEntry "Run Command: " & sCmd, LogTypeInfo
set oExec = oShell.Exec(sCmd)
do while oExec.Status = 0 or not oExec.StdOut.atEndOfStream
If not oExec.StdOut.atEndOfStream then
sLine = oExec.StdOut.ReadLine
oLogging.CreateEntry "BCD> " & sLine, LogTypeInfo
If not isnull(sOutput) then
sOutput = sOutput & vbNewLine & sLine
End if
End If
If not oExec.StdErr.atEndOfStream then
sLine = oExec.StdErr.ReadLine
oLogging.CreateEntry "BCD> " & sLine, LogTypeError
End If
loop
oLogging.CreateEntry "BCDEdit returned ErrorLevel = " & oExec.ExitCode, LogTypeInfo
RunBCDEditEx = oExec.ExitCode
End function
'//---------------------------------------------------------------------------
'//
'// WMI Object
'//
Dim g_oBCDUtility
Function oBCDUtility
If isempty(g_oBCDUtility) then
set g_oBCDUtility = new BCDUtility
End if
set oBCDUtility = g_oBCDUtility
End function
Class BCDUtility
'
' Private Global Variables
'
private g_sBCDEdit
private g_oBCD
private g_oBCDStore
private g_sBCDStore
private g_sCurrent
'
' Public Functions
'
Private Sub Class_Initialize
g_sBCDStore = ""
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Private Handles
'
Private Function oBCD
' Get the base BCD object
If isempty(g_oBCD) then
on error resume next
set g_oBCD = GetObject( "winmgmts:{impersonationlevel=Impersonate,(Backup,Restore)}!root/wmi:BcdStore" )
TestAndFail not g_oBCD is nothing, 6601, "GetObject(... root/wmi:BCDStore)"
on error goto 0
End if
set oBCD = g_oBCD
End function
Private Function oBCDStore
dim bResult
If isempty(g_oBCDStore) then
If g_sBCDStore = "" then
oLogging.CreateEntry "BCD: Open Store: {system store}",LogTypeInfo
Else
oLogging.CreateEntry "BCD: Open Store: " & g_sBCDStore,LogTypeInfo
End if
on error resume next
bResult = oBCD.OpenStore( g_sBCDStore, g_oBCDStore )
TestAndFail bResult, 6602, "BCD.OpenStore (" & g_sBCDStore & ")"
on error goto 0
End if
set oBCDStore = g_oBCDStore
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Base Objects
'
Property Let sBCDStore( sNew )
g_sBCDStore = sNew
If not isempty(g_oBCDStore) then
set g_oBCDStore = nothing
g_oBCDStore = empty
g_sCurrent = empty
End if
End Property
Property Get sBCDStore
sBCDStore = g_sBCDStore
End Property
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'
' Support Functions
'
Public Function TranslateGUIDToWellKnown ( sGUID )
Dim oObject
Select case sGUID
case "{9dea862c-5cdd-4e70-acc1-f32b344d4795}" TranslateGUIDToWellKnown = "{bootmgr}"
case "{a5a30fa2-3d06-4e9f-b5f4-a01df9d1fcba}" TranslateGUIDToWellKnown = "{fwbootmgr}"
case "{b2721d73-1db4-4c62-bf78-c548a880142d}" TranslateGUIDToWellKnown = "{memdiag}"
case "{466f5a88-0af2-4f76-9038-095b170dc21c}" TranslateGUIDToWellKnown = "{ntldr}"
case "{fa926493-6f1c-4193-a414-58f0b2456d1e}" TranslateGUIDToWellKnown = "{current}"
case "{5189b25c-5558-4bf2-bca4-289b11bd29e2}" TranslateGUIDToWellKnown = "{badmemory}"
case "{6efb52bf-1766-41db-a6b3-0ee5eff72bd7}" TranslateGUIDToWellKnown = "{bootloadersettings}"
case "{4636856e-540f-4170-a130-a84776f4c654}" TranslateGUIDToWellKnown = "{dbgsettings}"
case "{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}" TranslateGUIDToWellKnown = "{emssettings}"
case "{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}" TranslateGUIDToWellKnown = "{globalsettings}"
case "{1afa9c49-16ab-4a5c-901b-212802da9460}" TranslateGUIDToWellKnown = "{resumeloadersettings}"
case else
If sGUID = GetCurrentGUID then
TranslateGUIDToWellKnown = "{current}"
Else
TranslateGUIDToWellKnown = sGUID
End if
End select
End function
Public Function TranslateWellKnownToGUID ( sGUID )
Select case sGUID
case "{bootmgr}" TranslateWellKnownToGUID = "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"
case "{fwbootmgr}" TranslateWellKnownToGUID = "{a5a30fa2-3d06-4e9f-b5f4-a01df9d1fcba}"
case "{memdiag}" TranslateWellKnownToGUID = "{b2721d73-1db4-4c62-bf78-c548a880142d}"
case "{ntldr}" TranslateWellKnownToGUID = "{466f5a88-0af2-4f76-9038-095b170dc21c}"
case "{current}" TranslateWellKnownToGUID = "{fa926493-6f1c-4193-a414-58f0b2456d1e}"
case "{badmemory}" TranslateWellKnownToGUID = "{5189b25c-5558-4bf2-bca4-289b11bd29e2}"
case "{bootloadersettings}" TranslateWellKnownToGUID = "{6efb52bf-1766-41db-a6b3-0ee5eff72bd7}"
case "{dbgsettings}" TranslateWellKnownToGUID = "{4636856e-540f-4170-a130-a84776f4c654}"
case "{emssettings}" TranslateWellKnownToGUID = "{0ce4991b-e6b3-4b16-b23c-5e0d9250e5d9}"
case "{globalsettings}" TranslateWellKnownToGUID = "{7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e}"
case "{resumeloadersettings}" TranslateWellKnownToGUID = "{1afa9c49-16ab-4a5c-901b-212802da9460}"
case else TranslateWellKnownToGUID = sGUID
End select
End function
Public Function TranslateElementTypes ( iElementType )
Select case iElementType
case &h11000001 TranslateElementTypes = "ApplicationDevice"
case &h12000002 TranslateElementTypes = "ApplicationPath"
case &h12000004 TranslateElementTypes = "Description"
case &h12000005 TranslateElementTypes = "PreferredLocale"
case &h14000006 TranslateElementTypes = "InheritedObjects"
case &h15000007 TranslateElementTypes = "TruncatePhysicalMemory"
case &h14000008 TranslateElementTypes = "RecoverySequence"
case &h16000009 TranslateElementTypes = "AutoRecoveryEnabled"
case &h1700000a TranslateElementTypes = "BadMemoryList"
case &h1600000b TranslateElementTypes = "AllowBadMemoryAccess"
case &h1500000c TranslateElementTypes = "FirstMegabytePolicy"
case &h16000010 TranslateElementTypes = "DebuggerEnabled"
case &h15000011 TranslateElementTypes = "DebuggerType"
case &h15000012 TranslateElementTypes = "SerialDebuggerPortAddress"
case &h15000013 TranslateElementTypes = "SerialDebuggerPort"
case &h15000014 TranslateElementTypes = "SerialDebuggerBaudRate"
case &h15000015 TranslateElementTypes = "1394DebuggerChannel"
case &h12000016 TranslateElementTypes = "UsbDebuggerTargetName"
case &h16000017 TranslateElementTypes = "DebuggerIgnoreUsermodeExceptions"
case &h15000018 TranslateElementTypes = "DebuggerStartPolicy"
case &h16000020 TranslateElementTypes = "EmsEnabled"
case &h15000022 TranslateElementTypes = "EmsPort"
case &h15000023 TranslateElementTypes = "EmsBaudRate"
case &h12000030 TranslateElementTypes = "LoadOptionsString"
case &h16000040 TranslateElementTypes = "DisplayAdvancedOptions"
case &h16000041 TranslateElementTypes = "DisplayOptionsEdit"
case &h16000046 TranslateElementTypes = "GraphicsModeDisabled"
case &h15000047 TranslateElementTypes = "ConfigAccessPolicy"
case &h16000049 TranslateElementTypes = "AllowPrereleaseSignatures"
case &h24000001 TranslateElementTypes = "DisplayOrder"
case &h24000002 TranslateElementTypes = "BootSequence"
case &h23000003 TranslateElementTypes = "DefaultObject"
case &h25000004 TranslateElementTypes = "Timeout"
case &h26000005 TranslateElementTypes = "AttemptResume"
case &h23000006 TranslateElementTypes = "ResumeObject"
case &h24000010 TranslateElementTypes = "ToolsDisplayOrder"
case &h21000022 TranslateElementTypes = "BcdDevice"
case &h22000023 TranslateElementTypes = "BcdFilePath"
case &h35000001 TranslateElementTypes = "RamdiskImageOffset"
case &h35000002 TranslateElementTypes = "TftpClientPort"
case &h31000003 TranslateElementTypes = "SdiDevice"
case &h32000004 TranslateElementTypes = "SdiPath"
case &h35000005 TranslateElementTypes = "RamdiskImageLength"
case &h25000001 TranslateElementTypes = "PassCount"
case &h25000003 TranslateElementTypes = "FailureCount"
case &h21000001 TranslateElementTypes = "OSDevice"
case &h22000002 TranslateElementTypes = "SystemRoot"
case &h23000003 TranslateElementTypes = "AssociatedResumeObject"
case &h26000010 TranslateElementTypes = "DetectKernelAndHal"
case &h22000011 TranslateElementTypes = "KernelPath"
case &h22000012 TranslateElementTypes = "HalPath"
case &h22000013 TranslateElementTypes = "DbgTransportPath"
case &h25000020 TranslateElementTypes = "NxPolicy"
case &h25000021 TranslateElementTypes = "PAEPolicy"
case &h26000022 TranslateElementTypes = "WinPEMode"
case &h26000024 TranslateElementTypes = "DisableCrashAutoReboot"
case &h26000025 TranslateElementTypes = "UseLastGoodSettings"
case &h26000027 TranslateElementTypes = "AllowPrereleaseSignatures"
case &h26000030 TranslateElementTypes = "NoLowMemory"
case &h25000031 TranslateElementTypes = "RemoveMemory"
case &h25000032 TranslateElementTypes = "IncreaseUserVa"
case &h26000040 TranslateElementTypes = "UseVgaDriver"
case &h26000041 TranslateElementTypes = "DisableBootDisplay"
case &h26000042 TranslateElementTypes = "DisableVesaBios"
case &h25000050 TranslateElementTypes = "ClusterModeAddressing"
case &h26000051 TranslateElementTypes = "UsePhysicalDestination"
case &h25000052 TranslateElementTypes = "RestrictApicCluster"
case &h26000060 TranslateElementTypes = "UseBootProcessorOnly"
case &h25000061 TranslateElementTypes = "NumberOfProcessors"
case &h26000062 TranslateElementTypes = "ForceMaximumProcessors"
case &h25000063 TranslateElementTypes = "ProcessorConfigurationFlags"
case &h26000070 TranslateElementTypes = "UseFirmwarePciSettings"
case &h26000071 TranslateElementTypes = "MsiPolicy"
case &h25000080 TranslateElementTypes = "SafeBoot"
case &h26000081 TranslateElementTypes = "SafeBootAlternateShell"
case &h26000090 TranslateElementTypes = "BootLogInitialization"
case &h26000091 TranslateElementTypes = "VerboseObjectLoadMode"
case &h260000a0 TranslateElementTypes = "KernelDebuggerEnabled"
case &h260000a1 TranslateElementTypes = "DebuggerHalBreakpoint"
case &h260000b0 TranslateElementTypes = "EmsEnabled"
case &h250000c1 TranslateElementTypes = "DriverLoadFailurePolicy"
case &h250000E0 TranslateElementTypes = "BootStatusPolicy"
case else
TranslateElementTypes = hex(iElementType)
End Select
End function
Public Function TestObject(sObjectGUID)
Dim oObject
on error resume next
TestOBject = FALSE
TestObject = oBCDStore.OpenObject(TranslateWellKnownToGUID(sObjectGUID),oObject)
on error goto 0
End function
Public Function OpenObject(sObjectGUID)
TestAndLog oBCDStore.OpenObject(TranslateWellKnownToGUID(sObjectGUID),OpenObject), "OpenObject(" & sObjectGUID & ")"
End function
Public Function GetSystemPartition
TestAndLog oBCDStore.GetSystemPartition(GetSystemPartition), "GetSystemPartition = " & GetSystemPartition
End function
Public Function GetSystemDisk
TestAndLog oBCDStore.GetSystemDisk(GetSystemDisk), "GetSystemDisk = " & GetSystemDisk
End function
Public Function GetElement( oBCDStoreObject, oItem )
Dim bResult
on error resume next
bResult = oBCDStoreObject.GetElement( oItem, GetElement )
If Err <> 0 or not bResult then
CreateEntry oEnvironment.Substitute( "FAILURE (Err): " & FormatError(Err) & ": " & "GetElement = 0x" & hex(oItem) ), LogTypeWarning
End if
on error goto 0
End function
Public Function EnumerateObjects ( sEnumType )
Dim bResult
on error resume next
bResult = oBCDStore.EnumerateObjects( sEnumType, EnumerateObjects )
TestAndLog bResult, "Enumerate Objects"
on error goto 0
If not bResult or isempty(bResult) then
bResult = array()
End if
End function
Public Function EnumerateElementTypes( oStoreObject )
Dim bResult
on error resume next
bResult = oStoreObject.EnumerateElementTypes( EnumerateElementTypes )
TestAndLog bResult, "EnumerateElementTypes"
on error goto 0
If not bResult or isempty(bResult) then
bResult = array()
End if
End function
Public Function EnumerateElements( oStoreObject )
Dim bResult
on error resume next
bResult = oStoreObject.EnumerateElements( EnumerateElements )
TestAndLog bResult, "EnumerateElements"
on error goto 0
If not bResult or isempty(bResult) then
bResult = array()
End if
End function
Function GetCurrentGUID
Dim oObject
If isempty(g_sCurrent) then
set oObject = OpenObject("{9dea862c-5cdd-4e70-acc1-f32b344d4795}")
TestAndLog not oObject is nothing, "OpenObject({9dea862c-5cdd-4e70-acc1-f32b344d4795})"
g_sCurrent = GetElement( oObject, &h23000003 ).ID
End if
GetCurrentGUID = g_sCurrent
End function
Private Sub DumpBCDObjectStore ( oBCDStoreObject )
Dim oItem
for each oItem in EnumerateElementTypes( oBCDStoreObject )
oLogging.CreateEntry TranslateElementTypes(oItem) & " = " & DumpBCDElement ( GetElement(oBCDStoreObject,oItem) ), LogTypeInfo
next
End Sub
Private Function DumpBCDElement( oElement )
Dim oSubProp
Dim oSubSubProp
Dim Value
for each oSubProp in oElement.Properties_
Select case uCase(oSubProp.Name)
case "TYPE", "OBJECTID", "STOREFILEPATH"
case "STRING"
DumpBCDElement = oELement.String
exit for
case "ID"
DumpBCDElement = oELement.ID
exit for
case "BOOLEAN"
DumpBCDElement = oELement.Boolean
exit for
case "INTEGER"
DumpBCDElement = oELement.Integer
exit for
case "IDS"
DumpBCDElement = ostrings.ForceAsString(oELement.IDs)
exit for
case "INTEGERS"
DumpBCDElement = ostrings.ForceAsString(oELement.INtegers)
exit for
case "DEVICE"
for each oSubSubProp in oSubProp.Value.Properties_
Select Case uCase(oSubSubProp.Name)
Case "ADDITIONALOPTIONS", "DEVICETYPE"
Case else
DumpBCDElement = ostrings.ForceAsString(oSubSubProp.value)
End Select
next
case else
oLogging.CreateEntry vbTab & oSubProp.Name & " = " & Value, LogTypeInfo
End Select
next
DumpBCDElement = TranslateGUIDToWellKnown(DumpBCDElement)
End function
Public Function DumpBCDStore
Dim oItem
DumpBCDObjectStore OpenObject(TranslateWellKnownToGUID("{bootmgr}"))
for each oItem in EnumerateObjects( &h10300006 )
DumpBCDObjectStore oItem
next
for each oItem in EnumerateObjects( &h10200003 )
DumpBCDObjectStore oItem
next
End function
End class