├── .gitignore ├── LICENSE ├── README.md ├── XISOExtractorGUI.sln └── XISOExtractorGUI ├── ETACalculator.cs ├── EndianConverter.cs ├── EventArg.cs ├── ExtractionResults.Designer.cs ├── ExtractionResults.cs ├── ExtractionResults.resx ├── FTPSettings.Designer.cs ├── FTPSettings.cs ├── FTPSettings.resx ├── FolderSelectDialog.cs ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs └── Resources.resx ├── SettingsManager.Designer.cs ├── SettingsManager.cs ├── SettingsManager.resx ├── SfvGenerator.cs ├── System.Net.FtpClient.dll ├── Utils.cs ├── XGD.ico ├── XISOExtractor.cs ├── XISOExtractorGUI.csproj ├── XISOFTP.cs ├── XISOStatus.cs ├── file.png └── folder.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Rr]elease/ 19 | x64/ 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.log 36 | *.vspscc 37 | *.vssscc 38 | .builds 39 | 40 | # Visual C++ cache files 41 | ipch/ 42 | *.aps 43 | *.ncb 44 | *.opensdf 45 | *.sdf 46 | 47 | # Visual Studio profiler 48 | *.psess 49 | *.vsp 50 | *.vspx 51 | 52 | # Guidance Automation Toolkit 53 | *.gpState 54 | 55 | # ReSharper is a .NET coding add-in 56 | _ReSharper* 57 | 58 | # NCrunch 59 | *.ncrunch* 60 | .*crunch*.local.xml 61 | 62 | # Installshield output folder 63 | [Ee]xpress 64 | 65 | # DocProject is a documentation generator add-in 66 | DocProject/buildhelp/ 67 | DocProject/Help/*.HxT 68 | DocProject/Help/*.HxC 69 | DocProject/Help/*.hhc 70 | DocProject/Help/*.hhk 71 | DocProject/Help/*.hhp 72 | DocProject/Help/Html2 73 | DocProject/Help/html 74 | 75 | # Click-Once directory 76 | publish 77 | 78 | # Publish Web Output 79 | *.Publish.xml 80 | 81 | # NuGet Packages Directory 82 | packages 83 | 84 | # Windows Azure Build Output 85 | csx 86 | *.build.csdef 87 | 88 | # Windows Store app package directory 89 | AppPackages/ 90 | 91 | # Others 92 | [Bb]in 93 | [Oo]bj 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | 104 | # Backup & report files from converting an old project file to a newer 105 | # Visual Studio version. Backup files are not needed, because we have git ;-) 106 | _UpgradeReport_Files/ 107 | Backup*/ 108 | UpgradeLog*.XML 109 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | XISOExtractorGUI 2 | ================ 3 | -------------------------------------------------------------------------------- /XISOExtractorGUI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.21005.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "XISOExtractorGUI", "XISOExtractorGUI\XISOExtractorGUI.csproj", "{554E5E9C-0808-4913-8BE9-1F9636119379}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release_NoFTP|Any CPU = Release_NoFTP|Any CPU 12 | Release|Any CPU = Release|Any CPU 13 | EndGlobalSection 14 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 15 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 16 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Debug|Any CPU.Build.0 = Debug|Any CPU 17 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Release_NoFTP|Any CPU.ActiveCfg = Release_NoFTP|Any CPU 18 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Release_NoFTP|Any CPU.Build.0 = Release_NoFTP|Any CPU 19 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {554E5E9C-0808-4913-8BE9-1F9636119379}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | GlobalSection(SolutionProperties) = preSolution 23 | HideSolutionNode = FALSE 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /XISOExtractorGUI/ETACalculator.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | 6 | public interface IEtaCalculator { 7 | TimeSpan ETR { get; } 8 | 9 | void Reset(); 10 | 11 | void Update(float progress); 12 | } 13 | 14 | public class EtaCalculator: IEtaCalculator { 15 | private readonly Queue> _queue = new Queue>(); 16 | private readonly Stopwatch _timer; 17 | private KeyValuePair _current; 18 | 19 | public EtaCalculator() { _timer = Stopwatch.StartNew(); } 20 | 21 | public void Reset() { 22 | _queue.Clear(); 23 | _timer.Reset(); 24 | _timer.Start(); 25 | } 26 | 27 | public void Update(float progress) { 28 | if(_current.Value == progress) 29 | return; 30 | var currentTicks = _timer.ElapsedTicks; 31 | _current = new KeyValuePair(currentTicks, progress); 32 | _queue.Enqueue(_current); 33 | if(_queue.Count > 10) 34 | _queue.Dequeue(); 35 | } 36 | 37 | public TimeSpan ETR { 38 | get { 39 | if(_queue.Count < 1) 40 | return TimeSpan.Zero; 41 | var oldest = _queue.Peek(); 42 | var current = _current; 43 | if(oldest.Value == current.Value) 44 | return TimeSpan.Zero; 45 | var finishedInTicks = (1.0d - current.Value) * (current.Key - oldest.Key) / (current.Value - oldest.Value); 46 | return TimeSpan.FromSeconds(finishedInTicks / Stopwatch.Frequency); 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/EndianConverter.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | 4 | static class EndianConverter 5 | { 6 | #region Byteswap Methods 7 | 8 | private static ushort Swap16(ushort input) { 9 | return (ushort) ((input & 0xFF00U) >> 8 | (input & 0x00FFU) << 8); 10 | } 11 | 12 | private static uint Swap32(uint input) { 13 | return 14 | (input & 0x000000FFU) << 24 | 15 | (input & 0x0000FF00U) << 8 | 16 | (input & 0x00FF0000U) >> 8 | 17 | (input & 0xFF000000U) >> 24; 18 | } 19 | 20 | private static ulong Swap64(ulong input) { 21 | return 22 | (input & 0x00000000000000FFU) >> 56 | 23 | (input & 0x000000000000FF00U) >> 40 | 24 | (input & 0x0000000000FF0000U) >> 24 | 25 | (input & 0x00000000FF000000U) >> 8 | 26 | (input & 0x000000FF00000000U) << 8 | 27 | (input & 0x0000FF0000000000U) << 24 | 28 | (input & 0x00FF000000000000U) << 40 | 29 | (input & 0xFF00000000000000U) << 56; 30 | } 31 | 32 | #endregion Byteswap Methods 33 | 34 | #region Little Endian 35 | 36 | internal static ushort Little16(ushort ret) { 37 | return !BitConverter.IsLittleEndian ? Swap16(ret) : ret; 38 | } 39 | 40 | internal static bool Little16(ref byte[] data, out ushort retval, int offset = 0) { 41 | retval = 0; 42 | if (data.Length < offset + 2) 43 | return false; 44 | retval = BitConverter.ToUInt16(data, offset); 45 | retval = Little16(retval); 46 | return true; 47 | } 48 | 49 | internal static bool Little16(byte[] data, out ushort retval, int offset = 0) { 50 | return Little16(ref data, out retval, offset); 51 | } 52 | 53 | internal static uint Little32(uint ret) { 54 | return !BitConverter.IsLittleEndian ? Swap32(ret) : ret; 55 | } 56 | 57 | internal static bool Little32(ref byte[] data, out uint retval, int offset = 0) { 58 | retval = 0; 59 | if (data.Length < offset + 4) 60 | return false; 61 | retval = BitConverter.ToUInt32(data, offset); 62 | retval = Little32(retval); 63 | return true; 64 | } 65 | 66 | internal static bool Little32(byte[] data, out uint retval, int offset = 0) { 67 | return Little32(ref data, out retval, offset); 68 | } 69 | 70 | internal static ulong Little64(ulong ret) { 71 | return !BitConverter.IsLittleEndian ? Swap64(ret) : ret; 72 | } 73 | 74 | internal static bool Little64(ref byte[] data, out ulong retval, int offset = 0) { 75 | retval = 0; 76 | if (data.Length < offset + 8) 77 | return false; 78 | retval = BitConverter.ToUInt64(data, offset); 79 | retval = Little64(retval); 80 | return true; 81 | } 82 | 83 | #endregion Little Endian 84 | 85 | #region Big Endian 86 | 87 | internal static ushort Big16(ushort ret) { 88 | return BitConverter.IsLittleEndian ? Swap16(ret) : ret; 89 | } 90 | 91 | internal static bool Big16(ref byte[] data, out ushort retval, int offset = 0) { 92 | retval = 0; 93 | if (data.Length < offset + 2) 94 | return false; 95 | retval = BitConverter.ToUInt16(data, offset); 96 | retval = Big16(retval); 97 | return true; 98 | } 99 | 100 | internal static uint Big32(uint ret) { 101 | return BitConverter.IsLittleEndian ? Swap32(ret) : ret; 102 | } 103 | 104 | internal static bool Big32(ref byte[] data, out uint retval, int offset = 0) { 105 | retval = 0; 106 | if (data.Length < offset + 4) 107 | return false; 108 | retval = BitConverter.ToUInt32(data, offset); 109 | retval = Big32(retval); 110 | return true; 111 | } 112 | 113 | internal static bool Big32(byte[] data, out uint retval, int offset = 0) 114 | { 115 | return Big32(ref data, out retval, offset); 116 | } 117 | 118 | internal static ulong Big64(ulong ret) { 119 | return BitConverter.IsLittleEndian ? Swap64(ret) : ret; 120 | } 121 | 122 | internal static bool Big64(ref byte[] data, out ulong retval, int offset = 0) { 123 | retval = 0; 124 | if (data.Length < offset + 8) 125 | return false; 126 | retval = BitConverter.ToUInt64(data, offset); 127 | retval = Big64(retval); 128 | return true; 129 | } 130 | 131 | internal static bool Big64(byte[] data, out ulong retval, int offset = 0) { 132 | return Big64(ref data, out retval, offset); 133 | } 134 | 135 | #endregion Big Endian 136 | 137 | } 138 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/EventArg.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | 4 | internal sealed class EventArg : EventArgs { 5 | public readonly T Data; 6 | 7 | public EventArg(T data) { Data = data; } 8 | } 9 | 10 | internal sealed class EventArg : EventArgs 11 | { 12 | public readonly T1 Data; 13 | public readonly T2 Data2; 14 | 15 | public EventArg(T1 data, T2 data2) 16 | { 17 | Data = data; 18 | Data2 = data2; 19 | } 20 | } 21 | 22 | internal sealed class EventArg : EventArgs { 23 | public readonly T1 Data; 24 | public readonly T2 Data2; 25 | public readonly T3 Data3; 26 | 27 | public EventArg(T1 data, T2 data2, T3 data3) { 28 | Data = data; 29 | Data2 = data2; 30 | Data3 = data3; 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/ExtractionResults.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | internal sealed partial class ExtractionResults 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.resultbox = new System.Windows.Forms.ListView(); 32 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 33 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 34 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 35 | this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 36 | this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 37 | this.SuspendLayout(); 38 | // 39 | // resultbox 40 | // 41 | this.resultbox.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 42 | this.columnHeader1, 43 | this.columnHeader2, 44 | this.columnHeader3, 45 | this.columnHeader4, 46 | this.columnHeader5}); 47 | this.resultbox.Dock = System.Windows.Forms.DockStyle.Fill; 48 | this.resultbox.FullRowSelect = true; 49 | this.resultbox.GridLines = true; 50 | this.resultbox.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; 51 | this.resultbox.Location = new System.Drawing.Point(0, 0); 52 | this.resultbox.MultiSelect = false; 53 | this.resultbox.Name = "resultbox"; 54 | this.resultbox.Size = new System.Drawing.Size(653, 147); 55 | this.resultbox.TabIndex = 0; 56 | this.resultbox.UseCompatibleStateImageBehavior = false; 57 | this.resultbox.View = System.Windows.Forms.View.Details; 58 | // 59 | // columnHeader1 60 | // 61 | this.columnHeader1.Text = "Result"; 62 | // 63 | // columnHeader2 64 | // 65 | this.columnHeader2.Text = "Source"; 66 | // 67 | // columnHeader3 68 | // 69 | this.columnHeader3.Text = "Target"; 70 | // 71 | // columnHeader4 72 | // 73 | this.columnHeader4.Text = "Options"; 74 | // 75 | // columnHeader5 76 | // 77 | this.columnHeader5.Text = "Error Message"; 78 | this.columnHeader5.Width = 99; 79 | // 80 | // ExtractionResults 81 | // 82 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 83 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 84 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 85 | this.ClientSize = new System.Drawing.Size(653, 147); 86 | this.Controls.Add(this.resultbox); 87 | this.Name = "ExtractionResults"; 88 | this.Text = "ExtractionResults"; 89 | this.ResumeLayout(false); 90 | 91 | } 92 | 93 | #endregion 94 | 95 | private System.Windows.Forms.ListView resultbox; 96 | private System.Windows.Forms.ColumnHeader columnHeader1; 97 | private System.Windows.Forms.ColumnHeader columnHeader2; 98 | private System.Windows.Forms.ColumnHeader columnHeader3; 99 | private System.Windows.Forms.ColumnHeader columnHeader4; 100 | private System.Windows.Forms.ColumnHeader columnHeader5; 101 | } 102 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/ExtractionResults.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Windows.Forms; 3 | 4 | namespace XISOExtractorGUI 5 | { 6 | internal sealed partial class ExtractionResults : Form 7 | { 8 | internal ExtractionResults() 9 | { 10 | InitializeComponent(); 11 | Icon = Program.Icon; 12 | } 13 | 14 | internal void Show(IEnumerable results) 15 | { 16 | foreach (var res in results) 17 | { 18 | var viewitem = res.Result ? new ListViewItem("OK") : new ListViewItem("FAILED"); 19 | viewitem.SubItems.Add(res.Source); 20 | viewitem.SubItems.Add(res.Target); 21 | viewitem.SubItems.Add(Program.GetOptString(res)); 22 | viewitem.SubItems.Add(!res.Result ? res.ErrorMsg : ""); 23 | resultbox.Items.Add(viewitem); 24 | } 25 | Show(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /XISOExtractorGUI/ExtractionResults.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 | -------------------------------------------------------------------------------- /XISOExtractorGUI/FTPSettings.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | internal sealed partial class FTPSettings 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.transmode = new System.Windows.Forms.GroupBox(); 32 | this.PORT = new System.Windows.Forms.RadioButton(); 33 | this.PASVEX = new System.Windows.Forms.RadioButton(); 34 | this.PASV = new System.Windows.Forms.RadioButton(); 35 | this.Connectbtn = new System.Windows.Forms.Button(); 36 | this.label1 = new System.Windows.Forms.Label(); 37 | this.hostbox = new System.Windows.Forms.TextBox(); 38 | this.userbox = new System.Windows.Forms.TextBox(); 39 | this.label2 = new System.Windows.Forms.Label(); 40 | this.label3 = new System.Windows.Forms.Label(); 41 | this.passbox = new System.Windows.Forms.TextBox(); 42 | this.treeView1 = new System.Windows.Forms.TreeView(); 43 | this.portbox = new System.Windows.Forms.NumericUpDown(); 44 | this.label4 = new System.Windows.Forms.Label(); 45 | this.savebtn = new System.Windows.Forms.Button(); 46 | this.label5 = new System.Windows.Forms.Label(); 47 | this.pathbox = new System.Windows.Forms.TextBox(); 48 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 49 | this.status = new System.Windows.Forms.ToolStripStatusLabel(); 50 | this.conworker = new System.ComponentModel.BackgroundWorker(); 51 | this.disconnectbtn = new System.Windows.Forms.Button(); 52 | this.transmode.SuspendLayout(); 53 | ((System.ComponentModel.ISupportInitialize)(this.portbox)).BeginInit(); 54 | this.statusStrip1.SuspendLayout(); 55 | this.SuspendLayout(); 56 | // 57 | // transmode 58 | // 59 | this.transmode.Controls.Add(this.PORT); 60 | this.transmode.Controls.Add(this.PASVEX); 61 | this.transmode.Controls.Add(this.PASV); 62 | this.transmode.Location = new System.Drawing.Point(12, 38); 63 | this.transmode.Name = "transmode"; 64 | this.transmode.Size = new System.Drawing.Size(130, 88); 65 | this.transmode.TabIndex = 0; 66 | this.transmode.TabStop = false; 67 | this.transmode.Text = "Transfer Mode"; 68 | // 69 | // PORT 70 | // 71 | this.PORT.AutoSize = true; 72 | this.PORT.Location = new System.Drawing.Point(6, 65); 73 | this.PORT.Name = "PORT"; 74 | this.PORT.Size = new System.Drawing.Size(55, 17); 75 | this.PORT.TabIndex = 0; 76 | this.PORT.Text = "Active"; 77 | this.PORT.UseVisualStyleBackColor = true; 78 | // 79 | // PASVEX 80 | // 81 | this.PASVEX.AutoSize = true; 82 | this.PASVEX.Checked = true; 83 | this.PASVEX.Location = new System.Drawing.Point(6, 19); 84 | this.PASVEX.Name = "PASVEX"; 85 | this.PASVEX.Size = new System.Drawing.Size(110, 17); 86 | this.PASVEX.TabIndex = 0; 87 | this.PASVEX.TabStop = true; 88 | this.PASVEX.Text = "Passive Extended"; 89 | this.PASVEX.UseVisualStyleBackColor = true; 90 | // 91 | // PASV 92 | // 93 | this.PASV.AutoSize = true; 94 | this.PASV.Location = new System.Drawing.Point(6, 42); 95 | this.PASV.Name = "PASV"; 96 | this.PASV.Size = new System.Drawing.Size(62, 17); 97 | this.PASV.TabIndex = 0; 98 | this.PASV.Text = "Passive"; 99 | this.PASV.UseVisualStyleBackColor = true; 100 | // 101 | // Connectbtn 102 | // 103 | this.Connectbtn.Enabled = false; 104 | this.Connectbtn.Location = new System.Drawing.Point(12, 132); 105 | this.Connectbtn.Name = "Connectbtn"; 106 | this.Connectbtn.Size = new System.Drawing.Size(130, 23); 107 | this.Connectbtn.TabIndex = 0; 108 | this.Connectbtn.Text = "Connect"; 109 | this.Connectbtn.UseVisualStyleBackColor = true; 110 | this.Connectbtn.Click += new System.EventHandler(this.ConnectbtnClick); 111 | // 112 | // label1 113 | // 114 | this.label1.AutoSize = true; 115 | this.label1.Location = new System.Drawing.Point(12, 164); 116 | this.label1.Name = "label1"; 117 | this.label1.Size = new System.Drawing.Size(32, 13); 118 | this.label1.TabIndex = 2; 119 | this.label1.Text = "Host:"; 120 | // 121 | // hostbox 122 | // 123 | this.hostbox.Location = new System.Drawing.Point(50, 161); 124 | this.hostbox.Name = "hostbox"; 125 | this.hostbox.Size = new System.Drawing.Size(92, 20); 126 | this.hostbox.TabIndex = 3; 127 | this.hostbox.TextChanged += new System.EventHandler(this.HostboxTextChanged); 128 | // 129 | // userbox 130 | // 131 | this.userbox.Location = new System.Drawing.Point(50, 188); 132 | this.userbox.Name = "userbox"; 133 | this.userbox.Size = new System.Drawing.Size(92, 20); 134 | this.userbox.TabIndex = 4; 135 | this.userbox.Text = "xbox"; 136 | // 137 | // label2 138 | // 139 | this.label2.AutoSize = true; 140 | this.label2.Location = new System.Drawing.Point(12, 191); 141 | this.label2.Name = "label2"; 142 | this.label2.Size = new System.Drawing.Size(32, 13); 143 | this.label2.TabIndex = 2; 144 | this.label2.Text = "User:"; 145 | // 146 | // label3 147 | // 148 | this.label3.AutoSize = true; 149 | this.label3.Location = new System.Drawing.Point(11, 217); 150 | this.label3.Name = "label3"; 151 | this.label3.Size = new System.Drawing.Size(33, 13); 152 | this.label3.TabIndex = 2; 153 | this.label3.Text = "Pass:"; 154 | // 155 | // passbox 156 | // 157 | this.passbox.Location = new System.Drawing.Point(50, 214); 158 | this.passbox.Name = "passbox"; 159 | this.passbox.Size = new System.Drawing.Size(92, 20); 160 | this.passbox.TabIndex = 4; 161 | this.passbox.Text = "xbox"; 162 | // 163 | // treeView1 164 | // 165 | this.treeView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 166 | | System.Windows.Forms.AnchorStyles.Left) 167 | | System.Windows.Forms.AnchorStyles.Right))); 168 | this.treeView1.Location = new System.Drawing.Point(148, 38); 169 | this.treeView1.Name = "treeView1"; 170 | this.treeView1.Size = new System.Drawing.Size(302, 251); 171 | this.treeView1.TabIndex = 5; 172 | this.treeView1.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.TreeView1MouseDoubleClick); 173 | this.treeView1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.TreeView1KeyPress); 174 | this.treeView1.KeyUp += new System.Windows.Forms.KeyEventHandler(this.TreeView1KeyUp); 175 | // 176 | // portbox 177 | // 178 | this.portbox.Location = new System.Drawing.Point(50, 240); 179 | this.portbox.Maximum = new decimal(new int[] { 180 | 65535, 181 | 0, 182 | 0, 183 | 0}); 184 | this.portbox.Minimum = new decimal(new int[] { 185 | 1, 186 | 0, 187 | 0, 188 | 0}); 189 | this.portbox.Name = "portbox"; 190 | this.portbox.Size = new System.Drawing.Size(92, 20); 191 | this.portbox.TabIndex = 6; 192 | this.portbox.Value = new decimal(new int[] { 193 | 21, 194 | 0, 195 | 0, 196 | 0}); 197 | // 198 | // label4 199 | // 200 | this.label4.AutoSize = true; 201 | this.label4.Location = new System.Drawing.Point(15, 242); 202 | this.label4.Name = "label4"; 203 | this.label4.Size = new System.Drawing.Size(29, 13); 204 | this.label4.TabIndex = 2; 205 | this.label4.Text = "Port:"; 206 | // 207 | // savebtn 208 | // 209 | this.savebtn.DialogResult = System.Windows.Forms.DialogResult.OK; 210 | this.savebtn.Location = new System.Drawing.Point(12, 266); 211 | this.savebtn.Name = "savebtn"; 212 | this.savebtn.Size = new System.Drawing.Size(130, 23); 213 | this.savebtn.TabIndex = 7; 214 | this.savebtn.Text = "Save Settings"; 215 | this.savebtn.UseVisualStyleBackColor = true; 216 | this.savebtn.Click += new System.EventHandler(this.SaveBtnClick); 217 | // 218 | // label5 219 | // 220 | this.label5.AutoSize = true; 221 | this.label5.Location = new System.Drawing.Point(12, 15); 222 | this.label5.Name = "label5"; 223 | this.label5.Size = new System.Drawing.Size(77, 13); 224 | this.label5.TabIndex = 8; 225 | this.label5.Text = "Selected Path:"; 226 | // 227 | // pathbox 228 | // 229 | this.pathbox.Location = new System.Drawing.Point(95, 12); 230 | this.pathbox.Name = "pathbox"; 231 | this.pathbox.Size = new System.Drawing.Size(355, 20); 232 | this.pathbox.TabIndex = 9; 233 | // 234 | // statusStrip1 235 | // 236 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 237 | this.status}); 238 | this.statusStrip1.Location = new System.Drawing.Point(0, 297); 239 | this.statusStrip1.Name = "statusStrip1"; 240 | this.statusStrip1.Size = new System.Drawing.Size(462, 22); 241 | this.statusStrip1.SizingGrip = false; 242 | this.statusStrip1.TabIndex = 10; 243 | this.statusStrip1.Text = "statusStrip1"; 244 | // 245 | // status 246 | // 247 | this.status.Name = "status"; 248 | this.status.Size = new System.Drawing.Size(131, 17); 249 | this.status.Text = "Waiting for user input..."; 250 | // 251 | // conworker 252 | // 253 | this.conworker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.ConworkerDoWork); 254 | this.conworker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.ConworkerRunWorkerCompleted); 255 | // 256 | // disconnectbtn 257 | // 258 | this.disconnectbtn.Enabled = false; 259 | this.disconnectbtn.Location = new System.Drawing.Point(12, 132); 260 | this.disconnectbtn.Name = "disconnectbtn"; 261 | this.disconnectbtn.Size = new System.Drawing.Size(130, 23); 262 | this.disconnectbtn.TabIndex = 11; 263 | this.disconnectbtn.Text = "Disconnect"; 264 | this.disconnectbtn.UseVisualStyleBackColor = true; 265 | this.disconnectbtn.Visible = false; 266 | this.disconnectbtn.Click += new System.EventHandler(this.DisconnectbtnClick); 267 | // 268 | // FTPSettings 269 | // 270 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 271 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 272 | this.ClientSize = new System.Drawing.Size(462, 319); 273 | this.Controls.Add(this.disconnectbtn); 274 | this.Controls.Add(this.statusStrip1); 275 | this.Controls.Add(this.pathbox); 276 | this.Controls.Add(this.label5); 277 | this.Controls.Add(this.savebtn); 278 | this.Controls.Add(this.portbox); 279 | this.Controls.Add(this.treeView1); 280 | this.Controls.Add(this.passbox); 281 | this.Controls.Add(this.userbox); 282 | this.Controls.Add(this.label4); 283 | this.Controls.Add(this.label3); 284 | this.Controls.Add(this.hostbox); 285 | this.Controls.Add(this.label2); 286 | this.Controls.Add(this.label1); 287 | this.Controls.Add(this.Connectbtn); 288 | this.Controls.Add(this.transmode); 289 | this.MaximizeBox = false; 290 | this.MinimizeBox = false; 291 | this.MinimumSize = new System.Drawing.Size(478, 357); 292 | this.Name = "FTPSettings"; 293 | this.Text = "FTPSettings"; 294 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FTPSettingsFormClosing); 295 | this.Load += new System.EventHandler(this.FTPSettingsLoad); 296 | this.transmode.ResumeLayout(false); 297 | this.transmode.PerformLayout(); 298 | ((System.ComponentModel.ISupportInitialize)(this.portbox)).EndInit(); 299 | this.statusStrip1.ResumeLayout(false); 300 | this.statusStrip1.PerformLayout(); 301 | this.ResumeLayout(false); 302 | this.PerformLayout(); 303 | 304 | } 305 | 306 | #endregion 307 | 308 | private System.Windows.Forms.GroupBox transmode; 309 | private System.Windows.Forms.RadioButton PASV; 310 | private System.Windows.Forms.RadioButton PORT; 311 | private System.Windows.Forms.RadioButton PASVEX; 312 | private System.Windows.Forms.Button Connectbtn; 313 | private System.Windows.Forms.Label label1; 314 | private System.Windows.Forms.TextBox hostbox; 315 | private System.Windows.Forms.TextBox userbox; 316 | private System.Windows.Forms.Label label2; 317 | private System.Windows.Forms.Label label3; 318 | private System.Windows.Forms.TextBox passbox; 319 | private System.Windows.Forms.TreeView treeView1; 320 | private System.Windows.Forms.NumericUpDown portbox; 321 | private System.Windows.Forms.Label label4; 322 | private System.Windows.Forms.Button savebtn; 323 | private System.Windows.Forms.Label label5; 324 | private System.Windows.Forms.TextBox pathbox; 325 | private System.Windows.Forms.StatusStrip statusStrip1; 326 | private System.Windows.Forms.ToolStripStatusLabel status; 327 | private System.ComponentModel.BackgroundWorker conworker; 328 | private System.Windows.Forms.Button disconnectbtn; 329 | } 330 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/FTPSettings.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | 3 | namespace XISOExtractorGUI 4 | { 5 | using System; 6 | using System.Collections.Generic; 7 | using System.ComponentModel; 8 | using System.Net.FtpClient; 9 | using XISOExtractorGUI.Properties; 10 | 11 | internal sealed partial class FTPSettings : Form { 12 | private static readonly ImageList Imglist = new ImageList(); 13 | delegate void SetNodeCallback(TreeNode node); 14 | delegate void SetNodeCallback2(TreeNode node, TreeNode src); 15 | 16 | private sealed class NodeListItem { 17 | public TreeNode Node; 18 | public string Src; 19 | } 20 | 21 | private sealed class FTPConnectionSettings 22 | { 23 | public string Host; 24 | public string User = "xbox"; 25 | public string Password = "xbox"; 26 | public int Port = 21; 27 | public FtpDataConnectionType DataConnectionType = FtpDataConnectionType.PASVEX; 28 | } 29 | 30 | public FTPSettings() { 31 | InitializeComponent(); 32 | Icon = Program.Icon; 33 | if (Imglist.Images.Empty) { 34 | Imglist.Images.Add("folder", Resources.folder); 35 | Imglist.Images.Add("file", Resources.file); 36 | } 37 | treeView1.ImageList = Imglist; 38 | } 39 | 40 | private FtpDataConnectionType GetConnectionType() { 41 | if (PASV.Checked) 42 | return FtpDataConnectionType.PASV; 43 | return PORT.Checked ? FtpDataConnectionType.PORT : FtpDataConnectionType.PASVEX; 44 | } 45 | 46 | private void SetState(bool state) { 47 | pathbox.Enabled = state; 48 | transmode.Enabled = state; 49 | hostbox.Enabled = state; 50 | userbox.Enabled = state; 51 | passbox.Enabled = state; 52 | portbox.Enabled = state; 53 | } 54 | 55 | private void ConnectbtnClick(object sender, EventArgs e) 56 | { 57 | Connectbtn.Enabled = false; 58 | SetState(false); 59 | status.Text = string.Format(Resources.ConnectingToOnPort, hostbox.Text, portbox.Value); 60 | conworker.RunWorkerAsync(new FTPConnectionSettings 61 | { 62 | Host = hostbox.Text, 63 | User = userbox.Text, 64 | Password = passbox.Text, 65 | Port = (int)portbox.Value, 66 | DataConnectionType = GetConnectionType() 67 | }); 68 | } 69 | 70 | private void AddList(string src = null, TreeNode node = null) { 71 | status.Text = src == null ? Resources.GettingRootDirInfoFTP : string.Format(Resources.GettingDirInfoFTP, src.Replace('\\', '/')); 72 | var bw = new BackgroundWorker(); 73 | bw.DoWork += BWOnDoWork; 74 | bw.RunWorkerCompleted += BWOnRunWorkerCompleted; 75 | bw.RunWorkerAsync(new NodeListItem{ Node = node, Src = src }); 76 | } 77 | 78 | private void BWOnRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) { 79 | status.Text = Resources.DoneWaitingForFurtherInstructions; 80 | if(runWorkerCompletedEventArgs.Result != null) 81 | MessageBox.Show(runWorkerCompletedEventArgs.Result.ToString()); 82 | } 83 | 84 | private void BWOnDoWork(object sender, DoWorkEventArgs e) { 85 | if (!(e.Argument is NodeListItem)) 86 | return; 87 | var src = e.Argument as NodeListItem; 88 | var list = new List(); 89 | if(!Xisoftp.GetDirListing(src.Src, ref list)) { 90 | e.Result = Xisoftp.LastError; 91 | return; 92 | } 93 | foreach (var ftpDirList in list) 94 | { 95 | var node = new TreeNode(ftpDirList.Name) 96 | { 97 | ImageKey = ftpDirList.IsDirectory ? "folder" : "file", 98 | SelectedImageKey = ftpDirList.IsDirectory ? "folder" : "file" 99 | }; 100 | switch (src.Src) 101 | { 102 | case null: 103 | AddNewNode(node); 104 | break; 105 | default: 106 | AddNewChildNode(node, src.Node); 107 | break; 108 | } 109 | } 110 | } 111 | 112 | private void AddNewNode(TreeNode node) { 113 | if (InvokeRequired) { 114 | SetNodeCallback d = AddNewNode; 115 | Invoke(d, new object[] { node }); 116 | } 117 | else if (!treeView1.Nodes.ContainsKey(node.Text)) 118 | treeView1.Nodes.Add(node); 119 | } 120 | 121 | private void AddNewChildNode(TreeNode node, TreeNode src) { 122 | if (InvokeRequired) 123 | { 124 | SetNodeCallback2 d = AddNewChildNode; 125 | Invoke(d, new object[] { node, src }); 126 | } 127 | else if (!src.Nodes.ContainsKey(node.Text)) 128 | src.Nodes.Add(node); 129 | } 130 | 131 | private void FTPSettingsLoad(object sender, EventArgs e) 132 | { 133 | hostbox.Text = Program.Form.FtpSettings.Host; 134 | userbox.Text = Program.Form.FtpSettings.User; 135 | passbox.Text = Program.Form.FtpSettings.Password; 136 | portbox.Value = Program.Form.FtpSettings.Port; 137 | pathbox.Text = Program.Form.FtpSettings.Path; 138 | switch (Program.Form.FtpSettings.DataConnectionType) 139 | { 140 | case FtpDataConnectionType.PASV: 141 | PASV.Checked = true; 142 | break; 143 | case FtpDataConnectionType.PORT: 144 | PORT.Checked = true; 145 | break; 146 | default: 147 | PASVEX.Checked = true; 148 | break; 149 | } 150 | } 151 | 152 | private void SaveBtnClick(object sender, EventArgs e) 153 | { 154 | Xisoftp.Disconnect(); 155 | Program.Form.FtpSettings.Host = hostbox.Text; 156 | Program.Form.FtpSettings.User = userbox.Text; 157 | Program.Form.FtpSettings.Password = passbox.Text; 158 | Program.Form.FtpSettings.Port = (int)portbox.Value; 159 | Program.Form.FtpSettings.DataConnectionType = GetConnectionType(); 160 | Program.Form.FtpSettings.Path = pathbox.Text; 161 | } 162 | 163 | private void HostboxTextChanged(object sender, EventArgs e) 164 | { 165 | Connectbtn.Enabled = hostbox.Text.Length > 0 && !Xisoftp.IsConnected; 166 | Connectbtn.Visible = hostbox.Text.Length > 0 && !Xisoftp.IsConnected; 167 | } 168 | 169 | private void ConworkerDoWork(object sender, DoWorkEventArgs e) 170 | { 171 | if (!(e.Argument is FTPConnectionSettings)) 172 | return; 173 | var settings = e.Argument as FTPConnectionSettings; 174 | e.Result = Xisoftp.Connect(settings.Host, settings.Port, settings.DataConnectionType, settings.User, settings.Password); 175 | } 176 | 177 | private void ConworkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 178 | { 179 | if (!(e.Result is Boolean)) 180 | return; 181 | if (!(bool)e.Result) 182 | { 183 | Connectbtn.Enabled = true; 184 | SetState(true); 185 | MessageBox.Show(Xisoftp.LastError); 186 | return; 187 | } 188 | treeView1.Nodes.Clear(); 189 | AddList(); 190 | SetState(true); 191 | disconnectbtn.Visible = true; 192 | disconnectbtn.Enabled = true; 193 | Connectbtn.Enabled = false; 194 | Connectbtn.Visible = false; 195 | } 196 | 197 | private void TreeView1MouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) 198 | { 199 | var node = treeView1.SelectedNode; 200 | if (node.GetNodeCount(false) != 0 || !node.ImageKey.Equals("folder")) 201 | return; 202 | pathbox.Text = string.Format("/{0}/", node.FullPath.Replace('\\', '/')); 203 | AddList("/" + node.FullPath, node); 204 | } 205 | 206 | private void TreeView1KeyPress(object sender, KeyPressEventArgs e) 207 | { 208 | if (treeView1.SelectedNode == null || e.KeyChar != (char)Keys.Return) 209 | return; 210 | TreeView1MouseDoubleClick(null, null); 211 | e.Handled = true; 212 | } 213 | 214 | private void TreeView1KeyUp(object sender, KeyEventArgs e) 215 | { 216 | if (treeView1.SelectedNode == null || e.KeyCode != Keys.Right) 217 | return; 218 | TreeView1MouseDoubleClick(null, null); 219 | e.Handled = true; 220 | } 221 | 222 | private void DisconnectbtnClick(object sender, EventArgs e) 223 | { 224 | Xisoftp.Disconnect(); 225 | HostboxTextChanged(null, null); 226 | disconnectbtn.Visible = false; 227 | disconnectbtn.Enabled = false; 228 | } 229 | 230 | private void FTPSettingsFormClosing(object sender, FormClosingEventArgs e) 231 | { 232 | e.Cancel = true; 233 | if (Xisoftp.IsConnected) 234 | Xisoftp.Disconnect(); 235 | e.Cancel = false; 236 | } 237 | } 238 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/FTPSettings.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 | 124 | 133, 17 125 | 126 | -------------------------------------------------------------------------------- /XISOExtractorGUI/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | using System; 4 | using System.Reflection; 5 | using System.Windows.Forms; 6 | 7 | internal sealed class FolderSelectDialog 8 | { 9 | readonly OpenFileDialog _ofd; 10 | const string DefaultFilter = "Folders|\n"; 11 | 12 | public FolderSelectDialog() 13 | { 14 | _ofd = new OpenFileDialog { 15 | Filter = DefaultFilter, 16 | AddExtension = false, 17 | CheckFileExists = false, 18 | DereferenceLinks = true, 19 | }; 20 | } 21 | 22 | #region Properties 23 | 24 | public string InitialDirectory 25 | { 26 | get { return _ofd.InitialDirectory; } 27 | set { _ofd.InitialDirectory = string.IsNullOrEmpty(value) ? Environment.CurrentDirectory : value; } 28 | } 29 | 30 | public string Title 31 | { 32 | get { return _ofd.Title; } 33 | set { _ofd.Title = value ?? "Select a folder"; } 34 | } 35 | 36 | public string FileName 37 | { 38 | get { return _ofd.FileName; } 39 | set { _ofd.FileName = value; } 40 | } 41 | 42 | #endregion 43 | 44 | #region Methods 45 | 46 | public bool ShowDialog() 47 | { 48 | return ShowDialog(IntPtr.Zero); 49 | } 50 | 51 | private bool ShowDialog(IntPtr hWndOwner) 52 | { 53 | bool flag; 54 | if (Environment.OSVersion.Version.Major >= 6) 55 | { 56 | var r = new Reflector("System.Windows.Forms"); 57 | 58 | uint num = 0; 59 | var typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 60 | var dialog = Reflector.Call(_ofd, "CreateVistaDialog"); 61 | Reflector.Call(_ofd, "OnBeforeVistaDialog", dialog); 62 | 63 | var options = (uint)Reflector.CallAs(typeof(FileDialog), _ofd, "GetOptions"); 64 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 65 | Reflector.CallAs(typeIFileDialog, dialog, "SetOptions", options); 66 | 67 | var pfde = r.New("FileDialog.VistaDialogEvents", _ofd); 68 | var parameters = new[] { pfde, num }; 69 | Reflector.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 70 | num = (uint)parameters[1]; 71 | try 72 | { 73 | var num2 = (int)Reflector.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 74 | flag = 0 == num2; 75 | } 76 | finally 77 | { 78 | Reflector.CallAs(typeIFileDialog, dialog, "Unadvise", num); 79 | GC.KeepAlive(pfde); 80 | } 81 | } 82 | else 83 | { 84 | var fbd = new FolderBrowserDialog { 85 | Description = Title, 86 | SelectedPath = InitialDirectory 87 | }; 88 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) 89 | return false; 90 | _ofd.FileName = fbd.SelectedPath; 91 | return true; 92 | } 93 | 94 | return flag; 95 | } 96 | 97 | #endregion 98 | } 99 | 100 | internal sealed class WindowWrapper : IWin32Window 101 | { 102 | internal WindowWrapper(IntPtr handle) { 103 | _hwnd = handle; 104 | } 105 | public IntPtr Handle { 106 | get { return _hwnd; } 107 | } 108 | 109 | private readonly IntPtr _hwnd; 110 | } 111 | 112 | internal sealed class Reflector 113 | { 114 | #region variables 115 | 116 | readonly string _mNs; 117 | readonly Assembly _mAsmb; 118 | 119 | #endregion 120 | 121 | #region Constructors 122 | 123 | public Reflector(string ns) 124 | : this(ns, ns) 125 | { } 126 | 127 | public Reflector(string an, string ns) 128 | { 129 | _mNs = ns; 130 | _mAsmb = null; 131 | foreach (var aN in Assembly.GetExecutingAssembly().GetReferencedAssemblies()) 132 | { 133 | if (!aN.FullName.StartsWith(an, StringComparison.Ordinal)) 134 | continue; 135 | _mAsmb = Assembly.Load(aN); 136 | break; 137 | } 138 | } 139 | 140 | #endregion 141 | 142 | #region Methods 143 | 144 | public Type GetType(string typeName) 145 | { 146 | Type type = null; 147 | var names = typeName.Split('.'); 148 | 149 | if (names.Length > 0) 150 | type = _mAsmb.GetType(_mNs + "." + names[0]); 151 | 152 | for (var i = 1; i < names.Length; ++i) { 153 | if (type != null) 154 | type = type.GetNestedType(names[i], BindingFlags.NonPublic); 155 | } 156 | return type; 157 | } 158 | 159 | public object New(string name, params object[] parameters) 160 | { 161 | var type = GetType(name); 162 | 163 | var ctorInfos = type.GetConstructors(); 164 | foreach (var ci in ctorInfos) { 165 | try { 166 | return ci.Invoke(parameters); 167 | } catch { } 168 | } 169 | 170 | return null; 171 | } 172 | 173 | public static object Call(object obj, string func, params object[] parameters) { 174 | return Call2(obj, func, parameters); 175 | } 176 | 177 | private static object Call2(object obj, string func, object[] parameters) { 178 | return CallAs2(obj.GetType(), obj, func, parameters); 179 | } 180 | 181 | public static object CallAs(Type type, object obj, string func, params object[] parameters) { 182 | return CallAs2(type, obj, func, parameters); 183 | } 184 | 185 | public static object CallAs2(Type type, object obj, string func, object[] parameters) { 186 | var methInfo = type.GetMethod(func, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); 187 | return methInfo.Invoke(obj, parameters); 188 | } 189 | 190 | public object GetEnum(string typeName, string name) { 191 | var type = GetType(typeName); 192 | var fieldInfo = type.GetField(name); 193 | return fieldInfo.GetValue(null); 194 | } 195 | 196 | #endregion 197 | 198 | } 199 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/MainForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | public sealed partial class MainForm 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.components = new System.ComponentModel.Container(); 32 | this.selsrcbtn = new System.Windows.Forms.Button(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.srcbox = new System.Windows.Forms.TextBox(); 35 | this.queview = new System.Windows.Forms.ListView(); 36 | this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 37 | this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 38 | this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 39 | this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); 40 | this.seltargetbtn = new System.Windows.Forms.Button(); 41 | this.label2 = new System.Windows.Forms.Label(); 42 | this.targetbox = new System.Windows.Forms.TextBox(); 43 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 44 | this.settingsbtn = new System.Windows.Forms.Button(); 45 | this.ftpbox = new System.Windows.Forms.CheckBox(); 46 | this.genfilelistbox = new System.Windows.Forms.CheckBox(); 47 | this.delIsobox = new System.Windows.Forms.CheckBox(); 48 | this.gensfvbox = new System.Windows.Forms.CheckBox(); 49 | this.skipsysbox = new System.Windows.Forms.CheckBox(); 50 | this.addbtn = new System.Windows.Forms.Button(); 51 | this.processbtn = new System.Windows.Forms.Button(); 52 | this.extractbtn = new System.Windows.Forms.Button(); 53 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 54 | this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel(); 55 | this.fileprogressbar = new System.Windows.Forms.ToolStripProgressBar(); 56 | this.speedlbl = new System.Windows.Forms.ToolStripStatusLabel(); 57 | this.operation = new System.Windows.Forms.ToolStripStatusLabel(); 58 | this.label3 = new System.Windows.Forms.Label(); 59 | this.isoprogressbar = new System.Windows.Forms.ProgressBar(); 60 | this.label4 = new System.Windows.Forms.Label(); 61 | this.queueprogressbar = new System.Windows.Forms.ProgressBar(); 62 | this.bw = new System.ComponentModel.BackgroundWorker(); 63 | this.ofd = new System.Windows.Forms.OpenFileDialog(); 64 | this.statusStrip2 = new System.Windows.Forms.StatusStrip(); 65 | this.etalabel = new System.Windows.Forms.ToolStripStatusLabel(); 66 | this.status = new System.Windows.Forms.ToolStripStatusLabel(); 67 | this.queueMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 68 | this.removeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 69 | this.abortbtn = new System.Windows.Forms.Button(); 70 | this.groupBox2 = new System.Windows.Forms.GroupBox(); 71 | this.logbox = new System.Windows.Forms.RichTextBox(); 72 | this.logMenu = new System.Windows.Forms.ContextMenuStrip(this.components); 73 | this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 74 | this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); 75 | this.gensfvbtn = new System.Windows.Forms.Button(); 76 | this.groupBox1.SuspendLayout(); 77 | this.statusStrip1.SuspendLayout(); 78 | this.statusStrip2.SuspendLayout(); 79 | this.queueMenu.SuspendLayout(); 80 | this.groupBox2.SuspendLayout(); 81 | this.logMenu.SuspendLayout(); 82 | this.SuspendLayout(); 83 | // 84 | // selsrcbtn 85 | // 86 | this.selsrcbtn.Location = new System.Drawing.Point(521, 15); 87 | this.selsrcbtn.Margin = new System.Windows.Forms.Padding(4); 88 | this.selsrcbtn.Name = "selsrcbtn"; 89 | this.selsrcbtn.Size = new System.Drawing.Size(41, 28); 90 | this.selsrcbtn.TabIndex = 0; 91 | this.selsrcbtn.Text = "..."; 92 | this.selsrcbtn.UseVisualStyleBackColor = true; 93 | this.selsrcbtn.Click += new System.EventHandler(this.SelsrcbtnClick); 94 | // 95 | // label1 96 | // 97 | this.label1.AutoSize = true; 98 | this.label1.Location = new System.Drawing.Point(16, 21); 99 | this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 100 | this.label1.Name = "label1"; 101 | this.label1.Size = new System.Drawing.Size(57, 17); 102 | this.label1.TabIndex = 1; 103 | this.label1.Text = "Source:"; 104 | // 105 | // srcbox 106 | // 107 | this.srcbox.Location = new System.Drawing.Point(83, 17); 108 | this.srcbox.Margin = new System.Windows.Forms.Padding(4); 109 | this.srcbox.Name = "srcbox"; 110 | this.srcbox.Size = new System.Drawing.Size(429, 22); 111 | this.srcbox.TabIndex = 0; 112 | this.srcbox.TextChanged += new System.EventHandler(this.SrcboxTextChanged); 113 | // 114 | // queview 115 | // 116 | this.queview.AllowDrop = true; 117 | this.queview.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 118 | | System.Windows.Forms.AnchorStyles.Right))); 119 | this.queview.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 120 | this.columnHeader4, 121 | this.columnHeader1, 122 | this.columnHeader2, 123 | this.columnHeader3}); 124 | this.queview.FullRowSelect = true; 125 | this.queview.GridLines = true; 126 | this.queview.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; 127 | this.queview.Location = new System.Drawing.Point(571, 15); 128 | this.queview.Margin = new System.Windows.Forms.Padding(4); 129 | this.queview.Name = "queview"; 130 | this.queview.ShowGroups = false; 131 | this.queview.Size = new System.Drawing.Size(523, 185); 132 | this.queview.TabIndex = 3; 133 | this.queview.UseCompatibleStateImageBehavior = false; 134 | this.queview.View = System.Windows.Forms.View.Details; 135 | this.queview.DragDrop += new System.Windows.Forms.DragEventHandler(this.queview_DragDrop); 136 | this.queview.DragEnter += new System.Windows.Forms.DragEventHandler(this.DoDragEnter); 137 | this.queview.MouseClick += new System.Windows.Forms.MouseEventHandler(this.QueviewMouseClick); 138 | // 139 | // columnHeader4 140 | // 141 | this.columnHeader4.Text = "ID"; 142 | this.columnHeader4.Width = 35; 143 | // 144 | // columnHeader1 145 | // 146 | this.columnHeader1.Text = "Source"; 147 | this.columnHeader1.Width = 103; 148 | // 149 | // columnHeader2 150 | // 151 | this.columnHeader2.Text = "Target"; 152 | this.columnHeader2.Width = 113; 153 | // 154 | // columnHeader3 155 | // 156 | this.columnHeader3.Text = "Options"; 157 | this.columnHeader3.Width = 135; 158 | // 159 | // seltargetbtn 160 | // 161 | this.seltargetbtn.Location = new System.Drawing.Point(521, 50); 162 | this.seltargetbtn.Margin = new System.Windows.Forms.Padding(4); 163 | this.seltargetbtn.Name = "seltargetbtn"; 164 | this.seltargetbtn.Size = new System.Drawing.Size(41, 28); 165 | this.seltargetbtn.TabIndex = 0; 166 | this.seltargetbtn.Text = "..."; 167 | this.seltargetbtn.UseVisualStyleBackColor = true; 168 | this.seltargetbtn.Click += new System.EventHandler(this.SeltargetbtnClick); 169 | // 170 | // label2 171 | // 172 | this.label2.AutoSize = true; 173 | this.label2.Location = new System.Drawing.Point(20, 57); 174 | this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 175 | this.label2.Name = "label2"; 176 | this.label2.Size = new System.Drawing.Size(54, 17); 177 | this.label2.TabIndex = 1; 178 | this.label2.Text = "Target:"; 179 | // 180 | // targetbox 181 | // 182 | this.targetbox.Location = new System.Drawing.Point(83, 53); 183 | this.targetbox.Margin = new System.Windows.Forms.Padding(4); 184 | this.targetbox.Name = "targetbox"; 185 | this.targetbox.Size = new System.Drawing.Size(429, 22); 186 | this.targetbox.TabIndex = 2; 187 | // 188 | // groupBox1 189 | // 190 | this.groupBox1.Controls.Add(this.settingsbtn); 191 | this.groupBox1.Controls.Add(this.ftpbox); 192 | this.groupBox1.Controls.Add(this.genfilelistbox); 193 | this.groupBox1.Controls.Add(this.delIsobox); 194 | this.groupBox1.Controls.Add(this.gensfvbox); 195 | this.groupBox1.Controls.Add(this.skipsysbox); 196 | this.groupBox1.Location = new System.Drawing.Point(16, 85); 197 | this.groupBox1.Margin = new System.Windows.Forms.Padding(4); 198 | this.groupBox1.Name = "groupBox1"; 199 | this.groupBox1.Padding = new System.Windows.Forms.Padding(4); 200 | this.groupBox1.Size = new System.Drawing.Size(547, 80); 201 | this.groupBox1.TabIndex = 4; 202 | this.groupBox1.TabStop = false; 203 | this.groupBox1.Text = "Options"; 204 | // 205 | // settingsbtn 206 | // 207 | this.settingsbtn.Location = new System.Drawing.Point(394, 45); 208 | this.settingsbtn.Name = "settingsbtn"; 209 | this.settingsbtn.Size = new System.Drawing.Size(147, 28); 210 | this.settingsbtn.TabIndex = 12; 211 | this.settingsbtn.Text = "Settings Manager"; 212 | this.settingsbtn.UseVisualStyleBackColor = true; 213 | this.settingsbtn.Click += new System.EventHandler(this.settingsbtn_Click); 214 | // 215 | // ftpbox 216 | // 217 | this.ftpbox.AutoSize = true; 218 | this.ftpbox.Location = new System.Drawing.Point(394, 23); 219 | this.ftpbox.Margin = new System.Windows.Forms.Padding(4); 220 | this.ftpbox.Name = "ftpbox"; 221 | this.ftpbox.Size = new System.Drawing.Size(85, 21); 222 | this.ftpbox.TabIndex = 11; 223 | this.ftpbox.Text = "Use FTP"; 224 | this.ftpbox.UseVisualStyleBackColor = true; 225 | // 226 | // genfilelistbox 227 | // 228 | this.genfilelistbox.AutoSize = true; 229 | this.genfilelistbox.Location = new System.Drawing.Point(183, 52); 230 | this.genfilelistbox.Margin = new System.Windows.Forms.Padding(4); 231 | this.genfilelistbox.Name = "genfilelistbox"; 232 | this.genfilelistbox.Size = new System.Drawing.Size(138, 21); 233 | this.genfilelistbox.TabIndex = 0; 234 | this.genfilelistbox.Text = "Generate FileList"; 235 | this.genfilelistbox.UseVisualStyleBackColor = true; 236 | // 237 | // delIsobox 238 | // 239 | this.delIsobox.AutoSize = true; 240 | this.delIsobox.Location = new System.Drawing.Point(183, 23); 241 | this.delIsobox.Margin = new System.Windows.Forms.Padding(4); 242 | this.delIsobox.Name = "delIsobox"; 243 | this.delIsobox.Size = new System.Drawing.Size(203, 21); 244 | this.delIsobox.TabIndex = 0; 245 | this.delIsobox.Text = "Delete ISO after completion"; 246 | this.delIsobox.UseVisualStyleBackColor = true; 247 | // 248 | // gensfvbox 249 | // 250 | this.gensfvbox.AutoSize = true; 251 | this.gensfvbox.Location = new System.Drawing.Point(8, 23); 252 | this.gensfvbox.Margin = new System.Windows.Forms.Padding(4); 253 | this.gensfvbox.Name = "gensfvbox"; 254 | this.gensfvbox.Size = new System.Drawing.Size(120, 21); 255 | this.gensfvbox.TabIndex = 0; 256 | this.gensfvbox.Text = "Generate SFV"; 257 | this.gensfvbox.UseVisualStyleBackColor = true; 258 | // 259 | // skipsysbox 260 | // 261 | this.skipsysbox.AutoSize = true; 262 | this.skipsysbox.Checked = true; 263 | this.skipsysbox.CheckState = System.Windows.Forms.CheckState.Checked; 264 | this.skipsysbox.Location = new System.Drawing.Point(8, 52); 265 | this.skipsysbox.Margin = new System.Windows.Forms.Padding(4); 266 | this.skipsysbox.Name = "skipsysbox"; 267 | this.skipsysbox.Size = new System.Drawing.Size(161, 21); 268 | this.skipsysbox.TabIndex = 0; 269 | this.skipsysbox.Text = "Skip $SystemUpdate"; 270 | this.skipsysbox.UseVisualStyleBackColor = true; 271 | // 272 | // addbtn 273 | // 274 | this.addbtn.Enabled = false; 275 | this.addbtn.Location = new System.Drawing.Point(16, 172); 276 | this.addbtn.Margin = new System.Windows.Forms.Padding(4); 277 | this.addbtn.Name = "addbtn"; 278 | this.addbtn.Size = new System.Drawing.Size(547, 28); 279 | this.addbtn.TabIndex = 5; 280 | this.addbtn.Text = "Add To Queue"; 281 | this.addbtn.UseVisualStyleBackColor = true; 282 | this.addbtn.Click += new System.EventHandler(this.AddbtnClick); 283 | // 284 | // processbtn 285 | // 286 | this.processbtn.Enabled = false; 287 | this.processbtn.Location = new System.Drawing.Point(16, 208); 288 | this.processbtn.Margin = new System.Windows.Forms.Padding(4); 289 | this.processbtn.Name = "processbtn"; 290 | this.processbtn.Size = new System.Drawing.Size(547, 28); 291 | this.processbtn.TabIndex = 5; 292 | this.processbtn.Text = "Process Queue"; 293 | this.processbtn.UseVisualStyleBackColor = true; 294 | this.processbtn.Click += new System.EventHandler(this.ProcessbtnClick); 295 | // 296 | // extractbtn 297 | // 298 | this.extractbtn.Enabled = false; 299 | this.extractbtn.Location = new System.Drawing.Point(16, 244); 300 | this.extractbtn.Margin = new System.Windows.Forms.Padding(4); 301 | this.extractbtn.Name = "extractbtn"; 302 | this.extractbtn.Size = new System.Drawing.Size(269, 28); 303 | this.extractbtn.TabIndex = 5; 304 | this.extractbtn.Text = "Just Extract"; 305 | this.extractbtn.UseVisualStyleBackColor = true; 306 | this.extractbtn.Click += new System.EventHandler(this.ExtractbtnClick); 307 | // 308 | // statusStrip1 309 | // 310 | this.statusStrip1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 311 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 312 | this.toolStripStatusLabel1, 313 | this.fileprogressbar, 314 | this.speedlbl, 315 | this.operation}); 316 | this.statusStrip1.Location = new System.Drawing.Point(0, 503); 317 | this.statusStrip1.Name = "statusStrip1"; 318 | this.statusStrip1.Padding = new System.Windows.Forms.Padding(1, 0, 19, 0); 319 | this.statusStrip1.Size = new System.Drawing.Size(1108, 26); 320 | this.statusStrip1.SizingGrip = false; 321 | this.statusStrip1.TabIndex = 6; 322 | this.statusStrip1.Text = "statusStrip1"; 323 | // 324 | // toolStripStatusLabel1 325 | // 326 | this.toolStripStatusLabel1.Name = "toolStripStatusLabel1"; 327 | this.toolStripStatusLabel1.Size = new System.Drawing.Size(95, 21); 328 | this.toolStripStatusLabel1.Text = "File Progress:"; 329 | // 330 | // fileprogressbar 331 | // 332 | this.fileprogressbar.Name = "fileprogressbar"; 333 | this.fileprogressbar.Size = new System.Drawing.Size(67, 20); 334 | // 335 | // speedlbl 336 | // 337 | this.speedlbl.Name = "speedlbl"; 338 | this.speedlbl.Size = new System.Drawing.Size(0, 21); 339 | // 340 | // operation 341 | // 342 | this.operation.Name = "operation"; 343 | this.operation.Size = new System.Drawing.Size(153, 21); 344 | this.operation.Text = "Waiting for user input"; 345 | // 346 | // label3 347 | // 348 | this.label3.AutoSize = true; 349 | this.label3.Location = new System.Drawing.Point(589, 214); 350 | this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 351 | this.label3.Name = "label3"; 352 | this.label3.Size = new System.Drawing.Size(96, 17); 353 | this.label3.TabIndex = 7; 354 | this.label3.Text = "ISO Progress:"; 355 | // 356 | // isoprogressbar 357 | // 358 | this.isoprogressbar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 359 | | System.Windows.Forms.AnchorStyles.Right))); 360 | this.isoprogressbar.Location = new System.Drawing.Point(693, 208); 361 | this.isoprogressbar.Margin = new System.Windows.Forms.Padding(4); 362 | this.isoprogressbar.Name = "isoprogressbar"; 363 | this.isoprogressbar.Size = new System.Drawing.Size(401, 28); 364 | this.isoprogressbar.TabIndex = 8; 365 | // 366 | // label4 367 | // 368 | this.label4.AutoSize = true; 369 | this.label4.Location = new System.Drawing.Point(571, 250); 370 | this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 371 | this.label4.Name = "label4"; 372 | this.label4.Size = new System.Drawing.Size(116, 17); 373 | this.label4.TabIndex = 7; 374 | this.label4.Text = "Queue Progress:"; 375 | // 376 | // queueprogressbar 377 | // 378 | this.queueprogressbar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 379 | | System.Windows.Forms.AnchorStyles.Right))); 380 | this.queueprogressbar.Location = new System.Drawing.Point(693, 244); 381 | this.queueprogressbar.Margin = new System.Windows.Forms.Padding(4); 382 | this.queueprogressbar.Name = "queueprogressbar"; 383 | this.queueprogressbar.Size = new System.Drawing.Size(401, 28); 384 | this.queueprogressbar.TabIndex = 8; 385 | // 386 | // ofd 387 | // 388 | this.ofd.DefaultExt = "iso"; 389 | this.ofd.FileName = "xiso.iso"; 390 | this.ofd.Filter = "Xbox ISO Files|*.iso|All Files|*.*"; 391 | this.ofd.Title = "Select XISO to Extract"; 392 | // 393 | // statusStrip2 394 | // 395 | this.statusStrip2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 396 | this.statusStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 397 | this.etalabel, 398 | this.status}); 399 | this.statusStrip2.Location = new System.Drawing.Point(0, 478); 400 | this.statusStrip2.Name = "statusStrip2"; 401 | this.statusStrip2.Padding = new System.Windows.Forms.Padding(1, 0, 19, 0); 402 | this.statusStrip2.Size = new System.Drawing.Size(1108, 25); 403 | this.statusStrip2.SizingGrip = false; 404 | this.statusStrip2.TabIndex = 9; 405 | this.statusStrip2.Text = "statusStrip2"; 406 | // 407 | // etalabel 408 | // 409 | this.etalabel.Name = "etalabel"; 410 | this.etalabel.Size = new System.Drawing.Size(0, 20); 411 | // 412 | // status 413 | // 414 | this.status.Name = "status"; 415 | this.status.Size = new System.Drawing.Size(153, 20); 416 | this.status.Text = "Waiting for user input"; 417 | // 418 | // queueMenu 419 | // 420 | this.queueMenu.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 421 | this.queueMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 422 | this.removeToolStripMenuItem}); 423 | this.queueMenu.Name = "queueMenu"; 424 | this.queueMenu.ShowImageMargin = false; 425 | this.queueMenu.Size = new System.Drawing.Size(151, 56); 426 | // 427 | // removeToolStripMenuItem 428 | // 429 | this.removeToolStripMenuItem.Name = "removeToolStripMenuItem"; 430 | this.removeToolStripMenuItem.Size = new System.Drawing.Size(107, 24); 431 | this.removeToolStripMenuItem.Text = "Remove"; 432 | this.removeToolStripMenuItem.Click += new System.EventHandler(this.RemoveQueueItem); 433 | // 434 | // abortbtn 435 | // 436 | this.abortbtn.Enabled = false; 437 | this.abortbtn.Location = new System.Drawing.Point(16, 172); 438 | this.abortbtn.Margin = new System.Windows.Forms.Padding(4); 439 | this.abortbtn.Name = "abortbtn"; 440 | this.abortbtn.Size = new System.Drawing.Size(347, 28); 441 | this.abortbtn.TabIndex = 10; 442 | this.abortbtn.Text = "Abort Operation"; 443 | this.abortbtn.UseVisualStyleBackColor = true; 444 | this.abortbtn.Visible = false; 445 | this.abortbtn.Click += new System.EventHandler(this.AbortOperation); 446 | // 447 | // groupBox2 448 | // 449 | this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 450 | | System.Windows.Forms.AnchorStyles.Left) 451 | | System.Windows.Forms.AnchorStyles.Right))); 452 | this.groupBox2.Controls.Add(this.logbox); 453 | this.groupBox2.Location = new System.Drawing.Point(12, 279); 454 | this.groupBox2.Name = "groupBox2"; 455 | this.groupBox2.Size = new System.Drawing.Size(1084, 196); 456 | this.groupBox2.TabIndex = 11; 457 | this.groupBox2.TabStop = false; 458 | this.groupBox2.Text = "Log"; 459 | // 460 | // logbox 461 | // 462 | this.logbox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 463 | | System.Windows.Forms.AnchorStyles.Left) 464 | | System.Windows.Forms.AnchorStyles.Right))); 465 | this.logbox.ContextMenuStrip = this.logMenu; 466 | this.logbox.Location = new System.Drawing.Point(3, 18); 467 | this.logbox.Name = "logbox"; 468 | this.logbox.ReadOnly = true; 469 | this.logbox.Size = new System.Drawing.Size(1078, 175); 470 | this.logbox.TabIndex = 0; 471 | this.logbox.Text = ""; 472 | // 473 | // logMenu 474 | // 475 | this.logMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 476 | this.saveToolStripMenuItem, 477 | this.clearToolStripMenuItem}); 478 | this.logMenu.Name = "contextMenuStrip1"; 479 | this.logMenu.Size = new System.Drawing.Size(113, 52); 480 | // 481 | // saveToolStripMenuItem 482 | // 483 | this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; 484 | this.saveToolStripMenuItem.Size = new System.Drawing.Size(112, 24); 485 | this.saveToolStripMenuItem.Text = "Save"; 486 | this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click); 487 | // 488 | // clearToolStripMenuItem 489 | // 490 | this.clearToolStripMenuItem.Name = "clearToolStripMenuItem"; 491 | this.clearToolStripMenuItem.Size = new System.Drawing.Size(112, 24); 492 | this.clearToolStripMenuItem.Text = "Clear"; 493 | this.clearToolStripMenuItem.Click += new System.EventHandler(this.clearToolStripMenuItem_Click); 494 | // 495 | // gensfvbtn 496 | // 497 | this.gensfvbtn.Enabled = false; 498 | this.gensfvbtn.Location = new System.Drawing.Point(294, 244); 499 | this.gensfvbtn.Margin = new System.Windows.Forms.Padding(4); 500 | this.gensfvbtn.Name = "gensfvbtn"; 501 | this.gensfvbtn.Size = new System.Drawing.Size(269, 28); 502 | this.gensfvbtn.TabIndex = 5; 503 | this.gensfvbtn.Text = "Just Generate SFV"; 504 | this.gensfvbtn.UseVisualStyleBackColor = true; 505 | this.gensfvbtn.Click += new System.EventHandler(this.gensfvbtn_Click); 506 | // 507 | // MainForm 508 | // 509 | this.AllowDrop = true; 510 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 511 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 512 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(224)))), ((int)(((byte)(224)))), ((int)(((byte)(224))))); 513 | this.ClientSize = new System.Drawing.Size(1108, 529); 514 | this.Controls.Add(this.groupBox2); 515 | this.Controls.Add(this.statusStrip2); 516 | this.Controls.Add(this.queueprogressbar); 517 | this.Controls.Add(this.label4); 518 | this.Controls.Add(this.isoprogressbar); 519 | this.Controls.Add(this.label3); 520 | this.Controls.Add(this.statusStrip1); 521 | this.Controls.Add(this.gensfvbtn); 522 | this.Controls.Add(this.extractbtn); 523 | this.Controls.Add(this.processbtn); 524 | this.Controls.Add(this.groupBox1); 525 | this.Controls.Add(this.queview); 526 | this.Controls.Add(this.targetbox); 527 | this.Controls.Add(this.srcbox); 528 | this.Controls.Add(this.label2); 529 | this.Controls.Add(this.label1); 530 | this.Controls.Add(this.seltargetbtn); 531 | this.Controls.Add(this.selsrcbtn); 532 | this.Controls.Add(this.addbtn); 533 | this.Controls.Add(this.abortbtn); 534 | this.Margin = new System.Windows.Forms.Padding(4); 535 | this.MinimumSize = new System.Drawing.Size(1126, 576); 536 | this.Name = "MainForm"; 537 | this.Text = "XISO Extractor GUI v{0}.{1} (Build: {2}) By Swizzy"; 538 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainFormFormClosing); 539 | this.DragDrop += new System.Windows.Forms.DragEventHandler(this.MainFormDragDrop); 540 | this.DragEnter += new System.Windows.Forms.DragEventHandler(this.DoDragEnter); 541 | this.groupBox1.ResumeLayout(false); 542 | this.groupBox1.PerformLayout(); 543 | this.statusStrip1.ResumeLayout(false); 544 | this.statusStrip1.PerformLayout(); 545 | this.statusStrip2.ResumeLayout(false); 546 | this.statusStrip2.PerformLayout(); 547 | this.queueMenu.ResumeLayout(false); 548 | this.groupBox2.ResumeLayout(false); 549 | this.logMenu.ResumeLayout(false); 550 | this.ResumeLayout(false); 551 | this.PerformLayout(); 552 | 553 | } 554 | 555 | #endregion 556 | 557 | private System.Windows.Forms.Button selsrcbtn; 558 | private System.Windows.Forms.Label label1; 559 | private System.Windows.Forms.TextBox srcbox; 560 | private System.Windows.Forms.ListView queview; 561 | private System.Windows.Forms.ColumnHeader columnHeader1; 562 | private System.Windows.Forms.ColumnHeader columnHeader2; 563 | private System.Windows.Forms.ColumnHeader columnHeader3; 564 | private System.Windows.Forms.Button seltargetbtn; 565 | private System.Windows.Forms.Label label2; 566 | private System.Windows.Forms.TextBox targetbox; 567 | private System.Windows.Forms.GroupBox groupBox1; 568 | private System.Windows.Forms.ColumnHeader columnHeader4; 569 | private System.Windows.Forms.Button addbtn; 570 | private System.Windows.Forms.Button processbtn; 571 | private System.Windows.Forms.Button extractbtn; 572 | private System.Windows.Forms.StatusStrip statusStrip1; 573 | private System.Windows.Forms.ToolStripStatusLabel operation; 574 | private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1; 575 | private System.Windows.Forms.ToolStripProgressBar fileprogressbar; 576 | private System.Windows.Forms.Label label3; 577 | private System.Windows.Forms.ProgressBar isoprogressbar; 578 | private System.Windows.Forms.Label label4; 579 | private System.Windows.Forms.ProgressBar queueprogressbar; 580 | private System.ComponentModel.BackgroundWorker bw; 581 | private System.Windows.Forms.OpenFileDialog ofd; 582 | private System.Windows.Forms.StatusStrip statusStrip2; 583 | private System.Windows.Forms.ToolStripStatusLabel status; 584 | private System.Windows.Forms.ContextMenuStrip queueMenu; 585 | private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; 586 | private System.Windows.Forms.Button abortbtn; 587 | private System.Windows.Forms.GroupBox groupBox2; 588 | private System.Windows.Forms.RichTextBox logbox; 589 | private System.Windows.Forms.ContextMenuStrip logMenu; 590 | private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; 591 | private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; 592 | private System.Windows.Forms.ToolStripStatusLabel etalabel; 593 | private System.Windows.Forms.ToolStripStatusLabel speedlbl; 594 | private System.Windows.Forms.Button gensfvbtn; 595 | private System.Windows.Forms.Button settingsbtn; 596 | internal System.Windows.Forms.CheckBox genfilelistbox; 597 | internal System.Windows.Forms.CheckBox gensfvbox; 598 | internal System.Windows.Forms.CheckBox skipsysbox; 599 | internal System.Windows.Forms.CheckBox ftpbox; 600 | internal System.Windows.Forms.CheckBox delIsobox; 601 | } 602 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/MainForm.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.Globalization; 8 | using System.IO; 9 | using System.Reflection; 10 | using System.Threading; 11 | using System.Windows.Forms; 12 | using XISOExtractorGUI.Properties; 13 | using Timer = System.Windows.Forms.Timer; 14 | 15 | public sealed partial class MainForm: Form { 16 | internal readonly Xisoftp.FTPSettingsData FtpSettings = new Xisoftp.FTPSettingsData(); 17 | private readonly EtaCalculator _eta = new EtaCalculator(); 18 | private readonly Dictionary _queDict = new Dictionary(); 19 | private readonly SettingsManager _settingsManager; 20 | private int _id; 21 | private long _processedData; 22 | private Stopwatch _sw; 23 | 24 | internal MainForm(IList args) { 25 | _settingsManager = new SettingsManager(this); 26 | InitializeComponent(); 27 | Icon = Program.Icon; 28 | var ver = Assembly.GetExecutingAssembly().GetName().Version; 29 | Text = string.Format(Text, ver.Major, ver.Minor, ver.Build); 30 | XisoExtractor.FileProgress += XisoExtractorFileProgress; 31 | XisoExtractor.IsoProgress += XisoExtractorTotalProgress; 32 | XisoExtractor.Operation += XisoExtractorOnOperation; 33 | XisoExtractor.Status += XisoExtractorOnStatus; 34 | XisoExtractor.TotalProgress += XisoExtractorQueueProgress; 35 | var speedtimer = new Timer 36 | { 37 | Interval = 1000, 38 | Enabled = true 39 | }; 40 | speedtimer.Tick += (sender, eventArgs) => { 41 | speedlbl.Text = GetSpeed(); 42 | if(queueprogressbar.Value == queueprogressbar.Minimum) 43 | _eta.Update((float)isoprogressbar.Value / isoprogressbar.Maximum); 44 | else 45 | _eta.Update((float)queueprogressbar.Value / queueprogressbar.Maximum); 46 | UpdateTimeLeft(); 47 | }; 48 | var percenttimer = new Timer 49 | { 50 | Interval = 20, 51 | Enabled = true 52 | }; 53 | percenttimer.Tick += (sender, eventArgs) => { 54 | UpdateProgressText(ref isoprogressbar); 55 | UpdateProgressText(ref queueprogressbar); 56 | }; 57 | ResetButtons(); 58 | var settings = Path.Combine(Path.GetDirectoryName(Assembly.GetAssembly(typeof(Program)).Location), "default.cfg"); 59 | if(File.Exists(settings)) 60 | _settingsManager.LoadSettings(settings); 61 | #if NOFTP 62 | ftpbox.Visible = false; 63 | #endif 64 | if(args.Count <= 0) 65 | return; 66 | srcbox.Text = args[0]; 67 | if(args.Count >= 2) 68 | targetbox.Text = args[1]; 69 | ExtractbtnClick(null, null); 70 | } 71 | 72 | private void XisoExtractorOnStatus(object sender, EventArg e) { 73 | if(InvokeRequired) { 74 | BeginInvoke(new EventHandler>(XisoExtractorOnStatus), new[] { 75 | sender, e 76 | }); 77 | return; 78 | } 79 | status.Text = e.Data; 80 | logbox.AppendText(DateTime.Now.ToString("HH:mm:ss ") + e.Data + Environment.NewLine); 81 | } 82 | 83 | private void XisoExtractorOnOperation(object sender, EventArg e) { 84 | if(InvokeRequired) { 85 | BeginInvoke(new EventHandler>(XisoExtractorOnOperation), new[] { 86 | sender, e 87 | }); 88 | return; 89 | } 90 | operation.Text = e.Data; 91 | //logbox.AppendText(DateTime.Now.ToString("HH:mm:ss ") + e.Data + Environment.NewLine); 92 | } 93 | 94 | private void XisoExtractorFileProgress(object sender, EventArg e) { 95 | if(InvokeRequired) { 96 | BeginInvoke(new EventHandler>(XisoExtractorFileProgress), new[] { 97 | sender, e 98 | }); 99 | return; 100 | } 101 | SetProgress(ref fileprogressbar, (int)e.Data); 102 | _processedData += e.Data2; 103 | } 104 | 105 | private string GetSpeed() { 106 | var proc = _processedData; 107 | _processedData = 0; 108 | if(!bw.IsBusy) 109 | return ""; 110 | return Utils.GetSizeReadable(proc) + "/s"; 111 | } 112 | 113 | private static void SetProgress(ref ProgressBar pbar, int value) { 114 | if(pbar == null) 115 | return; 116 | if(value > pbar.Maximum) 117 | value = pbar.Maximum; 118 | else if(value < pbar.Minimum) 119 | value = pbar.Minimum; 120 | pbar.Value = value; 121 | } 122 | 123 | private static void UpdateProgressText(ref ProgressBar pbar) { 124 | pbar.Refresh(); 125 | if(pbar.Value == pbar.Minimum || pbar.Value == pbar.Maximum) 126 | return; 127 | using(var gr = pbar.CreateGraphics()) { 128 | gr.DrawString(pbar.Value + "%", SystemFonts.DefaultFont, Brushes.Black, 129 | new PointF(pbar.Width / 2 - (gr.MeasureString(pbar.Value + "%", SystemFonts.DefaultFont).Width / 2.0F), 130 | pbar.Height / 2 - (gr.MeasureString(pbar.Value + "%", SystemFonts.DefaultFont).Height / 2.0F))); 131 | } 132 | } 133 | 134 | private static void SetProgress(ref ToolStripProgressBar pbar, int value) { 135 | if(pbar == null) 136 | return; 137 | if(value > pbar.Maximum) 138 | pbar.Value = pbar.Maximum; 139 | else if(value < pbar.Minimum) 140 | pbar.Value = pbar.Minimum; 141 | else 142 | pbar.Value = value; 143 | } 144 | 145 | private void XisoExtractorTotalProgress(object sender, EventArg e) { 146 | if(InvokeRequired) { 147 | BeginInvoke(new EventHandler>(XisoExtractorTotalProgress), new[] { 148 | sender, e 149 | }); 150 | return; 151 | } 152 | SetProgress(ref isoprogressbar, (int)e.Data); 153 | } 154 | 155 | private void XisoExtractorQueueProgress(object sender, EventArg e) { 156 | if(InvokeRequired) { 157 | BeginInvoke(new EventHandler>(XisoExtractorQueueProgress), new[] { 158 | sender, e 159 | }); 160 | return; 161 | } 162 | SetProgress(ref queueprogressbar, (int)e.Data); 163 | } 164 | 165 | private void UpdateTimeLeft() { 166 | if(!bw.IsBusy || _eta.ETR.TotalSeconds <= 1) { 167 | etalabel.Text = ""; 168 | return; 169 | } 170 | var ts = _eta.ETR; 171 | var label = "Time Left:"; 172 | if(ts.TotalHours >= 1) 173 | label += ts.TotalHours.ToString("F0") + " Hour(s)"; 174 | etalabel.Text = string.Format("{0} {1} Minute(s) {2} Second(s)", label, ts.Minutes, ts.Seconds); 175 | } 176 | 177 | private void SeltargetbtnClick(object sender, EventArgs e) { 178 | #if !NOFTP 179 | if(!ftpbox.Checked) { 180 | #endif 181 | var sfd = new FolderSelectDialog { 182 | Title = "Select where to save the extracted data", 183 | InitialDirectory = "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}" 184 | }; 185 | if(!string.IsNullOrEmpty(srcbox.Text)) 186 | sfd.FileName = string.Format("{0}\\{1}", Path.GetDirectoryName(srcbox.Text), Path.GetFileNameWithoutExtension(srcbox.Text)); 187 | if(sfd.ShowDialog()) 188 | targetbox.Text = sfd.FileName; 189 | #if !NOFTP 190 | } 191 | else { 192 | var form = new FTPSettings(); 193 | if(form.ShowDialog() == DialogResult.OK) {} 194 | } 195 | #endif 196 | } 197 | 198 | private void SelsrcbtnClick(object sender, EventArgs e) { 199 | if(ofd.ShowDialog() != DialogResult.OK) 200 | return; 201 | srcbox.Text = ofd.FileName; 202 | ofd.FileName = Path.GetFileName(ofd.FileName); 203 | } 204 | 205 | private void ExtractbtnClick(object sender, EventArgs e) { 206 | SetBusyState(); 207 | bw.RunWorkerCompleted += SingleExtractCompleted; 208 | bw.DoWork += SingleExtractDoWork; 209 | _eta.Reset(); 210 | var bwargs = new BwArgs { 211 | Source = srcbox.Text, 212 | Target = targetbox.Text, 213 | SkipSystemUpdate = skipsysbox.Checked, 214 | GenerateFileList = genfilelistbox.Checked, 215 | DeleteIsoOnCompletion = delIsobox.Checked, 216 | UseFtp = ftpbox.Checked, 217 | FtpSettings = FtpSettings, 218 | GenerateSfv = gensfvbox.Checked 219 | }; 220 | 221 | if(bwargs.UseFtp && (bwargs.Target.IndexOf(':') > 0 || string.IsNullOrEmpty(bwargs.Target))) 222 | bwargs.Target = Path.GetFileNameWithoutExtension(srcbox.Text); 223 | bw.RunWorkerAsync(bwargs); 224 | } 225 | 226 | private void SetBusyState() { 227 | extractbtn.Enabled = false; 228 | processbtn.Enabled = false; 229 | addbtn.Visible = false; 230 | abortbtn.Visible = true; 231 | abortbtn.Enabled = true; 232 | AllowDrop = false; 233 | } 234 | 235 | private void AbortOperation(object sender, EventArgs eventArgs) { XisoExtractor.Abort = true; } 236 | 237 | private static void SingleExtractDoWork(object sender, DoWorkEventArgs e) { 238 | if(!(e.Argument is BwArgs)) { 239 | e.Cancel = true; 240 | return; 241 | } 242 | var args = e.Argument as BwArgs; 243 | e.Result = XisoExtractor.ExtractXiso(new XisoOptions { 244 | Source = args.Source, 245 | Target = args.Target, 246 | ExcludeSysUpdate = args.SkipSystemUpdate, 247 | GenerateFileList = args.GenerateFileList, 248 | GenerateSfv = args.GenerateSfv, 249 | UseFtp = args.UseFtp, 250 | FtpOpts = args.FtpSettings, 251 | DeleteIsoOnCompletion = args.DeleteIsoOnCompletion 252 | }); 253 | } 254 | 255 | private void SingleExtractCompleted(object sender, RunWorkerCompletedEventArgs e) { 256 | bw.RunWorkerCompleted -= SingleExtractCompleted; 257 | bw.DoWork -= SingleExtractDoWork; 258 | etalabel.Text = ""; 259 | ResetButtons(); 260 | } 261 | 262 | private void ResetButtons() { 263 | addbtn.Text = Resources.AddToQueueBtnText; 264 | addbtn.Visible = true; 265 | abortbtn.Visible = false; 266 | abortbtn.Size = addbtn.Size; 267 | SrcboxTextChanged(null, null); 268 | AllowDrop = true; 269 | } 270 | 271 | private void MainFormFormClosing(object sender, FormClosingEventArgs e) { 272 | e.Cancel = true; 273 | if(bw.IsBusy) { 274 | AbortOperation(sender, e); 275 | while(bw.IsBusy) { 276 | Thread.Sleep(100); 277 | Application.DoEvents(); 278 | } 279 | } 280 | #if !NOFTP 281 | if(Xisoftp.IsConnected) 282 | Xisoftp.Disconnect(); 283 | #endif 284 | e.Cancel = false; 285 | } 286 | 287 | private void SrcboxTextChanged(object sender, EventArgs e) { 288 | extractbtn.Enabled = (!string.IsNullOrEmpty(srcbox.Text) && File.Exists(srcbox.Text)); 289 | gensfvbtn.Enabled = extractbtn.Enabled; 290 | addbtn.Enabled = extractbtn.Enabled; 291 | } 292 | 293 | private void DoDragEnter(object sender, DragEventArgs e) { e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None; } 294 | 295 | private void MainFormDragDrop(object sender, DragEventArgs e) { 296 | var fileList = (string[])e.Data.GetData(DataFormats.FileDrop, false); 297 | foreach(var s in fileList) { 298 | if(!s.EndsWith(".iso", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".xiso", StringComparison.CurrentCultureIgnoreCase) && 299 | !s.EndsWith(".360", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".000", StringComparison.CurrentCultureIgnoreCase)) 300 | continue; 301 | srcbox.Text = s; 302 | return; 303 | } 304 | } 305 | 306 | private void AddbtnClick(object sender, EventArgs e) { AddQueueItem(true); } 307 | 308 | private void AddQueueItem(bool resetTarget) { 309 | if(string.IsNullOrEmpty(srcbox.Text)) 310 | return; 311 | var viewitem = new ListViewItem(_id.ToString(CultureInfo.InvariantCulture)); 312 | viewitem.SubItems.Add(srcbox.Text); 313 | var target = targetbox.Text; 314 | if(!resetTarget && !string.IsNullOrEmpty(target)) 315 | target = Path.Combine(target, Path.GetFileNameWithoutExtension(srcbox.Text)); 316 | if(string.IsNullOrEmpty(target) && !ftpbox.Checked) 317 | target = string.Format("{0}\\{1}", Path.GetDirectoryName(srcbox.Text), Path.GetFileNameWithoutExtension(srcbox.Text)); 318 | else if(target.IndexOf(':') > 0 || string.IsNullOrEmpty(target)) 319 | target = Path.GetFileNameWithoutExtension(srcbox.Text); 320 | viewitem.SubItems.Add(target); 321 | var queueitem = new BwArgs { 322 | Source = srcbox.Text, 323 | Target = target, 324 | SkipSystemUpdate = skipsysbox.Checked, 325 | GenerateFileList = genfilelistbox.Checked, 326 | UseFtp = ftpbox.Checked, 327 | FtpSettings = FtpSettings, 328 | GenerateSfv = gensfvbox.Checked, 329 | DeleteIsoOnCompletion = delIsobox.Checked 330 | }; 331 | var opt = Program.GetOptString(queueitem); 332 | viewitem.SubItems.Add(opt); 333 | queview.Items.Add(viewitem); 334 | _queDict.Add(_id, queueitem); 335 | _id++; 336 | 337 | if(resetTarget) 338 | targetbox.Text = ""; 339 | srcbox.Text = ""; 340 | processbtn.Enabled = true; 341 | } 342 | 343 | private void ProcessbtnClick(object sender, EventArgs e) { 344 | SetBusyState(); 345 | var list = new List(); 346 | foreach(var key in _queDict.Keys) 347 | list.Add(_queDict[key]); 348 | bw.DoWork += MultiExtractDoWork; 349 | bw.RunWorkerCompleted += MultiExtractCompleted; 350 | _eta.Reset(); 351 | bw.RunWorkerAsync(list); 352 | _queDict.Clear(); 353 | queview.Items.Clear(); 354 | } 355 | 356 | private void QueviewMouseClick(object sender, MouseEventArgs e) { 357 | if(e.Button != MouseButtons.Right || !queview.FocusedItem.Bounds.Contains(e.Location) || queview.SelectedItems.Count <= 0) 358 | return; 359 | queueMenu.Show(Cursor.Position); 360 | } 361 | 362 | private void RemoveQueueItem(object sender, EventArgs e) { 363 | foreach(ListViewItem entry in queview.SelectedItems) { 364 | int id; 365 | if(!int.TryParse(entry.SubItems[0].Text, out id)) 366 | continue; 367 | if(_queDict.ContainsKey(id)) 368 | _queDict.Remove(id); 369 | queview.Items.Remove(entry); 370 | } 371 | } 372 | 373 | private void MultiExtractDoWork(object sender, DoWorkEventArgs e) { 374 | var sw = new Stopwatch(); 375 | sw.Start(); 376 | if(!(e.Argument is List)) { 377 | e.Cancel = true; 378 | return; 379 | } 380 | var args = e.Argument as List; 381 | XisoExtractor.MultiSize = 0; 382 | var list = new XisoListAndSize[args.Count]; 383 | for(var i = 0; i < args.Count; i++) { 384 | if(XisoExtractor.Abort) 385 | return; 386 | BinaryReader br; 387 | XisoExtractor.UpdateStatus(string.Format("Getting information about {0}", args[i].Source)); 388 | args[i].Result = XisoExtractor.GetFileListAndSize(new XisoOptions { 389 | Source = args[i].Source, 390 | Target = args[i].Target, 391 | ExcludeSysUpdate = args[i].SkipSystemUpdate, 392 | GenerateFileList = args[i].GenerateFileList, 393 | GenerateSfv = args[i].GenerateSfv, 394 | UseFtp = args[i].UseFtp, 395 | FtpOpts = args[i].FtpSettings, 396 | DeleteIsoOnCompletion = args[i].DeleteIsoOnCompletion 397 | }, out list[i], out br); 398 | if(br != null) 399 | br.Close(); 400 | if(args[i].Result) 401 | XisoExtractor.MultiSize += list[i].Size; 402 | args[i].ErrorMsg = XisoExtractor.GetLastError(); 403 | GC.Collect(); 404 | } 405 | for(var i = 0; i < args.Count; i++) { 406 | if(XisoExtractor.Abort) 407 | return; 408 | if(!args[i].Result) 409 | continue; 410 | args[i].Result = XisoExtractor.ExtractXiso(new XisoOptions { 411 | Source = args[i].Source, 412 | Target = args[i].Target, 413 | ExcludeSysUpdate = args[i].SkipSystemUpdate, 414 | GenerateFileList = args[i].GenerateFileList, 415 | GenerateSfv = args[i].GenerateSfv, 416 | UseFtp = args[i].UseFtp, 417 | FtpOpts = args[i].FtpSettings, 418 | DeleteIsoOnCompletion = args[i].DeleteIsoOnCompletion 419 | }, list[i]); 420 | args[i].ErrorMsg = XisoExtractor.GetLastError(); 421 | } 422 | 423 | var failed = 0; 424 | foreach(var result in args) { 425 | if(!result.Result) 426 | failed++; 427 | } 428 | e.Result = failed == 0 ? (object)true : args; 429 | sw.Stop(); 430 | XisoExtractorOnOperation(null, new EventArg(string.Format("Completed Queue after {0:F0} Minute(s) and {1} Second(s)", sw.Elapsed.TotalMinutes, sw.Elapsed.Seconds))); 431 | XisoExtractorOnStatus(null, new EventArg(string.Format("Completed Queue after {0:F0} Minute(s) and {1} Second(s)", sw.Elapsed.TotalMinutes, sw.Elapsed.Seconds))); 432 | } 433 | 434 | private void MultiExtractCompleted(object sender, RunWorkerCompletedEventArgs e) { 435 | bw.DoWork -= MultiExtractDoWork; 436 | bw.RunWorkerCompleted -= MultiExtractCompleted; 437 | etalabel.Text = ""; 438 | ResetButtons(); 439 | if(XisoExtractor.Abort) { 440 | SetAbortState(); 441 | return; 442 | } 443 | if(!(e.Result is List) || MessageBox.Show(Resources.MultiExtractFailed, Resources.ExtractFailed, MessageBoxButtons.OKCancel, MessageBoxIcon.Error) != DialogResult.OK) 444 | return; 445 | var res = new ExtractionResults(); 446 | res.Show(e.Result as List); 447 | } 448 | 449 | private void SetAbortState() { 450 | SetProgress(ref fileprogressbar, fileprogressbar.Minimum); 451 | SetProgress(ref isoprogressbar, fileprogressbar.Minimum); 452 | SetProgress(ref queueprogressbar, fileprogressbar.Minimum); 453 | status.Text = Resources.OperationAbortedByUser; 454 | operation.Text = Resources.OperationAbortedByUser; 455 | logbox.AppendText(Resources.OperationAbortedByUser + Environment.NewLine); 456 | } 457 | 458 | private void queview_DragDrop(object sender, DragEventArgs e) { 459 | var fileList = (string[])e.Data.GetData(DataFormats.FileDrop, false); 460 | foreach(var s in fileList) { 461 | if(File.Exists(s)) { 462 | if(!s.EndsWith(".iso", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".xiso", StringComparison.CurrentCultureIgnoreCase) && 463 | !s.EndsWith(".360", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".000", StringComparison.CurrentCultureIgnoreCase)) 464 | continue; 465 | srcbox.Text = s; 466 | AddQueueItem(false); 467 | } 468 | else 469 | ScanDragDropMulti(s); 470 | } 471 | } 472 | 473 | private void ScanDragDropMulti(string dir) { 474 | foreach(var s in Directory.GetFiles(dir)) { 475 | if(!s.EndsWith(".iso", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".xiso", StringComparison.CurrentCultureIgnoreCase) && 476 | !s.EndsWith(".360", StringComparison.CurrentCultureIgnoreCase) && !s.EndsWith(".000", StringComparison.CurrentCultureIgnoreCase)) 477 | continue; 478 | srcbox.Text = s; 479 | AddQueueItem(false); 480 | } 481 | foreach(var s in Directory.GetDirectories(dir)) 482 | ScanDragDropMulti(s); 483 | } 484 | 485 | private void saveToolStripMenuItem_Click(object sender, EventArgs e) { 486 | var sfd = new SaveFileDialog(); 487 | if(sfd.ShowDialog() != DialogResult.OK) 488 | return; 489 | File.WriteAllLines(sfd.FileName, logbox.Lines); 490 | } 491 | 492 | private void clearToolStripMenuItem_Click(object sender, EventArgs e) { logbox.Text = ""; } 493 | 494 | private void gensfvbtn_Click(object sender, EventArgs e) { 495 | if(string.IsNullOrEmpty(srcbox.Text)) { 496 | MessageBox.Show("Select source first!"); 497 | return; 498 | } 499 | var sfd = new SaveFileDialog { 500 | FileName = "checksums.sfv", 501 | DefaultExt = "sfv", 502 | AddExtension = true 503 | }; 504 | if(sfd.ShowDialog() != DialogResult.OK) 505 | return; 506 | _sw = Stopwatch.StartNew(); 507 | bw.RunWorkerCompleted += SfvOnCompleted; 508 | bw.DoWork += SfvOnDoWork; 509 | bw.RunWorkerAsync(new XisoOptions { 510 | Source = srcbox.Text, 511 | Target = sfd.FileName, 512 | ExcludeSysUpdate = skipsysbox.Checked 513 | }); 514 | } 515 | 516 | private void SfvOnCompleted(object sender, RunWorkerCompletedEventArgs runWorkerCompletedEventArgs) { 517 | bw.DoWork -= SfvOnDoWork; 518 | bw.RunWorkerCompleted -= SfvOnCompleted; 519 | XisoExtractor.Abort = false; 520 | XisoExtractorOnStatus(null, new EventArg(string.Format("SFV Generation completed after {0} Minute(s) {1} Second(s)", _sw.Elapsed.Minutes, _sw.Elapsed.Seconds))); 521 | XisoExtractorOnOperation(null, new EventArg("SFV Generation completed")); 522 | } 523 | 524 | private void SfvOnDoWork(object sender, DoWorkEventArgs doWorkEventArgs) { 525 | var opts = doWorkEventArgs.Argument as XisoOptions; 526 | if(opts == null) 527 | return; 528 | var sfvgen = new SfvGenerator(opts.Target); 529 | BinaryReader br = null; 530 | try { 531 | XisoListAndSize xisoEntries; 532 | XisoExtractor.UpdateStatus(string.Format("Generating SFV for {0}", opts.Source)); 533 | if(!XisoExtractor.GetFileListAndSize(opts, out xisoEntries, out br)) 534 | return; 535 | long totalDone = 0; 536 | XisoExtractor.UpdateOperation("Generating SFV CRC32 values..."); 537 | foreach(var entry in xisoEntries.List) { 538 | if(!entry.IsFile) 539 | continue; 540 | XisoExtractor.UpdateStatus(string.Format("Calculating CRC32 for: {0}{1} ({2})", entry.Path, entry.Name, Utils.GetSizeReadable(entry.Size))); 541 | br.BaseStream.Seek(entry.Offset, SeekOrigin.Begin); 542 | var left = entry.Size; 543 | uint crc = 0; 544 | while(left > 0) { 545 | if(XisoExtractor.Abort) 546 | return; 547 | var size = Utils.GetSmallest(0x4000, left); 548 | crc = SfvGenerator.Crc.ComputeChecksum(br.ReadBytes((int)size), crc); 549 | left -= size; 550 | totalDone += size; 551 | XisoExtractorFileProgress(null, new EventArg(Utils.GetPercentage(entry.Size - left, entry.Size), size)); 552 | XisoExtractorTotalProgress(null, new EventArg(Utils.GetPercentage(totalDone, xisoEntries.Size))); 553 | } 554 | sfvgen.AddFile(Path.Combine(entry.Path, entry.Name), crc); 555 | } 556 | sfvgen.Save(); 557 | } 558 | finally { 559 | if(br != null) 560 | br.Close(); 561 | } 562 | } 563 | 564 | private void settingsbtn_Click(object sender, EventArgs e) { _settingsManager.ShowDialog(); } 565 | } 566 | 567 | public sealed class BwArgs { 568 | internal bool DeleteIsoOnCompletion; 569 | internal string ErrorMsg; 570 | internal Xisoftp.FTPSettingsData FtpSettings; 571 | internal bool GenerateFileList; 572 | internal bool GenerateSfv; 573 | internal bool Result; 574 | internal bool SkipSystemUpdate; 575 | internal string Source; 576 | internal string Target; 577 | internal bool UseFtp; 578 | } 579 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/MainForm.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 | 124 | 133, 17 125 | 126 | 127 | 201, 17 128 | 129 | 130 | 271, 17 131 | 132 | 133 | 387, 17 134 | 135 | 136 | 522, 17 137 | 138 | -------------------------------------------------------------------------------- /XISOExtractorGUI/Program.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | using System; 4 | using System.Drawing; 5 | using System.IO; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | 9 | static class Program { 10 | internal static MainForm Form; 11 | internal static Icon Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); 12 | /// 13 | /// The main entry point for the application. 14 | /// 15 | [STAThread] 16 | static void Main(string[] args) 17 | { 18 | Application.EnableVisualStyles(); 19 | Application.SetCompatibleTextRenderingDefault(false); 20 | AppDomain.CurrentDomain.AssemblyResolve += CurrentDomainAssemblyResolve; 21 | AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; 22 | Form = new MainForm(args); 23 | Application.Run(Form); 24 | } 25 | 26 | private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs) { 27 | File.WriteAllText(string.Format("crash{0}.log", DateTime.Now), unhandledExceptionEventArgs.ExceptionObject.ToString()); 28 | } 29 | 30 | static Assembly CurrentDomainAssemblyResolve(object sender, ResolveEventArgs args) { 31 | if (string.IsNullOrEmpty(args.Name)) 32 | throw new Exception("DLL Read Failure (Nothing to load!)"); 33 | var name = string.Format("{0}.dll", args.Name.Split(',')[0]); 34 | using (var stream = Assembly.GetAssembly(typeof(Program)).GetManifestResourceStream(string.Format("{0}.{1}", typeof(Program).Namespace, name))) 35 | { 36 | if(stream == null) 37 | throw new Exception(string.Format("Can't find external nor internal {0}!", name)); 38 | var data = new byte[stream.Length]; 39 | stream.Read(data, 0, data.Length); 40 | return Assembly.Load(data); 41 | } 42 | } 43 | 44 | internal static string GetOptString(BwArgs args) 45 | { 46 | var opt = ""; 47 | if (args.SkipSystemUpdate) 48 | opt += "nosystemupdate=true "; 49 | if (args.GenerateFileList) 50 | opt += "genfilelist=true "; 51 | if (args.GenerateSfv) 52 | opt += "gensfv=true "; 53 | if(args.DeleteIsoOnCompletion) 54 | opt += "deleteisooncompletion=true "; 55 | if(args.UseFtp) { 56 | opt += "useftp=true"; 57 | opt += " ftphost=" + args.FtpSettings.Host; 58 | opt += " ftpport=" + args.FtpSettings.Port; 59 | opt += " ftpuser=" + args.FtpSettings.User; 60 | opt += " ftppass=" + args.FtpSettings.Password; 61 | opt += " ftppath=" + args.FtpSettings.Path; 62 | opt += " ftpmode=" + args.FtpSettings.DataConnectionType; 63 | } 64 | return opt.Trim(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /XISOExtractorGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("XISOExtractorGUI")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("XISOExtractorGUI")] 12 | [assembly: AssemblyCopyright("Copyright © 2013")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("51e4003e-2f06-4567-86fc-6933932f3160")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.152.0")] 35 | [assembly: AssemblyFileVersion("1.0.152.0")] 36 | -------------------------------------------------------------------------------- /XISOExtractorGUI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34014 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 XISOExtractorGUI.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", "4.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("XISOExtractorGUI.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 string similar to Abort. 65 | /// 66 | internal static string AbortBtnText { 67 | get { 68 | return ResourceManager.GetString("AbortBtnText", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Add To Queue. 74 | /// 75 | internal static string AddToQueueBtnText { 76 | get { 77 | return ResourceManager.GetString("AddToQueueBtnText", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to Connecting to {0} on port {1}. 83 | /// 84 | internal static string ConnectingToOnPort { 85 | get { 86 | return ResourceManager.GetString("ConnectingToOnPort", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to Process completed... waiting for further instructions.... 92 | /// 93 | internal static string DoneWaitingForFurtherInstructions { 94 | get { 95 | return ResourceManager.GetString("DoneWaitingForFurtherInstructions", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to ERROR: Unable to open 101 | ///{0} 102 | ///For read, if it's open in any other program close that and press Retry!. 103 | /// 104 | internal static string ErrorLoadingFileTryAgain { 105 | get { 106 | return ResourceManager.GetString("ErrorLoadingFileTryAgain", resourceCulture); 107 | } 108 | } 109 | 110 | /// 111 | /// Looks up a localized string similar to ERROR. 112 | /// 113 | internal static string ERRORTitle { 114 | get { 115 | return ResourceManager.GetString("ERRORTitle", resourceCulture); 116 | } 117 | } 118 | 119 | /// 120 | /// Looks up a localized string similar to Extraction failed. 121 | /// 122 | internal static string ExtractFailed { 123 | get { 124 | return ResourceManager.GetString("ExtractFailed", resourceCulture); 125 | } 126 | } 127 | 128 | /// 129 | /// Looks up a localized resource of type System.Drawing.Bitmap. 130 | /// 131 | internal static System.Drawing.Bitmap file { 132 | get { 133 | object obj = ResourceManager.GetObject("file", resourceCulture); 134 | return ((System.Drawing.Bitmap)(obj)); 135 | } 136 | } 137 | 138 | /// 139 | /// Looks up a localized resource of type System.Drawing.Bitmap. 140 | /// 141 | internal static System.Drawing.Bitmap folder { 142 | get { 143 | object obj = ResourceManager.GetObject("folder", resourceCulture); 144 | return ((System.Drawing.Bitmap)(obj)); 145 | } 146 | } 147 | 148 | /// 149 | /// Looks up a localized string similar to FTP Transfer ERROR. 150 | /// 151 | internal static string FTPTransferErrorTitle { 152 | get { 153 | return ResourceManager.GetString("FTPTransferErrorTitle", resourceCulture); 154 | } 155 | } 156 | 157 | /// 158 | /// Looks up a localized string similar to Getting Directory information from: {0}. 159 | /// 160 | internal static string GettingDirInfoFTP { 161 | get { 162 | return ResourceManager.GetString("GettingDirInfoFTP", resourceCulture); 163 | } 164 | } 165 | 166 | /// 167 | /// Looks up a localized string similar to Getting Root directory information.... 168 | /// 169 | internal static string GettingRootDirInfoFTP { 170 | get { 171 | return ResourceManager.GetString("GettingRootDirInfoFTP", resourceCulture); 172 | } 173 | } 174 | 175 | /// 176 | /// Looks up a localized string similar to One or more extractions failed! Press Ok to get a list of the results.... 177 | /// 178 | internal static string MultiExtractFailed { 179 | get { 180 | return ResourceManager.GetString("MultiExtractFailed", resourceCulture); 181 | } 182 | } 183 | 184 | /// 185 | /// Looks up a localized string similar to Operation aborted by user!. 186 | /// 187 | internal static string OperationAbortedByUser { 188 | get { 189 | return ResourceManager.GetString("OperationAbortedByUser", resourceCulture); 190 | } 191 | } 192 | 193 | /// 194 | /// Looks up a localized string similar to There was an error while transfering {0}: 195 | ///{1}. 196 | /// 197 | internal static string XISOFTPTransferError { 198 | get { 199 | return ResourceManager.GetString("XISOFTPTransferError", resourceCulture); 200 | } 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /XISOExtractorGUI/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 | Add To Queue 122 | 123 | 124 | Abort 125 | 126 | 127 | One or more extractions failed! Press Ok to get a list of the results... 128 | 129 | 130 | Extraction failed 131 | 132 | 133 | Operation aborted by user! 134 | 135 | 136 | ERROR 137 | 138 | 139 | ERROR: Unable to open 140 | {0} 141 | For read, if it's open in any other program close that and press Retry! 142 | 143 | 144 | There was an error while transfering {0}: 145 | {1} 146 | 147 | 148 | FTP Transfer ERROR 149 | 150 | 151 | 152 | ..\file.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | ..\folder.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | Getting Root directory information... 159 | 160 | 161 | Getting Directory information from: {0} 162 | 163 | 164 | Connecting to {0} on port {1} 165 | 166 | 167 | Process completed... waiting for further instructions... 168 | 169 | -------------------------------------------------------------------------------- /XISOExtractorGUI/SettingsManager.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | partial class SettingsManager 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.savebtn = new System.Windows.Forms.Button(); 32 | this.defaultsbtn = new System.Windows.Forms.Button(); 33 | this.loadbtn = new System.Windows.Forms.Button(); 34 | this.SuspendLayout(); 35 | // 36 | // savebtn 37 | // 38 | this.savebtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 39 | this.savebtn.Location = new System.Drawing.Point(12, 12); 40 | this.savebtn.Name = "savebtn"; 41 | this.savebtn.Size = new System.Drawing.Size(154, 74); 42 | this.savebtn.TabIndex = 0; 43 | this.savebtn.Text = "Save Settings"; 44 | this.savebtn.UseVisualStyleBackColor = true; 45 | this.savebtn.Click += new System.EventHandler(this.savebtn_Click); 46 | // 47 | // defaultsbtn 48 | // 49 | this.defaultsbtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 50 | this.defaultsbtn.Location = new System.Drawing.Point(172, 12); 51 | this.defaultsbtn.Name = "defaultsbtn"; 52 | this.defaultsbtn.Size = new System.Drawing.Size(154, 74); 53 | this.defaultsbtn.TabIndex = 0; 54 | this.defaultsbtn.Text = "Defaults"; 55 | this.defaultsbtn.UseVisualStyleBackColor = true; 56 | this.defaultsbtn.Click += new System.EventHandler(this.defaultsbtn_Click); 57 | // 58 | // loadbtn 59 | // 60 | this.loadbtn.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 61 | this.loadbtn.Location = new System.Drawing.Point(332, 12); 62 | this.loadbtn.Name = "loadbtn"; 63 | this.loadbtn.Size = new System.Drawing.Size(154, 74); 64 | this.loadbtn.TabIndex = 0; 65 | this.loadbtn.Text = "Load Settings"; 66 | this.loadbtn.UseVisualStyleBackColor = true; 67 | this.loadbtn.Click += new System.EventHandler(this.loadbtn_Click); 68 | // 69 | // SettingsManager 70 | // 71 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 72 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 73 | this.ClientSize = new System.Drawing.Size(498, 98); 74 | this.Controls.Add(this.loadbtn); 75 | this.Controls.Add(this.defaultsbtn); 76 | this.Controls.Add(this.savebtn); 77 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 78 | this.Name = "SettingsManager"; 79 | this.Text = "SettingsManager"; 80 | this.ResumeLayout(false); 81 | 82 | } 83 | 84 | #endregion 85 | 86 | private System.Windows.Forms.Button savebtn; 87 | private System.Windows.Forms.Button defaultsbtn; 88 | private System.Windows.Forms.Button loadbtn; 89 | } 90 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/SettingsManager.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.Globalization; 4 | using System.IO; 5 | using System.Net.FtpClient; 6 | using System.Reflection; 7 | using System.Windows.Forms; 8 | using System.Xml; 9 | 10 | public partial class SettingsManager: Form { 11 | private readonly MainForm _mainfrm; 12 | 13 | public SettingsManager(MainForm mainForm) { 14 | InitializeComponent(); 15 | _mainfrm = mainForm; 16 | } 17 | 18 | private void savebtn_Click(object sender, EventArgs e) { 19 | var sfd = new SaveFileDialog { 20 | FileName = "default.cfg", 21 | DefaultExt = "cfg", 22 | AddExtension = true, 23 | Title = @"Select where to save your settings", 24 | InitialDirectory = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Program)).Location) 25 | }; 26 | if(sfd.ShowDialog() != DialogResult.OK) 27 | return; 28 | SaveSettings(sfd.FileName); 29 | Close(); 30 | } 31 | 32 | private void loadbtn_Click(object sender, EventArgs e) { 33 | var ofd = new OpenFileDialog { 34 | FileName = "default.cfg", 35 | DefaultExt = "cfg", 36 | AddExtension = true, 37 | Title = @"Select settings to load", 38 | InitialDirectory = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Program)).Location) 39 | }; 40 | if(ofd.ShowDialog() != DialogResult.OK) 41 | return; 42 | LoadSettings(ofd.FileName); 43 | Close(); 44 | } 45 | 46 | private void defaultsbtn_Click(object sender, EventArgs e) { 47 | _mainfrm.skipsysbox.Checked = true; 48 | _mainfrm.delIsobox.Checked = false; 49 | _mainfrm.ftpbox.Checked = false; 50 | _mainfrm.genfilelistbox.Checked = false; 51 | _mainfrm.gensfvbox.Checked = false; 52 | _mainfrm.FtpSettings.DataConnectionType = FtpDataConnectionType.PASVEX; 53 | _mainfrm.FtpSettings.Host = ""; 54 | _mainfrm.FtpSettings.Password = "xbox"; 55 | _mainfrm.FtpSettings.Port = 21; 56 | _mainfrm.FtpSettings.User = "xbox"; 57 | Close(); 58 | } 59 | 60 | private void SaveSettings(string file) { 61 | using(var xml = XmlWriter.Create(file, new XmlWriterSettings { 62 | Indent = true, 63 | CloseOutput = true 64 | })) { 65 | xml.WriteStartDocument(); 66 | xml.WriteStartElement("root"); 67 | xml.WriteElementString("skipsystemupdate", _mainfrm.skipsysbox.Checked.ToString()); 68 | xml.WriteElementString("deleteiso", _mainfrm.delIsobox.Checked.ToString()); 69 | xml.WriteElementString("generatefilelist", _mainfrm.genfilelistbox.Checked.ToString()); 70 | xml.WriteElementString("generatesfv", _mainfrm.gensfvbox.Checked.ToString()); 71 | xml.WriteElementString("useftp", _mainfrm.ftpbox.Checked.ToString()); 72 | xml.WriteElementString("ftpcontype", ((int)_mainfrm.FtpSettings.DataConnectionType).ToString("X")); 73 | xml.WriteElementString("ftphost", _mainfrm.FtpSettings.Host); 74 | xml.WriteElementString("ftpport", _mainfrm.FtpSettings.Port.ToString(CultureInfo.InvariantCulture)); 75 | xml.WriteElementString("ftpuser", _mainfrm.FtpSettings.User); 76 | xml.WriteElementString("ftppass", _mainfrm.FtpSettings.Password); 77 | xml.WriteEndElement(); 78 | xml.WriteEndDocument(); 79 | } 80 | } 81 | 82 | private static bool GetBool(XmlReader xml) { 83 | xml.Read(); 84 | return xml.Value.Equals("true", StringComparison.CurrentCultureIgnoreCase); 85 | } 86 | 87 | private static string GetString(XmlReader xml) { 88 | xml.Read(); 89 | return xml.Value; 90 | } 91 | 92 | private static int GetInt(XmlReader xml, int value, bool hex = false) { 93 | xml.Read(); 94 | int ret; 95 | if(hex) 96 | return int.TryParse(xml.Value, NumberStyles.HexNumber, null, out ret) ? ret : value; 97 | if(int.TryParse(xml.Value, out ret)) 98 | return ret; 99 | return int.TryParse(xml.Value, NumberStyles.HexNumber, null, out ret) ? ret : value; 100 | } 101 | 102 | private static FtpDataConnectionType GetConnectionType(XmlReader xml) { return (FtpDataConnectionType)GetInt(xml, (int)FtpDataConnectionType.PASVEX, true); } 103 | 104 | internal void LoadSettings(string file) { 105 | using(var xml = XmlReader.Create(file, new XmlReaderSettings { 106 | CloseInput = true 107 | })) { 108 | while(xml.Read()) { 109 | if(!xml.IsStartElement()) 110 | continue; 111 | switch(xml.Name.ToLower()) { 112 | case "skipsystemupdate": 113 | _mainfrm.skipsysbox.Checked = GetBool(xml); 114 | break; 115 | case "deleteiso": 116 | _mainfrm.delIsobox.Checked = GetBool(xml); 117 | break; 118 | case "generatefilelist": 119 | _mainfrm.genfilelistbox.Checked = GetBool(xml); 120 | break; 121 | case "generatesfv": 122 | _mainfrm.gensfvbox.Checked = GetBool(xml); 123 | break; 124 | case "useftp": 125 | _mainfrm.ftpbox.Checked = GetBool(xml); 126 | break; 127 | case "ftpcontype": 128 | _mainfrm.FtpSettings.DataConnectionType = GetConnectionType(xml); 129 | break; 130 | case "ftphost": 131 | _mainfrm.FtpSettings.Host = GetString(xml); 132 | break; 133 | case "ftpport": 134 | _mainfrm.FtpSettings.Port = GetInt(xml, 21); 135 | break; 136 | case "ftpuser": 137 | _mainfrm.FtpSettings.User = GetString(xml); 138 | break; 139 | case "ftppass": 140 | _mainfrm.FtpSettings.Password = GetString(xml); 141 | break; 142 | } 143 | } 144 | } 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/SettingsManager.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 | -------------------------------------------------------------------------------- /XISOExtractorGUI/SfvGenerator.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.IO; 4 | using System.Text; 5 | 6 | public class SfvGenerator { 7 | public static readonly Crc32 Crc = new Crc32(); 8 | private readonly string _file; 9 | private readonly StringBuilder _sb = new StringBuilder(); 10 | 11 | public SfvGenerator(string file) { _file = file; } 12 | 13 | ~SfvGenerator() { Save(); } 14 | 15 | public void Save() { File.WriteAllText(_file, _sb.ToString()); } 16 | 17 | public void AddFile(string name, uint crc) { _sb.AppendLine(string.Format("{0} {1:X8}", name.TrimStart('\\'), crc)); } 18 | 19 | public class Crc32 { 20 | private readonly uint[] _table; 21 | 22 | public Crc32() { 23 | const uint poly = 0xedb88320; 24 | _table = new uint[256]; 25 | for(uint i = 0; i < _table.Length; ++i) { 26 | var temp = i; 27 | for(var j = 8; j > 0; --j) { 28 | if((temp & 1) == 1) 29 | temp = (temp >> 1) ^ poly; 30 | else 31 | temp >>= 1; 32 | } 33 | _table[i] = temp; 34 | } 35 | } 36 | 37 | public uint ComputeChecksum(byte[] bytes, uint crc = 0) { 38 | crc = ~crc; 39 | for(var i = 0; i < bytes.Length; ++i) { 40 | var index = (byte)(((crc) & 0xff) ^ bytes[i]); 41 | crc = (crc >> 8) ^ _table[index]; 42 | } 43 | return ~crc; 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/System.Net.FtpClient.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Swizzy/XISOExtractorGUI/a5c9272b925d83eb3d2d5c757781295ea5840a9e/XISOExtractorGUI/System.Net.FtpClient.dll -------------------------------------------------------------------------------- /XISOExtractorGUI/Utils.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI 2 | { 3 | using System; 4 | using System.IO; 5 | 6 | static class Utils 7 | { 8 | public static uint GetSmallest(uint val1, uint val2) { 9 | return val1 < val2 ? val1 : val2; 10 | } 11 | 12 | public static long GetSmallest(long val1, long val2) { 13 | return val1 < val2 ? val1 : val2; 14 | } 15 | 16 | public static string GetSizeReadable(long i) { 17 | if (i >= 0x1000000000000000) // Exabyte 18 | return string.Format("{0:0.##} EB", (double)(i >> 50) / 1024); 19 | if (i >= 0x4000000000000) // Petabyte 20 | return string.Format("{0:0.##} PB", (double)(i >> 40) / 1024); 21 | if (i >= 0x10000000000) // Terabyte 22 | return string.Format("{0:0.##} TB", (double)(i >> 30) / 1024); 23 | if (i >= 0x40000000) // Gigabyte 24 | return string.Format("{0:0.##} GB", (double)(i >> 20) / 1024); 25 | if (i >= 0x100000) // Megabyte 26 | return string.Format("{0:0.##} MB", (double)(i >> 10) / 1024); 27 | return i >= 0x400 ? string.Format("{0:0.##} KB", (double)i / 1024) : string.Format("{0} B", i); 28 | } 29 | 30 | public static long GetTotalFreeSpace(string path) { 31 | foreach (var drive in DriveInfo.GetDrives()) 32 | if (drive.IsReady && drive.RootDirectory.FullName.Equals(Path.GetPathRoot(path), StringComparison.CurrentCultureIgnoreCase)) 33 | return drive.TotalFreeSpace; 34 | return -1; 35 | } 36 | 37 | public static double GetPercentage(long current, long max) { 38 | return ((double)current / max) * 100; 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /XISOExtractorGUI/XGD.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Swizzy/XISOExtractorGUI/a5c9272b925d83eb3d2d5c757781295ea5840a9e/XISOExtractorGUI/XGD.ico -------------------------------------------------------------------------------- /XISOExtractorGUI/XISOExtractor.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Text; 7 | 8 | internal static class XisoExtractor { 9 | private const uint ReadWriteBuffer = 0x200000; 10 | private static readonly Encoding Enc = Encoding.GetEncoding(1252); 11 | internal static bool Abort; 12 | private static long _baseOffset, _totalSize, _totalProcessed, _multiProcessed; 13 | internal static long MultiSize; 14 | private static int _errorlevel; 15 | 16 | static XisoExtractor() { 17 | Xisoftp.ProgressUpdate += (sender, arg) => { 18 | _totalProcessed += arg.Data; 19 | UpdateFileProgress(((double)arg.Data2 / arg.Data3) * 100, arg.Data); 20 | UpdateIsoProgress(((double)_totalProcessed / _totalSize) * 100); 21 | if(MultiSize <= 0) 22 | return; 23 | _multiProcessed += arg.Data; 24 | UpdateTotalProgress(((double)_multiProcessed / MultiSize) * 100); 25 | }; 26 | } 27 | 28 | internal static event EventHandler> Operation; 29 | 30 | internal static event EventHandler> Status; 31 | 32 | internal static event EventHandler> TotalProgress; 33 | 34 | internal static event EventHandler> IsoProgress; 35 | 36 | internal static event EventHandler> FileProgress; 37 | 38 | private static string GetErrorString(int error) { 39 | switch(error) { 40 | case 0: 41 | return ""; 42 | case -1: 43 | return "ERROR While verifying Xbox ISO: File to small for the type expected"; 44 | case -2: 45 | return "ERROR while verifying Xbox ISO: Not a valid Xbox ISO (could also be unsupported)"; 46 | case 1: 47 | return "ERROR while trying to get root sector offset: File to small"; 48 | case 2: 49 | return "ERROR while parsing root FS: File to small"; 50 | case 3: 51 | return "ERROR while parsing root FS: Invalid TOC Entry Detected"; 52 | case 4: 53 | return "ERROR while extracting: File to small"; 54 | case 5: 55 | return "ERROR while extracting: Not enough space on harddrive"; 56 | default: 57 | return "Unkown Error"; 58 | } 59 | } 60 | 61 | internal static string GetLastError() { return GetErrorString(_errorlevel); } 62 | 63 | internal static bool GetFileListAndSize(XisoOptions opts, out XisoListAndSize retval, out BinaryReader br) { 64 | Abort = false; 65 | if(opts.GenerateSfv) 66 | opts.SfvGen = new SfvGenerator(Path.Combine(Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)) + ".sfv"); 67 | retval = new XisoListAndSize(); 68 | br = null; 69 | _errorlevel = 1; 70 | if(!VerifyXiso(opts.Source)) 71 | return false; 72 | br = new BinaryReader(File.Open(opts.Source, FileMode.Open, FileAccess.Read, FileShare.Read)); 73 | if(!BinarySeek(ref br, ((_baseOffset + 32) * 2048) + 0x14, 8)) 74 | return false; 75 | var data = br.ReadBytes(8); 76 | UpdateOperation("Grabbing Root sector & offset..."); 77 | uint rootsector; 78 | _errorlevel = int.MaxValue; 79 | if(!EndianConverter.Little32(ref data, out rootsector)) 80 | return false; 81 | uint rootsize; 82 | if(!EndianConverter.Little32(ref data, out rootsize, 4)) 83 | return false; 84 | UpdateStatus(string.Format("Root sector: {0} (0x{0:X}) Root size: {1} (0x{1:X})", rootsector, rootsize)); 85 | UpdateOperation("Parsing Game Partition FS Table..."); 86 | Parse(ref br, ref retval.List, 0, 0, rootsector); 87 | _totalProcessed = 0; 88 | _totalSize = 0; 89 | var msg = ""; 90 | var newlist = new List(); 91 | foreach(var entry in retval.List) { 92 | if(opts.ExcludeSysUpdate && entry.Path.IndexOf("$SystemUpdate", StringComparison.CurrentCultureIgnoreCase) != -1 || 93 | entry.Name.IndexOf("$SystemUpdate", StringComparison.CurrentCultureIgnoreCase) != -1) 94 | continue; 95 | if(entry.IsFile) { 96 | if(opts.GenerateFileList) 97 | msg += string.Format("{0}{1} [Offset: 0x{2:X} Size: {3}]{4}", entry.Path, entry.Name, entry.Offset, Utils.GetSizeReadable(entry.Size), Environment.NewLine); 98 | _totalSize += entry.Size; 99 | retval.Files++; 100 | } 101 | else { 102 | if(opts.GenerateFileList) 103 | msg += string.Format("{0}{1}\\{2}", entry.Path, entry.Name, Environment.NewLine); 104 | retval.Folders++; 105 | } 106 | newlist.Add(entry); 107 | } 108 | retval.List = newlist; 109 | UpdateStatus(string.Format("Parsing Game Partition FS Table done! Total entries found: {0} Files: {1} Folders: {2} Total File size: {3}", retval.List.Count, retval.Files, retval.Folders, 110 | Utils.GetSizeReadable(_totalSize))); 111 | if(opts.GenerateFileList) { 112 | msg = string.Format("Total entries: {0}{4}Folders: {1}{4}Files: {2}{4}Total Filesize: {5}{4}{3}", retval.List.Count, retval.Folders, retval.Files, msg, Environment.NewLine, 113 | Utils.GetSizeReadable(_totalSize)); 114 | File.WriteAllText(string.Format("{0}\\{1}.txt", Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)), msg); 115 | } 116 | if(string.IsNullOrEmpty(opts.Target)) 117 | opts.Target = string.Format("{0}\\{1}", Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)); 118 | if(opts.Target.EndsWith("\\", StringComparison.Ordinal)) 119 | opts.Target = opts.Target.Substring(0, opts.Target.Length - 1); 120 | retval.Size = _totalSize; 121 | return true; 122 | } 123 | 124 | internal static bool ExtractXiso(XisoOptions opts) { 125 | BinaryReader br = null; 126 | try { 127 | Abort = false; 128 | var sw = new Stopwatch(); 129 | sw.Start(); 130 | XisoListAndSize retval; 131 | UpdateStatus(string.Format("Extracting {0}", opts.Source)); 132 | if(!GetFileListAndSize(opts, out retval, out br)) 133 | return false; 134 | _errorlevel = 0; 135 | if(ExtractXiso(opts, retval, ref br)) { 136 | if(opts.DeleteIsoOnCompletion) { 137 | br.Close(); 138 | File.Delete(opts.Source); 139 | } 140 | sw.Stop(); 141 | UpdateStatus(string.Format("Successfully extracted {0} Files in {1} Folders with a total size of {2}", retval.Files, retval.Folders, Utils.GetSizeReadable(_totalSize))); 142 | UpdateOperation(string.Format("Completed extraction after {0:F0} Minute(s) and {1} Seconds", sw.Elapsed.TotalMinutes, sw.Elapsed.Seconds)); 143 | return true; 144 | } 145 | sw.Stop(); 146 | if(Abort) { 147 | UpdateStatus("Aborted by user"); 148 | UpdateOperation(string.Format("Aborted extraction after {0:F0} Minute(s) and {1} Seconds", sw.Elapsed.TotalMinutes, sw.Elapsed.Seconds)); 149 | } 150 | 151 | else if(_errorlevel != 5) { 152 | UpdateStatus("Extraction failed!"); 153 | UpdateOperation(string.Format("Extraction failed after {0:F0} Minute(s) and {1} Seconds", sw.Elapsed.TotalMinutes, sw.Elapsed.Seconds)); 154 | } 155 | return false; 156 | } 157 | finally { 158 | if(br != null) 159 | br.Close(); 160 | } 161 | } 162 | 163 | internal static bool ExtractXiso(XisoOptions opts, XisoListAndSize retval) { 164 | var br = new BinaryReader(File.Open(opts.Source, FileMode.Open, FileAccess.Read, FileShare.Read)); 165 | try { 166 | if (opts.GenerateSfv) 167 | opts.SfvGen = new SfvGenerator(Path.Combine(Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)) + ".sfv"); 168 | var ret = ExtractXiso(opts, retval, ref br); 169 | if(!ret || !opts.DeleteIsoOnCompletion) 170 | return ret; 171 | br.Close(); 172 | File.Delete(opts.Source); 173 | return true; 174 | } 175 | finally { 176 | br.Close(); 177 | } 178 | } 179 | 180 | private static bool ExtractXiso(XisoOptions opts, XisoListAndSize retval, ref BinaryReader br) { 181 | _errorlevel = 0; 182 | if(opts.UseFtp && opts.FtpOpts.IsValid) 183 | return ExtractFiles(ref br, ref retval.List, opts.FtpOpts, opts); 184 | if(opts.UseFtp) 185 | opts.Target = Path.Combine(Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)); 186 | if (opts.GenerateSfv) 187 | opts.SfvGen = new SfvGenerator(Path.Combine(Path.GetDirectoryName(opts.Source), Path.GetFileNameWithoutExtension(opts.Source)) + ".sfv"); 188 | var space = GetTotalFreeSpace(opts.Target); 189 | if(space < 0) { 190 | UpdateStatus(string.Format("WARNING: Unable to get Total Free Space got: {0} We'll be extracting anyways...", space)); 191 | space = retval.Size * 100; // There was an error, try to extract anyways 192 | } 193 | if(space > retval.Size) { 194 | _totalSize = retval.Size; 195 | if(!ExtractFiles(ref br, ref retval.List, opts.Target, opts)) 196 | return false; 197 | if(opts.GenerateSfv) 198 | opts.SfvGen.Save(); 199 | return true; 200 | } 201 | _errorlevel = 5; 202 | UpdateStatus(string.Format("Extraction failed! (Not enough space on drive) space needed: {0} Space available: {1}", Utils.GetSizeReadable(retval.Size), Utils.GetSizeReadable(space))); 203 | return false; 204 | } 205 | 206 | private static bool ExtractFiles(ref BinaryReader br, ref List list, Xisoftp.FTPSettingsData ftpOpts, XisoOptions xisoOpts) { 207 | _totalProcessed = 0; 208 | if(list.Count == 0) 209 | return false; 210 | UpdateStatus("Connecting to server..."); 211 | if(!Xisoftp.Connect(ftpOpts.Host, ftpOpts.Port, ftpOpts.DataConnectionType, ftpOpts.User, ftpOpts.Password)) { 212 | UpdateStatus(string.Format("Connection failed! Last Error: {0}", Xisoftp.LastError)); 213 | return false; 214 | } 215 | if(!Xisoftp.SetDirectory(ftpOpts.Path)) { 216 | UpdateStatus(string.Format("Set Directory Failure! Last Error: {0}", Xisoftp.LastError)); 217 | Xisoftp.Disconnect(); 218 | return false; 219 | } 220 | UpdateStatus(string.Format("Creating Directory: {0}", xisoOpts.Target)); 221 | if(!Xisoftp.CreateDirectory(xisoOpts.Target)) { 222 | UpdateStatus(string.Format("Create target Directory Failure! Last Error: {0}", Xisoftp.LastError)); 223 | Xisoftp.Disconnect(); 224 | return false; 225 | } 226 | ftpOpts.Path += xisoOpts.Target; 227 | UpdateStatus(string.Format("Extracting files to ftp:{0}", ftpOpts.Path)); 228 | UpdateOperation(string.Format("Extracting files to ftp:{0}", ftpOpts.Path)); 229 | foreach(var entry in list) { 230 | if(entry.IsFile) 231 | continue; 232 | var dir = ftpOpts.Path + (entry.Path.Substring(1) + entry.Name).Replace("\\", "/"); 233 | UpdateStatus(string.Format("Creating Directory: {0}", dir)); 234 | Xisoftp.CreateDirectory(dir); 235 | } 236 | foreach(var entry in list) { 237 | if(Abort) 238 | return false; 239 | if(!entry.IsFile) 240 | continue; 241 | if(!Xisoftp.SetDirectory((ftpOpts.Path + entry.Path.Replace("\\", "/")).Replace("//", "/"))) { 242 | UpdateStatus(string.Format("Set Directory Failure! Last Error: {0}", Xisoftp.LastError)); 243 | Xisoftp.Disconnect(); 244 | return false; 245 | } 246 | UpdateStatus(string.Format("Extracting {0}{1} ({2})", entry.Path, entry.Name, Utils.GetSizeReadable(entry.Size))); 247 | if(!Xisoftp.SendFile(entry.Name, ref br, entry.Offset, entry.Size, xisoOpts, entry.Path)) { 248 | UpdateStatus(string.Format("Send File Failure! Last Error: {0}", Xisoftp.LastError)); 249 | Xisoftp.Disconnect(); 250 | return false; 251 | } 252 | } 253 | if(xisoOpts.GenerateSfv) 254 | xisoOpts.SfvGen.Save(); 255 | return true; 256 | } 257 | 258 | private static long GetTotalFreeSpace(string path) { 259 | foreach(var drive in DriveInfo.GetDrives()) { 260 | if(drive.IsReady && drive.RootDirectory.FullName.Equals(Path.GetPathRoot(path), StringComparison.CurrentCultureIgnoreCase)) 261 | return drive.TotalFreeSpace; 262 | } 263 | return -1; 264 | } 265 | 266 | internal static void UpdateOperation(string operation) { 267 | var handler = Operation; 268 | if(handler != null) 269 | handler(null, new EventArg(operation)); 270 | } 271 | 272 | internal static void UpdateStatus(string status) { 273 | var handler = Status; 274 | if(handler != null) 275 | handler(null, new EventArg(status)); 276 | } 277 | 278 | private static void UpdateIsoProgress(double progress) { 279 | var handler = IsoProgress; 280 | if(handler != null) 281 | handler(null, new EventArg(progress)); 282 | } 283 | 284 | private static void UpdateTotalProgress(double progress) { 285 | var handler = TotalProgress; 286 | if(handler != null) 287 | handler(null, new EventArg(progress)); 288 | } 289 | 290 | private static void UpdateFileProgress(double progress, long size) { 291 | var handler = FileProgress; 292 | if(handler != null) 293 | handler(null, new EventArg(progress, size)); 294 | } 295 | 296 | private static bool VerifyXiso(string filename) { 297 | UpdateOperation(string.Format("Verifying XISO: {0}", filename)); 298 | var br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)); 299 | _baseOffset = 0; //Gamepartition only... 300 | if(!CheckMediaString(ref br)) { 301 | if(_errorlevel != 0) 302 | return false; 303 | _baseOffset = 0x4100; //XGD3 304 | if(!CheckMediaString(ref br)) { 305 | if(_errorlevel != 0) 306 | return false; 307 | _baseOffset = 0x1fb20; //XGD2 308 | if(!CheckMediaString(ref br)) { 309 | if(_errorlevel != 0) 310 | return false; 311 | _baseOffset = 0x30600; //XGD1 (Original Xbox) 312 | if(!CheckMediaString(ref br)) { 313 | br.Close(); 314 | UpdateStatus("Invalid XISO Image!"); 315 | _errorlevel = -2; 316 | return false; 317 | } 318 | UpdateStatus("XGD (Original Xbox) Image detected!"); 319 | } 320 | else 321 | UpdateStatus("XGD2 Image detected!"); 322 | } 323 | else 324 | UpdateStatus("XGD3 Image detected!"); 325 | } 326 | else 327 | UpdateStatus("XGD (Original Xbox) Image detected!"); 328 | br.Close(); 329 | return true; 330 | } 331 | 332 | private static bool CheckMediaString(ref BinaryReader br) { 333 | _errorlevel = 0; 334 | if(!BinarySeek(ref br, (_baseOffset + 32) * 2048, 0x14)) { 335 | _errorlevel = -1; 336 | return false; 337 | } 338 | var data = br.ReadBytes(0x14); 339 | return Encoding.ASCII.GetString(data, 0, 0x14).Equals("MICROSOFT*XBOX*MEDIA"); 340 | } 341 | 342 | private static bool BinarySeek(ref BinaryReader br, long offset, long len) { 343 | if(br.BaseStream.Length < offset + len) { 344 | br.Close(); 345 | return false; 346 | } 347 | br.BaseStream.Seek(offset, SeekOrigin.Begin); 348 | return true; 349 | } 350 | 351 | private static void Parse(ref BinaryReader br, ref List list, int offset, int level, uint tocoffset, string dirprefix = "\\") { 352 | if(Abort) 353 | return; 354 | _errorlevel = 2; 355 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 4, 4)) 356 | return; 357 | uint sector; 358 | EndianConverter.Big32(br.ReadBytes(4), out sector); 359 | _errorlevel = 3; 360 | if(sector == uint.MaxValue) 361 | return; 362 | _errorlevel = 2; 363 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset, 2)) 364 | return; 365 | _errorlevel = int.MaxValue; 366 | ushort left; 367 | EndianConverter.Little16(br.ReadBytes(2), out left); 368 | ushort right; 369 | _errorlevel = 2; 370 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 2, 2)) 371 | return; 372 | _errorlevel = int.MaxValue; 373 | if(!EndianConverter.Little16(br.ReadBytes(2), out right)) 374 | return; 375 | if(left != 0) 376 | Parse(ref br, ref list, left * 4, level, tocoffset, dirprefix); 377 | _errorlevel = 2; 378 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 0xC, 1)) 379 | return; 380 | if((br.ReadByte() & 0x10) == 0x10) /* Dircectory found... */ { 381 | level++; 382 | uint tocSector; 383 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 4, 4)) 384 | return; 385 | _errorlevel = int.MaxValue; 386 | if(!EndianConverter.Little32(br.ReadBytes(4), out tocSector)) 387 | return; 388 | _errorlevel = 2; 389 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 0xD, 1)) 390 | return; 391 | int dirnamelen = br.ReadByte(); 392 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 0xE, dirnamelen)) 393 | return; 394 | var dirname = Enc.GetString(br.ReadBytes(dirnamelen)); 395 | list.Add(new XisoTableData { 396 | IsFile = false, 397 | Path = dirprefix, 398 | Name = dirname 399 | }); 400 | if(tocSector != 0) 401 | Parse(ref br, ref list, 0, level, tocSector, string.Format("{0}{1}\\", dirprefix, dirname)); 402 | } 403 | else { 404 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 0xD, 1)) 405 | return; 406 | int filenamelen = br.ReadByte(); 407 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 0xE, filenamelen)) 408 | return; 409 | var filename = Enc.GetString(br.ReadBytes(filenamelen)); 410 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 4, 4)) 411 | return; 412 | _errorlevel = int.MaxValue; 413 | if(!EndianConverter.Little32(br.ReadBytes(4), out sector)) 414 | return; 415 | uint size; 416 | _errorlevel = 2; 417 | if(!BinarySeek(ref br, ((_baseOffset + tocoffset) * 2048) + offset + 8, 4)) 418 | return; 419 | _errorlevel = int.MaxValue; 420 | if(!EndianConverter.Little32(br.ReadBytes(4), out size)) 421 | return; 422 | list.Add(new XisoTableData { 423 | IsFile = true, 424 | Path = dirprefix, 425 | Name = filename, 426 | Size = size, 427 | Offset = (sector + _baseOffset) * 0x800, 428 | }); 429 | } 430 | if(right != 0) 431 | Parse(ref br, ref list, right * 4, level, tocoffset, dirprefix); 432 | } 433 | 434 | private static bool ExtractFiles(ref BinaryReader br, ref List list, string target, XisoOptions xisoOpts) { 435 | _totalProcessed = 0; 436 | UpdateStatus(string.Format("Extracting files to {0}", target)); 437 | UpdateOperation(string.Format("Extracting files to {0}", target)); 438 | if(list.Count == 0) 439 | return false; 440 | Directory.CreateDirectory(target); 441 | foreach(var entry in list) { 442 | if(Abort) 443 | return false; 444 | Directory.CreateDirectory(target + entry.Path); 445 | if(!entry.IsFile) { 446 | Directory.CreateDirectory(target + entry.Path + entry.Name); 447 | continue; 448 | } 449 | UpdateStatus(string.Format("Extracting {0}{1} ({2})", entry.Path, entry.Name, Utils.GetSizeReadable(entry.Size))); 450 | if(!ExtractFile(ref br, entry.Offset, entry.Size, string.Format("{0}{1}{2}", target, entry.Path, entry.Name), xisoOpts)) 451 | return false; 452 | } 453 | if(xisoOpts.GenerateSfv) 454 | xisoOpts.SfvGen.Save(); 455 | return true; 456 | } 457 | 458 | private static bool ExtractFile(ref BinaryReader br, long offset, uint size, string target, XisoOptions xisoOpts) { 459 | _errorlevel = 4; 460 | if(!BinarySeek(ref br, offset, size)) { 461 | UpdateStatus("Seek failure"); 462 | return false; 463 | } 464 | using(var bw = new BinaryWriter(File.Open(target, FileMode.Create, FileAccess.Write, FileShare.None))) { 465 | _errorlevel = 0; 466 | UpdateFileProgress(0, 0); 467 | uint crc = 0; 468 | for(uint i = 0; i < size;) { 469 | if(Abort) 470 | return false; 471 | var readsize = Utils.GetSmallest(size - i, ReadWriteBuffer); 472 | if(!xisoOpts.GenerateSfv) 473 | bw.Write(br.ReadBytes((int)readsize)); 474 | else { 475 | var buf = br.ReadBytes((int)readsize); 476 | bw.Write(buf); 477 | crc = SfvGenerator.Crc.ComputeChecksum(buf, crc); 478 | } 479 | _totalProcessed += readsize; 480 | i += readsize; 481 | UpdateFileProgress(((double)i / size) * 100, readsize); 482 | UpdateIsoProgress(((double)_totalProcessed / _totalSize) * 100); 483 | if(MultiSize <= 0) 484 | continue; 485 | _multiProcessed += readsize; 486 | UpdateTotalProgress(((double)_multiProcessed / MultiSize) * 100); 487 | } 488 | if(xisoOpts.GenerateSfv) 489 | xisoOpts.SfvGen.AddFile(target.Replace(xisoOpts.Target, ""), crc); 490 | } 491 | return true; 492 | } 493 | } 494 | 495 | internal sealed class XisoListAndSize { 496 | public long Files; 497 | public long Folders; 498 | public List List = new List(); 499 | public long Size; 500 | } 501 | 502 | internal struct XisoTableData { 503 | public bool IsFile; 504 | public string Name; 505 | public long Offset; 506 | public string Path; 507 | public uint Size; 508 | } 509 | 510 | public sealed class XisoOptions { 511 | public bool DeleteIsoOnCompletion; 512 | public bool ExcludeSysUpdate = true; 513 | public Xisoftp.FTPSettingsData FtpOpts; 514 | public bool GenerateFileList; 515 | public bool GenerateSfv; 516 | public SfvGenerator SfvGen; 517 | public string Source; 518 | public string Target; 519 | public bool UseFtp; 520 | } 521 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/XISOExtractorGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {554E5E9C-0808-4913-8BE9-1F9636119379} 8 | WinExe 9 | Properties 10 | XISOExtractorGUI 11 | XISOExtractorGUI 12 | v2.0 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | none 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | Off 35 | 36 | 37 | bin\Release_NoFTP\ 38 | TRACE;NOFTP 39 | true 40 | AnyCPU 41 | Off 42 | prompt 43 | MinimumRecommendedRules.ruleset 44 | 45 | 46 | XGD.ico 47 | 48 | 49 | 50 | 51 | 52 | 53 | .\System.Net.FtpClient.dll 54 | False 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Form 65 | 66 | 67 | ExtractionResults.cs 68 | 69 | 70 | 71 | Form 72 | 73 | 74 | FTPSettings.cs 75 | 76 | 77 | Form 78 | 79 | 80 | MainForm.cs 81 | 82 | 83 | 84 | 85 | Form 86 | 87 | 88 | SettingsManager.cs 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | ExtractionResults.cs 97 | 98 | 99 | FTPSettings.cs 100 | 101 | 102 | MainForm.cs 103 | 104 | 105 | ResXFileCodeGenerator 106 | Resources.Designer.cs 107 | Designer 108 | 109 | 110 | True 111 | Resources.resx 112 | True 113 | 114 | 115 | 116 | 117 | SettingsManager.cs 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 139 | -------------------------------------------------------------------------------- /XISOExtractorGUI/XISOFTP.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Net; 6 | using System.Net.FtpClient; 7 | using System.Windows.Forms; 8 | using XISOExtractorGUI.Properties; 9 | 10 | public static class Xisoftp { 11 | private const uint BufferSize = 0x2000; 12 | public static string LastError; 13 | 14 | private static readonly FtpClient Client = new FtpClient(); 15 | 16 | static Xisoftp() { 17 | Client.SocketKeepAlive = true; 18 | } 19 | 20 | public static bool IsConnected { get { return Client.IsConnected; } } 21 | 22 | internal static event EventHandler> ProgressUpdate; 23 | 24 | private static bool Seek(ref BinaryReader br, long offset, long len, SeekOrigin origin = SeekOrigin.Begin) { 25 | if(origin == SeekOrigin.Begin && br.BaseStream.Length < offset + len) 26 | return false; 27 | if(origin == SeekOrigin.End && br.BaseStream.Length - offset < len) 28 | return false; 29 | if(origin == SeekOrigin.Current && br.BaseStream.Length < offset + len + br.BaseStream.Position) 30 | return false; 31 | br.BaseStream.Seek(offset, origin); 32 | return true; 33 | } 34 | 35 | public static bool Connect(string host, int port = 21, FtpDataConnectionType connectionType = FtpDataConnectionType.PASVEX, string user = "xbox", string password = "xbox") { 36 | try { 37 | if(Client.IsConnected) 38 | Client.Disconnect(); 39 | Client.Host = host; 40 | Client.Port = port; 41 | Client.DataConnectionType = connectionType; 42 | Client.EncryptionMode = FtpEncryptionMode.None; 43 | Client.Credentials = new NetworkCredential(user, password); 44 | Client.Connect(); 45 | return Client.IsConnected; 46 | } 47 | catch(Exception ex) { 48 | LastError = ex.Message; 49 | return false; 50 | } 51 | } 52 | 53 | public static void Disconnect() { Client.Disconnect(); } 54 | 55 | public static bool SendFile(string file, ref BinaryReader src, long offset, long size, XisoOptions xisoOpts, string path) { 56 | if(!Client.IsConnected) { 57 | XisoExtractor.UpdateStatus("FTP Not connected!"); 58 | return false; 59 | } 60 | try { 61 | using(var stream = Client.OpenWrite(file)) { 62 | if(src.BaseStream.Position != offset) { 63 | if(!Seek(ref src, offset, size)) { 64 | src.Close(); 65 | XisoExtractor.UpdateStatus("Seek failure!"); 66 | return false; 67 | } 68 | } 69 | else if(src.BaseStream.Length < src.BaseStream.Position + size) { 70 | src.Close(); 71 | XisoExtractor.UpdateStatus("Size failure!"); 72 | return false; 73 | } 74 | long processed = 0; 75 | XISOStatus.UpdateFTPProgress(processed, size); 76 | uint crc = 0; 77 | while(processed < size) { 78 | if(XisoExtractor.Abort) 79 | return false; 80 | var sendsize = Utils.GetSmallest(size - processed, BufferSize); 81 | var data = src.ReadBytes((int)sendsize); 82 | stream.Write(data, 0, data.Length); 83 | if(xisoOpts.GenerateSfv) 84 | crc = SfvGenerator.Crc.ComputeChecksum(data, crc); 85 | processed += sendsize; 86 | var handler = ProgressUpdate; 87 | if(handler != null) 88 | handler.Invoke(null, new EventArg(sendsize, processed, size)); 89 | XISOStatus.UpdateFTPProgress(processed, size); 90 | } 91 | if (xisoOpts.GenerateSfv) 92 | xisoOpts.SfvGen.AddFile(Path.Combine(path, file), crc); 93 | } 94 | } 95 | catch(Exception ex) { 96 | LastError = ex.Message; 97 | MessageBox.Show(string.Format(Resources.XISOFTPTransferError, file, ex), Resources.FTPTransferErrorTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); 98 | return false; 99 | } 100 | return true; 101 | } 102 | 103 | public static bool SetDirectory(string dir) { 104 | if(!Client.IsConnected) 105 | return false; 106 | try { 107 | Client.SetWorkingDirectory(dir); 108 | var ret = Client.GetWorkingDirectory(); 109 | if(!ret.EndsWith("/") && dir.EndsWith("/")) 110 | ret += "/"; 111 | if (ret.EndsWith("/") && !dir.EndsWith("/")) 112 | dir += "/"; 113 | return (ret == dir); 114 | } 115 | catch(FtpCommandException ex) { 116 | if (ex.Message.Equals("No such directory", StringComparison.CurrentCultureIgnoreCase) || ex.Message.EndsWith("Path not found.", StringComparison.CurrentCultureIgnoreCase)) 117 | { 118 | //var index = dir.Substring(0, dir.Length - 1).LastIndexOf('/'); 119 | //if(index <= 0) 120 | // return false; 121 | //var tmp = dir.Substring(index); 122 | //dir = dir.Substring(0, index) + "/"; 123 | Client.CreateDirectory(dir); 124 | Client.SetWorkingDirectory(dir); 125 | var ret = Client.GetWorkingDirectory(); 126 | if (!ret.EndsWith("/") && dir.EndsWith("/")) 127 | ret += "/"; 128 | if(ret.EndsWith("/") && !dir.EndsWith("/")) 129 | dir += "/"; 130 | return (ret == dir); 131 | } 132 | LastError = ex.Message; 133 | return false; 134 | } 135 | } 136 | 137 | public static bool GetDirListing(string dir, ref List list) { 138 | list.Clear(); 139 | if(!Client.IsConnected) 140 | return false; 141 | try { 142 | if(dir != null) 143 | Client.SetWorkingDirectory(dir); 144 | foreach(var ftpDirList in Client.GetListing()) { 145 | list.Add(new FTPDirList { 146 | Name = ftpDirList.Name, 147 | IsDirectory = ftpDirList.Type == FtpFileSystemObjectType.Directory 148 | }); 149 | } 150 | return list.Count > 0; 151 | } 152 | catch(Exception ex) { 153 | LastError = ex.Message; 154 | } 155 | return false; 156 | } 157 | 158 | public static bool CreateDirectory(string dir) { 159 | if(!Client.IsConnected) 160 | return false; 161 | Client.CreateDirectory(dir, false); 162 | return true; 163 | } 164 | 165 | public class FTPDirList { 166 | public bool IsDirectory; 167 | public string Name; 168 | } 169 | 170 | public class FTPSettingsData { 171 | public FtpDataConnectionType DataConnectionType = FtpDataConnectionType.PASVEX; 172 | public string Host; 173 | public string Password = "xbox"; 174 | private string _path; 175 | 176 | public string Path { 177 | get { 178 | return _path; 179 | } 180 | set { 181 | if(!value.EndsWith("/")) 182 | value += "/"; 183 | _path = value; 184 | } 185 | } 186 | 187 | public int Port = 21; 188 | public string User = "xbox"; 189 | 190 | public bool IsValid { get { return !string.IsNullOrEmpty(Host) && !string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(User) && !string.IsNullOrEmpty(Path); } } 191 | } 192 | } 193 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/XISOStatus.cs: -------------------------------------------------------------------------------- 1 | namespace XISOExtractorGUI { 2 | using System; 3 | 4 | public static class XISOStatus { 5 | public class EventArg : EventArgs { 6 | private readonly T _data; 7 | 8 | public EventArg(T data) { 9 | _data = data; 10 | } 11 | 12 | public T Data { 13 | get { return _data; } 14 | } 15 | 16 | } 17 | 18 | public static event EventHandler> Operation; 19 | public static event EventHandler> Status; 20 | public static event EventHandler> OverallProgress; 21 | public static event EventHandler> CurrentProgress; 22 | public static event EventHandler> FileProgress; 23 | public static event EventHandler> FTPProgress; 24 | 25 | internal static void UpdateOperation(string operation) { 26 | if (Operation != null) 27 | Operation(null, new EventArg(operation)); 28 | } 29 | 30 | internal static void UpdateStatus(string status) { 31 | if (Status != null) 32 | Status(null, new EventArg(status)); 33 | } 34 | 35 | internal static void UpdateCurrentProgress(long current, long max) { 36 | if (CurrentProgress != null) 37 | CurrentProgress(null, new EventArg(Utils.GetPercentage(current, max))); 38 | } 39 | 40 | internal static void UpdateOverallProgress(long current, long max) { 41 | if (OverallProgress != null) 42 | OverallProgress(null, new EventArg(Utils.GetPercentage(current, max))); 43 | } 44 | 45 | internal static void UpdateFileProgress(long current, long max) { 46 | if (FileProgress != null) 47 | FileProgress(null, new EventArg(Utils.GetPercentage(current, max))); 48 | } 49 | 50 | internal static void UpdateFTPProgress(long current, long max) 51 | { 52 | if (FTPProgress != null) 53 | FTPProgress(null, new EventArg(Utils.GetPercentage(current, max))); 54 | } 55 | 56 | } 57 | } -------------------------------------------------------------------------------- /XISOExtractorGUI/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Swizzy/XISOExtractorGUI/a5c9272b925d83eb3d2d5c757781295ea5840a9e/XISOExtractorGUI/file.png -------------------------------------------------------------------------------- /XISOExtractorGUI/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Swizzy/XISOExtractorGUI/a5c9272b925d83eb3d2d5c757781295ea5840a9e/XISOExtractorGUI/folder.png --------------------------------------------------------------------------------