├── .gitignore ├── DomainBlock.cs ├── DownloadForm.Designer.cs ├── DownloadForm.cs ├── DownloadForm.resx ├── ElevatedButton.cs ├── ExportForm.Designer.cs ├── ExportForm.cs ├── ExportForm.resx ├── ExportXMLClasses.cs ├── FileInformation.cs ├── GfWLRegistry.cs ├── GfWLUtility.csproj ├── GfWLUtility.sln ├── GfWLUtilityLogo.ico ├── MainWindow.Designer.cs ├── MainWindow.cs ├── MainWindow.resx ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── README.md ├── Resources ├── GfWLUtilityCheck.png ├── GfWLUtilityOld.png ├── GfWLUtilityUnknown.png ├── WLIDOld.png └── WLIDUnknown.png ├── TitleManager.cs ├── UserManager.cs ├── UtilityFuncs.cs └── app.manifest /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Ll]og/ 33 | [Ll]ogs/ 34 | 35 | # Visual Studio 2015/2017 cache/options directory 36 | .vs/ 37 | # Uncomment if you have tasks that create the project's static files in wwwroot 38 | #wwwroot/ 39 | 40 | # Visual Studio 2017 auto generated files 41 | Generated\ Files/ 42 | 43 | # MSTest test Results 44 | [Tt]est[Rr]esult*/ 45 | [Bb]uild[Ll]og.* 46 | 47 | # NUnit 48 | *.VisualState.xml 49 | TestResult.xml 50 | nunit-*.xml 51 | 52 | # Build Results of an ATL Project 53 | [Dd]ebugPS/ 54 | [Rr]eleasePS/ 55 | dlldata.c 56 | 57 | # Benchmark Results 58 | BenchmarkDotNet.Artifacts/ 59 | 60 | # .NET Core 61 | project.lock.json 62 | project.fragment.lock.json 63 | artifacts/ 64 | 65 | # ASP.NET Scaffolding 66 | ScaffoldingReadMe.txt 67 | 68 | # StyleCop 69 | StyleCopReport.xml 70 | 71 | # Files built by Visual Studio 72 | *_i.c 73 | *_p.c 74 | *_h.h 75 | *.ilk 76 | *.meta 77 | *.obj 78 | *.iobj 79 | *.pch 80 | *.pdb 81 | *.ipdb 82 | *.pgc 83 | *.pgd 84 | *.rsp 85 | # but not Directory.Build.rsp, as it configures directory-level build defaults 86 | !Directory.Build.rsp 87 | *.sbr 88 | *.tlb 89 | *.tli 90 | *.tlh 91 | *.tmp 92 | *.tmp_proj 93 | *_wpftmp.csproj 94 | *.log 95 | *.tlog 96 | *.vspscc 97 | *.vssscc 98 | .builds 99 | *.pidb 100 | *.svclog 101 | *.scc 102 | 103 | # Chutzpah Test files 104 | _Chutzpah* 105 | 106 | # Visual C++ cache files 107 | ipch/ 108 | *.aps 109 | *.ncb 110 | *.opendb 111 | *.opensdf 112 | *.sdf 113 | *.cachefile 114 | *.VC.db 115 | *.VC.VC.opendb 116 | 117 | # Visual Studio profiler 118 | *.psess 119 | *.vsp 120 | *.vspx 121 | *.sap 122 | 123 | # Visual Studio Trace Files 124 | *.e2e 125 | 126 | # TFS 2012 Local Workspace 127 | $tf/ 128 | 129 | # Guidance Automation Toolkit 130 | *.gpState 131 | 132 | # ReSharper is a .NET coding add-in 133 | _ReSharper*/ 134 | *.[Rr]e[Ss]harper 135 | *.DotSettings.user 136 | 137 | # TeamCity is a build add-in 138 | _TeamCity* 139 | 140 | # DotCover is a Code Coverage Tool 141 | *.dotCover 142 | 143 | # AxoCover is a Code Coverage Tool 144 | .axoCover/* 145 | !.axoCover/settings.json 146 | 147 | # Coverlet is a free, cross platform Code Coverage Tool 148 | coverage*.json 149 | coverage*.xml 150 | coverage*.info 151 | 152 | # Visual Studio code coverage results 153 | *.coverage 154 | *.coveragexml 155 | 156 | # NCrunch 157 | _NCrunch_* 158 | .*crunch*.local.xml 159 | nCrunchTemp_* 160 | 161 | # MightyMoose 162 | *.mm.* 163 | AutoTest.Net/ 164 | 165 | # Web workbench (sass) 166 | .sass-cache/ 167 | 168 | # Installshield output folder 169 | [Ee]xpress/ 170 | 171 | # DocProject is a documentation generator add-in 172 | DocProject/buildhelp/ 173 | DocProject/Help/*.HxT 174 | DocProject/Help/*.HxC 175 | DocProject/Help/*.hhc 176 | DocProject/Help/*.hhk 177 | DocProject/Help/*.hhp 178 | DocProject/Help/Html2 179 | DocProject/Help/html 180 | 181 | # Click-Once directory 182 | publish/ 183 | 184 | # Publish Web Output 185 | *.[Pp]ublish.xml 186 | *.azurePubxml 187 | # Note: Comment the next line if you want to checkin your web deploy settings, 188 | # but database connection strings (with potential passwords) will be unencrypted 189 | *.pubxml 190 | *.publishproj 191 | 192 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 193 | # checkin your Azure Web App publish settings, but sensitive information contained 194 | # in these scripts will be unencrypted 195 | PublishScripts/ 196 | 197 | # NuGet Packages 198 | *.nupkg 199 | # NuGet Symbol Packages 200 | *.snupkg 201 | # The packages folder can be ignored because of Package Restore 202 | **/[Pp]ackages/* 203 | # except build/, which is used as an MSBuild target. 204 | !**/[Pp]ackages/build/ 205 | # Uncomment if necessary however generally it will be regenerated when needed 206 | #!**/[Pp]ackages/repositories.config 207 | # NuGet v3's project.json files produces more ignorable files 208 | *.nuget.props 209 | *.nuget.targets 210 | 211 | # Microsoft Azure Build Output 212 | csx/ 213 | *.build.csdef 214 | 215 | # Microsoft Azure Emulator 216 | ecf/ 217 | rcf/ 218 | 219 | # Windows Store app package directories and files 220 | AppPackages/ 221 | BundleArtifacts/ 222 | Package.StoreAssociation.xml 223 | _pkginfo.txt 224 | *.appx 225 | *.appxbundle 226 | *.appxupload 227 | 228 | # Visual Studio cache files 229 | # files ending in .cache can be ignored 230 | *.[Cc]ache 231 | # but keep track of directories ending in .cache 232 | !?*.[Cc]ache/ 233 | 234 | # Others 235 | ClientBin/ 236 | ~$* 237 | *~ 238 | *.dbmdl 239 | *.dbproj.schemaview 240 | *.jfm 241 | *.pfx 242 | *.publishsettings 243 | orleans.codegen.cs 244 | 245 | # Including strong name files can present a security risk 246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 247 | #*.snk 248 | 249 | # Since there are multiple workflows, uncomment next line to ignore bower_components 250 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 251 | #bower_components/ 252 | 253 | # RIA/Silverlight projects 254 | Generated_Code/ 255 | 256 | # Backup & report files from converting an old project file 257 | # to a newer Visual Studio version. Backup files are not needed, 258 | # because we have git ;-) 259 | _UpgradeReport_Files/ 260 | Backup*/ 261 | UpgradeLog*.XML 262 | UpgradeLog*.htm 263 | ServiceFabricBackup/ 264 | *.rptproj.bak 265 | 266 | # SQL Server files 267 | *.mdf 268 | *.ldf 269 | *.ndf 270 | 271 | # Business Intelligence projects 272 | *.rdl.data 273 | *.bim.layout 274 | *.bim_*.settings 275 | *.rptproj.rsuser 276 | *- [Bb]ackup.rdl 277 | *- [Bb]ackup ([0-9]).rdl 278 | *- [Bb]ackup ([0-9][0-9]).rdl 279 | 280 | # Microsoft Fakes 281 | FakesAssemblies/ 282 | 283 | # GhostDoc plugin setting file 284 | *.GhostDoc.xml 285 | 286 | # Node.js Tools for Visual Studio 287 | .ntvs_analysis.dat 288 | node_modules/ 289 | 290 | # Visual Studio 6 build log 291 | *.plg 292 | 293 | # Visual Studio 6 workspace options file 294 | *.opt 295 | 296 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 297 | *.vbw 298 | 299 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 300 | *.vbp 301 | 302 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 303 | *.dsw 304 | *.dsp 305 | 306 | # Visual Studio 6 technical files 307 | *.ncb 308 | *.aps 309 | 310 | # Visual Studio LightSwitch build output 311 | **/*.HTMLClient/GeneratedArtifacts 312 | **/*.DesktopClient/GeneratedArtifacts 313 | **/*.DesktopClient/ModelManifest.xml 314 | **/*.Server/GeneratedArtifacts 315 | **/*.Server/ModelManifest.xml 316 | _Pvt_Extensions 317 | 318 | # Paket dependency manager 319 | .paket/paket.exe 320 | paket-files/ 321 | 322 | # FAKE - F# Make 323 | .fake/ 324 | 325 | # CodeRush personal settings 326 | .cr/personal 327 | 328 | # Python Tools for Visual Studio (PTVS) 329 | __pycache__/ 330 | *.pyc 331 | 332 | # Cake - Uncomment if you are using it 333 | # tools/** 334 | # !tools/packages.config 335 | 336 | # Tabs Studio 337 | *.tss 338 | 339 | # Telerik's JustMock configuration file 340 | *.jmconfig 341 | 342 | # BizTalk build output 343 | *.btp.cs 344 | *.btm.cs 345 | *.odx.cs 346 | *.xsd.cs 347 | 348 | # OpenCover UI analysis results 349 | OpenCover/ 350 | 351 | # Azure Stream Analytics local run output 352 | ASALocalRun/ 353 | 354 | # MSBuild Binary and Structured Log 355 | *.binlog 356 | 357 | # NVidia Nsight GPU debugger configuration file 358 | *.nvuser 359 | 360 | # MFractors (Xamarin productivity tool) working folder 361 | .mfractor/ 362 | 363 | # Local History for Visual Studio 364 | .localhistory/ 365 | 366 | # Visual Studio History (VSHistory) files 367 | .vshistory/ 368 | 369 | # BeatPulse healthcheck temp database 370 | healthchecksdb 371 | 372 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 373 | MigrationBackup/ 374 | 375 | # Ionide (cross platform F# VS Code tools) working folder 376 | .ionide/ 377 | 378 | # Fody - auto-generated XML schema 379 | FodyWeavers.xsd 380 | 381 | # VS Code files for those working on multiple tools 382 | .vscode/* 383 | !.vscode/settings.json 384 | !.vscode/tasks.json 385 | !.vscode/launch.json 386 | !.vscode/extensions.json 387 | *.code-workspace 388 | 389 | # Local History for Visual Studio Code 390 | .history/ 391 | 392 | # Windows Installer files from build outputs 393 | *.cab 394 | *.msi 395 | *.msix 396 | *.msm 397 | *.msp 398 | 399 | # JetBrains Rider 400 | *.sln.iml 401 | -------------------------------------------------------------------------------- /DomainBlock.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Windows.Forms; 7 | 8 | namespace GfWLUtility 9 | { 10 | internal class DomainBlock 11 | { 12 | private static string hosts_file_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "drivers\\etc\\hosts"); 13 | 14 | public static bool IsDomainBlocked(string domain) 15 | { 16 | if (!File.Exists(hosts_file_path)) return false; 17 | 18 | // scan through each entry in the hosts file to see if the block exists 19 | string[] hosts_lines = File.ReadAllLines(hosts_file_path); 20 | foreach (string entry in hosts_lines) 21 | { 22 | // ignore any entry starting with a comment, or any blank lines 23 | if (entry.Length == 0 || entry[0] == '#') continue; 24 | // to check if it's blocked, we see if it's routed nowhere or locally 25 | // GfWL doesn't support IPv6 so we don't care for that either 26 | if (entry.StartsWith("0.0.0.0") || entry.StartsWith("127.0.0.1")) 27 | { 28 | // would split but splitting is hard so we just see if the line contains the domain 29 | if (entry.Contains(domain)) return true; 30 | } 31 | } 32 | 33 | return false; 34 | } 35 | 36 | public static void BlockDomain(string domain) 37 | { 38 | if (!Program.Elevated) 39 | throw new Exception("Blocking domains requires admin."); 40 | 41 | // scan through each entry in the hosts file to see if the block exists 42 | string[] hosts_lines = File.ReadAllLines(hosts_file_path); 43 | List hosts_lines_list = hosts_lines.ToList(); 44 | foreach (string entry in hosts_lines) 45 | { 46 | // ignore any entry starting with a comment, or any blank lines 47 | if (entry.Length == 0 || entry[0] == '#') continue; 48 | // to check if it's blocked, we see if it's routed nowhere or locally 49 | // GfWL doesn't support IPv6 so we don't care for that either 50 | if (entry.StartsWith("0.0.0.0") || entry.StartsWith("127.0.0.1")) 51 | { 52 | // would split but splitting is hard so we just see if the line contains the domain 53 | if (entry.Contains(domain)) return; 54 | } 55 | } 56 | 57 | // if we got here the domain isn't blocked already so add it 58 | hosts_lines_list.Add($"0.0.0.0 {domain}"); 59 | File.WriteAllLines(hosts_file_path, hosts_lines_list.ToArray()); 60 | } 61 | 62 | public static void UnblockDomain(string domain) 63 | { 64 | if (!Program.Elevated) 65 | throw new Exception("Unblocking domains requires admin."); 66 | 67 | // scan through each entry in the hosts file to see if the block exists 68 | string[] hosts_lines = File.ReadAllLines(hosts_file_path); 69 | List hosts_lines_list = hosts_lines.ToList(); 70 | foreach (string entry in hosts_lines) 71 | { 72 | // ignore any entry starting with a comment, or any blank lines 73 | if (entry.Length == 0 || entry[0] == '#') continue; 74 | // to check if it's blocked, we see if it's routed nowhere or locally 75 | // GfWL doesn't support IPv6 so we don't care for that either 76 | if (entry.StartsWith("0.0.0.0") || entry.StartsWith("127.0.0.1")) 77 | { 78 | // would split but splitting is hard so we just see if the line contains the domain 79 | // and then we remove the line from the hosts file 80 | if (entry.Contains(domain)) 81 | hosts_lines_list.Remove(entry); 82 | } 83 | } 84 | // write the newly modified hosts file back to the hosts file 85 | File.WriteAllLines(hosts_file_path, hosts_lines_list.ToArray()); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /DownloadForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace GfWLUtility 2 | { 3 | partial class DownloadForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 32 | this.statusLabel = new System.Windows.Forms.Label(); 33 | this.currentDownloadURL = new System.Windows.Forms.Label(); 34 | this.cancelButton = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // progressBar1 38 | // 39 | this.progressBar1.Location = new System.Drawing.Point(12, 12); 40 | this.progressBar1.MarqueeAnimationSpeed = 30; 41 | this.progressBar1.Name = "progressBar1"; 42 | this.progressBar1.Size = new System.Drawing.Size(460, 23); 43 | this.progressBar1.TabIndex = 0; 44 | // 45 | // statusLabel 46 | // 47 | this.statusLabel.AutoSize = true; 48 | this.statusLabel.Location = new System.Drawing.Point(12, 61); 49 | this.statusLabel.Name = "statusLabel"; 50 | this.statusLabel.Size = new System.Drawing.Size(107, 13); 51 | this.statusLabel.TabIndex = 1; 52 | this.statusLabel.Text = "Download progress..."; 53 | // 54 | // currentDownloadURL 55 | // 56 | this.currentDownloadURL.AutoSize = true; 57 | this.currentDownloadURL.Location = new System.Drawing.Point(12, 38); 58 | this.currentDownloadURL.Name = "currentDownloadURL"; 59 | this.currentDownloadURL.Size = new System.Drawing.Size(407, 13); 60 | this.currentDownloadURL.TabIndex = 2; 61 | this.currentDownloadURL.Text = "https://downloadserver.example/downloads/titleupdate/tu00010000_00020000.cab"; 62 | // 63 | // cancelButton 64 | // 65 | this.cancelButton.Location = new System.Drawing.Point(397, 56); 66 | this.cancelButton.Name = "cancelButton"; 67 | this.cancelButton.Size = new System.Drawing.Size(75, 23); 68 | this.cancelButton.TabIndex = 3; 69 | this.cancelButton.Text = "Cancel"; 70 | this.cancelButton.UseVisualStyleBackColor = true; 71 | this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); 72 | // 73 | // DownloadForm 74 | // 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.ClientSize = new System.Drawing.Size(484, 88); 78 | this.Controls.Add(this.cancelButton); 79 | this.Controls.Add(this.currentDownloadURL); 80 | this.Controls.Add(this.statusLabel); 81 | this.Controls.Add(this.progressBar1); 82 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 83 | this.MaximizeBox = false; 84 | this.MinimizeBox = false; 85 | this.Name = "DownloadForm"; 86 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 87 | this.Text = "Downloading..."; 88 | this.ResumeLayout(false); 89 | this.PerformLayout(); 90 | 91 | } 92 | 93 | #endregion 94 | 95 | private System.Windows.Forms.ProgressBar progressBar1; 96 | private System.Windows.Forms.Label statusLabel; 97 | private System.Windows.Forms.Label currentDownloadURL; 98 | private System.Windows.Forms.Button cancelButton; 99 | } 100 | } -------------------------------------------------------------------------------- /DownloadForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Reflection.Emit; 10 | using System.Text; 11 | using System.Threading; 12 | using System.Windows.Forms; 13 | 14 | namespace GfWLUtility 15 | { 16 | internal enum DownloadFormResult 17 | { 18 | DownloadCancelled, 19 | DownloadSuccess, 20 | DownloadFailure 21 | } 22 | 23 | public partial class DownloadForm : Form 24 | { 25 | private DownloadFormResult result = DownloadFormResult.DownloadCancelled; 26 | private FileInformation fileInformation; 27 | private string downloadOutput; 28 | private string downloadUrl; 29 | private int downloadAttempt; 30 | 31 | public DownloadForm() 32 | { 33 | InitializeComponent(); 34 | } 35 | 36 | // https://stackoverflow.com/a/9459441 37 | private void StartDownload() 38 | { 39 | Thread thread = new Thread(() => { 40 | WebClient client = new WebClient(); 41 | client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged); 42 | client.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted); 43 | client.DownloadFileAsync(new Uri(downloadUrl), downloadOutput); 44 | }); 45 | thread.Start(); 46 | progressBar1.Style = ProgressBarStyle.Blocks; 47 | } 48 | void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) 49 | { 50 | this.BeginInvoke((MethodInvoker)delegate { 51 | double bytesIn = double.Parse(e.BytesReceived.ToString()); 52 | double totalBytes = double.Parse(e.TotalBytesToReceive.ToString()); 53 | double percentage = bytesIn / totalBytes * 100; 54 | statusLabel.Text = "Downloaded " + UtilityFuncs.BytesToString(e.BytesReceived) + " of " + UtilityFuncs.BytesToString(e.TotalBytesToReceive); 55 | progressBar1.Value = int.Parse(Math.Truncate(percentage).ToString()); 56 | }); 57 | } 58 | void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 59 | { 60 | this.BeginInvoke((MethodInvoker)delegate { 61 | result = DownloadFormResult.DownloadSuccess; 62 | Close(); 63 | }); 64 | } 65 | 66 | internal DownloadFormResult StartFileDownload(FileInformation fi, IWin32Window owner) 67 | { 68 | if (!Directory.Exists(System.IO.Path.GetTempPath() + "\\GfWLUtility")) 69 | Directory.CreateDirectory(System.IO.Path.GetTempPath() + "\\GfWLUtility"); 70 | downloadOutput = System.IO.Path.GetTempPath() + "\\GfWLUtility\\" + fi.Filename; 71 | if (File.Exists(downloadOutput)) 72 | File.Delete(downloadOutput); 73 | 74 | fileInformation = fi; 75 | // TODO: If a download fails on one URL, try another 76 | downloadUrl = fi.DownloadURLs.FirstOrDefault(); 77 | currentDownloadURL.Text = downloadUrl; 78 | statusLabel.Text = "Preparing download..."; 79 | progressBar1.Style = ProgressBarStyle.Marquee; 80 | StartDownload(); 81 | ShowDialog(owner); 82 | return result; 83 | } 84 | 85 | internal string GetOutputFilePath() 86 | { 87 | return downloadOutput; 88 | } 89 | 90 | private void cancelButton_Click(object sender, EventArgs e) 91 | { 92 | Close(); 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /DownloadForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ElevatedButton.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.InteropServices; 5 | using System.Security.Principal; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | 9 | namespace GfWLUtility 10 | { 11 | /// 12 | /// Is a button with the UAC shield 13 | /// https://stackoverflow.com/a/16226657 14 | /// Modified to remove shield when disabled 15 | /// 16 | public class ElevatedButton : Button 17 | { 18 | /// 19 | /// The constructor to create the button with a UAC shield if necessary. 20 | /// 21 | public ElevatedButton() 22 | { 23 | FlatStyle = FlatStyle.System; 24 | EnabledChanged += ElevatedOnEnabledChanged; 25 | if (!Program.Elevated && Enabled) ShowShield(); 26 | } 27 | 28 | 29 | [DllImport("user32.dll")] 30 | private static extern IntPtr 31 | SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 32 | 33 | private uint BCM_SETSHIELD = 0x0000160C; 34 | 35 | private void ElevatedOnEnabledChanged(object sender, EventArgs e) 36 | { 37 | if (!Enabled || Program.Elevated) 38 | HideShield(); 39 | else 40 | ShowShield(); 41 | } 42 | 43 | private void ShowShield() 44 | { 45 | IntPtr wParam = new IntPtr(0); 46 | IntPtr lParam = new IntPtr(1); 47 | SendMessage(new HandleRef(this, Handle), BCM_SETSHIELD, wParam, lParam); 48 | } 49 | 50 | private void HideShield() 51 | { 52 | IntPtr wParam = new IntPtr(0); 53 | IntPtr lParam = new IntPtr(0); 54 | SendMessage(new HandleRef(this, Handle), BCM_SETSHIELD, wParam, lParam); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /ExportForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace GfWLUtility 2 | { 3 | partial class ExportForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 32 | this.label4 = new System.Windows.Forms.Label(); 33 | this.label3 = new System.Windows.Forms.Label(); 34 | this.label2 = new System.Windows.Forms.Label(); 35 | this.userProfileCheckbox = new System.Windows.Forms.CheckBox(); 36 | this.pcInfoCheckbox = new System.Windows.Forms.CheckBox(); 37 | this.productKeyCheckbox = new System.Windows.Forms.CheckBox(); 38 | this.exportButton = new System.Windows.Forms.Button(); 39 | this.cancelButton = new System.Windows.Forms.Button(); 40 | this.statusLabel = new System.Windows.Forms.Label(); 41 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 42 | this.exportSaveFileDialog = new System.Windows.Forms.SaveFileDialog(); 43 | this.groupBox1.SuspendLayout(); 44 | this.SuspendLayout(); 45 | // 46 | // groupBox1 47 | // 48 | this.groupBox1.Controls.Add(this.label4); 49 | this.groupBox1.Controls.Add(this.label3); 50 | this.groupBox1.Controls.Add(this.label2); 51 | this.groupBox1.Controls.Add(this.userProfileCheckbox); 52 | this.groupBox1.Controls.Add(this.pcInfoCheckbox); 53 | this.groupBox1.Controls.Add(this.productKeyCheckbox); 54 | this.groupBox1.Location = new System.Drawing.Point(12, 12); 55 | this.groupBox1.Name = "groupBox1"; 56 | this.groupBox1.Size = new System.Drawing.Size(357, 145); 57 | this.groupBox1.TabIndex = 0; 58 | this.groupBox1.TabStop = false; 59 | this.groupBox1.Text = "Export Options"; 60 | // 61 | // label4 62 | // 63 | this.label4.AutoSize = true; 64 | this.label4.Location = new System.Drawing.Point(25, 109); 65 | this.label4.Name = "label4"; 66 | this.label4.Size = new System.Drawing.Size(323, 26); 67 | this.label4.TabIndex = 5; 68 | this.label4.Text = "Downloaded and offline user profiles, along with any saved content\r\nsuch as DLC f" + 69 | "or games that used LIVE."; 70 | // 71 | // label3 72 | // 73 | this.label3.AutoSize = true; 74 | this.label3.Location = new System.Drawing.Point(25, 72); 75 | this.label3.Name = "label3"; 76 | this.label3.Size = new System.Drawing.Size(216, 13); 77 | this.label3.TabIndex = 4; 78 | this.label3.Text = "Saved product keys for each of your games."; 79 | // 80 | // label2 81 | // 82 | this.label2.AutoSize = true; 83 | this.label2.Location = new System.Drawing.Point(26, 36); 84 | this.label2.Name = "label2"; 85 | this.label2.Size = new System.Drawing.Size(283, 13); 86 | this.label2.TabIndex = 3; 87 | this.label2.Text = "Your PC ID and machine accounts used to log into games."; 88 | // 89 | // userProfileCheckbox 90 | // 91 | this.userProfileCheckbox.AutoSize = true; 92 | this.userProfileCheckbox.Checked = true; 93 | this.userProfileCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; 94 | this.userProfileCheckbox.Location = new System.Drawing.Point(9, 91); 95 | this.userProfileCheckbox.Name = "userProfileCheckbox"; 96 | this.userProfileCheckbox.Size = new System.Drawing.Size(146, 17); 97 | this.userProfileCheckbox.TabIndex = 2; 98 | this.userProfileCheckbox.Text = "User Profiles and Content"; 99 | this.userProfileCheckbox.UseVisualStyleBackColor = true; 100 | // 101 | // pcInfoCheckbox 102 | // 103 | this.pcInfoCheckbox.AutoSize = true; 104 | this.pcInfoCheckbox.Checked = true; 105 | this.pcInfoCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; 106 | this.pcInfoCheckbox.Location = new System.Drawing.Point(9, 19); 107 | this.pcInfoCheckbox.Name = "pcInfoCheckbox"; 108 | this.pcInfoCheckbox.Size = new System.Drawing.Size(95, 17); 109 | this.pcInfoCheckbox.TabIndex = 1; 110 | this.pcInfoCheckbox.Text = "PC Information"; 111 | this.pcInfoCheckbox.UseVisualStyleBackColor = true; 112 | // 113 | // productKeyCheckbox 114 | // 115 | this.productKeyCheckbox.AutoSize = true; 116 | this.productKeyCheckbox.Checked = true; 117 | this.productKeyCheckbox.CheckState = System.Windows.Forms.CheckState.Checked; 118 | this.productKeyCheckbox.Location = new System.Drawing.Point(9, 54); 119 | this.productKeyCheckbox.Name = "productKeyCheckbox"; 120 | this.productKeyCheckbox.Size = new System.Drawing.Size(89, 17); 121 | this.productKeyCheckbox.TabIndex = 0; 122 | this.productKeyCheckbox.Text = "Product Keys"; 123 | this.productKeyCheckbox.UseVisualStyleBackColor = true; 124 | // 125 | // exportButton 126 | // 127 | this.exportButton.Location = new System.Drawing.Point(294, 163); 128 | this.exportButton.Name = "exportButton"; 129 | this.exportButton.Size = new System.Drawing.Size(75, 23); 130 | this.exportButton.TabIndex = 2; 131 | this.exportButton.Text = "Export..."; 132 | this.exportButton.UseVisualStyleBackColor = true; 133 | this.exportButton.Click += new System.EventHandler(this.exportButton_Click); 134 | // 135 | // cancelButton 136 | // 137 | this.cancelButton.Location = new System.Drawing.Point(213, 163); 138 | this.cancelButton.Name = "cancelButton"; 139 | this.cancelButton.Size = new System.Drawing.Size(75, 23); 140 | this.cancelButton.TabIndex = 3; 141 | this.cancelButton.Text = "Cancel"; 142 | this.cancelButton.UseVisualStyleBackColor = true; 143 | this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click); 144 | // 145 | // statusLabel 146 | // 147 | this.statusLabel.AutoSize = true; 148 | this.statusLabel.Location = new System.Drawing.Point(12, 168); 149 | this.statusLabel.Name = "statusLabel"; 150 | this.statusLabel.Size = new System.Drawing.Size(213, 13); 151 | this.statusLabel.TabIndex = 4; 152 | this.statusLabel.Text = "Some pretty long status message bla bla bla"; 153 | this.statusLabel.Visible = false; 154 | // 155 | // progressBar1 156 | // 157 | this.progressBar1.Location = new System.Drawing.Point(269, 163); 158 | this.progressBar1.Name = "progressBar1"; 159 | this.progressBar1.Size = new System.Drawing.Size(100, 23); 160 | this.progressBar1.TabIndex = 5; 161 | this.progressBar1.Visible = false; 162 | // 163 | // exportSaveFileDialog 164 | // 165 | this.exportSaveFileDialog.Filter = "ZIP Archives|*.zip"; 166 | this.exportSaveFileDialog.Title = "Games for Windows - LIVE Data Export"; 167 | // 168 | // ExportForm 169 | // 170 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 171 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 172 | this.ClientSize = new System.Drawing.Size(381, 197); 173 | this.Controls.Add(this.statusLabel); 174 | this.Controls.Add(this.cancelButton); 175 | this.Controls.Add(this.exportButton); 176 | this.Controls.Add(this.groupBox1); 177 | this.Controls.Add(this.progressBar1); 178 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 179 | this.MaximizeBox = false; 180 | this.MinimizeBox = false; 181 | this.Name = "ExportForm"; 182 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 183 | this.Text = "Export Games for Windows - LIVE Data"; 184 | this.groupBox1.ResumeLayout(false); 185 | this.groupBox1.PerformLayout(); 186 | this.ResumeLayout(false); 187 | this.PerformLayout(); 188 | 189 | } 190 | 191 | #endregion 192 | 193 | private System.Windows.Forms.GroupBox groupBox1; 194 | private System.Windows.Forms.Label label4; 195 | private System.Windows.Forms.Label label3; 196 | private System.Windows.Forms.Label label2; 197 | private System.Windows.Forms.CheckBox userProfileCheckbox; 198 | private System.Windows.Forms.CheckBox pcInfoCheckbox; 199 | private System.Windows.Forms.CheckBox productKeyCheckbox; 200 | private System.Windows.Forms.Button exportButton; 201 | private System.Windows.Forms.Button cancelButton; 202 | private System.Windows.Forms.Label statusLabel; 203 | private System.Windows.Forms.ProgressBar progressBar1; 204 | private System.Windows.Forms.SaveFileDialog exportSaveFileDialog; 205 | } 206 | } -------------------------------------------------------------------------------- /ExportForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Windows.Forms; 11 | 12 | namespace GfWLUtility 13 | { 14 | public partial class ExportForm : Form 15 | { 16 | public ExportForm() 17 | { 18 | InitializeComponent(); 19 | } 20 | 21 | public void ExportPCInfo(string filename) 22 | { 23 | if (File.Exists(filename)) 24 | File.Delete(filename); 25 | FileStream fs = new FileStream(filename, FileMode.Create); 26 | 27 | SavedPCInfo savedPCInfo = new SavedPCInfo(); 28 | savedPCInfo.PCID = GfWLRegistry.GetPCID(); 29 | // shit way to enumerate through every title to put it in the XML 30 | savedPCInfo.Titles = new SavedPCInfoTitle[TitleManager.KnownTitles.Count]; 31 | int i_title = 0; 32 | foreach (KnownTitle title in TitleManager.KnownTitles.Values) 33 | { 34 | savedPCInfo.Titles[i_title] = new SavedPCInfoTitle(); 35 | savedPCInfo.Titles[i_title].ID = title.TitleID.ToString("X8"); 36 | 37 | if (productKeyCheckbox.Checked) 38 | { 39 | string productKey = TitleManager.GetTitleProductKey(title.TitleID); 40 | if (productKey != null) 41 | savedPCInfo.Titles[i_title].Key = productKey; 42 | } 43 | 44 | // i really don't like this 45 | List sectors = new List(); 46 | for (int i = 0; i < 0x14; i++) 47 | { 48 | byte[] sectorData = TitleManager.GetConfigSector(title.TitleID, i); 49 | if (sectorData != null) 50 | { 51 | // because it's big and unweildy and these are *mostly* null bytes, trim ending nulls 52 | // this makes the mostly unused config sector basically invisible, and the account sector much smaller 53 | int sectorTrailingNulls = UtilityFuncs.CountTrailingNulls(sectorData); 54 | sectorData = sectorData.Take(sectorTrailingNulls + 1).ToArray(); 55 | SavedPCInfoTitleSector sec = new SavedPCInfoTitleSector() 56 | { 57 | ID = "0x" + i.ToString("X"), 58 | Value = Convert.ToBase64String(sectorData) 59 | }; 60 | sectors.Add(sec); 61 | } 62 | } 63 | savedPCInfo.Titles[i_title].Sector = sectors.ToArray(); 64 | i_title++; 65 | } 66 | savedPCInfo.Version = "1"; 67 | savedPCInfo.CreatedBy = "GfWLUtility-beta1"; 68 | savedPCInfo.CreatedAt = DateTime.Now.ToString(); 69 | System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(savedPCInfo.GetType()); 70 | x.Serialize(fs, savedPCInfo); 71 | 72 | fs.Close(); 73 | } 74 | 75 | public void ExportProductKeys(string filename) 76 | { 77 | if (File.Exists(filename)) 78 | File.Delete(filename); 79 | List productKeyStrings = new List(); 80 | productKeyStrings.Add("GfWL Utility Exported Product Keys:"); 81 | productKeyStrings.Add("-----------------------------------"); 82 | foreach (KnownTitle title in TitleManager.KnownTitles.Values) 83 | { 84 | string productKey = TitleManager.GetTitleProductKey(title.TitleID); 85 | if (productKey != null) 86 | productKeyStrings.Add($"{title} : {productKey}"); 87 | } 88 | productKeyStrings.Add("-----------------------------------"); 89 | productKeyStrings.Add($"Generated at {DateTime.Now}"); 90 | File.WriteAllLines(filename, productKeyStrings.ToArray()); 91 | } 92 | 93 | public void CopyContent(string directory) 94 | { 95 | if (Directory.Exists(directory + @"\Content")) 96 | Directory.Delete(directory + @"\Content", true); 97 | if (Directory.Exists(directory + @"\DLC")) 98 | Directory.Delete(directory + @"\DLC", true); 99 | 100 | string xliveDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\Xlive"); 101 | 102 | if (Directory.Exists(xliveDir + @"\Content")) 103 | { 104 | Directory.CreateDirectory(directory + @"\Content"); 105 | DirectoryInfo contentSourceInfo = new DirectoryInfo(xliveDir + @"\Content"); 106 | DirectoryInfo contentTargetInfo = new DirectoryInfo(directory + @"\Content"); 107 | UtilityFuncs.CopyFilesRecursively(contentSourceInfo, contentTargetInfo); 108 | } 109 | 110 | if (Directory.Exists(xliveDir + @"\DLC")) 111 | { 112 | Directory.CreateDirectory(directory + @"\DLC"); 113 | DirectoryInfo dlcSourceInfo = new DirectoryInfo(xliveDir + @"\DLC"); 114 | DirectoryInfo dlcTargetInfo = new DirectoryInfo(directory + @"\DLC"); 115 | UtilityFuncs.CopyFilesRecursively(dlcSourceInfo, dlcTargetInfo); 116 | } 117 | } 118 | 119 | private void exportButton_Click(object sender, EventArgs e) 120 | { 121 | UseWaitCursor = true; 122 | Application.DoEvents(); 123 | 124 | if (Directory.Exists("GfWL_Export")) 125 | Directory.Delete("GfWL_Export", true); 126 | 127 | Directory.CreateDirectory("GfWL_Export"); 128 | if (pcInfoCheckbox.Checked) 129 | ExportPCInfo("GfWL_Export\\SavedPCInfo.xml"); 130 | if (productKeyCheckbox.Checked) 131 | ExportProductKeys("GfWL_Export\\GfWL_ProductKeys.txt"); 132 | if (userProfileCheckbox.Checked) 133 | CopyContent("GfWL_Export"); 134 | 135 | UseWaitCursor = false; 136 | Application.DoEvents(); 137 | 138 | DialogResult dr = 139 | MessageBox.Show("Export created in 'GfWL_Export' folder. Open this folder now?", "GfWL Utility Export", 140 | MessageBoxButtons.YesNo, MessageBoxIcon.Information); 141 | 142 | if (dr == DialogResult.Yes) 143 | Process.Start("GfWL_Export"); 144 | 145 | Close(); 146 | } 147 | 148 | private void cancelButton_Click(object sender, EventArgs e) 149 | { 150 | Close(); 151 | } 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /ExportForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /ExportXMLClasses.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace GfWLUtility 7 | { 8 | 9 | // NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0. 10 | /// 11 | [System.SerializableAttribute()] 12 | [System.ComponentModel.DesignerCategoryAttribute("code")] 13 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 14 | [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] 15 | public partial class SavedPCInfo 16 | { 17 | 18 | private string pCIDField; 19 | 20 | private SavedPCInfoTitle[] titlesField; 21 | 22 | private string versionField; 23 | 24 | private string createdByField; 25 | 26 | private string createdAtField; 27 | 28 | /// 29 | public string PCID 30 | { 31 | get 32 | { 33 | return this.pCIDField; 34 | } 35 | set 36 | { 37 | this.pCIDField = value; 38 | } 39 | } 40 | 41 | /// 42 | [System.Xml.Serialization.XmlArrayItemAttribute("Title", IsNullable = false)] 43 | public SavedPCInfoTitle[] Titles 44 | { 45 | get 46 | { 47 | return this.titlesField; 48 | } 49 | set 50 | { 51 | this.titlesField = value; 52 | } 53 | } 54 | 55 | /// 56 | [System.Xml.Serialization.XmlAttributeAttribute()] 57 | public string Version 58 | { 59 | get 60 | { 61 | return this.versionField; 62 | } 63 | set 64 | { 65 | this.versionField = value; 66 | } 67 | } 68 | 69 | /// 70 | [System.Xml.Serialization.XmlAttributeAttribute()] 71 | public string CreatedBy 72 | { 73 | get 74 | { 75 | return this.createdByField; 76 | } 77 | set 78 | { 79 | this.createdByField = value; 80 | } 81 | } 82 | 83 | /// 84 | [System.Xml.Serialization.XmlAttributeAttribute()] 85 | public string CreatedAt 86 | { 87 | get 88 | { 89 | return this.createdAtField; 90 | } 91 | set 92 | { 93 | this.createdAtField = value; 94 | } 95 | } 96 | } 97 | 98 | /// 99 | [System.SerializableAttribute()] 100 | [System.ComponentModel.DesignerCategoryAttribute("code")] 101 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 102 | public partial class SavedPCInfoTitle 103 | { 104 | 105 | private string keyField; 106 | 107 | private SavedPCInfoTitleSector[] sectorField; 108 | 109 | private string idField; 110 | 111 | /// 112 | public string Key 113 | { 114 | get 115 | { 116 | return this.keyField; 117 | } 118 | set 119 | { 120 | this.keyField = value; 121 | } 122 | } 123 | 124 | /// 125 | [System.Xml.Serialization.XmlElementAttribute("Sector")] 126 | public SavedPCInfoTitleSector[] Sector 127 | { 128 | get 129 | { 130 | return this.sectorField; 131 | } 132 | set 133 | { 134 | this.sectorField = value; 135 | } 136 | } 137 | 138 | /// 139 | [System.Xml.Serialization.XmlAttributeAttribute()] 140 | public string ID 141 | { 142 | get 143 | { 144 | return this.idField; 145 | } 146 | set 147 | { 148 | this.idField = value; 149 | } 150 | } 151 | } 152 | 153 | /// 154 | [System.SerializableAttribute()] 155 | [System.ComponentModel.DesignerCategoryAttribute("code")] 156 | [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] 157 | public partial class SavedPCInfoTitleSector 158 | { 159 | 160 | private string idField; 161 | 162 | private string valueField; 163 | 164 | /// 165 | [System.Xml.Serialization.XmlAttributeAttribute()] 166 | public string ID 167 | { 168 | get 169 | { 170 | return this.idField; 171 | } 172 | set 173 | { 174 | this.idField = value; 175 | } 176 | } 177 | 178 | /// 179 | [System.Xml.Serialization.XmlTextAttribute()] 180 | public string Value 181 | { 182 | get 183 | { 184 | return this.valueField; 185 | } 186 | set 187 | { 188 | this.valueField = value; 189 | } 190 | } 191 | } 192 | 193 | 194 | } 195 | -------------------------------------------------------------------------------- /FileInformation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace GfWLUtility 7 | { 8 | internal struct FileInformation 9 | { 10 | public string Filename; 11 | public string[] AltFilenames; 12 | public string[] DownloadURLs; 13 | public int Size; 14 | public byte[] Hash; 15 | } 16 | 17 | internal class StaticFileInformation 18 | { 19 | // tu10177600_35005f00.cab - the latest GfWL title update, contains XLiveUpdate.msi and wllogin_32/wllogin_64 20 | public static FileInformation titleupdate_3_5_95_cab = new FileInformation() 21 | { 22 | Filename = "tu10177600_35005f00.cab", 23 | AltFilenames = null, 24 | DownloadURLs = new string[] 25 | { 26 | // Official Microsoft URL 27 | "http://download.xbox.com/content/585207d1/tu10177600_35005f00.cab", 28 | // Legacy Update provided URL 29 | "http://content.legacyupdate.net/download.xbox.com/content/585207d1/tu10177600_35005f00.cab", 30 | // Internet Archive archived URL 31 | "http://web.archive.org/web/20191010213301id_/http://download.xbox.com/content/585207d1/tu10177600_35005f00.cab" 32 | }, 33 | Size = 28021108, 34 | Hash = new byte[0x14] 35 | { 36 | 0x71, 0xc7, 0xc7, 0xa0, 0x42, 0x47, 0x8d, 0x51, 0xf2, 0x5c, 0x47, 0x65, 0xac, 0xe7, 0xd0, 0x80, 0x8a, 0x9e, 0xe8, 0x4c 37 | } 38 | }; 39 | 40 | // XLiveUpdate.msi - installs the XLive/GfWL redistributable used by applications 41 | public static FileInformation xliveupdate_3_5_95_msi = new FileInformation() 42 | { 43 | Filename = "XLiveUpdate.msi", 44 | AltFilenames = new string[] { "xliveredist.msi" }, 45 | DownloadURLs = null, // only found in tu10177600_35005f00 46 | Size = 21594112, 47 | Hash = new byte[0x14] 48 | { 49 | 0xad, 0x92, 0x4d, 0x74, 0x39, 0x47, 0x07, 0x3f, 0xe8, 0x27, 0x42, 0xe8, 0xf5, 0x29, 0xa3, 0x7e, 0xae, 0x07, 0x66, 0x2a 50 | } 51 | }; 52 | 53 | // xliveredist.msi - a slightly older version of the xlive redistributable, latest available standalone 54 | public static FileInformation xliveredist_3_5_92_msi = new FileInformation() 55 | { 56 | Filename = "xliveredist.msi", 57 | AltFilenames = null, 58 | DownloadURLs = new string[] 59 | { 60 | // Official Microsoft URL 61 | "http://download.gfwl.xboxlive.com/content/gfwl-public/redists/production/xliveredist.msi", 62 | // Legacy Update provided URL 63 | "http://content.legacyupdate.net/download.gfwl.xboxlive.com/content/gfwl-public/redists/production/xliveredist.msi", 64 | // Internet Archive archived URL 65 | "http://web.archive.org/web/20141203142251id_/http://download.gfwl.xboxlive.com/content/gfwl-public/redists/production/xliveredist.msi" 66 | }, 67 | Size = 21598208, 68 | Hash = new byte[0x14] 69 | { 70 | 0xfc, 0x04, 0xd5, 0xc4, 0x95, 0x6f, 0xbf, 0x21, 0x36, 0xbd, 0xd4, 0xf2, 0xab, 0x15, 0x4e, 0xfb, 0xf5, 0xf6, 0xec, 0xa9 71 | } 72 | }; 73 | 74 | // gfwlclient.msi - installs the Games for Windows Marketplace "dashboard" application 75 | public static FileInformation gfwlclient_msi = new FileInformation() 76 | { 77 | Filename = "gfwlclient.msi", 78 | AltFilenames = null, 79 | DownloadURLs = new string[] 80 | { 81 | // Official Microsoft URL 82 | "http://download.gfwl.xboxlive.com/content/gfwl-public/redists/production/gfwlclient.msi", 83 | // Legacy Update provided URL 84 | "http://content.legacyupdate.net/download.gfwl.xboxlive.com/content/gfwl-public/redists/production/gfwlclient.msi", 85 | // Internet Archive archived URL 86 | "http://web.archive.org/web/20141203142248id_/http://download.gfwl.xboxlive.com/content/gfwl-public/redists/production/gfwlclient.msi" 87 | }, 88 | Size = 3375104, 89 | Hash = new byte[0x14] 90 | { 91 | 0xdf, 0x6b, 0xe4, 0x41, 0xde, 0xed, 0x52, 0x54, 0x3c, 0xc1, 0xe8, 0xc7, 0x08, 0xa7, 0x2c, 0xa2, 0xca, 0x6b, 0xee, 0x92 92 | } 93 | }; 94 | 95 | // wllogin_32.msi - x86 Windows Live Identity Client Runtime Library 96 | // !! DANGER: ONLY HAS 1 MIRROR !! 97 | public static FileInformation wllogin_32_msi = new FileInformation() 98 | { 99 | Filename = "wllogin_32.msi", 100 | AltFilenames = null, 101 | DownloadURLs = new string[] 102 | { 103 | // Internet Archive archived URL 104 | "http://web.archive.org/web/20200801000000id_/download.microsoft.com/download/7/4/0/740357D6-EFA8-43C1-A7DF-A8EEDD104638/wllogin_32.msi" 105 | }, 106 | Size = 4649472, 107 | Hash = new byte[0x14] 108 | { 109 | 0xf4, 0x77, 0xf8, 0xab, 0xc4, 0x51, 0x95, 0x32, 0xef, 0x29, 0x21, 0xb1, 0x34, 0x3a, 0x06, 0xf2, 0xac, 0x54, 0x6c, 0x2c 110 | } 111 | }; 112 | 113 | // wllogin_64.msi - x64 Windows Live Identity Client Runtime Library. not used by GfWL but completeness 114 | // !! DANGER: ONLY HAS 1 MIRROR !! 115 | public static FileInformation wllogin_64_msi = new FileInformation() 116 | { 117 | Filename = "wllogin_64.msi", 118 | AltFilenames = null, 119 | DownloadURLs = new string[] 120 | { 121 | // Internet Archive archived URL 122 | "http://web.archive.org/web/20200801000000id_/download.microsoft.com/download/7/4/0/740357D6-EFA8-43C1-A7DF-A8EEDD104638/wllogin_64.msi" 123 | }, 124 | Size = 6575616, 125 | Hash = new byte[0x14] 126 | { 127 | 0x10, 0x78, 0xd3, 0x2c, 0xae, 0x64, 0xab, 0x1c, 0x5b, 0xce, 0x52, 0x63, 0x7e, 0xfa, 0xcb, 0xde, 0x70, 0xfa, 0x26, 0x70 128 | } 129 | }; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /GfWLRegistry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Microsoft.Win32; 6 | 7 | namespace GfWLUtility 8 | { 9 | internal class GfWLRegistry 10 | { 11 | private static string xlive_registry_key = "software\\classes\\software\\microsoft\\xlive"; 12 | 13 | // Returns the current PCID in hex string format, or N/A if not found. 14 | public static string GetPCID() 15 | { 16 | RegistryKey gfwlKey = Registry.CurrentUser.OpenSubKey(xlive_registry_key); 17 | if (gfwlKey == null) return "N/A"; 18 | object pcidValue = gfwlKey.GetValue("PCID"); 19 | if (pcidValue != null && gfwlKey.GetValueKind("PCID") == RegistryValueKind.QWord) 20 | { 21 | byte[] pcidBytes = BitConverter.GetBytes((long)pcidValue); 22 | return BitConverter.ToString(pcidBytes).Replace("-", ""); 23 | } else return "N/A"; 24 | } 25 | 26 | // Returns the last used GfWL version from the registry, or N/A if not found. 27 | public static string GetVersion() 28 | { 29 | 30 | RegistryKey gfwlKey = Registry.CurrentUser.OpenSubKey(xlive_registry_key); 31 | if (gfwlKey == null) return "N/A"; 32 | object verValue = gfwlKey.GetValue("Version"); 33 | if (verValue != null && gfwlKey.GetValueKind("Version") == RegistryValueKind.DWord) 34 | { 35 | int verInt = (int)verValue; 36 | int major = (int)(verInt >> 28 & 0xF); 37 | int minor = (int)(verInt >> 24 & 0xF); 38 | int build = (int)(verInt >> 8 & 0xFFFF); 39 | int qfe = (int)(verInt & 0xFF); 40 | return $"{major}.{minor}.{build:D4}.{qfe}"; 41 | } 42 | else return "N/A"; 43 | } 44 | 45 | // Returns the path that the GfWL "dash"/marketplace client is installed to. 46 | public static string GetDashPath() 47 | { 48 | RegistryKey gfwlKey = Registry.LocalMachine.OpenSubKey(xlive_registry_key); 49 | if (gfwlKey == null) return null; 50 | object dashDirValue = gfwlKey.GetValue("DashDir"); 51 | if (dashDirValue != null && gfwlKey.GetValueKind("DashDir") == RegistryValueKind.String) 52 | return (string)dashDirValue; 53 | else 54 | return null; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /GfWLUtility.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88} 8 | WinExe 9 | GfWLUtility 10 | GfWLUtility 11 | v3.5 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | GfWLUtilityLogo.ico 36 | 37 | 38 | true 39 | bin\x86\Debug\ 40 | DEBUG;TRACE 41 | full 42 | x86 43 | 7.3 44 | prompt 45 | 46 | 47 | bin\x86\Release\ 48 | TRACE 49 | true 50 | pdbonly 51 | x86 52 | 7.3 53 | prompt 54 | 55 | 56 | app.manifest 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Form 74 | 75 | 76 | DownloadForm.cs 77 | 78 | 79 | Component 80 | 81 | 82 | Form 83 | 84 | 85 | ExportForm.cs 86 | 87 | 88 | 89 | 90 | 91 | Form 92 | 93 | 94 | MainWindow.cs 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | DownloadForm.cs 103 | 104 | 105 | ExportForm.cs 106 | 107 | 108 | MainWindow.cs 109 | 110 | 111 | ResXFileCodeGenerator 112 | Resources.Designer.cs 113 | Designer 114 | 115 | 116 | True 117 | Resources.resx 118 | True 119 | 120 | 121 | 122 | SettingsSingleFileGenerator 123 | Settings.Designer.cs 124 | 125 | 126 | True 127 | Settings.settings 128 | True 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /GfWLUtility.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.8.34316.72 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GfWLUtility", "GfWLUtility.csproj", "{3DD60089-1D00-4DC7-8A88-A31CA30FBD88}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x86 = Debug|x86 12 | Release|Any CPU = Release|Any CPU 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Debug|x86.ActiveCfg = Debug|x86 19 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Debug|x86.Build.0 = Debug|x86 20 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Release|x86.ActiveCfg = Release|x86 23 | {3DD60089-1D00-4DC7-8A88-A31CA30FBD88}.Release|x86.Build.0 = Release|x86 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {54545973-5FC8-46EC-94DC-AF2E61F9B9C4} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /GfWLUtilityLogo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/GfWLUtilityLogo.ico -------------------------------------------------------------------------------- /MainWindow.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace GfWLUtility 2 | { 3 | partial class MainWindow 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainWindow)); 32 | this.mainTabControl = new System.Windows.Forms.TabControl(); 33 | this.runtimeTab = new System.Windows.Forms.TabPage(); 34 | this.systemInfoGroup = new System.Windows.Forms.GroupBox(); 35 | this.showPCIDCheckbox = new System.Windows.Forms.CheckBox(); 36 | this.versionText = new System.Windows.Forms.TextBox(); 37 | this.versionLabel = new System.Windows.Forms.Label(); 38 | this.pcidText = new System.Windows.Forms.TextBox(); 39 | this.pcidLabel = new System.Windows.Forms.Label(); 40 | this.marketplaceGroup = new System.Windows.Forms.GroupBox(); 41 | this.manageMarketplaceButton = new System.Windows.Forms.Button(); 42 | this.marketplaceLogoPicture = new System.Windows.Forms.PictureBox(); 43 | this.marketplaceInstallLabel = new System.Windows.Forms.Label(); 44 | this.marketplaceVersionLabel = new System.Windows.Forms.Label(); 45 | this.wlidGroup = new System.Windows.Forms.GroupBox(); 46 | this.wlidLogoPicture = new System.Windows.Forms.PictureBox(); 47 | this.wlidInstallLabel = new System.Windows.Forms.Label(); 48 | this.wlidInfoLabel = new System.Windows.Forms.Label(); 49 | this.runtimeGroup = new System.Windows.Forms.GroupBox(); 50 | this.manageRuntimeButton = new System.Windows.Forms.Button(); 51 | this.gfwlLogoPicture = new System.Windows.Forms.PictureBox(); 52 | this.runtimeInstallLabel = new System.Windows.Forms.Label(); 53 | this.runtimeVersionLabel = new System.Windows.Forms.Label(); 54 | this.accountsTab = new System.Windows.Forms.TabPage(); 55 | this.onlineXuidLabel = new System.Windows.Forms.Label(); 56 | this.onlineXuidBox = new System.Windows.Forms.TextBox(); 57 | this.accountGamerpic = new System.Windows.Forms.PictureBox(); 58 | this.accountLiveCheck = new System.Windows.Forms.CheckBox(); 59 | this.accountXuidBox = new System.Windows.Forms.TextBox(); 60 | this.accountNameBox = new System.Windows.Forms.TextBox(); 61 | this.accountXuidLabel = new System.Windows.Forms.Label(); 62 | this.accountNameLabel = new System.Windows.Forms.Label(); 63 | this.accountsListBox = new System.Windows.Forms.ListBox(); 64 | this.gamesTab = new System.Windows.Forms.TabPage(); 65 | this.titleIDFormattedLabel = new System.Windows.Forms.Label(); 66 | this.titleIconPicture = new System.Windows.Forms.PictureBox(); 67 | this.titleClearConfigLink = new System.Windows.Forms.LinkLabel(); 68 | this.titleShowKeyCheck = new System.Windows.Forms.CheckBox(); 69 | this.titleKeyLabel = new System.Windows.Forms.Label(); 70 | this.titleProductKeyBox = new System.Windows.Forms.TextBox(); 71 | this.titleIDBox = new System.Windows.Forms.TextBox(); 72 | this.titleNameBox = new System.Windows.Forms.TextBox(); 73 | this.titleIDLabel = new System.Windows.Forms.Label(); 74 | this.titleNameLabel = new System.Windows.Forms.Label(); 75 | this.gameListBox = new System.Windows.Forms.ListBox(); 76 | this.utilitiesTab = new System.Windows.Forms.TabPage(); 77 | this.connBlockGroup = new System.Windows.Forms.GroupBox(); 78 | this.blockLiveInfoLabel = new System.Windows.Forms.Label(); 79 | this.blockServicesInfoLabel = new System.Windows.Forms.Label(); 80 | this.dataExportGroup = new System.Windows.Forms.GroupBox(); 81 | this.dataExportInfoLabel = new System.Windows.Forms.Label(); 82 | this.dataImportButton = new System.Windows.Forms.Button(); 83 | this.dataExportButton = new System.Windows.Forms.Button(); 84 | this.label1 = new System.Windows.Forms.Label(); 85 | this.githubLinkLabel = new System.Windows.Forms.LinkLabel(); 86 | this.appVersionLabel = new System.Windows.Forms.Label(); 87 | this.installMarketplaceButton = new GfWLUtility.ElevatedButton(); 88 | this.installWLIDButton = new GfWLUtility.ElevatedButton(); 89 | this.installRuntimeButton = new GfWLUtility.ElevatedButton(); 90 | this.blockServicesButton = new GfWLUtility.ElevatedButton(); 91 | this.blockLiveButton = new GfWLUtility.ElevatedButton(); 92 | this.mainTabControl.SuspendLayout(); 93 | this.runtimeTab.SuspendLayout(); 94 | this.systemInfoGroup.SuspendLayout(); 95 | this.marketplaceGroup.SuspendLayout(); 96 | ((System.ComponentModel.ISupportInitialize)(this.marketplaceLogoPicture)).BeginInit(); 97 | this.wlidGroup.SuspendLayout(); 98 | ((System.ComponentModel.ISupportInitialize)(this.wlidLogoPicture)).BeginInit(); 99 | this.runtimeGroup.SuspendLayout(); 100 | ((System.ComponentModel.ISupportInitialize)(this.gfwlLogoPicture)).BeginInit(); 101 | this.accountsTab.SuspendLayout(); 102 | ((System.ComponentModel.ISupportInitialize)(this.accountGamerpic)).BeginInit(); 103 | this.gamesTab.SuspendLayout(); 104 | ((System.ComponentModel.ISupportInitialize)(this.titleIconPicture)).BeginInit(); 105 | this.utilitiesTab.SuspendLayout(); 106 | this.connBlockGroup.SuspendLayout(); 107 | this.dataExportGroup.SuspendLayout(); 108 | this.SuspendLayout(); 109 | // 110 | // mainTabControl 111 | // 112 | this.mainTabControl.Controls.Add(this.runtimeTab); 113 | this.mainTabControl.Controls.Add(this.accountsTab); 114 | this.mainTabControl.Controls.Add(this.gamesTab); 115 | this.mainTabControl.Controls.Add(this.utilitiesTab); 116 | this.mainTabControl.Location = new System.Drawing.Point(12, 12); 117 | this.mainTabControl.Name = "mainTabControl"; 118 | this.mainTabControl.SelectedIndex = 0; 119 | this.mainTabControl.Size = new System.Drawing.Size(454, 250); 120 | this.mainTabControl.TabIndex = 0; 121 | // 122 | // runtimeTab 123 | // 124 | this.runtimeTab.Controls.Add(this.systemInfoGroup); 125 | this.runtimeTab.Controls.Add(this.marketplaceGroup); 126 | this.runtimeTab.Controls.Add(this.wlidGroup); 127 | this.runtimeTab.Controls.Add(this.runtimeGroup); 128 | this.runtimeTab.Location = new System.Drawing.Point(4, 22); 129 | this.runtimeTab.Name = "runtimeTab"; 130 | this.runtimeTab.Padding = new System.Windows.Forms.Padding(3); 131 | this.runtimeTab.Size = new System.Drawing.Size(446, 224); 132 | this.runtimeTab.TabIndex = 0; 133 | this.runtimeTab.Text = "Runtime"; 134 | this.runtimeTab.UseVisualStyleBackColor = true; 135 | // 136 | // systemInfoGroup 137 | // 138 | this.systemInfoGroup.Controls.Add(this.showPCIDCheckbox); 139 | this.systemInfoGroup.Controls.Add(this.versionText); 140 | this.systemInfoGroup.Controls.Add(this.versionLabel); 141 | this.systemInfoGroup.Controls.Add(this.pcidText); 142 | this.systemInfoGroup.Controls.Add(this.pcidLabel); 143 | this.systemInfoGroup.Location = new System.Drawing.Point(251, 115); 144 | this.systemInfoGroup.Name = "systemInfoGroup"; 145 | this.systemInfoGroup.Size = new System.Drawing.Size(189, 103); 146 | this.systemInfoGroup.TabIndex = 13; 147 | this.systemInfoGroup.TabStop = false; 148 | this.systemInfoGroup.Text = "System Info"; 149 | // 150 | // showPCIDCheckbox 151 | // 152 | this.showPCIDCheckbox.AutoSize = true; 153 | this.showPCIDCheckbox.Location = new System.Drawing.Point(9, 55); 154 | this.showPCIDCheckbox.Name = "showPCIDCheckbox"; 155 | this.showPCIDCheckbox.Size = new System.Drawing.Size(97, 17); 156 | this.showPCIDCheckbox.TabIndex = 6; 157 | this.showPCIDCheckbox.Text = "Show full PCID"; 158 | this.showPCIDCheckbox.UseVisualStyleBackColor = true; 159 | this.showPCIDCheckbox.CheckedChanged += new System.EventHandler(this.showPCIDCheckbox_CheckedChanged); 160 | // 161 | // versionText 162 | // 163 | this.versionText.BorderStyle = System.Windows.Forms.BorderStyle.None; 164 | this.versionText.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 165 | this.versionText.Location = new System.Drawing.Point(57, 36); 166 | this.versionText.Name = "versionText"; 167 | this.versionText.ReadOnly = true; 168 | this.versionText.Size = new System.Drawing.Size(126, 13); 169 | this.versionText.TabIndex = 5; 170 | this.versionText.Text = "2.0.0000.0"; 171 | // 172 | // versionLabel 173 | // 174 | this.versionLabel.AutoSize = true; 175 | this.versionLabel.Location = new System.Drawing.Point(6, 35); 176 | this.versionLabel.Name = "versionLabel"; 177 | this.versionLabel.Size = new System.Drawing.Size(45, 13); 178 | this.versionLabel.TabIndex = 4; 179 | this.versionLabel.Text = "Version:"; 180 | // 181 | // pcidText 182 | // 183 | this.pcidText.BorderStyle = System.Windows.Forms.BorderStyle.None; 184 | this.pcidText.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 185 | this.pcidText.Location = new System.Drawing.Point(57, 19); 186 | this.pcidText.Name = "pcidText"; 187 | this.pcidText.ReadOnly = true; 188 | this.pcidText.Size = new System.Drawing.Size(126, 13); 189 | this.pcidText.TabIndex = 3; 190 | this.pcidText.Text = "AABBCCDD00112233"; 191 | // 192 | // pcidLabel 193 | // 194 | this.pcidLabel.AutoSize = true; 195 | this.pcidLabel.Location = new System.Drawing.Point(6, 19); 196 | this.pcidLabel.Name = "pcidLabel"; 197 | this.pcidLabel.Size = new System.Drawing.Size(35, 13); 198 | this.pcidLabel.TabIndex = 2; 199 | this.pcidLabel.Text = "PCID:"; 200 | // 201 | // marketplaceGroup 202 | // 203 | this.marketplaceGroup.Controls.Add(this.manageMarketplaceButton); 204 | this.marketplaceGroup.Controls.Add(this.marketplaceLogoPicture); 205 | this.marketplaceGroup.Controls.Add(this.marketplaceInstallLabel); 206 | this.marketplaceGroup.Controls.Add(this.installMarketplaceButton); 207 | this.marketplaceGroup.Controls.Add(this.marketplaceVersionLabel); 208 | this.marketplaceGroup.Location = new System.Drawing.Point(6, 115); 209 | this.marketplaceGroup.Name = "marketplaceGroup"; 210 | this.marketplaceGroup.Size = new System.Drawing.Size(239, 103); 211 | this.marketplaceGroup.TabIndex = 12; 212 | this.marketplaceGroup.TabStop = false; 213 | this.marketplaceGroup.Text = "Games for Windows Marketplace"; 214 | // 215 | // manageMarketplaceButton 216 | // 217 | this.manageMarketplaceButton.Location = new System.Drawing.Point(169, 73); 218 | this.manageMarketplaceButton.Name = "manageMarketplaceButton"; 219 | this.manageMarketplaceButton.Size = new System.Drawing.Size(64, 23); 220 | this.manageMarketplaceButton.TabIndex = 11; 221 | this.manageMarketplaceButton.Text = "Manage..."; 222 | this.manageMarketplaceButton.UseVisualStyleBackColor = true; 223 | this.manageMarketplaceButton.Visible = false; 224 | // 225 | // marketplaceLogoPicture 226 | // 227 | this.marketplaceLogoPicture.Image = global::GfWLUtility.Properties.Resources.GfWLUnknown; 228 | this.marketplaceLogoPicture.Location = new System.Drawing.Point(6, 19); 229 | this.marketplaceLogoPicture.Name = "marketplaceLogoPicture"; 230 | this.marketplaceLogoPicture.Size = new System.Drawing.Size(48, 48); 231 | this.marketplaceLogoPicture.TabIndex = 3; 232 | this.marketplaceLogoPicture.TabStop = false; 233 | // 234 | // marketplaceInstallLabel 235 | // 236 | this.marketplaceInstallLabel.AutoSize = true; 237 | this.marketplaceInstallLabel.Location = new System.Drawing.Point(60, 19); 238 | this.marketplaceInstallLabel.Name = "marketplaceInstallLabel"; 239 | this.marketplaceInstallLabel.Size = new System.Drawing.Size(165, 13); 240 | this.marketplaceInstallLabel.TabIndex = 0; 241 | this.marketplaceInstallLabel.Text = "Marketplace installed placeholder"; 242 | // 243 | // marketplaceVersionLabel 244 | // 245 | this.marketplaceVersionLabel.AutoSize = true; 246 | this.marketplaceVersionLabel.Location = new System.Drawing.Point(60, 37); 247 | this.marketplaceVersionLabel.Name = "marketplaceVersionLabel"; 248 | this.marketplaceVersionLabel.Size = new System.Drawing.Size(161, 13); 249 | this.marketplaceVersionLabel.TabIndex = 1; 250 | this.marketplaceVersionLabel.Text = "Marketplace version placeholder"; 251 | // 252 | // wlidGroup 253 | // 254 | this.wlidGroup.Controls.Add(this.wlidLogoPicture); 255 | this.wlidGroup.Controls.Add(this.wlidInstallLabel); 256 | this.wlidGroup.Controls.Add(this.installWLIDButton); 257 | this.wlidGroup.Controls.Add(this.wlidInfoLabel); 258 | this.wlidGroup.Location = new System.Drawing.Point(251, 6); 259 | this.wlidGroup.Name = "wlidGroup"; 260 | this.wlidGroup.Size = new System.Drawing.Size(189, 103); 261 | this.wlidGroup.TabIndex = 11; 262 | this.wlidGroup.TabStop = false; 263 | this.wlidGroup.Text = "Windows Live ID assistant"; 264 | // 265 | // wlidLogoPicture 266 | // 267 | this.wlidLogoPicture.Image = global::GfWLUtility.Properties.Resources.WLIDUnknown; 268 | this.wlidLogoPicture.Location = new System.Drawing.Point(6, 19); 269 | this.wlidLogoPicture.Name = "wlidLogoPicture"; 270 | this.wlidLogoPicture.Size = new System.Drawing.Size(48, 48); 271 | this.wlidLogoPicture.TabIndex = 6; 272 | this.wlidLogoPicture.TabStop = false; 273 | // 274 | // wlidInstallLabel 275 | // 276 | this.wlidInstallLabel.AutoSize = true; 277 | this.wlidInstallLabel.Location = new System.Drawing.Point(60, 19); 278 | this.wlidInstallLabel.Name = "wlidInstallLabel"; 279 | this.wlidInstallLabel.Size = new System.Drawing.Size(134, 13); 280 | this.wlidInstallLabel.TabIndex = 5; 281 | this.wlidInstallLabel.Text = "WLID installed placeholder"; 282 | // 283 | // wlidInfoLabel 284 | // 285 | this.wlidInfoLabel.AutoSize = true; 286 | this.wlidInfoLabel.Location = new System.Drawing.Point(60, 37); 287 | this.wlidInfoLabel.Name = "wlidInfoLabel"; 288 | this.wlidInfoLabel.Size = new System.Drawing.Size(113, 13); 289 | this.wlidInfoLabel.TabIndex = 7; 290 | this.wlidInfoLabel.Text = "WLID info placeholder"; 291 | // 292 | // runtimeGroup 293 | // 294 | this.runtimeGroup.Controls.Add(this.manageRuntimeButton); 295 | this.runtimeGroup.Controls.Add(this.gfwlLogoPicture); 296 | this.runtimeGroup.Controls.Add(this.runtimeInstallLabel); 297 | this.runtimeGroup.Controls.Add(this.installRuntimeButton); 298 | this.runtimeGroup.Controls.Add(this.runtimeVersionLabel); 299 | this.runtimeGroup.Location = new System.Drawing.Point(6, 6); 300 | this.runtimeGroup.Name = "runtimeGroup"; 301 | this.runtimeGroup.Size = new System.Drawing.Size(239, 103); 302 | this.runtimeGroup.TabIndex = 10; 303 | this.runtimeGroup.TabStop = false; 304 | this.runtimeGroup.Text = "Games for Windows - LIVE Runtime"; 305 | // 306 | // manageRuntimeButton 307 | // 308 | this.manageRuntimeButton.Location = new System.Drawing.Point(169, 73); 309 | this.manageRuntimeButton.Name = "manageRuntimeButton"; 310 | this.manageRuntimeButton.Size = new System.Drawing.Size(64, 23); 311 | this.manageRuntimeButton.TabIndex = 11; 312 | this.manageRuntimeButton.Text = "Manage..."; 313 | this.manageRuntimeButton.UseVisualStyleBackColor = true; 314 | this.manageRuntimeButton.Visible = false; 315 | // 316 | // gfwlLogoPicture 317 | // 318 | this.gfwlLogoPicture.Image = global::GfWLUtility.Properties.Resources.GfWLUnknown; 319 | this.gfwlLogoPicture.Location = new System.Drawing.Point(6, 19); 320 | this.gfwlLogoPicture.Name = "gfwlLogoPicture"; 321 | this.gfwlLogoPicture.Size = new System.Drawing.Size(48, 48); 322 | this.gfwlLogoPicture.TabIndex = 3; 323 | this.gfwlLogoPicture.TabStop = false; 324 | // 325 | // runtimeInstallLabel 326 | // 327 | this.runtimeInstallLabel.AutoSize = true; 328 | this.runtimeInstallLabel.Location = new System.Drawing.Point(60, 19); 329 | this.runtimeInstallLabel.Name = "runtimeInstallLabel"; 330 | this.runtimeInstallLabel.Size = new System.Drawing.Size(145, 13); 331 | this.runtimeInstallLabel.TabIndex = 0; 332 | this.runtimeInstallLabel.Text = "Runtime installed placeholder"; 333 | // 334 | // runtimeVersionLabel 335 | // 336 | this.runtimeVersionLabel.AutoSize = true; 337 | this.runtimeVersionLabel.Location = new System.Drawing.Point(60, 37); 338 | this.runtimeVersionLabel.Name = "runtimeVersionLabel"; 339 | this.runtimeVersionLabel.Size = new System.Drawing.Size(141, 13); 340 | this.runtimeVersionLabel.TabIndex = 1; 341 | this.runtimeVersionLabel.Text = "Runtime version placeholder"; 342 | // 343 | // accountsTab 344 | // 345 | this.accountsTab.Controls.Add(this.onlineXuidLabel); 346 | this.accountsTab.Controls.Add(this.onlineXuidBox); 347 | this.accountsTab.Controls.Add(this.accountGamerpic); 348 | this.accountsTab.Controls.Add(this.accountLiveCheck); 349 | this.accountsTab.Controls.Add(this.accountXuidBox); 350 | this.accountsTab.Controls.Add(this.accountNameBox); 351 | this.accountsTab.Controls.Add(this.accountXuidLabel); 352 | this.accountsTab.Controls.Add(this.accountNameLabel); 353 | this.accountsTab.Controls.Add(this.accountsListBox); 354 | this.accountsTab.Location = new System.Drawing.Point(4, 22); 355 | this.accountsTab.Name = "accountsTab"; 356 | this.accountsTab.Padding = new System.Windows.Forms.Padding(3); 357 | this.accountsTab.Size = new System.Drawing.Size(446, 224); 358 | this.accountsTab.TabIndex = 1; 359 | this.accountsTab.Text = "Profiles"; 360 | this.accountsTab.UseVisualStyleBackColor = true; 361 | // 362 | // onlineXuidLabel 363 | // 364 | this.onlineXuidLabel.AutoSize = true; 365 | this.onlineXuidLabel.Location = new System.Drawing.Point(195, 84); 366 | this.onlineXuidLabel.Name = "onlineXuidLabel"; 367 | this.onlineXuidLabel.Size = new System.Drawing.Size(40, 13); 368 | this.onlineXuidLabel.TabIndex = 18; 369 | this.onlineXuidLabel.Text = "Online:"; 370 | this.onlineXuidLabel.Visible = false; 371 | // 372 | // onlineXuidBox 373 | // 374 | this.onlineXuidBox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 375 | this.onlineXuidBox.Location = new System.Drawing.Point(237, 81); 376 | this.onlineXuidBox.Name = "onlineXuidBox"; 377 | this.onlineXuidBox.ReadOnly = true; 378 | this.onlineXuidBox.Size = new System.Drawing.Size(129, 20); 379 | this.onlineXuidBox.TabIndex = 17; 380 | this.onlineXuidBox.Text = "DEADBEEFDEADBEEF"; 381 | this.onlineXuidBox.Visible = false; 382 | // 383 | // accountGamerpic 384 | // 385 | this.accountGamerpic.Location = new System.Drawing.Point(376, 58); 386 | this.accountGamerpic.Name = "accountGamerpic"; 387 | this.accountGamerpic.Size = new System.Drawing.Size(64, 64); 388 | this.accountGamerpic.TabIndex = 16; 389 | this.accountGamerpic.TabStop = false; 390 | // 391 | // accountLiveCheck 392 | // 393 | this.accountLiveCheck.AutoSize = true; 394 | this.accountLiveCheck.Enabled = false; 395 | this.accountLiveCheck.Location = new System.Drawing.Point(198, 58); 396 | this.accountLiveCheck.Name = "accountLiveCheck"; 397 | this.accountLiveCheck.Size = new System.Drawing.Size(108, 17); 398 | this.accountLiveCheck.TabIndex = 15; 399 | this.accountLiveCheck.Text = "Xbox LIVE Profile"; 400 | this.accountLiveCheck.UseVisualStyleBackColor = true; 401 | this.accountLiveCheck.Visible = false; 402 | // 403 | // accountXuidBox 404 | // 405 | this.accountXuidBox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 406 | this.accountXuidBox.Location = new System.Drawing.Point(237, 32); 407 | this.accountXuidBox.Name = "accountXuidBox"; 408 | this.accountXuidBox.ReadOnly = true; 409 | this.accountXuidBox.Size = new System.Drawing.Size(203, 20); 410 | this.accountXuidBox.TabIndex = 14; 411 | this.accountXuidBox.Text = "DEADBEEFDEADBEEF"; 412 | // 413 | // accountNameBox 414 | // 415 | this.accountNameBox.Location = new System.Drawing.Point(257, 6); 416 | this.accountNameBox.Name = "accountNameBox"; 417 | this.accountNameBox.ReadOnly = true; 418 | this.accountNameBox.Size = new System.Drawing.Size(183, 20); 419 | this.accountNameBox.TabIndex = 13; 420 | this.accountNameBox.Text = "WWWWWWWWWWWWWWW"; 421 | // 422 | // accountXuidLabel 423 | // 424 | this.accountXuidLabel.AutoSize = true; 425 | this.accountXuidLabel.Location = new System.Drawing.Point(195, 35); 426 | this.accountXuidLabel.Name = "accountXuidLabel"; 427 | this.accountXuidLabel.Size = new System.Drawing.Size(36, 13); 428 | this.accountXuidLabel.TabIndex = 12; 429 | this.accountXuidLabel.Text = "XUID:"; 430 | // 431 | // accountNameLabel 432 | // 433 | this.accountNameLabel.AutoSize = true; 434 | this.accountNameLabel.Location = new System.Drawing.Point(195, 9); 435 | this.accountNameLabel.Name = "accountNameLabel"; 436 | this.accountNameLabel.Size = new System.Drawing.Size(56, 13); 437 | this.accountNameLabel.TabIndex = 11; 438 | this.accountNameLabel.Text = "Gamertag:"; 439 | // 440 | // accountsListBox 441 | // 442 | this.accountsListBox.FormattingEnabled = true; 443 | this.accountsListBox.Location = new System.Drawing.Point(6, 6); 444 | this.accountsListBox.Name = "accountsListBox"; 445 | this.accountsListBox.Size = new System.Drawing.Size(183, 212); 446 | this.accountsListBox.TabIndex = 10; 447 | this.accountsListBox.SelectedIndexChanged += new System.EventHandler(this.accountsListBox_SelectedIndexChanged); 448 | // 449 | // gamesTab 450 | // 451 | this.gamesTab.Controls.Add(this.titleIDFormattedLabel); 452 | this.gamesTab.Controls.Add(this.titleIconPicture); 453 | this.gamesTab.Controls.Add(this.titleClearConfigLink); 454 | this.gamesTab.Controls.Add(this.titleShowKeyCheck); 455 | this.gamesTab.Controls.Add(this.titleKeyLabel); 456 | this.gamesTab.Controls.Add(this.titleProductKeyBox); 457 | this.gamesTab.Controls.Add(this.titleIDBox); 458 | this.gamesTab.Controls.Add(this.titleNameBox); 459 | this.gamesTab.Controls.Add(this.titleIDLabel); 460 | this.gamesTab.Controls.Add(this.titleNameLabel); 461 | this.gamesTab.Controls.Add(this.gameListBox); 462 | this.gamesTab.Location = new System.Drawing.Point(4, 22); 463 | this.gamesTab.Name = "gamesTab"; 464 | this.gamesTab.Padding = new System.Windows.Forms.Padding(3); 465 | this.gamesTab.Size = new System.Drawing.Size(446, 224); 466 | this.gamesTab.TabIndex = 2; 467 | this.gamesTab.Text = "Games"; 468 | this.gamesTab.UseVisualStyleBackColor = true; 469 | // 470 | // titleIDFormattedLabel 471 | // 472 | this.titleIDFormattedLabel.AutoSize = true; 473 | this.titleIDFormattedLabel.Location = new System.Drawing.Point(314, 35); 474 | this.titleIDFormattedLabel.Name = "titleIDFormattedLabel"; 475 | this.titleIDFormattedLabel.Size = new System.Drawing.Size(62, 13); 476 | this.titleIDFormattedLabel.TabIndex = 18; 477 | this.titleIDFormattedLabel.Text = "(WW-9999)"; 478 | // 479 | // titleIconPicture 480 | // 481 | this.titleIconPicture.Location = new System.Drawing.Point(376, 58); 482 | this.titleIconPicture.Name = "titleIconPicture"; 483 | this.titleIconPicture.Size = new System.Drawing.Size(64, 64); 484 | this.titleIconPicture.TabIndex = 17; 485 | this.titleIconPicture.TabStop = false; 486 | // 487 | // titleClearConfigLink 488 | // 489 | this.titleClearConfigLink.AutoSize = true; 490 | this.titleClearConfigLink.Location = new System.Drawing.Point(394, 35); 491 | this.titleClearConfigLink.Name = "titleClearConfigLink"; 492 | this.titleClearConfigLink.Size = new System.Drawing.Size(46, 13); 493 | this.titleClearConfigLink.TabIndex = 9; 494 | this.titleClearConfigLink.TabStop = true; 495 | this.titleClearConfigLink.Text = "Config..."; 496 | this.titleClearConfigLink.Visible = false; 497 | // 498 | // titleShowKeyCheck 499 | // 500 | this.titleShowKeyCheck.AutoSize = true; 501 | this.titleShowKeyCheck.Location = new System.Drawing.Point(387, 181); 502 | this.titleShowKeyCheck.Name = "titleShowKeyCheck"; 503 | this.titleShowKeyCheck.Size = new System.Drawing.Size(53, 17); 504 | this.titleShowKeyCheck.TabIndex = 7; 505 | this.titleShowKeyCheck.Text = "Show"; 506 | this.titleShowKeyCheck.UseVisualStyleBackColor = true; 507 | this.titleShowKeyCheck.CheckedChanged += new System.EventHandler(this.titleShowKeyCheck_CheckedChanged); 508 | // 509 | // titleKeyLabel 510 | // 511 | this.titleKeyLabel.AutoSize = true; 512 | this.titleKeyLabel.Location = new System.Drawing.Point(195, 182); 513 | this.titleKeyLabel.Name = "titleKeyLabel"; 514 | this.titleKeyLabel.Size = new System.Drawing.Size(68, 13); 515 | this.titleKeyLabel.TabIndex = 6; 516 | this.titleKeyLabel.Text = "Product Key:"; 517 | // 518 | // titleProductKeyBox 519 | // 520 | this.titleProductKeyBox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 521 | this.titleProductKeyBox.Location = new System.Drawing.Point(195, 198); 522 | this.titleProductKeyBox.Name = "titleProductKeyBox"; 523 | this.titleProductKeyBox.ReadOnly = true; 524 | this.titleProductKeyBox.Size = new System.Drawing.Size(245, 20); 525 | this.titleProductKeyBox.TabIndex = 5; 526 | this.titleProductKeyBox.Text = "WWWWW-WWWWW-WWWWW-WWWWW-WWWWW"; 527 | // 528 | // titleIDBox 529 | // 530 | this.titleIDBox.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 531 | this.titleIDBox.Location = new System.Drawing.Point(245, 32); 532 | this.titleIDBox.Name = "titleIDBox"; 533 | this.titleIDBox.ReadOnly = true; 534 | this.titleIDBox.Size = new System.Drawing.Size(63, 20); 535 | this.titleIDBox.TabIndex = 4; 536 | this.titleIDBox.Text = "DEADF00D"; 537 | // 538 | // titleNameBox 539 | // 540 | this.titleNameBox.Location = new System.Drawing.Point(270, 6); 541 | this.titleNameBox.Name = "titleNameBox"; 542 | this.titleNameBox.ReadOnly = true; 543 | this.titleNameBox.Size = new System.Drawing.Size(170, 20); 544 | this.titleNameBox.TabIndex = 3; 545 | this.titleNameBox.Text = "Super Awesome Long Game Name Title"; 546 | // 547 | // titleIDLabel 548 | // 549 | this.titleIDLabel.AutoSize = true; 550 | this.titleIDLabel.Location = new System.Drawing.Point(195, 35); 551 | this.titleIDLabel.Name = "titleIDLabel"; 552 | this.titleIDLabel.Size = new System.Drawing.Size(44, 13); 553 | this.titleIDLabel.TabIndex = 2; 554 | this.titleIDLabel.Text = "Title ID:"; 555 | // 556 | // titleNameLabel 557 | // 558 | this.titleNameLabel.AutoSize = true; 559 | this.titleNameLabel.Location = new System.Drawing.Point(195, 9); 560 | this.titleNameLabel.Name = "titleNameLabel"; 561 | this.titleNameLabel.Size = new System.Drawing.Size(69, 13); 562 | this.titleNameLabel.TabIndex = 1; 563 | this.titleNameLabel.Text = "Game Name:"; 564 | // 565 | // gameListBox 566 | // 567 | this.gameListBox.FormattingEnabled = true; 568 | this.gameListBox.Location = new System.Drawing.Point(6, 6); 569 | this.gameListBox.Name = "gameListBox"; 570 | this.gameListBox.Size = new System.Drawing.Size(183, 212); 571 | this.gameListBox.TabIndex = 0; 572 | this.gameListBox.SelectedIndexChanged += new System.EventHandler(this.gameListBox_SelectedIndexChanged); 573 | // 574 | // utilitiesTab 575 | // 576 | this.utilitiesTab.Controls.Add(this.connBlockGroup); 577 | this.utilitiesTab.Controls.Add(this.dataExportGroup); 578 | this.utilitiesTab.Location = new System.Drawing.Point(4, 22); 579 | this.utilitiesTab.Name = "utilitiesTab"; 580 | this.utilitiesTab.Padding = new System.Windows.Forms.Padding(3); 581 | this.utilitiesTab.Size = new System.Drawing.Size(446, 224); 582 | this.utilitiesTab.TabIndex = 5; 583 | this.utilitiesTab.Text = "Utilities"; 584 | this.utilitiesTab.UseVisualStyleBackColor = true; 585 | // 586 | // connBlockGroup 587 | // 588 | this.connBlockGroup.Controls.Add(this.blockLiveInfoLabel); 589 | this.connBlockGroup.Controls.Add(this.blockServicesInfoLabel); 590 | this.connBlockGroup.Controls.Add(this.blockServicesButton); 591 | this.connBlockGroup.Controls.Add(this.blockLiveButton); 592 | this.connBlockGroup.Location = new System.Drawing.Point(6, 63); 593 | this.connBlockGroup.Name = "connBlockGroup"; 594 | this.connBlockGroup.Size = new System.Drawing.Size(434, 85); 595 | this.connBlockGroup.TabIndex = 4; 596 | this.connBlockGroup.TabStop = false; 597 | this.connBlockGroup.Text = "Connection Blocking"; 598 | // 599 | // blockLiveInfoLabel 600 | // 601 | this.blockLiveInfoLabel.AutoSize = true; 602 | this.blockLiveInfoLabel.Location = new System.Drawing.Point(136, 58); 603 | this.blockLiveInfoLabel.Name = "blockLiveInfoLabel"; 604 | this.blockLiveInfoLabel.Size = new System.Drawing.Size(275, 13); 605 | this.blockLiveInfoLabel.TabIndex = 4; 606 | this.blockLiveInfoLabel.Text = "Blocks *ALL* connections to Games for Windows - LIVE."; 607 | // 608 | // blockServicesInfoLabel 609 | // 610 | this.blockServicesInfoLabel.AutoSize = true; 611 | this.blockServicesInfoLabel.Location = new System.Drawing.Point(136, 24); 612 | this.blockServicesInfoLabel.Name = "blockServicesInfoLabel"; 613 | this.blockServicesInfoLabel.Size = new System.Drawing.Size(272, 26); 614 | this.blockServicesInfoLabel.TabIndex = 3; 615 | this.blockServicesInfoLabel.Text = "Blocks GfWL marketplace services to speed up loading.\r\n(Recommended)"; 616 | // 617 | // dataExportGroup 618 | // 619 | this.dataExportGroup.Controls.Add(this.dataExportInfoLabel); 620 | this.dataExportGroup.Controls.Add(this.dataImportButton); 621 | this.dataExportGroup.Controls.Add(this.dataExportButton); 622 | this.dataExportGroup.Location = new System.Drawing.Point(6, 6); 623 | this.dataExportGroup.Name = "dataExportGroup"; 624 | this.dataExportGroup.Size = new System.Drawing.Size(434, 51); 625 | this.dataExportGroup.TabIndex = 0; 626 | this.dataExportGroup.TabStop = false; 627 | this.dataExportGroup.Text = "Data Export"; 628 | // 629 | // dataExportInfoLabel 630 | // 631 | this.dataExportInfoLabel.AutoSize = true; 632 | this.dataExportInfoLabel.Location = new System.Drawing.Point(168, 24); 633 | this.dataExportInfoLabel.Name = "dataExportInfoLabel"; 634 | this.dataExportInfoLabel.Size = new System.Drawing.Size(225, 13); 635 | this.dataExportInfoLabel.TabIndex = 3; 636 | this.dataExportInfoLabel.Text = "Export or import your data to another computer"; 637 | // 638 | // dataImportButton 639 | // 640 | this.dataImportButton.Location = new System.Drawing.Point(6, 19); 641 | this.dataImportButton.Name = "dataImportButton"; 642 | this.dataImportButton.Size = new System.Drawing.Size(75, 23); 643 | this.dataImportButton.TabIndex = 1; 644 | this.dataImportButton.Text = "Import..."; 645 | this.dataImportButton.UseVisualStyleBackColor = true; 646 | this.dataImportButton.Click += new System.EventHandler(this.dataImportButton_Click); 647 | // 648 | // dataExportButton 649 | // 650 | this.dataExportButton.Location = new System.Drawing.Point(87, 19); 651 | this.dataExportButton.Name = "dataExportButton"; 652 | this.dataExportButton.Size = new System.Drawing.Size(75, 23); 653 | this.dataExportButton.TabIndex = 0; 654 | this.dataExportButton.Text = "Export..."; 655 | this.dataExportButton.UseVisualStyleBackColor = true; 656 | this.dataExportButton.Click += new System.EventHandler(this.dataExportButton_Click); 657 | // 658 | // label1 659 | // 660 | this.label1.AutoSize = true; 661 | this.label1.Location = new System.Drawing.Point(12, 265); 662 | this.label1.Name = "label1"; 663 | this.label1.Size = new System.Drawing.Size(351, 13); 664 | this.label1.TabIndex = 1; 665 | this.label1.Text = "Unofficial utility by Emma / InvoxiPlayGames. Not affiliated with Microsoft."; 666 | // 667 | // githubLinkLabel 668 | // 669 | this.githubLinkLabel.AutoSize = true; 670 | this.githubLinkLabel.Location = new System.Drawing.Point(13, 280); 671 | this.githubLinkLabel.Name = "githubLinkLabel"; 672 | this.githubLinkLabel.Size = new System.Drawing.Size(239, 13); 673 | this.githubLinkLabel.TabIndex = 2; 674 | this.githubLinkLabel.TabStop = true; 675 | this.githubLinkLabel.Text = "https://github.com/InvoxiPlayGames/GfWLUtility"; 676 | this.githubLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.githubLinkLabel_LinkClicked); 677 | // 678 | // appVersionLabel 679 | // 680 | this.appVersionLabel.AutoSize = true; 681 | this.appVersionLabel.Location = new System.Drawing.Point(359, 280); 682 | this.appVersionLabel.Name = "appVersionLabel"; 683 | this.appVersionLabel.Size = new System.Drawing.Size(107, 13); 684 | this.appVersionLabel.TabIndex = 3; 685 | this.appVersionLabel.Text = "version 1.0.0.0-beta1"; 686 | // 687 | // installMarketplaceButton 688 | // 689 | this.installMarketplaceButton.FlatStyle = System.Windows.Forms.FlatStyle.System; 690 | this.installMarketplaceButton.Location = new System.Drawing.Point(6, 73); 691 | this.installMarketplaceButton.Name = "installMarketplaceButton"; 692 | this.installMarketplaceButton.Size = new System.Drawing.Size(227, 23); 693 | this.installMarketplaceButton.TabIndex = 8; 694 | this.installMarketplaceButton.Text = "Install marketplace"; 695 | this.installMarketplaceButton.UseVisualStyleBackColor = true; 696 | this.installMarketplaceButton.Click += new System.EventHandler(this.installMarketplaceButton_Click); 697 | // 698 | // installWLIDButton 699 | // 700 | this.installWLIDButton.FlatStyle = System.Windows.Forms.FlatStyle.System; 701 | this.installWLIDButton.Location = new System.Drawing.Point(6, 73); 702 | this.installWLIDButton.Name = "installWLIDButton"; 703 | this.installWLIDButton.Size = new System.Drawing.Size(177, 23); 704 | this.installWLIDButton.TabIndex = 9; 705 | this.installWLIDButton.Text = "Install sign-in assistant"; 706 | this.installWLIDButton.UseVisualStyleBackColor = true; 707 | this.installWLIDButton.Click += new System.EventHandler(this.installWLIDButton_Click); 708 | // 709 | // installRuntimeButton 710 | // 711 | this.installRuntimeButton.FlatStyle = System.Windows.Forms.FlatStyle.System; 712 | this.installRuntimeButton.Location = new System.Drawing.Point(6, 73); 713 | this.installRuntimeButton.Name = "installRuntimeButton"; 714 | this.installRuntimeButton.Size = new System.Drawing.Size(227, 23); 715 | this.installRuntimeButton.TabIndex = 8; 716 | this.installRuntimeButton.Text = "Install runtime"; 717 | this.installRuntimeButton.UseVisualStyleBackColor = true; 718 | this.installRuntimeButton.Click += new System.EventHandler(this.installRuntimeButton_Click); 719 | // 720 | // blockServicesButton 721 | // 722 | this.blockServicesButton.FlatStyle = System.Windows.Forms.FlatStyle.System; 723 | this.blockServicesButton.Location = new System.Drawing.Point(6, 19); 724 | this.blockServicesButton.Name = "blockServicesButton"; 725 | this.blockServicesButton.Size = new System.Drawing.Size(124, 23); 726 | this.blockServicesButton.TabIndex = 1; 727 | this.blockServicesButton.Text = "Block Services"; 728 | this.blockServicesButton.UseVisualStyleBackColor = true; 729 | this.blockServicesButton.Click += new System.EventHandler(this.blockServicesButton_Click); 730 | // 731 | // blockLiveButton 732 | // 733 | this.blockLiveButton.FlatStyle = System.Windows.Forms.FlatStyle.System; 734 | this.blockLiveButton.Location = new System.Drawing.Point(6, 53); 735 | this.blockLiveButton.Name = "blockLiveButton"; 736 | this.blockLiveButton.Size = new System.Drawing.Size(124, 23); 737 | this.blockLiveButton.TabIndex = 0; 738 | this.blockLiveButton.Text = "Block LIVE"; 739 | this.blockLiveButton.UseVisualStyleBackColor = true; 740 | this.blockLiveButton.Click += new System.EventHandler(this.blockLiveButton_Click); 741 | // 742 | // MainWindow 743 | // 744 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 745 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 746 | this.ClientSize = new System.Drawing.Size(478, 304); 747 | this.Controls.Add(this.appVersionLabel); 748 | this.Controls.Add(this.githubLinkLabel); 749 | this.Controls.Add(this.label1); 750 | this.Controls.Add(this.mainTabControl); 751 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 752 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 753 | this.MaximizeBox = false; 754 | this.MinimizeBox = false; 755 | this.Name = "MainWindow"; 756 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 757 | this.Text = "GfWL Utility"; 758 | this.Load += new System.EventHandler(this.MainWindow_Load); 759 | this.mainTabControl.ResumeLayout(false); 760 | this.runtimeTab.ResumeLayout(false); 761 | this.systemInfoGroup.ResumeLayout(false); 762 | this.systemInfoGroup.PerformLayout(); 763 | this.marketplaceGroup.ResumeLayout(false); 764 | this.marketplaceGroup.PerformLayout(); 765 | ((System.ComponentModel.ISupportInitialize)(this.marketplaceLogoPicture)).EndInit(); 766 | this.wlidGroup.ResumeLayout(false); 767 | this.wlidGroup.PerformLayout(); 768 | ((System.ComponentModel.ISupportInitialize)(this.wlidLogoPicture)).EndInit(); 769 | this.runtimeGroup.ResumeLayout(false); 770 | this.runtimeGroup.PerformLayout(); 771 | ((System.ComponentModel.ISupportInitialize)(this.gfwlLogoPicture)).EndInit(); 772 | this.accountsTab.ResumeLayout(false); 773 | this.accountsTab.PerformLayout(); 774 | ((System.ComponentModel.ISupportInitialize)(this.accountGamerpic)).EndInit(); 775 | this.gamesTab.ResumeLayout(false); 776 | this.gamesTab.PerformLayout(); 777 | ((System.ComponentModel.ISupportInitialize)(this.titleIconPicture)).EndInit(); 778 | this.utilitiesTab.ResumeLayout(false); 779 | this.connBlockGroup.ResumeLayout(false); 780 | this.connBlockGroup.PerformLayout(); 781 | this.dataExportGroup.ResumeLayout(false); 782 | this.dataExportGroup.PerformLayout(); 783 | this.ResumeLayout(false); 784 | this.PerformLayout(); 785 | 786 | } 787 | 788 | #endregion 789 | 790 | private System.Windows.Forms.TabControl mainTabControl; 791 | private System.Windows.Forms.TabPage runtimeTab; 792 | private System.Windows.Forms.TabPage accountsTab; 793 | private System.Windows.Forms.Label runtimeVersionLabel; 794 | private System.Windows.Forms.Label runtimeInstallLabel; 795 | private System.Windows.Forms.TabPage gamesTab; 796 | private System.Windows.Forms.PictureBox gfwlLogoPicture; 797 | private System.Windows.Forms.Label wlidInfoLabel; 798 | private System.Windows.Forms.PictureBox wlidLogoPicture; 799 | private System.Windows.Forms.Label wlidInstallLabel; 800 | private System.Windows.Forms.TabPage utilitiesTab; 801 | private System.Windows.Forms.GroupBox dataExportGroup; 802 | private System.Windows.Forms.Label dataExportInfoLabel; 803 | private System.Windows.Forms.Button dataImportButton; 804 | private System.Windows.Forms.Button dataExportButton; 805 | private System.Windows.Forms.GroupBox wlidGroup; 806 | private System.Windows.Forms.GroupBox runtimeGroup; 807 | private System.Windows.Forms.Button manageRuntimeButton; 808 | private System.Windows.Forms.GroupBox systemInfoGroup; 809 | private System.Windows.Forms.GroupBox marketplaceGroup; 810 | private System.Windows.Forms.Button manageMarketplaceButton; 811 | private System.Windows.Forms.PictureBox marketplaceLogoPicture; 812 | private System.Windows.Forms.Label marketplaceInstallLabel; 813 | private System.Windows.Forms.Label marketplaceVersionLabel; 814 | private System.Windows.Forms.TextBox versionText; 815 | private System.Windows.Forms.Label versionLabel; 816 | private System.Windows.Forms.TextBox pcidText; 817 | private System.Windows.Forms.Label pcidLabel; 818 | private System.Windows.Forms.CheckBox showPCIDCheckbox; 819 | private ElevatedButton installRuntimeButton; 820 | private ElevatedButton installWLIDButton; 821 | private ElevatedButton installMarketplaceButton; 822 | private System.Windows.Forms.CheckBox titleShowKeyCheck; 823 | private System.Windows.Forms.Label titleKeyLabel; 824 | private System.Windows.Forms.TextBox titleProductKeyBox; 825 | private System.Windows.Forms.TextBox titleIDBox; 826 | private System.Windows.Forms.TextBox titleNameBox; 827 | private System.Windows.Forms.Label titleIDLabel; 828 | private System.Windows.Forms.Label titleNameLabel; 829 | private System.Windows.Forms.ListBox gameListBox; 830 | private System.Windows.Forms.LinkLabel titleClearConfigLink; 831 | private System.Windows.Forms.CheckBox accountLiveCheck; 832 | private System.Windows.Forms.TextBox accountXuidBox; 833 | private System.Windows.Forms.TextBox accountNameBox; 834 | private System.Windows.Forms.Label accountXuidLabel; 835 | private System.Windows.Forms.Label accountNameLabel; 836 | private System.Windows.Forms.ListBox accountsListBox; 837 | private System.Windows.Forms.PictureBox accountGamerpic; 838 | private System.Windows.Forms.PictureBox titleIconPicture; 839 | private System.Windows.Forms.GroupBox connBlockGroup; 840 | private System.Windows.Forms.Label blockServicesInfoLabel; 841 | private System.Windows.Forms.Label blockLiveInfoLabel; 842 | private System.Windows.Forms.Label label1; 843 | private System.Windows.Forms.LinkLabel githubLinkLabel; 844 | private System.Windows.Forms.Label appVersionLabel; 845 | private ElevatedButton blockServicesButton; 846 | private ElevatedButton blockLiveButton; 847 | private System.Windows.Forms.Label titleIDFormattedLabel; 848 | private System.Windows.Forms.Label onlineXuidLabel; 849 | private System.Windows.Forms.TextBox onlineXuidBox; 850 | } 851 | } 852 | 853 | -------------------------------------------------------------------------------- /MainWindow.cs: -------------------------------------------------------------------------------- 1 | using GfWLUtility.Properties; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Diagnostics; 7 | using System.Drawing; 8 | using System.Globalization; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Reflection; 12 | using System.Runtime.InteropServices; 13 | using System.Text; 14 | using System.Windows.Forms; 15 | 16 | namespace GfWLUtility 17 | { 18 | public partial class MainWindow : Form 19 | { 20 | public MainWindow() 21 | { 22 | InitializeComponent(); 23 | } 24 | 25 | private void LoadSystemInfoGroup() 26 | { 27 | showPCIDCheckbox.Checked = false; 28 | pcidText.Text = UtilityFuncs.CensorString(GfWLRegistry.GetPCID(), 2, 2, 4); 29 | versionText.Text = GfWLRegistry.GetVersion(); 30 | } 31 | 32 | private bool ConfirmIsAdmin() 33 | { 34 | if (!Program.Elevated) 35 | { 36 | // no UAC prompt on Windows XP, and while technically Run As... still exists it's not what i'm going for 37 | if (!UtilityFuncs.IsWindowsXP()) 38 | { 39 | DialogResult r = MessageBox.Show("You must run GfWL Utility as administrator to use this functionality.\n\nDo you want to relaunch as administrator?", 40 | "Permission Required", MessageBoxButtons.YesNo, MessageBoxIcon.Information); 41 | if (r == DialogResult.Yes) 42 | { 43 | Program.RelaunchAsAdmin(); 44 | return false; 45 | } else 46 | { 47 | return false; 48 | } 49 | } else 50 | { 51 | MessageBox.Show("You must run GfWL Utility as an administrator to use this functionality.", 52 | "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 53 | return false; 54 | } 55 | } 56 | else return true; 57 | } 58 | 59 | private void LoadRuntimeInfoGroup() 60 | { 61 | string xlive_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "xlive.dll"); 62 | if (File.Exists(xlive_path)) 63 | { 64 | Version xlive_version = UtilityFuncs.GetProductVersion(xlive_path); 65 | runtimeInstallLabel.Text = "Runtime installed!"; 66 | runtimeVersionLabel.Text = $"Version {xlive_version}"; 67 | // hardcoded latest version. sucks? 68 | if (xlive_version.CompareTo(new Version("3.5.95.0")) >= 0) { 69 | gfwlLogoPicture.Image = Resources.GfWLCheck; 70 | installRuntimeButton.Enabled = false; 71 | installRuntimeButton.Text = "Up to date!"; 72 | } else 73 | { 74 | gfwlLogoPicture.Image = Resources.GfWLOld; 75 | installRuntimeButton.Enabled = true; 76 | installRuntimeButton.Text = "Update runtime"; 77 | } 78 | } else 79 | { 80 | gfwlLogoPicture.Image = Resources.GfWLUnknown; 81 | runtimeInstallLabel.Text = "Runtime not installed."; 82 | runtimeVersionLabel.Text = ""; 83 | installRuntimeButton.Enabled = true; 84 | installRuntimeButton.Text = "Install runtime"; 85 | } 86 | } 87 | 88 | private void LoadMarketplaceInfoGroup() 89 | { 90 | string dashdir = GfWLRegistry.GetDashPath(); 91 | string gfwdashpath = ""; 92 | if (dashdir != null) 93 | gfwdashpath = Path.Combine(dashdir, "GFWLive.exe"); 94 | if (gfwdashpath != null && File.Exists(gfwdashpath)) 95 | { 96 | Version dash_version = UtilityFuncs.GetProductVersion(gfwdashpath); 97 | marketplaceInstallLabel.Text = "Marketplace installed!"; 98 | marketplaceVersionLabel.Text = $"Version {dash_version}"; 99 | // hardcoded latest version. sucks? 100 | if (dash_version.CompareTo(new Version("3.5.67.0")) >= 0) 101 | { 102 | Bitmap dashIcon = UtilityFuncs.Get48x48Icon(gfwdashpath); 103 | if (dashIcon != null) 104 | marketplaceLogoPicture.Image = dashIcon; 105 | else 106 | marketplaceLogoPicture.Image = Resources.GfWLCheck; 107 | installMarketplaceButton.Enabled = false; 108 | installMarketplaceButton.Text = "Up to date!"; 109 | } 110 | else 111 | { 112 | marketplaceLogoPicture.Image = Resources.GfWLOld; 113 | installMarketplaceButton.Enabled = true; 114 | installMarketplaceButton.Text = "Update marketplace"; 115 | } 116 | } 117 | else 118 | { 119 | marketplaceLogoPicture.Image = Resources.GfWLUnknown; 120 | marketplaceInstallLabel.Text = "Marketplace not installed."; 121 | marketplaceVersionLabel.Text = ""; 122 | installMarketplaceButton.Enabled = true; 123 | installMarketplaceButton.Text = "Install marketplace"; 124 | } 125 | } 126 | 127 | private void LoadWLIDGroup() 128 | { 129 | // Windows 8+ seems to have a forwarder from msidcrl40 to wlidcli 130 | // wlidcli has the icon assets so we use that 131 | string wlid_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "wlidcli.dll"); 132 | // sometimes msidcrl40.dll will end up at "C:\Program Files\Common Files\microsoft shared\Windows Live" 133 | if (!File.Exists(wlid_path)) 134 | wlid_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonProgramFiles), @"microsoft shared\Windows Live\msidcrl40.dll"); 135 | if (!File.Exists(wlid_path)) 136 | wlid_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "msidcrl40.dll"); 137 | // hack to get older versions to show up as existing but old 138 | if (!File.Exists(wlid_path)) 139 | wlid_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "msidcrl30.dll"); 140 | if (File.Exists(wlid_path)) 141 | { 142 | Version wlid_version = UtilityFuncs.GetProductVersion(wlid_path); 143 | wlidInstallLabel.Text = "Assistant installed!"; 144 | // are we on 8+? 145 | if (UtilityFuncs.IsWindowsModern()) 146 | wlidInfoLabel.Text = ""; 147 | else 148 | wlidInfoLabel.Text = $"Version {wlid_version}"; 149 | 150 | Bitmap wlidIcon = UtilityFuncs.Get48x48Icon(wlid_path); 151 | if (wlidIcon != null) 152 | wlidLogoPicture.Image = wlidIcon; 153 | else 154 | wlidLogoPicture.Image = Resources.WLIDOld; 155 | 156 | // hardcoded latest version. sucks? 157 | if (UtilityFuncs.IsWindowsModern() || wlid_version.CompareTo(new Version("6.500.3165.0")) >= 0) 158 | { 159 | installWLIDButton.Enabled = false; 160 | installWLIDButton.Text = UtilityFuncs.IsWindowsModern() ? "Included in Windows" : "Up to date!"; 161 | } 162 | else 163 | { 164 | installWLIDButton.Enabled = true; 165 | installWLIDButton.Text = "Update sign-in assistant"; 166 | } 167 | } 168 | else 169 | { 170 | wlidLogoPicture.Image = Resources.WLIDUnknown; 171 | wlidInstallLabel.Text = "Assistant missing."; 172 | wlidInfoLabel.Text = ""; 173 | installWLIDButton.Enabled = true; 174 | installWLIDButton.Text = "Install sign-in assistant"; 175 | } 176 | } 177 | 178 | private void LoadConnBlockGroup() 179 | { 180 | if (DomainBlock.IsDomainBlocked("services.gamesforwindows.com")) 181 | blockServicesButton.Text = "Unblock Services"; 182 | else 183 | blockServicesButton.Text = "Block Services"; 184 | 185 | if (DomainBlock.IsDomainBlocked("xeas.xboxlive.com") || 186 | DomainBlock.IsDomainBlocked("xemacs.xboxlive.com") || 187 | DomainBlock.IsDomainBlocked("xetgs.xboxlive.com")) 188 | blockLiveButton.Text = "Unblock LIVE"; 189 | else 190 | blockLiveButton.Text = "Block LIVE"; 191 | } 192 | 193 | private void LoadAllGroups() 194 | { 195 | LoadConnBlockGroup(); 196 | LoadRuntimeInfoGroup(); 197 | LoadSystemInfoGroup(); 198 | LoadMarketplaceInfoGroup(); 199 | LoadWLIDGroup(); 200 | } 201 | 202 | private void RefreshGamePage() 203 | { 204 | titleNameBox.Text = string.Empty; 205 | titleIDBox.Text = string.Empty; 206 | titleProductKeyBox.Text = string.Empty; 207 | titleIDFormattedLabel.Text = string.Empty; 208 | titleShowKeyCheck.Checked = false; 209 | 210 | if (gameListBox.SelectedIndex == -1) 211 | { 212 | titleShowKeyCheck.Enabled = false; 213 | titleClearConfigLink.Enabled = false; 214 | return; 215 | } 216 | 217 | titleShowKeyCheck.Enabled = true; 218 | titleClearConfigLink.Enabled = true; 219 | 220 | KnownTitle selected = (KnownTitle)gameListBox.SelectedItem; 221 | titleNameBox.Text = selected.Name; 222 | titleIDBox.Text = selected.TitleID.ToString("X8"); 223 | titleIDFormattedLabel.Text = "(" + UtilityFuncs.GetFormattedTitleID(selected.TitleID) + ")"; 224 | titleProductKeyBox.Text = UtilityFuncs.CensorString(TitleManager.GetTitleProductKey(selected.TitleID), 6, 6, 5); 225 | titleIconPicture.ImageLocation = $"http://image.xboxlive.com/global/t.{selected.TitleID:X8}/icon/0/8000"; 226 | } 227 | 228 | private void RefreshProfilePage() 229 | { 230 | accountNameBox.Text = string.Empty; 231 | accountXuidBox.Text = string.Empty; 232 | 233 | if (accountsListBox.SelectedIndex == -1) 234 | { 235 | return; 236 | } 237 | 238 | KnownUser selected = (KnownUser)accountsListBox.SelectedItem; 239 | accountNameBox.Text = selected.Gamertag; 240 | accountXuidBox.Text = selected.XUID.ToString("X8"); 241 | accountGamerpic.ImageLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 242 | $"Microsoft\\Xlive\\Content\\{selected.XUID:X8}\\FFFE07D1\\00010000\\{selected.XUID:X8}_MountPt\\tile_64.png"); 243 | } 244 | 245 | private void SearchForTitles() 246 | { 247 | string titlePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 248 | $"Microsoft\\Xlive\\Titles"); 249 | if (Directory.Exists(titlePath)) 250 | { 251 | string[] titleSubdirs = Directory.GetDirectories(titlePath); 252 | foreach(string subdir in titleSubdirs) 253 | { 254 | string titleID = Path.GetFileName(subdir); 255 | uint titleIDInt = 0; 256 | if (!uint.TryParse(titleID, NumberStyles.HexNumber, 257 | CultureInfo.CurrentCulture, out titleIDInt)) 258 | continue; 259 | TitleManager.FoundTitleExists(titleIDInt); 260 | } 261 | } 262 | 263 | gameListBox.Items.Clear(); 264 | foreach (KnownTitle title in TitleManager.KnownTitles.Values) 265 | { 266 | gameListBox.Items.Add(title); 267 | } 268 | 269 | RefreshGamePage(); 270 | } 271 | 272 | private void SearchForProfiles() 273 | { 274 | string profilesPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 275 | $"Microsoft\\Xlive\\Content"); 276 | if (Directory.Exists(profilesPath)) 277 | { 278 | string[] titleSubdirs = Directory.GetDirectories(profilesPath); 279 | foreach (string subdir in titleSubdirs) 280 | { 281 | string xuid = Path.GetFileName(subdir); 282 | ulong xuidInt = 0; 283 | if (!ulong.TryParse(xuid, NumberStyles.HexNumber, 284 | CultureInfo.CurrentCulture, out xuidInt)) 285 | continue; 286 | // make sure it's a valid xuid 287 | if ((xuidInt & 0xE000000000000000) != 0xE000000000000000) 288 | continue; 289 | UserManager.FoundUserExists(xuidInt); 290 | } 291 | } 292 | 293 | accountsListBox.Items.Clear(); 294 | foreach (KnownUser title in UserManager.KnownUsers.Values) 295 | { 296 | accountsListBox.Items.Add(title); 297 | } 298 | 299 | RefreshProfilePage(); 300 | } 301 | 302 | private void MainWindow_Load(object sender, EventArgs e) 303 | { 304 | MessageBox.Show(@"This application is in a very early beta! 305 | A lot of stuff won't work. 306 | PRs welcome on GitHub!", "Notice", MessageBoxButtons.OK, MessageBoxIcon.Warning); 307 | 308 | LoadAllGroups(); 309 | SearchForProfiles(); 310 | SearchForTitles(); 311 | if (Program.Elevated && !UtilityFuncs.IsWindowsXP()) 312 | Text += " (Administrator)"; 313 | } 314 | 315 | private void showPCIDCheckbox_CheckedChanged(object sender, EventArgs e) 316 | { 317 | if (showPCIDCheckbox.Checked) 318 | pcidText.Text = GfWLRegistry.GetPCID(); 319 | else 320 | pcidText.Text = UtilityFuncs.CensorString(GfWLRegistry.GetPCID(), 2, 2, 4); 321 | } 322 | 323 | private void blockServicesButton_Click(object sender, EventArgs e) 324 | { 325 | if (!ConfirmIsAdmin()) 326 | return; 327 | 328 | if (DomainBlock.IsDomainBlocked("services.gamesforwindows.com")) 329 | DomainBlock.UnblockDomain("services.gamesforwindows.com"); 330 | else 331 | DomainBlock.BlockDomain("services.gamesforwindows.com"); 332 | 333 | LoadConnBlockGroup(); 334 | } 335 | 336 | private void blockLiveButton_Click(object sender, EventArgs e) 337 | { 338 | if (!ConfirmIsAdmin()) 339 | return; 340 | 341 | string[] domains = new string[] { "xeas.xboxlive.com", "xemacs.xboxlive.com", "xetgs.xboxlive.com" }; 342 | if (domains.Any(DomainBlock.IsDomainBlocked)) 343 | { 344 | foreach (var d in domains) DomainBlock.UnblockDomain(d); 345 | } 346 | else 347 | { 348 | DialogResult r = MessageBox.Show("Blocking LIVE means all Games for Windows - LIVE games will no longer be able to sign in, and some games may be unplayable. Are you sure you want to continue?", 349 | "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); 350 | if (r == DialogResult.Yes) 351 | { 352 | foreach (var d in domains) DomainBlock.BlockDomain(d); 353 | } 354 | } 355 | 356 | LoadConnBlockGroup(); 357 | } 358 | 359 | private void githubLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 360 | { 361 | Process.Start("https://github.com/InvoxiPlayGames/GfWLUtility"); 362 | } 363 | 364 | private void gameListBox_SelectedIndexChanged(object sender, EventArgs e) 365 | { 366 | RefreshGamePage(); 367 | } 368 | 369 | private void titleShowKeyCheck_CheckedChanged(object sender, EventArgs e) 370 | { 371 | KnownTitle selected = (KnownTitle)gameListBox.SelectedItem; 372 | if (selected == null) return; 373 | if (titleShowKeyCheck.Checked) 374 | titleProductKeyBox.Text = TitleManager.GetTitleProductKey(selected.TitleID); 375 | else 376 | titleProductKeyBox.Text = UtilityFuncs.CensorString(TitleManager.GetTitleProductKey(selected.TitleID), 6, 6, 5); 377 | } 378 | 379 | private void accountsListBox_SelectedIndexChanged(object sender, EventArgs e) 380 | { 381 | RefreshProfilePage(); 382 | } 383 | 384 | private void dataExportButton_Click(object sender, EventArgs e) 385 | { 386 | ExportForm form = new ExportForm(); 387 | form.ShowDialog(); 388 | } 389 | 390 | private void dataImportButton_Click(object sender, EventArgs e) 391 | { 392 | MessageBox.Show("Data import is not currently supported.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); 393 | } 394 | 395 | private void installRuntimeButton_Click(object sender, EventArgs e) 396 | { 397 | /* 398 | DownloadForm form = new DownloadForm(); 399 | DownloadFormResult fr = form.StartFileDownload(StaticFileInformation.titleupdate_3_5_95_cab, this); 400 | if (fr == DownloadFormResult.DownloadCancelled) 401 | { 402 | MessageBox.Show("The download was cancelled.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 403 | return; 404 | } else if (fr == DownloadFormResult.DownloadFailure) 405 | { 406 | MessageBox.Show("The download failed.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); 407 | return; 408 | } 409 | string cabPath = form.GetOutputFilePath(); 410 | if (!File.Exists(cabPath)) 411 | { 412 | MessageBox.Show("The download worked, but the CAB doesn't exist?!", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); 413 | return; 414 | }*/ 415 | 416 | DialogResult dr = MessageBox.Show( 417 | "This will install an older version of the runtime (3.5.92). You will have to update in-game.\n\nContinue?", "GfWL Utility", 418 | MessageBoxButtons.YesNo, MessageBoxIcon.Question); 419 | if (dr != DialogResult.Yes) 420 | return; 421 | 422 | DoMSIDownloadAndInstall(StaticFileInformation.xliveredist_3_5_92_msi); 423 | LoadRuntimeInfoGroup(); 424 | } 425 | 426 | private void DoMSIDownloadAndInstall(FileInformation fi) 427 | { 428 | DownloadForm form = new DownloadForm(); 429 | DownloadFormResult fr = form.StartFileDownload(fi, this); 430 | if (fr == DownloadFormResult.DownloadCancelled) 431 | { 432 | MessageBox.Show("The download was cancelled.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 433 | return; 434 | } 435 | else if (fr == DownloadFormResult.DownloadFailure) 436 | { 437 | MessageBox.Show("The download failed.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); 438 | return; 439 | } 440 | string msiPath = form.GetOutputFilePath(); 441 | if (!File.Exists(msiPath)) 442 | { 443 | MessageBox.Show("The download worked, but the MSI doesn't exist?! Make sure any anti-virus software is not interfering.", "GfWL Utility", MessageBoxButtons.OK, MessageBoxIcon.Error); 444 | return; 445 | } 446 | 447 | Process p = new Process(); 448 | p.StartInfo.FileName = "msiexec"; 449 | p.StartInfo.Arguments = $"/qf /i \"{msiPath}\""; 450 | p.StartInfo.UseShellExecute = true; 451 | p.Start(); 452 | p.WaitForExit(); 453 | } 454 | 455 | private void installMarketplaceButton_Click(object sender, EventArgs e) 456 | { 457 | DoMSIDownloadAndInstall(StaticFileInformation.gfwlclient_msi); 458 | LoadMarketplaceInfoGroup(); 459 | } 460 | 461 | private void installWLIDButton_Click(object sender, EventArgs e) 462 | { 463 | DoMSIDownloadAndInstall(StaticFileInformation.wllogin_32_msi); 464 | if (UtilityFuncs.IsWindows64Bit()) 465 | DoMSIDownloadAndInstall(StaticFileInformation.wllogin_64_msi); 466 | LoadWLIDGroup(); 467 | } 468 | } 469 | } 470 | -------------------------------------------------------------------------------- /Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Security.Principal; 7 | using System.Windows.Forms; 8 | 9 | namespace GfWLUtility 10 | { 11 | internal static class Program 12 | { 13 | public static bool Elevated = false; 14 | 15 | /// 16 | /// The main entry point for the application. 17 | /// 18 | [STAThread] 19 | static void Main() 20 | { 21 | // store elevation status 22 | WindowsIdentity identity = WindowsIdentity.GetCurrent(); 23 | WindowsPrincipal principal = new WindowsPrincipal(identity); 24 | Elevated = principal.IsInRole(WindowsBuiltInRole.Administrator); 25 | 26 | // start the application 27 | Application.EnableVisualStyles(); 28 | Application.SetCompatibleTextRenderingDefault(false); 29 | Application.Run(new MainWindow()); 30 | } 31 | 32 | public static void RelaunchAsAdmin() 33 | { 34 | Process p = new Process(); 35 | p.StartInfo.FileName = Assembly.GetExecutingAssembly().Location; 36 | p.StartInfo.UseShellExecute = true; 37 | p.StartInfo.Verb = "runas"; 38 | p.Start(); 39 | Application.Exit(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("GfWL Utility")] 9 | [assembly: AssemblyDescription("GfWL Utility")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("GfWL Utility")] 13 | [assembly: AssemblyCopyright("Copyright © InvoxiPlayGames 2024")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3dd60089-1d00-4dc7-8a88-a31ca30fbd88")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GfWLUtility.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("GfWLUtility.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap GfWLCheck { 67 | get { 68 | object obj = ResourceManager.GetObject("GfWLCheck", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap GfWLOld { 77 | get { 78 | object obj = ResourceManager.GetObject("GfWLOld", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap GfWLUnknown { 87 | get { 88 | object obj = ResourceManager.GetObject("GfWLUnknown", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap WLIDOld { 97 | get { 98 | object obj = ResourceManager.GetObject("WLIDOld", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap WLIDUnknown { 107 | get { 108 | object obj = ResourceManager.GetObject("WLIDUnknown", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\GfWLUtilityCheck.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\GfWLUtilityOld.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\GfWLUtilityUnknown.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\WLIDOld.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\WLIDUnknown.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | -------------------------------------------------------------------------------- /Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace GfWLUtility.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GfWL Utility 2 | 3 | Work-in-progress highly incomplete utility for working with Games for Windows - LIVE. 4 | 5 | This is incomplete. There will be bugs. 6 | 7 | **Requires .NET Framework 3.5:** 8 | 9 | * On Windows 8 and newer, you will get a prompt to install this if you do not have this. 10 | * On Windows 7 when fully up-to-date, it should be included. 11 | * On Windows XP and Vista, you will need to install [.NET Framework 3.5 SP1](https://dotnet.microsoft.com/en-us/download/dotnet-framework/net35-sp1) manually. 12 | 13 | ## Current Features: 14 | 15 | - View saved product keys 16 | - View some profile metadata (not everything, see TODO) 17 | - View some game information (not everything, see TODO) 18 | - Create a backup of all GfWL data including product keys and config sectors 19 | - Adding/removing GfWL domains from hosts for speedups, or to block LIVE 20 | - Install the latest or mostly-latest versions of GfWL components 21 | - Xlive Runtime (3.5.92, *mildly outdated*) 22 | - Latest Games for Windows Marketplace Client (3.5.67.0, latest) 23 | - Windows Live ID Sign-In Assistant (6.500.3165.0, latest, on Windows XP, Vista and 7) 24 | 25 | ## TODO 26 | 27 | Ordered roughly in order of what would be best to do first 28 | 29 | - CAB extractor for installing 3.5.95.0 runtime 30 | - Verify size/checksums after downloading 31 | - Figure out AES-CBC encryption key (used by XeKeysUnObfuscate) for profile metadata 32 | - I do not think this is the Xbox 360 Roamable Obfuscation Key but there is a small chance it is 33 | - Error handling everywhere 34 | - Parsing for getting the game name and icon 35 | - Ability to manage/clear per-game configs 36 | - Downloading from other mirrors if a file is unavailable 37 | - Support data importing from the data backups 38 | - Other useful stuff 39 | - Key/PCID trick? 40 | 41 | ## Shoutouts 42 | 43 | * [Legacy Update](https://legacyupdate.net) for providing mirrors for some assets 44 | * [Free60 Wiki](https://free60.org/) 45 | * [NeKzor's Xlive reversing from Tron Evolution](https://github.com/NeKzor/tem/blob/master/doc/src/reversed/xlive.md) 46 | * [XLiveLessNess](https://gitlab.com/GlitchyScripts/xlivelessness) 47 | -------------------------------------------------------------------------------- /Resources/GfWLUtilityCheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/Resources/GfWLUtilityCheck.png -------------------------------------------------------------------------------- /Resources/GfWLUtilityOld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/Resources/GfWLUtilityOld.png -------------------------------------------------------------------------------- /Resources/GfWLUtilityUnknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/Resources/GfWLUtilityUnknown.png -------------------------------------------------------------------------------- /Resources/WLIDOld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/Resources/WLIDOld.png -------------------------------------------------------------------------------- /Resources/WLIDUnknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/InvoxiPlayGames/GfWLUtility/bbd663b90f9fb7124986f59560e72192ba964d72/Resources/WLIDUnknown.png -------------------------------------------------------------------------------- /TitleManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Security.Cryptography; 8 | using System.Text; 9 | 10 | namespace GfWLUtility 11 | { 12 | internal class KnownTitle 13 | { 14 | public uint TitleID; 15 | public string Name; 16 | public string ProductKey; 17 | public byte[] ConfigData; 18 | public Bitmap Icon; 19 | 20 | public KnownTitle(uint titleID) 21 | { 22 | TitleID = titleID; 23 | } 24 | 25 | public override string ToString() 26 | { 27 | if (Name != null) 28 | return Name; 29 | return $"{TitleID:X8} (Unknown)"; 30 | } 31 | } 32 | 33 | internal class TitleManager 34 | { 35 | // list from XLiveLessNess 36 | // https://gitlab.com/GlitchyScripts/xlln-data/-/blob/main/XLiveLessNess/hub/titles.json?ref_type=heads 37 | public static Dictionary TitleNameDatabase = new Dictionary() 38 | { 39 | { 0x33390FA0, "7 Wonders 3" }, 40 | { 0x33390FA1, "Chainz 2: Relinked" }, 41 | { 0x35530FA0, "Cubis Gold" }, 42 | { 0x35530FA1, "Cubis Gold 2" }, 43 | { 0x35530FA2, "Ranch Rush 2" }, 44 | { 0x355A0FA0, "Mahjongg Dimensions" }, 45 | { 0x36590FA0, "TextTwist 2" }, 46 | { 0x36590FA1, "Super TextTwist" }, 47 | { 0x41560829, "007: Quantum of Solace" }, 48 | { 0x41560FA0, "Call of Duty 4" }, 49 | { 0x41560FA1, "Call of Duty: WaW" }, 50 | { 0x41560FA2, "Singularity" }, 51 | { 0x41560FA3, "Transformers: WFC" }, 52 | { 0x41560FA4, "Blur" }, 53 | { 0x41560FA5, "[PROTOTYPE]" }, 54 | { 0x41560FA6, "007: Blood Stone" }, 55 | { 0x415807D5, "BlazBlue: Calamity Trigger" }, 56 | { 0x425307D6, "Fallout 3" }, 57 | { 0x42530FA0, "Hunted Demon's Forge" }, 58 | { 0x425607F3, "TRON: Evolution" }, 59 | { 0x42560FA0, "LEGO Pirates of the Caribbean: The Video Game" }, 60 | { 0x434307DE, "Lost Planet: Extreme Condition: Colonies Edition" }, 61 | { 0x434307F4, "Street Fighter IV" }, 62 | { 0x434307F7, "Resident Evil 5" }, 63 | { 0x43430803, "Dark Void" }, 64 | { 0x43430808, "Lost Planet 2" }, 65 | { 0x4343080E, "Dead Rising 2" }, 66 | { 0x43430FA0, "Super Street Fighter IV: Arcade Edition" }, 67 | { 0x43430FA1, "Resident Evil: Operation Raccoon City" }, 68 | { 0x43430FA2, "Dead Rising 2: Off the Record" }, 69 | { 0x43430FA5, "Street Fighter X Tekken" }, 70 | { 0x434D0820, "DiRT 2" }, 71 | { 0x434D082F, "FUEL" }, 72 | { 0x434D0831, "F1 2010" }, 73 | { 0x434D083E, "Operation Flashpoint: Red River" }, 74 | { 0x434D0FA0, "DiRT 3" }, 75 | { 0x434D0FA1, "F1 2011" }, 76 | { 0x44540FA0, "Crash Time 4: The Syndicate" }, 77 | { 0x44540FA1, "Crash Time 4 Demo" }, 78 | { 0x4541091C, "Dragon Age: Awakening" }, 79 | { 0x4541091F, "Battlefield: Bad Co. 2" }, 80 | { 0x45410920, "Mass Effect 2" }, 81 | { 0x45410921, "Dragon Age: Origins" }, 82 | { 0x45410935, "Bulletstorm" }, 83 | { 0x45410FA1, "Medal of Honor" }, 84 | { 0x45410FA2, "Need for Speed SHIFT" }, 85 | { 0x45410FA3, "Dead Space 2" }, 86 | { 0x45410FA4, "Bulletstrom DEMO" }, 87 | { 0x45410FA5, "Dragon Age 2" }, 88 | { 0x45410FA8, "Crysis 2" }, 89 | { 0x45410FAB, "The Sims 3" }, 90 | { 0x45410FAC, "The Sims 3 Late Night" }, 91 | { 0x45410FAD, "The Sims 3 Ambitions" }, 92 | { 0x45410FAE, "World Adventures" }, 93 | { 0x45410FAF, "The Sims Medieval" }, 94 | { 0x45410FB1, "Darkspore" }, 95 | { 0x45410FB2, "NFS SHIFT 2 Unleashed" }, 96 | { 0x45410FB3, "Spore" }, 97 | { 0x45410FB4, "The Sims 3 Generations" }, 98 | { 0x45410FB5, "Alice: Madness Returns" }, 99 | { 0x45410FB6, "Harry Potter (DH2)" }, 100 | { 0x45410FB7, "The Sims Medieval Pirates & Nobles" }, 101 | { 0x45410FB8, "Tiger Woods PGA TOUR 12: The Masters" }, 102 | { 0x454D07D4, "Flatout Ultimate Carnage" }, 103 | { 0x46450FA0, "Divinity II - DKS" }, 104 | { 0x46450FA1, "Cities XL 2011" }, 105 | { 0x46450FA2, "The Next Big Thing" }, 106 | { 0x46450FA3, "Faery" }, 107 | { 0x46450FA4, "Pro Cycling Manager" }, 108 | { 0x46550FA0, "Jewel Quest 5" }, 109 | { 0x46550FA1, "Family Feud Dream Home" }, 110 | { 0x48450FA0, "AFL Live" }, 111 | { 0x48450FA1, "Rugby League Live 2" }, 112 | { 0x49470FA1, "Test Drive Ferrari Racing Legend" }, 113 | { 0x4B590FA0, "Tropico 3 Gold Edition" }, 114 | { 0x4B590FA1, "Patrician IV" }, 115 | { 0x4B590FA3, "Commandos Complete" }, 116 | { 0x4B590FA5, "Dungeons" }, 117 | { 0x4B590FA8, "Patrician: RoaD" }, 118 | { 0x4B590FA9, "Elements of War" }, 119 | { 0x4B590FAA, "The First Templar" }, 120 | { 0x4C4107EB, "Star Wars: The Clone Wars - Republic Heroes" }, 121 | { 0x4D5307D6, "Shadowrun" }, 122 | { 0x4D53080F, "Halo 2 Vista" }, 123 | { 0x4D530841, "Viva Piñata" }, 124 | { 0x4D530842, "Gears of War" }, 125 | { 0x4D5308D2, "Microsoft Flight" }, 126 | { 0x4D5308D3, "Firebird Project" }, 127 | { 0x4D530901, "Game Room" }, 128 | { 0x4D53090A, "Fable 3" }, 129 | { 0x4D530935, "Flight Simulator X" }, 130 | { 0x4D530936, "Age of Empires III" }, 131 | { 0x4D530937, "Fable: TLC" }, 132 | { 0x4D530942, "AoE Online - Beta" }, 133 | { 0x4D530FA0, "Zoo Tycoon 2" }, 134 | { 0x4D530FA2, "Toy Soldiers" }, 135 | { 0x4D530FA3, "Age of Empires Online" }, 136 | { 0x4D530FA4, "Toy Soldiers: Cold War" }, 137 | { 0x4D530FA5, "Ms. Splosion Man" }, 138 | { 0x4D530FA6, "Skulls of the Shogun" }, 139 | { 0x4D530FA7, "Insanely Twisted Shadow Planet" }, 140 | { 0x4D530FA8, "Iron Brigade" }, 141 | { 0x4D530FA9, "MGS Pinball FX2 GFWL Games For Windows Live" }, 142 | { 0x4D530FAA, "MGS Vodka PC" }, 143 | { 0x4D5388B0, "BugBash 2" }, 144 | { 0x4E4D0FA1, "Dark Souls: Prepare to Die Edition" }, 145 | { 0x4E4D0FA2, "ACE COMBAT ASSAULT HORIZON: Enhanced Edition" }, 146 | { 0x4E4E0FA0, "Trainz Simulator 2010" }, 147 | { 0x4E4E0FA1, "Settle and Carlisle" }, 148 | { 0x4E4E0FA2, "Classic Cabon City" }, 149 | { 0x4E4E0FA3, "TS 2010: Blue Comet" }, 150 | { 0x4E4E0FA4, "Trainz Simulator 12" }, 151 | { 0x4F420FA0, "BubbleTown" }, 152 | { 0x4F430FA0, "King's Bounty Platinum" }, 153 | { 0x50470FA1, "Bejeweled 2" }, 154 | { 0x50470FA3, "Bookworm" }, 155 | { 0x50470FA4, "Plants vs. Zombies" }, 156 | { 0x50470FA5, "Zuma's Revenge" }, 157 | { 0x50470FA6, "Bejeweled 3" }, 158 | { 0x50580FA0, "Europa Universalis III" }, 159 | { 0x50580FA1, "Hearts of Iron III" }, 160 | { 0x50580FA2, "King Arthur" }, 161 | { 0x50580FA3, "Mount & Blade Warband" }, 162 | { 0x50580FA4, "Victoria 2" }, 163 | { 0x50580FA6, "EU 3: Divine Wind" }, 164 | { 0x50580FA7, "EU3:Heir to the Throne" }, 165 | { 0x50580FA8, "King Arthur The Druids" }, 166 | { 0x50580FA9, "King Arthur The Saxons" }, 167 | { 0x50580FAB, "Cities in Motion" }, 168 | { 0x50580FAC, "Cities in Motion" }, 169 | { 0x50580FAD, "EU 3: Chronicles" }, 170 | { 0x50580FAE, "Darkest Hour" }, 171 | { 0x50580FAF, "MnB: With Fire & Sword" }, 172 | { 0x50580FB0, "King Arthur Collection" }, 173 | { 0x50580FB1, "Supreme Ruler Cold War" }, 174 | { 0x50580FB2, "Pirates of Black Cove" }, 175 | { 0x51320FA0, "Poker Superstars III" }, 176 | { 0x51320FA1, "Slingo Deluxe" }, 177 | { 0x534307EB, "Kane & Lynch: Dead Men" }, 178 | { 0x534307FA, "Battlestations: Pacific" }, 179 | { 0x534307FF, "Batman: Arkham Asylum" }, 180 | { 0x53430800, "Battlestations: Pacific" }, 181 | { 0x5343080C, "Batman: AA GOTY" }, 182 | { 0x53430813, "ChampionshipManager 10" }, 183 | { 0x53430814, "Tomb Raider Underworld" }, 184 | { 0x534507F0, "Universe at War: Earth Assault" }, 185 | { 0x534507F6, "The Club" }, 186 | { 0x53450826, "Stormrise" }, 187 | { 0x5345082C, "Vancouver 2010" }, 188 | { 0x53450849, "Alpha Protocol" }, 189 | { 0x5345084E, "Football Manager 2010" }, 190 | { 0x53450854, "Rome: Total War" }, 191 | { 0x53450FA0, "Football Manager 2011" }, 192 | { 0x53450FA1, "Dreamcast Collection" }, 193 | { 0x53450FA2, "Virtua Tennis 4" }, 194 | { 0x53460FA0, "A Vampyre Story" }, 195 | { 0x53460FA1, "Ankh 2" }, 196 | { 0x53460FA2, "Ankh 3" }, 197 | { 0x53460FA3, "Rise of Flight: ICE" }, 198 | { 0x535007E3, "Section 8" }, 199 | { 0x53510FA0, "Deus Ex: GotY" }, 200 | { 0x53510FA1, "Deus Ex: Invisible War" }, 201 | { 0x53510FA2, "Hitman: Blood Money" }, 202 | { 0x53510FA3, "Thief: Deadly Shadows" }, 203 | { 0x53510FA4, "Hitman 2: SA" }, 204 | { 0x53510FA5, "MINI NINJAS" }, 205 | { 0x53510FA6, "Tomb Raider:Legend" }, 206 | { 0x53510FA7, "Tomb Raider: Anniv." }, 207 | { 0x53510FA8, "Battlestations: Midway" }, 208 | { 0x53510FA9, "Conflict: Denied Ops" }, 209 | { 0x53510FAA, "Project: Snowblind" }, 210 | { 0x544707D4, "Section 8: Prejudice" }, 211 | { 0x5451081F, "Juiced 2: Hot Import Nights" }, 212 | { 0x5451082D, "Warhammer 40,000: Dawn of War 2: Chaos Rising" }, 213 | { 0x54510837, "Red Faction: Guerrilla" }, 214 | { 0x54510868, "DoW II: Chaos Rising" }, 215 | { 0x54510871, "Saints Row 2" }, 216 | { 0x54510872, "S.T.A.L.K.E.R." }, 217 | { 0x5451087F, "Dawn of War" }, 218 | { 0x54510880, "DoW - Dark Crusade" }, 219 | { 0x54510881, "Supreme Commander" }, 220 | { 0x54510882, "Supreme Commander: Forged Alliance" }, 221 | { 0x5454083B, "Grand Theft Auto IV" }, 222 | { 0x5454085C, "BioShock 2" }, 223 | { 0x5454086E, "GTA IV: EFLC" }, 224 | { 0x54540873, "Borderlands" }, 225 | { 0x54540874, "Civ IV: Complete" }, 226 | { 0x54540876, "GTA San Andreas" }, 227 | { 0x54540877, "GTA: Vice City" }, 228 | { 0x54540878, "Max Payne 2" }, 229 | { 0x54540879, "Max Payne" }, 230 | { 0x5454087B, "BioShock" }, 231 | { 0x54540880, "Bully Scholarship Ed." }, 232 | { 0x54540881, "Grand Theft Auto III" }, 233 | { 0x54590FA0, "RIFT" }, 234 | { 0x54590FA1, "RIFT CE" }, 235 | { 0x54590FA2, "RIFT AoH CE" }, 236 | { 0x554C0FA0, "4 Elements" }, 237 | { 0x554C0FA1, "Gardenscapes" }, 238 | { 0x554C0FA2, "Call of Atlantis" }, 239 | { 0x554C0FA3, "Around the World in 80" }, 240 | { 0x554C0FA4, "Fishdom: Spooky Splash" }, 241 | { 0x55530855, "Prince of Persia: TFS" }, 242 | { 0x55530856, "Assassin's Creed II" }, 243 | { 0x55530857, "SplinterCellConviction" }, 244 | { 0x55530859, "Prince of Persia: WW" }, 245 | { 0x5553085A, "Prince of Persia: SoT" }, 246 | { 0x5553085B, "The Settlers 7" }, 247 | { 0x5553085E, "Assassin's Creed" }, 248 | { 0x5553085F, "World In Conflict" }, 249 | { 0x55530860, "Dawn of Discovery Gold" }, 250 | { 0x55530861, "Prince of Persia" }, 251 | { 0x55530862, "TC's RainbowSix Vegas2" }, 252 | { 0x55530864, "GRAW 2" }, 253 | { 0x55530865, "Far Cry 2" }, 254 | { 0x55530866, "Silent Hunter 5" }, 255 | { 0x55530FA0, "Prince of Persia: TT" }, 256 | { 0x55530FA1, "Tom Clancy's H.A.W.X.2" }, 257 | { 0x55530FA2, "Shaun White Skate" }, 258 | { 0x55530FA3, "AC Brotherhood" }, 259 | { 0x55530FA4, "AC Brotherhood Deluxe" }, 260 | { 0x55530FA6, "From Dust" }, 261 | { 0x57520806, "F.E.A.R. 2" }, 262 | { 0x57520808, "LEGO Batman" }, 263 | { 0x57520809, "LEGO Harry Potter: Years 1-4" }, 264 | { 0x57520FA0, "Batman: Arkham City" }, 265 | { 0x57520FA1, "LEGO Universe" }, 266 | { 0x57520FA2, "Mortal Kombat Arcade Kollection" }, 267 | { 0x57520FA3, "Gotham City Impostors" }, 268 | { 0x584109EB, "Tinker" }, 269 | { 0x584109F0, "World of Goo" }, 270 | { 0x584109F1, "Mahjong Wisdom" }, 271 | { 0x58410A01, "Where's Waldo" }, 272 | { 0x58410A10, "Osmos" }, 273 | { 0x58410A1C, "Carneyvale Showtime" }, 274 | { 0x58410A6D, "Blacklight: Tango Down" }, 275 | { 0x585207D1, "XLive" }, 276 | { 0x5A450FA0, "Battle vs. Chess" }, 277 | { 0x5A450FA1, "Two Worlds II" }, 278 | { 0x5A500FA1, "Kona's Crate" } 279 | }; 280 | 281 | public static Dictionary KnownTitles = new Dictionary(); 282 | 283 | public static void FoundTitleExists(uint titleID) 284 | { 285 | if (!KnownTitles.ContainsKey(titleID)) 286 | KnownTitles[titleID] = new KnownTitle(titleID); 287 | if (TitleNameDatabase.ContainsKey(titleID)) 288 | KnownTitles[titleID].Name = TitleNameDatabase[titleID]; 289 | } 290 | 291 | public static void FoundTitleName(uint titleID, string name) 292 | { 293 | FoundTitleExists(titleID); 294 | KnownTitles[titleID].Name = name; 295 | } 296 | 297 | public static string GetTitleProductKey(uint titleID) 298 | { 299 | if (KnownTitles.ContainsKey(titleID)) 300 | { 301 | // if we already fetched the product key, don't try to fetch it again 302 | if (KnownTitles[titleID].ProductKey != null) 303 | return KnownTitles[titleID].ProductKey; 304 | 305 | string rawTokenPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 306 | $"Microsoft\\Xlive\\Titles\\{titleID:X8}\\Token.bin"); 307 | if (File.Exists(rawTokenPath)) { 308 | byte[] tokenBytes = File.ReadAllBytes(rawTokenPath); 309 | // first 32-bits are a size, we can ignore that 310 | byte[] rawTokenBytes = tokenBytes.Skip(4).ToArray(); 311 | // try to decrypt it, if we fail just assume the key is a dud 312 | try 313 | { 314 | byte[] unprotectedBytes = ProtectedData.Unprotect(rawTokenBytes, null, DataProtectionScope.CurrentUser); 315 | string productKey = Encoding.UTF8.GetString(unprotectedBytes); 316 | KnownTitles[titleID].ProductKey = productKey; 317 | return productKey; 318 | } catch (Exception e) 319 | { 320 | return null; 321 | } 322 | } 323 | } 324 | return null; 325 | } 326 | 327 | public static byte[] GetConfigSector(uint titleID, int sectorID) 328 | { 329 | if (KnownTitles.ContainsKey(titleID)) 330 | { 331 | string configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 332 | $"Microsoft\\Xlive\\Titles\\{titleID:X8}\\config.bin"); 333 | byte[] configData = null; 334 | if (KnownTitles[titleID].ConfigData == null) 335 | { 336 | if (File.Exists(configPath)) 337 | KnownTitles[titleID].ConfigData = File.ReadAllBytes(configPath); 338 | else 339 | return null; 340 | } 341 | configData = KnownTitles[titleID].ConfigData; 342 | 343 | int sectorStart = sectorID * 0x400; 344 | // make sure the sector isn't empty 345 | if (configData[sectorStart] != 0x00) 346 | { 347 | // copy it into a buffer and unprotect it 348 | byte[] sector = new byte[0x400]; 349 | Buffer.BlockCopy(configData, sectorStart, sector, 0, 0x400); 350 | // try to decrypt it, if we fail just assume the sector doesn't exist 351 | try 352 | { 353 | byte[] unprotectedSector = ProtectedData.Unprotect(sector, null, DataProtectionScope.CurrentUser); 354 | return unprotectedSector; 355 | } catch (Exception e) 356 | { 357 | return null; 358 | } 359 | } else 360 | { 361 | return null; 362 | } 363 | } 364 | return null; 365 | } 366 | 367 | public static void WriteConfigSector(uint titleID, int sectorID, byte[] data) 368 | { 369 | byte[] sector = new byte[0x1EC]; 370 | Buffer.BlockCopy(data, 0, sector, 0, data.Length); 371 | 372 | byte[] protectedSector = new byte[0x400]; 373 | byte[] protectedSectorBytes = ProtectedData.Protect(sector, null, DataProtectionScope.CurrentUser); 374 | Buffer.BlockCopy(protectedSectorBytes, 0, protectedSector, 0, protectedSectorBytes.Length); 375 | 376 | string configPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), 377 | $"Microsoft\\Xlive\\Titles\\{titleID:X8}\\config.bin"); 378 | byte[] configData = null; 379 | if (File.Exists(configPath)) 380 | configData = File.ReadAllBytes(configPath); 381 | else 382 | configData = new byte[0x5000]; 383 | Buffer.BlockCopy(protectedSector, 0, configData, sectorID * 0x400, protectedSector.Length); 384 | File.WriteAllBytes(configPath, configData); 385 | } 386 | } 387 | } 388 | -------------------------------------------------------------------------------- /UserManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace GfWLUtility 8 | { 9 | internal class KnownUser 10 | { 11 | public ulong XUID; 12 | public string Gamertag; 13 | public bool LiveEnabled; 14 | public ulong OnlineXUID; 15 | public Bitmap ProfilePicture; 16 | 17 | public KnownUser(ulong xuid) 18 | { 19 | XUID = xuid; 20 | } 21 | 22 | public override string ToString() 23 | { 24 | if (Gamertag != null) 25 | return Gamertag; 26 | return $"{XUID:X}"; 27 | } 28 | } 29 | 30 | internal class UserManager 31 | { 32 | public static Dictionary KnownUsers = new Dictionary(); 33 | 34 | public static void FoundUserExists(ulong xuid) 35 | { 36 | if (!KnownUsers.ContainsKey(xuid)) 37 | KnownUsers[xuid] = new KnownUser(xuid); 38 | } 39 | 40 | public static void FoundUserGamertag(ulong xuid, string name) 41 | { 42 | FoundUserExists(xuid); 43 | KnownUsers[xuid].Gamertag = name; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /UtilityFuncs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Runtime.InteropServices; 8 | using System.Text; 9 | 10 | namespace GfWLUtility 11 | { 12 | internal class UtilityFuncs 13 | { 14 | 15 | [DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto, EntryPoint = "SHDefExtractIcon")] 16 | public static extern int SHDefExtractIcon(string pszIconFile, int index, uint uFlags, ref IntPtr phiconLarge, ref IntPtr phiconSmall, uint nIconSize); 17 | 18 | public static string CensorString(string str, int start, int end, int min_length) 19 | { 20 | if (str == null || str.Length < min_length) return str; 21 | int x_fill = str.Length - start - end; 22 | return str.Substring(0, start) + new string('x', x_fill) + str.Substring(str.Length - end, end); 23 | } 24 | 25 | // https://stackoverflow.com/a/58779 26 | public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) 27 | { 28 | foreach (DirectoryInfo dir in source.GetDirectories()) 29 | CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); 30 | foreach (FileInfo file in source.GetFiles()) 31 | file.CopyTo(Path.Combine(target.FullName, file.Name)); 32 | } 33 | 34 | public static string BytesToString(double bytes, int round = 2) 35 | { 36 | if (bytes > Math.Pow(1000, 4)) return $"{Math.Round(bytes / Math.Pow(1000, 4), round)} TB"; 37 | if (bytes > Math.Pow(1000, 3)) return $"{Math.Round(bytes / Math.Pow(1000, 3), round)} GB"; 38 | if (bytes > Math.Pow(1000, 2)) return $"{Math.Round(bytes / Math.Pow(1000, 2), round)} MB"; 39 | if (bytes > Math.Pow(1000, 1)) return $"{Math.Round(bytes / Math.Pow(1000, 1), round)} KB"; 40 | return $"{bytes} B"; 41 | } 42 | 43 | public static int CountTrailingNulls(byte[] buf) 44 | { 45 | int i = buf.Length - 1; 46 | while (buf[i] == 0 && i > 0) 47 | --i; 48 | return i; 49 | } 50 | 51 | public static Bitmap Get48x48Icon(string exe_path) 52 | { 53 | // get the icon from the shell 54 | IntPtr hIconLarge = default; 55 | IntPtr hIconSmall = default; // ignored? 56 | if (SHDefExtractIcon(exe_path, 0, 0, ref hIconLarge, ref hIconSmall, 48) != 0) 57 | return null; 58 | 59 | // load the icon and convert it to a bitmap 60 | Icon largeIcon = Icon.FromHandle(hIconLarge); 61 | Bitmap largeBitmap = largeIcon.ToBitmap(); 62 | 63 | largeIcon.Dispose(); 64 | return largeBitmap; 65 | } 66 | 67 | public static string GetFormattedTitleID(uint titleID) 68 | { 69 | ushort gameNum = (ushort)(titleID & 0xFFFF); 70 | char publisher1 = (char)(titleID >> 24); 71 | char publisher2 = (char)((titleID >> 16) & 0xFF); 72 | return publisher1.ToString() + publisher2.ToString() + "-" + gameNum.ToString(); 73 | } 74 | 75 | public static Version GetProductVersion(string exe_path) 76 | { 77 | FileVersionInfo info = FileVersionInfo.GetVersionInfo(exe_path); 78 | if (info == null) return null; 79 | return new Version(info.ProductVersion); 80 | } 81 | 82 | public static bool IsWindowsModern() 83 | { 84 | // are we higher than Windows 8? 85 | return Environment.OSVersion.Version.CompareTo(new Version("6.2")) >= 0; 86 | } 87 | 88 | public static bool IsWindowsXP() 89 | { 90 | // are we lower than Windows Vista? 91 | return Environment.OSVersion.Version.CompareTo(new Version("6.0")) < 0; 92 | } 93 | 94 | [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)] 95 | [return: MarshalAs(UnmanagedType.Bool)] 96 | private static extern bool IsWow64Process([In] IntPtr hProcess, [Out] out bool wow64Process); 97 | 98 | public static bool IsWindows64Bit() 99 | { 100 | using (Process p = Process.GetCurrentProcess()) 101 | { 102 | bool retVal; 103 | if (!IsWow64Process(p.Handle, out retVal)) 104 | { 105 | return false; 106 | } 107 | return retVal; 108 | } 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 42 | 43 | 44 | --------------------------------------------------------------------------------