Example #1
0
        public void Execute()
        {
            Dictionary <string, RegistryTuple>     registryKeyRows          = null;
            Dictionary <string, ResolvedDirectory> targetPathsByDirectoryId = null;
            Dictionary <string, string>            componentIdGenSeeds      = null;
            Dictionary <string, List <FileTuple> > filesByComponentId       = null;

            // Find components with generatable guids.
            foreach (var componentRow in this.Section.Tuples.OfType <ComponentTuple>())
            {
                // Skip components that do not specify generate guid.
                if (componentRow.ComponentId != "*")
                {
                    continue;
                }

                var odbcDataSourceKeyPath = (componentRow.Attributes & MsiInterop.MsidbComponentAttributesODBCDataSource) != 0;

                if (String.IsNullOrEmpty(componentRow.KeyPath) || odbcDataSourceKeyPath)
                {
                    this.Messaging.Write(ErrorMessages.IllegalComponentWithAutoGeneratedGuid(componentRow.SourceLineNumbers));
                    continue;
                }

                var registryKeyPath = (componentRow.Attributes & MsiInterop.MsidbComponentAttributesRegistryKeyPath) != 0;

                if (registryKeyPath)
                {
                    if (registryKeyRows is null)
                    {
                        registryKeyRows = this.Section.Tuples.OfType <RegistryTuple>().ToDictionary(t => t.Registry);
                    }

                    if (registryKeyRows.TryGetValue(componentRow.KeyPath, out var foundRow))
                    {
                        var is64Bit = (componentRow.Attributes & MsiInterop.MsidbComponentAttributes64bit) != 0;
                        var bitness = is64Bit ? "64" : String.Empty;
                        var regkey  = String.Concat(bitness, foundRow.AsString(1), "\\", foundRow.AsString(2), "\\", foundRow.AsString(3));
                        componentRow.ComponentId = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, regkey.ToLowerInvariant()).ToString("B").ToUpperInvariant();
                    }
                }
                else // must be a File KeyPath.
                {
                    // If the directory table hasn't been loaded into an indexed hash
                    // of directory ids to target names do that now.
                    if (targetPathsByDirectoryId is null)
                    {
                        var directories = this.Section.Tuples.OfType <DirectoryTuple>().ToList();

                        targetPathsByDirectoryId = new Dictionary <string, ResolvedDirectory>(directories.Count);

                        // Get the target paths for all directories.
                        foreach (var row in directories)
                        {
                            // If the directory Id already exists, we will skip it here since
                            // checking for duplicate primary keys is done later when importing tables
                            // into database
                            if (targetPathsByDirectoryId.ContainsKey(row.Directory))
                            {
                                continue;
                            }

                            var targetName = Common.GetName(row.DefaultDir, false, true);
                            targetPathsByDirectoryId.Add(row.Directory, new ResolvedDirectory(row.Directory_Parent, targetName));
                        }
                    }

                    // If the component id generation seeds have not been indexed
                    // from the WixDirectory table do that now.
                    if (componentIdGenSeeds is null)
                    {
                        // If there are any WixDirectory rows, build up the Component Guid
                        // generation seeds indexed by Directory/@Id.
                        componentIdGenSeeds = this.Section.Tuples.OfType <WixDirectoryTuple>()
                                              .Where(t => !String.IsNullOrEmpty(t.ComponentGuidGenerationSeed))
                                              .ToDictionary(t => t.Directory_, t => t.ComponentGuidGenerationSeed);
                    }

                    // if the file rows have not been indexed by File.Component yet
                    // then do that now
                    if (filesByComponentId is null)
                    {
                        var files = this.Section.Tuples.OfType <FileTuple>().ToList();

                        filesByComponentId = new Dictionary <string, List <FileTuple> >(files.Count);

                        foreach (var file in files)
                        {
                            if (!filesByComponentId.TryGetValue(file.Component_, out var componentFiles))
                            {
                                componentFiles = new List <FileTuple>();
                                filesByComponentId.Add(file.Component_, componentFiles);
                            }

                            componentFiles.Add(file);
                        }
                    }

                    // validate component meets all the conditions to have a generated guid
                    var    currentComponentFiles = filesByComponentId[componentRow.Component];
                    var    numFilesInComponent   = currentComponentFiles.Count;
                    string path = null;

                    foreach (var fileRow in currentComponentFiles)
                    {
                        if (fileRow.File == componentRow.KeyPath)
                        {
                            // calculate the key file's canonical target path
                            string directoryPath = PathResolver.GetDirectoryPath(targetPathsByDirectoryId, componentIdGenSeeds, componentRow.Directory_, true);
                            string fileName      = Common.GetName(fileRow.LongFileName, false, true).ToLowerInvariant();
                            path = Path.Combine(directoryPath, fileName);

                            // find paths that are not canonicalized
                            if (path.StartsWith(@"PersonalFolder\my pictures", StringComparison.Ordinal) ||
                                path.StartsWith(@"ProgramFilesFolder\common files", StringComparison.Ordinal) ||
                                path.StartsWith(@"ProgramMenuFolder\startup", StringComparison.Ordinal) ||
                                path.StartsWith("TARGETDIR", StringComparison.Ordinal) ||
                                path.StartsWith(@"StartMenuFolder\programs", StringComparison.Ordinal) ||
                                path.StartsWith(@"WindowsFolder\fonts", StringComparison.Ordinal))
                            {
                                this.Messaging.Write(ErrorMessages.IllegalPathForGeneratedComponentGuid(componentRow.SourceLineNumbers, fileRow.Component_, path));
                            }

                            // if component has more than one file, the key path must be versioned
                            if (1 < numFilesInComponent && String.IsNullOrEmpty(fileRow.Version))
                            {
                                this.Messaging.Write(ErrorMessages.IllegalGeneratedGuidComponentUnversionedKeypath(componentRow.SourceLineNumbers));
                            }
                        }
                        else
                        {
                            // not a key path, so it must be an unversioned file if component has more than one file
                            if (1 < numFilesInComponent && !String.IsNullOrEmpty(fileRow.Version))
                            {
                                this.Messaging.Write(ErrorMessages.IllegalGeneratedGuidComponentVersionedNonkeypath(componentRow.SourceLineNumbers));
                            }
                        }
                    }

                    // if the rules were followed, reward with a generated guid
                    if (!this.Messaging.EncounteredError)
                    {
                        componentRow.ComponentId = Uuid.NewUuid(BindDatabaseCommand.WixComponentGuidNamespace, path).ToString("B").ToUpperInvariant();
                    }
                }
            }
        }
Example #2
0
        public void Execute()
        {
            var fileTransfers = new List <FileTransfer>();

            var directories = new Dictionary <string, ResolvedDirectory>();

            var mediaRows = this.Section.Tuples.OfType <MediaTuple>().ToDictionary(t => t.DiskId);

            var wixMediaRows = this.Section.Tuples.OfType <WixMediaTuple>().ToDictionary(t => t.DiskId_);

            using (Database db = new Database(this.DatabasePath, OpenDatabase.ReadOnly))
            {
                using (View directoryView = db.OpenExecuteView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`"))
                {
                    while (true)
                    {
                        using (Record directoryRecord = directoryView.Fetch())
                        {
                            if (null == directoryRecord)
                            {
                                break;
                            }

                            string sourceName = Common.GetName(directoryRecord.GetString(3), true, this.LongNamesInImage);

                            directories.Add(directoryRecord.GetString(1), new ResolvedDirectory(directoryRecord.GetString(2), sourceName));
                        }
                    }
                }

                using (View fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?"))
                {
                    using (Record fileQueryRecord = new Record(1))
                    {
                        // for each file in the array of uncompressed files
                        foreach (FileFacade facade in this.FileFacades)
                        {
                            var    mediaTuple             = mediaRows[facade.WixFile.DiskId];
                            string relativeFileLayoutPath = null;
                            string mediaLayoutFolder      = null;

                            if (wixMediaRows.TryGetValue(facade.WixFile.DiskId, out var wixMediaRow))
                            {
                                mediaLayoutFolder = wixMediaRow.Layout;
                            }

                            var mediaLayoutDirectory = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);

                            // setup up the query record and find the appropriate file in the
                            // previously executed file view
                            fileQueryRecord[1] = facade.File.File;
                            fileView.Execute(fileQueryRecord);

                            using (Record fileRecord = fileView.Fetch())
                            {
                                if (null == fileRecord)
                                {
                                    throw new WixException(ErrorMessages.FileIdentifierNotFound(facade.File.SourceLineNumbers, facade.File.File));
                                }

                                relativeFileLayoutPath = PathResolver.GetFileSourcePath(directories, fileRecord[1], fileRecord[2], this.Compressed, this.LongNamesInImage);
                            }

                            // finally put together the base media layout path and the relative file layout path
                            string fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath);
                            if (FileTransfer.TryCreate(facade.WixFile.Source.Path, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out var transfer))
                            {
                                fileTransfers.Add(transfer);
                            }
                        }
                    }
                }
            }

            this.FileTransfers = fileTransfers;
        }
Example #3
0
        public void Execute()
        {
            var fileTransfers = new List <IFileTransfer>();

            var trackedFiles = new List <ITrackedFile>();

            var directories = new Dictionary <string, ResolvedDirectory>();

            var mediaRows = this.Section.Tuples.OfType <MediaTuple>().ToDictionary(t => t.DiskId);

            var wixMediaRows = this.Section.Tuples.OfType <WixMediaTuple>().ToDictionary(t => t.DiskId_);

            using (Database db = new Database(this.DatabasePath, OpenDatabase.ReadOnly))
            {
                using (View directoryView = db.OpenExecuteView("SELECT `Directory`, `Directory_Parent`, `DefaultDir` FROM `Directory`"))
                {
                    while (true)
                    {
                        using (Record directoryRecord = directoryView.Fetch())
                        {
                            if (null == directoryRecord)
                            {
                                break;
                            }

                            string sourceName = Common.GetName(directoryRecord.GetString(3), true, this.LongNamesInImage);

                            directories.Add(directoryRecord.GetString(1), new ResolvedDirectory(directoryRecord.GetString(2), sourceName));
                        }
                    }
                }

                using (View fileView = db.OpenView("SELECT `Directory_`, `FileName` FROM `Component`, `File` WHERE `Component`.`Component`=`File`.`Component_` AND `File`.`File`=?"))
                {
                    using (Record fileQueryRecord = new Record(1))
                    {
                        // for each file in the array of uncompressed files
                        foreach (FileFacade facade in this.FileFacades)
                        {
                            var    mediaTuple             = mediaRows[facade.WixFile.DiskId];
                            string relativeFileLayoutPath = null;
                            string mediaLayoutFolder      = null;

                            if (wixMediaRows.TryGetValue(facade.WixFile.DiskId, out var wixMediaRow))
                            {
                                mediaLayoutFolder = wixMediaRow.Layout;
                            }

                            var mediaLayoutDirectory = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);

                            // setup up the query record and find the appropriate file in the
                            // previously executed file view
                            fileQueryRecord[1] = facade.File.File;
                            fileView.Execute(fileQueryRecord);

                            using (Record fileRecord = fileView.Fetch())
                            {
                                if (null == fileRecord)
                                {
                                    throw new WixException(ErrorMessages.FileIdentifierNotFound(facade.File.SourceLineNumbers, facade.File.File));
                                }

                                relativeFileLayoutPath = PathResolver.GetFileSourcePath(directories, fileRecord[1], fileRecord[2], this.Compressed, this.LongNamesInImage);
                            }

                            // finally put together the base media layout path and the relative file layout path
                            var fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath);

                            var transfer = this.BackendHelper.CreateFileTransfer(facade.WixFile.Source.Path, fileLayoutPath, false, facade.File.SourceLineNumbers);
                            fileTransfers.Add(transfer);

                            // Track the location where the cabinet will be placed. If the transfer is
                            // redundant then then the file should not be cleaned. This is important
                            // because if the source and destination of the transfer is the same, we
                            // don't want to clean the file because we'd be deleting the original
                            // (and that would be bad).
                            var tracked = this.BackendHelper.TrackFile(transfer.Destination, TrackedFileType.Final, facade.File.SourceLineNumbers);
                            tracked.Clean = !transfer.Redundant;

                            trackedFiles.Add(tracked);
                        }
                    }
                }
            }

            this.FileTransfers = fileTransfers;
            this.TrackedFiles  = trackedFiles;
        }