// The following combinations of kernel and HAL will enable NICs to work in text-mode setup: // (regardless of whether the machine being used has one or more than one CPU core) // // Uniprocessor kernel + ACPI PC HAL // Uniprocessor kernel + ACPI Uniprocessor PC HAL // Multiprocessor kernel + ACPI Multiprocessor PC HAL // // Other combinations will either hang or reboot. // By default, text-mode setup will use Multiprocessor kernel + ACPI Uniprocessor PC HAL (which will hang) // // Note that we can use both multiprocessor kernel and multiprocessor HAL on uniprocessor machine, // (there might be a performance penalty for such configuration) // however, this approach will not work on older machines that uses the ACPI PC HAL (Pentium 3 / VirtualBox) // so the best approach is using the uniprocessor kernel. // references: // http://support.microsoft.com/kb/309283 // http://social.technet.microsoft.com/Forums/en-AU/configmgrosd/thread/fb1dbea9-9d39-4663-9c61-6bcdb4c1253f // general information about x86 HAL types: http://www.vernalex.com/guides/sysprep/hal.shtml // Note: /kernel switch does not work in text-mode, so we can't use this simple solution. public void UseUniprocessorKernel() { if (m_uniprocessorKernelEnabled) { return; } if (m_installation.ArchitectureIdentifier != "x86") { // amd64 and presumably ia64 use a single HAL for both uni and multiprocessor kernel) return; } Console.WriteLine(); Console.WriteLine("By default, text-mode setup will use a multiprocessor OS kernel with a"); Console.WriteLine("uniprocessor HAL. This configuration cannot support network adapters"); Console.WriteLine("(setup will hang)."); Console.WriteLine("IntegrateDrv will try to enable uniprocessor kernel:"); string setupldrPath; if (m_installation.IsTargetContainsTemporaryInstallation) { // sometimes NTLDR is being used instead of $LDR$ (when using winnt32.exe /syspart /tempdrive) // (even so, it's still a copy of setupldr.bin and not NTLDR from \I386) setupldrPath = m_installation.TargetDirectory + "$LDR$"; if (!File.Exists(setupldrPath)) { setupldrPath = m_installation.TargetDirectory + "NTLDR"; } } else // integration to installation media { setupldrPath = m_installation.SetupDirectory + "setupldr.bin"; } if (!File.Exists(setupldrPath)) { Console.WriteLine("Error: '{0}' does not exist.", setupldrPath); Program.Exit(); } if (m_installation.IsWindows2000) { PatchWindows2000SetupBootLoader(setupldrPath); } else // Winndows XP or Windows Server 2003 { PatchWindowsXP2003SetupBootLoader(setupldrPath); } if (m_installation.IsTargetContainsTemporaryInstallation) { ProgramUtils.CopyCriticalFile(m_installation.SetupDirectory + "ntoskrnl.ex_", m_installation.BootDirectory + "ntoskrnl.ex_"); } else // integration to installation media { m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory("ntoskrnl.ex_"); } Console.WriteLine("Uniprocessor kernel has been enabled."); m_uniprocessorKernelEnabled = true; }
// see comments above PrepareToPreventTextModeDriverNameCollision() ^^ /// <summary> /// Will copy PNP driver files to setup and boot directories, and update txtsetup.inf accordingly. /// The modifications support 3 different installation scenarions: /// 1. The user install using unmodified CD, use this program to integrate the drivers to the temporary installation folder that was created and then boot from it. /// 2. The user uses this program to create modified installation folder / CD, boots from Windows PE /// at the target machine, and use winnt32.exe to install the target OS. (DOS / winnt.exe should work too) /// 3. The user uses this program to create modified installation CD and boot from it. /// Note: We do not support RIS (seems too complex and can collide with our own TCP/IP integration) /// </summary> public void CopyDriverFiles(List <DeviceService> deviceServices) { List <string> serviceFileNames = new List <string>(); foreach (DeviceService deviceService in deviceServices) { serviceFileNames.Add(deviceService.FileName); } for (int index = 0; index < this.DriverFilesToCopy.Count; index++) { string sourceFilePath = this.DriverDirectory.Path + this.DriverFilesToCopy[index].RelativeSourceFilePath; string fileName = this.DriverFilesToCopy[index].DestinationFileName; bool serviceWithNameCollision = false; string textModeFileName; if (fileName.ToLower().EndsWith(".sys")) { int serviceIndex = StringUtils.IndexOfCaseInsensitive(serviceFileNames, fileName); if (serviceIndex >= 0) { string serviceName = deviceServices[index].ServiceName; textModeFileName = deviceServices[index].TextModeFileName; serviceWithNameCollision = StringUtils.ContainsCaseInsensitive(m_oldToNewFileName.Keys, textModeFileName); if (serviceName.Length > 8 && !m_installation.IsTargetContainsTemporaryInstallation) { Console.WriteLine("Warning: Service '{0}' has name longer than 8 characters.", serviceName); Console.Write("********************************************************************************"); Console.Write("*You must use ISO level 2 compatible settings if you wish to create a working *"); Console.Write("*bootable installation CD. *"); Console.Write("*if you're using nLite, choose mkisofs over the default ISO creation engine. *"); Console.Write("********************************************************************************"); } } else { int renameIndex = StringUtils.IndexOfCaseInsensitive(m_oldToNewFileName.Keys, fileName); if (renameIndex >= 0) { textModeFileName = m_oldToNewFileName[renameIndex].Value; } else { textModeFileName = fileName; } } } else { textModeFileName = fileName; } if (fileName.ToLower().EndsWith(".sys") || fileName.ToLower().EndsWith(".dll")) { // we copy all the executables to the setup directory, Note that we are using textModeFileName // (e.g. e1000325.sys becomes E1000.sys) this is necessary for a bootable cd to work properly) // but we have to rename the file during text-mode copy phase for GUI-mode to work properly ProgramUtils.CopyCriticalFile(sourceFilePath, m_installation.SetupDirectory + textModeFileName, true); } // see comments above PrepareToPreventTextModeDriverNameCollision() ^^ // in case of a service name collision, here we patch the service executable file that we just copied and update the name of its dependency if (serviceWithNameCollision) { // we need the renamed patched file in the setup (e.g. I386 folder) for a bootable cd to work properly PreventTextModeDriverNameCollision(m_installation.SetupDirectory + textModeFileName); // we need the original file too (for GUI-mode) ProgramUtils.CopyCriticalFile(sourceFilePath, m_installation.SetupDirectory + fileName); } // update txtsetup.sif: if (fileName.ToLower().EndsWith(".sys")) { // this is for the GUI-mode, note that we copy the files to their destination using their original name, // also note that if there is a collision we copy the original (unpatched) file instead of the patched one. if (serviceWithNameCollision) { // this is the unpatched file: m_installation.TextSetupInf.SetSourceDisksFileDriverEntry(m_installation.ArchitectureIdentifier, fileName, FileCopyDisposition.AlwaysCopy, fileName); // this is the patched file, we're not copying it anywhere, but we load this service executable so text-mode setup demand an entry (probably to locate the file source directory) m_installation.TextSetupInf.SetSourceDisksFileDriverEntry(m_installation.ArchitectureIdentifier, textModeFileName, FileCopyDisposition.DoNotCopy); } else { m_installation.TextSetupInf.SetSourceDisksFileDriverEntry(m_installation.ArchitectureIdentifier, textModeFileName, FileCopyDisposition.AlwaysCopy, fileName); } } else if (fileName.ToLower().EndsWith(".dll")) { m_installation.TextSetupInf.SetSourceDisksFileDllEntry(m_installation.ArchitectureIdentifier, fileName); } // finished updating txtsetup.sif if (m_installation.IsTargetContainsTemporaryInstallation) { if (fileName.ToLower().EndsWith(".sys")) { // we copy all drivers by their text-mode name ProgramUtils.CopyCriticalFile(m_installation.SetupDirectory + textModeFileName, m_installation.BootDirectory + textModeFileName); } } else { // update dosnet.inf if (fileName.ToLower().EndsWith(".sys")) { // we already made sure all the files in the setup directory are using their textModeFileName m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(textModeFileName, textModeFileName); m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory(textModeFileName, textModeFileName); if (serviceWithNameCollision) { // the unpatched .sys should be available with it's original (GUI) name in the \$WINNT$.~LS folder m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(fileName); } } else if (fileName.ToLower().EndsWith(".dll")) { // in the case of .dll fileName is the same as textModeFileName m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(fileName); } } } }
public void UseMultiprocessorHal() { if (m_multiprocessorHalEnabled) { return; } if (m_installation.ArchitectureIdentifier != "x86") { // amd64 and presumably ia64 use a single HAL for both uni and multiprocessor kernel) return; } Console.WriteLine(); Console.WriteLine("By default, text-mode setup will use a multiprocessor OS kernel"); Console.WriteLine("with a uniprocessor HAL. This configuration cannot support network adapters"); Console.WriteLine("(setup will hang)."); Console.WriteLine("IntegrateDrv will try to enable multiprocessor HAL:"); if (m_installation.IsTargetContainsTemporaryInstallation) { if (System.IO.File.Exists(m_installation.BootDirectory + "halmacpi.dl_")) { m_installation.TextSetupInf.UseMultiprocessorHal(); m_multiprocessorHalEnabled = true; Console.WriteLine("Multiprocessor HAL has been enabled."); return; } else if (System.IO.File.Exists(m_installation.SetupDirectory + "halmacpi.dl_")) { ProgramUtils.CopyCriticalFile(m_installation.SetupDirectory + "halmacpi.dl_", m_installation.BootDirectory + "halmacpi.dl_"); m_installation.TextSetupInf.UseMultiprocessorHal(); Console.WriteLine("halmacpi.dl_ was copied from local source directory."); m_multiprocessorHalEnabled = true; Console.WriteLine("Multiprocessor HAL has been enabled."); } else { int index; for (index = 3; index >= 1; index--) { string spFilename = string.Format("sp{0}.cab", index); if (File.Exists(m_installation.SetupDirectory + spFilename)) { CabInfo cabInfo = new CabInfo(m_installation.SetupDirectory + spFilename); if (cabInfo.GetFile("halmacpi.dll") != null) { cabInfo.UnpackFile("halmacpi.dll", m_installation.BootDirectory + "halmacpi.dll"); // setup is expecting a packed "halmacpi.dl_" //cabInfo = new CabInfo(m_installation.BootDirectory + "halmacpi.dl_"); //Dictionary<string, string> files = new Dictionary<string, string>(); //files.Add("halmacpi.dll", "halmacpi.dll"); //cabInfo.PackFileSet(m_installation.BootDirectory, files); Console.WriteLine("halmacpi.dl_ was extracted from local source directory."); m_installation.TextSetupInf.UseMultiprocessorHal(); m_multiprocessorHalEnabled = true; Console.WriteLine("Multiprocessor HAL has been enabled."); } break; } } if (index == 0) { Console.WriteLine("Warning: could not locate halmacpi.dll, multiprocessor HAL has not been enabled!"); } } } else // integration to installation media { m_installation.TextSetupInf.UseMultiprocessorHal(); m_installation.DosNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory("halmacpi.dl_"); m_multiprocessorHalEnabled = true; Console.WriteLine("Multiprocessor HAL has been enabled."); return; } }
public void AddDriverToBootDirectory(string sourceFilePath, string fileName) { ProgramUtils.CopyCriticalFile(sourceFilePath, this.SetupDirectory + fileName); }