/// <param name="relativeRoot"> /// The location where HKR entried will be stored, relative to 'SYSTEM\CurrentControlSet\' (or ControlSet001 for that matter) /// </param> private void ProcessAddRegSection(PNPDriverINFFile pnpDriverInf, string sectionName, string relativeRoot) { List <string> section = pnpDriverInf.GetSection(sectionName); foreach (string line in section) { List <string> values = INIFile.GetCommaSeparatedValues(line); string hiveName = values[0]; string subKeyName = INIFile.Unquote(values[1]); string valueName = INIFile.TryGetValue(values, 2); string valueType = INIFile.TryGetValue(values, 3);; string valueDataUnparsed = String.Empty; if (values.Count > 3) { valueDataUnparsed = StringUtils.Join(values.GetRange(4, values.Count - 4), ","); // byte-list is separated using commmas } valueName = INIFile.Unquote(valueName); valueType = pnpDriverInf.ExpandToken(valueType); int valueTypeFlags = PNPDriverINFFile.ConvertFromIntStringOrHexString(valueType); string valueTypeHexString; if (!valueType.StartsWith("0x")) { valueTypeHexString = "0x" + valueTypeFlags.ToString("X8"); // we want value type in 8 digit hex string. } else { valueTypeHexString = valueType; } RegistryValueKind valueKind = PNPDriverINFFile.GetRegistryValueKind(valueTypeFlags); if (valueKind == RegistryValueKind.String) { valueDataUnparsed = pnpDriverInf.ExpandToken(valueDataUnparsed); } object valueData = HiveINIFile.ParseValueDataString(valueDataUnparsed, valueKind); if (hiveName == "HKR") { string cssKeyName = relativeRoot; if (subKeyName != String.Empty) { cssKeyName = cssKeyName + @"\" + subKeyName; } // Note that software key will stick from text-mode: SetCurrentControlSetRegistryKey(cssKeyName, valueName, valueKind, valueData); } else if (hiveName == "HKLM" && subKeyName.StartsWith(@"SYSTEM\CurrentControlSet\", StringComparison.InvariantCultureIgnoreCase)) { string cssKeyName = subKeyName.Substring(@"SYSTEM\CurrentControlSet\".Length); SetCurrentControlSetRegistryKey(cssKeyName, valueName, valueKind, valueData); } else { //Console.WriteLine("Warning: unsupported registry path: " + hiveName + @"\" + subKeyName); } } }
// Windows File Protection may restore a newer unsigned driver file to an older in-box signed driver file (sfc.exe is executed at the end of GUI-mode setup). // The list of files that is being protected is stored in sfcfiles.sys, and we can prevent a file from being protected by making sure it's not in that list. public static void DisableInBoxDeviceDriverFile(string setupDirectory, string fileName) { fileName = fileName.ToLower(); // sfcfiles.dll stores all file names in lowercase string path = setupDirectory + "sfcfiles.dl_"; byte[] packed = File.ReadAllBytes(path); byte[] unpacked = HiveINIFile.Unpack(packed, "sfcfiles.dll"); PortableExecutableInfo peInfo = new PortableExecutableInfo(unpacked); string oldValue = @"%systemroot%\system32\drivers\" + fileName; string newValue = @"%systemroot%\system32\drivers\" + fileName.Substring(0, fileName.Length - 1) + "0"; // e.g. e1000325.sys => e1000325.sy0 byte[] oldSequence = Encoding.Unicode.GetBytes(oldValue); byte[] newSequence = Encoding.Unicode.GetBytes(newValue); bool replaced = false; for (int index = 0; index < peInfo.Sections.Count; index++)// XP uses the .text section while Windows 2000 uses the .data section { byte[] section = peInfo.Sections[index]; bool replacedInSection = KernelAndHalIntegrator.ReplaceInBytes(ref section, oldSequence, newSequence); if (replacedInSection) { peInfo.Sections[index] = section; replaced = true; } } if (replaced) { Console.WriteLine(); Console.WriteLine("'{0}' has been removed from Windows File Protection file list.", fileName); MemoryStream peStream = new MemoryStream(); PortableExecutableInfo.WritePortableExecutable(peInfo, peStream); unpacked = peStream.ToArray(); packed = HiveINIFile.Pack(unpacked, "sfcfiles.dll"); FileSystemUtils.ClearReadOnlyAttribute(path); File.WriteAllBytes(path, packed); } }
/// <summary> /// Successful USB 2.0 Boot: Inbox USB 2.0 host controller and hub Drivers + USB mass storage class driver (usbstor.sys). /// Successful USB 3.0 Boot: Vendor provided host controller anb hub drivers + USB mass storage class driver (usbstor.sys). /// In addition, most systems will require an additional step in the form of a driver that will wait for the USB storage device to be initialized, /// I have written Wait4UFD for that purpose. /// See: http://msdn.microsoft.com/en-us/library/ee428799.aspx /// http://reboot.pro/topic/14427-waitbt-for-usb-booting/ /// </summary> public void IntegrateUSB20HostControllerAndHubDrivers() { if (m_installation.IsWindows2000) { // The service pack version must be SP4 for the /usbboot switch to get accepted if (!FileSystemUtils.IsFileExist(m_installation.SetupDirectory + "sp4.cab")) { Console.WriteLine("Error: Missing file: sp4.cab"); Program.Exit(); } // Note: Windows 2000 SP4 added USB 2.0 support, earlier versions are limited to USB 1.1 // Copy USB 2.0 filles from SP4.cab: string path = m_installation.SetupDirectory + "sp4.cab"; byte[] packed = File.ReadAllBytes(path); byte[] unpacked = HiveINIFile.Unpack(packed, "usbehci.sys"); File.WriteAllBytes(m_installation.BootDirectory + "usbehci.sys", unpacked); unpacked = HiveINIFile.Unpack(packed, "usbport.sys"); File.WriteAllBytes(m_installation.BootDirectory + "usbport.sys", unpacked); unpacked = HiveINIFile.Unpack(packed, "usbhub20.sys"); File.WriteAllBytes(m_installation.BootDirectory + "usbhub20.sys", unpacked); // Create the [files.usbehci] and [files.usbhub20] sections. // Those sections lists the driver files that will be copied if the device has been detected. m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "hid.dll", (int)WinntDirectoryName.System32); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "hccoin.dll", (int)WinntDirectoryName.System32); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "hidclass.sys", (int)WinntDirectoryName.System32); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "hidparse.sys", (int)WinntDirectoryName.System32_Drivers); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "usbd.sys", (int)WinntDirectoryName.System32_Drivers); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "usbport.sys", (int)WinntDirectoryName.System32_Drivers); m_installation.TextSetupInf.AddFileToFilesSection("files.usbehci", "usbehci.sys", (int)WinntDirectoryName.System32_Drivers); m_installation.TextSetupInf.AddFileToFilesSection("files.usbhub20", "usbhub20.sys", (int)WinntDirectoryName.System32_Drivers); RegisterBootBusExtender("usbehci", "Enhanced Host Controller", "files.usbehci"); m_installation.UsbInf.SetWindows2000UsbEnhancedHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("openhci"); RegisterBootBusExtender("openhci", "Open Host Controller", "files.openhci"); m_installation.UsbInf.SetWindows2000OpenHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("uhcd"); RegisterBootBusExtender("uhcd", "Universal Host Controller", "files.uhcd"); m_installation.UsbInf.SetWindows2000UsbUniversalHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("usbhub"); RegisterBootBusExtender("usbhub", "Generic USB Hub Driver", "files.usbhub"); RegisterBootBusExtender("usbhub20", "Generic USB Hub Driver", "files.usbhub20"); m_installation.UsbInf.SetWindows2000UsbRootHubToBootStart(); m_installation.UsbInf.SetWindows2000Usb20RootHubToBootStart(); m_installation.UsbInf.SetWindows2000Usb20GenericHubToBootStart(); // Update the CDDB m_installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(@"PCI\CC_0C0320", "usbehci"); m_installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(@"USB\ROOT_HUB20", "usbhub20"); // Needed in case the user uses a USB 2.0 Hub between the UFD and the root hub: // Note: Under Windows 2000 SP4, 'USB\HubClass' is the identifier of USB 2.0 Hubs. m_installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(@"USB\HubClass", "usbhub20"); // Note: I could not get usbhub.sys and usbhub20.sys working consistently at the same time under text-mode setup. // as a solution, we must prevent usbhub.sys from being loaded (USB 1.x devices such as mouse / keyboard may not work) m_installation.TextSetupInf.RemoveDeviceFromCriticalDeviceDatabase(@"USB\COMPOSITE"); m_installation.TextSetupInf.RemoveDeviceFromCriticalDeviceDatabase(@"USB\ROOT_HUB"); m_installation.TextSetupInf.RemoveDeviceFromCriticalDeviceDatabase(@"USB\CLASS_09&SUBCLASS_01"); m_installation.TextSetupInf.RemoveDeviceFromCriticalDeviceDatabase(@"USB\CLASS_09"); Console.Write("********************************************************************************"); Console.Write("*The author was not able to get USB 1.x and USB 2.0 consistently working at the*"); Console.Write("*same time during Windows 2000 text-mode setup. USB 1.x has been temporarily *"); Console.Write("*disabled, devices such as USB mouse or keyboard may not work as a result. *"); Console.Write("*USB 1.x will be re-enabled during GUI-mode setup. *"); Console.Write("********************************************************************************"); // One notable exception to the above was when a USB 2.0 hub was connected between the UFD and the onboard USB port: // When connected directly, the I got a BSOD, but when connected to the same port through a USB 2.0 hub // ('USB\ROOT_HUB' was set to load usbhub.sys, 'USB\CLASS_09' had to be removed from the CDDB), Both USB 1.x and USB 2.0 devices worked properly. } else { m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("usbehci"); RegisterBootBusExtender("usbehci", "Enhanced Host Controller", "files.usbehci"); m_installation.UsbPortInf.SetUsbEnhancedHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("usbohci"); RegisterBootBusExtender("usbohci", "Open Host Controller", "files.usbohci"); m_installation.UsbPortInf.SetUsbUniversalHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("usbuhci"); RegisterBootBusExtender("usbuhci", "Universal Host Controller", "files.usbuhci"); m_installation.UsbPortInf.SetUsbOpenHostControllerToBootStart(); m_installation.TextSetupInf.RemoveInputDevicesSupportDriverLoadInstruction("usbhub"); RegisterBootBusExtender("usbhub", "Generic USB Hub Driver", "files.usbhub"); m_installation.UsbPortInf.SetUsbRootHubToBootStart(); // The root hub and generic hub have two different INF files, but both use the same service, // so if a generic USB 2.0 hub is detected, the service will be reinstalled. // We must make sure the service will still be set to boot start during this process. m_installation.UsbInf.SetWindowsXP2003UsbStandardHubToBootStart(); } // Add the generic USB hub to the final CDDB, in case our user will decide to add // a hub between the UFD and the root hub after the installation. // see: http://www.usb.org/developers/defined_class m_installation.HiveSystemInf.AddDeviceToCriticalDeviceDatabase(@"USB\Class_09", "usbhub"); if (m_installation.IsWindows2000) { // Windows 2000 uses usbhub.sys for USB 1.x hubs, and usbhub20.sys for USB 2.0 hubs. m_installation.HiveSystemInf.AddDeviceToCriticalDeviceDatabase(@"USB\HubClass", "usbhub20"); } }
public void SetRegistryKeyUnparsed(string keyName, string valueName, RegistryValueKind valueKind, string valueData) { SetRegistryKey(keyName, valueName, valueKind, HiveINIFile.ParseValueDataString(valueData, valueKind)); }
// update txtsetup.sif and dotnet.inf private void UpdateTextSetupInformationFileAndCopyFiles(string deviceID) { // Files.HwComponent.ID Section TextModeDriverSetupINIFile driverINI = m_driverDirectory.TextModeDriverSetupINI; List <string> section = driverINI.GetDriverFilesSection(deviceID); string serviceName = String.Empty; List <string> driverKeys = new List <string>(); string sourceDirectoryInMediaRootForm = m_installation.GetSourceDriverDirectoryInMediaRootForm(deviceID); int sourceDiskID = m_installation.TextSetupInf.AllocateSourceDiskID(m_installation.ArchitectureIdentifier, sourceDirectoryInMediaRootForm); string destinationWinntDirectory = m_installation.GetDriverDestinationWinntDirectory(m_deviceID); int destinationWinntDirectoryID = m_installation.TextSetupInf.AllocateWinntDirectoryID(destinationWinntDirectory); foreach (string line in section) { KeyValuePair <string, List <string> > keyAndValues = INIFile.GetKeyAndValues(line); string fileType = keyAndValues.Key; string directory = driverINI.GetDirectoryOfDisk(keyAndValues.Value[0]); string fileName = keyAndValues.Value[1]; string sourceFilePath = m_driverDirectory.Path + "." + directory + @"\" + fileName; bool isDriver = keyAndValues.Key.Equals("driver", StringComparison.InvariantCultureIgnoreCase); m_installation.CopyFileToSetupDriverDirectory(sourceFilePath, deviceID + @"\", fileName); if (isDriver) { m_installation.CopyDriverToSetupRootDirectory(sourceFilePath, fileName); if (m_installation.IsTargetContainsTemporaryInstallation) { m_installation.CopyFileFromSetupDirectoryToBootDirectory(fileName); } } m_installation.TextSetupInf.SetSourceDisksFileEntry(m_installation.ArchitectureIdentifier, sourceDiskID, destinationWinntDirectoryID, fileName, FileCopyDisposition.AlwaysCopy); if (isDriver) { // http://msdn.microsoft.com/en-us/library/ff544919%28v=VS.85%29.aspx // unlike what one may understand from the reading specs, this value is *only* used to form [Config.DriverKey] section name, // and definitely NOT to determine the service subkey name under CurrentControlSet\Services. (which is determined by the service file name without a .sys extension) string driverKey = keyAndValues.Value[2]; // http://support.microsoft.com/kb/885756 // according to this, only the first driver entry should be processed. // http://app.nidc.kr/dirver/IBM_ServerGuide_v7.4.17/sguide/w3x64drv/$oem$/$1/drv/dds/txtsetup.oem // however, this sample and my experience suggest that files / registry entries from a second driver entry will be copied / registered, // (both under the same Services\serviceName key), so we'll immitate that. driverKeys.Add(driverKey); if (serviceName == String.Empty) { // Some txtsetup.oem drivers are without HardwareID entries, // but we already know that the service is specified by the file name of its executable image without a .sys extension, // so we should use that. serviceName = TextSetupINFFile.GetServiceName(fileName); } // We should use FileCopyDisposition.DoNotCopy, because InstructToLoadSCSIDriver will already copy the device driver. m_installation.TextSetupInf.SetSourceDisksFileDriverEntry(m_installation.ArchitectureIdentifier, fileName, FileCopyDisposition.DoNotCopy); m_installation.TextSetupInf.SetFileFlagsEntryForDriver(fileName); string deviceName = driverINI.GetDeviceName(deviceID); m_installation.TextSetupInf.InstructToLoadSCSIDriver(fileName, deviceName); } // add file to the list of files to be copied to local source directory if (!m_installation.IsTargetContainsTemporaryInstallation) { m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceDriverDirectory(sourceDirectoryInMediaRootForm, fileName); if (isDriver) { m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory(fileName); } } } section = driverINI.GetHardwareIdsSection(deviceID); foreach (string line in section) { KeyValuePair <string, List <string> > keyAndValues = INIFile.GetKeyAndValues(line); string hardwareID = keyAndValues.Value[0]; // http://msdn.microsoft.com/en-us/library/ff546129%28v=VS.85%29.aspx // The service is specified by the file name of its executable image without a .sys extension // it is incomprehensible that this line will change the value of serviceName, because we already set serviceName to the service file name without a .sys extension serviceName = INIFile.Unquote(keyAndValues.Value[1]); hardwareID = INIFile.Unquote(hardwareID); m_installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(hardwareID, serviceName); } foreach (string driverKey in driverKeys) { section = driverINI.GetConfigSection(driverKey); foreach (string line in section) { KeyValuePair <string, List <string> > keyAndValues = INIFile.GetKeyAndValues(line); string subKeyNameQuoted = keyAndValues.Value[0]; string valueName = keyAndValues.Value[1]; string valueType = keyAndValues.Value[2]; string valueDataUnparsed = keyAndValues.Value[3]; RegistryValueKind valueKind = TextModeDriverSetupINIFile.GetRegistryValueKind(valueType); object valueData = HiveINIFile.ParseValueDataString(valueDataUnparsed, valueKind); string subKeyName = INIFile.Unquote(subKeyNameQuoted); m_installation.HiveSystemInf.SetServiceRegistryKey(serviceName, subKeyName, valueName, valueKind, valueData); m_installation.SetupRegistryHive.SetServiceRegistryKey(serviceName, subKeyName, valueName, valueKind, valueData); } } }