2008-03-26
| Table of Contents: |
| Rate This Article: | Add This Article To: |
( Page 3 of 4 )
Explore resource data formats
Table 1 identifies the various types of resources that can be stored in the resource section. (I'm unaware of any additional
resource types.) These resource types have their own data formats, which need to be understood in order to recreate the
original resource files (bitmap .bmp and cursor .cur files, for example). For brevity, this section
examines only a few of these formats.
RT_BITMAP
The RT_BITMAP resource type describes the resource data as a single device-independent bitmap. The bitmap is stored as a
Windows BITMAPINFOHEADER structure or OS/2 BITMAPCOREHEADER structure, optionally followed by a
color table (a sequence of RGBQUAD structures for Windows; a sequence of RGBTRIPLE structures for
OS/2), followed by the bitmap image data.
It doesn't matter to the utility program whether the resource data contains BITMAPINFOHEADER and RGBQUAD structures, or BITMAPCOREHEADER and RGBTRIPLE structures. However, the absence
of a BITMAPFILEHEADER structure is an impediment to the program -- this structure must be present at the start
of a .bmp file.
Before writing the resource data to the .bmp file, the utility program creates a BITMAPFILEHEADER structure and initializes the structure's fields appropriately (add the size of the BITMAPFILEHEADER structure
to the size of the resource data, and assign the sum to the structure's bfSize field, for example). The program
then writes this structure to the file.
RT_GROUP_CURSOR and RT_CURSOR
A resource script statement for a cursor resource (MyCursor CURSOR "mycursor.cur", for example) is described in
a PE file via RT_GROUP_CURSOR and RT_CURSOR resource types. The former resource type stores a directory in the resource data.
This directory identifies the various images comprising the cursor resource, and begins with a header structure:
typedef struct
{
WORD wReserved; // Always 0
WORD wResID; // Always 2
WORD wNumImages; // Number of cursor images/directory entries
}
CURHEADER;
This header, which also appears at the beginning of a .cur file (and is written "as is" to a .cur file by the utility program), identifies the number of cursor images that are stored elsewhere in the resource data. Each
cursor image is described by one of the entries in the array of cursor directory entry structures that follows the header:
typedef struct
{
WORD wWidth;
WORD wHeight; // Divide by 2 to get the actual height.
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInImage;
WORD wID;
}
CURDIRENTRY;
Most of the directory entry's fields present values for interpreting the image data. The wID field provides an
integer ID that the utility program uses to find the appropriate RT_CURSOR resource, which stores the actual cursor image in
the resource data. The Name field in the only IMAGE_RESOURCE_DIRECTORY_ENTRY for this resource's
instance resource directory stores the cursor image's ID.
RT_CURSOR describes a single cursor image's resource data as a two-byte x hotspot value, followed by a two-byte y hotspot
value. A BITMAPINFOHEADER structure followed by a color table comes next -- I've yet to encounter a cursor image
with 24-bit color. The resource data next stores the image's XOR bitmap followed by its AND bitmap. These two bitmaps are
used together to support transparency.
To recreate the .cur file, the utility program first writes the values that are stored in the CURHEADER structure, located at the beginning of RT_GROUP_CURSOR's resource data, to the file. The program then
converts each of the CURDIRENTRY structures and associated hotspot values to an equivalent CURSORDIRENTRY structure:
typedef struct
{
BYTE bWidth;
BYTE bHeight; // Set to CURDIRENTRY.wHeight/2.
BYTE bColorCount;
BYTE bReserved;
WORD wHotspotX;
WORD wHotspotY;
DWORD dwBytesInImage;
DWORD dwImageOffset; // Offset from start of header to the image
}
CURSORDIRENTRY;
After calculating the offset to a cursor image and assigning this value to the dwImageOffset field in the
associated CURSORDIRENTRY structure, the utility program writes the CURSORDIRENTRY structure to the .cur file. After writing these structures, it writes all of the cursor images' resource data areas (without
their hotspot fields) to the file.
RT_GROUP_ICON and RT_ICON
Icons are organized similarly to cursors. A resource script statement for an icon resource (MyIcon ICON
"myicon.ico", for example) is described in a PE file via RT_GROUP_ICON and RT_ICON resource types. Although there are
many similarities between icon and cursor resources, there are also differences, beginning with the following structures:
typedef struct
{
WORD wReserved; // Always 0
WORD wResID; // Always 1
WORD wNumImages; // Number of icon images/directory entries
}
ICOHEADER;
typedef struct
{
BYTE bWidth;
BYTE bHeight;
BYTE bColors;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInImage;
WORD wID;
}
ICODIRENTRY;
As with .cur files, the header appears at the beginning of .ico files, but with 1 as its resource
ID. Also, the ICODIRENTRY structure differs from its CURDIRENTRY structure counterpart in terms of
new fields (bColors and bReserved) and field sizes (BYTE instead of WORD for the width and height fields).
RT_ICON is similar to RT_CURSOR in that it stores a single image, but without hotspot information. The resource data
typically begins with a BITMAPINFOHEADER structure, often followed by a color table, followed by XOR and AND
structures. However, if the image is specified via the Portable Network Graphics format, the image's resource data consists
entirely of PNG information.
To recreate the .ico file, the utility program first writes the values that are stored in the ICOHEADER structure, located at the beginning of RT_GROUP_ICON's resource data, to the file. The program then
converts each of the ICODIRENTRY structures to an equivalent ICONDIRENTRY structure:
typedef struct
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInImage;
DWORD dwImageOffset; // Offset from start of header to the image
}
ICONDIRENTRY;
After calculating the offset to an icon image and assigning this value to the dwImageOffset field in the
associated ICONDIRENTRY structure, the utility program writes the ICONDIRENTRY structure to the .ico file. After writing these structures, it writes all of the icon images' resource data areas to the file.
| Note |
|---|
| To explore additional resource data formats, check out Floyd Rogers (somewhat dated) article Win32 Binary Resource Formats. |
![]() |
|


