Example #1
0
        /// <summary>
        /// Extracts files from an MSI database and rewrites the paths embedded in the source .wixpdb to the output .wixpdb.
        /// </summary>
        private void MeltProduct()
        {
            // print friendly message saying what file is being decompiled
            Console.WriteLine("{0} / {1}", Path.GetFileName(this.inputFile), Path.GetFileName(this.inputPdbFile));

            // extract files from the .msi (unless suppressed) and get the path map of File ids to target paths
            string outputDirectory             = this.exportBasePath ?? Environment.GetEnvironmentVariable("WIX_TEMP");
            IDictionary <string, string> paths = null;

            using (InstallPackage package = new InstallPackage(this.inputFile, DatabaseOpenMode.ReadOnly, null, outputDirectory))
            {
                if (!this.suppressExtraction)
                {
                    package.ExtractFiles();
                }

                paths = package.Files.SourcePaths;
            }

            Pdb   inputPdb     = Pdb.Load(this.inputPdbFile, true, true);
            Table wixFileTable = inputPdb.Output.Tables["WixFile"];

            if (null != wixFileTable)
            {
                foreach (Row row in wixFileTable.Rows)
                {
                    WixFileRow fileRow = row as WixFileRow;
                    if (null != fileRow)
                    {
                        string newPath;
                        if (paths.TryGetValue(fileRow.File, out newPath))
                        {
                            fileRow.Source = Path.Combine(outputDirectory, newPath);
                        }
                    }
                }
            }

            string tempPath = Path.Combine(Environment.GetEnvironmentVariable("WIX_TEMP") ?? Path.GetTempPath(), Path.GetRandomFileName());

            try
            {
                inputPdb.Save(this.outputFile, null, null, tempPath);
            }
            finally
            {
                if (this.tidy)
                {
                    if (!AppCommon.DeleteDirectory(tempPath, this.messageHandler))
                    {
                        Console.WriteLine(MeltStrings.WAR_FailedToDeleteTempDir, tempPath);
                    }
                }
                else
                {
                    Console.WriteLine(MeltStrings.INF_TempDirLocatedAt, tempPath);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Main running method for the application.
        /// </summary>
        /// <param name="args">Commandline arguments to the application.</param>
        /// <returns>Returns the application error code.</returns>
        private int Run(string[] args)
        {
            try
            {
                // parse the command line
                this.ParseCommandLine(args);

                // exit if there was an error parsing the command line (otherwise the logo appears after error messages)
                if (Messaging.Instance.EncounteredError)
                {
                    return(Messaging.Instance.LastErrorNumber);
                }

                if (0 == this.inputFiles.Count)
                {
                    this.showHelp = true;
                }

                if (this.showLogo)
                {
                    AppCommon.DisplayToolHeader();
                }

                if (this.showHelp)
                {
                    Console.WriteLine(SmokeStrings.HelpMessage);
                    AppCommon.DisplayToolFooter();
                    return(Messaging.Instance.LastErrorNumber);
                }

                foreach (string parameter in this.invalidArgs)
                {
                    Messaging.Instance.OnMessage(WixWarnings.UnsupportedCommandLineArgument(parameter));
                }
                this.invalidArgs = null;

                string tempFilesLocation = AppCommon.GetTempLocation();
                validator.TempFilesLocation = tempFilesLocation;

                // TODO: rename ValidatorExtensions to "ValidatorFilterExtension" or something like that. Actually,
                //       revisit all of this as we try to build a more generic validation system around ICEs.
                //
                // load any extensions
                //bool validatorExtensionLoaded = false;
                //foreach (string extension in this.extensionList)
                //{
                //    WixExtension wixExtension = WixExtension.Load(extension);

                //    ValidatorExtension validatorExtension = wixExtension.ValidatorExtension;
                //    if (null != validatorExtension)
                //    {
                //        if (validatorExtensionLoaded)
                //        {
                //            throw new ArgumentException(String.Format(CultureInfo.CurrentUICulture, SmokeStrings.EXP_CannotLoadLinkerExtension, validatorExtension.GetType().ToString(), validator.Extension.ToString()), "ext");
                //        }

                //        validator.Extension = validatorExtension;
                //        validatorExtensionLoaded = true;
                //    }
                //}

                // disable ICE33 and ICE66 by default
                this.suppressICEs.Add("ICE33");
                this.suppressICEs.Add("ICE66");

                // set the ICEs
                string[] iceArray = new string[this.ices.Count];
                this.ices.CopyTo(iceArray, 0);
                validator.ICEs = iceArray;

                // set the suppressed ICEs
                string[] suppressICEArray = new string[this.suppressICEs.Count];
                this.suppressICEs.CopyTo(suppressICEArray, 0);
                validator.SuppressedICEs = suppressICEArray;

                // Load the pdb and assign the Output to the validator
                if (null != pdbPath)
                {
                    string pdbFullPath = Path.GetFullPath(pdbPath);
                    Pdb    pdb         = Pdb.Load(pdbFullPath, false);
                    this.validator.Output = pdb.Output;
                }

                foreach (string inputFile in this.inputFiles)
                {
                    // set the default cube file
                    Assembly assembly     = Assembly.GetExecutingAssembly();
                    string   appDirectory = Path.GetDirectoryName(assembly.Location);

                    if (this.addDefault)
                    {
                        switch (Path.GetExtension(inputFile).ToLower(CultureInfo.InvariantCulture))
                        {
                        case msm:
                            validator.AddCubeFile(Path.Combine(appDirectory, "mergemod.cub"));
                            break;

                        case msi:
                            validator.AddCubeFile(Path.Combine(appDirectory, "darice.cub"));
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedFileExtension(inputFile, ".msi, .msm"));
                        }
                    }

                    // print friendly message saying what file is being validated
                    Console.WriteLine(Path.GetFileName(inputFile));
                    Stopwatch stopwatch = Stopwatch.StartNew();

                    try
                    {
                        validator.Validate(Path.GetFullPath(inputFile));
                    }
                    catch (UnauthorizedAccessException)
                    {
                        Messaging.Instance.OnMessage(WixErrors.UnauthorizedAccess(Path.GetFullPath(inputFile)));
                    }
                    finally
                    {
                        stopwatch.Stop();
                        Messaging.Instance.OnMessage(WixVerboses.ValidatedDatabase(stopwatch.ElapsedMilliseconds));

                        if (this.tidy)
                        {
                            if (!AppCommon.DeleteDirectory(tempFilesLocation, Messaging.Instance))
                            {
                                Console.Error.WriteLine(SmokeStrings.WAR_FailedToDeleteTempDir, tempFilesLocation);
                            }
                        }
                        else
                        {
                            Console.WriteLine(SmokeStrings.INF_TempDirLocatedAt, tempFilesLocation);
                        }
                    }
                }
            }
            catch (WixException we)
            {
                Messaging.Instance.OnMessage(we.Error);
            }
            catch (Exception e)
            {
                Messaging.Instance.OnMessage(WixErrors.UnexpectedException(e.Message, e.GetType().ToString(), e.StackTrace));
                if (e is NullReferenceException || e is SEHException)
                {
                    throw;
                }
            }

            return(Messaging.Instance.LastErrorNumber);
        }