示例#1
0
        unsafe public void EnumerateFiles(IntPtr medBuffer, ref Dictionary <ulong, FileNameAndParentFrn> files)
        {
            IntPtr pData = Marshal.AllocHGlobal(sizeof(UInt64) + 0x10000);

            PInvokeWin32.ZeroMemory(pData, sizeof(UInt64) + 0x10000);
            uint outBytesReturned = 0;

            while (false != PInvokeWin32.DeviceIoControl(_changeJournalRootHandle, PInvokeWin32.FSCTL_ENUM_USN_DATA, medBuffer,
                                                         sizeof(PInvokeWin32.MFT_ENUM_DATA), pData, sizeof(UInt64) + 0x10000, out outBytesReturned,
                                                         IntPtr.Zero))
            {
                IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64));
                while (outBytesReturned > 60)
                {
                    PInvokeWin32.USN_RECORD usn = new PInvokeWin32.USN_RECORD(pUsnRecord);
                    if (0 != (usn.FileAttributes & PInvokeWin32.FILE_ATTRIBUTE_DIRECTORY))
                    {
                        //
                        // handle directories
                        //
                        if (!files.ContainsKey(usn.FileReferenceNumber))
                        {
                            files.Add(usn.FileReferenceNumber,
                                      new FileNameAndParentFrn(usn.FileName, usn.ParentFileReferenceNumber));
                        }
                        else
                        {   // this is debug code and should be removed when we are certain that
                            // duplicate frn's don't exist on a given drive.  To date, this exception has
                            // never been thrown.  Removing this code improves performance....
                            throw new Exception(string.Format("Duplicate FRN: {0} for {1}",
                                                              usn.FileReferenceNumber, usn.FileName));
                        }
                    }
                    else
                    {
                        if (!files.ContainsKey(usn.FileReferenceNumber))
                        {
                            files.Add(usn.FileReferenceNumber,
                                      new FileNameAndParentFrn(usn.FileName, usn.ParentFileReferenceNumber));
                        }
                        else
                        {
                            FileNameAndParentFrn frn = files[usn.FileReferenceNumber];
                            if (0 != string.Compare(usn.FileName, frn.Name, true))
                            {
                                //	Log.InfoFormat(
                                //	"Attempt to add duplicate file reference number: {0} for file {1}, file from index {2}",
                                //	usn.FileReferenceNumber, usn.FileName, frn.Name);
                                throw new Exception(string.Format("Duplicate FRN: {0} for {1}",
                                                                  usn.FileReferenceNumber, usn.FileName));
                            }
                        }
                    }
                    pUsnRecord        = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength);
                    outBytesReturned -= usn.RecordLength;
                }
                Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
            }
            Marshal.FreeHGlobal(pData);
        }
示例#2
0
        public static string soloMFTGetFullyQualifiedPath(UInt32 frn)
        {
            string retval = string.Empty;;
            FileNameAndParentFrn fnFRN = null;

            if (frn >= 0)
            {
                if (soloMFTDictOffsets.TryGetValue(frn, out fnFRN))
                {
                    retval = fnFRN.Name;
                    while (fnFRN.ParentFrn != 0)
                    {
                        if (soloMFTDictOffsets.TryGetValue(fnFRN.ParentFrn, out fnFRN))
                        {
                            string name = fnFRN.Name;
                            retval = Path.Combine(name, retval);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
            else
            {
                throw new ArgumentException("Invalid argument", "frn");
            }
            return(retval);
        }
示例#3
0
 private void ResolvePath(string drive, ref Dictionary <ulong, FileNameAndParentFrn> files)
 {
     foreach (KeyValuePair <ulong, FileNameAndParentFrn> entry in files)
     {
         FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;
         file.Path = string.Concat(FrnToParentDirectory(drive, file.ParentFrn), Path.DirectorySeparatorChar, file.Name);
     }
 }
示例#4
0
        public void ScanExes()
        {
            DriveInfo[] drives = DriveInfo.GetDrives();
            Stopwatch   stop   = new Stopwatch();

            for (int i = 0; i < drives.Length; i++)
            {
                DriveInfo d = drives[i];

                if (d.DriveFormat != "NTFS")
                {
                    continue;
                }

                LogManager.Log("> Searching drive {0} for game executables", d.Name);

                stop.Reset();
                stop.Start();

                Dictionary <ulong, FileNameAndParentFrn> mDict = new Dictionary <ulong, FileNameAndParentFrn>();
                MFTReader mft = new MFTReader();
                mft.Drive = d.RootDirectory.FullName;

                mft.EnumerateVolume(out mDict, new string[] { ".exe" });
                foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in mDict)
                {
                    FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                    string name  = file.Name;
                    string lower = name.ToLower();

                    GameInfo game;
                    if (gameManager.GameInfos.TryGetValue(lower, out game))
                    {
                        string path = mft.GetFullPath(file);
                        LogManager.Log("Found game: {0}, full path: {1}", game.GameName, path);

                        UserGameInfo info = new UserGameInfo();
                        info.InitializeDefault(game, path);
                        gameManager.User.Games.Add(info);
                    }
                }

                stop.Stop();
                LogManager.Log("> Took {0} seconds to search drive {1}", stop.Elapsed.TotalSeconds.ToString("0.00"), d.Name);
            }

            gameManager.SaveUserProfile();
            gameManager.WaitSave();
        }
示例#5
0
        public FileNameAndParentFrn SearchId(ulong key, Dictionary <ulong, FileNameAndParentFrn> mDict)
        {
            FileNameAndParentFrn file = null;

            if (mDict.ContainsKey(key))
            {
                file = mDict[key];

                Program.nameLst.Add(file.Name);

                while (file != null)
                {
                    file = SearchId(file.ParentFrn, mDict);
                }
            }


            return(file);
        }
示例#6
0
        private void GetRootFrnEntry(string drive)
        {
            string driveRoot = string.Concat("\\\\.\\", drive);

            driveRoot = string.Concat(driveRoot, Path.DirectorySeparatorChar);
            IntPtr hRoot = NativeWrapper.CreateFile(driveRoot,
                                                    0,
                                                    NativeWrapper.FILE_SHARE_READ | NativeWrapper.FILE_SHARE_WRITE,
                                                    IntPtr.Zero,
                                                    NativeWrapper.OPEN_EXISTING,
                                                    NativeWrapper.FILE_FLAG_BACKUP_SEMANTICS,
                                                    IntPtr.Zero);

            if (hRoot.ToInt32() != NativeWrapper.INVALID_HANDLE_VALUE)
            {
                BY_HANDLE_FILE_INFORMATION fi = new BY_HANDLE_FILE_INFORMATION();
                bool bRtn = NativeWrapper.GetFileInformationByHandle(hRoot, out fi);
                if (bRtn)
                {
                    UInt64 fileIndexHigh = (UInt64)fi.FileIndexHigh;
                    UInt64 indexRoot     = (fileIndexHigh << 32) | fi.FileIndexLow;

                    FileNameAndParentFrn f = new FileNameAndParentFrn(driveRoot, 0);

                    _directories.Add(indexRoot, f);
                }
                else
                {
                    throw new IOException("GetFileInformationbyHandle() returned invalid handle",
                                          new Win32Exception(Marshal.GetLastWin32Error()));
                }
                NativeWrapper.CloseHandle(hRoot);
            }
            else
            {
                throw new IOException("Unable to get root frn entry", new Win32Exception(Marshal.GetLastWin32Error()));
            }
        }
示例#7
0
        private void SearchDrive(object state)
        {
            int             i    = (int)state;
            SearchDriveInfo info = toSearch[i];

            if (!info.drive.IsReady)
            {
                done++;
                return;
            }

            float totalDiskPc = 1 / (float)toSearch.Count;
            float thirdDiskPc = totalDiskPc / 3.0f;

            // 1/3 done, we started the operation
            UpdateProgress(thirdDiskPc);

            LogManager.Log("> Searching drive {0} for game executables", info.drive.Name);

            Dictionary <ulong, FileNameAndParentFrn> mDict = new Dictionary <ulong, FileNameAndParentFrn>();
            MFTReader mft = new MFTReader();

            mft.Drive = info.drive.RootDirectory.FullName;

            mft.EnumerateVolume(out mDict, new string[] { ".exe" });

            progress += thirdDiskPc; // 2/3 done
            UpdateProgress(thirdDiskPc);

            float increment = thirdDiskPc / (float)mDict.Count;

            foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in mDict)
            {
                if (closed)
                {
                    return;
                }

                UpdateProgress(increment);

                FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                string name  = file.Name;
                string lower = name.ToLower();

                if (GameManager.Instance.AnyGame(lower))
                {
                    string path = mft.GetFullPath(file);
                    if (path.Contains("$Recycle.Bin") ||
                        path.Contains(@"\Instance"))
                    {
                        // noope
                        continue;
                    }

                    UserGameInfo uinfo = GameManager.Instance.TryAddGame(path);

                    if (uinfo != null)
                    {
#if RELEASE
                        if (uinfo.Game.Debug)
                        {
                            continue;
                        }
#endif

                        LogManager.Log("> Found new game {0} on drive {1}", uinfo.Game.GameName, info.drive.Name);
                        Invoke(new Action(delegate
                        {
                            listGames.Items.Add(uinfo.Game.GameName + " - " + path);
                            listGames.Invalidate();
                            main.NewUserGame(uinfo);
                        }));
                    }
                }
            }

            if (closed)
            {
                return;
            }

            done++;
            if (done == toSearch.Count)
            {
                searching = false;
                Invoke(new Action(delegate
                {
                    progress = 1;
                    UpdateProgress(0);
                    btnSearch.Enabled = true;
                    main.RefreshGames();
                    MessageBox.Show("Finished searching!");
                }));
            }
        }
示例#8
0
        private void SearchDrive(object state)
        {
            int driveIndex         = (int)state;
            SearchStorageInfo info = drivesToSearch[driveIndex];

            if (!info.Drive.IsReady)
            {
                drivesFinishedSearching++;
                return;
            }

            float totalDiskPc = 1 / (float)drivesToSearch.Count;
            float thirdDiskPc = totalDiskPc / 3.0f;

            // 1/3 done, we started the operation
            UpdateProgress(thirdDiskPc);

            Log.WriteLine($"> Searching drive {info.Drive.Name} for game executables");

            Dictionary <ulong, FileNameAndParentFrn> allExes = new Dictionary <ulong, FileNameAndParentFrn>();
            MFTReader mft = new MFTReader();

            mft.Drive = info.Drive.RootDirectory.FullName;

            // TODO: search only for specific games?
            mft.EnumerateVolume(out allExes, new string[] { ".exe" });

            UpdateProgress(thirdDiskPc); // 2/3 done

            float perFilePCIncrement = thirdDiskPc / (float)allExes.Count;
            bool  shouldUpdate       = false;

            foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in allExes)
            {
                UpdateProgress(perFilePCIncrement);

                FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                string name  = file.Name;
                string lower = name.ToLower();

                if (GameManager.Instance.AnyGame(lower))
                {
                    string path = mft.GetFullPath(file);
                    if (path.Contains("$Recycle.Bin") ||
                        path.Contains(@"\Instance"))
                    {
                        // noope
                        continue;
                    }

                    UserGameInfo uinfo = GameManager.Instance.TryAddGame(path);

                    if (uinfo != null)
                    {
                        Log.WriteLine($"> Found new game ID {uinfo.GameID} on drive {info.Drive.Name}");
                        Invoke(new Action(delegate {
                            list_games.Items.Add(GameManager.Instance.MetadataManager.GetGameName(uinfo.GameID) + " - " + path);
                            list_games.Invalidate();

                            shouldUpdate = true;
                        }));
                    }
                }
            }

            if (shouldUpdate)
            {
                MainForm.Instance.Invoke((Action)MainForm.Instance.RefreshGames);
            }

            drivesFinishedSearching++;
            if (drivesFinishedSearching == drivesToSearch.Count)
            {
                searching = false;
                Invoke(new Action(delegate {
                    progress = 1;
                    UpdateProgress(0);
                    btn_search.Enabled = true;

                    // TODO make it better
                    MainForm.Instance.RefreshGames();
                    MessageBox.Show("Finished searching!");
                }));
            }
        }
示例#9
0
        unsafe public void EnumerateFiles(IntPtr medBuffer, ref Dictionary <ulong, FileNameAndParentFrn> files, string[] fileExtensions)
        {
            IntPtr pData = Marshal.AllocHGlobal(sizeof(UInt64) + 0x10000);

            try
            {
                NativeWrapper.ZeroMemory(pData, sizeof(UInt64) + 0x10000);
                uint outBytesReturned = 0;

                while (false != NativeWrapper.DeviceIoControl(_changeJournalRootHandle,
                                                              NativeWrapper.FSCTL_ENUM_USN_DATA,
                                                              medBuffer,
                                                              sizeof(MFT_ENUM_DATA),
                                                              pData,
                                                              sizeof(UInt64) + 0x10000,
                                                              out outBytesReturned,
                                                              IntPtr.Zero))
                {
                    IntPtr pUsnRecord = new IntPtr(pData.ToInt32() + sizeof(Int64));
                    while (outBytesReturned > 60)
                    {
                        USN_RECORD usn = new USN_RECORD(pUsnRecord);
                        if (0 != (usn.FileAttributes & NativeWrapper.FILE_ATTRIBUTE_DIRECTORY))
                        {
                            //
                            // handle directories
                            //
                            if (!_directories.ContainsKey(usn.FileReferenceNumber))
                            {
                                _directories.Add(usn.FileReferenceNumber,
                                                 new FileNameAndParentFrn(usn.FileName, usn.ParentFileReferenceNumber));
                            }
                            else
                            { // this is debug code and should be removed when we are certain that
                              // duplicate frn's don't exist on a given drive.  To date, this exception has
                              // never been thrown.  Removing this code improves performance....
                                throw new Exception(string.Format("Duplicate FRN: {0} for {1}",
                                                                  usn.FileReferenceNumber, usn.FileName));
                            }
                        }
                        else
                        {
                            //
                            // handle files
                            //

                            // at this point we could get the * for the extension
                            bool add      = true;
                            bool fullpath = false;
                            if (fileExtensions != null && fileExtensions.Length != 0)
                            {
                                if (fileExtensions[0].ToString() == "*")
                                {
                                    add      = true;
                                    fullpath = true;
                                }
                                else
                                {
                                    add = false;
                                    string s = Path.GetExtension(usn.FileName);
                                    foreach (string extension in fileExtensions)
                                    {
                                        if (0 == string.Compare(s, extension, true))
                                        {
                                            add = true;
                                            break;
                                        }
                                    }
                                }
                            }
                            if (add)
                            {
                                if (fullpath)
                                {
                                    if (!files.ContainsKey(usn.FileReferenceNumber))
                                    {
                                        files.Add(usn.FileReferenceNumber,
                                                  new FileNameAndParentFrn(usn.FileName, usn.ParentFileReferenceNumber));
                                    }
                                    else
                                    {
                                        FileNameAndParentFrn frn = files[usn.FileReferenceNumber];
                                        if (0 != string.Compare(usn.FileName, frn.Name, true))
                                        {
                                            //	Log.InfoFormat(
                                            //	"Attempt to add duplicate file reference number: {0} for file {1}, file from index {2}",
                                            //	usn.FileReferenceNumber, usn.FileName, frn.Name);
                                            throw new Exception(string.Format("Duplicate FRN: {0} for {1}",
                                                                              usn.FileReferenceNumber, usn.FileName));
                                        }
                                    }
                                }
                                else
                                {
                                    if (!files.ContainsKey(usn.FileReferenceNumber))
                                    {
                                        files.Add(usn.FileReferenceNumber,
                                                  new FileNameAndParentFrn(usn.FileName, usn.ParentFileReferenceNumber));
                                    }
                                    else
                                    {
                                        FileNameAndParentFrn frn = files[usn.FileReferenceNumber];
                                        if (0 != string.Compare(usn.FileName, frn.Name, true))
                                        {
                                            //	Log.InfoFormat(
                                            //	"Attempt to add duplicate file reference number: {0} for file {1}, file from index {2}",
                                            //	usn.FileReferenceNumber, usn.FileName, frn.Name);
                                            throw new Exception(string.Format("Duplicate FRN: {0} for {1}",
                                                                              usn.FileReferenceNumber, usn.FileName));
                                        }
                                    }
                                }
                            }
                        }
                        pUsnRecord        = new IntPtr(pUsnRecord.ToInt32() + usn.RecordLength);
                        outBytesReturned -= usn.RecordLength;
                    }
                    Marshal.WriteInt64(medBuffer, Marshal.ReadInt64(pData, 0));
                }
            }
            catch (Exception e)
            {
                Console.Error.WriteLine(e.Message);
                Console.Error.WriteLine(e.StackTrace);
                throw new ApplicationException("Error in EnumerateFiles()", e);
            }
            finally
            {
                Marshal.FreeHGlobal(pData);
            }
        }
示例#10
0
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("### " + Constants.APP_SIGNATURE + " ###");
                Console.WriteLine("### " + Constants.APP_URL + " ###\n");
                Console.Write("Processing...\r");

                Int32 unixTimestampInit = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

                string driveLetter   = Properties.Settings.Default.search_volume;
                string fileNamePath  = Properties.Settings.Default.report_folder;
                string fileExtension = Properties.Settings.Default.search_extensions;
                bool   calcMd5       = Properties.Settings.Default.calc_md5;

                string fileNamePathRecommendation = "report_folder (" + fileNamePath + ") must be a valid folder, and the current user must have write access in it. The valid slash must be / and NOT \\.";

                if (!Directory.Exists(fileNamePath))
                {
                    Utils.Instance.ThrowErr(fileNamePathRecommendation);
                }
                else if (fileNamePath[fileNamePath.Length - 1] == '/')
                {
                    fileNamePath = fileNamePath.Substring(0, fileNamePath.Length - 1);
                }


                if (driveLetter.Length > 1 || driveLetter.Contains(":") || fileNamePath.Contains("\\") || !fileExtension.Contains(".") || fileExtension.Contains("*"))
                {
                    Utils.Instance.ThrowErr("\n\nCheck the config file:\n\n1. search_volume (" + driveLetter + ") must be JUST a NTFS volume/drive letter WITHOUT ':', like C, D, F, G, etc. The current user must have administration rights over this volume.\n\n" +
                                            "2. " + fileNamePathRecommendation + "\n\n" +
                                            "3. search_extensions (" + fileExtension + ") is the representation of a file extension, like .txt, .pdf, .doc, etc, WITH dot (.) WITHOUT asterisk (*).");
                }


                nameLst = new List <string>();
                Dictionary <ulong, FileNameAndParentFrn> mDict = new Dictionary <ulong, FileNameAndParentFrn>();

                long totalBytes = 0l;
                EnumerateVolume.PInvokeWin32 mft = new EnumerateVolume.PInvokeWin32();
                mft.Drive = driveLetter;
                mft.Drive = mft.Drive + ":";
                mft.EnumerateVolume(out mDict);
                StringBuilder sb               = new StringBuilder();
                StringBuilder pathSb           = null;
                String        jsonFileNamePath = fileNamePath + "/" + driveLetter + "." + unixTimestampInit + ".json";

                Console.Write("Volume: " + driveLetter + "\t\t\n");
                Console.WriteLine("Report folder: " + fileNamePath);
                Console.WriteLine("Extension: " + fileExtension);

                long totalDriveSize = 0;

                try
                {
                    totalDriveSize = Utils.Instance.GetDriveTotalSize(driveLetter);
                }
                catch (Exception e)
                {
                    Utils.Instance.LogException(e);
                }

                if (File.Exists(jsonFileNamePath))
                {
                    File.Delete(jsonFileNamePath);
                    Console.WriteLine("Old file deleted: " + jsonFileNamePath);
                }

                finalNameLst = new List <string>();
                Console.WriteLine("MFT items: " + mDict.Count);
                foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in mDict)
                {
                    FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;
                    pathSb = new StringBuilder();

                    string extractedExtension = Utils.Instance.ExtractExtension(file.Name);

                    if (extractedExtension != null && fileExtension.ToLower().Contains(extractedExtension.ToLower()))
                    {
                        pathSb.Append(driveLetter + ":\\");
                        Utils.Instance.SearchId(file.ParentFrn, mDict);

                        nameLst.Reverse();

                        foreach (var item in nameLst)
                        {
                            pathSb.Append(item + "\\");
                        }

                        pathSb.Append(file.Name);

                        finalNameLst.Add(pathSb.ToString());



                        Console.Write("File references found: " + finalNameLst.Count + "\r");

                        nameLst.Clear();
                    }
                }

                Console.WriteLine();
                sb.AppendLine("{\"initTime\": " + unixTimestampInit + ", \"search_volume\": \"" + driveLetter + "\", \"report_folder\": \"" + fileNamePath + "\", \"search_extensions\": \"" + fileExtension + "\", \"totalDriveSize\": " + totalDriveSize + ", \"objectLst\": [");
                String comma                     = ", ";
                int    notFoundCount             = 0;
                int    ownerExceptionCount       = 0;
                int    machineNameExceptionCount = 0;
                int    fqdnExceptionCount        = 0;
                int    md5ExceptionCount         = 0;
                for (int i = 0; i < finalNameLst.Count; i++)
                {
                    String item = finalNameLst[i];

                    if (File.Exists(item))
                    {
                        if (i + 1 == finalNameLst.Count)
                        {
                            comma = "";
                        }
                        long     fileSize         = new FileInfo(item).Length;
                        DateTime fileCreationDate = File.GetCreationTime(item);
                        DateTime fileUpdateDate   = File.GetLastWriteTime(item);
                        string   owner            = "n/a";
                        string   machineName      = "n/a";
                        string   fqdn             = "n/a";
                        string   md5Hash          = "";


                        if (calcMd5)
                        {
                            try
                            {
                                byte[] byteArray = File.ReadAllBytes(item);
                                string strMd5    = Utils.Instance.ByteArrayToMd5HashString(byteArray);
                                md5Hash = ", \"md5\": \"" + strMd5 + "\"";
                            }
                            catch (Exception e)
                            {
                                md5ExceptionCount++;
                                md5Hash = ", \"md5\": \"n/a\"";
                                Utils.Instance.LogException(e);
                            }
                        }


                        try { owner = Utils.Instance.GetOwnerName(item); }
                        catch (Exception e)
                        {
                            ownerExceptionCount++;
                            Utils.Instance.LogException(e);
                        } finally { owner = Uri.EscapeDataString(owner); }

                        try { machineName = Environment.MachineName; }
                        catch (Exception e)
                        {
                            machineNameExceptionCount++;
                            Utils.Instance.LogException(e);
                        }  finally { machineName = Uri.EscapeDataString(machineName); }

                        try { fqdn = Utils.Instance.GetFQDN(); }
                        catch (Exception e)
                        {
                            fqdnExceptionCount++;
                            Utils.Instance.LogException(e);
                        }
                        finally { fqdn = Uri.EscapeDataString(fqdn); }

                        sb.AppendLine("{ \"fileName\": \"" + Uri.EscapeDataString(item) + "\", \"fileSize\": " + fileSize + ", \"fileCreationDate\": \"" + fileCreationDate + "\", \"fileUpdateDate\": \"" + fileUpdateDate + "\", \"fileAuthor\": \"" + owner + "\", \"fqdn\": \"" + fqdn + "\" " + md5Hash + "}" + comma);
                        totalBytes = fileSize + totalBytes;
                    }
                    else
                    {
                        notFoundCount++;
                    }

                    Console.Write("Inspecting file: " + (i + 1) + "/" + finalNameLst.Count + "\r");
                }
                Int32 unixTimestampEnd = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
                sb.AppendLine("], \"endTime\": " + unixTimestampEnd + " }");

                Utils.Instance.WriteToFile(sb.ToString(), jsonFileNamePath);

                Console.WriteLine("\nFile references not found: " + notFoundCount);
                Console.WriteLine("FQDN resolution errors: " + fqdnExceptionCount);
                Console.WriteLine("Machine Name resolution errors: " + machineNameExceptionCount);
                Console.WriteLine("File ownership resolution errors: " + ownerExceptionCount);
                Console.WriteLine("MD5 hash errors: " + md5ExceptionCount);
                Console.WriteLine("\nTotal bytes: " + Utils.Instance.FormatBytesLength(totalBytes));
                Console.WriteLine("Process ended. Check the results in: " + jsonFileNamePath);

                Console.WriteLine("\n[PRESS ENTER]");
                Console.ReadLine();
            }
            catch (Exception e)
            {
                Utils.Instance.ThrowErr(e.Message);
                Utils.Instance.LogException(e);
            }
        }
示例#11
0
        private static void ExecuteTask(StartGameData data)
        {
            switch (data.Task)
            {
            case GameStarterTask.StartGame: {
                string gamePath       = data.Parameters[0];
                string gameArgs       = data.Parameters[1];
                string gameWorkingDir = data.Parameters[2];

                ConsoleU.WriteLine($"Start game: EXE: {gamePath} ARGS: {gameArgs} WORKDIR: {gameWorkingDir}", Palette.Feedback);
                StartGame(gamePath, gameArgs, gameWorkingDir);
            }
            break;

            case GameStarterTask.KillMutex: {
                Log.WriteLine($"Kill Mutex Task");
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
                KillMutex(procId, mutexes);
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
            }
            break;

            case GameStarterTask.RenameMutex: {
                Log.WriteLine($"Rename Mutex Task");
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
                KillMutex(procId, mutexes);
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
            }
            break;

            case GameStarterTask.ScanKillMutex: {
                Log.WriteLine($"Scan Kill Mutex");

                List <int> processIds = new List <int>();

                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string        scanMutexDataRaw = data.Parameters[j];
                    ScanMutexData scanMutex        = JsonConvert.DeserializeObject <ScanMutexData>(scanMutexDataRaw);
                    Log.WriteLine($"Kill Mutex for process {scanMutex.ProcessName}");

                    for (; ;)
                    {
                        Process[] procs = Process.GetProcessesByName(scanMutex.ProcessName);
                        if (procs == null || procs.Length == 0)
                        {
                            Thread.Sleep(250);
                        }
                        else
                        {
                            // kill mutexes
                            bool killedMutexes = false;
                            for (int k = 0; k < procs.Length; k++)
                            {
                                Process p = procs[k];
                                if (processIds.Contains(p.Id))
                                {
                                    continue;
                                }

                                // start other process, as the mutexes are only truly killed
                                // when the process is ended
                                if (scanMutex.ShouldRename)
                                {
                                    StartGameUtil.RenameMutex(p, scanMutex.Mutexes);
                                }
                                else
                                {
                                    StartGameUtil.KillMutex(p, scanMutex.Mutexes);
                                }
                                //KillMutex(p.Id.ToString(), scanMutex.Mutexes);
                                processIds.Add(p.Id);
                                killedMutexes = true;
                                break;
                            }

                            if (killedMutexes)
                            {
                                Log.WriteLine($"Killed all mutexes for process {scanMutex.ProcessName}");
                                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
                                break;
                            }
                        }
                    }
                }
            }
            break;

            case GameStarterTask.MultipleTasks: {
                Log.WriteLine($"Multiple tasks");
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string        taskDataRaw = data.Parameters[j];
                    StartGameData taskData    = JsonConvert.DeserializeObject <StartGameData>(taskDataRaw);

                    Log.WriteLine($"Executing task {j + 1}");
                    ExecuteTask(taskData);
                }
            }
            break;

            case GameStarterTask.QueryMutex: {
                string   procId  = data.Parameters[0];
                string[] mutexes = new string[data.Parameters.Length - 1];
                for (int j = 1; j < data.Parameters.Length; j++)
                {
                    string m = data.Parameters[j];
                    mutexes[j - 1] = m;
                }
            }
            break;

            case GameStarterTask.ListMonitors:
                break;

            case GameStarterTask.ScanGames: {
                // initialize game manager to read available handlers
                GameManager gameManager = new GameManager();

                List <string> games = new List <string>();
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string driveName = data.Parameters[j];
                    //SearchStorageInfo info = JsonConvert.DeserializeObject<SearchStorageInfo>(storageData);
                    DriveInfo drive = new DriveInfo(driveName);

                    if (!drive.IsReady)
                    {
                        continue;
                    }

                    Log.WriteLine($"> Searching drive {drive.Name} for game executables");

                    Dictionary <ulong, FileNameAndParentFrn> allExes = new Dictionary <ulong, FileNameAndParentFrn>();
                    MFTReader mft = new MFTReader();
                    mft.Drive = drive.RootDirectory.FullName;

                    // TODO: search only for specific games?
                    mft.EnumerateVolume(out allExes, new string[] { ".exe" });

                    foreach (KeyValuePair <UInt64, FileNameAndParentFrn> entry in allExes)
                    {
                        FileNameAndParentFrn file = (FileNameAndParentFrn)entry.Value;

                        string name  = file.Name;
                        string lower = name.ToLower();

                        string path = mft.GetFullPath(file);
                        if (path.Contains("$Recycle.Bin") ||
                            path.Contains(@"\Instance"))
                        {
                            // noope
                            continue;
                        }

                        if (GameManager.Instance.AnyGame(lower))
                        {
                            Log.WriteLine($"Found game at path: {path}");
                            games.Add(path);
                        }
                    }
                }

                WriteToDataFile(Assembly.GetEntryAssembly().Location, JsonConvert.SerializeObject(games));
            }
            break;

            case GameStarterTask.SymlinkFolders:
                for (int j = 0; j < data.Parameters.Length; j++)
                {
                    string symData = data.Parameters[j];
                    Log.WriteLine($"Symlink game instance {j + 1}");

                    SymlinkGameData gameData = JsonConvert.DeserializeObject <SymlinkGameData>(symData);
                    int             exitCode;
                    WinDirectoryUtil.LinkDirectory(gameData.SourcePath, new DirectoryInfo(gameData.SourcePath), gameData.DestinationPath, out exitCode, gameData.DirExclusions, gameData.FileExclusions, gameData.FileCopies, true);
                }
                WriteToDataFile(Assembly.GetEntryAssembly().Location, true.ToString());
                break;
            }
        }