示例#1
0
        private void AddEntryToHeaderBlock(EntryHeader eh, UInt32 blockNumber)
        {
            BlockInfo block = m_headerBlocks[blockNumber];

            if (block.entryHeaders == null)
            {
                block.entryHeaders = new List <EntryHeader>();
            }

            block.entryHeaders.Add(eh);
            m_headerBlocks[blockNumber] = block;
        }
示例#2
0
        private void OrganizeBlocks()
        {
            UInt32 indexFile = 0;

            UInt32[] dataBlocks      = m_dataBlocks.Keys.ToArray();
            UInt32   dataBlockOffset = (UInt32)m_headerBlocks.Count + 1;

            List <UInt32> keys = new List <UInt32>(m_headerBlocks.Keys);

            foreach (UInt32 i in keys)
            {
                BlockInfo block = m_headerBlocks[i];
                if (block.entryHeaders != null)
                {
                    for (int j = 0; j < block.entryHeaders.Count; j++)
                    {
                        EntryHeader entry = block.entryHeaders[j];

                        // Don't do anything with directories, Disc label file or catapult file.
                        if (Encoding.ASCII.GetString(entry.type).Equals("*dir") == false &&
                            Encoding.ASCII.GetString(entry.type).Equals("*lbl") == false &&
                            Encoding.ASCII.GetString(entry.type).Equals("*zap") == false)
                        {
                            entry.avatars    = new UInt32[1];
                            entry.avatars[0] = dataBlockOffset + dataBlocks[indexFile];

                            block.entryHeaders[j] = entry;

                            if (Encoding.ASCII.GetString(entry.filename).Contains("rom_tags") == true)
                            {
                                Console.WriteLine("rom_tags position: " + entry.avatars[0]);
                            }

                            indexFile++;
                        }
                    }
                }
                m_headerBlocks[i] = block;

                // TODO: Set directoryHeader.firstFreeByte HERE.
            }
        }
示例#3
0
        private void ReadEntry(UInt32 currentBlock, UInt32 offset, String currentPath)
        {
            m_br.BaseStream.Seek((currentBlock * m_rootHeader.blockSize) + offset, SeekOrigin.Begin);

            // Check creation of directory.
            if (Directory.Exists(currentPath) == false)
            {
                Directory.CreateDirectory(currentPath);
            }

            int entrycount = 0;

            bool lastEntry = false;

            while (lastEntry == false)
            {
                // Entry.
                //Console.Write(Environment.NewLine);
                //Console.WriteLine("Entry: ");

                EntryHeader eh = new EntryHeader();

                // Flags.
                eh.flags = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Convert flags.
                EntryFlags entryFlags = EntryFlags.None;

                if ((eh.flags & 0x80000000) == 0x80000000)
                {
                    entryFlags |= EntryFlags.LastEntryInDir;
                }
                if ((eh.flags & 0x40000000) == 0x40000000)
                {
                    entryFlags |= EntryFlags.LastEntryInBlock;
                }

                if ((eh.flags & 0x07) == 0x07)
                {
                    entryFlags |= EntryFlags.Directory;
                }
                else if ((eh.flags & 0x06) == 0x06)
                {
                    entryFlags |= EntryFlags.SpecialFile;
                }
                else if ((eh.flags & 0x02) == 0x02)
                {
                    entryFlags |= EntryFlags.File;
                }

                if (entryFlags.HasFlag(EntryFlags.LastEntryInDir) == true)
                {
                    lastEntry = true;
                }

                // Identifier.
                eh.id = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Type.
                eh.type = m_br.ReadBytes(m_entryTypeSize);

                //Console.Write("Type: ");
                //for (int i = 0; i < m_entryTypeSize; i++)
                //  Console.Write((Char)eh.type[i]);
                //Console.Write(Environment.NewLine);

                // Block size.
                eh.blockSize = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // failsafe: Read error, return immediately.
                if (eh.blockSize != m_rootHeader.blockSize)
                {
                    break;
                }

                entrycount++;

                // Length of the entry in bytes.
                eh.byteCount = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Length of the entry in blocks.
                eh.blockCount = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));
                //Console.WriteLine("BlockCount: " + eh.blockCount);

                // Burst.
                eh.burst = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Gap.
                eh.gap = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Filename.
                eh.filename = m_br.ReadBytes(m_filenameSize);

                //Console.Write("Filename: ");
                //for (int i = 0; i < m_filenameSize; i++)
                //  Console.Write((Char)eh.filename[i]);
                //Console.Write(Environment.NewLine);

                // Number of avatars.
                eh.avatarsCount = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));

                // Offset to the avatars, from the beginning of the disk, in blocks.
                eh.avatars = new UInt32[eh.avatarsCount + 1];
                //Console.Write("Locations of the avatars: ");
                for (int i = 0; i < eh.avatarsCount + 1; i++)
                {
                    eh.avatars[i] = Util.ArrayToUint32(m_br.ReadBytes(sizeof(UInt32)));
                    //Console.Write(eh.avatars[i] + " ");
                }
                //Console.Write(Environment.NewLine);

                // Add entry header to the list.
                m_entryHeaderList.Add(eh);

                //--
                if (m_blocks.ContainsKey(currentBlock) == false)
                {
                    m_blocks[currentBlock] = new BlockInfo();
                }

                BlockInfo block = m_blocks[currentBlock];
                if (block.entryHeaders == null)
                {
                    block.entryHeaders = new List <EntryHeader>();
                }

                block.entryHeaders.Add(eh);

                m_blocks[currentBlock] = block;
                //--

                //if (entryFlags.HasFlag(EntryFlags.SpecialFile) == true)
                //{
                //  Console.Write("Special File: ");
                //  for (int i = 0; i < m_filenameSize; i++)
                //    Console.Write((Char)eh.filename[i]);
                //  Console.Write(Environment.NewLine);
                //}

                // Create directory.
                if (entryFlags.HasFlag(EntryFlags.Directory) == true)
                {
                    // Store the current position.
                    long currentPosition = m_br.BaseStream.Position;

                    // For the filename we need to convert from Byte ASCII to Unicode string and trim the padding ('\0').
                    Byte[] bytes   = Encoding.Convert(Encoding.ASCII, Encoding.Unicode, eh.filename);
                    String unicode = Encoding.Unicode.GetString(bytes).Trim('\0');

                    String dirPath = currentPath + m_separator + unicode;

                    ReadDirectory(eh.avatars[0], 0, dirPath);

                    // Return to previous position.
                    m_br.BaseStream.Seek(currentPosition, SeekOrigin.Begin);
                }
                else // Write file.
                {
                    // [CRIS] special case: Disc label is the header of the FileSystem referenced as a file. Do not create this file.
                    if (Encoding.ASCII.GetString(eh.filename).Contains("Disc label") == false &&
                        Encoding.ASCII.GetString(eh.type).Equals("*lbl") == false)
                    {
                        // Store the current position.
                        long currentPosition = m_br.BaseStream.Position;

                        // For the filename we need to convert from Byte ASCII to Unicode string and trim the padding ('\0').
                        Byte[] bytes   = Encoding.Convert(Encoding.ASCII, Encoding.Unicode, eh.filename);
                        String unicode = Encoding.Unicode.GetString(bytes).Trim('\0');

                        String filePath = currentPath + m_separator + unicode;
                        //Console.WriteLine("Writing '" + unicode + "'...");
                        ReadFile(eh.avatars[0], filePath, eh.byteCount);

                        // Return to previous position.
                        m_br.BaseStream.Seek(currentPosition, SeekOrigin.Begin);
                    }
                }
            }
        }
示例#4
0
        private void ConvertFilesToBlocks(String path)
        {
            m_currentFSIndex = 413666134; // Starting index.

            UInt32 currentHBlock = 1;     // Header block.
            UInt32 currentDBlock = 0;     // Data block.
            bool   isFirstBlock  = true;

            //-------------------------------------------------
            // Special file: Disc label.

            CreateNewHeaderBlock(currentHBlock, 0xffffffff, 0xffffffff);

            EntryHeader ehLabel = new EntryHeader();

            ehLabel.flags        = 0x06; // Special file.
            ehLabel.id           = GetNewFSIndex();
            ehLabel.type         = GetEntryTypeAsArray("*lbl");
            ehLabel.blockSize    = m_blockSize;
            ehLabel.byteCount    = m_discLabelByteCount;
            ehLabel.blockCount   = 1;
            ehLabel.burst        = 1;
            ehLabel.gap          = 0;
            ehLabel.filename     = GetFilenameAsArray("Disc label");
            ehLabel.avatarsCount = 0;
            ehLabel.avatars      = new UInt32[] { 0 };

            // Add to current block.
            AddEntryToHeaderBlock(ehLabel, currentHBlock);

            //-------------------------------------------------
            // Headers.
            int dirCountTotal  = 0;
            int fileCountTotal = 0;

            UInt32 avatarPosition = 2;

            Queue <String> queue = new Queue <String>();

            queue.Enqueue(path);
            while (queue.Count > 0)
            {
                path = queue.Dequeue();

                try
                {
                    int    totalEntriesCount = Directory.GetDirectories(path).Length + Directory.GetFiles(path).Length;
                    UInt32 blockOffset       = 0;
                    int    indexEntry        = 1;
                    int    totalIndexEntry   = 1;

                    // Create new header block (only after block, because of Disc label).
                    if (isFirstBlock == false)
                    {
                        currentHBlock++;
                        CreateNewHeaderBlock(currentHBlock, 0xffffffff, 0xffffffff);
                    }
                    else
                    {
                        isFirstBlock = false;
                    }

                    UInt32 blockCountAvatarOffset = (UInt32)((totalEntriesCount + m_maxEntryHeadersPerBlock - 1) / m_maxEntryHeadersPerBlock);

                    String lastIndexDir = String.Empty;

                    // Directories.
                    foreach (String subDir in Directory.GetDirectories(path))
                    {
                        queue.Enqueue(subDir);
                        //Console.WriteLine(subDir);

                        dirCountTotal++;

                        int currentEntriesCount = Directory.GetDirectories(subDir).Length + Directory.GetFiles(subDir).Length;

                        // Create entry.
                        EntryHeader eh = new EntryHeader();

                        eh.flags        = 0x07;
                        eh.id           = GetNewFSIndex();
                        eh.type         = GetEntryTypeAsArray("*dir");
                        eh.blockSize    = m_blockSize;
                        eh.blockCount   = (UInt32)((currentEntriesCount + m_maxEntryHeadersPerBlock - 1) / m_maxEntryHeadersPerBlock);
                        eh.byteCount    = (UInt32)(eh.blockCount * m_blockSize);
                        eh.burst        = 1;
                        eh.gap          = 0;
                        eh.filename     = GetFilenameAsArray(Path.GetFileName(subDir));
                        eh.avatarsCount = 0; // Remember: must add actual avatar array later.
                        //eh.avatars = // Remember: must add actual avatar array later.
                        eh.avatars = new UInt32[1];

                        //----------------------------
                        // Calculate avatar position.

                        eh.avatars[0] = avatarPosition;

                        avatarPosition += eh.blockCount;

                        if (eh.blockCount * m_maxEntryHeadersPerBlock == currentEntriesCount)
                        {
                            avatarPosition++;
                        }

                        //----------------------------

                        // Check if this is the last dir entry of the dir.
                        if (totalIndexEntry == totalEntriesCount)
                        {
                            eh.flags |= 0x80000000;
                            eh.flags |= 0x40000000;

                            //avatarPosition += eh.blockCount;
                        }
                        // Check if this is the last dir entry in the block.
                        else if (indexEntry + 1 == m_maxEntryHeadersPerBlock)
                        {
                            eh.flags |= 0x40000000;
                        }

                        if (indexEntry == m_maxEntryHeadersPerBlock)
                        {
                            indexEntry = 1;
                            blockOffset++;

                            // Set the info about the new block in the older one.
                            BlockInfo oldBlock = m_headerBlocks[currentHBlock];
                            oldBlock.directoryHeader.nextBlock = blockOffset;
                            m_headerBlocks[currentHBlock]      = oldBlock;

                            // Create a new block and add it.
                            currentHBlock++;
                            CreateNewHeaderBlock(currentHBlock, 0xffffffff, blockOffset - 1);
                        }

                        // Add to current block.
                        AddEntryToHeaderBlock(eh, currentHBlock);

                        totalIndexEntry++;
                        indexEntry++;
                    }

                    // Files.
                    foreach (String file in Directory.GetFiles(path))
                    {
                        fileCountTotal++;

                        //Console.WriteLine(file);

                        // Create data block.
                        BlockInfo dataBlock = new BlockInfo();
                        dataBlock.data = File.ReadAllBytes(file);
                        m_dataBlocks[currentDBlock] = dataBlock;
                        currentDBlock += (UInt32)(dataBlock.data.Length / m_blockSize) + 1;

                        // Create entry.
                        EntryHeader eh = new EntryHeader();

                        eh.flags        = 0x02;
                        eh.id           = GetNewFSIndex();
                        eh.type         = GetEntryTypeAsArray(Path.GetExtension(file));
                        eh.blockSize    = m_blockSize;
                        eh.byteCount    = (UInt32)dataBlock.data.Length;
                        eh.blockCount   = (UInt32)((dataBlock.data.Length + m_blockSize - 1) / m_blockSize);
                        eh.burst        = 1;
                        eh.gap          = 0;
                        eh.filename     = GetFilenameAsArray(Path.GetFileName(file));
                        eh.avatarsCount = 0; // Remember: must add actual avatar array later.
                                             //eh.avatars = // Remember: must add actual avatar array later.
                                             // TODO...

                        // Check if this is the last dir entry of the dir.
                        if (totalIndexEntry == totalEntriesCount)
                        {
                            eh.flags |= 0x80000000;
                            eh.flags |= 0x40000000;
                        }
                        // Check if this is the last dir entry in the block.
                        else if (indexEntry + 1 == m_maxEntryHeadersPerBlock)
                        {
                            eh.flags |= 0x40000000;
                        }

                        if (indexEntry == m_maxEntryHeadersPerBlock)
                        {
                            indexEntry = 1;
                            blockOffset++;

                            //avatarPosition++;

                            // Set the info about the new block in the older one.
                            BlockInfo oldBlock = m_headerBlocks[currentHBlock];
                            oldBlock.directoryHeader.nextBlock = blockOffset;
                            m_headerBlocks[currentHBlock]      = oldBlock;

                            // Create a new block and add it.
                            currentHBlock++;
                            CreateNewHeaderBlock(currentHBlock, 0xffffffff, blockOffset - 1);
                        }

                        // Add to current block.
                        AddEntryToHeaderBlock(eh, currentHBlock);

                        totalIndexEntry++;
                        indexEntry++;
                    }
                }
                catch (Exception ex)
                {
                    Console.Error.WriteLine(ex);
                }
            }

            Console.WriteLine("dirCountTotal: " + dirCountTotal);
            Console.WriteLine("fileCountTotal: " + fileCountTotal);
        }