Example #1
0
        public static (bool, string) VerifyFileIsAvailableForPackage(CompDBXmlClass.Package pkg, string UUPPath)
        {
            string missingPackage = "";

            //
            // Some download utilities that start with the letter U and finish with UPDump or start with the letter U and finish with UP.rg-adguard download files without respecting Microsoft filenames
            // We attempt to locate files based on what we think they use first.
            //
            string file = pkg.GetCommonlyUsedIncorrectFileName();

            if (!File.Exists(Path.Combine(UUPPath, file)))
            {
                //
                // Wow, someone actually downloaded UUP files using a tool that respects Microsoft paths, that's exceptional
                //
                file = pkg.Payload.PayloadItem.Path;
                if (!File.Exists(Path.Combine(UUPPath, file)))
                {
                    //
                    // What a disapointment, they simply didn't download everything.. Oops.
                    // TODO: generate missing files out of thin air
                    //
                    missingPackage = file;
                }
            }

            return(string.IsNullOrEmpty(missingPackage), missingPackage);
        }
Example #2
0
        private static async Task BuildUpdateXml(UpdateData update, MachineType MachineType)
        {
            string buildstr = "";
            IEnumerable <string> languages = null;

            var compDBs = await update.GetCompDBsAsync();

            await Task.WhenAll(
                Task.Run(async() => buildstr  = await update.GetBuildStringAsync()),
                Task.Run(async() => languages = await update.GetAvailableLanguagesAsync()));

            buildstr = buildstr ?? "";

            CompDBXmlClass.Package editionPackPkg = compDBs.GetEditionPackFromCompDBs();
            string editionPkg = await update.DownloadFileFromDigestAsync(editionPackPkg.Payload.PayloadItem.PayloadHash);

            var plans = await Task.WhenAll(languages.Select(x => update.GetTargetedPlanAsync(x, editionPkg)));

            UpdateScan scan = new UpdateScan()
            {
                Architecture = MachineType,
                BuildString  = buildstr,
                Description  = update.Xml.LocalizedProperties.Description,
                Title        = update.Xml.LocalizedProperties.Title,
                Targets      = plans,
                UpdateData   = update
            };

            File.WriteAllText("updatetest.xml", scan.Serialize());
        }
        public static async Task <EditionPlanningWithLanguage> GetTargetedPlanAsync(this UpdateData update, string LanguageCode)
        {
            var compDBs = await update.GetCompDBsAsync();

            CompDBXmlClass.Package editionPackPkg = compDBs.GetEditionPackFromCompDBs();

            string editionPkg = await update.DownloadFileFromDigestAsync(editionPackPkg.Payload.PayloadItem.PayloadHash);

            return(await update.GetTargetedPlanAsync(LanguageCode, editionPkg));
        }
        public static bool GetTargetedPlan(
            string UUPPath,
            string LanguageCode,
            out List <EditionTarget> EditionTargets,
            ProgressCallback progressCallback = null)
        {
            progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, "Acquiring Composition Databases");

            HashSet <CompDBXmlClass.CompDB> compDBs = FileLocator.GetCompDBsFromUUPFiles(UUPPath);

            string EditionPack = "";

            //
            // Get base editions that are available with all their files
            //
            IEnumerable <CompDBXmlClass.CompDB> filteredCompDBs = compDBs.GetEditionCompDBsForLanguage(LanguageCode).Where(x =>
            {
                (bool success, HashSet <string> missingfiles) = FileLocator.VerifyFilesAreAvailableForCompDB(x, UUPPath);
                return(success);
            });

            if (filteredCompDBs.Count() > 0)
            {
                foreach (CompDBXmlClass.Package feature in filteredCompDBs.First().Features.Feature[0].Packages.Package)
                {
                    CompDBXmlClass.Package pkg = filteredCompDBs.First().Packages.Package.First(x => x.ID == feature.ID);

                    string file = pkg.GetCommonlyUsedIncorrectFileName();

                    //
                    // We know already that all files exist, so it's just a matter of knowing which path format is used
                    //
                    file = !File.Exists(Path.Combine(UUPPath, file)) ? pkg.Payload.PayloadItem.Path : file;

                    if (!file.EndsWith(".esd", StringComparison.InvariantCultureIgnoreCase) ||
                        !file.Contains("microsoft-windows-editionspecific", StringComparison.InvariantCultureIgnoreCase) ||
                        file.Contains("WOW64", StringComparison.InvariantCultureIgnoreCase) ||
                        file.Contains("arm64.arm", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // We do not care about this file
                        continue;
                    }

                    EditionPack = file;
                }
            }

            return(ConversionPlanBuilder.GetTargetedPlan(UUPPath, compDBs, Path.Combine(UUPPath, EditionPack), LanguageCode, out EditionTargets, (string msg) => progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, msg)));
        }
Example #5
0
        internal static (bool Succeeded, string BaseESD) LocateFilesForSetupMediaCreation(
            string UUPPath,
            string LanguageCode,
            ProgressCallback?progressCallback = null)
        {
            progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, "Looking up Composition Database in order to find a Base ESD image appropriate for building windows setup files.");

            if (Planning.NET.FileLocator.GetCompDBsFromUUPFiles(UUPPath) is HashSet <CompDBXmlClass.CompDB> compDBs)
            {
                HashSet <CompDBXmlClass.CompDB> filteredCompDBs = compDBs.GetEditionCompDBsForLanguage(LanguageCode);
                if (filteredCompDBs.Count > 0)
                {
                    foreach (var currentCompDB in filteredCompDBs)
                    {
                        foreach (CompDBXmlClass.Package feature in currentCompDB.Features.Feature[0].Packages.Package)
                        {
                            CompDBXmlClass.Package pkg = currentCompDB.Packages.Package.First(x => x.ID == feature.ID);

                            string file = pkg.GetCommonlyUsedIncorrectFileName();

                            if (feature.PackageType == "MetadataESD")
                            {
                                if (!File.Exists(Path.Combine(UUPPath, file)))
                                {
                                    file = pkg.Payload.PayloadItem.Path;
                                    if (!File.Exists(Path.Combine(UUPPath, file)))
                                    {
                                        break;
                                    }
                                }

                                return(true, Path.Combine(UUPPath, file));
                            }
                        }
                    }
                }

                progressCallback?.Invoke(Common.ProcessPhase.Error, true, 0, "While looking up the Composition Database, we couldn't find an edition composition for the specified language. This error is fatal.");
                return(false, null);
            }
            else
            {
                progressCallback?.Invoke(Common.ProcessPhase.Error, true, 0, "We couldn't find the Composition Database. Please make sure you have downloaded the <aggregatedmetadata> cabinet file, or the <CompDB> cabinet files (if the build is lower than RS3 RTM). This error is fatal.");
                return(false, null);
            }
        }
Example #6
0
        public static (bool, HashSet <string>) VerifyFilesAreAvailableForCompDB(CompDBXmlClass.CompDB compDB, string UUPPath)
        {
            HashSet <string> missingPackages = new HashSet <string>();

            foreach (CompDBXmlClass.Package feature in compDB.Features.Feature[0].Packages.Package)
            {
                CompDBXmlClass.Package pkg = compDB.Packages.Package.First(x => x.ID == feature.ID);

                (bool succeeded, string missingFile) = VerifyFileIsAvailableForPackage(pkg, UUPPath);
                if (!succeeded)
                {
                    missingPackages.Add(missingFile);
                }
            }

            return(missingPackages.Count <= 0, missingPackages);
        }
Example #7
0
        private static async Task ProcessUpdateAsync(UpdateData update, string pOutputFolder, MachineType MachineType, string Language = "", string Edition = "", bool WriteMetadata = true)
        {
            HashSet <CompDBXmlClass.PayloadItem> payloadItems       = new HashSet <CompDBXmlClass.PayloadItem>();
            HashSet <CompDBXmlClass.PayloadItem> bannedPayloadItems = new HashSet <CompDBXmlClass.PayloadItem>();
            HashSet <CompDBXmlClass.CompDB>      specificCompDBs    = new HashSet <CompDBXmlClass.CompDB>();

            string buildstr = "";
            IEnumerable <string> languages = null;

            int returnCode = 0;
            IEnumerable <CExtendedUpdateInfoXml.File> filesToDownload = null;

            bool getSpecific         = !string.IsNullOrEmpty(Language) && !string.IsNullOrEmpty(Edition);
            bool getSpecificLanguage = !string.IsNullOrEmpty(Language) && string.IsNullOrEmpty(Edition);

            Logging.Log("Gathering update metadata...");

            var compDBs = await update.GetCompDBsAsync();

            await Task.WhenAll(
                Task.Run(async() => buildstr  = await update.GetBuildStringAsync()),
                Task.Run(async() => languages = await update.GetAvailableLanguagesAsync()));

            buildstr = buildstr ?? "";

            CompDBXmlClass.Package editionPackPkg = compDBs.GetEditionPackFromCompDBs();
            if (editionPackPkg != null)
            {
                string editionPkg = await update.DownloadFileFromDigestAsync(editionPackPkg.Payload.PayloadItem.PayloadHash);

                var plans = await Task.WhenAll(languages.Select(x => update.GetTargetedPlanAsync(x, editionPkg)));

                foreach (var plan in plans)
                {
                    Logging.Log("");
                    Logging.Log("Editions available for language: " + plan.LanguageCode);
                    plan.EditionTargets.PrintAvailablePlan();
                }
            }

            string name         = $"{buildstr.Replace(" ", ".").Replace("(", "").Replace(")", "")}_{MachineType.ToString().ToLower()}fre_{update.Xml.UpdateIdentity.UpdateID.Split("-")[^1]}";
Example #8
0
        private static (List <PlannedEdition>, List <PlannedEdition>) GetEditionsThatCanBeTargetedUsingPackageDowngrade(
            string UUPPath,
            HashSet <CompDBXmlClass.CompDB> compDBs,
            IEnumerable <PlannedEdition> availableCanonicalEditions,
            List <EditionMappingXML.Edition> possibleEditionUpgrades,
            ProgressCallback?progressCallback = null)
        {
            List <PlannedEdition> availableEditionsByDowngradingInPriority = new List <PlannedEdition>();
            List <PlannedEdition> availableEditionsByDowngrading           = new List <PlannedEdition>();

            //
            // Attempt to get the neutral Composition Database listing all available files
            //
            CompDBXmlClass.CompDB?neutralCompDB = compDBs.GetNeutralCompDB();

            if (neutralCompDB != null)
            {
                var packages = neutralCompDB.Features.Feature.First(x => x.FeatureID == "BaseNeutral").Packages.Package;

                var editionSpecificPackages = packages.Where(x => x.ID.Count(y => y == '-') == 4).Where(x => x.ID.Contains("microsoft-windows-editionspecific", StringComparison.InvariantCultureIgnoreCase));
                var highPriorityPackages    = editionSpecificPackages.Where(x => x.ID.Contains("starter", StringComparison.InvariantCultureIgnoreCase) ||
                                                                            x.ID.Contains("professional", StringComparison.InvariantCultureIgnoreCase) ||
                                                                            x.ID.Contains("core", StringComparison.InvariantCultureIgnoreCase));
                editionSpecificPackages = editionSpecificPackages.Except(highPriorityPackages);

                foreach (var file in highPriorityPackages)
                {
                    CompDBXmlClass.Package pkg = neutralCompDB.Packages.Package.First(x => x.ID == file.ID);

                    //
                    // First check if the file exists
                    //
                    if (!string.IsNullOrEmpty(UUPPath))
                    {
                        (bool Success, string MissingFile) = FileLocator.VerifyFileIsAvailableForPackage(pkg, UUPPath);
                        if (!Success)
                        {
                            progressCallback?.Invoke("One edition Composition Database failed file validation, below is highlighted the files that could not be found in the UUP path. This means that you will not get all possible editions.");
                            progressCallback?.Invoke($"Missing: {MissingFile}");
                            continue;
                        }
                    }

                    var sku = file.ID.Split('-')[3];

                    //
                    // If the edition not available as canonical
                    //
                    if (!availableCanonicalEditions.Any(x => x.EditionName.Equals(sku, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        if (possibleEditionUpgrades != null && !possibleEditionUpgrades
                            .Where(x => availableCanonicalEditions.Any(y => y.EditionName.Equals(x.ParentEdition, StringComparison.InvariantCultureIgnoreCase)) ||
                                   availableEditionsByDowngrading.Any(y => y.EditionName.Equals(x.ParentEdition, StringComparison.InvariantCultureIgnoreCase)))
                            .Any(x => x.Name.Equals(sku, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            PlannedEdition edition = new PlannedEdition
                            {
                                EditionName      = sku,
                                AvailabilityType = AvailabilityType.EditionPackageSwap
                            };

                            availableEditionsByDowngradingInPriority.Add(edition);
                        }
                    }
                }

                foreach (var file in editionSpecificPackages)
                {
                    CompDBXmlClass.Package pkg = neutralCompDB.Packages.Package.First(x => x.ID == file.ID);

                    //
                    // First check if the file exists
                    //
                    if (!string.IsNullOrEmpty(UUPPath))
                    {
                        (bool Success, string MissingFile) = FileLocator.VerifyFileIsAvailableForPackage(pkg, UUPPath);
                        if (!Success)
                        {
                            progressCallback?.Invoke("One edition Composition Database failed file validation, below is highlighted the files that could not be found in the UUP path. This means that you will not get all possible editions.");
                            progressCallback?.Invoke($"Missing: {MissingFile}");
                            continue;
                        }
                    }

                    var sku = file.ID.Split('-')[3];

                    //
                    // If the edition not available as canonical
                    //
                    if (!availableCanonicalEditions.Any(x => x.EditionName.Equals(sku, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        if (possibleEditionUpgrades != null && !possibleEditionUpgrades
                            .Where(x => availableCanonicalEditions.Any(y => y.EditionName.Equals(x.ParentEdition, StringComparison.InvariantCultureIgnoreCase)) ||
                                   availableEditionsByDowngrading.Any(y => y.EditionName.Equals(x.ParentEdition, StringComparison.InvariantCultureIgnoreCase)))
                            .Any(x => x.Name.Equals(sku, StringComparison.InvariantCultureIgnoreCase)))
                        {
                            PlannedEdition edition = new PlannedEdition
                            {
                                EditionName      = sku,
                                AvailabilityType = AvailabilityType.EditionPackageSwap
                            };

                            availableEditionsByDowngrading.Add(edition);
                        }
                    }
                }
            }

            return(availableEditionsByDowngradingInPriority, availableEditionsByDowngrading);
        }
Example #9
0
        internal static (bool Succeeded, string BaseESD, HashSet <string> ReferencePackages, HashSet <string> ReferencePackagesToConvert) LocateFilesForBaseEditionCreation(
            string UUPPath,
            string LanguageCode,
            string EditionID,
            ProgressCallback progressCallback = null)
        {
            bool success = true;

            HashSet <string> ReferencePackages          = new HashSet <string>();
            HashSet <string> referencePackagesToConvert = new HashSet <string>();
            string           BaseESD = null;

            progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, "Enumerating files");

            CompDBXmlClass.CompDB?compDB = GetEditionCompDBForLanguage(Planning.NET.FileLocator.GetCompDBsFromUUPFiles(UUPPath), EditionID, LanguageCode);

            if (compDB == null)
            {
                progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, "No compDB found");
                goto error;
            }

            foreach (CompDBXmlClass.Package feature in compDB.Features.Feature[0].Packages.Package)
            {
                CompDBXmlClass.Package pkg = compDB.Packages.Package.First(x => x.ID == feature.ID);

                string file = pkg.GetCommonlyUsedIncorrectFileName();

                if (!File.Exists(Path.Combine(UUPPath, file)))
                {
                    file = pkg.Payload.PayloadItem.Path;
                    if (!File.Exists(Path.Combine(UUPPath, file)))
                    {
                        progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, $"File {file} is missing");
                        goto error;
                    }
                }

                if (feature.PackageType == "MetadataESD")
                {
                    BaseESD = Path.Combine(UUPPath, file);
                    continue;
                }

                if (file.EndsWith(".esd", StringComparison.InvariantCultureIgnoreCase))
                {
                    ReferencePackages.Add(Path.Combine(UUPPath, file));
                }
                else if (file.EndsWith(".cab", StringComparison.InvariantCultureIgnoreCase))
                {
                    referencePackagesToConvert.Add(Path.Combine(UUPPath, file));
                }
            }

            if (BaseESD == null)
            {
                progressCallback?.Invoke(Common.ProcessPhase.ReadingMetadata, true, 0, "Base ESD not found");
                goto error;
            }

            goto exit;

error:
            success = false;

exit:
            return(success, BaseESD, ReferencePackages, referencePackagesToConvert);
        }