/// <summary> /// Calls self-reg harvester. /// </summary> /// <param name="parentElement">The parent element.</param> /// <param name="fileSource">The file source.</param> private void HarvestSelfReg(Wix.IParentElement parentElement, string fileSource) { // try the self-reg harvester try { DllHarvester dllHarvester = new DllHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = dllHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } } catch (TargetInvocationException tie) { if (tie.InnerException is EntryPointNotFoundException) { // No DllRegisterServer(), which is fine by me. } else { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, tie.Message)); } } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } }
/// <summary> /// Mutate a file. /// </summary> /// <param name="parentElement">The parent of the element to mutate.</param> /// <param name="file">The file to mutate.</param> protected void MutateFile(Wix.IParentElement parentElement, Wix.File file) { if (null == file.Source) { return; } string fileExtension = Path.GetExtension(file.Source); string fileSource = this.Core.ResolveFilePath(file.Source); if (String.Equals(".dll", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".ocx", fileExtension, StringComparison.OrdinalIgnoreCase)) // ActiveX { mutateDllComServer(parentElement, fileSource); } else if (String.Equals(".exe", fileExtension, StringComparison.OrdinalIgnoreCase)) { mutateExeComServer(parentElement, fileSource); } else if (string.Equals(".plb", fileExtension, StringComparison.OrdinalIgnoreCase) || string.Equals(".tlb", fileExtension, StringComparison.OrdinalIgnoreCase)) { // try the type library harvester try { ATLTypeLibraryHarvester atlTypeLibHarvester = new ATLTypeLibraryHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingTypeLib(fileSource)); Wix.RegistryValue[] registryValues = atlTypeLibHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } } catch (COMException ce) { // 0x8002801C (TYPE_E_REGISTRYACCESS) // If we don't have permission to harvest typelibs, it's likely because we're on // Vista or higher and aren't an Admin, or don't have the appropriate QFE installed. if (!this.calledPerUserTLibReg && (0x8002801c == unchecked ((uint)ce.ErrorCode))) { this.Core.OnMessage(WixWarnings.InsufficientPermissionHarvestTypeLib()); } else if (0x80029C4A == unchecked ((uint)ce.ErrorCode)) // generic can't load type library { this.Core.OnMessage(UtilWarnings.TypeLibLoadFailed(fileSource, ce.Message)); } } } }
/// <summary> /// Parse a value from a line. /// </summary> /// <param name="sr">Reader for the reg file.</param> /// <param name="name">Name of the value.</param> /// <param name="value">Value of the value.</param> /// <param name="type">Type of the value.</param> /// <returns>true if the value can be parsed, false otherwise.</returns> private bool GetValue(StreamReader sr, ref string name, ref string value, out Wix.RegistryValue.TypeType type) { string line = this.GetNextLine(sr); if (null == line || 0 == line.Length) { type = 0; return(false); } string[] parts; if (line.StartsWith("@")) { // Special case for default value parts = line.Trim().Split("=".ToCharArray(), 2); name = null; } else { parts = line.Trim().Split("=".ToCharArray()); // It is valid to have an '=' in the name or the data. This is probably a string so the separator will be '"="'. if (2 != parts.Length) { string[] stringSeparator = new string[] { "\"=\"" }; parts = line.Trim().Split(stringSeparator, StringSplitOptions.None); if (2 != parts.Length) { // Line still no parsed correctly throw new ApplicationException(String.Format("Cannot parse value: {0} at line {1}.", line, this.currentLineNumber)); } // Put back quotes stripped by Split() parts[0] += "\""; parts[1] = "\"" + parts[1]; } name = parts[0].Substring(1, parts[0].Length - 2); } if (parts[1].StartsWith("hex:")) { // binary value = parts[1].Substring(4); type = Wix.RegistryValue.TypeType.binary; } else if (parts[1].StartsWith("dword:")) { // dword value = parts[1].Substring(6); type = Wix.RegistryValue.TypeType.integer; } else if (parts[1].StartsWith("hex(2):")) { // expandable string value = parts[1].Substring(7); type = Wix.RegistryValue.TypeType.expandable; } else if (parts[1].StartsWith("hex(7):")) { // multi-string value = parts[1].Substring(7); type = Wix.RegistryValue.TypeType.multiString; } else if (parts[1].StartsWith("hex(")) { // Give a better error when we find something that isn't supported // by specifying the type that isn't supported. string unsupportedType = ""; if (parts[1].StartsWith("hex(0")) { unsupportedType = "REG_NONE"; } else if (parts[1].StartsWith("hex(6")) { unsupportedType = "REG_LINK"; } else if (parts[1].StartsWith("hex(8")) { unsupportedType = "REG_RESOURCE_LIST"; } else if (parts[1].StartsWith("hex(9")) { unsupportedType = "REG_FULL_RESOURCE_DESCRIPTOR"; } else if (parts[1].StartsWith("hex(a")) { unsupportedType = "REG_RESOURCE_REQUIREMENTS_LIST"; } else if (parts[1].StartsWith("hex(b")) { unsupportedType = "REG_QWORD"; } // REG_NONE(0), REG_LINK(6), REG_RESOURCE_LIST(8), REG_FULL_RESOURCE_DESCRIPTOR(9), REG_RESOURCE_REQUIREMENTS_LIST(a), REG_QWORD(b) this.Core.OnMessage(UtilWarnings.UnsupportedRegistryType(parts[0], this.currentLineNumber, unsupportedType)); type = 0; return(false); } else if (parts[1].StartsWith("\"")) { // string value = parts[1].Substring(1, parts[1].Length - 2); type = Wix.RegistryValue.TypeType.@string; } else { // unsupported value throw new ApplicationException(String.Format("Unsupported registry value {0} at line {1}.", line, this.currentLineNumber)); } return(true); }
/// <summary> /// Mutate a file. /// </summary> /// <param name="parentElement">The parent of the element to mutate.</param> /// <param name="file">The file to mutate.</param> private void MutateFile(Wix.IParentElement parentElement, Wix.File file) { if (null != file.Source) { string fileExtension = Path.GetExtension(file.Source); string fileSource = this.Core.ResolveFilePath(file.Source); if (String.Equals(".ax", fileExtension, StringComparison.OrdinalIgnoreCase) || // DirectShow filter String.Equals(".dll", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".exe", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".ocx", fileExtension, StringComparison.OrdinalIgnoreCase)) // ActiveX { // try the assembly harvester try { AssemblyHarvester assemblyHarvester = new AssemblyHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingAssembly(fileSource)); Wix.RegistryValue[] registryValues = assemblyHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } // also try self-reg since we could have a mixed-mode assembly this.HarvestSelfReg(parentElement, fileSource); } catch (BadImageFormatException) // not an assembly, try raw DLL. { this.HarvestSelfReg(parentElement, fileSource); } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.AssemblyHarvestFailed(fileSource, ex.Message)); } } else if (String.Equals(".olb", fileExtension, StringComparison.OrdinalIgnoreCase) || // type library String.Equals(".tlb", fileExtension, StringComparison.OrdinalIgnoreCase)) // type library { // try the type library harvester try { TypeLibraryHarvester typeLibHarvester = new TypeLibraryHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingTypeLib(fileSource)); Wix.RegistryValue[] registryValues = typeLibHarvester.HarvestRegistryValues(fileSource); foreach (Wix.RegistryValue registryValue in registryValues) { parentElement.AddChild(registryValue); } } catch (COMException ce) { // 0x8002801C (TYPE_E_REGISTRYACCESS) // If we don't have permission to harvest typelibs, it's likely because we're on // Vista or higher and aren't an Admin, or don't have the appropriate QFE installed. if (!this.calledPerUserTLibReg && (0x8002801c == unchecked ((uint)ce.ErrorCode))) { this.Core.OnMessage(WixWarnings.InsufficientPermissionHarvestTypeLib()); } else if (0x80029C4A == unchecked ((uint)ce.ErrorCode)) // generic can't load type library { this.Core.OnMessage(UtilWarnings.TypeLibLoadFailed(fileSource, ce.Message)); } } } } }
private void mutateDllComServer(Wix.IParentElement parentElement, string fileSource) { try { ATLDllHarvester dllHarvester = new ATLDllHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = dllHarvester.HarvestRegistryValues(fileSource, addShellExtensionKey); // Set Win64 on parent component if 64-bit PE. Wix.Component component = parentElement as Wix.Component; if ((component != null) && dllHarvester.Win64) { component.Win64 = Wix.YesNoType.yes; } foreach (Wix.RegistryValue registryValue in registryValues) { if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ATLRegistrarKey, StringComparison.InvariantCultureIgnoreCase)) { continue; // ignore ATL Registrar values } else if (addShellExtensionKey && (Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ShellKey, StringComparison.InvariantCultureIgnoreCase) && string.IsNullOrEmpty(registryValue.Name)) { continue; // ignore Shell Extension base key } else { parentElement.AddChild(registryValue); } } } catch (TargetInvocationException tie) { if (tie.InnerException is EntryPointNotFoundException) { // No DllRegisterServer() } else { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, tie.Message)); } } catch (COMException ce) { // 0x8002801C (TYPE_E_REGISTRYACCESS) // If we don't have permission to harvest typelibs, it's likely because we're on // Vista or higher and aren't an Admin, or don't have the appropriate QFE installed. if (!this.calledPerUserTLibReg && (0x8002801c == unchecked ((uint)ce.ErrorCode))) { this.Core.OnMessage(WixWarnings.InsufficientPermissionHarvestTypeLib()); } else { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ce.Message)); } } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } }
private void mutateExeComServer(Wix.IParentElement parentElement, string fileSource) { try { ATLExeHarvester exeHarvester = new ATLExeHarvester(useDash); this.Core.OnMessage(UtilVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = exeHarvester.HarvestRegistryValues(fileSource); // Set Win64 on parent component if 64-bit PE. Wix.Component component = parentElement as Wix.Component; if ((component != null) && exeHarvester.Win64) { component.Win64 = Wix.YesNoType.yes; } foreach (Wix.RegistryValue registryValue in registryValues) { if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ATLRegistrarKey)) { continue; // ignore ATL Registrar values } else if (addShellExtensionKey && (Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ShellKey, StringComparison.InvariantCultureIgnoreCase) && string.IsNullOrEmpty(registryValue.Name)) { continue; // ignore Shell Extension base key } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && registryValue.Key.StartsWith(@"CLSID\{") && registryValue.Key.EndsWith(@"}\LocalServer32", StringComparison.OrdinalIgnoreCase)) { // Fix double (or double-double) quotes around LocalServer32 value, if present. if (registryValue.Value.StartsWith("\"") && registryValue.Value.EndsWith("\"")) { registryValue.Value = registryValue.Value.Substring(1, registryValue.Value.Length - 2); } else if (registryValue.Value.StartsWith("\"\"") && registryValue.Value.EndsWith("\"\"")) { registryValue.Value = registryValue.Value.Substring(2, registryValue.Value.Length - 4); } parentElement.AddChild(registryValue); } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, "Interface", StringComparison.OrdinalIgnoreCase)) { continue; // ignore extra HKCR\Interface key } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && !registryValue.Key.StartsWith(@"SOFTWARE\Classes\Root", StringComparison.InvariantCultureIgnoreCase)) { continue; // ignore anything written to HKLM for now, unless it's under SW\Classes\Root .. } else { parentElement.AddChild(registryValue); } } } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } }
/// <summary> /// Mutate a file. /// </summary> /// <param name="parentElement">The parent of the element to mutate.</param> /// <param name="file">The file to mutate.</param> protected void MutateFile(Wix.IParentElement parentElement, Wix.File file) { if (null != file.Source) { string fileExtension = Path.GetExtension(file.Source); string fileSource = this.Core.ResolveFilePath(file.Source); if (String.Equals(".dll", fileExtension, StringComparison.OrdinalIgnoreCase) || String.Equals(".ocx", fileExtension, StringComparison.OrdinalIgnoreCase)) // ActiveX { try { ATLDllHarvester dllHarvester = new ATLDllHarvester(); this.Core.OnMessage(UtilVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = dllHarvester.HarvestRegistryValues(fileSource, addShellExtensionKey); // Set Win64 on parent component if 64-bit PE. Wix.Component component = parentElement as Wix.Component; if ((component != null) && dllHarvester.Win64) { component.Win64 = Wix.YesNoType.yes; } foreach (Wix.RegistryValue registryValue in registryValues) { if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ATLRegistrarKey, StringComparison.InvariantCultureIgnoreCase)) { continue; // ignore ATL Registrar values } else if (addShellExtensionKey && (Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ShellKey, StringComparison.InvariantCultureIgnoreCase) && string.IsNullOrEmpty(registryValue.Name)) { continue; // ignore Shell Extension base key } else { parentElement.AddChild(registryValue); } } } catch (TargetInvocationException tie) { if (tie.InnerException is EntryPointNotFoundException) { // No DllRegisterServer() } else { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, tie.Message)); } } catch (COMException ce) { // 0x8002801C (TYPE_E_REGISTRYACCESS) // If we don't have permission to harvest typelibs, it's likely because we're on // Vista or higher and aren't an Admin, or don't have the appropriate QFE installed. if (!this.calledPerUserTLibReg && (0x8002801c == unchecked ((uint)ce.ErrorCode))) { this.Core.OnMessage(WixWarnings.InsufficientPermissionHarvestTypeLib()); } else { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ce.Message)); } } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } } else if (String.Equals(".exe", fileExtension, StringComparison.OrdinalIgnoreCase)) { try { ATLExeHarvester exeHarvester = new ATLExeHarvester(useDash); this.Core.OnMessage(UtilVerboses.HarvestingSelfReg(fileSource)); Wix.RegistryValue[] registryValues = exeHarvester.HarvestRegistryValues(fileSource); // Set Win64 on parent component if 64-bit PE. Wix.Component component = parentElement as Wix.Component; if ((component != null) && exeHarvester.Win64) { component.Win64 = Wix.YesNoType.yes; } foreach (Wix.RegistryValue registryValue in registryValues) { if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ATLRegistrarKey)) { continue; // ignore ATL Registrar values } else if (addShellExtensionKey && (Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && string.Equals(registryValue.Key, ATLRegistryHarvester.ShellKey, StringComparison.InvariantCultureIgnoreCase) && string.IsNullOrEmpty(registryValue.Name)) { continue; // ignore Shell Extension base key } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && registryValue.Key.StartsWith(@"CLSID\{") && registryValue.Key.EndsWith(@"}\LocalServer32", StringComparison.OrdinalIgnoreCase)) { // Fix double (or double-double) quotes around LocalServer32 value, if present. if (registryValue.Value.StartsWith("\"") && registryValue.Value.EndsWith("\"")) { registryValue.Value = registryValue.Value.Substring(1, registryValue.Value.Length - 2); } else if (registryValue.Value.StartsWith("\"\"") && registryValue.Value.EndsWith("\"\"")) { registryValue.Value = registryValue.Value.Substring(2, registryValue.Value.Length - 4); } parentElement.AddChild(registryValue); } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKCR == registryValue.Root) && string.Equals(registryValue.Key, "Interface", StringComparison.OrdinalIgnoreCase)) { continue; // ignore extra HKCR\Interface key } else if ((Wix.RegistryValue.ActionType.write == registryValue.Action) && (Wix.RegistryRootType.HKLM == registryValue.Root) && !registryValue.Key.StartsWith(@"SOFTWARE\Classes\Root", StringComparison.InvariantCultureIgnoreCase)) { continue; // ignore anything written to HKLM for now, unless it's under SW\Classes\Root .. } else { parentElement.AddChild(registryValue); } } } catch (Exception ex) { this.Core.OnMessage(UtilWarnings.SelfRegHarvestFailed(fileSource, ex.Message)); } } } }