The AutomaticDestinations-ms File Format Explained
An automaticDestinations-ms file is an OLE Compound File (CFB / MS-CFB). Each
numbered stream holds a shell link (LNK) for a recently-used item, and a single
DestList stream provides ordering, timestamps, and the originating hostname.
The outer container: OLE Compound File
The file follows the Microsoft Compound File Binary format (MS-CFB), the same structured-storage container behind pre-2007 Office documents. Internally, the file is divided into fixed-size sectors (512 bytes for most jump lists), threaded through a FAT, with a mini-stream for entries smaller than 4096 bytes. A directory at a known sector index lists the named streams ("storages" and "streams" in CFB terminology).
For a Jump List you only care about the directory listing. You will see a flat
set of streams: one per recent item, named with a hexadecimal number, plus a
single DestList stream. There are no nested storages.
Numbered streams: one LNK per entry
Each numbered stream name is a lowercase hex integer — 1, 2, a, 1f,
and so on — and contains a standard Windows shell link, as documented in
[MS-SHLLINK]. That means the same LNK parser you already use for .lnk
files on disk will decode it: ShellLinkHeader, optional LinkTargetIDList,
LinkInfo, the StringData blocks (NAME_STRING, RELATIVE_PATH, WORKING_DIR,
COMMAND_LINE_ARGUMENTS, ICON_LOCATION), and the ExtraData blocks
(TrackerDataBlock, PropertyStoreDataBlock, and friends).
The stream name is the entry ID, and it is what links each LNK back to a row in
the DestList.
The DestList stream
DestList is the index that turns the bag of LNKs into an ordered, dated
recently-used list. It begins with a 32-byte header followed by a sequence of
variable-length entry records.
DestList header (32 bytes, little-endian)
offset size field
0x00 4 version (0x01..0x04 observed; Win7=1, Win10+=3/4)
0x04 4 number of entries
0x08 4 number of pinned entries
0x0C 4 unused / reserved (often a float; varies by version)
0x10 4 last entry ID issued
0x14 4 unused / reserved
0x18 4 last revision number
0x1C 4 unused / reserved
Each entry that follows carries — in order — the metadata needed to reconstruct where the LNK came from:
DestList entry (variable length)
field size notes
checksum / reserved 8 version-dependent
NewVolumeID (GUID) 16 target volume
NewObjectID (GUID) 16 target object (file)
BirthVolumeID (GUID) 16 original volume
BirthObjectID (GUID) 16 original object
NetBIOS hostname 16 ASCII, NUL-padded
entry ID 4 matches the numbered stream name
reserved 4
access count 4 IEEE-754 float; sentinel = pinned
last access FILETIME 8 100-ns ticks since 1601-01-01 UTC
entry pin status / reserved 4 layout differs by version
name length (chars) 2 UTF-16LE code units
name 2*N UTF-16LE, not NUL-terminated
trailer 4 only on DestList v3/v4
Versions 3 and 4 (Windows 10 and later) add a small trailer per entry and tweak
a few reserved fields; the field names and purposes above are stable, but
exact offsets shift slightly between versions. Always branch on the header
version before parsing entries.
Pinned vs unpinned entries
The header reports the number of pinned entries, but the per-entry pin marker is
encoded into the access-count field. Unpinned items store a normalised float
representing how often the user opened the target. Pinned items store a sentinel
value — historically 0xFFFFFFFF interpreted as a 32-bit float (NaN) — to mark
that the entry is user-pinned and that the count is not meaningful. The exact
sentinel and the position of any additional pin flag varies between DestList
versions, so treat the count as opaque until you have checked the version.
Practical parsing notes
- Endianness. Everything is little-endian, including GUIDs (
Data1/Data2/Data3are little-endian;Data4is a byte array). - FILETIME. Convert with
unix_seconds = (filetime / 10_000_000) - 11_644_473_600. Keep them in UTC; jump lists do not record timezone. - Hostname. The 16-byte NetBIOS name is the workstation that opened the file. On a domain it is invaluable for correlating activity across hosts.
- Entry ID. Match the 4-byte
entry IDfrom each DestList row against the hex stream names in the CFB directory; that is your join key. - Version skew. Windows 7 produced DestList v1. Windows 8/8.1 introduced v3; Windows 10 and 11 commonly emit v3 or v4. Older parsers that assume v1 layout will misread modern files — always read the header first.
- Ordering. Do not assume the DestList rows are in MRU order. Sort by
last access FILETIME(or bylast entry IDminus offset, depending on what you need).
To inspect a real file without writing any code, drop one on the in-browser parser — it runs a Rust DestList + LNK parser compiled to WebAssembly, entirely client-side. For background on where these files come from and why they matter for an investigation, see the forensic primer.