Skip to content

RSRC Format

mefistotelis edited this page Nov 26, 2022 · 9 revisions

Table of Content

General structure

The RSRC file contains two identical RSRC headers. Data for sections of each block follow the first RSRC header. Second RSRC header is followed by Blocks Info and then an array of Block Headers. Following these is an array of Block Section Info. The file ends with some section names stored as Pascal string (there is often only one name).

+-----------------------------+
|        RSRC header 1        |
|+---------------------------+|
||      Section 1 Data       ||
|+---------------------------+|
||           ....            ||
|+---------------------------+|
||      Section M Data       ||
|+---------------------------+|
+-----------------------------+
+-----------------------------+
|        RSRC header 2        |
|+---------------------------+|
||  Block Info List Header   ||
|+---------------------------+|
||        Blocks Info        ||
||+-------------------------+||
|||     Block 1 Header      |||
||+-------------------------+||
|||          ....           |||
||+-------------------------+||
|||     Block N Header      |||
||+-------------------------+||
|+---------------------------+|
||      Section 1 Info       ||
|+---------------------------+|
||           ....            ||
|+---------------------------+|
||      Section M Info       ||
|+---------------------------+|
|+---------------------------+|
||       Section Names       ||
|+---------------------------+|
+-----------------------------+

Reading the file starts with finding second RSRC header (pointed to by size in 1st RSRC Header). Then reading Block Info and Block Headers. The Block Headers contain offset to list of Section Infos for each block, and the count of sections within each block. Then Section Info structures can then be parsed, and these contain offsets, within the first RSRC, to the Block Section Data. There, the real data is stored.

It is not fully known why there is the division to sections. Each section of a block seem to contain alternative data for that block. The idea seem to be that a loading program selects the section which matches its environment, and ignores other sections in specific block.

RSRC Header

offset1: 0 offset2: RSRC Data Offset

 Length | Type    | Value
--------+---------+-------
      6 | string  | "RSRC\r\n" Magic ID
      2 | uint16  | Format version
      4 | string  | "LVIN" File type (ie. LabVIEW Instrument)
      4 | string  | "LBVW" Creator (always LabVIEW)
      4 | uint32  | RSRC Info Offset
      4 | uint32  | RSRC Info Size
      4 | uint32  | RSRC Data Offset
      4 | uint32  | RSRC Data Size

For more information, see RSRCHeader class declaration within pylabview source.

Block Info List Header

offset: RSRC Info Offset + RSRC Header Size

 Length | Type    | Value
--------+---------+-------
      4 |         | ?
      4 |         | ?
      4 | uint32  | size of `RSRCHeader`
      4 | uint32  | Block Info Offset
      4 | uint32  | Block Info Size

For more information, see BlockInfoListHeader class declaration within pylabview source.

Blocks Info

offset: RSRC Info Offset + Block Info Offset

 Length | Type    | Value
--------+---------+-------
      4 | uint32  | Block Count (+1)
        |         | Block data

For more information, see BlockInfoHeader class declaration within pylabview source.

Block Header

 Length | Type    | Value
--------+---------+-------
      4 | string  | Name
      4 | uint32  | Count (+1)
      4 | uint32  | Info Offset

For more information, see BlockHeader class declaration within pylabview source.

Block Section Info

offset: Info Offset + Block Offset

 Length | Type    | Value
--------+---------+-------
      4 | uint32  | Section Index
      4 | uint32  | Section Name Offset
      4 | uint32  | ?
      4 | uint32  | Section Data Offset
      4 | int32   | ?

For more information, see BlockSectionStart class declaration within pylabview source.

Block Section Data

offset: Offset + Data Offset

Max size is Data Size. Otherwise you can get the size by comparing the offsets. Repeat Count of these:

 Length | Type    | Value
--------+---------+-------
      4 | uint32  | Size
   Size | data    | Contents of the block (might be compressed (zlib))

Other sources

Findings in this document are based on work of @jcreigh and @tomsoftware. See VI Explorer Source and Jessica's Wiki for more.