private VersionData GetVersionData(PinnedBufferReader reader, ref UInt32 padding) { VersionData result = new VersionData(); padding = NativeMethods.AlignToInt(padding); UInt32 length = padding; result.Info = reader.BytesToStructure <WinNT.Resource.VarFileInfo>(ref padding); String szKey = reader.BytesToStringUni(ref padding); result.szKey = (VersionTableType)Enum.Parse(typeof(VersionTableType), szKey); List <VersionTable> items = new List <VersionTable>(); while (padding - length < result.Info.wLength) { padding = NativeMethods.AlignToInt(padding); items.Add(this.GetVersionTable(reader, result.szKey, ref padding)); padding = NativeMethods.AlignToInt(padding); } result.Items = items.ToArray(); return(result); }
/// <summary>Получить меню старого образца</summary> /// <param name="padding">Отступ от начала меню</param> /// <returns>Элементы меню</returns> private IEnumerable <MenuItem> GetMenuOld(UInt32 padding) { //List<MenuItem> result = new List<MenuItem>(); using (PinnedBufferReader reader = base.CreateDataReader()) while (padding < reader.Length) { WinUser.MENUITEM item = reader.BytesToStructure <WinUser.MENUITEM>(ref padding); MenuItem menu = new MenuItem() { Item = item, }; //result.Add(menu); menu.Title = reader.BytesToStringUni(ref padding); if (item.IsPopUp) { menu.SubItems = this.GetPopupMenuOld(reader, ref padding); } yield return(menu); if (item.IsFinal) { yield break; } //return result.ToArray(); } //throw new InvalidOperationException();C:\Program Files\Windows NT\Accessories\wordpad.exe - Нет MF_END //return result.ToArray(); }
/// <summary>Gets version table from PE/PE+ resources</summary> /// <param name="reader">Mapped bytes</param> /// <param name="type">Type of version table</param> /// <param name="padding">Base padding</param> /// <exception cref="T:NotImplementedException">Unknown table row type</exception> /// <returns>Readed version table</returns> private VersionTable GetVersionTable(PinnedBufferReader reader, VersionTableType type, ref UInt32 padding) { VersionTable result = new VersionTable(); UInt32 length = padding; result.Table = reader.BytesToStructure <WinNT.Resource.StringTable>(ref padding); result.szKey = reader.BytesToStringUni(ref padding); List <VersionItem> items = new List <VersionItem>(); while (padding - length < result.Table.wLength) { padding = NativeMethods.AlignToInt(padding); switch (type) { case VersionTableType.StringFileInfo: items.Add(this.GetStringVersionItem(reader, ref padding)); break; case VersionTableType.VarFileInfo: items.Add(this.GetBinaryVersionItem(reader, result, ref padding)); break; default: throw new NotImplementedException(); } padding = NativeMethods.AlignToInt(padding); } result.Items = items.ToArray(); return(result); }
/// <summary>Gets popup menu items from padding</summary> /// <param name="reader">Menu bytes</param> /// <param name="padding">Starting popup menu padding</param> /// <exception cref="T:InvalidOperationException">Can't find end of menu marker</exception> /// <returns>Readed popup menu items</returns> private MenuPopupItem[] GetPopupMenu(PinnedBufferReader reader, ref UInt32 padding) { List <MenuPopupItem> result = new List <MenuPopupItem>(); while (padding < reader.Length) { padding = NativeMethods.AlignToInt(padding); WinUser.MENUITEMEX item = reader.BytesToStructure <WinUser.MENUITEMEX>(ref padding); MenuPopupItem menu = new MenuPopupItem() { ItemEx = item, }; result.Add(menu); menu.Title = reader.BytesToStringUni(ref padding); if (item.IsPopUp) { menu.dwHelpId = reader.BytesToStructure <UInt32>(ref padding); menu.SubItems = this.GetPopupMenu(reader, ref padding); } if (item.IsFinal) { return(result.ToArray()); } } throw new InvalidOperationException(); }
/// <summary>Gets menu items from padding</summary> /// <param name="padding">Starting menu padding</param> /// <exception cref="T:InvalidOperationException">Can't find end of menu marker</exception> /// <returns>Menu items</returns> private IEnumerable <MenuItem> GetMenu(UInt32 padding) { //List<MenuItem> result = new List<MenuItem>(); using (PinnedBufferReader reader = base.CreateDataReader()) while (padding < reader.Length) { padding = NativeMethods.AlignToInt(padding); WinUser.MENUITEMEX item = reader.BytesToStructure <WinUser.MENUITEMEX>(ref padding); MenuItem menu = new MenuItem() { ItemEx = item, }; //result.Add(menu); menu.Title = reader.BytesToStringUni(ref padding); //TODO: bResInfo в 16 битных приложениях занимает не WORD, а BYTE. Если найдётся реальный пример, придётся полностью делать динамичесую структуру. if (item.IsPopUp) { menu.dwHelpId = reader.BytesToStructure <UInt32>(ref padding); menu.SubItems = this.GetPopupMenu(reader, ref padding); } yield return(menu); if (item.IsFinal) { yield break; } //return result.ToArray(); } throw new InvalidOperationException(); }
internal static void GetFont <T>(PinnedBufferReader reader, ref T result, ref UInt32 padding) where T : FontEntry { WinNT.Resource.FONTDIRENTRY font = reader.BytesToStructure <WinNT.Resource.FONTDIRENTRY>(ref padding); String szDeviceName; String szFaceName; if (font.dfDevice > 0 && font.dfDevice < reader.Length) { szDeviceName = reader.BytesToStringAnsi(font.dfDevice); } else { szDeviceName = reader.BytesToStringAnsi(ref padding); } if (font.dfFace > 0 && font.dfFace < reader.Length) { szFaceName = reader.BytesToStringAnsi(font.dfFace); } else { szFaceName = reader.BytesToStringAnsi(ref padding); } result.Font = font; result.szDeviceName = szDeviceName; result.szFaceName = szFaceName; }
/// <summary>Gets the array of toolbar buttons and separators from the current toolbar</summary> /// <returns></returns> public IEnumerable <CommCtrl.TBBUTTON> GetToolBarTemplate() { UInt32 iIconIndex = 0; UInt32 padding = ResourceToolBar.SizeOfStruct; using (PinnedBufferReader reader = base.CreateDataReader()) for (UInt16 loop = 0; loop < this.Header.wItemsCount; loop++) { UInt16 toolBarItem = reader.BytesToStructure <UInt16>(ref padding); if (toolBarItem <= 0) { CommCtrl.TBBUTTON separator = new CommCtrl.TBBUTTON(); separator.iBitmap = 0; separator.idCommand = 0; separator.fsState = CommCtrl.TBSTATE.ENABLED; separator.fsStyle = CommCtrl.TBSTYLE.BTNS_SEP; separator.dwData = 0; separator.iString = null; yield return(separator); } else { String title = "RT_STRING ID: " + toolBarItem; CommCtrl.TBBUTTON button = new CommCtrl.TBBUTTON(); button.iBitmap = iIconIndex++; button.idCommand = toolBarItem; button.fsState = CommCtrl.TBSTATE.ENABLED; button.fsStyle = CommCtrl.TBSTYLE.BTNS_BUTTON; button.dwData = 0; button.iString = title; yield return(button); } } }
private IEnumerable <WinNT.Resource.MESSAGE_RESOURCE_BLOCK> GetMessageBlocks(PinnedBufferReader reader) { UInt32 padding = sizeof(UInt32); //Skippng NumberOfBlocks size for (Int32 loop = 0; loop < this.NumberOfBlocks; loop++) { yield return(reader.BytesToStructure <WinNT.Resource.MESSAGE_RESOURCE_BLOCK>(ref padding)); } }
/// <summary>Получить список используемых акселераторов</summary> /// <returns>Массив используемых акселераторов</returns> public IEnumerator <WinUser.ACCELTABLEENTRY> GetEnumerator() { UInt32 position = 0; using (PinnedBufferReader reader = base.CreateDataReader()) while (position < reader.Length) { yield return(reader.BytesToStructure <WinUser.ACCELTABLEENTRY>(ref position)); } }
/// <summary>Get all messages from resource directory</summary> /// <returns>Messages array</returns> public IEnumerator <ResourceMessageTable.MessageResourceEntry> GetEnumerator() { using (PinnedBufferReader reader = base.CreateDataReader()) foreach (var block in this.GetMessageBlocks(reader)) { foreach (var entry in this.GetMessageBlockEntries(reader, block)) { yield return(entry); } } }
/// <summary>Get all strings from resource directory</summary> /// <returns>Strings from resource</returns> public IEnumerator <String> GetEnumerator() { UInt32 padding = 0; using (PinnedBufferReader reader = base.CreateDataReader()) while (padding < reader.Length) { UInt16 length = reader.BytesToStructure <UInt16>(ref padding); length *= 2; yield return(System.Text.Encoding.Unicode.GetString(reader.GetBytes(padding, length))); padding += length; } }
private VersionItem GetStringVersionItem(PinnedBufferReader reader, ref UInt32 padding) { VersionItem result = new VersionItem(); result.Item = reader.BytesToStructure <WinNT.Resource.V_STRING>(ref padding); result.szKey = reader.BytesToStringUni(ref padding); padding = NativeMethods.AlignToInt(padding); result.Value = reader.BytesToStringUni(padding); padding += result.Item.Value.ValueLength; return(result); }
/// <summary>Get version tables</summary> /// <returns>Extended file description</returns> public VersionData[] GetFileInfo() { UInt32 padding = this.HeaderPadding; using (PinnedBufferReader reader = base.CreateDataReader()) { List <VersionData> result = new List <VersionData>(); while (padding < reader.Length && result.Count < 2) { result.Add(this.GetVersionData(reader, ref padding)); } return(result.ToArray()); } }
/// <summary>Gets media info structure by index</summary> /// <param name="index">index</param> /// <returns>DEVICE_MEDIA_INFO</returns> public DEVICE_MEDIA_INFO this[UInt32 index] { get { if (index >= this.MediaInfoCount) { throw new ArgumentOutOfRangeException("index"); } else { using (PinnedBufferReader reader = new PinnedBufferReader(this.MediaInfo)) return(reader.BytesToStructure <DEVICE_MEDIA_INFO>(index * (UInt32)Marshal.SizeOf(typeof(DEVICE_MEDIA_INFO)))); } } }
/// <summary>Get version tables</summary> /// <returns>Extended file description</returns> public IEnumerable <VersionData> GetFileInfo() { UInt32 padding = this.HeaderPadding; using (PinnedBufferReader reader = base.CreateDataReader()) { Int32 index = 0; while (padding < reader.Length && index < 2) { yield return(this.GetVersionData(reader, ref padding)); index++; } } }
/// <summary>Получить элемент версии в сохранённый в бинарном виде</summary> /// <param name="reader">Allocated bytes in memory</param> /// <param name="item">Version table</param> /// <param name="padding">Отступ от начала массива</param> /// <returns>Элемент версии</returns> private VersionItem GetBinaryVersionItem(PinnedBufferReader reader, VersionTable item, ref UInt32 padding) { VersionItem result = new VersionItem(); if (item.szKey == "Translation") { result.Value = reader.BytesToStructure <Translation>(padding); String text = result.Value.ToString(); } else { result.Value = reader.GetBytes(padding, item.Table.wValueLength); } padding += item.Table.wValueLength; return(result); }
/// <summary>Get all fonts from directory</summary> /// <returns>Fonts from directory</returns> public IEnumerator <FontDirEntry> GetEnumerator() { UInt16 numberOfFonts = this.NumberOfFonts; if (numberOfFonts > 0) { UInt32 padding = sizeof(UInt16); using (PinnedBufferReader reader = base.CreateDataReader()) for (UInt16 loop = 0; loop < numberOfFonts; loop++) { FontDirEntry entry = new FontDirEntry() { fontOrdinal = reader.BytesToStructure <UInt16>(ref padding), }; ResourceFont.GetFont(reader, ref entry, ref padding); yield return(entry); } } }
/// <summary>Get array of MFC dialog init data</summary> /// <returns>MFC dialog init data</returns> public IEnumerator <ResourceDialogInit.ControlInitData> GetEnumerator() { UInt32 padding = 0; UInt32 headerDataSize = (UInt32)Marshal.SizeOf(typeof(MfcCtrlData)); using (PinnedBufferReader reader = base.CreateDataReader()) while (padding < reader.Length) { MfcCtrlData header = reader.BytesToStructure <MfcCtrlData>(ref padding); Byte[] data = reader.GetBytes(padding, (UInt32)header.DataLength); padding += (UInt32)header.DataLength; yield return(new ControlInitData(header, data)); if (padding + headerDataSize > reader.Length) { yield break; //TODO: В заключении, обычно, идут 2 байта. Но проверял пока только на DBaseTool } } }
/// <summary>Read integer or string from mapped object</summary> /// <param name="reader">Resource allocated bytes array</param> /// <param name="padding">Padding from the beginning</param> /// <returns></returns> protected internal static SzInt GetSzOrInt(PinnedBufferReader reader, ref UInt32 padding) { SzInt result = new SzInt(); UInt16 flag = reader.BytesToStructure <UInt16>(padding); switch (flag) { case 0x0000: //Нет значения padding += sizeof(UInt16); return(result); case 0xFFFF: //Есть ещё один элемент ссылающийся на индекс в ресурсах padding += sizeof(UInt16); //Сдвиг от первого элемента result.Index = reader.BytesToStructure <UInt16>(ref padding); return(result); default: result.Name = reader.BytesToStringUni(ref padding); return(result); } }
private Byte[] CreateHeader() { BinaryReader reader = new BinaryReader(this._rtBitmap); Int32 headerSize = reader.ReadInt32(); Int32 pixelSize = (Int32)this._rtBitmap.Length - headerSize; Int32 fileSize = 14 + headerSize + pixelSize; /* Get the palette size * The Palette size is stored as an int32 at offset 32 * Actually stored as number of colours, so multiply by 4*/ this._rtBitmap.Position = 32; Int32 paletteSize = 4 * reader.ReadInt32(); // Get the palette size from the bbp if none was specified if (paletteSize == 0) { // Get the bits per pixel. The bits per pixel is store as an int16 at offset 14 this._rtBitmap.Position = 14; int bpp = reader.ReadInt16(); // Only set the palette size if the bpp < 16 if (bpp < 16) { paletteSize = 4 * (2 << (bpp - 1)); } } this._rtBitmap.Position = 0; BitmapHeader header = new BitmapHeader() { magic = new Byte[] { (Byte)'B', (Byte)'M' }, fileSize = fileSize, Unk1 = 0, headerSize = 14 + headerSize + paletteSize }; return(PinnedBufferReader.StructureToArray <BitmapHeader>(header)); }
/// <summary>Get all strings from resource directory</summary> /// <returns>Strings from resource</returns> public IEnumerator <ResourceString.StringItem> GetEnumerator() { UInt32 name = base.Directory.Parent.DirectoryEntry.NameAddress; UInt32 id = this.Id; UInt32 padding = 0; using (PinnedBufferReader reader = base.CreateDataReader()) while (padding < reader.Length) { UInt16 length = reader.BytesToStructure <UInt16>(ref padding); length *= 2; String value = Encoding.Unicode.GetString(reader.GetBytes(padding, length)); //if(value.Length > 0) yield return(new StringItem() { ID = id, Value = value, }); id++; padding += length; } }
/// <summary>Получить всплывающее меню</summary> /// <param name="reader">Allocated bytes in memory</param> /// <param name="padding">Отступ от начала</param> /// <exception cref="T:InvalidOperationException">Cand find end of menu marker</exception> /// <returns>Всплывающее меню</returns> private MenuPopupItem[] GetPopupMenuOld(PinnedBufferReader reader, ref UInt32 padding) { List <MenuPopupItem> result = new List <MenuPopupItem>(); while (padding < reader.Length) { WinUser.MENUITEMPOPUP item = reader.BytesToStructure <WinUser.MENUITEMPOPUP>(padding); if (item.IsPopUp) { item.mtID = 0; padding += (UInt32)Marshal.SizeOf(typeof(WinUser.MENUITEM)); } else //Если это попап, то читать надо только 1 WORD. { padding += (UInt32)Marshal.SizeOf(typeof(WinUser.MENUITEMPOPUP)); } MenuPopupItem menu = new MenuPopupItem() { Item = item, }; result.Add(menu); menu.Title = reader.BytesToStringUni(ref padding); if (item.IsPopUp) { menu.SubItems = this.GetPopupMenuOld(reader, ref padding); } if (item.IsFinal) { return(result.ToArray()); } } throw new InvalidOperationException(); }
/// <summary>Get message block entries from starting address</summary> /// <param name="reader">Mapped bytes</param> /// <param name="block">message block header</param> /// <exception cref="T:NotImplementedException">Unknown string encoding specified</exception> /// <returns></returns> private IEnumerable <ResourceMessageTable.MessageResourceEntry> GetMessageBlockEntries(PinnedBufferReader reader, WinNT.Resource.MESSAGE_RESOURCE_BLOCK block) { UInt32 padding = block.OffsetToEntries; UInt32 entryId = block.LowId; while (entryId <= block.HighId) { WinNT.Resource.MESSAGE_RESOURCE_ENTRY entry = reader.BytesToStructure <WinNT.Resource.MESSAGE_RESOURCE_ENTRY>(ref padding); String message; switch (entry.Flags) { case WinNT.Resource.ResourceEncodingType.Ansi: message = System.Text.Encoding.ASCII.GetString(reader.GetBytes(padding, entry.MessageLength)); break; case WinNT.Resource.ResourceEncodingType.Unicode: message = System.Text.Encoding.Unicode.GetString(reader.GetBytes(padding, entry.MessageLength)); break; default: throw new NotImplementedException(); } yield return(new ResourceMessageTable.MessageResourceEntry() { EntryId = entryId, EntryName = message, }); padding += entry.MessageLength; entryId++; } }
/// <summary>Get all messages from block</summary> /// <param name="block">Message block from witch read all messages</param> /// <returns>Messages array</returns> public IEnumerable <ResourceMessageTable.MessageResourceEntry> GetMessageBlockEntries(WinNT.Resource.MESSAGE_RESOURCE_BLOCK block) { using (PinnedBufferReader reader = base.CreateDataReader()) return(this.GetMessageBlockEntries(reader, block)); }
/// <summary>Получить блоки сообщений</summary> /// <returns>Массив блоков сообщений</returns> public IEnumerable <WinNT.Resource.MESSAGE_RESOURCE_BLOCK> GetMessageBlocks() { using (PinnedBufferReader reader = base.CreateDataReader()) return(this.GetMessageBlocks(reader)); }
/// <summary>Get dialog template in resource directory</summary> /// <exception cref="T:NotImplementedException">Class type not implemented</exception> /// <returns>Dialog template from directory</returns> public DialogTemplate GetDialogTemplate() { UInt32 padding = 0; DialogTemplate result; using (PinnedBufferReader reader = base.CreateDataReader()) { WinUser.DLGTEMPLATEEX template = reader.BytesToStructure <WinUser.DLGTEMPLATEEX>(0); WinUser.DLGTEMPLATE templateOld; if (template.IsValid) { //Чтение нового шаблона диалогового окна templateOld = new WinUser.DLGTEMPLATE(); padding = (UInt32)Marshal.SizeOf(typeof(WinUser.DLGTEMPLATEEX)); result = new DialogTemplate(template); } else { //Чтение старого шаблона диалогового окна templateOld = reader.BytesToStructure <WinUser.DLGTEMPLATE>(ref padding); result = new DialogTemplate(templateOld); } result.Menu = ResourceBase.GetSzOrInt(reader, ref padding); //Идентификатор ресурса или наименование меню result.WindowName = ResourceBase.GetSzOrInt(reader, ref padding); //Идентификатор окна или наименование класса окна if (reader.BytesToStructure <UInt16>(padding) == 0x0000) { padding += sizeof(UInt16); } else //Чтение заголовка окна { result.Title = reader.BytesToStringUni(ref padding); } //Чтение информации о шрифте if ((template.IsValid && template.ContainsFont) || templateOld.ContainsFont) { DialogFont font = new DialogFont(); font.FontSize = reader.BytesToStructure <UInt16>(ref padding); if (template.IsValid) { //Reaing new dialog font font.FontWeight = reader.BytesToStructure <UInt16>(ref padding); font.Italic = reader[padding++]; font.CharSet = reader[padding++]; } font.TypeFace = reader.BytesToStringUni(ref padding); result.Font = font; //padding += (padding % 4 == 0) ? 4 - (padding % 4) : 0;//Align to DWORD //padding += padding % sizeof(UInt32);//Align to DWORD } //Чтение элементов управления, следующих после описателя окна for (Int32 loop = 0; loop < result.Controls.Length; loop++) { padding = NativeMethods.AlignToInt(padding); UInt32 startTemplate = padding; WinUser.DLGITEMTEMPLATEEX?controlEx = null; WinUser.DLGITEMTEMPLATE? control = null; if (template.IsValid) { controlEx = reader.BytesToStructure <WinUser.DLGITEMTEMPLATEEX>(ref padding); } else { control = reader.BytesToStructure <WinUser.DLGITEMTEMPLATE>(ref padding); } SzInt itemClass = ResourceBase.GetSzOrInt(reader, ref padding); SzInt itemText = ResourceBase.GetSzOrInt(reader, ref padding); Byte[] extraData; UInt16 extraCount = reader.BytesToStructure <UInt16>(padding); if (extraCount > 0) { //TODO: Missing: +sizeof(UInt16)??? extraData = reader.GetBytes(padding, extraCount); padding += extraCount; //Including size of extraCount } else { extraData = new Byte[] { }; padding += sizeof(UInt16); } result.Controls[loop] = DialogItemTemplate.CreateDialogItem(control, controlEx, itemClass, itemText, extraData); /*UInt32 align = (padding - startTemplate) % sizeof(UInt32); * if(align > 0) * padding += sizeof(UInt32) - align;//Выравнивание по 4 байта. При этом, даже если выравнивания нет, то 4 байта всё равно надо прибавить*/ } } return(result); }
/// <summary>Detected drive parameters that are supplied by an x86 PC BIOS on boot.</summary> /// <returns>Detected drive parameters</returns> public DISK_DETECTION_INFO GetDiscDetectionInfo() { using (PinnedBufferReader reader = new PinnedBufferReader(this.Data)) return(reader.BytesToStructure <DISK_DETECTION_INFO>(this.GetDiscPartitionInfo().SizeOfPartitionInfo)); }
/// <summary>Detected drive parameters that are supplied by an x86 PC BIOS on boot.</summary> /// <returns>Detected drive parameters</returns> public DISK_DETECTION_INFO GetDiscDetectionInfo() { using(PinnedBufferReader reader = new PinnedBufferReader(this.Data)) return reader.BytesToStructure<DISK_DETECTION_INFO>(this.GetDiscPartitionInfo().SizeOfPartitionInfo); }
/// <summary>Gets media info structure by index</summary> /// <param name="index">index</param> /// <returns>DEVICE_MEDIA_INFO</returns> public DEVICE_MEDIA_INFO this[UInt32 index] { get { if(index >= this.MediaInfoCount) throw new ArgumentOutOfRangeException("index"); else using(PinnedBufferReader reader = new PinnedBufferReader(this.MediaInfo)) return reader.BytesToStructure<DEVICE_MEDIA_INFO>(index * (UInt32)Marshal.SizeOf(typeof(DEVICE_MEDIA_INFO))); } }
/// <summary>Information about the disk's partition table.</summary> /// <returns>Partition table info</returns> public DISK_PARTITION_INFO GetDiscPartitionInfo() { using(PinnedBufferReader reader = new PinnedBufferReader(this.Data)) return reader.BytesToStructure<DISK_PARTITION_INFO>(0); }
/// <summary>Information about the disk's partition table.</summary> /// <returns>Partition table info</returns> public DISK_PARTITION_INFO GetDiscPartitionInfo() { using (PinnedBufferReader reader = new PinnedBufferReader(this.Data)) return(reader.BytesToStructure <DISK_PARTITION_INFO>(0)); }