How Windows 98 Processed LNK Shortcut Files

In Microsoft Windows 98, shell shortcuts (bearing the .lnk extension) were not plain-text pointers, but complex binary structures processed via the Component Object Model (COM) and the Windows Shell namespace. When a user interacted with a shortcut, Windows 98 parsed its binary headers, resolved the target using Item Identifier Lists (PIDLs), invoked heuristic link-tracking algorithms if the target had moved, and finally executed the associated file or virtual shell folder using the ShellExecuteEx API.

The Binary Architecture of .lnk Files

Rather than storing a simple path string, Windows 98 structured .lnk files according to the Shell Link Binary File Format. Every .lnk file began with a fixed-size header (ShellLinkHeader) containing metadata flags, target attributes, timestamps, and icon information.

Key data structures within the binary format included:

  • LinkFlags: A bitfield indicating which optional structures were present, such as an Item ID List, relative path strings, working directory parameters, or environment variables.
  • LinkTargetIDList: A structure containing an Item Identifier List (PIDL) that allowed shortcuts to target virtual folders, like "Control Panel" or "Printers," which had no real representation on the FAT32 file system.
  • LinkInfo: Stored local drive letters, volume serial numbers, and UNC (Universal Naming Convention) network paths necessary for resolving the target location.

COM Interfaces and SHELL32.DLL

Windows 98 handled shortcuts dynamically through SHELL32.DLL rather than static file reads. The operating system exposed the functionality through two primary COM interfaces: IShellLink and IPersistFile.

  1. Initialization: When Windows Explorer encountered a .lnk file, it instantiated the ShellLink object via COM.
  2. Loading: The IPersistFile::Load method opened the .lnk file and read its raw bytes into memory.
  3. Parsing: The IShellLink interface exposed methods like GetPath, GetArguments, GetWorkingDirectory, and GetIconLocation, translating the binary blocks into usable parameters for the operating system.

Namespace Resolution Using PIDLs

Because Windows 98 unified the physical file system with virtual objects under the Windows Desktop namespace, it relied heavily on PIDLs (Pointers to Item ID Lists).

When processing the shortcut, the Shell checked whether the target was a real file path or a virtual namespace object:

  • If the target was a standard file, the system checked the LinkInfo structure for a local path (such as C:\Program Files\App.exe).
  • If the target was a non-file system object, the Shell navigated the Shell Namespace using the LinkTargetIDList. This allowed shortcuts to open system applets, dial-up connections, and network resources seamlessly.

If a target file was moved, renamed, or located on a mapped drive that changed, Windows 98 initiated a resolution algorithm via IShellLink::Resolve. Because Windows 98 ran primarily on the FAT32 file system (which lacked the NTFS Object IDs introduced later in Windows 2000), it relied on heuristic searching:

  1. Direct Path Validation: The Shell first checked the stored absolute path.
  2. Relative Path Traversal: If the absolute path failed, it checked the relative path calculated from the shortcut’s current location.
  3. Volume and Metadata Match: The Shell analyzed the volume serial number, original creation time, file size, and file attributes. It then scanned nearby directories and the root of the drive for an object matching those specific attributes.
  4. User Intervention: If heuristic matching failed, Windows 98 displayed a dialog prompting the user to manually locate the missing target.

Execution via ShellExecuteEx

Once the target was validated, Windows Explorer finalized the launch through the ShellExecuteEx API. The operating system extracted the runtime configuration embedded within the shortcut:

  • Injected command-line parameters into the process creation call.
  • Set the working directory to the path specified in the shortcut rather than the directory containing the .lnk file itself.
  • Applied the specified window display state (SW_SHOWNORMAL, SW_SHOWMAXIMIZED, or SW_SHOWMINNOACTIVE).
  • Registered any assigned hotkeys through the Windows Shell message loop.

After assembling these properties, ShellExecuteEx made the low-level CreateProcess system call, launching the application as configured.