;
;       Title:  FSACCESS UTILITY
;
;       Description: modify FSFILTER drive map
;
;       Design/Implementation Notes:
;
;       Modification History:
;           6/3/91    created     Mark Rogalski
;
;   B001  9/11/91 CP20 PTR B726834 Mark Rogalski
;         Was testing wrong bit in checking for removable media.
;
;   B002  12/6/91 CP20 PTR AC01543 Mark Rogalski
;         Need to test for remote drive before checking if removable.
;
;   B003  1/18/93 R206 DEF 60491   Bill Madden
;         Replaced Int 66 calls with Int 2f.
;
;   B004  12/23/93 R206 DEF 74953  Doug Azzarito
;         Change how we look for FSFILTER - DBLSPACE can fool it
;


        .xlist
        .xcref
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include demmac.inc
include dossymc.inc
include devsym.inc
include demver.inc
include demdbcs.inc
include syscalls.inc
include error.inc
include exe.inc
        .cref
        .list

NAME    FSACCESS
TITLE   FILE SYSTEM ACCESS UTILITY

CpuMode  286           ; This machine has at least this CPU

VDDINTERFACE    equ     02fh    ; Int vector for VDD interface

ACCESS    SEGMENT DWORD PUBLIC 'CODE'

        assume cs:ACCESS,ds:ACCESS,es:ACCESS

; Global variables go here

header_string   db      'INT 21 Filter Program ver. 1.0'

;*** filter_in - determine if filter is present
;
;
;       ENTRY   pushed - address of drive_map variable
;
;       EXIT    SUCCESS: return address of drive map
;                        return 0 in AX
;               FAILURE: return 1 in AX
;
;       GLOBAL EFFECTS
;               None
;
;       METHOD
;               search memory for filter header.

public filter_in
filter_in proc far

;       int     3       ;mdr mdr
        push    bp
        mov     bp,sp
        SaveReg <si,di,ds,es>

; search for checkword on paragraph boundary

        xor     ax,ax                  ; segment to start looking
;@B004 loop0 used to come back to here
        xor     si,si                  ; zero out index
loop1:  mov     ds,ax
        cmp     ds:[si],0acceh         ; look for header checkword
        je      found
;@B004 move loop0 here
loop0:  inc     ax                     ; inc segment number
        cmp     ax,0h                  ; look until end of memory
        jnz     loop1

        jmp     ret1

found:  mov     si,2                   ; now check header string
        push    cs                     ; set up es:di with comparison string
        pop     es
        mov     di,offset ACCESS:header_string
        mov     cx,30
        repe cmpsb
        mov     si,0                   ; zap index - don't XOR, we need ZF @B004
        jne     loop0                  ; go back to search if not right string

        les     di,ss:[bp+6]           ; get address of drive map variable
        mov     es:[di+2],ax           ; store drive map address in it
        mov     word ptr es:[di],20h   ; offset of drive map in segment

        mov     ax,1                   ; success
ret1:   RestoreReg <es,ds,di,si>
        pop     bp
        ret     4

filter_in endp


;*** cur_drive - return number of current drive
;
;
;       ENTRY   none
;
;       EXIT    return drive number in AX (A=0,B=1..)
;
;       GLOBAL EFFECTS
;               None
;
;       METHOD
;               issue int 21h, func 19h
;

public cur_drive
cur_drive  proc far

        mov     ah,19h                 ; call current disk func
        int     21h                    ; result in AL
        xor     ah,ah                  ; 0 out high byte
        ret                            ; no parms, just return

cur_drive endp



;*** vdsk_release - release A: drive back to OS/2
;
;       ENTRY   none
;
;       EXIT    none
;
;       GLOBAL EFFECTS
;               None
;
;       METHOD
;               call VDSK API entry point, func 2h
;

public vdsk_release
vdsk_release proc far

        SaveReg <es,ds,di>                                              ;BC003
        push    cs
        pop     ds                     ; point DS:SI to VDD name
        lea     si,VDSK
        xor     di,di                                                   ;BN003 begin
        mov     es,di
        mov     ax,04011h
        int     VDDINTERFACE
        mov     ax,es
        or      ax,di                  ; did we get the entry point?
        jz      short vdr_exit         ; no, exit

        mov     word ptr cs:[pfnVDSK],di
        mov     word ptr cs:[pfnVDSK+2],es

        mov     ah,2h                  ; call release disk func
        call    cs:[pfnVDSK]           ; go check
;BD003  int     66h
vdr_exit:                                                               ;BN003 end
        RestoreReg <di,ds,es>                                           ;BC003
        ret                            ; no parms, just return

 VDSK    db 'VDSK',0
 pfnVDSK dd 0

vdsk_release endp


;*** lock_drive_req - lock diskette drive
;
;       ENTRY   pushed word = request - 0 to lock drive, 1 to unlock.
;               pushed word = drive # (1=A:,2=B:...)
;
;       EXIT    return rc in ax
;
;       ERROR EXIT - fff1h if drive is not removable, else other error
;
;       GLOBAL EFFECTS
;               None
;
;       METHOD  issue int 21h, func 4409h to determine if drive is local or remote
;               issue int 21h, func 4408h to determine if drive is removable
;               issue int 21h, func 6ch to open drive and then
;               issue int 21h, func 440ch to lock it
;

public lock_drive_req
lock_drive_req proc far

        push    bp
        mov     bp,sp
        SaveReg <bx,cx,dx,ds,si,es,di>

        mov     bx,ss:[bp+6]           ; get drive number from stack
        mov     ax,4409h               ; determine if remote drive      BN002
        int     21h                                                    ;BN002
        jc      not_remv               ; return "not removable" if err  BN002
        test    ax,1000h               ; remote? look at bit 12         BN002
        jnz     not_remv               ; yes? then return               BN002

        mov     ax,4408h               ; determine if removable media
        int     21h
        jc      not_remv               ; return if error                BC002
        test    al,01h                 ; removable ? look at bit 0      BC001
        jnz     not_remv               ; no? then return

        mov     ax,6c00h               ; open diskette as file
        push    cs                     ; drive spec
        pop     ds
        mov     si,offset filespec
        add     bx,'A'-1               ; BX contains drive num, make letter
        mov     ds:[si],bl             ; store letter in drive spec
        mov     bx,80c2h               ; open mode
        mov     cx,0                   ; open attribs
        mov     dx,1                   ; open flag
        int     21h
        jc      r_err

        mov     bx,ax                  ; put handle in BX for next function
        mov     cx,ss:[bp+8]           ; function number
        mov     ch,08h                 ; catagory
        xor     ax,ax                  ; zero out address of parms
        mov     ds,ax
        mov     dx,ax
        mov     es,ax
        mov     di,ax
        mov     ax,440ch               ; do generic IOCLT request
        int     21h
        jc      r_err
        mov     ax,0                   ; return a-ok
        jmp     short r_err            ; go back to C code            ;BN002

not_remv:                                                             ;BN002
        mov     ax,0fff1h              ; return not removable code    ;BN002

r_err:
        RestoreReg <di,es,si,ds,dx,cx,bx>
        pop     bp
        ret     4                      ; clear 2 parms off stack

lock_drive_req endp

filespec db 'A:',0

ACCESS  ends

        end
