/// <summary> /// Grabs the STFS name of the package /// </summary> /// <returns></returns> public string GetSTFSName() { if (xDrive.ActiveCheck()) return null; string xReturn = null; try { if (xSize < 0x500) throw new Exception(); xDrive.GetIO(); uint[] blocks = Partition.xTable.GetBlocks(xStartBlock); if (blocks.Length == 0) throw new Exception(); xDrive.xActive = false; FATXStreamIO io = new FATXStreamIO(this, ref blocks, true); uint xBuff = io.ReadUInt32(); if (xBuff != (uint)STFS.PackageMagic.CON && xBuff != (uint)STFS.PackageMagic.LIVE && xBuff != (uint)STFS.PackageMagic.PIRS) throw new Exception(); io.Position = 0x411; xReturn = io.ReadString(StringForm.Unicode, 0x80); io.Position = 0x340; byte xbase = (byte)(((io.ReadUInt32() + 0xFFF) & 0xF000) >> 0xC); if (io.ReadUInt32() != (uint)STFS.PackageType.Profile) throw new Exception(); io.Position = 0x379; if (io.ReadByte() != 0x24 || io.ReadByte() != 0) throw new Exception(); byte idx = (byte)(io.ReadByte() & 3); byte[] Desc = io.ReadBytes(5); if (idx == 0 || idx == 2) { if (xbase != 0xA) throw new Exception(); } else if (idx == 1) { if (xbase != 0xB) throw new Exception(); } else throw new Exception(); io.Position = 0x395; STFS.STFSDescriptor xDesc = new X360.STFS.STFSDescriptor(Desc, io.ReadUInt32(), io.ReadUInt32(), idx); int pos = (int)xDesc.GenerateDataOffset(xDesc.DirectoryBlock); uint block = xDesc.DirectoryBlock; while (pos != -1) { for (int i = 0; i < 0x40; i++) { if (pos == -1) break; io.Position = pos + 0x28 + (0x40 * i); byte nlen = (byte)(io.ReadByte() & 0x3F); if (nlen > 0x28) nlen = 0x28; io.Position = pos + (0x40 * i); if (io.ReadString(StringForm.ASCII, nlen) == "Account") { io.Position = pos + (0x40 * i) + 0x2F; List<byte> buff = new List<byte>(io.ReadBytes(3)); buff.Add(0); block = BitConv.ToUInt32(buff.ToArray(), false); pos = -1; } } if (pos != -1) { byte shift = xDesc.TopRecord.Index; if (xDesc.BlockCount >= Constants.BlockLevel[1]) { io.Position = (int)xDesc.GenerateHashOffset(block, X360.STFS.TreeLevel.L2) + 0x14 + (shift << 0xC); shift = (byte)((io.ReadByte() >> 6) & 1); } if (xDesc.BlockCount >= Constants.BlockLevel[0]) { io.Position = (int)xDesc.GenerateHashOffset(block, X360.STFS.TreeLevel.L1) + 0x14 + (xDesc.ThisType == STFS.STFSType.Type0 ? 0 : (shift << 0xC)); shift = (byte)((io.ReadByte() >> 6) & 1); } io.Position = (int)xDesc.GenerateHashOffset(block, X360.STFS.TreeLevel.L0) + 0x15 + (xDesc.ThisType == STFS.STFSType.Type0 ? 0 : (shift << 0xC)); List<byte> xbuff = new List<byte>(io.ReadBytes(3)); xbuff.Reverse(); xbuff.Insert(0, 3); block = BitConv.ToUInt32(xbuff.ToArray(), true); if (block == Constants.STFSEnd) pos = -1; } } if (block == 0xFFFFFF) throw new Exception(); io.Position = (int)xDesc.GenerateDataOffset(block); byte[] databuff = io.ReadBytes(404); Profile.UserAccount ua = new X360.Profile.UserAccount(new DJsIO(databuff, true), X360.Profile.AccountType.Stock, false); if (!ua.Success) { ua = new X360.Profile.UserAccount(new DJsIO(databuff, true), X360.Profile.AccountType.Kits, false); if (!ua.Success) throw new Exception(); } xReturn = ua.GetGamertag(); io.Close(); xDrive.xActive = false; return xReturn; } catch { xDrive.xActive = false; return xReturn; } }
public FATXStreamIO GetFatXStream() { try { uint[] xChain = Partition.xTable.GetBlocks(xStartBlock); uint xct = (uint)(((xSize - 1) / Partition.xBlockSize) + 1); if (xChain.Length < xct) return null; FATXStreamIO io = new FATXStreamIO(this, ref xChain, true); return io; } catch { return null; } }