private void addFileToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Multiselect = true; ofd.Title = "Open Xbox Live Packages"; ofd.Filter = ""; if (ofd.ShowDialog() != DialogResult.OK) return; menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = false; progressBarX1.Value = 0; progressBarX1.Maximum = ofd.FileNames.Length; foreach (string x in ofd.FileNames) { DJsIO y = null; try { y = new DJsIO(x, DJFileMode.Open, true); } catch { progressBarX1.Value++; continue; } if (!y.Accessed) { progressBarX1.Value++; continue; } y.Position = 0; if (y.ReadUInt32() == (uint)AllMagic.CON) listBox1.Items.Add(x); y.Dispose(); if (checkBoxX3.Checked) fix(listBox1.Items.Count - 1); progressBarX1.Value++; } menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = true; }
/// <summary> /// Attempts to find the type of the file /// </summary> /// <param name="FileLocale"></param> /// <returns></returns> public static XboxFileType ReadFileType(string FileLocale) { /* ADD FATX SUPPORT */ DJsIO xIO = new DJsIO(FileLocale, DJFileMode.Open, true); try { XboxFileType xReturn = XboxFileType.None; xIO.Position = 0; uint sig = xIO.ReadUInt32(); switch (sig) { case (uint)AllMagic.CON: case (uint)AllMagic.LIVE: case (uint)AllMagic.PIRS: { if (xIO.Length < 0x37C) break; xIO.Position = 0x379; byte[] desc = xIO.ReadBytes(3); if (desc[0] == 0x24 && desc[1] == 0 && (desc[2] == 0 || desc[2] == 1 || desc[2] == 2)) xReturn = XboxFileType.STFS; else if (desc[0] == 0x24 && desc[1] == 5 && desc[2] == 5) xReturn = XboxFileType.SVOD; } break; case (uint)AllMagic.Music: { xReturn = XboxFileType.Music; } break; case (uint)AllMagic.XDBF: { xReturn = XboxFileType.GPD; } break; case 0: { if (xIO.Length < 0x130EB0004) break; xIO.Position = 0x130EB0000; if (xIO.ReadUInt32() != (uint)AllMagic.FATX) break; xReturn = XboxFileType.FATX; } break; case (uint)AllMagic.XSF: { xReturn = XboxFileType.GDF; } break; default: break; } if (xReturn == XboxFileType.None) { try { xIO.Position = 0; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x1FB20; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x30600; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x7FF000; if (xIO.ReadUInt32() != (uint)AllMagic.FATX) { xIO.Position = 0xFDA0000; if (xIO.ReadBytes(20).HexString() != GDFX.GDFMagic.XMedia.HexString()) { xIO.Position = 0x130EB0000; if (xIO.ReadUInt32() == (uint)AllMagic.FATX) xReturn = XboxFileType.FATX; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.FATX; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.GDF; } else xReturn = XboxFileType.GDF; } catch { } } xIO.Dispose(); return xReturn; } catch (Exception x) { xIO.Close(); throw x; } }
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; } }
/// <summary> /// Determins if a Drive is FATX format /// </summary> /// <param name="xIO">Stream to check</param> /// <param name="xType">Grabs the type of drive</param> /// <returns></returns> public static bool IsFATX(ref DJsIO xIO, out DriveTypes xType) { // Tries to read the offsets of Xbox 360 drives to see if the magic's match xType = DriveTypes.Unknown; try { if (xIO.IOType != DataType.Drive || ((DriveIO)xIO).xDrive.Type != DeviceType.LogicalDrive) throw new Exception(); string dat0 = ((DriveIO)xIO).xDrive.DeviceName + @"\Xbox360\Data0000"; if (!File.Exists(dat0)) throw new Exception(); var fa = File.GetAttributes(dat0); if ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) { return false; } DJsIO xio = new DJsIO(dat0, DJFileMode.Open, true); if (!xio.Accessed) throw new Exception(); xio.Position = (long)USB.Partition1; try { if (xio.ReadUInt32() == (uint)AllMagic.FATX) { xType = DriveTypes.USBFlashDrive; xio.Dispose(); return true; } } catch { } xio.Dispose(); } catch { } try { xIO.Position = (long)MU.Partition2; if (xIO.ReadUInt32() == (uint)AllMagic.FATX) { xType = DriveTypes.MemoryUnit; return true; } } catch { } try { xIO.Position = (long)HDD.Partition5; if (xIO.ReadUInt32() == (uint)AllMagic.FATX) { xType = DriveTypes.HardDrive; return true; } } catch { } try { xIO.Position = 8; xIO.Position = (xIO.ReadUInt32() * 0x200); if (xIO.ReadUInt32() == (uint)AllMagic.FATX) { xType = DriveTypes.DevHardDrive; return true; } } catch { } return false; }
/// <summary> /// Initializes this object /// </summary> /// <param name="FileLocale"></param> public MusicFile(string FileLocale) { xActive = true; DJsIO xIO = new DJsIO(FileLocale, DJFileMode.Open, true); if (!xIO.Accessed) throw STFSExcepts.ParseError; try { xIO.Position = 0; xIO.IsBigEndian = true; if (xIO.ReadUInt32() != 0x464D494D) throw MusicExcepts.NotMusic; xIO.Position = 0xC; so = xIO.ReadString(StringForm.Unicode, 0x100); al = xIO.ReadString(StringForm.Unicode, 0x100); ar = xIO.ReadString(StringForm.Unicode, 0x100); xIO.Position += 0x200; ge = xIO.ReadString(StringForm.Unicode, 0x100); IO = xIO; xActive = false; } catch { xIO.Dispose(); throw STFSExcepts.ParseError; } }
/// <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; }
private void listBox1_DragDrop(object sender, DragEventArgs e) { menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = false; string[] xfiles = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (string x in xfiles) { DJsIO y = null; try { y = new DJsIO(x, DJFileMode.Open, true); } catch { continue; } if (!y.Accessed) continue; y.Position = 0; if (y.ReadUInt32() == (uint)AllMagic.CON) listBox1.Items.Add(x); y.Dispose(); listBox1.SelectedIndex = listBox1.Items.Count - 1; Application.DoEvents(); if (checkBoxX3.Checked) fix(listBox1.Items.Count - 1); } menuStrip1.Enabled = groupPanel1.Enabled = listBox1.Enabled = true; }
/// <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; } }
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>Initialize the package via header info /// <param name="xHeaderIO">Stream to header information</param> /// <param name="xDataPath">Path of data files, null if you want to want to load header only</param> /// </summary> public SVODPackage(DJsIO xHeaderIO, string xDataPath) { xActive = true; if (xDataPath != null && xDataPath != "") { xDataPath = xDataPath.Replace('\\', '/'); if (xDataPath[xDataPath.Length - 1] == '/') xDataPath = xDataPath.Substring(0, xDataPath.Length - 1); } new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(System.DLLIdentify.PrivilegeCheck)).Start(System.Threading.Thread.CurrentThread); IO = xHeaderIO; xHeaderIO.Position = 0; xHeaderIO.IsBigEndian = true; uint xBuff = xHeaderIO.ReadUInt32(); if (!Enum.IsDefined(typeof(PackageMagic), xBuff) || (PackageMagic)xBuff == PackageMagic.Unknown) return; xHeaderIO.Position = 0x379; if (xHeaderIO.ReadByte() != 0x24 && xHeaderIO.ReadByte() != 5 && xHeaderIO.ReadByte() != 5 && xHeaderIO.ReadByte() != 0x11) return; xHeaderData = new HeaderData(xHeaderIO, (PackageMagic)xBuff); xHeaderIO.Position = 0x391; xIsShifted = (((xHeaderIO.ReadByte() >> 6) & 1) == 1); xBlockCount = xHeaderIO.ReadUInt24(); if (xIsShifted) xDeviation = xHeaderIO.ReadUInt32(false); if (xDataPath == null || xDataPath == "") { xActive = false; return; } try { xDataFiles = new DJsIO[(int)xHeaderData.DataFileCount]; } catch { throw SVODExcepts.Unknown; } if (xDataFiles.Length > 9999 || xDataFiles.Length == 0) throw SVODExcepts.Count; for (uint i = 0; i < xDataFiles.Length; i++) { xDataFiles[i] = new DJsIO(xDataPath + SVODFuncs.formatstring((uint)i), DJFileMode.Open, true); if (!xDataFiles[i].Accessed) { throw SVODExcepts.Access; } } xActive = false; }