/// <summary>
 /// Sets a package comming in to this package
 /// </summary>
 /// <param name="xIn"></param>
 void SetSamePackage(ref STFSPackage xIn)
 {
     xLog = xIn.xLog;
     AddToLog("Setting Package");
     xIO = xIn.xIO;
     xSTFSStruct = xIn.STFSStruct;
     xFolderDirectory = xIn.xFolderDirectory;
     xFileDirectory = xIn.xFileDirectory;
     xHeader = xIn.xHeader;
     xFileBlocks = xIn.xFileBlocks;
     xActive = xIn.xActive;
     xroot = xIn.xroot;
     xIn = null;
     foreach (FileEntry x in xFileDirectory)
         x.xPackage = this;
     foreach (FolderEntry x in xFolderDirectory)
         x.xPackage = this;
 }
 /// <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; }
 }
 /// <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; }
 }
        /// <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, out byte[] ret, LogRecord LogIn)
        {
            ret = null;
            xActive = true;
            if (!xSigning.Valid)
                throw CryptoExcepts.ParamError;
            if (xSession.xFileDirectory.Count == 0)
                throw new Exception();
            ////try
            {
                //AddToLog("Setting Package variables");

                xroot = new FolderEntry("", 0, 0xFFFF, 0xFFFF, this);
                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();
                var 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++;

                }
                xFileBlocks = DirectoryBlockz.ToArray();
                xWriteChain(xFileBlocks);
                xSTFSStruct.xDirectoryBlockCount = (ushort)xFileBlocks.Length;
                ushort xCurID = 0;
                xSession.xFolderDirectory.Sort(new Comparison<CFolderEntry>(sortpathct));
                foreach (var 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));

                    var xAlloc = new List<BlockRecord>();
                    for (uint i = 0; i < x.BlockCount(); i++)
                    {
                        xAlloc.Add(new BlockRecord());
                        xAlloc[xAlloc.Count - 1].ThisBlock = xcurblock++;

                    }
                    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 (var z in xSession.xFileDirectory)
                {
                    var 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.FileData, true);
                        xWriteTo(ref x, w.ToArray());
                    }
                    //catch { }
                    if (x != null)
                        x.Dispose();
                }
                xWriteTables();
                xWriteHeader(xSigning);
                ret = xIO.GetBytes();
                xIO.Close();
                //VariousFunctions.MoveFile(xIO.FileNameLong, xOutPath);

                xActive = false;
            }
            ////catch (Exception x) { xFileDirectory = null; xFolderDirectory = null; xIO.Dispose(); throw x; }
        }