DOC File Documentation


Summary

A DOC (Microsoft Word Document) file is a word-processing document in Word’s legacy binary format, used by default from Word 97 through Word 2003. It is an OLE2 Compound File Binary that begins with the bytes D0 CF 11 E0 A1 B1 1A E1, and its MIME type is application/msword. The modern replacement is the ZIP-based DOCX; free tools such as LibreOffice Writer and Google Docs open old .doc files.

Technical details

FeatureValue
Full nameMicrosoft Word 97-2003 Document
File extension.doc
MIME typeapplication/msword
Format typeOLE2 Compound File Binary (binary)
Container / base formatCompound File Binary (CFB / OLE2 structured storage)
DeveloperMicrosoft
IntroducedWord 1.0 in 1983; OLE-based layout from Word 97 (1997)
Default throughWord 2003 (replaced by DOCX in Office 2007)
Specification[MS-DOC] Word Binary File Format; [MS-CFB] Compound File Binary
Open standardNo — Microsoft-proprietary
Byte orderLittle-endian
Main text streamWordDocument
Formatting streams0Table / 1Table, Data
Properties stream\x05SummaryInformation
ScriptingVBA macros stored in the CFB (Macros / VBA project)
EncryptionSupported (RC4 / CryptoAPI, document password)
Magic numberD0 CF 11 E0 A1 B1 1A E1
Related extensions.docx, .docm, .dot, .rtf, .odt
Specification URLlearn.microsoft.com/openspecs/office_file_formats/ms-doc
File signature (magic bytes)
D0 CF 11 E0 A1 B1 1A E1

Offset 0, 8 bytes. This is the OLE2 / Compound File Binary header, shared by all legacy Office binaries (.doc, .xls, .ppt) and other OLE structured-storage files. It does not identify Word by itself: the application is recognised from the named streams inside, chiefly the WordDocument stream. This differs from DOCX, which is a ZIP archive and starts with 50 4B 03 04 (“PK”).

What is a DOC file?

A .doc file is a Microsoft Word document in Word’s legacy binary format. The extension goes back to Word 1.0 in 1983, but the layout that almost every surviving .doc file uses was introduced with Word 97 in 1997 and remained the default through Word 2003. With Office 2007 Microsoft switched the default to the ZIP-and-XML DOCX, so plain .doc is now a legacy format. Microsoft later published the once-secret internals as the open specification [MS-DOC].

Unlike a text or XML document, a .doc is not human-readable in an editor. It is a small file system packed inside a single file: an OLE2 Compound File Binary holding named streams, with the running text in one stream and the formatting described by tables in others. The sections below walk through that container, the header that anchors the document, and the piece table that reassembles the text.

The OLE2 Compound File Binary container

Every .doc begins with the 8-byte signature D0 CF 11 E0 A1 B1 1A E1 at offset 0. This is the header of the Compound File Binary format (CFB, also called OLE2 structured storage), documented as [MS-CFB]. The same header fronts legacy .xls and .ppt files and many other OLE objects, so the signature alone does not say “Word”; the application is identified by which streams the container holds.

A CFB file is a container that emulates a file system. Internally it is divided into fixed-size sectors (512 bytes when the major version is 3, 4096 bytes for version 4). A file-allocation-table structure (the FAT and mini-FAT) chains sectors together into streams, which are the equivalent of files, and streams are organised under storages, the equivalent of directories. A directory, held as a red-black tree of entries, names each stream and storage. Streams shorter than 4096 bytes are packed into a separate mini-stream to avoid wasting whole sectors. All multi-byte integers in the format are little-endian.

example.doc  (Compound File Binary)
 ├─ WordDocument          main stream: text + FIB
 ├─ 1Table  (or 0Table)   formatting tables, piece table, style/list data
 ├─ Data                  embedded objects, pictures, form/field data
 ├─ \x05SummaryInformation      title, author, dates (property set)
 ├─ \x05DocumentSummaryInformation   further document properties
 └─ Macros / VBA          optional VBA project (present only if macros exist)

The names beginning \x05 use control character 0x05 as the first byte, a convention that marks standard property-set streams. A reader opens the container, finds the directory, and reads the streams it needs by name.

The WordDocument stream and the FIB

The WordDocument stream is the anchor of the whole document. It begins at its offset 0 with the File Information Block (FIB), a large, versioned header structure that is the map to everything else. The FIB opens with a fixed base: a 16-bit magic value wIdent (0xA5EC for Word), a version field nFib, and a set of flag bits in a field named fibBase. Two of those flags matter immediately for parsing: fWhichTblStm selects whether the formatting tables live in the 0Table or the 1Table stream, and fEncrypted marks a password-protected document.

After the base, the FIB contains arrays of file pointers, the fcLcb pairs. Each pair is a file offset (fc, a byte position, historically called a “character position” pointer into the table stream) and a length (lcb). These pairs locate every structure the document uses: the piece table, the style sheet, paragraph and character formatting runs, the list tables, footnotes, headers, and so on. The FIB also records ccpText and its siblings, the counts of characters in the main text, footnotes, headers and other subdocuments, which together partition the text stream into regions.

The 0Table and 1Table streams

The bulk of a Word document’s formatting does not sit next to the text. It lives in one of two streams, 0Table or 1Table; a given file uses exactly one, chosen by the fWhichTblStm flag in the FIB. (Two names exist so that a fast save could write a fresh table stream without disturbing the old one.) The table stream holds the structures the FIB’s fcLcb pairs point into: the style sheet (STSH), the arrays of formatting properties for paragraphs and characters (the PLCF structures that map text ranges to property sets), the list-formatting tables, and, most importantly for reading the text at all, the piece table.

The piece table (CLX): reassembling the text

Here is the detail that surprises people who assume the text sits contiguously in the WordDocument stream. It usually does not. Word stored text in pieces so that editing could append new text and rewrite only a small index rather than the whole file, an optimisation called fast save. The index is the piece table, stored in a structure called the CLX inside the table stream and located by the FIB fields fcClx / lcbClx.

The CLX contains a PlcPcd: a plex (parallel-array structure) of character positions and, for each piece, a PCD descriptor. Each descriptor carries an fc that points into the WordDocument stream where that run of text physically begins. A single high bit in that fc encodes the character encoding of the piece: when the bit is set, the text is 8-bit code-page characters and the real offset is the value with the bit cleared and halved; when clear, the text is 16-bit Unicode (UTF-16). To recover the document’s text, a reader walks the piece table in logical order, and for each piece jumps to its physical offset in the WordDocument stream and reads the stated number of characters in the stated encoding. Concatenating the pieces yields the visible text; the character positions then index into the formatting plexes to apply styles.

Logical text  →  piece table (CLX / PlcPcd)  →  physical runs
 piece 0: chars 0..99     PCD.fc → WordDocument offset A  (Unicode)
 piece 1: chars 100..149  PCD.fc → WordDocument offset B  (8-bit cp1252)
 piece 2: chars 150.....  PCD.fc → WordDocument offset C  (Unicode)

This piece-based, index-driven storage is a large part of why third-party software historically struggled to render complex .doc files exactly: correct output depends on faithfully implementing the FIB, the piece table, the encoding bit, and every formatting plex it references.

DOC versus DOCX, structurally

The 2007 successor DOCX keeps almost nothing of this design. A DOCX is not a Compound File Binary; it is a plain ZIP archive (its first bytes are 50 4B 03 04, “PK”) containing a tree of XML parts under the Open Packaging Conventions, standardised as ECMA-376 and ISO/IEC 29500. The document text is human-readable XML in word/document.xml, formatting is XML elements rather than binary property plexes, and there is no piece table. That shift, from an opaque binary with an index-driven text store to an inspectable ZIP of XML, is why DOCX is easier for non-Microsoft software to read and write correctly. A related sibling, RTF, takes a different route again: it stores a Word-equivalent document as plain-text control words with no binary container at all.

Security: VBA macros, auto-execution and Protected View

The main security concern with .doc is not the text but executable code that the CFB container can carry. A document that contains macros stores a VBA project as its own storage inside the compound file, holding compiled and source VBA modules. Because the macro code rides in the same file as the document, a .doc is a classic malware carrier.

The attack mechanics turn on auto-execution. VBA defines event procedures that Word runs automatically when a document is opened: a Sub AutoOpen() in a standard module, or a Document_Open() handler in the ThisDocument class module, executes as soon as macros are enabled, with no further user action. Malicious documents pair this with social engineering, the familiar “enable content to view this document” banner, to get the victim to lift the macro block.

Modern Office defends against this in layers. A .doc arriving from email or the internet carries a mark-of-the-web and opens in Protected View: a sandboxed, read-only mode where macros do not run and editing is disabled until the user explicitly clicks to leave it. Even after that, macros from internet-sourced files are blocked by default and must be deliberately unblocked. The practical rule follows from the mechanics: do not enable editing or content on an unexpected .doc, because enabling content is precisely the step that lets AutoOpen/Document_Open fire. Opening the file in LibreOffice or Google Docs is generally safer, since their macro engines differ from Word’s VBA and do not run it.

Frequently asked questions

What is the real difference between DOC and DOCX?

DOC is an OLE2 Compound File Binary: named streams, a File Information Block, and text stored as pieces indexed by a piece table. DOCX is a ZIP archive of XML parts (ECMA-376 / ISO/IEC 29500), with the text as readable XML. DOCX is smaller, standardised and easier for third-party software to parse exactly; DOC is opaque binary.

Why can’t I just read the text out of a .doc with a text editor?

Because the text is not stored contiguously or in plain form. Runs of text are scattered through the WordDocument stream and reassembled in logical order by the piece table (CLX) in the table stream, with each piece flagged as either 8-bit code-page or 16-bit Unicode. Without walking that index you see fragments in mixed encodings surrounded by binary formatting data.

References