Overview
A STEP 7 project (file extension .s7p) is not a single binary blob. It is a structured container of dBase III/IV tables, subfolders, link lists, and resource archives that the SIMATIC Manager uses to rebuild the station, CPU, and program tree shown in the project navigator. The on-disk format is intentionally undocumented by Siemens; only the contents of readme.rtf shipped with STEP 7 release 5.6 give an approximate description, as confirmed in the official Programming with STEP 7 manual. Third-party OPC servers, asset management tools, and version-control bridges must parse these files directly when the SIMATIC Manager cannot be invoked.
This reference documents the container layout as observed for STEP 7 V5.x projects containing S7-300 and S7-400 stations, the role of every dBase file, the relationship IDs between tables, and the practical techniques used to read them without the SIMATIC Manager. It also covers the official alternative path for symbol export (S5 SEQ and DIF formats) and the interaction with ProTool .pdb files in mixed PC-based automation projects.
STEP 7 Project Container Architecture
An .s7p file is a Microsoft Compound File (OLE2) container. Inside the container the SIMATIC Manager stores:
-
Root object files: the project metadata (
objtyp.dat, masterS7RESOFF). -
Subfolders that mirror the logical tree:
hOmSave7(offline/save),hOmLoad7(online view),OMBSTX(offline blocks),YDBs(symbolic lists),hrs(link resources). -
Hardware subfolders:
S7HK31AX(S7-300 hardware catalog),S7HK41AX(S7-400 hardware catalog). -
Project history (
s7hstatx) that tracks stations and their relationship to CPU and program folders.
The logical hierarchy inside the container is always three levels deep:
-
S7-Station— one per physical or simulated PLC. -
S7-CPU— one per CPU inside the station (a station can carry more than one CPU). -
S7-Program— the program folder containing all blocks (OB, FB, FC, DB, SDB, SFB, SFC, UDT) and the symbol table.
Folder Layout Summary
| Folder | Role | Key Contents |
|---|---|---|
hOmSave7\s7hstatx |
Station registry |
HOBJECT1.DBF, HRELATI1.DBF
|
hOmSave7\S7HK31AX |
S7-300 HW view |
HOBJECT1.DBF, HRELATI1.DBF
|
hOmSave7\S7HK41AX |
S7-400 HW view |
HOBJECT1.DBF, HRELATI1.DBF
|
OMBSTX |
Offline blocks container | Subfolders per program (e.g. 001A0000) |
YDBs |
Symbol table storage | One subfolder per program; SYMLIST.DBF per program |
hrs |
Hour/resource linkage |
linkhrs.lnk (binary 512-byte records) |
hOmLoad7 |
Online PLC cache | Mirrors hOmSave7 after a download |
Top-Down Traversal Logic
To resolve a complete station > CPU > program tree, query the dBase tables in the following order. The logic mirrors what the SIMATIC Manager does internally when it opens the project:
- List stations by filtering
HOBJECT1inhOmSave7\s7hstatxonOBJTYP. - Use the station's
IDasSOBJIDinHRELATI1withRELID = 16to get the childTOBJIDthat points at the CPU folder. - Open
HOBJECT1inS7HK31AX(S7-300) orS7HK41AX(S7-400) and match onUNITID=TOBJIDto retrieve the CPU name and its ownID. - Repeat the parent-child lookup using
RELID = 16against the CPU'sIDto obtain theS7-Programfolder ID. - Open
S7RESOFF.DBFat the project root and locate the program entries that match theTOBJIDfrom step 4.
hOmSave7 Station Database
The station registry lives at hOmSave7\s7hstatx. Two tables drive it:
-
HOBJECT1.DBF — master object list. Columns used:
ID,NAME,OBJTYP,UNITID,PARENTID. -
HRELATI1.DBF — relation list between objects. Columns used:
SOBJID(source),TOBJID(target),SOBJTYP,TOBJTYP,RELID.
The relationship type RELID = 16 is the structural parent-child link used throughout the project tree.
Station Object Type Identifiers
OBJTYP |
Meaning |
|---|---|
| 1314969 | S7-300 station (S7-Station) |
| 1314970 | S7-400 station (S7-Station) |
| 1331969 | S7-Program folder node inside the CPU hardware catalog |
OBJTYP values were constant across STEP 7 V5.3 through V5.6. TIA Portal projects (file extension .ap16) use a completely different schema based on SQLite and should not be traversed with the queries below.Hardware Folder Queries (S7HK31AX / S7HK41AX)
The hardware folders store the rack, module, and CPU objects. They expose the same column layout as s7hstatx but each subfolder is dedicated to a PLC family:
-
S7HK31AX— hardware objects of S7-300 stations (IM, SM, FM, CP). -
S7HK41AX— hardware objects of S7-400 stations (UR, CR, ER, FM, CP).
When resolving the CPU that owns a given program:
- From
S7RESOFF, capture the program'sID. - Search
S7HK31AX\HRELATI1for rows whereTOBJID= program-ID andTOBJTYP= 1331969. - From the matched row, take
SOBJIDandSOBJTYPand look them up inS7HK31AX\HOBJECT1to recover the CPU display name. - For S7-400 stations, repeat the query in
S7HK41AXinstead ofS7HK31AX.
S7RESOFF and the Program Resource Tree
S7RESOFF.DBF at the project root is the master program-resource index. Each row represents either an offline program folder or a system resource. The column most often needed externally is RSRVD4_L: a 32-bit offset, expressed in bytes, that points into the binary resource archive linkhrs.lnk stored in hrs\.
Typical S7RESOFF columns used by parsers:
| Column | Type | Purpose |
|---|---|---|
ID |
Integer | Primary key |
NAME |
String | Display name of the program folder |
UNITID |
Integer | Foreign key to owning CPU object |
RSRVD4_L |
Long | Byte offset into linkhrs.lnk
|
RSRVD1 … RSRVD3
|
Various | Reserved indexes used by SIMATIC Manager internals |
Decoding linkhrs.lnk and the OMBSTX Folder Mapping
The folder names inside OMBSTX (where the actual block binaries live) do not match the numeric ID in S7RESOFF. To resolve them, read hrs\linkhrs.lnk at byte offset RSRVD4_L for 512 bytes, then search for the magic byte sequence 01 60 11. The two bytes immediately following the magic form a big-endian 16-bit value that is the hexadecimal subfolder name (for example, 00 1A yields folder 0000001A).
Reference Perl idiom:
if ($filedata =~ /\x01\x60\x11(.{2})/) {
my @xx = unpack("C2", $1);
my $folder = sprintf "0000%02X%02X", $xx[0], $xx[1];
}
016011 is not documented by Siemens and is shared with internal SIMATIC Manager pointer types. If multiple matches occur within one 512-byte block, take the first occurrence, which corresponds to the record offset read from RSRVD4_L.Symbol Table Files
Symbol tables are stored under YDBs, one subfolder per program. Each subfolder contains SYMLIST.DBF, and the parent SYMLISTS.DBF maps programs to their symbol-table subfolder.
SYMLISTS and YLNKLIST Join
To locate the symbol table of a given program, perform a two-table join:
- From
S7RESOFF, capture the programID(= xxx). - From
YLNKLIST.DBF, run:SELECT SOI FROM YLNKLIST WHERE TOI = xxx— result is yyy, the linkage ID. - From
SYMLISTS.DBF, run:SELECT _DBPATH FROM SYMLISTS WHERE _ID = yyy— result is the subfolder, e.g.\YDBs\zzzz\.
SYMLIST Columns
| Column | Meaning |
|---|---|
_SKZ |
Symbolic name (e.g. Motor1_Start) |
_OPHIST |
Operand (e.g. M 245.3, DB1.DBX0.0, I 0.1) |
_COMMENT |
Symbol comment (multiline allowed) |
_DATATYP |
Data type (BOOL, INT, REAL, STRING, UDT, ARRAY) |
The _OPHIST operand string follows the classic STEP 7 mnemonic grammar and must be re-parsed to recover absolute addresses; the dBase file does not store the resolved byte/bit address. Multi-element operands (UDT members, ARRAY indices) are flattened to the root operand only.
Block Files (BAUSTEIN and SUBBLK)
Code blocks live inside the resolved OMBSTX subfolder. Two dBase files catalog them:
-
BAUSTEIN.DBF — one row per block; columns include
BLOCKNO,BLOCKTYP(OB, FB, FC, DB, SDB, SFB, SFC, UDT),AUTHOR,VERSION,CRC. - SUBBLK.DBF — the sub-block list; useful for instance DBs of FBs and for multi-instance UDT structures.
The block binary itself is a separate .awl / .scl / .db file referenced from BAUSTEIN; its content is a S7-pack container that wraps the compiled code or the source. STEP 7 release 5.6 is the last release that ships with the documented block-container specification.
Reading the dBase Files Programmatically
The dBase files have two quirks that frequently trip parsers:
- The encryption flag (bit 0 of byte 0 of the header) is often set, even though the file is plaintext.
- The MDX index flag (bit 7 of byte 28) is frequently set, indicating a companion
.mdxfile that the SIMATIC Manager keeps but does not require for read access.
.dbf to a temporary directory, clear both flags, then open it with the consumer driver. Without this, the OLE DB provider for dBase (used by C# via OleDbConnection) refuses to read encrypted tables and throws ISAM errors.Perl (DBD::XBase) Approach
use DBI;
my $dbh = DBI->connect(
"dbi:XBase:/path/to/folder",
undef, undef,
{ RaiseError => 1 }
);
my $sth = $dbh->prepare(
"SELECT ID, NAME FROM S7RESOFF WHERE ID = ?"
);
$sth->execute($program_id);
while (my @row = $sth->fetchrow_array) {
print "$row[0]\t$row[1]\n";
}
C# / OLE DB Approach
The Microsoft OLE DB Provider for Visual FoxPro / dBase handles the files after the flag workaround above. A robust connection string is:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\TempDbf;
Extended Properties="dBase 5.0;HDR=NO;IMEX=1";
MS Access
MS Access 2000 (and later, with the deprecated dBase ISAM) can open S7RESOFF.DBF, BAUSTEIN.DBF, and most of the non-encrypted .dbf files directly. MS Access is the fastest path to a manual audit but cannot be scripted headlessly.
Alternative: Native STEP 7 Export Formats
For consumers that only need the symbol table, the SIMATIC Manager Symbol Editor offers four export formats; two of them are open and reversible:
| Format | Extension | Reversible | Notes |
|---|---|---|---|
| S5 symbol list | .SEQ |
Importable | Plain text; compatible with legacy S5 tools |
| Data Interchange Format | .DIF |
Yes (round-trip safe) | Openable in Excel; edit and reimport |
| ASCII | .ASC |
Importable | Free-form text |
| Assignment list | .AWL |
Importable | Carries operand and symbol on the same line |
Use the SIMATIC Manager path Options > Symbol Table > Export or, inside the Symbol Editor, Edit > Select All > Copy to push the table to the clipboard and paste it into Excel. The clipboard format is line-delimited:
LL12ks22 M 245.3 BOOL description 1
LL12ks23 M 245.4 BOOL description 2
LL12ks24 M 245.5 BOOL description 3
ProTool PDB Files in STEP 7 Projects
STEP 7 projects for PC-based automation (WinAC, S7-300 with integrated ProTool/Pro RT) carry an additional set of files with the .pdb extension, which are the project databases of the ProTool/Pro HMI tool. These files are independent of the PLC dBase schema and cannot be parsed with the queries above. Their structure is documented only in the legacy ProTool manuals and is out of scope for the block and symbol parser. The official SiePortal note on PDB files confirms that these belong to the HMI part of the project.
Verification and Troubleshooting Matrix
| Symptom | Likely Cause | Resolution |
|---|---|---|
Empty result from HOBJECT1 query |
Encryption or MDX flag set | Copy to temp folder, clear header flags 0x01 and 0x80 |
RELID = 16 returns no row |
Querying the wrong hardware folder | Use S7HK31AX for S7-300, S7HK41AX for S7-400 |
OMBSTX folder name does not match S7RESOFF.ID
|
Folder comes from linkhrs.lnk via RSRVD4_L
|
Read 512 bytes at offset, locate 01 60 11, decode next 2 bytes |
| Symbol table blank | Program ID not joined via YLNKLIST
|
Two-step join S7RESOFF.ID → YLNKLIST.SOI → SYMLISTS._DBPATH
|
OleDbException on opening SYMLIST.DBF
|
File locked by running SIMATIC Manager | Close all STEP 7 processes, or copy file to read-only temp path |
| Absolute addresses missing for DB symbols | Only root operand stored; UDT expansion not stored | Resolve UDT/ARRAY structure from BAUSTEIN + manual walk |
| Field mismatches between hardware catalog and station | Project contains both S7-300 and S7-400 | Dispatch to S7HK31AX or S7HK41AX based on OBJTYP (1314969/1314970) |
Engineering Notes and Caveats
- The
hOmSave7andhOmLoad7trees diverge after the first download from a live PLC. Always read fromhOmSave7if you need the as-engineered offline view. - STEP 7 V5.6 is the last release with this dBase-based layout. STEP 7 within TIA Portal stores projects in a SQLite-backed archive; the queries in this reference will return zero rows if applied to
.ap16/.ap17containers. - The 512-byte record size inside
linkhrs.lnkwas stable from STEP 7 V5.0 through V5.6; do not hard-code 256 or 1024 byte records observed in older S5 archives. - Reading the files while the SIMATIC Manager holds an exclusive lock can corrupt the encryption header. Always take a copy first.
How do I tell whether a STEP 7 station is S7-300 or S7-400 from the dBase files?
Query hOmSave7\s7hstatx\HOBJECT1.DBF and filter on OBJTYP. The value 1314969 identifies an S7-300 station and 1314970 identifies an S7-400 station. Use the result to choose between S7HK31AX and S7HK41AX for subsequent CPU lookups.
Why does my OPC server see no symbols even though the project contains a symbol table?
Most parsers stop at S7RESOFF and never perform the YLNKLIST join. The correct path is S7RESOFF.ID → YLNKLIST.SOI → SYMLISTS._DBPATH → SYMLIST. Skipping the join returns zero rows because SYMLISTS is the index layer that points at the actual SYMLIST.DBF file.
Can I read these files while the SIMATIC Manager is running?
Not reliably. SYMLIST.DBF is typically locked, and OleDb will fail with an ISAM error. Copy the folder to a temp directory, clear the encryption bit (0x01) and the MDX bit (0x80) of the header byte 0, then open the copy read-only.
Where is the list of blocks in a STEP 7 project stored?
In BAUSTEIN.DBF and SUBBLK.DBF located at the project root. BAUSTEIN lists each block with its number, type, author, and version; SUBBLK carries instance relations needed for multi-instance DBs and UDT expansion.
Is there a supported, documented alternative to parsing the dBase files?
Yes. Use the SIMATIC Manager Symbol Editor to export the symbol table as .SEQ (S5 symbol list) or .DIF (Data Interchange Format). Both are plain text, round-trip safe, and avoid the encryption-flag workaround described in the manual reading techniques section.