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); } }
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); }
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(); } }
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(); }
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; }
private void WriteResourceBlock(ref MESSAGE_RESOURCE_BLOCK block) { writer.WriteUInt32(block.LowId); writer.WriteUInt32(block.HighId); writer.WriteUInt32(block.Offset); }
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(); }