Example #1
0
        // 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);
                    }
                }
            }
        }
Example #3
0
        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);
 }