[Back to DOS SWAG index] [Back to Main SWAG index] [Original]

    (*
    From: HELGE HELGESEN
    Subj: SHARE.EXE
    ---------------------------------------------------------------------------
    -> Can I lock the files after the RESET and unlock before / after
    -> the close?

    Yes. This is one advantage of network files. All users running
    your program will open the files simultaneously, and when a
    process wants to write to a record, it simply locks it. No other
    processes can then read or write to the record, though they can
    read/write all other records.

    (I assume you're NOT using text files!)

    -> I'd like to add a thing that checks if the file is locked
    -> before the reset.

    If a record is locked, then the process still can open the file.

    -> Does the "lock" occur on the open or the read of the file?

    What do you mean? You can open a file in numerous ways. If you
    open it for shDenyN, then locking is done on record(byte) basis.
    If you open it for exclusive(FileMode=2) access or shDenyRW (no
    other can access the file) then locking is done on file basis.

    Here's a short unit with file locking support. It's written for
    Turbo Pascal (or Borland Pascal) 7.0, but it should work with
    TP60 without many modifications.
    SHARE.PAS --->
    *)

    Unit Share;
    {
      Utility to allow file sharing on a network
      (c) 1993 Helge Olav Helgesen
    }

    interface

    uses
      dos;

    function shShareInstalled: boolean; { check if SHARE is installed }
    function LockByte(var thefile; FirstByte, NoBytes: longint): byte;
    function UnLockByte(var thefile; FirstByte, NoBytes: longint): byte;
    function Lock(var thefile; FirstRec, NoRecs: word): byte;
    function UnLock(var thefile; FirstRec, NoRecs: word): byte;

    const
    {
      Here's a list of file file modes you can open a file with. To allow
      multiple access to one file, it should either be marked R/O, or opened
      with shDenyN-mode. To open a file with a spesified mode, do:

      FileMode:=shDenyN+shAccessRW; (Add the flags)
    }
      shDenyR    = $30; { Deny Read to other Processes }
      shDenyW    = $20; { Deny Write to other Processes }
      shDenyRW   = $10; { Deny access to other Processes }
      shDenyN    = $40; { Deny none - full access to other Processes }
      shAccessR  = $0;  { open for Read access }
      shAccessW  = $1;  { open for Write Access }
      shAccessRW = $2;  { open for both read and write }
      shPrivate  = $80; { private mode - don't know what this is... }

    implementation { the private part }

    function shShareInstalled; assembler;
    {
      Returns TRUE if Share is installed on the local machine!
    }
    asm
      mov ax,$1000 { check if SHARE is installed }
      int $2f { call multiplex interrupt }
    end; { shShareInstalled }

    function LockByte; assembler;
    {
      Locks a region of bytes in the specified file.
    }
    asm
      mov ax, $5c00
      les bx, thefile
      mov bx, es:[bx].FileRec.Handle
      les dx, FirstByte
      mov cx, es
      les di, NoBytes
      mov si, es
      int $21
      jc @1
      xor al, al
    @1:
    end;

    function Lock; assembler;
    {
      Lock records.
    }
    asm
      les bx, thefile
      mov cx, es:[bx].FileRec.RecSize
      mov ax, FirstRec
      mul cx
      push ax
      push dx
      mov ax, NoRecs
      mul cx
      mov si, dx
      mov di, ax
      pop cx
      pop dx
      mov ax, $5c00
      mov bx, es:[bx].FileRec.Handle
      int $21
      jc @1
      xor al, al
    @1:
    end;

    function UnLockByte; assembler;
    asm
      mov ax, $5c01
      les bx, thefile
      mov bx, es:[bx].FileRec.Handle
      les dx, FirstByte
      mov cx, es
      les di, NoBytes
      mov si, es
      int $21
      jc @1
      xor al, al
    @1:
    end;

    function UnLock; assembler;
    asm
      les bx, thefile
      mov cx, es:[bx].FileRec.RecSize
      mov ax, FirstRec
      mul cx
      push ax
      push dx
      mov ax, NoRecs
      mul cx
      mov si, dx
      mov di, ax
      pop cx
      pop dx
      mov ax, $5c01
      mov bx, es:[bx].FileRec.Handle
      int $21
      jc @1
      xor al, al
    @1:
    end;

    end.

    They're used this way:
    Lock(MyFile, FirstByteToLock, NoBytesToLock);
    LockByte(MyFile, FirstRecToLock, NoRecsToLock);

    Since you're working with records, you probably want to use Lock.
    When you want to update a record, this might be the code:

    Lock(MyFile, Rec, 1);
    Write(MyFile, MyRec);
    UnLock(MyFile, Rec, 1);

    You will of course have to make code to check if the lock failed
    (any result but 0), you can't write to the record. Always unlock
    the record as soon you're done!

    The last ones are UnLock and UnLockByte. They're used the same
    way as Lock and LockByte.

    And a last note! You can't open a file in a mode that conflicts
    with the access other processes have to a file.

    Eg.

    if you first open a file with mode shDenyN+shAccessRW, and then
    try to open the file again (without closing the first one) with
    the mode shDenyRW+shAccessRW, the reset will fail.

    I'll see if I can make a short program to illustrate how this
    works...

    Hope this helps a litte,

    ... Helge

[Back to DOS SWAG index] [Back to Main SWAG index] [Original]