MS-DOS 6.22 File Locking in Multitasking Environments

MS-DOS 6.22 was architected as a single-user, single-tasking operating system, yet it supported concurrent access demands introduced by local area networks and multitasking managers like DESQview and Microsoft Windows. Because the core DOS kernel (specifically the DOS-BIOS and DOS kernel routines exposed via Interrupt 21h) was fundamentally non-reentrant, it relied on an external background utility called SHARE.EXE along with standard access and sharing modes to manage file integrity, enforce byte-range locking, and prevent data corruption when multiple processes accessed the file system simultaneously.

The Foundation: SHARE.EXE

By default, the MS-DOS 6.22 kernel provides minimal file contention protection. If two processes attempt to write to the same file, the second operation typically overwrites the first without warning. To enable file and record locking, users had to load SHARE.EXE via CONFIG.SYS (INSTALL=C:\DOS\SHARE.EXE) or AUTOEXEC.BAT.

SHARE.EXE operates as a Terminate-and-Stay-Resident (TSR) program that hooks the primary DOS API vector, INT 21h. It allocates memory to maintain internal tables tracking:

  • Every open file handle and its associated System File Table (SFT) entry.
  • File access rights and sharing modes specified during file creation or opening.
  • Byte-range locks (the starting offset and length of locked segments).

Configurable parameters allowed administrators to tune performance:

SHARE /F:filesize_allocation /L:number_of_locks

The /F switch allocated memory (in bytes) for file-sharing information, while /L designated the maximum number of simultaneous locks system-wide.

File Sharing Modes (Open Semantics)

When a process opens a file using INT 21h, Function 3Dh, it passes an access mode byte in the AL register. In DOS 6.22 with SHARE.EXE resident, bits 4–6 of this byte dictate the sharing behavior:

  • Compatibility Mode (000b): Designed for legacy applications unaware of multi-access environments. If an application opens a file in this mode, no other process can open the file unless it is also opened in Compatibility mode (and even then, behavior is constrained).
  • Deny Read/Write (Exclusive) (001b): Grants access to the calling program while denying all read or write access attempts by any other process.
  • Deny Write (010b): Allows other programs to open and read the file, but prevents any concurrent process from writing to it.
  • Deny Read (011b): Allows other programs to write, but denies them read access (rarely used).
  • Deny None (100b): Permits any other process to read from or write to the file concurrently, relying on record-level locking to avoid data collision.

If a second process requests access that conflicts with an active sharing mode, the DOS kernel rejects the call, returning an error code (such as Error 05h: Access Denied or Error 20h: Sharing Violation).

Byte-Range (Record) Locking: INT 21h, Function 5Ch

For programs sharing access under "Deny None" or "Deny Write," MS-DOS 6.22 provides fine-grained control through byte-range locking, implemented via INT 21h, Function 5Ch.

A program provides:

  • AH = 5Ch
  • AL = 00h (Lock region) or 01h (Unlock region)
  • BX = File handle
  • CX:DX = High and low words of the starting offset
  • SI:DI = High and low words of the length (number of bytes to lock)

Operational Rules of Byte-Range Locks:

  1. Exclusivity: Locks are non-overlapping and strictly exclusive. If Process A locks bytes 100 to 199, Process B cannot read or write within that boundary.
  2. Precision Matching: To unlock a region, the calling process must issue Function 5Ch with an offset and length that exactly match the parameters used to establish the lock. A program cannot partially unlock a previously locked range.
  3. Mandatory Cleanup: Applications must release all byte locks before closing the file handle. While MS-DOS 6.22 attempts to clean up stranded locks if a process terminates abnormally, failing to unlock regions explicitly prior to closing can lead to orphaned lock table entries.
  4. No Lock Upgrades/Downgrades: Locks cannot be shared or converted. Any region is either locked by one process or entirely unlocked.

Multitasking Contexts and Limitations

In true preemptive or cooperative multitasking environments running atop DOS 6.22—such as Microsoft Windows 3.1x or Quarterdeck DESQview—the single-threaded architecture of the underlying DOS kernel posed performance bottlenecks:

  • Serialization and Reentrancy: The DOS kernel uses internal static data structures. Even when locks are managed properly, multitasking environments rely on mechanisms like the InDOS flag (monitored via INT 21h, Function 34h) to avoid entering the kernel while an existing DOS operation is in progress. File I/O operations are strictly serialized.
  • Transition to 32-Bit File Access: In Windows for Workgroups 3.11, the reliance on the 16-bit SHARE.EXE was superseded by VSHARE.386, a 32-bit protected-mode virtual device driver. VSHARE.386 virtualized the INT 21h/Function 5Ch calls and file sharing checks within 386 Enhanced Mode, removing the real-mode memory overhead of SHARE.EXE and improving throughput across concurrent Windows virtual machines (VMs).
  • Lock Contention and Timeouts: When a collision occurs, DOS invokes the Critical Error Handler (INT 24h), traditionally resulting in the familiar "Abort, Retry, Fail?" prompt unless trapped programmatically. Multitasking-aware software typically catches sharing violations, waits briefly, and retries the operation automatically rather than allowing an unhandled critical error to freeze the active task.