Ejemplo n.º 1
0
        public PatchApplication(IPatchDestinationWritable destination, bool enabled, bool useRemote, string patchSet,
                                params string[] patchesRoots)
        {
            PatchSet     = patchSet;
            PatchesRoots = patchesRoots;
            Destination  = destination;
            Enabled      = enabled;
            UseRemote    = useRemote;

            PatchList patches         = new PatchList();
            string    selectedVersion = null;

            foreach (string patchesRoot in PatchesRoots)
            {
                string    previouslySelectedVersion = selectedVersion;
                PatchList loaded = Destination.SelectPatches(patchesRoot, ref selectedVersion, PatchSet);
                if (previouslySelectedVersion != null &&
                    selectedVersion != null &&
                    string.Compare(selectedVersion, previouslySelectedVersion, StringComparison.InvariantCulture) > 0)
                {
                    // replaced with higher version
                    patches = new PatchList();
                }
                patches.Merge(loaded);
            }

            Patches         = patches;
            SelectedVersion = selectedVersion;
            Status          = StatusCodes.Unknown;
        }
Ejemplo n.º 2
0
        private static bool WriteBack(IPatchDestinationWritable destination, PatchFile patch, string patched, string verbing,
                                      out StatusReportItem status)
        {
            if (destination.TryWritePatched(patch.TargetPath, patched))
            {
                status = new StatusReportItem
                {
                    Status = $"{destination.LongDescription} successfully wrote {patch.TargetPath} after {verbing} patch"
                };
                return(true);
            }

            status = new StatusReportItem
            {
                Status =
                    $"{destination.LongDescription} could not write {patch.TargetPath} after {verbing} patch",
                Severity       = StatusReportItem.SeverityCode.Error,
                Recommendation = "please ensure you have write permission to all the files in the target location"
            };
            return(false);
        }
Ejemplo n.º 3
0
 public IEnumerable <StatusReportItem> Apply(IPatchDestinationWritable destination, HashSet <string> patchExclusions) => DoApply(destination, destination, patchExclusions, Mode.Apply);
Ejemplo n.º 4
0
        public IEnumerable <StatusReportItem> Revert(IPatchDestinationWritable destination, HashSet <string> patchExclusions)
        {
            if (!destination.TryLock())
            {
                yield return(new StatusReportItem
                {
                    Status = $"cannot acquire lock on {destination.LongDescription} to revert patches",
                    Recommendation = "close any programs that are holding a lock on this location",
                    Severity = StatusReportItem.SeverityCode.Error
                });

                yield break;
            }

            foreach (PatchFile patch in _patches)
            {
                if (patchExclusions.Contains(patch.TargetPath))
                {
                    continue;
                }

                if (!destination.TryGetSource(patch.TargetPath, out string source))
                {
                    yield return(new StatusReportItem
                    {
                        Status = $"{patch.TargetPath} does not exist in {destination.LongDescription}; ignoring patch"
                    });

                    continue;
                }

                if (!patch.IsApplied(source))
                {
                    // patch not present in this file any more, go to next patch
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} does not have our patches for {patch.TargetPath}"
                    });

                    continue;
                }

                if (destination.TryRestoreOriginal(patch.TargetPath))
                {
                    // restored original file for this version, no need to revert patch
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} restored original file {patch.TargetPath}",
                        Flags = StatusReportItem.StatusFlags.ConfigurationUpToDate
                    });

                    continue;
                }

                if (!patch.TryRevert(source, out string patched, out string failureStatus))
                {
                    // could not apply reverse patch; keep going trying to fix up as much as possible
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} {failureStatus}",
                        Recommendation = "please repair DCS installation using dcs_updater.exe",
                        Severity = StatusReportItem.SeverityCode.Error
                    });
                }

                if (!WriteBack(destination, patch, patched, "reverting", out StatusReportItem status))
                {
                    yield return(status);

                    destination.TryUnlock();
                    yield break;
                }

                yield return(status);
            }

            if (!destination.TryUnlock())
            {
                yield return(new StatusReportItem
                {
                    Status = $"cannot release lock on {destination.LongDescription} after reverting patches",
                    Recommendation = "please restart and try the revert patches process again",
                    Severity = StatusReportItem.SeverityCode.Error
                });
            }
        }
Ejemplo n.º 5
0
        private IEnumerable <StatusReportItem> DoApply(IPatchDestination destination, IPatchDestinationWritable writable, HashSet <string> patchExclusions, Mode mode)
        {
            // set up according to mode
            string verb;
            string verbing;

            switch (mode)
            {
            case Mode.Simulate:
                verb    = "simulate";
                verbing = "simulating";
                break;

            case Mode.Apply:
                verb    = "apply";
                verbing = "applying";
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(mode), mode, null);
            }

            if (!destination.TryLock())
            {
                yield return(new StatusReportItem
                {
                    Status = $"cannot acquire lock on {destination.LongDescription} to {verb} patches",
                    Recommendation = "close any programs that are holding a lock on this location",
                    Severity = StatusReportItem.SeverityCode.Error
                });

                yield break;
            }

            foreach (PatchFile patch in _patches)
            {
                if (patchExclusions.Contains(patch.TargetPath))
                {
                    continue;
                }

                if (!destination.TryGetSource(patch.TargetPath, out string source))
                {
                    yield return(new StatusReportItem
                    {
                        Status = $"{patch.TargetPath} does not exist in {destination.LongDescription}; ignoring patch"
                    });

                    continue;
                }

                if (patch.IsApplied(source))
                {
                    // already applied, go to next patch
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} has already patched {patch.TargetPath}"
                    });

                    continue;
                }

                if (!patch.TryApply(source, out string patched, out string failureStatus, out string expectedCode))
                {
                    // send a general failure message that will become the header of the dialog box if any
                    string failedPatchRecommendation = "Please make sure you do not have viewport mods installed.  If your DCS installation is free from modifications and patches still fail, then install a newer Helios distribution or patches with support for this DCS version.";
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} could not install patches.  You may have viewport mods installed that need to be removed or DCS may have changed too much during a recent update.",
                        Recommendation = failedPatchRecommendation,
                        Severity = StatusReportItem.SeverityCode.Error
                    });

                    // send detail including code
                    yield return(new StatusReportItem
                    {
                        Status = $"{destination.LongDescription} {failureStatus}",
                        Recommendation = failedPatchRecommendation,
                        Severity = StatusReportItem.SeverityCode.Error,
                        Code = expectedCode
                    });

                    // could not patch; fatal
                    destination.TryUnlock();
                    yield break;
                }

                if (mode == Mode.Simulate)
                {
                    continue;
                }

                if (!writable.TrySaveOriginal(patch.TargetPath))
                {
                    // abort
                    yield return(new StatusReportItem
                    {
                        Status =
                            $"{destination.LongDescription} could not save original copy of {patch.TargetPath}",
                        Recommendation =
                            "please check write permissions to make sure you can write files in the DCS installation location",
                        Severity = StatusReportItem.SeverityCode.Error
                    });

                    destination.TryUnlock();
                    yield break;
                }

                if (!WriteBack(writable, patch, patched, verbing, out StatusReportItem status))
                {
                    // abort
                    yield return(status);

                    destination.TryUnlock();
                    yield break;
                }

                // success result
                yield return(status);
            }

            if (!destination.TryUnlock())
            {
                yield return(new StatusReportItem
                {
                    Status = $"cannot release lock on {destination.LongDescription} after {verbing} patches",
                    Recommendation = $"please restart and try the {verb} process again",
                    Severity = StatusReportItem.SeverityCode.Error
                });
            }
        }