Resources are the parts of a program that are data rather than code: icons, cursors, bitmaps, menus, dialogs, string tables, fonts and version information. A Windows NE file lists them in its resource table, by type, and keeps their bytes elsewhere in the file. OS/2 1.x files store them differently, as segments; see OS/2’s form.
Layout
The table starts at ne_rsrctab
from the start of the NE header and runs up to the resident name table. A module with
no resources has ne_rsrctab equal to ne_restab, or a table of
just a shift and an end mark. In order:
rscAlignShift, 2 bytes: resource offsets and lengths are in units of 2shift bytes.- One TYPEINFO record for each resource type, each followed by a NAMEINFO record for each resource of that type.
- A type ID of 0, 2 bytes, which ends the types.
- The names of named types and resources, ending with a zero byte.
TYPEINFO
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 2 | rtTypeID | With the top bit set, a numbered type: the low 15 bits are its number. Otherwise the offset of the type’s name from the start of the resource table. 0 ends the list. |
| 2 | 2 | rtResourceCount | The number of resources of this type. |
| 4 | 4 | rtReserved | Reserved; Windows uses it in memory. |
| 8 | 12 × count | NAMEINFO | The resources of this type. |
NAMEINFO
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 2 | rnOffset | Where the resource’s data starts, in units of 2shift bytes. |
| 2 | 2 | rnLength | The length of the data, in the same units. |
| 4 | 2 | rnFlags | See Flags. |
| 6 | 2 | rnID | With the top bit set, the resource’s number (the low 15 bits). Otherwise the offset of its name from the start of the resource table. |
| 8 | 2 | rnHandle | Reserved; Windows keeps a handle here in memory. |
| 10 | 2 | rnUsage | Reserved; Windows keeps a usage count here in memory. |
Flags
| Bit | Meaning |
|---|---|
0x0010 | Movable; otherwise fixed. |
0x0020 | Pure: it can be shared. |
0x0040 | Preload; otherwise loaded when first needed. |
0x1000 | Discardable. |
These are the memory attributes of Microsoft’s resource compiler, MOVEABLE, PURE,
PRELOAD and DISCARDABLE. As in the segment table, the bits 0x0C00 are often
set too; what they mean was not confirmed.
Names
A type or resource with a name instead of a number gives the offset of that name from the start of the resource table. The names follow the end of the types: each is a length byte and that many characters, with no zero at the end, and a zero length byte ends them. The explorer shows any bytes after that as padding.
The data
A resource’s bytes are at file offset rnOffset × 2shift, and rnLength × 2shift bytes long, so the stated length is rounded up and may end in padding. The data is in the resource’s own format, the 16-bit Windows form of an icon, a menu or a dialog. The explorer lists every resource in its Resources table, with its type, name and size, and selecting one shows its bytes.
Packers can rewrite the table: one self-extractor examined for this site, packed with PKLITE for Windows, has resource offsets that point back inside the header. The explorer reports resources that lie outside the file or overlap other blocks.
Type numbers
Windows NE files use Windows’ numbering of resource types:
| Number | Type | Number | Type |
|---|---|---|---|
| 1 | Cursor | 8 | Font |
| 2 | Bitmap | 9 | Accelerators |
| 3 | Icon | 10 | Raw data |
| 4 | Menu | 11 | Message table |
| 5 | Dialog | 12 | Cursor group |
| 6 | String table | 14 | Icon group |
| 7 | Font directory | 16 | Version |
Type 15 also occurs in several files examined for this site. It is not in Wine’s list, and the explorer shows it as “Type 15”.
OS/2’s form
OS/2 1.x keeps each resource as a segment. The header’s
ne_cres gives
how many, and they are the last ne_cres entries of the
segment table. The resource table is then
just ne_cres entries of 4 bytes, in the same order as those segments:
| Offset | Size | Field | Meaning |
|---|---|---|---|
| 0 | 2 | type | The resource type, in OS/2’s numbering: 1 pointer, 2 bitmap, 3 menu, 4 dialog, 5 string table, and more. |
| 2 | 2 | name | The resource’s number. |
Resource i, counting from 0, is segment ne_cseg − ne_cres + i +
1. The explorer reads the table this way when the target system is not Windows,
ne_cres is not 0, and the table is exactly 4 bytes a resource; otherwise
it reads the Windows form. No OS/2 1.x file with resources was among the files examined
for this site, so this form has been tested only on files built for the purpose.
Worked example
WINMINE.EXE, Microsoft’s Minesweeper v3.1, has 15 resources. Its resource table is at
0x450:
00000450 04 00 0E 80 01 00 00 00 00 00 DC 03 03 00 30 1C ..............0.
00000460 64 80 00 00 00 00 02 80 06 00 00 00 00 00 DF 03 d...............
00000470 87 00 30 0C 9A 81 00 00 00 00 66 04 43 00 30 0C ..0.......f.C.0.
04 00: the shift is 4, so offsets and lengths count 16-byte units.0E 80 01 00 00 00 00 00: type0x800E, numbered type 14, an icon group; 1 resource; reserved.DC 03 03 00 30 1C 64 80 00 00 00 00: data at0x03DC× 16 =0x3DC0, 3 × 16 = 48 bytes; flags0x1C30, movable, pure and discardable; ID0x8064, resource number 100; handle and usage 0.02 80 06 00 00 00 00 00: type 2, bitmaps, 6 of them. The first,DF 03 87 00 30 0C 9A 81 …, is bitmap 410, 2,160 bytes at0x3DF0.
After the bitmaps come a menu, three dialogs, a string table, an accelerator table and
two icons. The table
ends with 00 00 at 0x53E; no type or resource is named, so
there are no names, and the resident name table starts at 0x540.