/// <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));
            }
        }
Exemple #2
0
        /// <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));
                        }
                    }
                }
            }
        }
Exemple #5
0
        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));
            }
        }
Exemple #6
0
        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));
            }
        }
Exemple #7
0
        /// <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));
                    }
                }
            }
        }