コード例 #1
0
 private void InstructToLoadTextModeDeviceService(BaseDeviceService deviceService)
 {
     // update txtsetup.sif
     if (deviceService.ServiceGroup == string.Empty)
     {
         // No group, which means txtsetup.sif will have effect on initialization order.
         // In final Windows this means the service is initialized after all other services.
         // To do the same in text-mode, we should load this service last (which means using the [CdRomDrivers.Load] section):
         _installation.TextSetupInf.InstructToLoadCdRomDriversDriver(
             deviceService.TextModeFileName,
             deviceService.DeviceDescription);
     }
     else
     {
         // we have set a group in setupreg.hiv, so for text-mode it doesn't matter where we put the service in txtsetup.sif,
         // however, some of the [xxxx.Load] groups will stick and cause problems later (GUI-mode / final Windows),
         // see TextSetupINFFile.Load.cs to see which groups may cause problems
         //
         // Note that the service is renamed back to its original name if necessary.
         _installation.TextSetupInf.InstructToLoadKeyboardDriver(
             deviceService.TextModeFileName,
             deviceService.DeviceDescription);
     }
 }
コード例 #2
0
        private void RegisterDeviceService(ISystemRegistryHive systemRegistryHive, PNPDriverINFFile pnpDriverInf, BaseDeviceService deviceService)
        {
            // We ignore start type. if the user uses this program, she wants to boot something!
            const int startType = 0;
            // Note: using a different service registry key under CurrentControlSet\Services with an ImagePath entry referring to the .sys will not work in text mode setup!
            // Text-mode setup will always initialize services based on the values stored under Services\serviceName, where serviceName is the service file name without the .sys extension.

            // write all to registry:
            var serviceName = deviceService.ServiceName;

            if (deviceService.ServiceDisplayName != string.Empty)
            {
                systemRegistryHive.SetServiceRegistryKey(
                    serviceName,
                    string.Empty,
                    "DisplayName",
                    RegistryValueKind.String,
                    deviceService.ServiceDisplayName);
            }
            systemRegistryHive.SetServiceRegistryKey(serviceName, string.Empty, "ErrorControl", RegistryValueKind.DWord, deviceService.ErrorControl);
            if (deviceService.ServiceGroup != string.Empty)
            {
                systemRegistryHive.SetServiceRegistryKey(
                    serviceName,
                    string.Empty,
                    "Group",
                    RegistryValueKind.String,
                    deviceService.ServiceGroup);
            }
            systemRegistryHive.SetServiceRegistryKey(serviceName, string.Empty, "Start", RegistryValueKind.DWord, startType);
            systemRegistryHive.SetServiceRegistryKey(serviceName, string.Empty, "Type", RegistryValueKind.DWord, deviceService.ServiceType);

            if (systemRegistryHive is HiveSystemINFFile)             // GUI Mode registry
            {
                systemRegistryHive.SetServiceRegistryKey(
                    serviceName,
                    string.Empty,
                    "ImagePath",
                    RegistryValueKind.String,
                    deviceService.ImagePath);
            }

            // Note that software key will stick from text-mode:
            var softwareKeyName = @"Control\Class\" + pnpDriverInf.ClassGUID + @"\" + _classInstanceID;

            var service = deviceService as NetworkDeviceService;

            if (service != null)
            {
                var netCfgInstanceID = service.NetCfgInstanceID;
                // - sanbootconf and iScsiBP use this value, but it's not necessary for successful boot, static IP can be used instead.
                // - the presence of this value will stick and stay for the GUI mode
                // - the presence of this value during GUI Mode will prevent the IP settings from being resetted
                // - the presence of this value will cause Windows 2000 \ XP x86 to hang after the NIC driver installation (there is no problem with Windows Server 2003)
                // - the presence of this value will cause Windows XP x64 to hang during the "Installing Network" phase (there is no problem with Windows Server 2003)

                // we will set this value so sanbootconf / iScsiBP could use it, and if necessary, delete it before the NIC driver installation (using hal.inf)
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "NetCfgInstanceId", RegistryValueKind.String, netCfgInstanceID);
                if (!_installation.IsWindowsServer2003)
                {
                    // delete the NetCfgInstanceId registry value during the beginning of GUI-mode setup
                    _installation.HalInf.DeleteNetCfgInstanceIdFromNetworkAdapterClassInstance(_classInstanceID);
                }

                // The Linkage subkey is critical, and is used to bind the network adapter to TCP/IP:
                // - The NetCfgInstanceId here is the one Windows actually uses for TCP/IP configuration.
                // - The first component in one entry corresponds to the first component in the other entries:
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "Linkage", "Export", RegistryValueKind.MultiString, new[] { @"\Device\" + netCfgInstanceID });
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "Linkage", "RootDevice", RegistryValueKind.MultiString, new[] { netCfgInstanceID });                 // Windows can still provide TCP/IP without this entry
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "Linkage", "UpperBind", RegistryValueKind.MultiString, new[] { "Tcpip" });
            }

            // We need to make sure the software key is created, otherwise two devices can end up using the same software key

            // Note for network adapters:
            // "MatchingDeviceId" is not critical for successfull boot or devices which are not network adapters, but it's critical for NICBootConf in case it's being used
            // Note: Windows will store the hardwareID as it appears in the driver, including &REV
            systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "MatchingDeviceId", RegistryValueKind.String, HardwareID.ToLower());

            // not necessary. in addition, it will also be performed by GUI-mode setup
            if (deviceService.DeviceDescription != string.Empty)
            {
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "DriverDesc", RegistryValueKind.String,
                                                                   deviceService.DeviceDescription);
            }
            if (pnpDriverInf.DriverVersion != string.Empty)
            {
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "DriverVersion", RegistryValueKind.String,
                                                                   pnpDriverInf.DriverVersion);
            }
            if (pnpDriverInf.Provider != string.Empty)
            {
                systemRegistryHive.SetCurrentControlSetRegistryKey(softwareKeyName, "ProviderName", RegistryValueKind.String,
                                                                   pnpDriverInf.Provider);
            }
        }
コード例 #3
0
        // unlike other types of hardware (SCSI controllers etc.), it's not enough to add a NIC to the
        // Criticla Device Database (CDDB) to make it usable during boot (Note that NIC driver is an NDIS
        // miniport driver, and the driver does not have an AddDevice() routine and instead uses NDIS' AddDevice())
        // This method performs the additional steps needed for a NIC that is added to the CDDB, which are basically letting Windows
        // know which device class instance is related to the device (TCP/IP settings are tied to the device class instance)
        // The above is true for both text-mode and GUI-mode / Final Windows.
        // Note: it's best to use a driver that does these steps during boot, I have written NICBootConf for that purpose.

        /*
         * private void PreconfigureCriticalNetworkAdapter(PNPDriverINFFile pnpDriverInf, string enumerator, string deviceID, string deviceInstanceID, DeviceService deviceService)
         * {
         *      string keyName = @"ControlSet001\Enum\" + enumerator + @"\" + deviceID + @"\" + deviceInstanceID;
         *      m_installation.SetupRegistryHive.SetRegistryKey(keyName, "Driver", RegistryValueKind.String, pnpDriverInf.ClassGUID + @"\" + m_classInstanceID);
         *      // The presence of DeviceDesc is critical for some reason, but any value can be used
         *      m_installation.SetupRegistryHive.SetRegistryKey(keyName, "DeviceDesc", RegistryValueKind.String, deviceService.DeviceDescription);
         *
         *      // not critical:
         *      m_installation.SetupRegistryHive.SetRegistryKey(keyName, "ClassGUID", RegistryValueKind.String, pnpDriverInf.ClassGUID);
         *
         *      // we must not specify ServiceName or otherwise kernel-PNP will skip this device
         *
         *      // let kernel-PNP take care of the rest for us, ClassGUID is not critical:
         *      m_installation.TextSetupInf.AddDeviceToCriticalDeviceDatabase(this.HardwareID, deviceService.ServiceName);
         * }
         */

        /// <summary>
        /// When using this method, there is no need to use the Critical Device Database
        /// </summary>
        private void PreconfigureDeviceInstance(PNPDriverINFFile pnpDriverInf, string enumerator, string deviceID, string deviceInstanceID, BaseDeviceService deviceService)
        {
            PreconfigureDeviceInstance(pnpDriverInf, _installation.SetupRegistryHive, enumerator, deviceID, deviceInstanceID, deviceService);
            // Apparently this is not necessary for the devices to work properly in GUI-mode, because configuration will stick from text-mode setup:
            PreconfigureDeviceInstance(pnpDriverInf, _installation.HiveSystemInf, enumerator, deviceID, deviceInstanceID, deviceService);
        }
コード例 #4
0
        private void PreconfigureDeviceInstance(PNPDriverINFFile pnpDriverInf, ISystemRegistryHive systemRegistryHive, string enumerator, string deviceID, string deviceInstanceID, BaseDeviceService deviceService)
        {
            var driver           = pnpDriverInf.ClassGUID.ToUpper() + @"\" + _classInstanceID;
            var manufacturerName = pnpDriverInf.GetDeviceManufacturerName(HardwareID, _installation.ArchitectureIdentifier, _installation.MinorOSVersion, _installation.ProductType);

            var hardwareKeyName = @"Enum\" + enumerator + @"\" + deviceID + @"\" + deviceInstanceID;

            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "ClassGUID", RegistryValueKind.String, pnpDriverInf.ClassGUID);
            // The presence of DeviceDesc is critical for some reason, but any value can be used
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "DeviceDesc", RegistryValueKind.String, deviceService.DeviceDescription);
            // "Driver" is used to help Windows determine which software key belong to this hardware key.
            // Note: When re-installing the driver, the software key to be used will be determined by this value as well.
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "Driver", RegistryValueKind.String, driver);
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "Service", RegistryValueKind.String, deviceService.ServiceName);

            // ConfigFlags is not related to the hardware, it's the status of the configuration of the device by Windows (CONFIGFLAG_FAILEDINSTALL etc.)
            // the presence of this value tells windows the device has driver installed
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "ConfigFlags", RegistryValueKind.DWord, 0);

            if (PNPDriverINFFile.IsRootDevice(HardwareID))
            {
                // Windows uses the "HardwareID" entry to determine if the hardware is already installed,
                // We don't have to add this value for physical devices, because Windows will get this value from the device,
                // but we must add this for virtual devices, or we will find ourselves with duplicity when re-installing (e.g. two Microsoft iScsi Initiators).
                systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "HardwareID", RegistryValueKind.MultiString,
                                                                   new[] { HardwareID });
            }

            // not necessary:
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "Mfg", RegistryValueKind.String, manufacturerName);
            systemRegistryHive.SetCurrentControlSetRegistryKey(hardwareKeyName, "Class", RegistryValueKind.String, pnpDriverInf.ClassName);
        }
コード例 #5
0
        private void ProcessServiceInstallSection(PNPDriverINFFile pnpDriverInf, string sectionName, string serviceName)
        {
            Console.WriteLine("Registering service '" + serviceName + "'");
            var serviceInstallSection = pnpDriverInf.GetSection(sectionName);

            var displayName        = string.Empty;
            var serviceBinary      = string.Empty;
            var serviceTypeString  = string.Empty;
            var errorControlString = string.Empty;
            var loadOrderGroup     = string.Empty;

            //string guiModeRelativeRoot = @"Services\" + serviceName;
            foreach (var line in serviceInstallSection)
            {
                var keyAndValues = INIFile.GetKeyAndValues(line);
                switch (keyAndValues.Key)
                {
                case "AddReg":
                {
                    // http://msdn.microsoft.com/en-us/library/ff546326%28v=vs.85%29.aspx
                    // AddReg will always come after ServiceBinaryServiceBinary

                    var relativeRoot = @"Services\" + serviceName;

                    foreach (var registrySectionName in keyAndValues.Value)
                    {
                        ProcessAddRegSection(pnpDriverInf, registrySectionName, relativeRoot);
                    }
                    break;
                }

                case "DisplayName":
                {
                    displayName = INIFile.TryGetValue(keyAndValues.Value, 0);
                    break;
                }

                case "ServiceBinary":
                {
                    serviceBinary = INIFile.TryGetValue(keyAndValues.Value, 0);
                    break;
                }

                case "ServiceType":
                {
                    serviceTypeString = INIFile.TryGetValue(keyAndValues.Value, 0);
                    break;
                }

                case "ErrorControl":
                {
                    errorControlString = INIFile.TryGetValue(keyAndValues.Value, 0);
                    break;
                }

                case "LoadOrderGroup":
                {
                    loadOrderGroup = INIFile.TryGetValue(keyAndValues.Value, 0);
                    break;
                }
                }
            }

            displayName = pnpDriverInf.ExpandToken(displayName);
            displayName = INIFile.Unquote(displayName);

            var fileName  = serviceBinary.Replace(@"%12%\", string.Empty);
            var imagePath = PNPDriverINFFile.ExpandDirID(serviceBinary);

            var serviceType  = PNPDriverINFFile.ConvertFromIntStringOrHexString(serviceTypeString);
            var errorControl = PNPDriverINFFile.ConvertFromIntStringOrHexString(errorControlString);

            var deviceDescription = pnpDriverInf.GetDeviceDescription(_hardwareID, _architectureIdentifier, _minorOSVersion,
                                                                      _productType);

            BaseDeviceService deviceService;

            if (pnpDriverInf.IsNetworkAdapter)
            {
                // this is a nic, we are binding TCP/IP to it
                // we need a unique NetCfgInstanceID that will be used with Tcpip service and the nic's class
                var netCfgInstanceID = "{" + Guid.NewGuid().ToString().ToUpper() + "}";
                deviceService = new NetworkDeviceService(deviceDescription, serviceName, displayName, loadOrderGroup, serviceType,
                                                         errorControl, fileName, imagePath, netCfgInstanceID);
                _deviceServices.Add(deviceService);
            }
            else
            {
                deviceService = new BaseDeviceService(deviceDescription, serviceName, displayName, loadOrderGroup, serviceType,
                                                      errorControl, fileName, imagePath);
                _deviceServices.Add(deviceService);
            }
        }