Search code examples
winapidosboxwindows-3.1

In Windows 3.1 WinAPI How To Lock A File?


I was trying to run Visual Basic 4 (16-bit) in Windows 3.1 running within DosBox. However it failed to launch with error:

SHARE.exe must be installed in order to run Visual Basic

Some old MS-DOS applications just check for existence of the EXE and it's presence in autoexec.bat, but in this case the EXE exists, but the error still occurs.

Running on Windows 7 32-bit and using a debugger attached to NTVDM.exe I found the following process is used:

  1. A Temp file is created with GetTempFilename
  2. Call to LockFile API
  3. Call to UnlockFile API

When I set a breakpoint at return of LockFile API and faked a faliure (returned false) On Windows 7 I got the same error message "SHARE.exe must be installed in order to run Visual Basic"

However within the VB.exe I can't find any reference to LOCKFILE API, so I suspect NTVDM.exe is translating it somehow.

The APIs that seem potentially related in the import table of VB.exe are:

  • Kernel!OPENFILE
  • Kernel!_LWRITE
  • Kernel!_LREAD
  • Kernel!_LOPEN
  • Kernel!_LLSEEK
  • Kernel!_LCREAT
  • Kernel!_LCLOSE
  • OLE2!OLELOCKRUNNING
  • Kernel!LOCKRESOURCE
  • Kernel!LOCKSEGMENT

I am trying to work out how the lock / unlock file test is done so I can try to remediate within DosBox and create my own test program to replicate in C or VB.


Solution

  • SHARE.exe must be installed in order to run Visual Basic

    SHARE.EXE works as Terminate and Stay Resident kind of program. So it existence is not enough. It must be run, to hook into system and intercept some requests.

    SHARE.EXE intercepts DOS Interupt (0x21) and DOS Multiplex Interrupt (0x2F).

    In 0x21 interrupt code 0x5c handles locking and unlocking files


    http://www.techhelpmanual.com/530-dos_fn_5c00h__lock_file_access.html

    LockFile 5c00h
    Expects:
    AX 5c00H
    BX file handle
    CX:DX file offset from start of file (CX * 65536)+DX
    SI:DI length in bytes of region to lock (SI * 65536)+DI
    Returns: AX error code if CF is set to CY

    This function locks access to a region of the file identified by the file handle in BX. The region of the file that begins at file logical offset CX:DX extending for a length of SI:DI is locked ...

    http://www.techhelpmanual.com/531-dos_fn_5c01h__unlock_file_access.html

    UnlockFile 5c01h
    Expects:
    AX 5c01H
    BX file handle
    CX:DX file offset from start of file (CX * 65536)+DX
    SI:DI length in bytes of region to lock (SI * 65536)+DI
    Returns: AX error code if CF is set to CY

    This function unlocks access to a region of the file which was previously locked...


    You could also check 5dh functions marked mostly as internal.

    Implementation in Free DOS:

    https://sourceforge.net/p/freedos/svn/HEAD/tree/kernel/trunk/kernel/dosfns.c
    see DosLockUnlock function
    https://sourceforge.net/p/freedos/svn/HEAD/tree/kernel/trunk/share/share.c

    Looking at vDos source code could help if you plan to bring this funcionality to Dos Box

    https://sourceforge.net/projects/vdos/files/Version%202015.04.10/


    However within the VB.exe I can't find any reference to LOCKFILE API

    I'm not sure if LockFile existed in Win16 (probably not), but there is possibility that sharing API is called directly through DOS interrupts.

    I suspect NTVDM.exe is translating it somehow

    I don't know it for sure, but I would assume that it intercepts DOS interrupts and uses Win32 API calls to simulate needed behavior.

    I am trying to work out how the lock / unlock file test is done so I can try to remediate within DosBox and create my own test program to replicate in C or VB

    I would try to log INT 21h and INT 2Fh calls in DOS Box.