Skip to content
FreeDOSDeep Dive Published Updated 6 min readViews unavailable

FreeDOS SHARE: File Sharing Modes and Byte-Range Locks in Real Mode

How FreeDOS SHARE implements DOS open-sharing rules, tracks byte-range locks by process, reports conflicts, and fits into a practical compatibility test.

DOS applications that update a common database cannot safely rely on good timing. They need the operating environment to enforce whether another process may open the same file and which byte ranges it may change. FreeDOS supplies that compatibility layer with SHARE, a resident program that implements DOS file-sharing and locking behavior for local hard-disk files.

The old name can be misleading. Loading SHARE does not turn a PC into a modern network file server and it does not make an application transactional. It gives cooperating DOS programs the sharing semantics exposed through the DOS API: open modes can conflict, and a process can reserve ranges of a file against access by another process.

Open mode and share mode are separate decisions

An extended DOS open request describes how the caller wants to access a file and what it permits other callers to do. Read-only, write-only, and read/write access are distinct from share modes such as deny read, deny write, deny all, or deny none. SHARE records the active opens and rejects a new combination that violates an existing declaration.

This is more precise than marking a whole file as “busy.” A reporting process may read a file while another reader has it open, yet be rejected if the accounting program opened it with deny-read. A writer may coexist with readers only if every relevant mode allows that combination. Applications written for multiuser DOS software often depend on these exact conflicts to prevent two stations from rewriting the same logical record.

The FreeDOS source tracks opens by Program Segment Prefix, or PSP. The PSP identifies the process context in traditional DOS. That association lets SHARE release state when a process closes a handle or terminates through the normal DOS path.

Byte-range locks protect only selected regions

DOS locking calls specify an offset and a length. SHARE records those intervals and rejects overlapping operations from another process. A database can therefore lock one record while other work continues elsewhere in the file.

Range arithmetic needs care. Applications must agree on record boundaries and avoid overflow when computing an end offset. A zero-length or boundary-adjacent request may behave differently across software that makes undocumented assumptions. The right compatibility test uses the real application and realistic files, not only a synthetic open-close program.

Locks are advisory in the sense that they work through DOS services. Software that bypasses DOS and writes sectors directly can ignore them and corrupt data. A forced reset also skips orderly cleanup. SHARE is one layer in a design that still needs correct application behavior, stable storage, and recoverable backups.

Load and inspect SHARE deliberately

The FreeDOS implementation documents this command shape:

SHARE [/F:space] [/L:locks] [/U] [/S] [/O] [/D] [/E]

/F selects space for file-sharing information and /L configures lock capacity. /S reports status and table sizes. /U requests uninstall, while /D and /E disable or enable the installed service. /O tells the command to act only when SHARE is already resident, which is useful in conditional startup scripts.

Do not maximize the tables reflexively on a conventional-memory-constrained machine. Resident bookkeeping occupies memory that applications may need. Instead, measure the highest concurrent open and lock counts in a representative workload, leave operating margin, and confirm the status after boot.

@ECHO OFF
SHARE /F:4096 /L:100
SHARE /S

Those numbers are an example, not a universal recommendation. A single-user game machine and a multi-station business application have different requirements. If the application documents required SHARE switches, treat that manual as part of its data-integrity specification.

Conflicts have distinct DOS errors

SHARE returns standard extended error conditions rather than a generic failure. The implementation identifies sharing violation 0x20, lock violation 0x21, and sharing-buffer overflow 0x24. A well-behaved application distinguishes them.

A sharing violation means the requested open mode conflicts with an existing open. A lock violation means the requested file operation intersects a locked range. A buffer-overflow error means SHARE cannot record more state with its current allocation. Retrying the last case forever cannot create capacity; configuration or workload must change.

User interfaces often collapse these into “access denied” or “file in use.” During diagnosis, capture the exact extended DOS error and the sequence of opens and locks. That evidence separates a legitimate collision from an undersized SHARE table or a program that failed to release a handle.

Residency depends on DOS multiplex services

FreeDOS SHARE installs as a resident component and participates in DOS multiplex conventions. Its source uses interrupt 2Fh and AMIS-style discovery so a later invocation can find and control the resident instance. This explains why repeatedly launching SHARE is not equivalent to creating independent services.

Uninstall succeeds only when it is safe for the resident component to detach. Other resident software, interrupt-vector changes, or active state can prevent removal. For production startup, load SHARE once in a controlled order and leave it active for the session instead of toggling it around individual applications.

The project describes its implementation as compatible with the FreeDOS kernel. That qualification matters when assembling a mixed historical environment. A binary intended for one DOS kernel may rely on internal behavior another kernel does not expose. Match the SHARE build to the FreeDOS release and test after kernel or memory-manager changes.

Build a two-process compatibility test

The strongest test uses two independent processes against a disposable copy of real data:

  1. Process A opens the file with the application’s normal access and share flags.
  2. Process B attempts each allowed and prohibited open combination.
  3. Process A locks a known byte interval.
  4. Process B reads and writes outside that interval, then attempts an overlapping operation.
  5. Both programs close normally, and the same opens are attempted again.
  6. The test is repeated until configured table limits are approached.

Record which operation fails and which extended error it returns. Then repeat after loading the actual network redirector, cache, and memory manager used on the machine. DOS compatibility problems often arise from interactions between resident components, not from one component in isolation.

Finally, test an abnormal termination on disposable data. Verify whether the kernel and SHARE release process-associated state and whether the application can repair its own journal or indexes. Do not use a reset as a normal unlock procedure: even if resident locks disappear, partially written application structures remain.

SHARE is effective when applications ask DOS for honest sharing modes, respect byte-range locks, and handle violations explicitly. It cannot rescue software that writes around the API or treats every error as permission to overwrite. The goal is not merely to see SHARE in memory, but to prove that conflicting work is rejected before shared data is damaged.

Related:

Sources:

Comments