private void Rebuild() { sio.FileStream fsw = null; sio.BinaryWriter bww = null; sio.FileStream fsr = null; sio.BinaryReader brr = null; sio.BinaryWriter brw = null; sio.MemoryStream ms = null; sio.BinaryReader br = null; sio.BinaryWriter bw = null; sio.FileInfo fi; int dataLen; bool dataStartPositioned = true; byte[] tb, b; string tocPath; int mod, modAct; int bytesWritten; int maxBR, curBR, temBR; bool error = false; string errorText = ""; int idx; int i, j; int m; ModCB Mod = delegate(int val) { m = val % filesMod; if (m == 0) { return(val); } else { return(val + (filesMod - m)); } }; try { fsw = new sio.FileStream(imgPath, sio.FileMode.Create, sio.FileAccess.Write, sio.FileShare.None); bww = new sio.BinaryWriter(fsw, ste.Default); fsr = new sio.FileStream(toc.fils[2].path, sio.FileMode.Open, sio.FileAccess.ReadWrite, sio.FileShare.None); brr = new sio.BinaryReader(fsr, ste.Default); ms = new sio.MemoryStream(brr.ReadBytes((int)fsr.Length), true); br = new sio.BinaryReader(ms, ste.Default); bw = new sio.BinaryWriter(ms, ste.Default); ms.Position = 0x400; toc.fils[2].pos = 0; toc.fils[3].pos = 0x2440; bw.WriteInt32BE(toc.fils[3].len); //ldr len ms.Position += 0x1c; i = Mod(0x2440 + toc.fils[3].len); bw.WriteInt32BE(i); //dol start toc.fils[4].pos = i; i = Mod(i + toc.fils[4].len); bw.WriteInt32BE(i); //toc start tocPath = toc.fils[5].path; toc.fils[5].path = sio.Path.GetTempPath() + "game.toc"; toc.fils[5].pos = i; toc.dataStart = 0; tb = ReGenTOC(toc.fils[5].pos, out toc.fils[5].len, ref toc.dataStart, out toc.totalLen); if (appendImage) { dataLen = toc.totalLen - toc.dataStart; toc.dataStart = maxImageSize - dataLen; tb = ReGenTOC(toc.fils[5].pos, out toc.fils[5].len, ref toc.dataStart, out toc.totalLen); } bw.WriteInt32BE(toc.fils[5].len); //toc len bw.WriteInt32BE(toc.fils[5].len); //total toc len ms.Position += 0x04; bw.WriteInt32BE(toc.dataStart); //data start ms.WriteTo(fsw); if (miOptionsModifySystemFiles.Checked) { fsr.Position = 0; ms.WriteTo(fsr); brr.Close(); fsr.Close(); fsr = new sio.FileStream(tocPath, sio.FileMode.Create, sio.FileAccess.Write, sio.FileShare.None); brw = new sio.BinaryWriter(fsr, ste.Default); brw.Write(tb); brw.Close(); fsr.Close(); } else { brr.Close(); fsr.Close(); } br.Close(); bw.Close(); ms.Close(); brr.Close(); fsr.Close(); bytesWritten = (int)fsw.Position; //if (resPath.Substring(0, 2).ToLower() == imgPath.Substring(0, 2).ToLower()) // maxBR = 0x0800000; //else maxBR = 0x8000; curBR = maxBR - bytesWritten; ResetProgressBar(0, 100, 0); mod = (int)Math.Floor((float)toc.totalLen / sspbProgress.Maximum); mod = (mod | (maxBR - 1)) + 1; i = (int)Math.Ceiling((float)toc.totalLen / mod); if (i < 100) { ResetProgressBar(0, i, 0); } modAct = (int)Math.Floor((float)toc.totalLen / 1000); modAct = (modAct | (maxBR - 1)) + 1; UpdateActionLabel("Rebuilding…"); if (toc.totalLen > maxImageSize || toc.totalLen < 0) { errorText = "The resulting image is too large"; error = true; } idx = 3; if (!error) { for (i = 3; i < toc.fils.Count; i++) { if (!addressRebuild) { idx = i; } if (!toc.fils[i].isDir) { fi = new sio.FileInfo(toc.fils[idx].path); if (!fi.Exists) { errorText = string.Format("File '{0}' not found", fi.FullName); error = true; break; } fsr = new sio.FileStream(toc.fils[idx].path, sio.FileMode.Open, sio.FileAccess.Read, sio.FileShare.Read); brr = new sio.BinaryReader(fsr, ste.Default); if (!dataStartPositioned) { m = filesMod - ((int)fsw.Position % filesMod); for (j = 0; j < m; j++) { bww.Write((byte)0); } bytesWritten += maxBR - (bytesWritten % maxBR); m = (int)fsw.Position; b = new byte[maxBR]; for (j = m; j < toc.dataStart; j += maxBR) { fsw.Write(b, 0, maxBR); bytesWritten += maxBR; if (bytesWritten % modAct == 0) { UpdateActionLabel(string.Format("Rebuilding: {0}/{1} bytes written", bytesWritten, toc.totalLen)); } if (bytesWritten % mod == 0) { UpdateProgressBar(1); } if (escapePressed) { if (ShowMTMBox("Cancel current process?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, DialogResult.Yes)) { stopCurrProc = true; } } if (stopCurrProc) { break; } } if (!stopCurrProc) { fsw.Write(b, 0, toc.dataStart % maxBR); curBR = maxBR; bytesWritten = toc.dataStart + (maxBR - (toc.dataStart % maxBR)) - maxBR; fsw.Position = toc.dataStart; dataStartPositioned = true; } } if (stopCurrProc) { break; } if (fsw.Position != toc.fils[idx].pos) { m = toc.fils[idx].pos - (int)fsw.Position; for (j = 0; j < m; j++) { bww.Write((byte)0); } curBR -= m; bytesWritten += m; } if (curBR < 0) { errorText = "Oooopps)\r\nPlease mail me info about this image"; error = true; break; } while (fsr.Position < fsr.Length) { b = brr.ReadBytes(curBR); temBR = b.Length; bytesWritten += temBR; if (temBR == curBR) { curBR = maxBR; if (bytesWritten % modAct == 0) { UpdateActionLabel(string.Format("Rebuilding: {0}/{1} bytes written", bytesWritten, toc.totalLen)); if (stopCurrProc) { break; } } if (bytesWritten % mod == 0) { UpdateProgressBar(1); } } else { curBR -= temBR; } bww.Write(b); if (escapePressed) { if (ShowMTMBox("Cancel current process?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2, DialogResult.Yes)) { stopCurrProc = true; } } } brr.Close(); fsr.Close(); if (stopCurrProc) { break; } if (addressRebuild) { idx = toc.fils[i].nextIdx; } if (i == 5) { dataStartPositioned = false; } } } } m = filesMod - ((int)fsw.Position % filesMod); for (i = 0; i < m; i++) { bww.Write((byte)0); } fi = new sio.FileInfo(toc.fils[5].path); if (fi.Exists) { sio.File.Delete(toc.fils[5].path); toc.fils[5].path = tocPath; } } catch (Exception ex) { error = true; errorText = ex.Message; } if (!error && !stopCurrProc) { if (appendImage) { fsw.SetLength(maxImageSize); //1459978240 } } if (bww != null) { bww.Close(); } if (fsw != null) { fsw.Close(); } if (brr != null) { brr.Close(); } if (brw != null) { brw.Close(); } if (fsr != null) { fsr.Close(); } if (br != null) { br.Close(); } if (bw != null) { bw.Close(); } if (ms != null) { ms.Close(); } ResetControlsRebuild(error, errorText); isRebuilding = false; stopCurrProc = false; }
private byte[] ReGenTOC(int tocStart, out int tocLen, ref int dataStart, out int totalLen) { int m; ModCB Mod = delegate(int val) { m = val % filesMod; if (m == 0) { return(val); } else { return(val + (filesMod - m)); } }; sio.MemoryStream ms; sio.BinaryReader br; sio.BinaryWriter bw; sio.FileStream fs; byte[] tb = new byte[0x40000]; byte[] res; long pos, newPos; int rawPos; int itemNum, shift; int idx; int[] poses = new int[0x8000]; int namesTableEntryCount; int namesTableStart; int itemNamePtr; int itemPos; int itemLen; string itemName; ms = new sio.MemoryStream(tb, true); br = new sio.BinaryReader(ms, ste.Default); bw = new sio.BinaryWriter(ms, ste.Default); itemLen = 0; for (int i = 6; i < toc.fils.Count; i++) { itemLen += toc.fils[i].name.Length + 1; } itemNum = 6; shift = itemNum - 1; namesTableEntryCount = toc.fils.Count - shift; namesTableStart = (namesTableEntryCount * 12); tocLen = namesTableStart + itemLen; if (dataStart == 0) { dataStart = Mod(tocStart + tocLen); } itemNamePtr = 0; bw.Write(1); bw.Write(0); bw.WriteInt32BE(namesTableEntryCount); pos = ms.Position; rawPos = dataStart; idx = toc.fils[5].nextIdx; if (!addressRebuild) { for (int i = 6; i < toc.fils.Count; i++) { if (!toc.fils[i].isDir) { itemLen = toc.fils[i].len; poses[i] = rawPos; rawPos = Mod(rawPos + itemLen); } } } else { for (int i = 6; i < toc.fils.Count; i++) { if (!toc.fils[i].isDir) { itemLen = toc.fils[idx].len; poses[idx] = rawPos; rawPos = Mod(rawPos + itemLen); idx = toc.fils[i].nextIdx; } } } for (int i = 6; i < toc.fils.Count; i++) { ms.Position = pos; if (toc.fils[i].isDir) { itemNamePtr = (itemNamePtr & 0xffffff) | 0x01000000; itemPos = (toc.fils[i].pos > 0) ? toc.fils[i].pos - shift : toc.fils[i].pos; itemLen = toc.fils[i].len - shift; itemName = toc.fils[i].name; } else { itemNamePtr = (itemNamePtr & 0xffffff); itemPos = poses[i]; toc.fils[i].pos = itemPos; itemLen = toc.fils[i].len; itemName = toc.fils[i].name; } bw.WriteInt32BE(itemNamePtr); bw.WriteInt32BE(itemPos); bw.WriteInt32BE(itemLen); pos = ms.Position; newPos = (itemNamePtr & 0xffffff) + namesTableStart; ms.Position = newPos; bw.WriteStringNT(itemName); itemNamePtr += itemName.Length + 1; } totalLen = rawPos; res = new byte[tocLen]; Array.Copy(tb, res, tocLen); fs = new sio.FileStream(toc.fils[5].path, sio.FileMode.Create, sio.FileAccess.Write, sio.FileShare.None); fs.Write(res, 0, tocLen); fs.Close(); return(res); }