Files

1331 lines
42 KiB
XML

<job id="ZTIDrivers">
<script language="VBScript" src="ZTIUtility.vbs"/>
<script language="VBScript" src="ZTICOnfigFile.vbs"/>
<script language="VBScript">
' // ***************************************************************************
' //
' // Copyright (c) Microsoft Corporation. All rights reserved.
' //
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File: ZTIDrivers.wsf
' //
' // Version: 6.3.8456.1000
' //
' // Purpose: Inject needed drivers
' //
' // Usage: cscript ZTIDrivers.wsf [/debug:true]
' //
' // ***************************************************************************
Option Explicit
RunNewInstance
'//----------------------------------------------------------------------------
'// Main Class
'//----------------------------------------------------------------------------
Class ZTIDrivers
'//----------------------------------------------------------------------------
'// Global constant and variable declarations
'//----------------------------------------------------------------------------
Dim sArchitecture ' Target Platform Type, either x86 or x64
Dim sPlatformDir ' Target Platform Dir, either i386 or amd64
Dim sTargetBuild ' Target Build, 6 or 5
Dim sGroupList
Dim sDestinationDrive
' Global Drivers ConfigObject
Private oXMLDrivers
Private g_dAllDrivers
Private g_dFilteredDrivers
Private g_dAllPnPIDs
Private g_sDriversDir
'//----------------------------------------------------------------------------
'// Constructor to initialize needed global objects
'//----------------------------------------------------------------------------
Private Sub Class_Initialize
g_sDriversDir = ""
sTargetBuild = Left(oEnvironment.Item("ImageBuild"), 1)
sGroupList = "DriverGroup"
g_dAllDrivers = empty
g_dFilteredDrivers = empty
g_dAllPnPIDs = empty
' Determine the architecture of drivers to inject
If UCase(oEnvironment.Item("OSDPLATFORMARCH")) = "AMD64" then
sArchitecture = "X64"
sPlatformDir = "amd64"
ElseIf UCase(oEnvironment.Item("OSDPLATFORMARCH")) = "X86" then
sArchitecture = "X86"
sPlatformDir = "i386"
ElseIf oEnvironment.Item("ImageProcessor") <> "" then
sArchitecture = UCase(oEnvironment.Item("ImageProcessor"))
If UCase(sArchitecture) = "X64" then
sPlatformDir = "amd64"
Else
sPlatformDir = "i386"
End if
Else
sArchitecture = UCase(oEnvironment.Item("ARCHITECTURE"))
If UCase(sArchitecture) = "X64" then
sPlatformDir = "amd64"
Else
sPlatformDir = "i386"
End if
End If
oLogging.CreateEntry "Processing drivers for an " & sArchitecture & " operating system.", LogTypeInfo
End Sub
'//----------------------------------------------------------------------------
'// Main routine
'//----------------------------------------------------------------------------
Function Main
' Local Variables
Dim oItem
Dim oPath
Dim sSource
Dim sGUID
Dim iCurrent, iTotal, iPercent
Main = Success
sDestinationDrive = oUtility.GetOSTargetDriveLetter
' ---------------------------------------------------------------------------
' Abort if there is nothing to do at this point
' ---------------------------------------------------------------------------
If oEnvironment.Item("DeploymentMethod") = "OSD" and oEnvironment.Item("PHASE") = "PREINSTALL" then
oLogging.CreateEntry "No driver actions need to be taken during the OSD preinstall phase.", LogTypeInfo
Exit function
End if
' ---------------------------------------------------------------------------
' Point of no return...if you upgrade from X86 to X64 this WILL delete all the drivers
' ---------------------------------------------------------------------------
If UCase(oEnvironment.Item("DriverCleanup")) <> "DONE" Then
oEnvironment.Item("DriverCleanup") = "DONE"
oLogging.CreateEntry "Compare Image processor Type with Original ["& oEnvironment.Item("OriginalArchitecture") & "] = [" & sArchitecture & "].", LogTypeInfo
If ucase(oEnvironment.Item("OriginalArchitecture")) <> ucase(sArchitecture) and oEnvironment.Item("OriginalArchitecture") <> "" Then
If oFSO.FolderExists( sDestinationDrive & "\Drivers" ) Then
oFileHandling.RemoveFolder( sDestinationDrive & "\Drivers")
oLogging.CreateEntry "Remove folder: " & sDestinationDrive & "\Drivers" , LogTypeInfo
End if
End if
End if
' ---------------------------------------------------------------------------
' Load Driver Configuraiton Files, and perform basic parsing
' ---------------------------------------------------------------------------
set oXMLDrivers = new ConfigFile
oXMLDrivers.sFileType = "Drivers"
oXMLDrivers.sSelectionProfile = oEnvironment.Item("DriverSelectionProfile")
oXMLDrivers.sCustomSelectionProfile = oEnvironment.Item("CustomDriverSelectionProfile")
oXMLDrivers.bMustSucceed = false
' ---------------------------------------------------------------------------
' Load Driver Configuraiton Files, and perform basic parsing
' ---------------------------------------------------------------------------
If ucase(oEnvironment.Item("DriverInjectionMode")) = "ALL" then
' ---------------------------------------------------------------------------
' Enumerate through all drivers
' ---------------------------------------------------------------------------
iTotal = dFilteredDrivers.Count
iCurrent = 0
for each oItem in dFilteredDrivers.Items
iCurrent = iCurrent + 1
If PlatformCheck ( oItem ) then
iPercent = CInt((iCurrent / iTotal) * 100)
CopySingleDriver oItem.attributes.getNamedItem("guid").value, "Device", False, iPercent
End if
next
UpdateConfiguration
ElseIf oEnvironment.Item("DeploymentMethod") <> "OSD" and oEnvironment.Item("PHASE") = "POSTINSTALL" then
oLogging.CreateEntry "No driver copying needs to be performed during the Lite Touch postinstall phase.", LogTypeInfo
' Downlevel OS configuration is necessary to update the XP DevicePath after the image has been applied
UpdateConfiguration
ElseIf oEnvironment.Item("DoCapture") = "YES" and oEnvironment.Item("PHASE") = "STATERESTORE" then
oLogging.CreateEntry "Prepare machine for Sysprep.", LogTypeInfo
If ucase(right(oEnvironment.Item("InstallFromPath"),4)) = ".WIM" then
oLogging.CreateEntry "No driver actions can be taken for OS Images installed from *.wim files.", LogTypeInfo
Exit function
End if
oXMLDrivers.xPathFilter = "/*/*[ ( Class = 'SCSIAdapter' or Class = 'hdc' ) and " & oXMLDrivers.XPathFilterString( oXMLDrivers.bEnabled, oXMLDrivers.bHidden ) & "]"
oXMLDrivers.sSelectionProfile = oEnvironment.Item("SysPrepDriverSelectionProfile")
sGroupList = "StorageDriverSysPrepGroup"
Main = MarkupTextFilesSysPrep( dFilteredDrivers )
Else
oLogging.CreateEntry "Copying any drivers that may be needed for this computer into Target.", LogTypeInfo
' ---------------------------------------------------------------------------
' Look for drivers for the devices
' ---------------------------------------------------------------------------
CopyDrivers "/devices/device", FALSE
' ---------------------------------------------------------------------------
' Now copy any folders specified via DriverPaths list (BDD 2.5 parity)
' ---------------------------------------------------------------------------
For each oItem in oEnvironment.ListItem("DriverPaths")
Main = CopyDriverDir(oItem, "." )
If Main <> SUCCESS then
exit for
End if
Next
UpdateConfiguration
' ---------------------------------------------------------------------------
' If there are any SCSI or IDE drivers installed, then markup for Windows 5.x
' ---------------------------------------------------------------------------
If sTargetBuild = 5 then
oLogging.CreateEntry "Check for Storage Drivers.", LogTypeInfo
If ucase(right(oEnvironment.Item("InstallFromPath"),4)) = ".WIM" then
oLogging.CreateEntry "No driver actions can be taken for OS Images installed from *.wim files.", LogTypeInfo
Else
MarkupWinNTTextFiles
End if
End if
End if
End Function
'//---------------------------------------------------------------------------
'//
'// Purpose: Update OS configuration files for downlevel OS deployments
'//
'//---------------------------------------------------------------------------
Function UpdateConfiguration
Dim sSysprepInf
Dim sUnattendTxt
Dim iRetVal
sSysprepInf = ""
sUnattendTxt = ""
oLogging.CreateEntry "Updating downlevel OS configuration.", LogTypeInfo
' ---------------------------------------------------------------------------
' Update device path entries
' ---------------------------------------------------------------------------
If sTargetBuild <> 5 then
oLogging.CreateEntry "Vista identified, skipping update of Device Path", LogTypeInfo
Else
If oEnvironment.Item("OSDAnswerFilePathSysprep") = "" Then
iRetVal = oUtility.FindSysPrepAnswerFile
End If
IF oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePathSysPrep")) = False Then
iRetVal = oUtility.FindSysPrepAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
' If an unattend.txt or sysprep.inf file exist, update them with driver information
If oEnvironment.Item("OSDAnswerFilePathSysprep") <> "" then
sSysprepInf = oEnvironment.Item("OSDAnswerFilePathSysprep")
UpdateOEMPath sSysprepInf
End If
If oEnvironment.Item("OSDAnswerFilePath") = "" Then
iRetVal = oUtility.FindUnattendAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
IF oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePath")) = False Then
iRetVal = oUtility.FindUnattendAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
If oEnvironment.Item("OSDAnswerFilePath") <> "" then
sUnattendTxt = oEnvironment.Item("OSDAnswerFilePath")
UpdateOEMPath sUnattendTxt
End If
If sSysprepInf <> "" then
UpdateDevicePath Left(sSysprepInf, 2)
ElseIf sUnattendTxt <> "" then
UpdateDevicePath Left(sUnattendTxt, 2)
Else
UpdateDevicePath sDestinationDrive
End If
End If
UpdateConfiguration = Success
End Function
'//---------------------------------------------------------------------------
'//
'// Purpose: Find a driver that matches the specified PnP ID
'//
'//---------------------------------------------------------------------------
Function CopyDrivers(sXPath, fVerifyOEM)
Dim bAnyFound
Dim sFirstPnPID
Dim oItem
Dim sGuidCollection
Dim oPnPID
Dim sGUID
Dim oNodes
Dim iCurrent, iTotal, iPercent
Set oNodes = oLocalPNPIDs(sXPath)
iTotal = oNodes.length
iCurrent = 0
For each oItem in oNodes
bAnyFound = FALSE
sFirstPnPID = ""
iCurrent = iCurrent + 1
For each oPnPID in oItem.childnodes
If sFirstPnPID = "" then
sFirstPnPID = oPNPID.text
End if
If not dFilteredPnPIDs.Exists(oPNPID.text) then
' oLogging.CreateEntry vbTab & "Skipping Device " & oPNPID.text& " No 3rd party drivers found.", LogTypeVerbose
Else
bAnyFound = TRUE
sGuidCollection = dFilteredPnPIDs.Item(oPNPID.text)
oLogging.CreateEntry vbTab & "Found Device " & oPNPID.text & " with 3rd party drivers! Count = " & ubound(split(sGuidCollection,vbTab)) & " = " & sGuidCollection, LogTypeInfo
for each sGUID in split(sGuidCollection,vbTab)
iPercent = CInt((iCurrent / iTotal) * 100)
CopySingleDriver sGUID, oPNPID.text, fVerifyOEM, iPercent
next
End if
next
if not bAnyFound and oItem.childnodes.length > 0 then
oLogging.CreateEntry "Skipping Device " & sFirstPnPID & " No 3rd party drivers found. " & oItem.childnodes.length, LogTypeInfo
end if
Next
End function
'//---------------------------------------------------------------------------
'//
'// Purpose: Copy a single driver locally
'//
'//---------------------------------------------------------------------------
Function CopySingleDriver(sGUID, sPnPID, fVerifyOEM, iPercent)
Dim oParent
Dim sSource
Dim oSource
TestAndFail dAllDrivers.Exists(sGUID),7901,"AllDrivers.Exists(" & sGUID & ")"
set oParent = dAllDrivers.Item(sGUID)
set oSource = oParent.SelectSingleNode("./Source")
if oSource is nothing then
oLogging.CreateEntry "Driver path not found in XML: " & sGuid, LogTypeWarning
Else
sSource = oEnvironment.Item("ResourceRoot") & Mid(oSource.text, 2)
oLogging.CreateEntry "Found a driver for " & sPnPID & ": " & sGUID & " from " & sSource, LogTypeInfo
sSource = oFSO.GetParentFolderName(sSource)
If not PlatformCheck(oParent) then
oLogging.CreateEntry "Skipping driver " & sGUID & " because it is not for this platform (driver " & oUtility.SelectSingleNodeString(oParent,"Platform") & " != OS platform " & sArchitecture & ")", LogTypeInfo
Elseif fVerifyOEM and not oFSO.FileExists( sSource & "\TxtSetup.oem" ) then
oLogging.CreateEntry "DriverPackage is missing txtsetup.oem : " & sSource & "\TxtSetup.oem" , LogTypeInfo
Elseif fVerifyOEM then
oLogging.ReportProgress "Copying OEM driver: " & oParent.SelectSingleNode("./Name").Text, iPercent
oLogging.CreateEntry "Copy: " & sSource & " To: " & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE", LogTypeInfo
oUtility.RunWithHeartbeat "cmd.exe /c xcopy /ieryh """ & sSource & """ """ & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE"" 1> NUL 2>NUL"
' Windows XP/2003 *may* have problems finding binaries at the $OEM$\TextMode location, copying them to $OEM$\ should help.
oUtility.RunWithHeartbeat "cmd.exe /c xcopy /ieryh """ & sSource & """ """ & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$"" 1> NUL 2>NUL"
Else
oLogging.ReportProgress "Copying driver: " & oParent.SelectSingleNode("./Name").Text, iPercent
CopyDriverDir sSource, Mid(sSource, Instr(sSource, "Out-of-box Drivers\") + 19)
End if
End If
End function
'//---------------------------------------------------------------------------
'//
'// Function: UpdateOEMPath()
'//
'// Input: none
'//
'// Return: Success - 0
'// Failure - 1
'//
'// Purpose: Update the OemPnpDriversPath entry in the specified file
'//
'//---------------------------------------------------------------------------
Function UpdateOEMPath(sConfigurationFile)
Dim dicDriverPaths
Dim sCurrentPath
Dim sTmp
' Initialization
Set dicDriverPaths = CreateObject("Scripting.Dictionary")
dicDriverPaths.CompareMode = TextCompare
' Get the current list of driver paths from the specified file
' Strip out any tab characters
sCurrentPath = oUtility.ReadIni(sConfigurationFile, "Unattended", "OemPnPDriversPath")
sCurrentPath = trim(replace(sCurrentPath, vbTab, "", 1, -1, vbTextCompare))
oLogging.CreateEntry "Original " & sConfigurationFile & " section [Unattended] OemPnPDriversPath=" & sCurrentPath, LogTypeInfo
' Split into the component paths
If Len(sCurrentPath) = 0 then
oLogging.CreateEntry sConfigurationFile & " did not contain an OemPnPDriversPath entry.", LogTypeInfo
ElseIf Left(sCurrentPath,1) = """" and Right(sCurrentPath,1) = """" then
sCurrentPath = Mid(sCurrentPath,2,Len(sCurrentPath)-2) ' Remove quotes, we'll put them back later
ElseIf Left(sCurrentPath,1) = """" then
sCurrentPath = Mid(sCurrentPath,2) ' Remove quotes, we'll put them back later
ElseIf Right(sCurrentPath,1) = """" then
sCurrentPath = Mid(sCurrentPath,1,Len(sCurrentPath)-1) ' Remove quotes, we'll put them back later
End If
For each sTmp in Split(sCurrentPath, ";")
If not dicDriverPaths.Exists(sTmp) then
dicDriverPaths.Add sTmp, ""
End If
Next
' Add the list of paths found in the Drivers directory
If oFSO.FolderExists( sDestinationDrive & "\Drivers") then
oLogging.CreateEntry "Checking """ & sDestinationDrive & "\Drivers"" for driver directories to add", LogTypeInfo
GetDriverPaths dicDriverPaths, sDestinationDrive & "\Drivers", True
Else
oLogging.CreateEntry "Driver directory """ & sDestinationDrive & "\Drivers"" does not exist, creating it.", LogTypeInfo
On Error Resume Next
fso.CreateFolder sDestinationDrive & "\Drivers"
On Error Goto 0
End If
' Build the new path and write it back to the Sysprep.inf
sCurrentPath = ""
for each sTmp in dicDriverPaths.Keys
If trim(sTmp) <> "" then
oStrings.AddToList sCurrentPath, sTmp, ";"
End if
next
oUtility.WriteIni sConfigurationFile, "Unattended", "OemPnPDriversPath", """" & sCurrentPath & """"
oLogging.CreateEntry "Updated " & sConfigurationFile & " section [Unattended] with OemPnPDriversPath=" & sCurrentPath, LogTypeInfo
'UpdateOEMPath = iRetVal
End Function
'//---------------------------------------------------------------------------
'//
'// Function: UpdateDevicePath()
'//
'// Input: sSystemDrive - drive letter (e.g. C:) containing Windows
'//
'// Return: Success - 0
'// Failure - 1
'//
'// Purpose: Update the DevicePath registry key with the Driver directories.
'//
'//---------------------------------------------------------------------------
Function UpdateDevicePath(sSystemDrive)
Dim bFound
Dim sCurrentPath
Dim sTmp
Dim dicDevicePaths
Dim sNewPath
Dim sDir
Dim iRetVal
oLogging.CreateEntry "------ Updating DevicePath Registry Value ------", LogTypeInfo
'Create Drivers Directory
If g_sDriversDir = "" Then
g_sDriversDir = sDestinationDrive & "\Drivers"
oUtility.VerifyPathExists g_sDriversDir
oFSO.GetFolder(g_sDriversDir).Attributes = 2 ' Make the folder hidden
End If
' Find the "software" hive
bFound = False
For each sDir in oFSO.GetFolder(sSystemDrive & "\").Subfolders
If oFSO.FileExists(sDir & "\system32\config\software") then
oLogging.CreateEntry "Trying to load registry file " & sDir & "\system32\config\software", LogTypeInfo
iRetVal = oUtility.RunWithHeartbeat("reg load HKLM\NewOS """ & sDir & "\system32\config\software""")
If iRetVal = SUCCESS then
bFound = True
exit for
End if
End If
Next
If not bFound then
oLogging.CreateEntry "Unable to find the new OS registry file; DevicePath cannot be updated.", LogTypeInfo
UpdateDevicePath = Success
EXIT FUNCTION
End If
' Get the current DevicePath registry key
Set dicDevicePaths = CreateObject("Scripting.Dictionary")
dicDevicePaths.CompareMode = TextCompare
sCurrentPath = trim(oShell.RegRead("HKEY_LOCAL_MACHINE\NewOS\Microsoft\Windows\CurrentVersion\DevicePath"))
oLogging.CreateEntry "Original DevicePath=" & sCurrentPath, LogTypeInfo
For each sTmp in Split(sCurrentPath, ";")
If not dicDevicePaths.Exists(sTmp) then
dicDevicePaths.Add sTmp, ""
End If
Next
' Add the list of paths found in the Drivers directory (use the same drive letter as Sysprep.inf)
If oFSO.FolderExists(sSystemDrive & "\Drivers") then
oLogging.CreateEntry "Checking """ & sSystemDrive & "\Drivers"" for driver directories to add", LogTypeInfo
GetDriverPaths dicDevicePaths, sSystemDrive & "\Drivers", False
Else
oLogging.CreateEntry "Driver directory """ & sSystemDrive & "\Drivers"" not found, impossible to add driver paths.", LogTypeWarning
UpdateDevicePath = Failure
EXIT FUNCTION
End If
' Build the new path and write it back to the Sysprep.inf
sNewPath = ""
for each sTmp in dicDevicePaths.Keys
oStrings.AddToList sNewPath, sTmp, ";"
next
oShell.RegWrite "HKEY_LOCAL_MACHINE\NewOS\Microsoft\Windows\CurrentVersion\DevicePath", sNewPath, "REG_EXPAND_SZ"
oLogging.CreateEntry "Updated DevicePath=" & sNewPath, LogTypeInfo
' Unload the registry file
oShell.Run "reg unload HKLM\NewOS", 0, true
UpdateDevicePath = Success
End Function
'//---------------------------------------------------------------------------
'//
'// Function: MarkupWinNTTextFiles()
'//
'// Purpose: Markup TxtSetup.OEM and Unattend.txt
'//
'//---------------------------------------------------------------------------
Function MarkupWinNTTextFiles
Dim sDestTxtSetupDisks
Dim sDestTxtSetup
Dim sDestTxtSetupSCSI
Dim sUnattendTxt
Dim oListSCSI
Dim oListFiles
Dim oDriversImported
Dim iRetVal
Dim oItem
Dim f
Dim sLine
Dim sTrimLine
set oListSCSI = CreateObject("Scripting.Dictionary")
set oListFiles = CreateObject("Scripting.Dictionary")
set oDriversImported = CreateObject("Scripting.Dictionary")
oListSCSI.CompareMode = vbTextCompare
oListFiles.CompareMode = vbTextCompare
oDriversImported.CompareMode = vbTExtCompare
sDestTxtSetupDisks = ""
sDestTxtSetup = ""
sDestTxtSetupSCSI = ""
oXMLDrivers.xPathFilter = "/*/*[ ( Class = 'SCSIAdapter' or Class = 'hdc' ) and " & oXMLDrivers.XPathFilterString( oXMLDrivers.bEnabled, oXMLDrivers.bHidden ) & "]"
sGroupList = "StorageDriverGroup"
g_dFilteredDrivers = empty
set g_dAllPnPIDs = nothing
g_dAllPnPIDs = empty
CopyDrivers "/devices/device[not(CompatibleID = 'PCI\CC_0101') or not(CompatibleID)]/*", True
for each oItem in oLocalPNPIDs("/devices/device[not(CompatibleID = 'PCI\CC_0101') or not(CompatibleID)]/*")
If dFilteredPnPIDs.Exists(oItem.text) then
MarkupTextFilesWinNT dFilteredPnPIDs.Item(oItem.text), oListSCSI, oListFiles, sDestTxtSetupDisks, sDestTxtSetup, sDestTxtSetupSCSI, oDriversImported
End if
next
' ---------------------------------------------------------------------------
' Write out the TxtSetup.OEM file to the target location
' ---------------------------------------------------------------------------
If sDestTxtSetupDisks = "" and sDestTxtSetupSCSI = "" and sDestTxtSetup = "" then
oLogging.CreateEntry "MarkupTextFilesWinNT: No files to process", LogTypeInfo
Exit Function
End if
oLogging.CreateEntry "Create target file: " & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE\TXTSetup.OEM", LogTypeInfo
oUtility.VerifyPathExists oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE"
oUtility.RunWithHeartbeat "attrib -r """ & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE\TXTSetup.OEM"""
set f = oFSO.CreateTextFile(oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE\TXTSetup.OEM",True)
f.WriteLine "[Disks]" & sDestTxtSetupDisks
f.WriteLine "[scsi]" & sDestTxtSetupSCSI
f.WriteLine sDestTxtSetup
f.Close
set f = nothing
' ---------------------------------------------------------------------------
' Add the appropriate lines to the unattend.txt file to the target location
' ---------------------------------------------------------------------------
If oEnvironment.Item("OSDAnswerFilePath") = "" Then
iRetVal = oUtility.FindUnattendAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
IF oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePath")) = False Then
iRetVal = oUtility.FindUnattendAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
sUnattendTxt = oEnvironment.Item("OSDAnswerFilePath")
oLogging.CreateEntry "Markup file: " & sUnattendTxt, LogTypeInfo
oUtility.WriteIni sUnattendTxt, "MassStorageDrivers", "",""
oUtility.WriteIni sUnattendTxt, "OEMBootFiles", "",""
set f = oFSO.OpenTextFile(sUnattendTxt,ForAppending,False)
f.WriteLine "[OEMBootFiles]"
for each sLine in oListFiles.keys
sTrimLine = ucase(mid(sLine,instr(1,sLine,".",vbTextCompare)+1))
if sTrimLine <> "SYS" and sTrimLine <> "INF" and sTrimLine <> "CAT" then
' In accordance with Microsoft KB Article q275334, we will move these files. Do not write to unattend.txt.
oLogging.CreateEntry "Copy file: " & sLine, LogTypeInfo
oUtility.VerifyPathExists oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\$$\OEMDIR"
oFileHandling.CopyFile oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\TEXTMODE\" & sLine, oUtility.LocalRootPath & "\source\" & sPlatformDir & "\$OEM$\$$\OEMDIR\" , TRUE
else
f.WriteLine sLine
end if
next
f.WriteLine "TXTSetup.OEM"
f.WriteLine ""
f.WriteLine "[MassStorageDrivers]"
for each sLine in oListSCSI.keys
if sLine <> "" then
f.WriteLine sLine + " = OEM"
end if
next
' Write a fallback entry
WriteFallbackEntry f
' Cleanup
f.Close
set f = nothing
'Only Create the bak file if debugging
If oLogging.Debug then
oFSO.CopyFile sUnattendTxt,sUnattendTxt & ".bak", TRUE
End If
End function
'//---------------------------------------------------------------------------
'//
'// Function: WriteFallbackEntry()
'//
'// Purpose: Write a mass storage driver fallback entry to Unattend.txt
'//
'//---------------------------------------------------------------------------
Function WriteFallbackEntry(f)
Dim sFallback
Dim sSif
' If we can't find the txtsetup.sif file, bail out
sSif = oEnvironment.Item("SourcePath") & "\" & sPlatformDir & "\txtsetup.sif"
If not oFSO.FileExists(sSif) then
oLogging.CreateEntry "Unable to find the TXTSETUP.SIF file needed to find the localized string for the default IDE controller. No fallback entry will be created.", LogTypeInfo
Exit Function
End if
' Read the entry
sFallback = Trim(oUtility.ReadIni(sSif, "SCSI", "atapi"))
If sFallback = "" then
oLogging.CreateEntry "Unable to find the SCSI atapi entry in " & oUtility.LocalRootPath & "\source\" & sPlatformDir & "\TXTSETUP.SIF. No fallback entry will be created.", LogTypeInfo
Exit Function
End if
' Write the entry
oLogging.CreateEntry "Writing fallback entry in unattend.txt:", LogTypeInfo
oLogging.CreateEntry sFallback & " = RETAIL", LogTypeInfo
f.WriteLine sFallback & " = RETAIL"
End function
'//---------------------------------------------------------------------------
'//
'// Function: MarkupTextFiles()
'//
'// Purpose: Markup TxtSetup.OEM and Unattend.txt
'//
'//---------------------------------------------------------------------------
Function MarkupTextFilesWinNT ( oStorageGUIDs, ByRef oListSCSI, ByRef oListFiles, ByRef sDestTxtSetupDisks, ByRef sDestTxtSetup, ByRef sDestTxtSetupSCSI, byRef oDriversImported )
Dim sTxtSetOEM
Dim sGuid
Dim oListFilesPackage
Dim f
Dim sLine
Dim sTrimLine
Dim fIsFirst
Dim sSectionName
Dim sExtName
Dim oItem
MarkupTextFilesWinNT = Success
fIsFirst = True
oLogging.CreateEntry "MarkupTextFilesWinNT: " & oStorageGUIDs, LogTypeInfo
set oListFilesPackage = CreateObject("Scripting.Dictionary")
oListFilesPackage.CompareMode = vbTextCompare
' ---------------------------------------------------------------------------
' Read each TxtSetup.OEM file from oDrivers
' ---------------------------------------------------------------------------
for each sGuid in split( oStorageGUIDs , vbTab )
TestAndFail dAllDrivers.Exists(sGUID),7904,"AllDrivers.Exists(" & sGUID & ")"
set oItem = dAllDrivers.Item(sGUID)
sTxtSetOEM = oUtility.SelectSingleNodeString(oItem,"./Source")
sTxtSetOEM = oEnvironment.Item("ResourceRoot") & Mid(ofso.GetParentFolderName ( sTxtSetOEM ), 2) & "\TxtSetup.oem"
If not oFSO.FileExists( sTxtSetOEM ) then
oLogging.CreateEntry "FileMissing, Skip: " & sTxtSetOEM, LogTypeInfo
ElseIf not PlatformCheck(oItem) then
oLogging.CreateEntry "Skipping driver " & sGUID & " because it is not for this platform (driver " & oUtility.SelectSingleNodeString(oItem,"Platform") & " != OS platform " & sArchitecture & ")", LogTypeInfo
ElseIf oDriversImported.Exists(sTxtSetOEM) then
oLogging.CreateEntry "Driver has already been imported: " & sTxtSetOEM, LogTypeInfo
Else
oLogging.CreateEntry "Markup(" & fIsFirst & "): " & sGuid & " -> " & sTxtSetOEM, LogTypeInfo
oListFilesPackage.RemoveAll
oDriversImported.Add sTxtSetOEM,""
set f = oFSO.OpenTextFile( sTxtSetOEM, ForReading )
Do While not f.AtEndOfStream
'
' Parse each line
'
sLine = f.ReadLine
sTrimLine = TrimWS(sLine)
if len(sLine) = 0 or left(sLine,1) = "#" or left(sLine,1) = ";" then
' Comments - Do nothing
elseif left(sTrimLine,1) = "[" then
' This is a [Section] line
sSectionName = lcase(mid(sTrimLine,2,instr(1,sTrimLine,"]",vbTextCompare)-2))
if instr(1,sDestTxtSetup,"[" & sSectionName & "]",vbTextCompare) <> 0 and ucase(sSectionName) <> "DEFAULTS" then
oLogging.CreateEntry "Section [" & sSectionName & "] found in more than one file, possible conflict: " & sTxtSetOEM, LogTypeWarning
end if
if instr(1,sSectionName,".",vbTextCompare) then
sSectionName = mid(sSectionName,1,instr(1,sSectionName,".",vbTextCompare)-1)
end if
if sSectionName = "files" or sSectionName = "config" or sSectionName = "hardwareids" then
sDestTxtSetup = sDestTxtSetup & vbNewLine & sLine
end if
else
' This is a regular line, process according to the section type.
if sSectionName = "disks" then
' Normalize the line
sDestTxtSetupDisks = sDestTxtSetupDisks & vbNewLine & mid( sTrimLine, 1, instr( 1, sTrimLine, "=", vbTextCompare ) )
sDestTxtSetupDisks = sDestTxtSetupDisks & " ""Microsoft Deployment 3rd party driver directory"", \txtsetup.oem, \"
elseif sSectionName = "defaults" and fIsFirst then
' Output only the 1st instance of this section
sDestTxtSetup = sDestTxtSetup & vbNewLine & "[Defaults]" & vbNewLine & sLine
elseif sSectionName = "scsi" then
sDestTxtSetupSCSI = sDestTxtSetupSCSI & vbNewLine & sLine
sTrimLine = TrimWS(mid(sTrimLine,instr(1,sTrimLine,"=",vbTextCompare)+1))
if left(sTrimLine,1) = """" then
sTrimLine = TrimWS(mid(sTrimLine,1,instr(3,sTrimLine,"""",vbTextCompare)))
elseif instr(1,sTrimLine,",",vbTextCompare) <> 0 then
sTrimLine = TrimWS(mid(sTrimLine,1,instr(1,sTrimLine,",",vbTextCompare)-1))
end if
if oListSCSI.exists(sTrimLine) then
oLogging.CreateEntry "SCSI Driver Name [" & sTrimLine & "] found in more than one file in " & sTxtSetOEM, LogTypeWarning
else
oListSCSI.Add sTrimLine,""
end if
elseif sSectionName = "files" then
sTrimLine = TrimWS(mid(sTrimLine,instr(1,sTrimLine,",",vbTextCompare)+1))
if instr(1,sTrimLine,",",vbTextCompare) <> 0 then
sTrimLine = TrimWS(mid(sTrimLine,1,instr(1,sTrimLine,",",vbTextCompare)-1))
end if
sExtName = ucase(mid(sTrimLine,instr(1,sTrimLine,".",vbTextCompare)+1))
if sExtName = "SYS" or sExtName = "INF" or sExtName = "CAT" then
sDestTxtSetup = sDestTxtSetup & vbNewLine & sLine
end if
if not oListFilesPackage.exists(sTrimLine) then
oListFilesPackage.Add sTrimLine,""
end if
elseif sSectionName = "config" or sSectionName = "hardwareids" then
sDestTxtSetup = sDestTxtSetup & vbNewLine & sLine
end if
end if
Loop
for each sTrimLine in oListFilesPackage.Keys
if oListFiles.exists(sTrimLine) then
oLogging.CreateEntry "Driver File [" & sGUID & " " & sTrimLine & "] duplicate found in " & oListFiles.Item(sTrimLine), LogTypeWarning
else
oListFiles.Add sTrimLine,sGUID
end if
next
f.Close
set f = nothing
fIsFirst = false
exit for
End if
next
End function
Function MarkupTextFilesSysPrep ( oStorageGUIDs )
Dim iRetVal
Dim oListPnP
Dim oListINFs
Dim sGuid
Dim sGuidDone
Dim sTxtSetOEMfull
Dim sTxtSetOEM
Dim f
Dim sLine
Dim sTrimLine
Dim sSectionName
Dim sSectionID
Dim sUnattendTxt
Dim oItem
Dim sSource
'
' Markup TxtSetup.OEM file
'
set oListPnP = CreateObject("Scripting.Dictionary")
oListPnP.CompareMode = vbTextCompare
set oListINFs = CreateObject("Scripting.Dictionary")
oListINFs.CompareMode = vbTextCompare
' ---------------------------------------------------------------------------
' Read each TxtSetup.OEM file from oStorageGUIDS
' ---------------------------------------------------------------------------
for each sGUID in oStorageGUIDs
set oItem = dFilteredDrivers.Item(sGUID)
TestAndFail not oItem is nothing , 7908, "Test dFilteredDrivers.Item(" & sGUID& ")"
sTxtSetOEMfull = oUtility.SelectSingleNodeString(oItem, "./Source")
sSource = oEnvironment.Item("ResourceRoot") & Mid(ofso.GetParentFolderName ( sTxtSetOEMfull ), 2)
sTxtSetOEM = sSource & "\TxtSetup.oem"
If instr(1,sGuidDone, sGUID, vbTextCompare ) <> 0 then
oLogging.CreateEntry "Skip, Already parsed " & sGUID, LogTypeInfo
ElseIf not PlatformCheck(oItem) then
oLogging.CreateEntry "Skipping driver " & sGUID & " because it is not for this platform (driver " & oUtility.SelectSingleNodeString(oItem,"Platform") & " != OS platform " & sArchitecture & ")", LogTypeInfo
Elseif not oFSO.FileExists( sTxtSetOEM ) then
oLogging.CreateEntry "Driver Package " & sGUID & " is missing txtsetup.oem : " & sTxtSetOEM , LogTypeInfo
Else
oLogging.CreateEntry "Markup: " & sGuid & " -> " & sTxtSetOEM, LogTypeInfo
' Copy Files first.
CopyDriverDir sSource, Mid(sSource, Instr(sSource, "Out-of-box Drivers\") + 19)
' PArse TxtSetup.OEM
set f = oFSO.OpenTextFile( sTxtSetOEM, ForReading )
Do While not f.AtEndOfStream
'
' Parse each line
'
sLine = f.ReadLine
sTrimLine = TrimWS(sLine)
if len(sLine) = 0 or left(sLine,1) = "#" or left(sLine,1) = ";" then
' Comments - Do nothing
elseif left(sTrimLine,1) = "[" then
' This is a [Section] line
sSectionName = lcase(mid(sTrimLine,2,instr(1,sTrimLine,"]",vbTextCompare)-2))
sSectionID = ""
if instr(1,sSectionName,".",vbTextCompare) then
sSectionID = mid(sSectionName,instr(1,sSectionName,".",vbTextCompare)+1)
sSectionName = mid(sSectionName,1,instr(1,sSectionName,".",vbTextCompare)-1)
if instr(1,sSectionID,".",vbTextCompare) then
sSectionID = mid(sSectionID,instr(1,sSectionID,".",vbTextCompare)+1)
end if
end if
else
' This is a regular line, process according to the section type.
if sSectionName = "hardwareids" then
sTrimLine = TrimWS(mid(sTrimLine,instr(1,sTrimLine,"=",vbTextCompare)+1))
if instr(1,sTrimLine,",",vbTextCompare) <> 0 then
sTrimLine = TrimWS(mid(sTrimLine,1,instr(1,sTrimLine,",",vbTextCompare)-1))
end if
if not oListPnP.exists(sTrimLine) then
oListPnP.Add sTrimLine, sGUID & "." & sSectionID & "." & sSectionName
end if
elseif sSectionName = "files" then
sTrimLine = TrimWS(mid(sTrimLine,instr(1,sTrimLine,"=",vbTextCompare)+1))
if instr(1,sTrimLine,",",vbTextCompare) <> 0 then
sTrimLine = TrimWS(mid(sTrimLine,instr(1,sTrimLine,",",vbTextCompare)+1))
end if
if instr(1,sTrimLine,",",vbTextCompare) <> 0 then
sTrimLine = TrimWS(mid(sTrimLine,1,instr(1,sTrimLine,",",vbTextCompare)-1))
end if
if ucase(right(sTrimLine,4)) = ".INF" then
if not oListINFs.exists(sGUID & "." & sSectionID & ".hardwareids") then
oListINFs.Add sGUID & "." & sSectionID & ".hardwareids", _
oFSO.GetParentFolderName ( sDestinationDrive & "\Drivers\" & _
Mid(sTxtSetOEMfull, Instr(sTxtSetOEMfull, "Out-of-box Drivers\") + 19) ) & "\" & sTrimLine
end if
end if
end if
end if
Loop
f.Close
set f = nothing
sGuidDone = sGuidDone & "," & sGUID
end if
next
If oListPnP.Count = 0 then
oLogging.CreateEntry "MarkupTextFilesSysPrep: No files to process", LogTypeInfo
Exit Function
End if
' ---------------------------------------------------------------------------
' Add the appropriate lines to the unattend.txt file to the target location
' ---------------------------------------------------------------------------
If oEnvironment.Item("OSDAnswerFilePathSysprep") = "" Then
iRetVal = oUtility.FindSysprepAnswerFile
End If
IF oFSO.FileExists(oEnvironment.Item("OSDAnswerFilePathSysPrep")) = False Then
iRetVal = oUtility.FindSysPrepAnswerFile
TestAndFail iRetVal, 7001, "Looking for unattend AnswerFile"
End If
sUnattendTxt = oEnvironment.Item("OSDAnswerFilePathSysprep")
oLogging.CreateEntry "Markup file: " & sUnattendTxt, LogTypeInfo
oUtility.WriteIni sUnattendTxt, "Sysprep", "BuildMassStorageSection","Yes"
oUtility.WriteIni sUnattendTxt, "SysprepMassStorage", "", ""
set f = oFSO.OpenTextFile(sUnattendTxt,ForAppending,False)
f.WriteLine "[SysprepMassStorage]"
for each sLine in oListPnP.keys
if sLine <> "" then
f.WriteLine sLine + "=""" & oListINFs.Item(oListPnP.Item(sLine)) & """"
end if
next
f.Close
set f = nothing
If oLogging.Debug Then
oFSO.CopyFile sUnattendTxt,sUnattendTxt & ".bak", TRUE
End If
End function
Function TrimWS( sTrimStr )
TrimWS = oStrings.TrimAllWS( STrimStr )
End function
'//---------------------------------------------------------------------------
'//
'// Function: GetDriverPaths()
'//
'// Input: dicPaths - dictionary object to hold retrieved paths
'// sPath - path to check
'// bRelative - flag to indicate whether paths should be relative
'//
'// Return: (via dicPaths)
'//
'// Purpose: Scan the specified directory to determine what paths need to be
'// added
'//
'//---------------------------------------------------------------------------
Sub GetDriverPaths(dicPaths, sPath, bRelative)
Dim objFolder, objFile, objSubFolder
dim sCurrentDir
' See if there are any INF files in the current directory
Set objFolder = oFSO.GetFolder(sPath)
For each objFile in objFolder.Files
If UCase(oFSO.GetExtensionName(objFile.Name)) = "INF" then
If bRelative then
sCurrentDir = Mid(objFolder.Path, 3)
Else
sCurrentDir = "%SystemDrive%" & Mid(objFolder.Path, 3)
End If
If not dicPaths.Exists(sCurrentDir) then
dicPaths.Add sCurrentDir, ""
oLogging.CreateEntry "Found new driver path: " & sCurrentDir, LogTypeInfo
End If
Exit For
End If
Next
' Check each of the subfolders
For each objSubFolder in objFolder.SubFolders
GetDriverPaths dicPaths, objSubFolder.Path, bRelative
Next
End Sub
'//---------------------------------------------------------------------------
'//
'// Function: CopyDriverDir()
'//
'// Purpose: Copies a specific driver directory to C:\Drivers
'//
'//---------------------------------------------------------------------------
Function CopyDriverDir(sPath,sDriversTarget)
Dim iRetVal
If g_sDriversDir = "" then
g_sDriversDir = sDestinationDrive & "\Drivers"
oUtility.VerifyPathExists g_sDriversDir
oFSO.GetFolder(g_sDriversDir).Attributes = 2 ' Make the folder hidden
End if
' Make sure the Source path specified exists
sPath = oEnvironment.Substitute(sPath)
oUtility.ValidateConnection sPath
If not oFSO.FolderExists(sPath) then
oLogging.CreateEntry "WARNING - Invalid driver path " & sPath & " specified - no copying will be done.", LogTypeWarning
CopyDriverDir = Failure
EXIT FUNCTION
End If
' Copy the drivers
oLogging.CreateEntry "Copying drivers from """ & sPath & """ to """ & g_sDriversDir & "\" & sDriversTarget & """", LogTypeInfo
oUtility.RunWithHeartbeat "cmd.exe /c xcopy /seihycd """ & sPath & """ """ & g_sDriversDir & "\" & sDriversTarget & """ 1> NUL 2>NUL"
if oEnvironment.Item("IsOSUpgrade") <> "" and oEnvironment.Item("IsOSUpgrade") = "1" then
oLogging.CreateEntry "UPGRADE: Copying drivers from """ & sPath & """ to stagging directory """ & oUtility.LocalRootPath & "\Scripts\Drivers" & """", LogTypeInfo
oUtility.RunWithHeartbeat "cmd.exe /c xcopy /seihycd """ & sPath & """ """ & oUtility.LocalRootPath & "\Drivers" & """ 1> NUL 2>NUL"
oEnvironment.Item("OSUpgradeDriverPath") = oUtility.LocalRootPath & "\Drivers"
oLogging.CreateEntry "UPGRADE: Setting OSUpgradeDriverPath = " & oEnvironment.Item("OSUpgradeDriverPath") , LogTypeInfo
End if
End Function
Public Function PlatformCheck ( oParent )
dim oEntry
PlatformCheck = FALSE
for each oEntry in oParent.SelectNodes("Platform")
If ucase(oEntry.Text) = ucase(sArchitecture) then
PlatformCheck = TRUE
exit for
End if
next
End function
' ---------------------------------------------------------------------------
' Use the Microsoft.BDD.PnPEnum.exe tool to enumerate through all PnPID on the system.
' ---------------------------------------------------------------------------
Function oLocalPNPIDs(sFilter)
Dim iRetVal
DIm sEnum
iRetVal = oUtility.FindFile("Microsoft.BDD.PnpEnum.exe", sEnum)
TestAndFail iRetVal, 7900, "Findfile: Microsoft.BDD.PnpEnum.exe"
oUtility.RunWithHeartbeat "cmd /c """ & sEnum & """ > " & oLogging.LogPath & "\PnpEnum.xml"
' Load the resulting XML
set oLocalPNPIDs = oUtility.CreateXMLDOMObjectEx(oLogging.LogPath & "\PnpEnum.xml").SelectNodes(sFilter)
End function
Function dAllDrivers
' Returns a list of All drivers (guid to oxmldomnode)
set dAllDrivers = oXMLDrivers.FindAllItems
End function
Function dFilteredDrivers
' Returns a list of drivers (guid to oxmldomnode)
If isempty(g_dFilteredDrivers) then
oXMLDrivers.sGroupList = sGroupList
set g_dFilteredDrivers = oXMLDrivers.FindItems
oLogging.CreateEntry "Filtered.Count: " & g_dFilteredDrivers.Count, LogTypeInfo
End if
set dFilteredDrivers = g_dFilteredDrivers
End function
Function dFilteredPnPIDs
' Returns a collection of filtered Driver PNPIDs' to Driver GUID's
Dim oDevice
Dim oPnPId
If isempty(g_dAllPnPIDs) then
set g_dAllPnPIDs = CreateObject("Scripting.Dictionary")
g_dAllPnPIDs.CompareMode = TextCompare
for each oDevice in dFilteredDrivers.Items
for each oPnPID in oDevice.SelectNodes("./PNPId")
if g_dAllPnPIDs.Exists( oPnPID.Text ) then
g_dAllPnPIDs.Item( oPnPID.TExt ) = g_dAllPnPIDs.Item( oPnPID.TExt ) & vbTab & oDevice.attributes.getNamedItem("guid").value
else
g_dAllPnPIDs.add oPnPID.Text, oDevice.attributes.getNamedItem("guid").value
end if
next
next
oLogging.CreateEntry "Indexed PnP Ids: " & g_dAllPnPIDs.Count, LogTypeInfo
End if
set dFilteredPnPIDs = g_dAllPnPIDs
End function
End Class
</script>
</job>