/// <summary> /// Builds the package /// </summary> /// <param name="xParams"></param> /// <param name="ContentType"></param> /// <returns></returns> public bool Create(RSAParams xParams, PackageType ContentType) { if (BaseImage == null) throw new Exception("No image"); if (!xParams.Valid) throw CryptoExcepts.ParamError; if (ContentType != PackageType.HDDInstalledGame && ContentType != PackageType.OriginalXboxGame && ContentType != PackageType.GamesOnDemand && ContentType != PackageType.SocialTitle) return false; if (xActive) return false; xActive = true; DJsIO x = null; DJsIO h = null; try { string outlocale = OutLocation.Replace('\\', '/'); if (outlocale[outlocale.Length - 1] == '/') outlocale = outlocale.Substring(0, outlocale.Length - 1); outlocale += '/' + ((uint)ContentType).ToString("X8"); string DataFolder = outlocale + "/" + xHeader.TitleID.ToString("X8") + ".data"; if (!VariousFunctions.xCheckDirectory(OutLocation)) throw IOExcepts.CreateError; if (!VariousFunctions.xCheckDirectory(DataFolder)) throw IOExcepts.CreateError; uint xBlockCount = 0; uint xDataFileCount = 0; long xDataLength = 0; BaseImage.xIO.Position = BaseImage.baseoffset; while (BaseImage.xIO.Position < BaseImage.xIO.Length) { if ((xBlockCount % Constants.SVODBL[1]) == 0) { if (x != null) { for (int i = 0; i < 0xCB; i++) { x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 0); byte[] Data1 = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 1); x.Write(Data1); } x.Flush(); xDataLength += x.Length; x.Close(); } x = new DJsIO(DataFolder + SVODFuncs.formatstring(xDataFileCount), DJFileMode.Create, true); xDataFileCount++; } x.Position = SVODFuncs.GenerateDataOffset(xBlockCount); byte[] Data = BaseImage.xIO.ReadBytes(0x1000); x.Write(Data); x.Position = SVODFuncs.GenerateHashOffset(xBlockCount, 0); x.Write(SHA1Quick.ComputeHash(Data)); xBlockCount++; } if (xBlockCount == 0) { x.Close(); return (xActive = false); } x.Flush(); xDataLength += x.Length; int lvlct = (int)((((xBlockCount % Constants.SVODBL[1]) - 1) / Constants.SVODBL[0]) + 1); for (int i = 0; i < lvlct; i++) { x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 0); byte[] Data1 = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); x.Position = SVODFuncs.GenerateHashOffset((uint)(i * Constants.SVODBL[0]), 1); x.Write(Data1); } x.Flush(); x.Close(); byte[] Hash = null; for (int i = (int)(xDataFileCount - 1); i >= 0; i--) { x = new DJsIO(DataFolder + SVODFuncs.formatstring((uint)i), DJFileMode.Open, true); if (Hash != null) { x.Position = 0xFF0; x.Write(Hash); x.Flush(); } x.Position = 0; Hash = SHA1Quick.ComputeHash(x.ReadBytes(0x1000)); } xHeader.DataFileSize = xDataLength; xHeader.DataFileCount = xDataFileCount; xHeader.xThisType = ContentType; h = new DJsIO(outlocale + "/" + xHeader.TitleID.ToString("X8"), DJFileMode.Create, true); xHeader.Write(ref h); h.SetLength(0xB000); h.Position = 0x340; h.Write((uint)0xAD0E); h.Position = 0x379; h.Write(new byte[] { 0x24, 5, 5, 0x11 }); h.Write(Hash); h.Write((byte)((Deviation == 0) ? 0 : 0x40)); h.WriteUInt24(xBlockCount); h.Write(Deviation, false); h.Position = 0x344; byte[] xHash = SHA1Quick.ComputeHash(h.ReadBytes((int)(h.Length - 0x344))); h.Position = 0x32C; h.Write(xHash); h.Flush(); h.Position = 0x22C; xHash = SHA1Quick.ComputeHash(h.ReadBytes(0x118)); h.Position = 4; if (xParams.Type == PackageMagic.CON) { h.Write(xParams.Certificate); h.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { h.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); h.Write(new byte[0x128]); } h.IsBigEndian = true; h.Position = 0; h.Write(((uint)xParams.Type)); xHeader.xMagic = xParams.Type; h.Flush(); h.Close(); return !(xActive = false); } catch { if (x != null) x.Close(); if (h != null) h.Close(); return (xActive = false); } }
/// <summary> /// Writes the STFS Descriptor to make perm. changes /// </summary> /// <returns></returns> bool xWriteDescriptor(ref DJsIO io) { AddToLog("Writing new Descriptor"); io.Position = 0x379; xSTFSStruct.xDirectoryBlockCount = (ushort)xCurEntBlckCnt; io.Write(xSTFSStruct.GetData()); io.Flush(); /*switched0.Clear(); switched1.Clear(); switched2 = false;*/ return true; }
internal bool xExtract(DJsIO xIO) { if (xSize == 0) return true; try { xIO.Position = 0; xref.xIO.Position = xref.GenerateDataOffset(xStartBlock); int ct = (((xSize - 1) / GDFImage.blocksize) + 1); for (int i = 0; i < (ct - 1); i++) xIO.Write(xref.xIO.ReadBytes(GDFImage.blocksize)); xIO.Write(xref.xIO.ReadBytes(((xSize - 1) % GDFImage.blocksize) + 1)); xIO.Flush(); return true; } catch { return false; } }
internal bool xExtract(DJsIO xIOOut) { if (!Opened && !ReadBlocks()) return false; try { // Gets data and writes it xIOOut.Position = 0; for (uint i = 0; i < xBlockCount; i++) { xPackage.xIO.Position = xPackage.GenerateDataOffset(xBlocks[i].ThisBlock); if (i < (xBlockCount - 1)) xIOOut.Write(xPackage.xIO.ReadBytes(0x1000)); else xIOOut.Write(xPackage.xIO.ReadBytes((((Size - 1) % 0x1000) + 1))); } xIOOut.Flush(); ClearBlocks(); return true; } catch { ClearBlocks(); return false; } }
/// <summary> /// Produces a file via entries /// </summary> /// <param name="xFile"></param> /// <returns></returns> bool xEntriesToFile(out DJsIO xFile) { xFile = null; try { // Not much explaination is needed, just writes entries into a file xFile = new DJsIO(true); ushort xCurEnt = 0; foreach (FolderEntry v in xFolderDirectory) { if (v.IsDeleted) continue; xFile.Position = 0x40 * xCurEnt; // Reorders the folders to current entry // Note: Don't have to do this, but I think it's sexy to handle folders at top of directory foreach (FolderEntry y in xFolderDirectory) { if (y.xFolderPointer == v.EntryID) y.xFolderPointer = xCurEnt; } foreach (FileEntry y in xFileDirectory) { if (y.xFolderPointer == v.EntryID) y.xFolderPointer = xCurEnt; } // Sets current entry v.xEntryID = xCurEnt; // Writes xFile.Write(v.GetEntryData()); xCurEnt++; } for (int i = 0; i < xFolderDirectory.Count; i++) { // Write new folder pointer xFile.Position = (0x40 * i) + 0x32; xFile.Write(xFolderDirectory[i].xFolderPointer); } foreach (FileEntry y in xFileDirectory) { if (y.IsDeleted) continue; // Sets y.xEntryID = xCurEnt; xFile.Position = 0x40 * xCurEnt; // Writes xFile.Write(y.GetEntryData()); xCurEnt++; } xFile.Flush(); return true; } catch { return false; } }
bool xEncrypt(ref DJsIO xNewPayload) { try { if (!xSuccess) return false; if (xIsLive) { byte[] xService = (ThisType == AccountType.Stock ? new byte[] { 0x50, 0x52, 0x4F, 0x44 } : // PROD new byte[] { 0x50, 0x41, 0x53, 0x54 }); // PART xNewPayload.Position = 0x34; xNewPayload.Write(xService); xNewPayload.Flush(); } List<byte> xReturn = new List<byte>(); byte[] xConfounder = xRC4.NewConfounder(8); byte[] NewPay = xNewPayload.ReadStream(); xNewPayload.Dispose(); byte[] xHeaderKey = xComputeHeaderKey(xConfounder, NewPay); xRC4.KeyBinary = xComputeRC4Key(xHeaderKey); xReturn.AddRange(xHeaderKey); xReturn.AddRange(xRC4.KerberosEncrypt(ref xConfounder, ref NewPay)); IO.Position = 0; IO.Write(xReturn.ToArray()); IO.Flush(); return true; } catch { return false; } }
/// <summary> /// Writes header to the file /// </summary> /// <param name="xParams"></param> /// <returns></returns> internal bool xWriteHeader(RSAParams xParams) { if (!xParams.Valid) throw CryptoExcepts.ParamError; // Writes, hashes, and signs data to a temp file AddToLog("Writing Header values"); DJsIO x = new DJsIO(true); if (!x.Accessed) return false; if (!xHeader.Write(ref x)) { x.Close(); return false; } xHeader.SetSize(xIO.Length - xSTFSStruct.BaseBlock); x.Position = 0x340; if (xSTFSStruct.ThisType == STFSType.Type0) x.Write((int)0xAD0E); else x.Write((int)0x971A); // Fills to bottom of header x.Position = x.Length; x.Write(new byte[(0x8E6 + (xSTFSStruct.BaseBlock - 0xA000))]); x.Position = 0x379; xWriteDescriptor(ref x); AddToLog("Writing Master hash"); long xLocale = 0; if (xSTFSStruct.xBlockCount <= Constants.BlockLevel[0]) xLocale = GenerateBaseOffset(0, TreeLevel.L0); else if (xSTFSStruct.xBlockCount <= Constants.BlockLevel[1]) xLocale = GenerateBaseOffset(0, TreeLevel.L1); else xLocale = GenerateBaseOffset(0, TreeLevel.L2); XTakeHash(ref xIO, xLocale, 0x381, 0x1000, ref x); AddToLog("Writing Header hash"); int xSize = 0; if (xSTFSStruct.BaseBlock == 0xA000) xSize = 0x9CBC; else xSize = 0xACBC; // b000 XTakeHash(0x344, 0x32C, xSize, ref x); AddToLog("Signing Header"); x.Position = 0x22C; byte[] xHash = SHA1Quick.ComputeHash(x.ReadBytes(0x118)); x.Position = 4; if (xParams.Type == PackageMagic.CON) { x.Write(xParams.Certificate); x.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { x.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); x.Write(new byte[0x128]); } x.IsBigEndian = true; x.Position = 0; x.Write(((uint)xParams.Type)); x.Flush(); xHeader.xMagic = xParams.Type; // Writes header to Package just incase of a emergency close, the Package still attains original strucure AddToLog("Writing Header to Package"); xIO.Position = 0; xIO.Write(x.ReadStream()); xIO.Flush(); // Flush all the unused blocks to say they are written and now perm wif the new STFS Descriptor /*switched0.Clear(); switched1.Clear(); switched2 = false;*/ x.Close(); VariousFunctions.DeleteFile(x.FileNameLong); return true; }
internal bool WriteText(ref DJsIO x) { if (!xLoaded || x == null || !x.Accessed) return false; try { x.Position = 0; x.Write("Signature Type - " + xMagic.ToString() + Environment.NewLine); x.Write("Package Licences:" + Environment.NewLine); for (int i = 0; i < xLisc.Count; i++) { x.Write("License " + i.ToString() + " ID: " + xLisc[i].ID.ToString("X") + Environment.NewLine); x.Write("License " + i.ToString() + " Bits: " + xLisc[i].Var1.ToString("X") + Environment.NewLine); x.Write("License " + i.ToString() + " Flags: " + xLisc[i].Flags.ToString("X") + Environment.NewLine); } x.Write("Package Type: " + xThisType.ToString() + Environment.NewLine); x.Write("Meta Data Version: " + MetaDataVersion.ToString() + Environment.NewLine); x.Write("Recorded ContentSize: " + xContentSize.ToString() + " bytes" + Environment.NewLine); x.Write("Media ID: " + MediaID.ToString() + Environment.NewLine); x.Write("Version: " + Version_.ToString() + Environment.NewLine); x.Write("Version Base: " + Version_Base.ToString() + Environment.NewLine); x.Write("Title ID: " + TitleID.ToString("X2") + Environment.NewLine); x.Write("Platform: " + Platform.ToString() + Environment.NewLine); x.Write("Executable Type: " + ExecutableType.ToString() + Environment.NewLine); x.Write("Disc Number: " + DiscNumber.ToString() + Environment.NewLine); x.Write("Disc In Set: " + DiscInSet.ToString() + Environment.NewLine); x.Write("Save Game ID: " + SaveGameID.ToString() + Environment.NewLine); x.Write("Creator's Console ID: " + xSaveConsoleID.ToString("X2") + Environment.NewLine); x.Write("Creator's Profile ID: " + ProfileID.ToString("X2") + Environment.NewLine); x.Write("Data File Count: " + DataFileCount.ToString() + Environment.NewLine); x.Write("Data File Size: " + DataFileSize.ToString() + Environment.NewLine); x.Write("Series ID: " + SeriesID.HexString() + Environment.NewLine); x.Write("Season ID: " + SeasonID.HexString() + Environment.NewLine); x.Write("Season Number: " + SeasonNumber.ToString() + Environment.NewLine); x.Write("Epidsode Number: " + EpidsodeNumber.ToString() + Environment.NewLine); x.Write("Device ID: " + xDeviceID.HexString() + Environment.NewLine); x.Write("Languages:" + Environment.NewLine); for (int i = 0; i < 9; i++) { x.Write(((Languages)i).ToString() + " Display Title and Description:" + Environment.NewLine); x.Write(xTitles[i] + Environment.NewLine); x.Write(xDescriptions[i] + Environment.NewLine); } x.Write("Publisher Name: " + xPublisher + Environment.NewLine); x.Write("Package Title: " + xTitle + Environment.NewLine); x.Write("Package Transfer Type: " + IDTransfer.ToString()); x.Flush(); return true; } catch { return false; } }
/// <summary> /// Initializes a package parse from an already accessed file /// </summary> /// <param name="xIOIn"></param> /// <param name="LogIn"></param> public STFSPackage(DJsIO xIOIn, LogRecord LogIn) { if (!xIOIn.Accessed) return; xIO = xIOIn; xLog = LogIn; xActive = true; try { xIO.Position = 0; xIO.IsBigEndian = true; uint xBuff = xIOIn.ReadUInt32(); PackageMagic xMagic = PackageMagic.Unknown; if (Enum.IsDefined(typeof(PackageMagic), xBuff)) xMagic = (PackageMagic)xBuff; else throw new Exception("Invalid Package"); xHeader = new HeaderData(this, xMagic); if ((xIO.Length % 0x1000) != 0) { xIO.Position = xIO.Length; xIO.Write(new byte[(int)(0x1000 - (xIO.Length % 0x1000))]); xIO.Flush(); } if (xHeader.ThisType == PackageType.HDDInstalledGame || xHeader.ThisType == PackageType.OriginalXboxGame || xHeader.ThisType == PackageType.GamesOnDemand || xHeader.ThisType == PackageType.SocialTitle) throw STFSExcepts.Game; AddToLog("Getting Package Structure"); new Thread(new ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(Thread.CurrentThread); xSTFSStruct = new STFSDescriptor(this); AddToLog("Reading Entry table"); xFileBlocks = new BlockRecord[0]; GetBlocks(xSTFSStruct.DirectoryBlockCount, xSTFSStruct.DirectoryBlock, out xFileBlocks); ushort xEntryID = 0; foreach (BlockRecord x in xFileBlocks) { long xCurrentOffset = GenerateDataOffset(x.ThisBlock); for (int i = 0; i < 0x40; i++) { xIO.Position = (xCurrentOffset + (0x40 * i)); if (xIO.ReadByte() == 0) continue; xIO.Position--; ItemEntry xItem = new ItemEntry(xIO.ReadBytes(0x40), (xIO.Position - 0x40), xEntryID, this); if (xItem.IsDeleted) continue; if (!xItem.FolderFlag) xFileDirectory.Add(new FileEntry(xItem)); else xFolderDirectory.Add(new FolderEntry(xItem)); xEntryID++; } } xroot = new FolderEntry("", 0, 0xFFFF, 0xFFFF, this); xActive = false; } catch (Exception x) { xIO = null; throw x; } }
internal bool xUpdate() { try { int xsize = xpairs.Count * 0x10; if (Size > xsize) { new FreeSpaceEntry(xRef, xOffset + xsize, Size - xsize); xRef.PatchFree(); } else if (Size < xsize) { int off = xRef.AllocateData(xsize); if (off == -1) return false; new FreeSpaceEntry(xRef, xOffset, Size); xRef.PatchFree(); xOffset = off; } DJsIO xbuff = new DJsIO(new byte[xsize], true); xbuff.Position = 0; foreach (SyncPair x in xpairs) { xbuff.Write(x.ID); xbuff.Write(x.Sync); } xbuff.Flush(); xRef.xIO.Position = Offset; xRef.xIO.Write(xbuff.ReadStream()); xRef.xIO.Flush(); if (xsize > xSize) xRef.UpdateHeader(); xSize = xsize; return true; } catch { return false; } }
internal bool IncreaseXDBFCount() { DJsIO xtemp = new DJsIO(true); try { xtemp.Position = (HeaderSize + (0xFF * 0x12)); xIO.Position = HeaderSize; int len = (int)(xIO.Length - xIO.Position); for (int i = 0; i < len; i++) xtemp.Write(xIO.ReadByte()); xtemp.Position = 0; xtemp.Write((uint)AllMagic.XDBF); xtemp.Write((int)0x10000); xEntryMax += 0xFF; xtemp.Write((int)xEntryMax); xtemp.Write((int)xEntryCurrent); xtemp.Write((int)xFreeCurrent); xtemp.Write((int)xFreeMax); List<XDBFEntry> xEntries = GetEntries(); foreach (XDBFEntry x in xEntries) { xtemp.Write((ushort)x.NS); xtemp.Write(x.ID); xtemp.Write(x.xOffset); xtemp.Write(x.Size); } xtemp.Write(new byte[0x12 * (xEntryMax - xEntries.Count)]); foreach (FreeSpaceEntry x in xFreeEnts) { if (x.Size != 0) { xtemp.Write(x.offset); xtemp.Write(x.Size); } } int xdatasize = (int)(xtemp.Length - HeaderSize); xtemp.Write(xdatasize); xtemp.Write((int)(((-1) - xdatasize))); xtemp.Write(new byte[0x8 * (xFreeMax - (xFreeEnts.Count + 1))]); xtemp.Flush(); xtemp.Close(); xIO.Close(); VariousFunctions.MoveFile(xtemp.FileNameLong, xIO.FileNameLong); xIO = new DJsIO(xIO.FileNameLong, DJFileMode.Open, true); return true; } catch { xtemp.Dispose(true); return false; } }
/// <summary> /// Writes the STFS Descriptor to make perm. changes /// </summary> /// <returns></returns> bool xWriteDescriptor(ref DJsIO io) { //AddToLog("Writing new Descriptor"); io.Position = 0x379; xSTFSStruct.xDirectoryBlockCount = (ushort)xCurEntBlckCnt; io.Write(xSTFSStruct.GetData()); io.Flush(); return true; }
bool xWriteHeader(RSAParams xParams) { try { DJsIO xio = new DJsIO(true); xHeaderData.Write(ref xio); xio.SetLength(0xB000); xio.Position = 0x340; xio.Write((uint)0xAD0E); xio.Position = 0x379; xio.Write(new byte[] { 0x24, 5, 5, 0x11 }); IO.Position = 0x37D; xio.Write(IO.ReadBytes(20)); xio.Write((byte)((xIsShifted ? 1 : 0) << 6)); xio.WriteUInt24(xBlockCount); xio.Write(xDeviation); xio.Flush(); xio.Position = 0x344; byte[] xHash = SHA1Quick.ComputeHash(xio.ReadBytes((int)(xio.Length - 0x344))); xio.Position = 0x32C; xio.Write(xHash); xio.Flush(); xio.Position = 0x22C; xHash = SHA1Quick.ComputeHash(xio.ReadBytes(0x118)); xio.Position = 4; if (xParams.Type == PackageMagic.CON) { xio.Write(xParams.Certificate); xio.Write(ScrambleMethods.StockScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash), true)); } else { xio.Write(ScrambleMethods.DevScramble(RSAQuick.SignatureGenerate(xParams.RSAKeys, xHash))); xio.Write(new byte[0x128]); } xio.IsBigEndian = true; xio.Position = 0; xio.Write(((uint)xParams.Type)); xio.Flush(); xHeaderData.xMagic = xParams.Type; IO.Position = 0; IO.Write(xio.ReadStream()); IO.Flush(); xio.Dispose(); return true; } catch { return false; } }
/// <summary> /// Extract the data of the package /// </summary> /// <param name="xIOOut"></param> /// <returns></returns> public bool ExtractData(DJsIO xIOOut) { if (!dataloaded || xIOOut == null || !xIOOut.Accessed || !ActiveCheck()) return false; try { xIOOut.Position = 0; for (uint i = 0; i < xBlockCount; i++) { xDataFiles[(int)(i / Constants.SVODBL[1])].Position = GenerateDataOffset(i); xIOOut.Write(xDataFiles[(int)(i / Constants.SVODBL[1])].ReadBytes(0x1000)); } xIOOut.Flush(); return !(xActive = false); } catch { return (xActive = false); } }
void xExtract(ref DJsIO xIOOut) { xIOOut.Position = 0; IO.Position = 0xD08; /* Self Note: * not in 0x1000 blocks, just decided to write them * in those size to avoid memory conflicts * */ while (IO.Position < IO.Length) xIOOut.Write(IO.ReadBytes(0x1000)); xIOOut.Flush(); }
/// <summary> /// Create an STFS Package /// </summary> /// <param name="xSession"></param> /// <param name="xSigning"></param> /// <param name="xOutPath"></param> /// <param name="LogIn"></param> public STFSPackage(CreateSTFS xSession, RSAParams xSigning, string xOutPath, LogRecord LogIn) { xActive = true; if (!xSigning.Valid) throw CryptoExcepts.ParamError; if (xSession.xFileDirectory.Count == 0) throw new Exception(); try { AddToLog("Setting Package variables"); new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(System.Threading.Thread.CurrentThread); xroot = new FolderEntry("", 0, 0xFFFF, 0xFFFF, this); if (xSession.HeaderData.ThisType == PackageType.ThematicSkin) { DJsIO x1 = new DJsIO(true); DJsIO x2 = new DJsIO(true); x1.Write((int)xSession.ThemeSettings.StyleType); x1.Flush(); x1.Close(); if (!xSession.AddFile(x1.FileNameLong, "DashStyle")) throw STFSExcepts.ThemeError; x2.Write("SphereColor=" + ((byte)xSession.ThemeSettings.Sphere).ToString().PadRight(2, '\0')); x2.Write(new byte[] { 0xD, 0xA }); x2.Write("AvatarLightingDirectional=" + xSession.ThemeSettings.AvatarLightingDirectional0.ToString("#0.0") + "," + xSession.ThemeSettings.AvatarLightingDirectional1.ToString("#0.0000") + "," + xSession.ThemeSettings.AvatarLightingDirectional2.ToString("#0.0") + ",0x" + xSession.ThemeSettings.AvatarLightingDirectional3.ToString("X")); x2.Write(new byte[] { 0xD, 0xA }); x2.Write("AvatarLightingAmbient=0x" + xSession.ThemeSettings.AvatarLightingAmbient.ToString("X")); x2.Write(new byte[] { 0xD, 0xA }); x2.Flush(); x2.Close(); if (!xSession.AddFile(x2.FileNameLong, "parameters.ini")) throw STFSExcepts.ThemeError; } else if (xSession.HeaderData.ThisType == PackageType.GamesOnDemand || xSession.HeaderData.ThisType == PackageType.HDDInstalledGame || xSession.HeaderData.ThisType == PackageType.OriginalXboxGame || xSession.HeaderData.ThisType == PackageType.SocialTitle) throw STFSExcepts.Game; xLog = LogIn; xHeader = xSession.HeaderData; xSTFSStruct = new STFSDescriptor(xSession.STFSType, 0); xIO = new DJsIO(true); List<BlockRecord> DirectoryBlockz = new List<BlockRecord>(); // switched2 = true; uint xcurblock = 0; for (ushort i = 0; i < xSession.GetDirectoryCount; i++) { DirectoryBlockz.Add(new BlockRecord()); DirectoryBlockz[DirectoryBlockz.Count - 1].ThisBlock = xcurblock++; /*if (!switched0.Contains((int)(xcurblock / Constants.BlockLevel[0]))) switched0.Add((int)(xcurblock / Constants.BlockLevel[0])); if (!switched1.Contains((int)(xcurblock / Constants.BlockLevel[1]))) switched1.Add((int)(xcurblock / Constants.BlockLevel[1]));*/ } xFileBlocks = DirectoryBlockz.ToArray(); xWriteChain(xFileBlocks); xSTFSStruct.xDirectoryBlockCount = (ushort)xFileBlocks.Length; ushort xCurID = 0; xSession.xFolderDirectory.Sort(new Comparison<CFolderEntry>(sortpathct)); foreach (CFolderEntry x in xSession.xFolderDirectory) { ushort pointer = 0xFFFF; if (x.xthispath.xPathCount() > 1) pointer = xGetParentFolder(x.Path).EntryID; xFolderDirectory.Add(new FolderEntry(x.Name, 0, xCurID++, pointer, this)); xFolderDirectory[xFolderDirectory.Count - 1].xFixOffset(); } foreach (CFileEntry x in xSession.xFileDirectory) { ushort pointer = 0xFFFF; if (x.xthispath.xPathCount() > 1) pointer = xGetParentFolder(x.Path).EntryID; xFileDirectory.Add(new FileEntry(x.Name, (int)x.GetLength(), false,xCurID++, pointer, this)); List<BlockRecord> xAlloc = new List<BlockRecord>(); for (uint i = 0; i < x.BlockCount(); i++) { xAlloc.Add(new BlockRecord()); xAlloc[xAlloc.Count - 1].ThisBlock = xcurblock++; /*if (!switched0.Contains((int)(xcurblock / Constants.BlockLevel[0]))) switched0.Add((int)(xcurblock / Constants.BlockLevel[0])); if (!switched1.Contains((int)(xcurblock / Constants.BlockLevel[1]))) switched1.Add((int)(xcurblock / Constants.BlockLevel[1]));*/ } xFileDirectory[xFileDirectory.Count - 1].xBlockCount = (uint)xAlloc.Count; xFileDirectory[xFileDirectory.Count - 1].xStartBlock = xAlloc[0].ThisBlock; xFileDirectory[xFileDirectory.Count - 1].xPackage = this; xFileDirectory[xFileDirectory.Count - 1].xFixOffset(); xWriteChain(xAlloc.ToArray()); } AddToLog("Writing Entry Table"); DJsIO xent; if (!xEntriesToFile(out xent)) throw new Exception(); xWriteTo(ref xent, xFileBlocks); xent.Close(); VariousFunctions.DeleteFile(xent.FileNameLong); AddToLog("Writing Files"); uint curblck = xSession.GetDirectoryCount; foreach (CFileEntry z in xSession.xFileDirectory) { List<BlockRecord> w = new List<BlockRecord>(); uint ct = z.BlockCount(); for (uint y = 0; y < ct; y++) { w.Add(new BlockRecord()); w[w.Count - 1].ThisBlock = curblck++; } DJsIO x = null; try { x = new DJsIO(z.FileLocale, DJFileMode.Open, true); xWriteTo(ref x, w.ToArray()); } catch { } if (x != null) x.Dispose(); } xWriteTables(); xWriteHeader(xSigning); xIO.Close(); VariousFunctions.MoveFile(xIO.FileNameLong, xOutPath); xIO = new DJsIO(xOutPath, DJFileMode.Open, true); xActive = false; } catch (Exception x) { xFileDirectory = null; xFolderDirectory = null; xIO.Dispose(); throw x; } }
internal bool xExtract(ref DJsIO xIOOut) { try { xIOOut.Position = 0; uint[] xChain = Partition.xTable.GetBlocks(xStartBlock); uint xct = (uint)(((xSize - 1) / Partition.xBlockSize) + 1); if (xChain.Length < xct) return false; xDrive.GetIO(); for (uint i = 0; i < xct - 1; i++) { xDrive.xIO.Position = Partition.BlockToOffset(xChain[(int)i]); xIOOut.Write(xDrive.xIO.ReadBytes(Partition.xBlockSize)); } int xleft = (int)(((xSize - 1) % Partition.xBlockSize) + 1); xDrive.xIO.Position = Partition.BlockToOffset(xChain[(int)xct - 1]); xIOOut.Write(xDrive.xIO.ReadBytes(xleft)); xIOOut.Flush(); return true; } catch { return false; } }
/// <summary> /// Writes the legal documentation to a local location /// </summary> public static void WriteLegalLocally() { DJsIO xIO = new DJsIO(Application.StartupPath + "/" + "X360 READ ME.txt", DJFileMode.Create, true); if (!xIO.Accessed) return; xIO.Position = 0; xIO.Write("------------ Legal Info ------------" + Environment.NewLine); xIO.Write(Legal + Environment.NewLine); xIO.Write("------------------------------------" + Environment.NewLine); xIO.Write("------- Terms and Conditions -------" + Environment.NewLine); xIO.Write(GNUProtected + Environment.NewLine); xIO.Write("------------------------------------" + Environment.NewLine); xIO.Write("----------- GNU License ------------" + Environment.NewLine); xIO.Write(PublicResources.GPL + Environment.NewLine); xIO.Write("------------------------------------"); xIO.Flush(); xIO.Dispose(); }