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 = 5ChAL = 00h(Lock region) or01h(Unlock region)BX =File handleCX:DX =High and low words of the starting offsetSI:DI =High and low words of the length (number of bytes to lock)
Operational Rules of Byte-Range Locks:
- 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.
- 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.
- 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.
- 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.EXEwas superseded byVSHARE.386, a 32-bit protected-mode virtual device driver.VSHARE.386virtualized the INT 21h/Function 5Ch calls and file sharing checks within 386 Enhanced Mode, removing the real-mode memory overhead ofSHARE.EXEand 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.