Формат Res файла

Тема в разделе "WASM.RESEARCH", создана пользователем SOA, 22 июн 2010.

  1. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Привет всем возникла необходимость програмно без помощи редакторов ресурсов создавать Res файлы.
    Покопавшись в сети нашел следующие страницы:
    http://msdn.microsoft.com/en-us/library/ms648027(VS.85).aspx
    http://msdn.microsoft.com/en-us/library/ms648007(VS.85).aspx
    http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx

    Откуда узнал что файл ресурсов состоит из каскада записей(HEADER) за которыми идут сами данные.

    По структуре заголовка тоже дана информация
    typedef struct {
    DWORD DataSize;
    DWORD HeaderSize;
    DWORD TYPE;
    DWORD NAME;
    DWORD DataVersion;
    WORD MemoryFlags;
    WORD LanguageId;
    DWORD Version;
    DWORD Characteristics;
    } RESOURCEHEADER;

    но также есть оговорка, в которой говорится что эта структура представлена только для ознакомления и она не представлена в каком либо стандартном файле ресурсов.

    Откуда возникает вопрос какова всетаки структура RES файла потому что если использовать эту структуру и предерживаться понятий о структуре записей в res файле описаных выше получается что если взять файл и откомпелировать его в res файл программой основанной на этом принципе и компилятором ресурсов то у компилятора ресурсов файл получается на 18 байт больше.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    формат рес файла, как я помню, - просто дерево ресурсов подряд один за другим, заголовок-данные, заголовокданные.
    Открой хексредактором рес файл из одного ресурса и сравни его содержимое и содержимое ресурса. Найдешь хидер. Сравни со структурой.
     
  3. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Посмотрел в WinHex, совпадение началось
    res bmp
    64 14 биты
    Размер хидера получился 64 бита для res
    14 бит для bmp
    Размер исходного файла bmp 938 бит
    Значит размер данных равен 924 байта

    В хидере res файла удалось покачто установить смещение для DataSize оказалось равным 32
     
  4. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    еще можно почитать макросы фасма
     
  5. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    GoldFinch
    Чет я там ничего по своей теме не нашел :dntknw:(((((((((
     
  6. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Покачто удалось установить что величина хидера для res файла всетаки вещь не постоянная и меняется в зависимости от таких величин как NAME которая на самом деле не является параметром типа DWORD в языках высокого уровня ее обычно инициируют как PCHAR.

    Удалось установить смещение для следующих полей
    Смещение Поле
    32 DataSize
    42 TYPE
    44 NAME

    Смещение для поля входящего в минимальное число полей для работы с файлом ресурсов HeaderSize установить не удается.
     
  7. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
  8. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Чем открыть можно у меня в Opera одни крокозябры?
     
  9. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Все открыл в первый раз просто наверно каряво скачалось не zip а htm.
     
  10. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    На первый взгляд сильно напоминает
    http://www.moon-soft.com/program/format/windows/res32.htm
     
  11. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Там идет чисто по размеру полей как в ms ссылках что я давал выше и скорее всего взято оттуда же.
    По форматам полей размер хидера не должен превышать 32, но в реальности размер хидера больше чем в два раза превышает 32 в моем случае был размер 64 при имени ресурса 1 и 80 при имени ресурса BITMAP_0.
     
  12. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Удалось определить поле HeaderSize.
    Оно рассчитывается по двум смещениям
    1 равно 4, значение всегда равно 32 видимо отражает что ресурс предназначен для 32 битных приложений, а также используется как база при вычислении поля.
    2 равно 36 по этому смещению располагается число равное разнице между размером заголовка и 32.
     
  13. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Сообщение для модераторов
    Как можно разместить статью по формату res файлов на вашем сайте.
    Вариант Wasm@wasm.ru не катит mail bot пишет что такого сервера нет.
     
  14. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Подведем итог по res файлам(в данном случае применительно к ресурсу типа BITMAP):

    res файл представляет собой файл в котором записаны поверх друг друга заголовки ресурсов и соответственно сами данные ресурсов.
    Код (Text):
    1. Header  (Заголовок)
    2. DATA    (Данные)
    3. Header  (Заголовок)
    4. DATA    (Даные)
    Что из себя представляет заголовок некую структуру с полями
    Код (Text):
    1. typedef struct {
    2.   DWORD DataSize;
    3.   DWORD HeaderSize;
    4.   DWORD TYPE;
    5.   DWORD NAME;
    6.   DWORD DataVersion;
    7.   WORD  MemoryFlags;
    8.   WORD  LanguageId;
    9.   DWORD Version;
    10.   DWORD Characteristics;
    11. } RESOURCEHEADER;
    но эта структура лишь является эталонной моделью как в сетях является эталонной моделью модель ISO/OSI.
    На практике же чаще используется менее громоздкая конструкция
    Код (Text):
    1. typedef struct {
    2.   DWORD DataSize;
    3.   DWORD HeaderSize;
    4.   DWORD TYPE;
    5.   DWORD NAME;
    6. } RESOURCEHEADER;
    Разберемся что значат поля в этой структуре

    DataSize размер данных ресурса, т.е. данных копируемых из файла bmp он всегда меньше реального размера файла на 14 бит ввиду того что отбрасываются несколько полей заголовка файла bmp.

    HeaderSize размер заголовка ресурса т.е. размер занимаемый всей структурой RESOURCEHEADER в байтах. Равен разнице между размером заголовка и 32.

    TYPE тип ресурса в нашем случае это значение равно FFFF0200 где ключевым числом является 2 т.к. именно она является числовым эквивалентом типа BITMAP.
    Значения для других типов можно посмотреть здесь
    http://msdn.microsoft.com/en-us/library/ms648009(VS.85).aspx
    Записываем конечно в шестнадцатиричном виде.

    NAME официально это поле имеет тип DWORD. ms пишет что на самом деле это поле является строкой с нулевым окончанием. На практике было выяснено что поле NAME записывается по одному коду символа в ASCII кодировке с отделением символов друг от друга нулевым битом, после чего по неизвестному автору алгоритму строка добивается нулевыми битами после чего ставится ASCII код нуля.

    Пример поля name.
    [​IMG]

    Также стоит заметить что в начале заголовка ставится значение типа DWORD равное нулю и в конце заголовка ставится два значения типа DWORD равные нулю

    Рассмотрим как на практике пишется файл ресурса по смещениям.

    Код (Text):
    1. ┌────────────┬────────────────┐
    2. │  Смещение  │     Поле       │
    3. ├────────────┼────────────────┤
    4. │     32     │    DataSize    │
    5. │     36     │   HeaderSize   │
    6. │     40     │     TYPE       │
    7. │     44     │     NAME       │
    8. └────────────┴────────────────┘
    Далее после заголовка записываются данные из bmp файла начиная с 14 бита потому что как я уже писал часть заголовка bmp файла отбрасывается.
     
  15. SOA

    SOA New Member

    Публикаций:
    0
    Регистрация:
    31 май 2010
    Сообщения:
    67
    Также хотелось бы привести пример программы формирующей res файл из bmp файла. Программа написана на delphi, но никто не мешает переписать ее на asm. Также следует отметить тот факт что имя ресурса не может превышать двух символов, ввиду отсутствия информации по алгоритму выравнивания имени нулями.

    Код (Text):
    1. unit Unit1;
    2.  
    3. interface
    4.  
    5. uses
    6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
    7.   Dialogs, StdCtrls;
    8.  
    9. type
    10.   TForm1 = class(TForm)
    11.     Button1: TButton;
    12.     OpenDialog1: TOpenDialog;
    13.     Edit1: TEdit;
    14.     procedure Button1Click(Sender: TObject);
    15.   private
    16.     { Private declarations }
    17.   public
    18.     { Public declarations }
    19.   end;
    20.  
    21. type Header = Record
    22. DataSize:DWORD;
    23. HeaderSize:DWORD;
    24. Base:DWORD;
    25. RcType:DWORD;
    26. NAME:String;
    27. End;
    28.  
    29. const
    30. HearedSizeBase = 4;
    31. HeaderSizeOffset = 36;
    32. DataSizeOffset = 32;
    33. TypeOffset = 40;
    34. NameOffset = 44;
    35.  
    36. var
    37.   Form1: TForm1;
    38.   MyRes,SrcFile: TFileStream;
    39.   Heder:Header;
    40.   NULL: array [0..43] of byte;
    41.  
    42. implementation
    43.  
    44. {$R *.dfm}
    45.  
    46. procedure TForm1.Button1Click(Sender: TObject);
    47. var
    48. i:Integer;
    49. Buf: BYTE;
    50. Count: LongInt;
    51. FFFF:DWORD;
    52. CHR:WORD;
    53.  
    54. begin
    55. for i:=0 to 43 do
    56. NULL[i]:=0;
    57. i:=FileCreate('Resource.res');//Создаем сам файл ресурса
    58. FileClose(i);
    59.  
    60. MyRes:=TFileStream.Create('Resource.res',fmOpenWrite);
    61. If OpenDialog1.Execute=true then
    62. SrcFile:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
    63.  
    64.  Heder.NAME:=Edit1.Text;//Имя текущего файла для записи в ресурсы
    65.  Heder.DataSize:=SrcFile.Size-14;//Размер ресурса (-14 это отбрасываемая часть заголовка файла bmp)
    66.  Heder.RcType:=$0002FFFF; //ffff0200 тип ресурса
    67.  
    68.  //Записываем описание ресурса
    69.  MyRes.Write(NULL,SizeOf(NULL));
    70.  MyRes.Seek(8,soFromBeginning);
    71.  FFFF:=$0000FFFF;
    72.  MyRes.Write(FFFF,SizeOf(FFFF));
    73.  MyRes.Write(FFFF,SizeOf(FFFF));
    74.  MyRes.Seek(HearedSizeBase,soFromBeginning);
    75.  Heder.Base:=32;
    76.  MyRes.Write(Heder.Base,SizeOf(Heder.Base));//записываем базу заголовка
    77.  MyRes.Seek(DataSizeOffset,soFromBeginning);
    78.  MyRes.Write(Heder.DataSize,SizeOf(Heder.DataSize));//записываем размер данных
    79.  
    80.  MyRes.Seek(NameOffset-2,soFromBeginning);//Записываем имя ресурса
    81.  For i:=0 to Length(Heder.Name) do
    82.  Begin
    83.   CHR:=Ord(Heder.Name[i]);
    84.   MyRes.Write(CHR,SizeOf(CHR));
    85.  End;
    86.  
    87.  buf:=0;                     //Выравнивание
    88.  if Length(Heder.Name)=1 Then
    89.  For i:=1 to 6 do
    90.  MyRes.Write(buf,SizeOf(buf))
    91.  Else
    92.  Begin
    93.  FFFF:=$00000000;
    94.  For i:=1 to 2 do//расчет
    95.  MyRes.Write(FFFF,SizeOf(FFFF));
    96.  End;
    97.  FFFF:=$00001030;
    98.  MyRes.Write(FFFF,SizeOf(FFFF));
    99.  
    100.  i:=MyRes.Seek(0,soFromCurrent);
    101.  MyRes.Seek(TypeOffset,soFromBeginning);
    102.  MyRes.Write(Heder.RcType,SizeOf(Heder.RcType));//Записываем тип ресурса
    103.  MyRes.Seek(i,soFromBeginning);
    104.  
    105.  FFFF:=$00000000;
    106.  MyRes.Write(FFFF,SizeOf(FFFF));
    107.  MyRes.Write(FFFF,SizeOf(FFFF));
    108.  
    109.  i:=MyRes.Seek(0,soFromCurrent);
    110.  Heder.HeaderSize:=i-32;//Размер описания ресурса
    111.  MyRes.Seek(HeaderSizeOffset,soFromBeginning);
    112.  MyRes.Write(Heder.HeaderSize,SizeOf(Heder.HeaderSize));//записываем разницу между размером и базой заголовка
    113.  MyRes.Seek(i,soFromBeginning);
    114.  
    115.  //пишем сам ресурс
    116.  Count:=14;//Отбрасываем часть заголовка bmp файла
    117.  SrcFile.Seek(14,soFromBeginning);
    118.  While Count<SrcFile.Size do
    119.  Begin
    120.  SrcFile.Read(Buf,1);
    121.  MyRes.Write(Buf,1);
    122.  Count:=Count+1;
    123.  End;
    124.  
    125.  SrcFile.Free;
    126.  MyRes.Free;
    127.  ShowMessage('Готово');
    128. end;
    129.  
    130. end.