Ejemplo n.º 1
0
        public void UnloadHive(bool commit)
        {
            if (_isLoaded)
            {
                var result = RegistryUtils.UnloadHive(HiveKeyName);
                _isLoaded = (result != 0);
                if (commit)
                {
                    FileSystemUtils.ClearReadOnlyAttribute(_hivePath);
                    ProgramUtils.CopyCriticalFile(_tempHivePath, _hivePath);
                }

                try
                {
                    File.Delete(_tempHivePath);
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch
                {
                }

                if (_isLoaded)
                {
                    Console.WriteLine("Warning: failed to unload setup registry hive [Code: {0}]", result);
                }
            }
        }
Ejemplo n.º 2
0
        public void CopyFileToSetupDriverDirectory(string sourceFilePath, string destinationRelativeDirectoryPath,
                                                   string destinationFileName)
        {
            var destinationDirectoryPath = GetSetupDriverDirectoryPath(destinationRelativeDirectoryPath);

            FileSystemUtils.CreateDirectory(destinationDirectoryPath);
            ProgramUtils.CopyCriticalFile(sourceFilePath, destinationDirectoryPath + destinationFileName);
        }
Ejemplo n.º 3
0
        /*
         * public string FindVirtualDeviceInstanceID(string deviceClassName, string hardwareIDToFind)
         * {
         *      string result = string.Empty;
         *      string keyName = @"ControlSet001\Enum\Root\" + deviceClassName;
         *      if (m_isLoaded)
         *      {
         *              RegistryKey hiveKey = Registry.Users.OpenSubKey(m_hiveKeyName);
         *              RegistryKey key = hiveKey.OpenSubKey(keyName);
         *
         *              List<string> deviceInstanceIDs = new List<string>(key.GetSubKeyNames());
         *              foreach (string deviceInstanceID in deviceInstanceIDs)
         *              {
         *                      RegistryKey deviceInstanceKey = key.OpenSubKey(deviceInstanceID);
         *                      object hardwareIDEntry = deviceInstanceKey.GetValue("HardwareID", new string[0]);
         *                      if (hardwareIDEntry is string[])
         *                      {
         *                              string hardwareID = ((string[])hardwareIDEntry)[0];
         *                              if (string.Equals(hardwareID, hardwareIDToFind, StringComparison.InvariantCultureIgnoreCase))
         *                              {
         *                                      result = deviceInstanceID;
         *                                      break;
         *                              }
         *                      }
         *                      deviceInstanceKey.Close();
         *              }
         *              key.Close();
         *              hiveKey.Close();
         *              return result;
         *      }
         *      else
         *      {
         *              throw new Exception("Registry hive is not loaded");
         *      }
         * }
         */

        public void LoadHiveFromDirectory(string directory)
        {
            _hivePath = directory + FileName;
            // GetTempPath() should end with backward slash:
            _tempHivePath = Path.GetTempPath() + FileName;

            try
            {
                File.Copy(_hivePath, _tempHivePath, true);
            }
            catch
            {
                // perhaps the hive is already loaded from a previous crash / break
                // let's try to unload it
                RegistryUtils.UnloadHive(HiveKeyName);
                ProgramUtils.CopyCriticalFile(_hivePath, _tempHivePath);
                // CopyCriticalFile will exit the program on failue
            }

            var result = RegistryUtils.LoadHive(HiveKeyName, _tempHivePath);

            _isLoaded = (result == 0);
            if (!_isLoaded)
            {
                Console.WriteLine("Error: failed to load registry hive '{0}', error code: {1}", FileName, result);
                Console.WriteLine("This may happen due to one of the following reasons:");
                Console.WriteLine("- You do not have access to perform this operation");
                Console.WriteLine("- The hive is already loaded and needs to be manually unloaded (HKEY_USERS\\setupreg)");
                Environment.Exit(-1);
            }
            else
            {
                // if ControlSet001\Enum exist, its permissions will stick and stay for GUI-Mode \ final windows,
                // The default windows permissions for CurrentControlSet\Enum are:
                // SYSTEM   -> Full Control
                // Everyone -> Read
                // so we must make sure the default permissions are granted.
                const string subKeyName = HiveKeyName + @"\ControlSet001\Enum";
                // we're creating or opening the Enum key (if it's already exist, the permissions will simply be overwritten)
                // Note that we're creating ControlSet001\Enum even if we're not using it.
                var enumKey = Registry.Users.CreateSubKey(subKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree);
                enumKey.Close();
                RegistryKeyUtils.SetHKeyUsersKeySecutiryDescriptor(subKeyName, RegistryKeyUtils.DesiredEnumSecurityDescriptorString);
            }
        }
Ejemplo n.º 4
0
 public void SaveRegistryChanges()
 {
     SetupRegistryHive.UnloadHive(true);
     if (IsTargetContainsTemporaryInstallation)
     {
         FileSystemUtils.ClearReadOnlyAttribute(BootDirectory + SetupRegistryHiveFile.FileName);
         try
         {
             ProgramUtils.CopyCriticalFile(SetupDirectory + SetupRegistryHiveFile.FileName,
                                           BootDirectory + SetupRegistryHiveFile.FileName);
         }
         catch
         {
             Console.WriteLine("Error: failed to copy '{0}' to '{1}' (setup boot folder)", SetupRegistryHiveFile.FileName,
                               BootDirectory);
             Program.Exit();
         }
     }
 }
Ejemplo n.º 5
0
        // 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>
        private void CopyDriverFiles(List <BaseDeviceService> deviceServices)
        {
            var serviceFileNames = new List <string>();

            foreach (var deviceService in deviceServices)
            {
                serviceFileNames.Add(deviceService.FileName);
            }

            for (var index = 0; index < DriverFilesToCopy.Count; index++)
            {
                var sourceFilePath           = DriverDirectory.Path + DriverFilesToCopy[index].RelativeSourceFilePath;
                var fileName                 = DriverFilesToCopy[index].DestinationFileName;
                var serviceWithNameCollision = false;

                string textModeFileName;
                if (fileName.ToLower().EndsWith(".sys"))
                {
                    var serviceIndex = StringUtils.IndexOfCaseInsensitive(serviceFileNames, fileName);
                    if (serviceIndex >= 0)
                    {
                        var serviceName = deviceServices[index].ServiceName;
                        textModeFileName         = deviceServices[index].TextModeFileName;
                        serviceWithNameCollision = StringUtils.ContainsCaseInsensitive(_oldToNewFileName.Keys, textModeFileName);

                        if (serviceName.Length > 8 && !_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
                    {
                        var renameIndex = StringUtils.IndexOfCaseInsensitive(_oldToNewFileName.Keys, fileName);
                        textModeFileName = renameIndex >= 0
                                                        ? _oldToNewFileName[renameIndex].Value
                                                        : 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, _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(_installation.SetupDirectory + textModeFileName);

                    // we need the original file too (for GUI-mode)
                    ProgramUtils.CopyCriticalFile(sourceFilePath, _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:
                        _installation.TextSetupInf.SetSourceDisksFileDriverEntry(
                            _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)
                        _installation.TextSetupInf.SetSourceDisksFileDriverEntry(
                            _installation.ArchitectureIdentifier,
                            textModeFileName,
                            FileCopyDisposition.DoNotCopy);
                    }
                    else
                    {
                        _installation.TextSetupInf.SetSourceDisksFileDriverEntry(
                            _installation.ArchitectureIdentifier,
                            textModeFileName,
                            FileCopyDisposition.AlwaysCopy,
                            fileName);
                    }
                }
                else if (fileName.ToLower().EndsWith(".dll"))
                {
                    _installation.TextSetupInf.SetSourceDisksFileDllEntry(_installation.ArchitectureIdentifier, fileName);
                }
                // finished updating txtsetup.sif

                if (_installation.IsTargetContainsTemporaryInstallation)
                {
                    if (fileName.ToLower().EndsWith(".sys"))
                    {
                        // we copy all drivers by their text-mode name
                        ProgramUtils.CopyCriticalFile(
                            _installation.SetupDirectory + textModeFileName,
                            _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
                        _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(textModeFileName, textModeFileName);
                        _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory(textModeFileName, textModeFileName);

                        if (serviceWithNameCollision)
                        {
                            // the unpatched .sys should be available with it's original (GUI) name in the \$WINNT$.~LS folder
                            _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(fileName);
                        }
                    }
                    else if (fileName.ToLower().EndsWith(".dll"))
                    {
                        // in the case of .dll fileName is the same as textModeFileName
                        _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceRootDirectory(fileName);
                    }
                }
            }
        }
Ejemplo n.º 6
0
 public void AddDriverToBootDirectory(string sourceFilePath, string fileName)
 {
     ProgramUtils.CopyCriticalFile(sourceFilePath, SetupDirectory + fileName);
 }
Ejemplo n.º 7
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 (_uniprocessorKernelEnabled)
            {
                return;
            }

            // amd64 and presumably ia64 use a single HAL for both uni and multiprocessor kernel)
            if (_installation.ArchitectureIdentifier != "x86")
            {
                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 (_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 = _installation.TargetDirectory + "$LDR$";
                if (!File.Exists(setupldrPath))
                {
                    setupldrPath = _installation.TargetDirectory + "NTLDR";
                }
            }
            else             // integration to installation media
            {
                setupldrPath = _installation.SetupDirectory + "setupldr.bin";
            }

            if (!File.Exists(setupldrPath))
            {
                Console.WriteLine("Error: '{0}' does not exist.", setupldrPath);
                Program.Exit();
            }

            if (_installation.IsWindows2000)
            {
                PatchWindows2000SetupBootLoader(setupldrPath);
            }
            else
            {
                // Winndows XP or Windows Server 2003
                PatchWindowsXP2003SetupBootLoader(setupldrPath);
            }

            if (_installation.IsTargetContainsTemporaryInstallation)
            {
                ProgramUtils.CopyCriticalFile(
                    _installation.SetupDirectory + "ntoskrnl.ex_",
                    _installation.BootDirectory + "ntoskrnl.ex_");
            }
            else
            {
                // integration to installation media
                _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory("ntoskrnl.ex_");
            }
            Console.WriteLine("Uniprocessor kernel has been enabled.");

            _uniprocessorKernelEnabled = true;
        }
Ejemplo n.º 8
0
        public void UseMultiprocessorHal()
        {
            if (_multiprocessorHalEnabled)
            {
                return;
            }
            if (_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 (_installation.IsTargetContainsTemporaryInstallation)
            {
                if (File.Exists(_installation.BootDirectory + "halmacpi.dl_"))
                {
                    _installation.TextSetupInf.UseMultiprocessorHal();
                    _multiprocessorHalEnabled = true;
                    Console.WriteLine("Multiprocessor HAL has been enabled.");
                }
                else if (File.Exists(_installation.SetupDirectory + "halmacpi.dl_"))
                {
                    ProgramUtils.CopyCriticalFile(_installation.SetupDirectory + "halmacpi.dl_", _installation.BootDirectory + "halmacpi.dl_");
                    _installation.TextSetupInf.UseMultiprocessorHal();
                    Console.WriteLine("halmacpi.dl_ was copied from local source directory.");
                    _multiprocessorHalEnabled = true;
                    Console.WriteLine("Multiprocessor HAL has been enabled.");
                }
                else
                {
                    int index;
                    for (index = 3; index >= 1; index--)
                    {
                        var spFilename = string.Format("sp{0}.cab", index);
                        if (File.Exists(_installation.SetupDirectory + spFilename))
                        {
                            var cabInfo = new CabInfo(_installation.SetupDirectory + spFilename);
                            if (cabInfo.GetFile("halmacpi.dll") != null)
                            {
                                cabInfo.UnpackFile("halmacpi.dll", _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.");
                                _installation.TextSetupInf.UseMultiprocessorHal();
                                _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
            {
                _installation.TextSetupInf.UseMultiprocessorHal();
                _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory("halmacpi.dl_");
                _multiprocessorHalEnabled = true;
                Console.WriteLine("Multiprocessor HAL has been enabled.");
            }
        }