diff --git a/NUS Downloader/Form1.Designer.cs b/NUS Downloader/Form1.Designer.cs
index aae886f..f370bd9 100644
--- a/NUS Downloader/Form1.Designer.cs
+++ b/NUS Downloader/Form1.Designer.cs
@@ -116,6 +116,8 @@
this.europePALToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.japanNTSCJToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.koreaToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.saveaswadbox = new System.Windows.Forms.CheckBox();
+ this.deletecontentsbox = new System.Windows.Forms.CheckBox();
this.databaseStrip.SuspendLayout();
this.tmdgpbox.SuspendLayout();
this.ticketgpbox.SuspendLayout();
@@ -169,13 +171,14 @@
// packbox
//
this.packbox.AutoSize = true;
- this.packbox.Location = new System.Drawing.Point(12, 422);
+ this.packbox.Location = new System.Drawing.Point(12, 416);
this.packbox.Name = "packbox";
this.packbox.Size = new System.Drawing.Size(92, 17);
this.packbox.TabIndex = 6;
this.packbox.Text = "Pack -> WAD";
this.packbox.UseVisualStyleBackColor = true;
this.packbox.CheckedChanged += new System.EventHandler(this.packbox_CheckedChanged);
+ this.packbox.EnabledChanged += new System.EventHandler(this.packbox_EnabledChanged);
//
// dlprogress
//
@@ -191,11 +194,11 @@
this.localuse.Checked = true;
this.localuse.CheckState = System.Windows.Forms.CheckState.Checked;
this.localuse.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.localuse.Location = new System.Drawing.Point(12, 468);
+ this.localuse.Location = new System.Drawing.Point(104, 463);
this.localuse.Name = "localuse";
- this.localuse.Size = new System.Drawing.Size(167, 17);
+ this.localuse.Size = new System.Drawing.Size(76, 17);
this.localuse.TabIndex = 8;
- this.localuse.Text = "Use/Keep Present Local Files";
+ this.localuse.Text = "Local Files";
this.localuse.UseVisualStyleBackColor = true;
//
// NUSDownloader
@@ -249,7 +252,7 @@
this.wadnamebox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.wadnamebox.Enabled = false;
this.wadnamebox.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.wadnamebox.Location = new System.Drawing.Point(102, 421);
+ this.wadnamebox.Location = new System.Drawing.Point(102, 416);
this.wadnamebox.MaxLength = 99999;
this.wadnamebox.Name = "wadnamebox";
this.wadnamebox.Size = new System.Drawing.Size(160, 18);
@@ -258,21 +261,21 @@
// ignoreticket
//
this.ignoreticket.AutoSize = true;
- this.ignoreticket.Location = new System.Drawing.Point(12, 445);
+ this.ignoreticket.Location = new System.Drawing.Point(104, 440);
this.ignoreticket.Name = "ignoreticket";
- this.ignoreticket.Size = new System.Drawing.Size(135, 17);
+ this.ignoreticket.Size = new System.Drawing.Size(89, 17);
this.ignoreticket.TabIndex = 18;
- this.ignoreticket.Text = "Ignore Ticket if Missing";
+ this.ignoreticket.Text = "Ignore Ticket";
this.ignoreticket.UseVisualStyleBackColor = true;
//
// decryptbox
//
this.decryptbox.AutoSize = true;
- this.decryptbox.Location = new System.Drawing.Point(154, 445);
+ this.decryptbox.Location = new System.Drawing.Point(199, 440);
this.decryptbox.Name = "decryptbox";
- this.decryptbox.Size = new System.Drawing.Size(108, 17);
+ this.decryptbox.Size = new System.Drawing.Size(63, 17);
this.decryptbox.TabIndex = 19;
- this.decryptbox.Text = "Decrypt Contents";
+ this.decryptbox.Text = "Decrypt";
this.decryptbox.UseVisualStyleBackColor = true;
//
// databaseButton
@@ -431,7 +434,7 @@
// truchabox
//
this.truchabox.AutoSize = true;
- this.truchabox.Location = new System.Drawing.Point(184, 468);
+ this.truchabox.Location = new System.Drawing.Point(199, 463);
this.truchabox.Name = "truchabox";
this.truchabox.Size = new System.Drawing.Size(60, 17);
this.truchabox.TabIndex = 21;
@@ -870,7 +873,7 @@
this.radioButton2.ImageAlign = System.Drawing.ContentAlignment.TopCenter;
this.radioButton2.Location = new System.Drawing.Point(78, 385);
this.radioButton2.Name = "radioButton2";
- this.radioButton2.Size = new System.Drawing.Size(74, 31);
+ this.radioButton2.Size = new System.Drawing.Size(74, 30);
this.radioButton2.TabIndex = 13;
this.radioButton2.UseVisualStyleBackColor = true;
this.radioButton2.CheckedChanged += new System.EventHandler(this.radioButton2_CheckedChanged);
@@ -944,40 +947,64 @@
this.koreaToolStripMenuItem.Size = new System.Drawing.Size(154, 22);
this.koreaToolStripMenuItem.Text = "Korea";
//
+ // saveaswadbox
+ //
+ this.saveaswadbox.AutoSize = true;
+ this.saveaswadbox.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.saveaswadbox.Location = new System.Drawing.Point(22, 437);
+ this.saveaswadbox.Name = "saveaswadbox";
+ this.saveaswadbox.Size = new System.Drawing.Size(58, 16);
+ this.saveaswadbox.TabIndex = 43;
+ this.saveaswadbox.Text = "SaveAs";
+ this.saveaswadbox.UseVisualStyleBackColor = true;
+ //
+ // deletecontentsbox
+ //
+ this.deletecontentsbox.AutoSize = true;
+ this.deletecontentsbox.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.deletecontentsbox.Location = new System.Drawing.Point(22, 454);
+ this.deletecontentsbox.Name = "deletecontentsbox";
+ this.deletecontentsbox.Size = new System.Drawing.Size(62, 28);
+ this.deletecontentsbox.TabIndex = 44;
+ this.deletecontentsbox.Text = "Delete\r\nContents";
+ this.deletecontentsbox.UseVisualStyleBackColor = true;
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(539, 492);
+ this.Controls.Add(this.deletecontentsbox);
this.Controls.Add(this.button3);
this.Controls.Add(this.shamelessvariablelabel);
this.Controls.Add(this.button1);
this.Controls.Add(this.button17);
this.Controls.Add(this.ticketgpbox);
this.Controls.Add(this.tmdgpbox);
- this.Controls.Add(this.truchabox);
+ this.Controls.Add(this.saveaswadbox);
this.Controls.Add(this.databaseButton);
this.Controls.Add(this.button5);
this.Controls.Add(this.contentModBox);
this.Controls.Add(this.button4);
- this.Controls.Add(this.decryptbox);
- this.Controls.Add(this.ignoreticket);
this.Controls.Add(this.wadnamebox);
this.Controls.Add(this.button7);
+ this.Controls.Add(this.truchabox);
this.Controls.Add(this.label2);
this.Controls.Add(this.titleversion);
this.Controls.Add(this.button2);
+ this.Controls.Add(this.decryptbox);
this.Controls.Add(this.label1);
this.Controls.Add(this.radioButton1);
this.Controls.Add(this.radioButton2);
- this.Controls.Add(this.localuse);
this.Controls.Add(this.dlprogress);
this.Controls.Add(this.packbox);
this.Controls.Add(this.statusbox);
+ this.Controls.Add(this.ignoreticket);
this.Controls.Add(this.downloadstartbtn);
this.Controls.Add(this.titleidbox);
this.Controls.Add(this.Extrasbtn);
this.Controls.Add(this.button6);
+ this.Controls.Add(this.localuse);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
@@ -1086,6 +1113,8 @@
private System.Windows.Forms.ToolStripMenuItem europePALToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem japanNTSCJToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem koreaToolStripMenuItem;
+ private System.Windows.Forms.CheckBox saveaswadbox;
+ private System.Windows.Forms.CheckBox deletecontentsbox;
}
}
diff --git a/NUS Downloader/Form1.cs b/NUS Downloader/Form1.cs
index 401ba7a..6974475 100644
--- a/NUS Downloader/Form1.cs
+++ b/NUS Downloader/Form1.cs
@@ -22,7 +22,6 @@ namespace NUS_Downloader
WebClient generalWC = new WebClient();
static RijndaelManaged rijndaelCipher;
static bool dsidecrypt = false;
- const string certs_MD5 = "7677AD47BAA5D6E3E313E72661FBDC16";
// Images do not compare unless globalized...
Image green = Properties.Resources.bullet_green;
@@ -42,6 +41,8 @@ namespace NUS_Downloader
byte[] cert_total_sha1 = new byte[20] {0xAC, 0xE0, 0xF1, 0x5D, 0x2A, 0x85, 0x1C, 0x38, 0x3F, 0xE4, 0x65, 0x7A, 0xFC, 0x38, 0x40, 0xD6, 0xFF, 0xE3, 0x0A, 0xD0};
+ string WAD_Saveas_Filename;
+ /*
public struct WADHeader
{
public int HeaderSize;
@@ -52,7 +53,7 @@ namespace NUS_Downloader
public int TMDSize;
public int DataSize;
public int FooterSize;
- };
+ };*/
public struct TitleContent
{
@@ -171,6 +172,10 @@ namespace NUS_Downloader
this.Size = this.MinimumSize;
}
+ ///
+ /// Checks certain file existances, etc.
+ ///
+ ///
private bool BootChecks()
{
// Success?
@@ -265,6 +270,11 @@ namespace NUS_Downloader
return result;
}
+ ///
+ /// Gets the database version.
+ ///
+ /// The database file.
+ ///
private string GetDatabaseVersion(string file)
{
// Read version of Database.xml
@@ -284,6 +294,9 @@ namespace NUS_Downloader
extrasStrip.Show(Extrasbtn, 2, 2);
}
+ ///
+ /// Loads the title info from TMD.
+ ///
private void LoadTitleFromTMD()
{
// Show dialog for opening TMD file...
@@ -350,6 +363,11 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Returns needed IOS from TMD.
+ ///
+ /// The TMD.
+ ///
private string IOSNeededFromTMD(byte[] tmd)
{
string sysversion = "";
@@ -361,6 +379,11 @@ namespace NUS_Downloader
return sysversion;
}
+ ///
+ /// Returns content count of TMD
+ ///
+ /// The TMD.
+ /// int Count of Contents
private int ContentCount(byte[] tmd)
{
// nbr_cont (0xDE) len=0x02
@@ -369,6 +392,11 @@ namespace NUS_Downloader
return nbr_cont;
}
+ ///
+ /// Gets a TMD Boot Index
+ ///
+ /// The TMD.
+ /// int BootIndex
private int GetBootIndex(byte[] tmd)
{
// nbr_cont (0xE0) len=0x02
@@ -377,6 +405,12 @@ namespace NUS_Downloader
return bootidx;
}
+ ///
+ /// Sets the Boot index of a TMD.
+ ///
+ /// The TMD.
+ /// Index to set it too
+ /// Edited TMD
private byte[] SetBootIndex(byte[] tmd, int bootindex)
{
// nbr_cont (0xE0) len=0x02
@@ -386,7 +420,11 @@ namespace NUS_Downloader
return tmd;
}
- private void WriteStatus(string Update)
+ ///
+ /// Writes the status to the statusbox.
+ ///
+ /// The update.
+ public void WriteStatus(string Update)
{
// Small function for writing text to the statusbox...
if (statusbox.Text == "")
@@ -450,6 +488,11 @@ namespace NUS_Downloader
return ret;
}
+ ///
+ /// Makes a hex string the correct length.
+ ///
+ /// The hex.
+ ///
private string MakeProperLength(string hex)
{
// If hex is like, 'A', makes it '0A', etc.
@@ -459,6 +502,11 @@ namespace NUS_Downloader
return hex;
}
+ ///
+ /// Converts to hex.
+ ///
+ /// The string.
+ /// hex string
private string ConvertToHex(string decval)
{
// Convert text string to unsigned integer
@@ -466,6 +514,10 @@ namespace NUS_Downloader
return String.Format("{0:x2}", uiDecimal);
}
+ ///
+ /// Reads the type of the Title ID.
+ ///
+ /// The TitleID.
private void ReadIDType(string ttlid)
{
/* Wiibrew TitleID Info...
@@ -488,39 +540,28 @@ namespace NUS_Downloader
*/
if (ttlid.Substring(0, 8) == "00000001")
- {
WriteStatus("ID Type: System Title. BE CAREFUL!");
- }
else if ((ttlid.Substring(0, 8) == "00010000") || (ttlid.Substring(0, 8) == "00010004"))
- {
WriteStatus("ID Type: Disc-Based Game. Unlikely NUS Content!");
- }
else if (ttlid.Substring(0, 8) == "00010001")
- {
WriteStatus("ID Type: Downloaded Channel. Possible NUS Content.");
- }
else if (ttlid.Substring(0, 8) == "00010002")
- {
WriteStatus("ID Type: System Channel. BE CAREFUL!");
- }
else if (ttlid.Substring(0, 8) == "00010004")
- {
WriteStatus("ID Type: Game Channel. Unlikely NUS Content!");
- }
else if (ttlid.Substring(0, 8) == "00010005")
- {
WriteStatus("ID Type: Downloaded Game Content. Unlikely NUS Content!");
- }
else if (ttlid.Substring(0, 8) == "00010008")
- {
WriteStatus("ID Type: 'Hidden' Channel. Unlikely NUS Content!");
- }
else
- {
WriteStatus("ID Type: Unknown. Unlikely NUS Content!");
- }
}
+ ///
+ /// Trims the leading zeros of a string.
+ ///
+ /// The string with leading zeros.
+ /// no-0-string
private string TrimLeadingZeros(string num)
{
int startindex = 0;
@@ -535,6 +576,12 @@ namespace NUS_Downloader
return num.Substring(startindex, (num.Length - startindex));
}
+ ///
+ /// Gets the content names in a TMD.
+ ///
+ /// The TMD.
+ /// The TMD contentcount.
+ /// Array of Content names
private string[] GetContentNames(byte[] tmdfile, int length)
{
string[] contentnames = new string[length];
@@ -552,6 +599,12 @@ namespace NUS_Downloader
return contentnames;
}
+ ///
+ /// Gets the content sizes in a TMD.
+ ///
+ /// The TMD.
+ /// The TMD contentcount.
+ ///
private string[] GetContentSizes(byte[] tmdfile, int length)
{
string[] contentsizes = new string[length];
@@ -583,6 +636,12 @@ namespace NUS_Downloader
return contentsizes;
}
+ ///
+ /// Gets the content hashes.
+ ///
+ /// The tmd.
+ /// The content_count.
+ ///
private byte[] GetContentHashes(byte[] tmdfile, int length)
{
byte[] contenthashes = new byte[length*20];
@@ -599,7 +658,12 @@ namespace NUS_Downloader
return contenthashes;
}
- // Returns array of shared/normal values for a tmd...
+ ///
+ /// Gets the content types.
+ ///
+ /// The tmd.
+ /// The content_count.
+ ///
private int[] GetContentTypes(byte[] tmdfile, int length)
{
int[] contenttypes = new int[length];
@@ -617,6 +681,12 @@ namespace NUS_Downloader
return contenttypes;
}
+ ///
+ /// Gets the content indices.
+ ///
+ /// The tmd.
+ /// The contentcount.
+ ///
private byte[] GetContentIndices(byte[] tmdfile, int length)
{
byte[] contentindices = new byte[length];
@@ -652,6 +722,20 @@ namespace NUS_Downloader
}
}
+ // Handle SaveAs here so it shows up properly...
+ if (saveaswadbox.Checked)
+ {
+ SaveFileDialog wad_saveas = new SaveFileDialog();
+ wad_saveas.Title = "Save WAD File...";
+ wad_saveas.Filter = "WAD Files|*.wad|All Files|*.*";
+ wad_saveas.AddExtension = true;
+ DialogResult dres = wad_saveas.ShowDialog();
+ if (dres != DialogResult.Cancel)
+ WAD_Saveas_Filename = wad_saveas.FileName;
+ }
+ else
+ WAD_Saveas_Filename = "";
+
// Running Downloads in background so no form freezing
NUSDownloader.RunWorkerAsync();
}
@@ -1006,12 +1090,12 @@ namespace NUS_Downloader
System.Threading.Thread.Sleep(1000);
}
- // Re-Gather information...
+ /* Re-Gather information...
byte[] tmdrefresh = FileLocationToByteArray(titledirectory + tmdfull);
tmdcontents = GetContentNames(tmd, ContentCount(tmdrefresh));
tmdsizes = GetContentSizes(tmd, ContentCount(tmdrefresh));
tmdhashes = GetContentHashes(tmd, ContentCount(tmdrefresh));
- tmdindices = GetContentIndices(tmd, ContentCount(tmdrefresh));
+ tmdindices = GetContentIndices(tmd, ContentCount(tmdrefresh)); */
/*
WriteStatus("Trucha Signing TMD...");
@@ -1043,7 +1127,7 @@ namespace NUS_Downloader
if ((packbox.Checked == true) && (wiimode == true))
{
- PackWAD(titleid, tmdfull, tmdcontents.Length, tmdcontents, tmdsizes, titledirectory);
+ PackWAD(titleid, tmdfull, titledirectory);
}
SetEnableforDownload(true);
@@ -1052,6 +1136,9 @@ namespace NUS_Downloader
}
+ ///
+ /// Creates the title directory.
+ ///
private void CreateTitleDirectory()
{
// Creates the directory for the downloaded title...
@@ -1080,6 +1167,9 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Deletes the title directory.
+ ///
private void DeleteTitleDirectory()
{
string currentdir = Application.StartupPath;
@@ -1099,6 +1189,14 @@ namespace NUS_Downloader
//Directory.CreateDirectory(currentdir + titleidbox.Text);
}
+ ///
+ /// Downloads the NUS file.
+ ///
+ /// The titleid.
+ /// The filename.
+ /// The placementdir.
+ /// The sizeinbytes.
+ /// if set to true [iswiititle].
private void DownloadNUSFile(string titleid, string filename, string placementdir, int sizeinbytes, bool iswiititle)
{
// Create NUS URL...
@@ -1118,7 +1216,18 @@ namespace NUS_Downloader
generalWC.DownloadFile(nusfileurl, placementdir + filename);
}
- public void PackWAD(string titleid, string tmdfilename, int contentcount, string[] contentnames, string[] contentsizes, string totaldirectory)
+ void StatusChange(string status)
+ {
+ WriteStatus(status);
+ }
+
+ ///
+ /// Packs the WAD.
+ ///
+ /// The titleid.
+ /// The tmdfilename.
+ /// The working directory.
+ public void PackWAD(string titleid, string tmdfilename, string totaldirectory)
{
WriteStatus("Beginning WAD Pack...");
// Directory stuff
@@ -1126,6 +1235,9 @@ namespace NUS_Downloader
if (!(currentdir.EndsWith(@"\")) || !(currentdir.EndsWith(@"/")))
currentdir += @"\";
+ WADPacker packer = new WADPacker();
+ packer.StatusChanged += WriteStatus;
+
// Create cert file holder
//byte[] certsbuf = FileLocationToByteArray(currentdir + @"\cert.sys");
byte[] certsbuf = new byte[0xA00];
@@ -1135,34 +1247,63 @@ namespace NUS_Downloader
return;
}
for (int c = 0; c < cert_CA.Length; c++)
- {
certsbuf[c] = cert_CA[c];
- }
for (int c = 0; c < cert_CACP.Length; c++)
- {
certsbuf[c + 0x400] = cert_CACP[c];
- }
for (int c = 0; c < cert_CAXS.Length; c++)
- {
certsbuf[c + 0x700] = cert_CAXS[c];
- }
if (!(TotalCertValid(certsbuf)))
{
WriteStatus("Error: Cert array did not hash properly!");
return;
}
-
+ packer.Certs = certsbuf;
+
// Create ticket file holder
- byte[] cetkbuf = FileLocationToByteArray(totaldirectory + @"\cetk");
+ //byte[] cetkbuf = FileLocationToByteArray(totaldirectory + @"\cetk");
+ packer.Ticket = FileLocationToByteArray(totaldirectory + @"\cetk");
// Create tmd file holder
- byte[] tmdbuf = FileLocationToByteArray(totaldirectory + @"\" + tmdfilename);
+ //byte[] tmdbuf = FileLocationToByteArray(totaldirectory + @"\" + tmdfilename);
+ packer.TMD = FileLocationToByteArray(totaldirectory + @"\" + tmdfilename);
+
+ // Get the TMD variables in here instead...
+ int contentcount = ContentCount(packer.TMD);
+ //packer.TMDContentCount = ContentCount(packer.TMD);
+ string[] contentnames = GetContentNames(packer.TMD, contentcount);
+ //string[] contentsizes =
+ packer.tmdnames = GetContentNames(packer.TMD, contentcount);
+ packer.tmdsizes = GetContentSizes(packer.TMD, contentcount);
if (wadnamebox.Text.Contains("[v]") == true)
wadnamebox.Text = wadnamebox.Text.Replace("[v]", "v" + titleversion.Text);
-
+
+ // SaveAs Dialog
+ string wad_filename = totaldirectory + @"\" + RemoveIllegalCharacters(wadnamebox.Text);
+
+ if (!(String.IsNullOrEmpty(WAD_Saveas_Filename)))
+ {
+ packer.FileName = System.IO.Path.GetFileName(WAD_Saveas_Filename);
+ packer.Directory = WAD_Saveas_Filename.Replace(packer.FileName, "");
+ }
+ else
+ {
+ packer.Directory = totaldirectory;
+ packer.FileName = System.IO.Path.GetFileName(wad_filename);
+ }
+
+ // Gather contents...
+ byte[][] contents_array = new byte[contentcount][];
+ for (int a = 0; a < contentcount; a++)
+ {
+ contents_array[a] = FileLocationToByteArray(totaldirectory + contentnames[a]);
+ }
+ packer.Contents = contents_array;
+
+ packer.PackWAD();
+ /*
// Create wad file
- FileStream wadfs = new FileStream(totaldirectory + @"\" + RemoveIllegalCharacters(wadnamebox.Text), FileMode.Create);
+ FileStream wadfs = new FileStream(wad_filename, FileMode.Create);
// Add wad stuffs
WADHeader wad = new WADHeader();
@@ -1178,7 +1319,6 @@ namespace NUS_Downloader
// Need 64 byte boundary...
wadfs.Seek(2624, SeekOrigin.Begin);
- // Cert is 2560
// Write ticket at this point...
wad.TicketSize = 0x2A4;
wadfs.Write(cetkbuf, 0, wad.TicketSize);
@@ -1245,13 +1385,38 @@ namespace NUS_Downloader
byte[] datasize = InttoByteArray(wad.DataSize, 4);
wadfs.Write(datasize, 0, 4);
- // Finished.
- WriteStatus("WAD Created: " + wadnamebox.Text);
-
// Close filesystem...
wadfs.Close();
+
+ // Finished.
+ WriteStatus("WAD Created: " + wadnamebox.Text);
+ */
+ // Delete contents now...
+ if (deletecontentsbox.Checked)
+ {
+ WriteStatus("Deleting contents...");
+ File.Delete(totaldirectory + @"\" + tmdfilename);
+ File.Delete(totaldirectory + @"\cetk");
+ for (int a = 0; a < contentnames.Length; a++)
+ {
+ File.Delete(totaldirectory + @"\" + contentnames[a]);
+ }
+ WriteStatus(" - Contents have been deleted.");
+ string[] leftovers = Directory.GetFiles(totaldirectory);
+ if (leftovers.Length <= 0)
+ {
+ WriteStatus(" - Title directory was empty; Deleted.");
+ Directory.Delete(totaldirectory);
+ }
+ WriteStatus("All deletion completed.");
+ }
}
+ ///
+ /// Returns next 0x40 padded length.
+ ///
+ /// The currentlength.
+ ///
private long ByteBoundary(int currentlength)
{
// Gets the next 0x40 offset.
@@ -1270,6 +1435,12 @@ namespace NUS_Downloader
return (long)thelength;
}
+ ///
+ /// Int -> Byte[] (OLD)
+ ///
+ /// The int.
+ /// The array length.
+ ///
private byte[] InttoByteArray(int inte, int arraysize)
{
// Take integer and make into byte array
@@ -1299,6 +1470,9 @@ namespace NUS_Downloader
wadnamebox.Enabled = false;
wadnamebox.Text = "";
+
+ // Cannot doit
+ truchabox.Enabled = false;
}
}
@@ -1310,6 +1484,7 @@ namespace NUS_Downloader
// packbox.Checked = true;
packbox.Enabled = true;
decryptbox.Enabled = true;
+ truchabox.Enabled = true;
}
}
@@ -1357,104 +1532,6 @@ namespace NUS_Downloader
WriteStatus(" * Famfamfam for the Silk Icon Set.");
}
- private void getcerts_Click(object sender, EventArgs e)
- {
- // Get a certs.sys from NUS...
- /*
- // Directory stuff
- string currentdir = Application.StartupPath;
- if (currentdir.EndsWith(Convert.ToString(Path.DirectorySeparatorChar)) == false)
- currentdir += Path.DirectorySeparatorChar;
-
- // Create certs file
- FileStream certsfs = new FileStream(currentdir + @"\cert.sys", FileMode.Create);
-
- // Getting it from SystemMenu 3.2
- DownloadNUSFile("0000000100000002", "tmd.289", currentdir + @"\", 0, true);
- DownloadNUSFile("0000000100000002", "cetk", currentdir + @"\", 0, true);
-
- // Create ticket file holder
- byte[] cetkbuf = FileLocationToByteArray(currentdir + "cetk");
-
- // Create tmd file holder
- byte[] tmdbuf = FileLocationToByteArray(currentdir + "tmd.289");
-
- // Write CA cert...
- certsfs.Seek(0, SeekOrigin.Begin);
- certsfs.Write(tmdbuf, 0x628, 0x400);
- WriteStatus("Added CA Cert!");
-
- // Write CACP cert...
- certsfs.Seek(0x400, SeekOrigin.Begin);
- certsfs.Write(tmdbuf, 0x328, 0x300);
- WriteStatus("Added CACP Cert!");
-
- // Write CAXS cert...
- certsfs.Seek(0x700, SeekOrigin.Begin);
- certsfs.Write(cetkbuf, 0x2A4, 0x300);
- WriteStatus("Added CAXS Cert!");
- certsfs.Close();
-
- // Hash check the cert.sys...
- if (verifyMd5Hash(currentdir + @"\cert.sys", certs_MD5) == true)
- {
- WriteStatus("Certs File Successfully Created!");
- }
- else
- {
- WriteStatus("Error in Creating Certs File!");
- WriteStatus("Please report this error if you are sure it is not your internet connection");
- }
-
- // Re-enable controls...
- foreach (Control ctrl in this.Controls)
- {
- ctrl.Enabled = true;
- }
- getcerts.Visible = false;
- wadnamebox.Enabled = false;
-
- // Cleanup...
- File.Delete(currentdir + "cetk");
- File.Delete(currentdir + "tmd.289");
- */
- }
- /*
- static string getMd5Hash(string input)
- {
- System.Text.StringBuilder sb = new System.Text.StringBuilder();
- FileStream fs = new FileStream(input, FileMode.Open);
- MD5 md5 = new MD5CryptoServiceProvider();
- byte[] hash = md5.ComputeHash(fs);
- fs.Close();
- fs.Dispose();
- foreach (byte hex in hash)
- {
- //Returns hash in lower case.
- sb.Append(hex.ToString("x2"));
- }
- return sb.ToString();
- }
-
- // Verify a hash against a string.
- static bool verifyMd5Hash(string input, string hash)
- {
- // Hash the input.
- string hashOfInput = getMd5Hash(input);
-
- // Create a StringComparer an comare the hashes.
- StringComparer comparer = StringComparer.OrdinalIgnoreCase;
-
- if (0 == comparer.Compare(hashOfInput, hash))
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- */
private void packbox_CheckedChanged(object sender, EventArgs e)
{
if (packbox.Checked == true)
@@ -1468,6 +1545,7 @@ namespace NUS_Downloader
wadnamebox.Enabled = false;
wadnamebox.Text = "";
}
+
}
private void titleidbox_TextChanged(object sender, EventArgs e)
@@ -1480,6 +1558,11 @@ namespace NUS_Downloader
UpdatePackedName();
}
+ ///
+ /// Inits the crypto stuffz.
+ ///
+ /// The iv.
+ /// The key.
public void initCrypt(byte[] iv, byte[] key)
{
rijndaelCipher = new RijndaelManaged();
@@ -1491,6 +1574,11 @@ namespace NUS_Downloader
rijndaelCipher.IV = iv;
}
+ ///
+ /// Encrypts the specified plain bytes.
+ ///
+ /// The plain bytes.
+ ///
public byte[] Encrypt(byte[] plainBytes)
{
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
@@ -1503,6 +1591,11 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Decrypts the specified encrypted data.
+ ///
+ /// The encrypted data.
+ ///
public byte[] Decrypt(byte[] encryptedData)
{
ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
@@ -1515,6 +1608,11 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Reads the stream.
+ ///
+ /// The stream.
+ ///
public byte[] ReadFully(Stream stream)
{
byte[] buffer = new byte[32768];
@@ -1530,6 +1628,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Displays the bytes.
+ ///
+ /// The bytes.
+ /// What separates the bytes
+ ///
public string DisplayBytes(byte[] bytes, string spacer)
{
string output = "";
@@ -1540,6 +1644,11 @@ namespace NUS_Downloader
return output;
}
+ ///
+ /// Computes the SHA-1 Hash.
+ ///
+ /// A byte[].
+ ///
static public byte[] ComputeSHA(byte[] data)
{
SHA1 sha = new SHA1CryptoServiceProvider();
@@ -1547,6 +1656,11 @@ namespace NUS_Downloader
return sha.ComputeHash(data);
}
+ ///
+ /// Loads the common key from disc.
+ ///
+ /// The keyfile.
+ ///
public byte[] LoadCommonKey(string keyfile)
{
// Directory stuff
@@ -1569,6 +1683,9 @@ namespace NUS_Downloader
databaseStrip.Show(databaseButton, 2, 2);
}
+ ///
+ /// Clears the database strip.
+ ///
private void ClearDatabaseStrip()
{
SystemMenuList.DropDownItems.Clear();
@@ -1589,6 +1706,9 @@ namespace NUS_Downloader
VCArcadeMenuList.DropDownItems.Clear();
}
+ ///
+ /// Fills the database strip.
+ ///
private void FillDatabaseStrip()
{
XmlDocument xDoc = new XmlDocument();
@@ -1685,6 +1805,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Adds the tool strip item to strip.
+ ///
+ /// The type.
+ /// The additionitem.
+ /// The attributes.
void AddToolStripItemToStrip(int type, ToolStripMenuItem additionitem, XmlAttributeCollection attributes)
{
// Deal with VC list depth...
@@ -1801,6 +1927,10 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Mods WAD names to be official.
+ ///
+ /// The titlename.
public void OfficialWADNaming(string titlename)
{
if (titlename.Contains("IOS"))
@@ -1908,21 +2038,12 @@ namespace NUS_Downloader
}
}
- void HandleMismatch(int contentsize, int actualsize)
- {
- if (contentsize != actualsize)
- {
- if ((contentsize - actualsize) > 16)
- {
- statusbox.Text += " (BAD Mismatch) (Dif: " + (contentsize - actualsize);
- }
- else
- {
- statusbox.Text += " (Safe Mismatch)";
- }
- }
- }
-
+ ///
+ /// Gathers the region based on index
+ ///
+ /// The index.
+ /// XmlDocument with database inside
+ /// Region desc
string RegionFromIndex(int index, XmlDocument databasexml)
{
/* Typical Region XML
@@ -1960,6 +2081,9 @@ namespace NUS_Downloader
return "XX (Error)";
}
+ ///
+ /// Loads the region codes.
+ ///
private void LoadRegionCodes()
{
XmlDocument xDoc = new XmlDocument();
@@ -1981,6 +2105,11 @@ namespace NUS_Downloader
titleidbox.Text = titleidbox.Text.Substring(0, 14) + e.ClickedItem.Text.Substring(0, 2);
}
+ ///
+ /// Removes the illegal characters.
+ ///
+ /// removes the illegal chars
+ /// legal string
private string RemoveIllegalCharacters(string databasestr)
{
// Database strings must contain filename-legal characters.
@@ -1992,6 +2121,11 @@ namespace NUS_Downloader
return databasestr;
}
+ ///
+ /// Zeroes the signature in TMD/TIK.
+ ///
+ /// TMD/TIK
+ /// Zeroed TMD/TIK
private byte[] ZeroSignature(byte[] tmdortik)
{
// Write all 0x00 to signature...
@@ -2005,6 +2139,11 @@ namespace NUS_Downloader
return tmdortik;
}
+ ///
+ /// Trucha Signs a TMD/TIK
+ ///
+ /// The tmdortik.
+ /// Fake-signed byte[]
private byte[] TruchaSign(byte[] tmdortik)
{
// Loop through 2 bytes worth of numbers until hash starts with 0x00...
@@ -2036,6 +2175,12 @@ namespace NUS_Downloader
return tmdortik;
}
+ ///
+ /// Increments at an index.
+ ///
+ /// The array.
+ /// The index.
+ ///
static public byte[] incrementAtIndex(byte[] array, int index)
{
if (array[index] == byte.MaxValue)
@@ -2231,13 +2376,6 @@ namespace NUS_Downloader
testtik.Close();
}
- // C# to convert a string to a byte array.
- public static byte[] StrToByteArray(string str)
- {
- System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
- return encoding.GetBytes(str);
- }
-
private void button7_Click(object sender, EventArgs e)
{
// Proceed with process (BG worker waits for form to resize)
@@ -2251,6 +2389,10 @@ namespace NUS_Downloader
statusbox.Text = "";
}
+ ///
+ /// Makes everything disabled/enabled.
+ ///
+ /// if set to true [enabled].
private void SetEnableforDownload(bool enabled)
{
// Disable things the user should not mess with during download...
@@ -2266,6 +2408,10 @@ namespace NUS_Downloader
decryptbox.Enabled = enabled;
}
+ ///
+ /// Makes tooltips disappear in the database, as many contain danger tag info.
+ ///
+ /// if set to true [enabled].
private void ShowInnerToolTips(bool enabled)
{
// Force tooltips to GTFO in sub menus...
@@ -2284,6 +2430,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Selects the database item image.
+ ///
+ /// if set to true [ticket].
+ /// if set to true [danger].
+ /// Correct Image
private System.Drawing.Image SelectItemImage(bool ticket, bool danger)
{
// All is good, go green...
@@ -2305,6 +2457,11 @@ namespace NUS_Downloader
return null;
}
+ ///
+ /// Loads a file into a byte[]
+ ///
+ /// The filename.
+ /// byte[] of file contents
private byte[] FileLocationToByteArray(string filename)
{
FileStream fs = File.OpenRead(filename);
@@ -2313,6 +2470,9 @@ namespace NUS_Downloader
return filebytearray;
}
+ ///
+ /// Updates the name of the packed WAD in the textbox.
+ ///
private void UpdatePackedName()
{
// Change WAD name if applicable
@@ -2343,7 +2503,12 @@ namespace NUS_Downloader
}
- // This is WIP code/theory...
+ ///
+ /// Generates a ticket from TitleKey/ID
+ ///
+ /// The enc title key.
+ /// The title ID.
+ /// New Ticket
private byte[] GenerateTicket(byte[] EncTitleKey, byte[] TitleID)
{
byte[] Ticket = new byte[0x2A4];
@@ -2403,6 +2568,10 @@ namespace NUS_Downloader
FillContentInfo(tmd);
}
+ ///
+ /// Fills the content editor with info from TMD
+ ///
+ /// The TMD.
private void FillContentInfo(byte[] tmd)
{
// Clear anything existing...
@@ -2603,6 +2772,11 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Checks for a hex string.
+ ///
+ /// The test string
+ /// Whether string is hex or not.
public bool OnlyHexInString(string test)
{
return System.Text.RegularExpressions.Regex.IsMatch(test, @"\A\b[0-9a-fA-F]+\b\Z");
@@ -2640,6 +2814,9 @@ namespace NUS_Downloader
UpdateTMDContents();
}
+ ///
+ /// Updates the TMD contents.
+ ///
private void UpdateTMDContents()
{
// Write changes to TMD of contents...
@@ -2903,21 +3080,12 @@ namespace NUS_Downloader
testtmd.Close();
}
- /* Pad Byte[] to specific alignment...
- private byte[] AlignByteArray(byte[] content, int alignto)
- {
- long thelength = content.Length - 1;
- long remainder = thelength % alignto;
-
- while (remainder != 0)
- {
- thelength += 1;
- remainder = thelength % alignto;
- }
- Array.Resize(ref content, (int)thelength);
- return content;
- } */
-
+ ///
+ /// Pads to multiple of....
+ ///
+ /// The binary.
+ /// The pad amount.
+ /// Padded byte[]
private byte[] PadToMultipleOf(byte[] src, int pad)
{
int len = (src.Length + pad - 1) / pad * pad;
@@ -2971,6 +3139,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Determines whether OS is win7.
+ ///
+ ///
+ /// true if OS = win7; otherwise, false.
+ ///
private bool IsWin7()
{
return (Environment.OSVersion.VersionString.Contains("6.1") == true);
@@ -3177,6 +3351,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Does byte[] contain byte[]?
+ ///
+ /// The large byte[].
+ /// Small byte[] which may be in large one.
+ /// messed up int[] with offsets.
private int[] ByteArrayContainsByteArray(byte[] bigboy, byte[] littleman)
{
// bigboy.Contains(littleman);
@@ -3200,6 +3380,13 @@ namespace NUS_Downloader
return offset;
}
+ ///
+ /// Patches the binary.
+ ///
+ /// The content.
+ /// The offset.
+ /// The newvalues.
+ ///
private byte[] PatchBinary(byte[] content, int offset, byte[] newvalues)
{
for (int a = 0; a < newvalues.Length; a++)
@@ -3210,6 +3397,9 @@ namespace NUS_Downloader
return content;
}
+ ///
+ /// Recalculates the indices.
+ ///
private void RecalculateIndices()
{
for (int a = 0; a < contentsEdit.Items.Count; a++)
@@ -3226,6 +3416,10 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Retrieves the new database via WiiBrew.
+ ///
+ /// Database as a String
private string RetrieveNewDatabase()
{
// Retrieve Wiibrew database page source code
@@ -3288,6 +3482,11 @@ namespace NUS_Downloader
LoadTitleFromTMD();
}
+ ///
+ /// Sends the SOAP request to NUS.
+ ///
+ /// The Request
+ ///
public string SendSOAPRequest(string soap_xml)
{
System.Net.HttpWebRequest req = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create("http://nus.shop.wii.com:80/nus/services/NetUpdateSOAP");
@@ -3391,9 +3590,12 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Scans for certs in TMD/TIK.
+ ///
+ /// The tmdortik.
private void ScanForCerts(byte[] tmdortik)
{
-
// For some reason a few 00s are cut off, so pad it up to be safe.
tmdortik = PadToMultipleOf(tmdortik, 16);
@@ -3432,7 +3634,7 @@ namespace NUS_Downloader
}
// Search for cert_CA
- if ((!(tmdortik.Length < 0x400)) && ((Convert.ToBase64String(cert_CA) != Convert.ToBase64String(cert_CA_sha1))))
+ if ((!(tmdortik.Length < 0x400)) && ((Convert.ToBase64String(ComputeSHA(cert_CA)) != Convert.ToBase64String(cert_CA_sha1))))
{
for (int a = 0; a < (tmdortik.Length - 0x400); a++)
{
@@ -3451,6 +3653,10 @@ namespace NUS_Downloader
}
}
+ ///
+ /// Checks whether the certs are obtained.
+ ///
+ ///
private bool CertsValid()
{
if (Convert.ToBase64String(ComputeSHA(cert_CA)) != Convert.ToBase64String(cert_CA_sha1))
@@ -3462,6 +3668,11 @@ namespace NUS_Downloader
return true;
}
+ ///
+ /// Checks the whole cert file for validity.
+ ///
+ /// The cert_sys.
+ /// Valid Cert state.
private bool TotalCertValid(byte[] cert_sys)
{
if (Convert.ToBase64String(ComputeSHA(cert_sys)) != Convert.ToBase64String(cert_total_sha1))
@@ -3469,6 +3680,11 @@ namespace NUS_Downloader
return true;
}
+ ///
+ /// Looks for a title's name by TitleID in Database.
+ ///
+ /// The titleid.
+ /// Existing name; else null
private string NameFromDatabase(string titleid)
{
XmlDocument xDoc = new XmlDocument();
@@ -3514,6 +3730,7 @@ namespace NUS_Downloader
{
case "name":
return ChildrenOfTheNode[z].InnerText;
+ default:
break;
}
}
@@ -3522,5 +3739,11 @@ namespace NUS_Downloader
}
return null;
}
+
+ private void packbox_EnabledChanged(object sender, EventArgs e)
+ {
+ saveaswadbox.Enabled = packbox.Enabled;
+ deletecontentsbox.Enabled = packbox.Enabled;
+ }
}
}
diff --git a/NUS Downloader/NUS Downloader.csproj b/NUS Downloader/NUS Downloader.csproj
index dbbdd8e..e603db5 100644
--- a/NUS Downloader/NUS Downloader.csproj
+++ b/NUS Downloader/NUS Downloader.csproj
@@ -95,6 +95,7 @@
Settings.settings
True
+
diff --git a/NUS Downloader/WADPacker.cs b/NUS Downloader/WADPacker.cs
new file mode 100644
index 0000000..7a25aad
--- /dev/null
+++ b/NUS Downloader/WADPacker.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace NUS_Downloader
+{
+ ///
+ /// Class for handling WAD Packaging.
+ ///
+ class WADPacker
+ {
+ // WAD Component Variables
+ private byte[] Certsys;
+ public byte[] Certs { get { return Certsys;} set { Certsys = value; CertChainSize = Certsys.Length; } }
+ private byte[] tmd;
+ public byte[] TMD { get { return tmd; }
+ set {
+ tmd = value;
+ TMDContentCount = ContentCount(TMD);
+ TMDSize = 484 + (TMDContentCount * 36);
+ } }
+ public byte[] Ticket; //{ get { return Ticket; } set { Ticket = value; } }
+ private int TMDContentCount; //{ get { return TMDContentCount; } set { TMDContentCount = value; } }
+
+ // WAD Contents
+ private byte[][] TMDContents;
+ public byte[][] Contents { get { return TMDContents; }
+ set {
+ TMDContents = value;
+ for (int a = 0; a < TMDContents.Length; a++)
+ {
+ DataSize += TMDContents[a].Length;
+ }
+ } }
+
+ // WAD Saving Variables
+ public string Directory; //{ get { return Directory; } set { Directory = value; } }
+ public string FileName; //{ get { return FileName; } set { FileName = value; } }
+
+ // TMD Informations
+ public string[] tmdnames; //{ get { return tmdnames; } set { tmdnames = value; } }
+ public string[] tmdsizes; //{ get { return tmdsizes; } set { tmdsizes = value; } }
+
+ // WAD Header Variables
+ private const int HeaderSize = 0x20;
+ private int CertChainSize; //{ get { return CertChainSize; } set { CertChainSize = value; } }
+ private const int TicketSize = 0x2A4;
+ private int TMDSize; //{ get { return TMDSize; } set { TMDSize = value; } }
+ private int DataSize; //{ get { return DataSize; } set { DataSize = value; } }
+ private byte[] WADMagic = new byte[8] { 0x00, 0x00, 0x00, 0x20, 0x49, 0x73, 0x00, 0x00 };
+ private byte[] RESERVED_CONST = new byte[4] { 0x00, 0x00, 0x00, 0x00 };
+ private byte[] TIKSIZE_CONST = new byte[4] { 0x00, 0x00, 0x02, 0xA4 };
+
+ // Report Status back in EventHandler
+ public delegate void StatusChangedEventHandler(string status);
+ public event StatusChangedEventHandler StatusChanged;
+
+
+ ///
+ /// Pads byte[].
+ ///
+ /// The byte[] or binary to be padded.
+ /// How much to pad by.
+ /// Padded byte[]
+ private long PadToMultipleOf(long src, int pad)
+ {
+ long len = (src + pad - 1) / pad * pad;
+ return len;
+ }
+
+ ///
+ /// Converts an integer into its equivilant byte array.
+ ///
+ /// The integer
+ /// Length you desire the byte[] to be.
+ ///
+ private byte[] ConvertInttoByteArray(int theInt, int arrayLen)
+ {
+ byte[] resultArray = new byte[arrayLen];
+ for (int i = arrayLen - 1; i >= 0; i--)
+ {
+ resultArray[i] = (byte)((theInt >> (8 * i)) & 0xFF);
+ }
+ Array.Reverse(resultArray);
+
+ // Fix duplication, rewrite extra to 0x00;
+ if (arrayLen > 4)
+ {
+ for (int i = 0; i < (arrayLen - 4); i++)
+ resultArray[i] = 0x00;
+ }
+ return resultArray;
+ }
+
+ ///
+ /// Handles the size mismatch.
+ ///
+ /// The contentsize.
+ /// The actualsize.
+ void HandleMismatch(int contentsize, int actualsize)
+ {
+ if (contentsize != actualsize)
+ if ((contentsize - actualsize) > 16)
+ StatusChanged(String.Format(" (BAD Mismatch) (Dif: {0}", (contentsize - actualsize)));
+ //else
+ //statusbox.Text += " (Safe Mismatch)";
+ }
+
+ ///
+ /// Returns content count of TMD
+ ///
+ /// The TMD.
+ /// int Count of Contents
+ private int ContentCount(byte[] tmd)
+ {
+ return (tmd[0x1DE] * 256) + tmd[0x1DF];
+ }
+
+ ///
+ /// Packs the WAD file, saves it to specified location.
+ ///
+ public void PackWAD()
+ {
+ //StatusChanged("Beginning WAD Pack...");
+
+ if ((String.IsNullOrEmpty(Directory)) || (String.IsNullOrEmpty(FileName)))
+ {
+ StatusChanged("ERROR: No Directory/FileName provided!");
+ return;
+ }
+
+ FileStream wadfs = new FileStream((Directory + FileName), FileMode.Create);
+
+ // Seek the beginning of the WAD...
+ wadfs.Seek(0, SeekOrigin.Begin);
+
+ // Write initial part of header (WADType)
+ wadfs.Write(WADMagic, 0, WADMagic.Length);
+
+ // Write CertChainLength
+ wadfs.Seek(0x08, SeekOrigin.Begin);
+ byte[] chainsize = ConvertInttoByteArray(CertChainSize, 4);
+ wadfs.Write(chainsize, 0, chainsize.Length);
+
+ // Write res
+ wadfs.Seek(0x0C, SeekOrigin.Begin);
+ wadfs.Write(RESERVED_CONST, 0, RESERVED_CONST.Length);
+
+ // Write ticketsize
+ wadfs.Seek(0x10, SeekOrigin.Begin);
+ wadfs.Write(TIKSIZE_CONST, 0, TIKSIZE_CONST.Length);
+
+ // Write tmdsize
+ wadfs.Seek(0x14, SeekOrigin.Begin);
+ byte[] tmdsize = ConvertInttoByteArray(TMDSize, 4);
+ wadfs.Write(tmdsize, 0, tmdsize.Length);
+
+ // Write data size
+ wadfs.Seek(0x18, SeekOrigin.Begin);
+ wadfs.Write(ConvertInttoByteArray(DataSize, 4), 0, 4);
+ StatusChanged(" - WAD Header wrote (0x00)");
+
+ // Write cert[] to 0x40.
+ wadfs.Seek(0x40, SeekOrigin.Begin);
+ wadfs.Write(Certs, 0, Certs.Length);
+ StatusChanged(String.Format(" - Certs wrote (0x{0})", Convert.ToString(64, 16)));
+
+ // Pad to next 64 byte boundary.
+ wadfs.Seek(2624, SeekOrigin.Begin);
+
+ // Write ticket at this point...
+ wadfs.Write(Ticket, 0, TicketSize);
+ StatusChanged(String.Format(" - Ticket wrote (0x{0})", Convert.ToString((wadfs.Length - 0x2A4), 16)));
+
+ // Pad to next 64 byte boundary.
+ wadfs.Seek(PadToMultipleOf(wadfs.Length, 64), SeekOrigin.Begin);
+
+ // Write TMD at this point...
+ wadfs.Write(TMD, 0, TMDSize);
+ StatusChanged(String.Format(" - TMD wrote (0x{0})", Convert.ToString((wadfs.Length - TMDSize), 16)));
+
+ // Add the individual contents
+ for (int a = 0; a < TMDContentCount; a++)
+ {
+ // Pad to next 64 byte boundary...
+ wadfs.Seek(PadToMultipleOf(wadfs.Length, 64), SeekOrigin.Begin);
+
+ wadfs.Write(Contents[a], 0, Contents[a].Length);
+
+ StatusChanged(String.Format(" - {0} wrote (0x{1})", tmdnames[a], Convert.ToString((wadfs.Length - Contents[a].Length), 16)));
+ HandleMismatch(int.Parse(tmdsizes[a], System.Globalization.NumberStyles.HexNumber), Contents[a].Length);
+ }
+
+ // Close filesystem...
+ wadfs.Close();
+
+ // Finished.
+ StatusChanged("WAD Created: " + FileName);
+ }
+ }
+}