private void CopyDriverToSetupDriverDirectoryAndRegisterIt(PNPDriverINFFile pnpDriverInf)
        {
            Console.WriteLine();
            Console.WriteLine("Making the driver available to GUI mode setup.");

            // build list of source files:
            var driverFiles = new List <string>();

            foreach (var fileToCopy in DriverFilesToCopy)
            {
                DisableInBoxDeviceDriverFile(_installation.SetupDirectory, fileToCopy.DestinationFileName);

                driverFiles.Add(fileToCopy.RelativeSourceFilePath);
            }

            // make sure the .inf file will be copied too
            driverFiles.Add(pnpDriverInf.FileName);

            if (pnpDriverInf.CatalogFile != string.Empty)
            {
                if (File.Exists(DriverDirectory.Path + pnpDriverInf.CatalogFile))
                {
                    // add the catalog file too (to suppress unsigned driver warning message if the .inf has not been modified)
                    // the catalog file is in the same location as the INF file ( http://msdn.microsoft.com/en-us/library/windows/hardware/ff547502%28v=vs.85%29.aspx )
                    driverFiles.Add(pnpDriverInf.CatalogFile);
                }
            }

            // Note that we may perform some operations on the same directory more than once,
            // the allocate / register methods are supposed to return the previously allocated IDs on subsequent calls,
            // and skip registration of previously registered directories
            foreach (var relativeFilePath in driverFiles)
            {
                var fileName = FileSystemUtils.GetNameFromPath(relativeFilePath);
                var relativeDirectoryPath = relativeFilePath.Substring(0, relativeFilePath.Length - fileName.Length);

                // we need to copy the files to the proper sub-directories
                var sourceDir      = DriverDirectory.Path + relativeDirectoryPath;
                var pathParts      = sourceDir.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
                var destinationDir = pnpDriverInf.ClassName + '\\' + pathParts[pathParts.Length - 1] + relativeDirectoryPath + Path.DirectorySeparatorChar;
                _installation.CopyFileToSetupDriverDirectory(sourceDir + fileName, destinationDir, fileName);

                var sourceDirectoryInMediaRootForm = _installation.GetSourceDriverDirectoryInMediaRootForm(HardwareID + @"\" + relativeDirectoryPath);                 // note that we may violate ISO9660 - & is not allowed
                var sourceDiskID = _installation.TextSetupInf.AllocateSourceDiskID(_installation.ArchitectureIdentifier, sourceDirectoryInMediaRootForm);

                var destinationWinntDirectory   = _installation.GetDriverDestinationWinntDirectory(HardwareID + @"\" + relativeDirectoryPath);
                var destinationWinntDirectoryID = _installation.TextSetupInf.AllocateWinntDirectoryID(destinationWinntDirectory);

                _installation.TextSetupInf.SetSourceDisksFileEntry(_installation.ArchitectureIdentifier, sourceDiskID, destinationWinntDirectoryID, fileName, FileCopyDisposition.AlwaysCopy);

                // dosnet.inf: we add the file to the list of files to be copied to local source directory
                if (!_installation.IsTargetContainsTemporaryInstallation)
                {
                    _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceDriverDirectory(
                        sourceDirectoryInMediaRootForm, fileName);
                }

                _installation.HiveSoftwareInf.RegisterDriverDirectory(destinationWinntDirectory);
                if (_installation.Is64Bit)
                {
                    // hivsft32.inf
                    _installation.HiveSoftware32Inf.RegisterDriverDirectory(destinationWinntDirectory);
                }
            }

            // set inf to boot start:
            {
                var sourceDir      = DriverDirectory.Path;
                var pathParts      = sourceDir.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);
                var destinationDir = pnpDriverInf.ClassName + '\\' + pathParts[pathParts.Length - 1];

                var setupDriverDirectoryPath = _installation.GetSetupDriverDirectoryPath(destinationDir + Path.DirectorySeparatorChar);
                var installSectionName       = pnpDriverInf.GetDeviceInstallSectionName(HardwareID, _installation.ArchitectureIdentifier, _installation.MinorOSVersion, _installation.ProductType);
                pnpDriverInf.SetServiceToBootStart(installSectionName, _installation.ArchitectureIdentifier, _installation.MinorOSVersion);
                pnpDriverInf.SaveToDirectory(setupDriverDirectoryPath);
                // finished setting inf to boot start
            }
        }
Ejemplo n.º 2
0
        // update txtsetup.sif and dotnet.inf
        private void UpdateTextSetupInformationFileAndCopyFiles(string deviceID)
        {
            // Files.HwComponent.ID Section
            var driverINI = _driverDirectory.TextModeDriverSetupINI;
            var section   = driverINI.GetDriverFilesSection(deviceID);

            var serviceName = string.Empty;
            var driverKeys  = new List <string>();

            var sourceDirectoryInMediaRootForm = _installation.GetSourceDriverDirectoryInMediaRootForm(deviceID);
            var sourceDiskID = _installation.TextSetupInf.AllocateSourceDiskID(_installation.ArchitectureIdentifier, sourceDirectoryInMediaRootForm);

            var destinationWinntDirectory   = _installation.GetDriverDestinationWinntDirectory(_deviceID);
            var destinationWinntDirectoryID = _installation.TextSetupInf.AllocateWinntDirectoryID(destinationWinntDirectory);

            foreach (var line in section)
            {
                var keyAndValues   = INIFile.GetKeyAndValues(line);
                var directory      = driverINI.GetDirectoryOfDisk(keyAndValues.Value[0]);
                var fileName       = keyAndValues.Value[1];
                var sourceFilePath = _driverDirectory.Path + "." + directory + @"\" + fileName;
                var isDriver       = keyAndValues.Key.Equals("driver", StringComparison.InvariantCultureIgnoreCase);
                _installation.CopyFileToSetupDriverDirectory(sourceFilePath, deviceID + @"\", fileName);

                if (isDriver)
                {
                    _installation.CopyDriverToSetupRootDirectory(sourceFilePath, fileName);
                    if (_installation.IsTargetContainsTemporaryInstallation)
                    {
                        _installation.CopyFileFromSetupDirectoryToBootDirectory(fileName);
                    }
                }

                _installation.TextSetupInf.SetSourceDisksFileEntry(_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)
                    var 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.
                    _installation.TextSetupInf.SetSourceDisksFileDriverEntry(_installation.ArchitectureIdentifier, fileName, FileCopyDisposition.DoNotCopy);
                    _installation.TextSetupInf.SetFileFlagsEntryForDriver(fileName);
                    var deviceName = driverINI.GetDeviceName(deviceID);
                    _installation.TextSetupInf.InstructToLoadSCSIDriver(fileName, deviceName);
                }

                // add file to the list of files to be copied to local source directory
                if (!_installation.IsTargetContainsTemporaryInstallation)
                {
                    _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToLocalSourceDriverDirectory(sourceDirectoryInMediaRootForm, fileName);
                    if (isDriver)
                    {
                        _installation.DOSNetInf.InstructSetupToCopyFileFromSetupDirectoryToBootDirectory(fileName);
                    }
                }
            }

            section = driverINI.GetHardwareIdsSection(deviceID);
            foreach (var line in section)
            {
                var keyAndValues = INIFile.GetKeyAndValues(line);
                var 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);
                _installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(hardwareID, serviceName);
            }

            foreach (var driverKey in driverKeys)
            {
                section = driverINI.GetConfigSection(driverKey);
                foreach (var line in section)
                {
                    var keyAndValues      = INIFile.GetKeyAndValues(line);
                    var subKeyNameQuoted  = keyAndValues.Value[0];
                    var valueName         = keyAndValues.Value[1];
                    var valueType         = keyAndValues.Value[2];
                    var valueDataUnparsed = keyAndValues.Value[3];
                    var valueKind         = TextModeDriverSetupINIFile.GetRegistryValueKind(valueType);
                    var valueData         = HiveINIFile.ParseValueDataString(valueDataUnparsed, valueKind);
                    var subKeyName        = INIFile.Unquote(subKeyNameQuoted);

                    _installation.HiveSystemInf.SetServiceRegistryKey(serviceName, subKeyName, valueName, valueKind, valueData);
                    _installation.SetupRegistryHive.SetServiceRegistryKey(serviceName, subKeyName, valueName, valueKind, valueData);
                }
            }
        }