Пример #1
0
        private void WriteResourceData(List <MessageBlock> blocks, List <Message> messages)
        {
            writer.WriteUInt32((uint)blocks.Count);

            int i      = 0;
            int offset = 4 + (blocks.Count * Marshal.SizeOf <MESSAGE_RESOURCE_BLOCK>());

            foreach (var block in blocks)
            {
                var mbr = new MESSAGE_RESOURCE_BLOCK {
                    LowId  = block.LowId,
                    HighId = block.HighId,
                    Offset = (uint)offset,
                };
                WriteResourceBlock(ref mbr);

                for (; i < messages.Count; ++i)
                {
                    var message = messages[i];
                    if (message.Id > block.HighId)
                    {
                        break;
                    }

                    offset += GetResourceEntryByteCount(message);
                }
            }

            foreach (var message in messages)
            {
                WriteResourceEntry(message);
            }
        }
Пример #2
0
        internal MESSAGE_RESOURCE_BLOCK Write(ref Int64 offset, MemoryMappedViewAccessor memory)
        {
            MESSAGE_RESOURCE_BLOCK result = new MESSAGE_RESOURCE_BLOCK
            {
                LowId           = FirstMessageId,
                HighId          = LastMessageId,
                OffsetToEntries = (UInt32)offset
            };

            foreach (String message in Messages)
            {
                Byte[] payload = Encoding.Unicode.GetBytes(message);

                MESSAGE_RESOURCE_ENTRY entry = new MESSAGE_RESOURCE_ENTRY
                {
                    Length = (UInt16)(payload.Length + SizeOfEntry),
                    Flags  = MESSAGE_RESOURCE_ENTRY_ENCODING.Unicode
                };

                memory.Write(offset, ref entry);
                offset += SizeOfEntry;

                memory.WriteArray(offset, payload, 0, payload.Length);
                offset += payload.Length;
            }

            return(result);
        }
Пример #3
0
        public MessageResource(String filePath)
        {
            FileName = filePath;

            using (MemoryMappedFile mmfile = MemoryMappedFile.CreateFromFile(filePath, FileMode.Open, null, 0L, MemoryMappedFileAccess.Read))
                using (MemoryMappedViewAccessor memory = mmfile.CreateViewAccessor(0L, 0L, MemoryMappedFileAccess.Read))
                {
                    UInt32 numberOfBlocks;
                    memory.Read(0, out numberOfBlocks);

                    MESSAGE_RESOURCE_BLOCK[] blocks = new MESSAGE_RESOURCE_BLOCK[numberOfBlocks];
                    memory.ReadArray(sizeof(UInt32), blocks, 0, blocks.Length);

                    MessageBlocks = blocks.Select(block => new MessageBlock(ref block, memory)).ToList().AsReadOnly();
                }
        }
Пример #4
0
        public MessageBlock(ref MESSAGE_RESOURCE_BLOCK block, MemoryMappedViewAccessor memory)
        {
            List <String> messages = new List <String>();

            Int64 offset = block.OffsetToEntries;

            for (UInt32 messageid = block.LowId; messageid <= block.HighId; ++messageid)
            {
                MESSAGE_RESOURCE_ENTRY entry;
                memory.Read(offset, out entry);
                offset += SizeOfEntry;

                Byte[] data = new Byte[entry.Length - SizeOfEntry];
                memory.ReadArray(offset, data, 0, data.Length);
                offset += data.Length;

                String message;

                switch (entry.Flags)
                {
                case MESSAGE_RESOURCE_ENTRY_ENCODING.Ansi:
                    message = Encoding.ASCII.GetString(data);
                    break;

                case MESSAGE_RESOURCE_ENTRY_ENCODING.Unicode:
                    message = Encoding.Unicode.GetString(data);
                    break;

                default:
                    throw new FileFormatException();
                }

                messages.Add(message);
            }

            FirstMessageId = block.LowId;
            Messages       = messages.AsReadOnly();
        }
Пример #5
0
        public void Save(String filePath, Boolean overrideExisting)
        {
            FileMode fileMode = overrideExisting ? FileMode.Create : FileMode.CreateNew;

            Int64 finalLength = 0L;

            using (MemoryMappedFile mmfile = MemoryMappedFile.CreateFromFile(filePath, fileMode, null, 1024 * 1024, MemoryMappedFileAccess.ReadWrite))
                using (MemoryMappedViewAccessor memory = mmfile.CreateViewAccessor(0L, 0L, MemoryMappedFileAccess.Write))
                {
                    Int64 offset = 0L;

                    memory.Write(offset, (UInt32)MessageBlocks.Count);
                    offset += sizeof(UInt32);

                    MESSAGE_RESOURCE_BLOCK[] blocks = new MESSAGE_RESOURCE_BLOCK[MessageBlocks.Count];

                    memory.WriteArray(sizeof(UInt32), blocks, 0, blocks.Length);
                    offset += blocks.Length * Marshal.SizeOf <MESSAGE_RESOURCE_BLOCK>();

                    for (Int32 i = 0; i < MessageBlocks.Count; ++i)
                    {
                        blocks[i] = MessageBlocks[i].Write(ref offset, memory);
                    }

                    finalLength = offset;

                    memory.WriteArray(sizeof(UInt32), blocks, 0, blocks.Length);
                }

            using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite))
            {
                stream.SetLength(finalLength);
                stream.Flush();
            }

            FileName = filePath;
        }
Пример #6
0
 private void WriteResourceBlock(ref MESSAGE_RESOURCE_BLOCK block)
 {
     writer.WriteUInt32(block.LowId);
     writer.WriteUInt32(block.HighId);
     writer.WriteUInt32(block.Offset);
 }
Пример #7
0
        private void DumpMessageTable(BinaryReader r)
        {
            writer.PushListScope("MESSAGE_RESOURCE_DATA");

            uint blockCount = r.ReadUInt32();

            writer.WriteNumber("NumberOfBlocks", blockCount);

            var resourceBlocks = new List <MESSAGE_RESOURCE_BLOCK>();

            for (uint i = 0; i < blockCount; ++i)
            {
                uint lowId  = r.ReadUInt32();
                uint highId = r.ReadUInt32();
                uint offset = r.ReadUInt32();
                var  block  = new MESSAGE_RESOURCE_BLOCK {
                    LowId  = lowId,
                    HighId = highId,
                    Offset = offset
                };
                resourceBlocks.Add(block);

                writer.PushDictScope("MESSAGE_RESOURCE_BLOCK");
                writer.WriteHex("LowId", block.LowId);
                writer.WriteHex("HighId", block.HighId);
                writer.WriteNumber("Offset", block.Offset);
                writer.PopScope();
            }

            resourceBlocks.Sort((x, y) => x.Offset.CompareTo(y.Offset));

            for (int i = 0; i < resourceBlocks.Count; ++i)
            {
                var block = resourceBlocks[i];
                r.BaseStream.Position = block.Offset;

                writer.PushListScope($"Block {i} (0x{block.LowId:X}-0x{block.HighId:X})");
                for (uint id = block.LowId; id <= block.HighId; ++id)
                {
                    if (r.BaseStream.Position == r.BaseStream.Length)
                    {
                        continue;
                    }

                    ushort length = r.ReadUInt16();
                    ushort flags  = r.ReadUInt16();
                    var    bytes  = new byte[length - 4];
                    r.Read(bytes, 0, bytes.Length);

                    Encoding encoding;
                    if ((flags & NativeMethods.MESSAGE_RESOURCE_UNICODE) != 0)
                    {
                        encoding = Encoding.Unicode;
                    }
                    else
                    {
                        encoding = Encoding.ASCII;
                    }
                    string text = encoding.GetString(bytes).TrimEnd('\r', '\n', '\0');

                    writer.PushDictScope("MESSAGE_RESOURCE_ENTRY");
                    writer.WriteNumber("Length", length);
                    writer.WriteNumber("Flags", flags);
                    writer.WriteString("Text", text);
                    writer.PopScope();
                }

                writer.PopScope();
            }

            writer.PopScope();
        }