// pass the path to the file and check the return public static FilePEType GetFilePE(string path) { FilePEType pe = new FilePEType(); pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN; if (File.Exists(path)) { using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { byte[] data = new byte[4096]; fs.Read(data, 0, 4096); ushort result = BitConverter.ToUInt16(data, BitConverter.ToInt32(data, 60) + 4); try { pe = (FilePEType)result; } catch (Exception) { pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN; } } } return(pe); }
private void PerformLocalInstall() { ActiveOperation = true; /* * 1. Browse for appropriate executable. * 2. Download and extract Special K archive to a dummy folder. * 3. Detect 32-bit or 64-bit from the file executable. * 4. Prompt user about API support (might be able to be automated in the future?) * 5. Move appropriate SpecialK32/64.dll files to the target folder. * */ ApiDialog apiDialog = new ApiDialog(); OpenFileDialog fileDialog = new OpenFileDialog { Filter = "Game executables (*.exe)|*.exe", Title = "Browse for game executable", CheckFileExists = true, CheckPathExists = true, Multiselect = false, ValidateNames = true, RestoreDirectory = true }; if (fileDialog.ShowDialog() == DialogResult.OK && apiDialog.ShowDialog() == DialogResult.OK) { LocalInstallAPI = apiDialog.Api; Log("Attempting to install local (game-specific) wrapper DLLs for " + fileDialog.FileName); FilePEType type = GetFilePE(fileDialog.FileName); if (type == FilePEType.IMAGE_FILE_MACHINE_AMD64) { LocalInstall64bit = true; // 64-bit } else if (type == FilePEType.IMAGE_FILE_MACHINE_I386) { LocalInstall64bit = false; // 32-bit, or AnyCPU for .NET-based games } else { Log("Unknown executable architecture."); // Unknown } TargetInstallPath = Path.GetDirectoryName(fileDialog.FileName); bool fileExists = File.Exists(_tmpDownloadPath); bool cancel = false; if (fileExists) { Log("A file called " + _tmpArchiveName + " was found in the downloads folder. Prompting user on how to proceed."); switch (MessageBox.Show("A file called " + _tmpArchiveName + " was found in the downloads folder.\r\nDo you want to use that one?\r\n\r\nClicking 'No' will redownload the file from the Internet.", "Found local file for selected version", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3)) { case DialogResult.Yes: Log("User chose to reuse the local copy found."); break; case DialogResult.No: fileExists = false; Log("User chose to redownload the archive from the Internet."); break; case DialogResult.Cancel: cancel = true; ActiveOperation = false; Log("User canceled the install process."); break; } } if (cancel == false) { if (fileExists == false) { Log("Downloading " + _tmpDownloadURL); using (OngoingDownload = new WebClient()) { OngoingDownload.DownloadProgressChanged += OnDownloadProgressChanged; OngoingDownload.DownloadFileCompleted += (object sender, AsyncCompletedEventArgs e) => { if (!tsProgress.IsDisposed) { tsProgress.Visible = false; } if (e.Cancelled || e.Error != null) { if (e.Cancelled) { Log("Download cancelled!"); } else if (e.Error != null) { Log("Download failed!"); Log("Error message: " + e.Error.Message + "\r\n"); } Log("Cleaning up incomplete file " + _tmpDownloadPath); if (File.Exists(_tmpDownloadPath)) { File.Delete(_tmpDownloadPath); } ActiveOperation = false; CancelOperation = true; OngoingDownload.Dispose(); OngoingDownload = null; return; } Log("Download completed!"); FinalizeLocalInstall(); OngoingDownload.Dispose(); OngoingDownload = null; }; OngoingDownload.DownloadFileAsync(new Uri(_tmpDownloadURL), _tmpDownloadPath); } } else { FinalizeLocalInstall(); } } } else { ActiveOperation = CancelOperation = false; } }