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); }
/// <summary> /// Update the registry, set TCP/IP related services to boot start /// </summary> private void SetRegistryToTCPIPBootStart(ISystemRegistryHive systemRegistryHive) { const int serviceBootStart = 0; if (systemRegistryHive is SetupRegistryHiveFile) { // text-mode: _installation.SetupRegistryHive.SetServiceRegistryKey("KSecDD", string.Empty, "Start", RegistryValueKind.DWord, serviceBootStart); _installation.SetupRegistryHive.SetServiceRegistryKey("KSecDD", string.Empty, "Group", RegistryValueKind.String, "Base"); _installation.SetupRegistryHive.SetServiceRegistryKey("NDIS", string.Empty, "Start", RegistryValueKind.DWord, serviceBootStart); _installation.SetupRegistryHive.SetServiceRegistryKey("NDIS", string.Empty, "Group", RegistryValueKind.String, "NDIS Wrapper"); } // GUI-mode: KSecDD is already taken care of by default // GUI-mode: NDIS is already taken care of by default if (!_installation.IsWindows2000) // Windows 2000 has an independent Tcpip service that does not require IPSec { systemRegistryHive.SetServiceRegistryKey("IPSec", string.Empty, "Start", RegistryValueKind.DWord, serviceBootStart); systemRegistryHive.SetServiceRegistryKey("IPSec", string.Empty, "Group", RegistryValueKind.String, "PNP_TDI"); // this will be ignored, text-mode setup will assign Tcpip to 'SCSI Miniport' (because that's where we put it in txtsetup.sif) systemRegistryHive.SetServiceRegistryKey("IPSec", string.Empty, "Type", RegistryValueKind.DWord, 1); // SERVICE_KERNEL_DRIVER } systemRegistryHive.SetServiceRegistryKey("Tcpip", string.Empty, "Start", RegistryValueKind.DWord, serviceBootStart); systemRegistryHive.SetServiceRegistryKey("Tcpip", string.Empty, "Group", RegistryValueKind.String, "PNP_TDI"); // this will be ignored, text-mode setup will assign IPSec to 'SCSI Miniport' (because that's where we put it in txtsetup.sif) systemRegistryHive.SetServiceRegistryKey("Tcpip", string.Empty, "Type", RegistryValueKind.DWord, 1); // SERVICE_KERNEL_DRIVER if (!_installation.IsWindows2000) // Windows 2000 has an independent Tcpip service that does not require IPSec // not absolutely necessary apparently. however. it's still a good practice: { systemRegistryHive.SetServiceRegistryKey("Tcpip", string.Empty, "DependOnService", RegistryValueKind.String, "IPSec"); } // Needed for stability systemRegistryHive.SetCurrentControlSetRegistryKey(@"Control\Session Manager\Memory Management", "DisablePagingExecutive", RegistryValueKind.DWord, 1); // not sure that's really necessary, but sanbootconf setup does it, so it seems like a good idea (1 by default for Server 2003) systemRegistryHive.SetServiceRegistryKey("Tcpip", "Parameters", "DisableDHCPMediaSense", RegistryValueKind.DWord, 1); var bootServices = new List <string>(new[] { "NDIS Wrapper", "NDIS", "Base", "PNP_TDI" }); systemRegistryHive.AddServiceGroupsAfterSystemBusExtender(bootServices); }
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); } }