public static int GetPartitionDiskBackingType(string partitionLetter)
 {
     using (var partitionSearcher = new ManagementObjectSearcher(
                @"\\localhost\ROOT\Microsoft\Windows\Storage",
                $"SELECT DiskNumber FROM MSFT_Partition WHERE DriveLetter='{partitionLetter}'"))
     {
         try
         {
             var partition = partitionSearcher.Get().Cast <ManagementBaseObject>().Single();
             using (var physicalDiskSearcher = new ManagementObjectSearcher(
                        @"\\localhost\ROOT\Microsoft\Windows\Storage",
                        $"SELECT Size, Model, MediaType FROM MSFT_PhysicalDisk WHERE DeviceID='{ partition["DiskNumber"] }'"))
             {
                 var physicalDisk = physicalDiskSearcher.Get().Cast <ManagementBaseObject>().Single();
                 return
                     ((UInt16)physicalDisk["MediaType"]);/*||
                                                          * SSDModelSubstrings.Any(substring => result.Model.ToLower().Contains(substring)); ;*/
             }
         }
         catch (Exception e)
         {
             MERLog.Error("Error reading partition type on " + partitionLetter + ": " + e.Message);
             return(-1);
         }
     }
 }
Beispiel #2
0
        private static void handleM3Passthrough()
        {
            if (PassthroughME1Path != null)
            {
                handlePassthrough(MEGame.ME1, PassthroughME1Path);
            }
            if (PassthroughME2Path != null)
            {
                handlePassthrough(MEGame.ME2, PassthroughME2Path);
            }
            if (PassthroughME3Path != null)
            {
                handlePassthrough(MEGame.ME3, PassthroughME3Path);
            }

            PassthroughME1Path = PassthroughME2Path = PassthroughME3Path = null;

            void handlePassthrough(MEGame game, string path)
            {
                if (path != null && Directory.Exists(path))
                {
                    GameTarget gt = new GameTarget(game, path, true, false);
                    var        passThroughValidationResult = gt.ValidateTarget(false);
                    if (passThroughValidationResult != null)
                    {
                        MERLog.Error($@"{game} path passthrough failed game target validation: {passThroughValidationResult}");
                    }
                    else
                    {
                        MERLog.Information($@"Valid passthrough for game {game}. Assigning path.");
                        Locations.SetTarget(gt, false);
                    }
                }
            }
        }
Beispiel #3
0
        private static void PerformRAMCheck(Action <string, string> messageCallback)
        {
            var ramAmountsBytes = Utilities.GetInstalledRamAmount();
            var installedRamGB  = ramAmountsBytes * 1.0d / (2 ^ 30);

            if (ramAmountsBytes > 0 && installedRamGB < 10)
            {
                messageCallback?.Invoke("System memory is less than 10 GB", "Randomization can use significant amounts of memory (up to 6GB) in multithreaded mode. It is recommended that you disable multithreaded randomization if your system has less than 10GB of memory. This will increase randomization time but will reduce the memory required to randomize.");
            }
#if WINDOWS
            //Check pagefile
            try
            {
                //Current
                var pageFileLocations = new List <string>();
                using (var query = new ManagementObjectSearcher("SELECT Caption,AllocatedBaseSize FROM Win32_PageFileUsage"))
                {
                    foreach (ManagementBaseObject obj in query.Get())
                    {
                        string pagefileName = (string)obj.GetPropertyValue("Caption");
                        MERLog.Information("Detected pagefile: " + pagefileName);
                        pageFileLocations.Add(pagefileName.ToLower());
                    }
                }

                //Max
                using (var query = new ManagementObjectSearcher("SELECT Name,MaximumSize FROM Win32_PageFileSetting"))
                {
                    foreach (ManagementBaseObject obj in query.Get())
                    {
                        string pagefileName = (string)obj.GetPropertyValue("Name");
                        uint   max          = (uint)obj.GetPropertyValue("MaximumSize");
                        if (max > 0)
                        {
                            // Not system managed
                            pageFileLocations.RemoveAll(x => Path.GetFullPath(x).Equals(Path.GetFullPath(pagefileName)));
                            MERLog.Error($"Pagefile has been modified by the end user. The maximum page file size on {pagefileName} is {max} MB. Does this user **actually** know what capping a pagefile does?");
                        }
                    }
                }

                if (pageFileLocations.Any())
                {
                    MERLog.Information("We have a usable system managed page file - OK");
                }
                else
                {
                    MERLog.Error("We have no uncapped or available pagefiles to use! Very high chance application will run out of memory");
                    messageCallback?.Invoke($"Pagefile is off or size has been capped", $"The system pagefile (virtual memory) settings are not currently managed by Windows, or the pagefile is off. Mass Effect 2 Randomizer uses significant amounts of memory and will crash if the system runs low on memory. You should always leave page files managed by Windows.");
                }
            }
            catch (Exception e)
            {
                MERLog.Exception(e, "Unable to check pagefile settings:");
            }
#endif
        }
 public static void OpenWebPage(string link)
 {
     try
     {
         ProcessStartInfo psi = new ProcessStartInfo
         {
             FileName        = link,
             UseShellExecute = true
         };
         Process.Start(psi);
     }
     catch (Exception e)
     {
         MERLog.Error("Exception trying to open web page from system (typically means browser default is incorrectly configured by Windows): " + e.Message + ". Try opening the URL manually: " + link);
     }
 }
 public static int runProcessAsAdmin(string exe, string args, bool standAlone = false)
 {
     MERLog.Information("Running process as admin: " + exe + " " + args);
     using (Process p = new Process())
     {
         p.StartInfo.CreateNoWindow  = true;
         p.StartInfo.FileName        = exe;
         p.StartInfo.UseShellExecute = true;
         p.StartInfo.Arguments       = args;
         p.StartInfo.Verb            = "runas";
         try
         {
             p.Start();
             if (!standAlone)
             {
                 p.WaitForExit(60000);
                 try
                 {
                     return(p.ExitCode);
                 }
                 catch (Exception e)
                 {
                     MERLog.Error("Error getting return code from admin process. It may have timed out.\n" + FlattenException(e));
                     return(-1);
                 }
             }
             else
             {
                 return(0);
             }
         }
         catch (System.ComponentModel.Win32Exception e)
         {
             MERLog.Error("Error running elevated process: " + e.Message);
             return(WIN32_EXCEPTION_ELEVATED_CODE);
         }
     }
 }
Beispiel #6
0
        public static async void BeginFlow(MainWindow window)
        {
            // PRE LIBRARY LOAD
            RegistryHandler.RegistrySettingsPath       = @"HKEY_CURRENT_USER\Software\MassEffect2Randomizer";
            RegistryHandler.CurrentUserRegistrySubpath = @"Software\MassEffect2Randomizer";
            LegendaryExplorerCoreLib.SetSynchronizationContext(TaskScheduler.FromCurrentSynchronizationContext());

            try
            {
                // This is in a try catch because this is a critical no-crash zone that is before launch
                window.Title = $"Mass Effect 2 Randomizer {App.AppVersion}";
            }
            catch { }

            if (Utilities.GetExecutablePath().StartsWith(Path.GetTempPath(), StringComparison.InvariantCultureIgnoreCase))
            {
                // Running from temp! This is not allowed
                await window.ShowMessageAsync("Cannot run from temp directory", $"Mass Effect 2 Randomizer cannot be run from the system's Temp directory. If this executable was run from within an archive, it needs to be extracted first.");

                Environment.Exit(1);
            }

            var pd = await window.ShowProgressAsync("Starting up", $"Mass Effect 2 Randomizer is starting up. Please wait.");

            pd.SetIndeterminate();
            NamedBackgroundWorker bw = new NamedBackgroundWorker("StartupThread");

            bw.DoWork += (a, b) =>
            {
                ALOTInstallerCoreLib.Startup(SetWrapperLogger, RunOnUIThread, startTelemetry, stopTelemetry, $"Mass Effect 2 Randomizer {App.AppVersion} starting up", false);
                // Logger is now available

                // Setup telemetry handlers
                CoreAnalytics.TrackEvent = TelemetryController.TrackEvent;
                CoreCrashes.TrackError   = TelemetryController.TrackError;
                CoreCrashes.TrackError2  = TelemetryController.TrackError2;
                CoreCrashes.TrackError3  = TelemetryController.TrackError3;

                // Setup the InteropPackage for the update check
                #region Update interop
                CancellationTokenSource ct = new CancellationTokenSource();

                AppUpdateInteropPackage interopPackage = new AppUpdateInteropPackage()
                {
                    GithubOwner              = "Mgamerz",
                    GithubReponame           = "MassEffect2Randomizer",
                    UpdateAssetPrefix        = "ME2Randomizer",
                    UpdateFilenameInArchive  = "ME2Randomizer.exe",
                    ShowUpdatePromptCallback = (title, text, updateButtonText, declineButtonText) =>
                    {
                        bool   response = false;
                        object syncObj  = new object();
                        Application.Current.Dispatcher.Invoke(async() =>
                        {
                            if (Application.Current.MainWindow is MainWindow mw)
                            {
                                var result = await mw.ShowMessageAsync(title, text, MessageDialogStyle.AffirmativeAndNegative, new MetroDialogSettings()
                                {
                                    AffirmativeButtonText = updateButtonText,
                                    NegativeButtonText    = declineButtonText,
                                    DefaultButtonFocus    = MessageDialogResult.Affirmative
                                },
                                                                       75);
                                response = result == MessageDialogResult.Affirmative;
                                lock (syncObj)
                                {
                                    Monitor.Pulse(syncObj);
                                }
                            }
                        });
                        lock (syncObj)
                        {
                            Monitor.Wait(syncObj);
                        }
                        return(response);
                    },
                    ShowUpdateProgressDialogCallback = (title, initialmessage, canCancel) =>
                    {
                        // We don't use this as we are already in a progress dialog
                        pd.SetCancelable(canCancel);
                        pd.SetMessage(initialmessage);
                        pd.SetTitle(title);
                    },
                    SetUpdateDialogTextCallback = s =>
                    {
                        pd.SetMessage(s);
                    },
                    ProgressCallback = (done, total) =>
                    {
                        pd.SetProgress(done * 1d / total);
                        pd.SetMessage($"Downloading update {FileSize.FormatSize(done)} / {FileSize.FormatSize(total)}");
                    },
                    ProgressIndeterminateCallback = () =>
                    {
                        pd.SetIndeterminate();
                    },
                    ShowMessageCallback = (title, message) =>
                    {
                        object syncObj = new object();
                        Application.Current.Dispatcher.Invoke(async() =>
                        {
                            if (Application.Current.MainWindow is MainWindow mw)
                            {
                                await mw.ShowMessageAsync(title, message);
                                lock (syncObj)
                                {
                                    Monitor.Pulse(syncObj);
                                }
                            }
                        });
                        lock (syncObj)
                        {
                            Monitor.Wait(syncObj);
                        }
                    },
                    NotifyBetaAvailable = () =>
                    {
                        App.BetaAvailable = true;
                    },
                    DownloadCompleted = () =>
                    {
                        pd.SetCancelable(false);
                    },
                    cancellationTokenSource    = ct,
                    ApplicationName            = "Mass Effect 2 Randomizer",
                    RequestHeader              = "ME2Randomizer",
                    ForcedUpgradeMaxReleaseAge = 3
                };

                #endregion



                pd.SetMessage("Checking for application updates");
                pd.Canceled += (sender, args) =>
                {
                    ct.Cancel();
                };
                AppUpdater.PerformGithubAppUpdateCheck(interopPackage);

                // If user aborts download
                pd.SetCancelable(false);
                pd.SetIndeterminate();
                pd.SetTitle("Starting up");

                void setStatus(string message)
                {
                    pd.SetIndeterminate();
                    pd.SetMessage(message);
                }

                GameTarget target = null;
                try
                {
                    pd.SetMessage("Loading Mass Effect 2 Randomizer framework");
                    ToolTipService.ShowOnDisabledProperty.OverrideMetadata(typeof(Control), new FrameworkPropertyMetadata(true));
                    ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(int.MaxValue));

                    ALOTInstallerCoreLib.PostCriticalStartup(x => pd.SetMessage(x), RunOnUIThread, false);

#if __LE2__
                    LE2Directory.ReloadDefaultGamePath(true);
                    if (LE2Directory.DefaultGamePath != null)
                    {
                        GameTarget gt = new GameTarget(MEGame.LE2, LE2Directory.DefaultGamePath, true);
                        if (gt.ValidateTarget() == null)
                        {
                            Locations.SetTarget(gt, false);
                        }
                    }
#endif
                    MEPackageHandler.GlobalSharedCacheEnabled = false; // ME2R does not use the global shared cache.

                    handleM3Passthrough();
                    target = Locations.GetTarget(MERFileSystem.Game);
                    if (target == null)
                    {
                        var gamePath = MEDirectories.GetDefaultGamePath(MERFileSystem.Game);
                        if (Directory.Exists(gamePath))
                        {
                            target = new GameTarget(MERFileSystem.Game, gamePath, true);
                            var validationFailedReason = target.ValidateTarget();
                            if (validationFailedReason == null)
                            {
                                // CHECK NOT TEXTURE MODIFIED
                                if (target.TextureModded)
                                {
                                    MERLog.Error($@"Game target is texture modded: {target.TargetPath}. This game target is not targetable by ME2R");
                                    object o = new object();
                                    Application.Current.Dispatcher.Invoke(async() =>
                                    {
                                        if (Application.Current.MainWindow is MainWindow mw)
                                        {
                                            await mw.ShowMessageAsync("Mass Effect 2 target is texture modded", $"The game located at {target.TargetPath} has had textures modified. Mass Effect 2 Randomizer cannot randomize texture modified games, as it adds package files. If you want to texture mod your game, it must be done after randomization.", ContentWidthPercent: 75);
                                            lock (o)
                                            {
                                                Monitor.Pulse(o);
                                            }
                                        }
                                    });
                                    lock (o)
                                    {
                                        Monitor.Wait(o);
                                    }
                                }

                                // We still set target so we can restore game if necessary
                                Locations.SetTarget(target, false);
                            }
                        }
                    }


                    pd.SetMessage("Performing startup checks");
                    MERStartupCheck.PerformStartupCheck((title, message) =>
                    {
                        object o = new object();
                        Application.Current.Dispatcher.Invoke(async() =>
                        {
                            if (Application.Current.MainWindow is MainWindow mw)
                            {
                                await mw.ShowMessageAsync(title, message, ContentWidthPercent: 75);
                                lock (o)
                                {
                                    Monitor.Pulse(o);
                                }
                            }
                        });
                        lock (o)
                        {
                            Monitor.Wait(o);
                        }
                    }, x => pd.SetMessage(x));

                    // force initial refresh
                    MERPeriodicRefresh(null, null);
                }
                catch (Exception e)
                {
                    MERLog.Exception(e, @"There was an error starting up the framework!");
                }

                pd.SetMessage("Preparing interface");
                Thread.Sleep(250); // This will allow this message to show up for moment so user can see it.

                Application.Current.Dispatcher.Invoke(async() =>
                {
                    if (Application.Current.MainWindow is MainWindow mw)
                    {
                        mw.SetupTargetDescriptionText();


                        var backupStatus                = BackupService.GetBackupStatus(MERFileSystem.Game);
                        mw.BackupRestoreText            = backupStatus?.BackupActionText;
                        mw.BackupRestore_Button.ToolTip = backupStatus != null && backupStatus.BackedUp ? "Click to restore game/uninstall randomizer mod" : "Click to backup game";

                        mw.FinalizeInterfaceLoad();

                        /*
                         * if (!hasWorkingMEM)
                         * {
                         *  await mw.ShowMessageAsync("Required components are not available",
                         *      "Some components for installation are not available, likely due to network issues (blocking, no internet, etc). To install these components, folow the 'How to install the Installer Support Package' directions on any of the ALOT pages on NexusMods. The installer will not work without these files installed.",
                         *      ContentWidthPercent: 75);
                         * }*/

                        PeriodicRefresh.OnPeriodicRefresh += MERPeriodicRefresh;
                    }
                });
            };
            bw.RunWorkerCompleted += async(a, b) =>
            {
                // Post critical startup
                Random random  = new Random();
                var    preseed = random.Next();
                window.ImageCredits.ReplaceAll(ImageCredit.LoadImageCredits("imagecredits.txt", false));
                window.ContributorCredits.ReplaceAll(window.GetContributorCredits());
                window.LibraryCredits.ReplaceAll(LibraryCredit.LoadLibraryCredits("librarycredits.txt"));
#if DEBUG
                window.SeedTextBox.Text = 529572808.ToString();
#else
                window.SeedTextBox.Text = preseed.ToString();
#endif
                window.TextBlock_AssemblyVersion.Text = $"Version {App.AppVersion}";
                window.SelectedRandomizeMode          = MainWindow.RandomizationMode.ERandomizationMode_SelectAny;


                var hasFirstRun = RegistryHandler.GetRegistrySettingBool(MainWindow.SETTING_FIRSTRUN);
                if (hasFirstRun == null || !hasFirstRun.Value)
                {
                    window.FirstRunFlyoutOpen = true;
                }
                await pd.CloseAsync();
            };
            bw.RunWorkerAsync();
        }
        //public static ALOTVersionInfo GetInstalledALOTInfo()
        //{
        //    string gamePath = MERUtilities.GetALOTMarkerFilePath();
        //    if (gamePath != null && File.Exists(gamePath))
        //    {
        //        try
        //        {
        //            using (FileStream fs = new FileStream(gamePath, System.IO.FileMode.Open, FileAccess.Read))
        //            {
        //                fs.SeekEnd();
        //                long endPos = fs.Position;
        //                fs.Position = endPos - 4;
        //                uint memi = fs.ReadUInt32();

        //                if (memi == MEMI_TAG)
        //                {
        //                    //ALOT has been installed
        //                    fs.Position = endPos - 8;
        //                    int installerVersionUsed = fs.ReadInt32();
        //                    int perGameFinal4Bytes = 0;

        //                    if (installerVersionUsed >= 10 && installerVersionUsed != perGameFinal4Bytes) //default bytes before 178 MEMI Format
        //                    {
        //                        fs.Position = endPos - 12;
        //                        short ALOTVER = fs.ReadInt16();
        //                        byte ALOTUPDATEVER = (byte)fs.ReadByte();
        //                        byte ALOTHOTFIXVER = (byte)fs.ReadByte();

        //                        //unused for now
        //                        fs.Position = endPos - 16;
        //                        int MEUITMVER = fs.ReadInt32();

        //                        return new ALOTVersionInfo(ALOTVER, ALOTUPDATEVER, ALOTHOTFIXVER, MEUITMVER);
        //                    }
        //                    else
        //                    {
        //                        return new ALOTVersionInfo(0, 0, 0, 0); //MEMI tag but no info we know of
        //                    }
        //                }
        //            }
        //        }
        //        catch (Exception e)
        //        {
        //            MERLog.Error("Error reading marker file for Mass Effect. ALOT Info will be returned as null (nothing installed). " + e.Message);
        //            return null;
        //        }
        //    }
        //    return null;
        //}


        public static int runProcess(string exe, string args, bool standAlone = false)
        {
            MERLog.Information("Running process: " + exe + " " + args);
            using (Process p = new Process())
            {
                p.StartInfo.CreateNoWindow         = true;
                p.StartInfo.FileName               = exe;
                p.StartInfo.UseShellExecute        = false;
                p.StartInfo.Arguments              = args;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError  = true;


                StringBuilder output = new StringBuilder();
                StringBuilder error  = new StringBuilder();

                using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
                    using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                    {
                        p.OutputDataReceived += (sender, e) =>
                        {
                            if (e.Data == null)
                            {
                                outputWaitHandle.Set();
                            }
                            else
                            {
                                output.AppendLine(e.Data);
                            }
                        };
                        p.ErrorDataReceived += (sender, e) =>
                        {
                            if (e.Data == null)
                            {
                                errorWaitHandle.Set();
                            }
                            else
                            {
                                error.AppendLine(e.Data);
                            }
                        };

                        p.Start();
                        if (!standAlone)
                        {
                            int timeout = 600000;
                            p.BeginOutputReadLine();
                            p.BeginErrorReadLine();

                            if (p.WaitForExit(timeout) &&
                                outputWaitHandle.WaitOne(timeout) &&
                                errorWaitHandle.WaitOne(timeout))
                            {
                                // Process completed. Check process.ExitCode here.
                                MERLog.Information("Process standard output of " + exe + " " + args + ":");
                                if (output.ToString().Length > 0)
                                {
                                    MERLog.Information("Standard:\n" + output.ToString());
                                }
                                if (error.ToString().Length > 0)
                                {
                                    MERLog.Error("Error output:\n" + error.ToString());
                                }
                                return(p.ExitCode);
                            }
                            else
                            {
                                // Timed out.
                                MERLog.Error("Process timed out: " + exe + " " + args);
                                return(-1);
                            }
                        }
                        else
                        {
                            return(0); //standalone
                        }
                    }
            }
        }