How Windows 98 Processed System.dat and User.dat

Microsoft Windows 98 relied on two core binary files, System.dat and User.dat, to store and manage the centralized configuration database known as the Windows Registry. During startup, the operating system validated, read, and mapped these discrete files into a single unified in-memory hierarchical tree, dynamically routing machine-wide and user-specific configurations to their respective root keys. This article explains the technical architecture, memory management, and file-handling mechanisms Windows 98 used to parse, modify, and commit data to these two critical files.

File Roles and Separation of Data

Windows 98 split the registry into two physical files to separate global system configurations from individual user settings:

  • System.dat: Located by default in C:\WINDOWS, this file contained machine-wide hardware profiles, device driver configurations, installed software paths, and low-level system settings. In the logical registry tree, its contents formed the basis for HKEY_LOCAL_MACHINE.
  • User.dat: By default stored alongside System.dat in C:\WINDOWS (or in C:\WINDOWS\Profiles\<Username> when multi-user profiles were enabled), this file held user preferences, desktop layouts, network connections, and personal application settings. Its contents populated HKEY_CURRENT_USER and subkeys under HKEY_USERS.

Boot Validation and the Real-Mode Phase

The processing of the registry began before Windows 98 entered 32-bit protected mode. During initial system startup, real-mode DOS components and the Registry Checker (SCANREG.EXE) executed to verify file integrity.

  1. Integrity Check: The system verified the internal checksums and structural headers of both System.dat and User.dat.
  2. Automated Recovery: If the files were flagged as corrupt or unreadable, SCANREG.EXE replaced them with the most recent clean automated backup stored in C:\WINDOWS\SYSBCKUP (compressed as RB00x.CAB files).
  3. Execution: Once validated, control was handed over to WIN.COM and the Virtual Machine Manager (VMM32.VXD).

Memory Allocation and the RGKN Binary Format

Both System.dat and User.dat were structured using a proprietary, non-transacted binary format characterized by the CREG or RGKN file signature. This structure was optimized for fast linear parsing and low memory footprints:

  • Header (RGKN): Defined file size, version metadata, and root offsets.
  • Record Blocks (RGDB): Stored individual registry keys, values, and security identifiers as fragmented blocks linked via internal byte offsets.

When Windows transitioned to 32-bit protected mode, the kernel module responsible for registry handling—primarily managed through 32-bit kernel components and exposed via ADVAPI32.DLL—read the files from disk. Instead of reading the entire multi-megabyte files into continuous blocks of linear memory, Windows 98 utilized a caching layer. The operating system loaded index tables and frequently accessed nodes into system memory buffers, resolving key lookups using internal pointer offsets mapped to the file's binary structures.

Dynamic Namespace Unification

To software applications and the Windows interface, the registry appeared as a single tree rather than two distinct files. Windows 98 processed this through pointer abstraction:

  • HKEY_LOCAL_MACHINE directly interfaced with the memory cache linked to System.dat.
  • HKEY_CLASSES_ROOT functioned as a dynamic link referencing HKEY_LOCAL_MACHINE\Software\Classes.
  • HKEY_USERS mapped both the default profile and active user hives.
  • HKEY_CURRENT_USER redirected directly to the parsed contents of the currently active User.dat.

When an application called 32-bit Win32 Registry APIs (such as RegOpenKeyEx or RegQueryValueEx), the registry engine resolved the path, determined whether the target resided in System.dat or User.dat, and fetched the binary record from memory.

Writing, Flushes, and Disk Commit

Modifications to the registry in Windows 98 were handled asynchronously in memory before being committed to disk:

  1. In-Memory Modification: When an application executed write operations like RegSetValueEx, the kernel updated the corresponding in-memory structures and marked the affected blocks as "dirty."
  2. Flushing Mechanism: Changes remained in memory until triggered by an explicit API call (RegFlushKey), an idle timeout controlled by the operating system, or a standard system shutdown sequence.
  3. File Writing: When writing back to disk, Windows 98 cleared the hidden, system, and read-only attributes of System.dat and User.dat, appended or altered the data blocks, updated file checksums, and restored the original file attributes. Because the format lacked the transaction-logging capabilities found in Windows NT registry hives, sudden power loss during this write phase was the primary cause of registry corruption in Windows 98.