예제 #1
0
        public static UserGame FromDisk(string fileName)
        {
            var item         = new UserGame();
            var fi           = new FileInfo(fileName);
            var vi           = System.Diagnostics.FileVersionInfo.GetVersionInfo(fi.FullName);
            var architecture = Win32.PEReader.GetProcessorArchitecture(fi.FullName);
            var mask         = GetMask(fi.FullName, architecture);

            if (mask == Engine.XInputMask.None)
            {
                mask = (architecture == System.Reflection.ProcessorArchitecture.Amd64)
                                ? mask = Engine.XInputMask.XInput13_x64
                                : mask = Engine.XInputMask.XInput13_x86;
            }
            item.Timeout               = -1;
            item.Comment               = vi.Comments ?? "";
            item.DateCreated           = DateTime.Now;
            item.DateUpdated           = item.DateCreated;
            item.FileName              = fi.Name ?? "";
            item.FileProductName       = EngineHelper.FixName(vi.ProductName, item.FileName);
            item.FileVersion           = vi.FileVersion ?? "";
            item.CompanyName           = vi.CompanyName ?? "";
            item.DiskDriveId           = BoardInfo.GetHashedDiskId();
            item.FileVersion           = new Version(vi.FileMajorPart, vi.FileMinorPart, vi.FileBuildPart, vi.FilePrivatePart).ToString();
            item.FullPath              = fi.FullName ?? "";
            item.GameId                = Guid.NewGuid();
            item.HookMask              = 0;
            item.XInputMask            = (int)mask;
            item.DInputMask            = 0;
            item.DInputFile            = "";
            item.FakeVID               = 0;
            item.FakePID               = 0;
            item.Timeout               = -1;
            item.Weight                = 1;
            item.IsEnabled             = true;
            item.ProcessorArchitecture = (int)architecture;
            return(item);
        }
        /// <summary>
        /// Check game settings against the folder
        /// </summary>
        /// <param name="game"></param>
        /// <param name="fix"></param>
        /// <returns></returns>
        /// <remarks>Implement ability to run this method as Administrator later, because INI/DLL files inside "Program Files" folder will be protected by UAC.</remarks>
        public GameRefreshStatus GetDllAndIniStatus(x360ce.Engine.Data.UserGame game, bool fix = false)
        {
            var status = GameRefreshStatus.OK;
            var fi     = new FileInfo(game.FullPath);

            // Check if game file exists.
            if (!fi.Exists)
            {
                return(GameRefreshStatus.ExeNotExist);
            }
            // Check if game is not enabled.
            else if (!game.IsEnabled)
            {
                return(status);
            }
            else
            {
                var settingsDirectory = game.GetLibraryAndSettingsDirectory();
                var iniFullName       = Path.Combine(settingsDirectory.FullName, IniFileName);
                var tmpFullName       = Path.Combine(settingsDirectory.FullName, TmpFileName);
                // Create dictionary from XInput type and XInput file name.
                var xiValues = ((XInputMask[])Enum.GetValues(typeof(XInputMask))).Where(x => x != XInputMask.None).ToArray();
                var dic      = new Dictionary <XInputMask, string>();
                foreach (var value in xiValues)
                {
                    dic.Add(value, Attributes.GetDescription(value));
                }
                // Get file names: xinput9_1_0.dll, xinput1_1.dll, xinput1_2.dll, xinput1_3.dll, xinput1_4.dll
                var xiFileNames = dic.Values.Distinct();
                // If game DLL emulation is not enabled then...
                if (!game.IsLibrary)
                {
                    // If INI file exists then...
                    status |= CheckUnnecessarySettingFile(fix, iniFullName);
                    // If TMP file exists then...
                    status |= CheckUnnecessaryBackupFile(fix, tmpFullName);
                    // Loop through XInput DLL files.
                    foreach (var xiFileName in xiFileNames)
                    {
                        // Get information about XInput DLL file.
                        var dllFullPath = Path.Combine(fi.Directory.FullName, xiFileName);
                        status |= CheckUnnecessaryLibraryFile(fix, dllFullPath);
                    }
                }
                else
                {
                    status = CheckSettingFileContent(fix, game);
                    // Loop through XInput DLL files.
                    foreach (var xiFileName in xiFileNames)
                    {
                        // Get enumeration linked to 64-bit version of the file.
                        var x64Value = dic.First(x => x.Value == xiFileName && x.ToString().Contains("x64")).Key;
                        // Get enumeration linked to 32-bit version of the file.
                        var x86Value = dic.First(x => x.Value == xiFileName && x.ToString().Contains("x86")).Key;
                        // Get information about XInput DLL file.
                        var xiFullPath = System.IO.Path.Combine(fi.Directory.FullName, xiFileName);
                        var xiFileInfo = new System.IO.FileInfo(xiFullPath);
                        // Determine required architecture.
                        var requiredArchitecture = ProcessorArchitecture.None;
                        var x64Enabled           = ((XInputMask)game.XInputMask).HasFlag(x64Value);
                        var x86Enabled           = ((XInputMask)game.XInputMask).HasFlag(x86Value);
                        if (x86Enabled && x64Enabled)
                        {
                            requiredArchitecture = ProcessorArchitecture.MSIL;
                        }
                        else if (x86Enabled)
                        {
                            requiredArchitecture = ProcessorArchitecture.X86;
                        }
                        else if (x64Enabled)
                        {
                            requiredArchitecture = ProcessorArchitecture.Amd64;
                        }
                        // Get embedded resource name for current XInput file.
                        var resourceName = EngineHelper.GetXInputResoureceName(requiredArchitecture);
                        // If both XInput file CheckBoxes are disabled then...
                        if (requiredArchitecture == ProcessorArchitecture.None)
                        {
                            // If XInput file exists then...
                            if (xiFileInfo.Exists)
                            {
                                if (fix)
                                {
                                    // Delete unnecessary XInput file.
                                    xiFileInfo.Delete();
                                }
                                else
                                {
                                    status |= GameRefreshStatus.UnnecessaryLibraryFile;
                                }
                            }
                        }
                        // If XInput file doesn't exists then...
                        else if (!xiFileInfo.Exists)
                        {
                            // Create XInput file.
                            if (fix)
                            {
                                AppHelper.WriteFile(resourceName, xiFileInfo.FullName);
                            }
                            else
                            {
                                status |= GameRefreshStatus.XInputFilesNotExist;
                            }
                        }
                        else
                        {
                            // Get current architecture of XInput DLL.
                            var xiCurrentArchitecture = PEReader.GetProcessorArchitecture(xiFullPath);
                            // If processor architectures doesn't match then...
                            if (requiredArchitecture != xiCurrentArchitecture)
                            {
                                // Create XInput file.
                                if (fix)
                                {
                                    AppHelper.WriteFile(resourceName, xiFileInfo.FullName);
                                }
                                else
                                {
                                    status |= GameRefreshStatus.XInputFilesWrongPlatform;
                                }
                            }
                            else
                            {
                                // Determine if file was created by Microsoft.
                                bool byMicrosoft;
                                // Get version of XInput DLL on the disk.
                                var dllVersion = EngineHelper.GetDllVersion(xiFullPath, out byMicrosoft);
                                // Get version of embedded XInput DLL.
                                var embededVersion = EngineHelper.GetEmbeddedDllVersion(xiCurrentArchitecture);
                                // If file on disk is older then...
                                if (dllVersion < embededVersion)
                                {
                                    // Overwrite XInput file.
                                    if (fix)
                                    {
                                        AppHelper.WriteFile(resourceName, xiFileInfo.FullName);
                                    }
                                    else
                                    {
                                        status |= GameRefreshStatus.XInputFilesOlderVersion;
                                    }
                                }
                                else if (dllVersion > embededVersion)
                                {
                                    // Allow new version.
                                    // return GameRefreshStatus.XInputFileNewerVersion;
                                }
                            }
                        }
                    }
                }
            }
            return(status);
        }