/// <summary> /// Grabs an image from an IO and specified Deviation /// </summary> /// <param name="xIOIn"></param> /// <param name="Deviation"></param> public GDFImage(DJsIO xIOIn, uint Deviation) { if (!xIOIn.Accessed) throw IOExcepts.AccessError; xIOIn.Position = 0; new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(System.Threading.Thread.CurrentThread); if (xIOIn.ReadUInt32() == (uint)AllMagic.XSF) { xIOIn.Position = baseoffset = 0x10000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } else { xIOIn.Position = baseoffset = 0; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x1FB20) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x1FB20; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x30600) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x30600; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIO.Length < 0xFDA0000) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0xFDA0000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } } } } uint xStartBlock = xIOIn.ReadUInt32(false); int xStartSize = xIOIn.ReadInt32(false); unknown = xIOIn.ReadBytes(9); xIO = xIOIn; xRoot = new GDFFolder(xStartSize, xStartBlock, this); xDeviation = Deviation; xActive = false; }
internal FATXEntry(long Pos, byte[] xData, ref FATXDrive xdrive) { xDrive = xdrive; xOffset = Pos; try { DJsIO xIO = new DJsIO(xData, true); xNLen = xIO.ReadByte(); if (xNLen == 0xE5 || xNLen == 0xFF || xNLen == 0 || xNLen > 0x2A) return; byte xatt = (byte)((xIO.ReadByte() >> 4) & 1); byte xLen = (byte)(xNLen & 0x3F); xName = xIO.ReadString(StringForm.ASCII, xLen); xName.IsValidXboxName(); xIO.Position = 0x2C; xStartBlock = xIO.ReadUInt32(); if (xStartBlock == Constants.FATX32End) return; xSize = xIO.ReadInt32(); xT1 = xIO.ReadInt32(); xT2 = xIO.ReadInt32(); xT3 = xIO.ReadInt32(); if (xatt == 1) xIsFolder = true; else if (xSize == 0) return; xIsValid = true; } catch { xIsValid = false; } }
internal ItemEntry(byte[] xDataIn, long DirectOffset, ushort xID, STFSPackage xPackageIn) { try { xPackage = xPackageIn; DJsIO xFileIO = new DJsIO(xDataIn, true); xFileIO.Position = 0; xEntryID = xID; xFileIO.Position = 0x28; xFlag = xFileIO.ReadByte(); if (xNameLength > 0x28) xNameLength = 0x28; xFileIO.Position = 0; if (xNameLength == 0) return; xName = xFileIO.ReadString(StringForm.ASCII, xNameLength); xName.IsValidXboxName(); xFileIO.Position = 0x2F; xStartBlock = xFileIO.ReadUInt24(false); xFolderPointer = xFileIO.ReadUInt16(); xSize = xFileIO.ReadInt32(); xBlockCount = (uint)(((xSize - 1) / 0x1000) + 1); xCreated = xFileIO.ReadInt32(); xAccessed = xFileIO.ReadInt32(); xDirectoryOffset = DirectOffset; } catch { xNameLength = 0; } }
void read(DJsIO xIO, STFSPackage xPackage, PackageMagic MagicType) { xMagic = MagicType; xIO.Position = 0x22C; if (xPackage != null) xPackage.AddToLog("Reading Liscenses"); xLisc = new List<STFSLicense>(); for (int i = 0; i < 0x10; i++) xLisc.Add(new STFSLicense(xIO.ReadInt64(), xIO.ReadInt32(), xIO.ReadInt32(), i == 0)); if (xPackage != null) xPackage.AddToLog("Reading Package locks"); xIO.Position = 0x344; if (xPackage != null) xPackage.AddToLog("Reading Header Values"); xThisType = (PackageType)xIO.ReadUInt32(); ; MetaDataVersion = xIO.ReadUInt32(); xContentSize = xIO.ReadInt64(); MediaID = xIO.ReadUInt32(); Version_ = xIO.ReadUInt32(); Version_Base = xIO.ReadUInt32(); TitleID = xIO.ReadUInt32(); Platform = xIO.ReadByte(); ExecutableType = xIO.ReadByte(); DiscNumber = xIO.ReadByte(); DiscInSet = xIO.ReadByte(); SaveGameID = xIO.ReadUInt32(); SaveConsoleID = (long)xIO.ReadUInt40(); ProfileID = xIO.ReadInt64(); xIO.Position = 0x39D; DataFileCount = xIO.ReadUInt32(); DataFileSize = xIO.ReadInt64(); Reserved = xIO.ReadInt64(); xSeriesID = xIO.ReadBytes(0x10); xSeasonID = xIO.ReadBytes(0x10); SeasonNumber = xIO.ReadUInt16(); EpidsodeNumber = xIO.ReadUInt16(); xIO.Position += 0x28; xDeviceID = xIO.ReadBytes(0x14); for (int i = 0; i < 9; i++) xTitles[i] = xIO.ReadString(StringForm.Unicode, 0x80).Replace("\0", ""); for (int i = 0; i < 9; i++) xDescriptions[i] = xIO.ReadString(StringForm.Unicode, 0x80).Replace("\0", ""); xPublisher = xIO.ReadString(StringForm.Unicode, 0x40).Replace("\0", ""); xTitle = xIO.ReadString(StringForm.Unicode, 0x40).Replace("\0", ""); IDTransferByte = xIO.ReadByte(); // Package Image int xSize = xIO.ReadInt32(); xIO.Position = 0x171A; if (xSize < 0x4000) xPackageImage = xIO.ReadBytes(xSize); else xPackageImage = xIO.ReadBytes(0x4000); // Content Image xIO.Position = 0x1716; xSize = xIO.ReadInt32(); xIO.Position = 0x571A; if (xSize < 0x4000) xContentImage = xIO.ReadBytes(xSize); else xContentImage = xIO.ReadBytes(0x4000); xLoaded = true; }
/* All functions are self explanitory, here's a general structure: * Header * - Info * - XDBF Entries (Data entries) * - Free space entries (old unused data that can be reused) * Entries * * To comment everything out in GPD's would be useless and repetitive * * Achievements, Settings, and TitlesPlayed have syncs associated with them. * This is used when updating information to the servers without having to * constantly update every single item, it would be a bad system, uneffecient. * Each syncable NameSpace has a Sync Entry and an Index Record (I don't know * why they wouldn't just combine them, maybe it's a spacial issue). Sync Entry * contains the last synced entry and the next sync ID to be used when needing to * assign a sync ID. To update a sync, you just get the next SyncID, assign it to * the respected SyncPair in the IndexRecord, move it to the bottom, and increase * the next sync by one. The Xbox checks it and will sync all ID's that are * between the last sync and the next sync. One trick is you have to make sure you * order the entries in the header properly. */ internal GPD(string GPDLocale, uint xTitleID) { xActive = true; xIO = new DJsIO(GPDLocale, DJFileMode.Open, true); if (!xIO.Accessed) return; TitleID = xTitleID; xIO.IsBigEndian = true; xIO.Position = 0; if (xIO.ReadUInt32() != 0x58444246) throw GPDExcepts.IsntXDBF; xIO.Position += 4; // Version xEntryMax = xIO.ReadInt32(); xEntryCurrent = xIO.ReadInt32(); xFreeMax = xIO.ReadInt32(); xFreeCurrent = xIO.ReadInt32(); List<XDBFEntry> xEntries = new List<XDBFEntry>(); try { for (int i = 0; i < xEntryCurrent; i++) xEntries.Add(new XDBFEntry(this)); xIO.Position = (0x18 + (xEntryMax * 0x12)); for (int i = 0; i < xFreeCurrent - 1; i++) { FreeSpaceEntry x = new FreeSpaceEntry(this); xFreeEnts.Add(x); } PatchFree(); for (int i = 0; i < xEntries.Count; i++) { XDBFEntry x = xEntries[i]; switch (x.ID) { case (long)GPDIDs.IndexRecord: { RecordEntry xThisRec = new RecordEntry(x); xIndexRecords.Add(xThisRec); if (xThisRec.NS == NameSpace.Achievement && xAchievements.Count == 0) xIsInErase = true; } break; case (long)GPDIDs.SyncRecord: { SyncEntry xThisSync = new SyncEntry(x); xSyncs.Add(xThisSync); } break; default: { switch (x.NS) { case NameSpace.Nothing: xEntries.RemoveAt(i--); break; case NameSpace.Achievement: { AchievementEntry xCurrentAchievment = new AchievementEntry(x); xAchievements.Add(xCurrentAchievment); } break; case NameSpace.Image: { if (!ContainsEntry(x)) { ImageEntry xCurrentImage = new ImageEntry(x); xImages.Add(xCurrentImage); } } break; case NameSpace.Setting: { if (!ContainsEntry(x)) { Setting xThisSetting = new Setting(x); xUserSettings.Add(xThisSetting); } } break; case NameSpace.Title: { if (!ContainsEntry(x)) { TitlePlayedEntry xTitle = new TitlePlayedEntry(x); xTitlesPlayed.Add(xTitle); } } break; case NameSpace.String: { if (!ContainsEntry(x)) { StringEntry x_String = new StringEntry(x); xStrings.Add(x_String); } } break; default: xEntries.RemoveAt(i--); xEntryCurrent--; break; } } break; } } for (int i = 0; i < xUserSettings.Count; i++) { if (!xUserSettings[i].LoadDetails()) { OtherEntry xUnknown = new OtherEntry(xUserSettings[i]); xUnknownData.Add(xUnknown); xUserSettings.RemoveAt(i--); } } for (int i = 0; i < xUnknownData.Count; i++) { if (!xUnknownData[i].LoadData()) { xUnknownData.RemoveAt(i--); xEntryCurrent--; } } for (int i = 0; i < xImages.Count; i++) { if (!xImages[i].LoadImage()) { xImages.RemoveAt(i--); xEntryCurrent--; } } for (int i = 0; i < xStrings.Count; i++) { if (!xStrings[i].LoadString()) { xStrings.RemoveAt(i--); xEntryCurrent--; } } for (int i = 0; i < xIndexRecords.Count; i++) { if (!xIndexRecords[i].xLoadDetails()) { xIndexRecords.RemoveAt(i--); xEntryCurrent--; } } for (int i = 0; i < xSyncs.Count; i++) { if (!xSyncs[i].LoadSyncs()) { xSyncs.RemoveAt(i--); xEntryCurrent--; } } for (int i = 0; i < xFreeEnts.Count; i++) { if (xFreeEnts[i].Size == 0) { xFreeEnts.RemoveAt(i--); xEntryCurrent--; } } xUserSettings.Sort(sortbyid); xAchievements.Sort(sortbyid); } catch (Exception x) { xIO = null; throw x; } }
/// <summary> /// Grabs an image from an IO and specified Deviation /// </summary> /// <param name="xIOIn"></param> /// <param name="Deviation"></param> public GDFImage(DJsIO xIOIn, uint Deviation) { if (!xIOIn.Accessed) throw IOExcepts.AccessError; xIOIn.Position = 0; if (xIOIn.ReadUInt32() == (uint)AllMagic.XSF) { xIOIn.Position = baseoffset = 0x10000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } else { xIOIn.Position = baseoffset = 0; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x1FB20) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x1FB20; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIOIn.Length < 0x30600) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0x30600; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) { if (xIO.Length < 0xFDA0000) throw GDFExceptions.NotGDF; xIOIn.Position = baseoffset = 0xFDA0000; if (xIOIn.ReadBytes(20).HexString() != GDFMagic.XMedia.HexString()) throw GDFExceptions.NotGDF; } } } } uint xStartBlock = xIOIn.ReadUInt32(false); int xStartSize = xIOIn.ReadInt32(false); unknown = xIOIn.ReadBytes(9); xIO = xIOIn; xRoot = new GDFFolder(xStartSize, xStartBlock, this); xDeviation = Deviation; xActive = false; }
///<summary>Extracts a WSG from a CON (Xbox 360 Container File).</summary> public MemoryStream WSGExtract(Stream InputX360File) { BinaryReader br = new BinaryReader(InputX360File); byte[] fileInMemory = br.ReadBytes((int)InputX360File.Length); if (fileInMemory.Count() != InputX360File.Length) throw new EndOfStreamException(); try { STFSPackage CON = new STFSPackage(new DJsIO(fileInMemory, true), new X360.Other.LogRecord()); //DJsIO Extract = new DJsIO(true); //CON.FileDirectory[0].Extract(Extract); ProfileID = CON.Header.ProfileID; DeviceID = CON.Header.DeviceID; //DJsIO Save = new DJsIO("C:\\temp.sav", DJFileMode.Create, true); //Save.Write(Extract.ReadStream()); //Save.Close(); //byte[] nom = CON.GetFile("SaveGame.sav").GetEntryData(); return new MemoryStream(CON.GetFile("SaveGame.sav").GetTempIO(true).ReadStream(), false); } catch { try { DJsIO Manual = new DJsIO(fileInMemory, true); Manual.ReadBytes(881); ProfileID = Manual.ReadInt64(); Manual.ReadBytes(132); DeviceID = Manual.ReadBytes(20); Manual.ReadBytes(48163); int size = Manual.ReadInt32(); Manual.ReadBytes(4040); return new MemoryStream(Manual.ReadBytes(size), false); } catch { return null; } } }