;       SCCSID = @(#)dempath.asm        6.1 91/07/12
;       SCCSID = @(#)dempath.asm        6.1 90/11/17
;       SCCSID = @(#)dempath.asm        13.8 90/07/09
TITLE   PATH - Directory related system calls
NAME    DEMPATH

;
; Directory related system calls.  These will be passed direct text of the
; pathname from the user.  They will need to be passed through the macro
; expander prior to being sent through the low-level stuff.  I/O specs are
; defined in DISPATCH.  The system calls are:
;
;   $CURRENT_DIR  Written
;   $RMDIR        Written
;   $CHDIR        Written
;   $MKDIR        Written
;   $Unlink
;   $Rename
;   $GSetMediaID
;   $EnumAttrib
;   $QMaxEASize
;
;
;   Modification history:
;
;       Created: ARR 4 April 1983
;                MZ 10 May 1983     CurrentDir implemented
;                MZ 11 May 1983     RmDir, ChDir, MkDir implemented
;                EE 19 Oct 1983     RmDir no longer allows you to delete a
;                                   current directory.
;                MZ 19 Jan 1983     Brain damaged applications rely on success
;                                   values of AL.
;                DAN 17-Feb-1989    Modified for MVDM
;                Nagara 14-Sep-89   Added $EnumAttrib,$QMaxEASize
; BD005 - 5/13/92  defect 24729  Mark Rogalski                         ;BD005;
;         Remove unneeded code for handling RM devices.                ;BD005;
;**********************************************************************;
; 59625 - 1/29/93  Catherine Bundy                                     ;59625;
;         Changed $UnLink to store the environment from the CurrentPDB ;59625;
;**********************************************************************;
; 63221 - 03/10/93 Lisa M. Primm                                       ;63221;
;         Moved 59625 code so it doesn't interfere with VMCheck_fname  ;63221;
;**********************************************************************;
; 73751 - 09/13/93 ChangeTeam                                          ;73751;
;         Added check for Win running to UNLINK - needed because Win   ;73751;
;           converts the addr of the env vars from segm to slctr so    ;73751;
;           demDelete needs to know if this conversion has occured     ;73751;
;**********************************************************************;75462;
; 75462 - 12/17/93 Changeteam defect.  B.Clare                         ;75462;
;         Added support for wildcard deletes to $Unlink, when called   ;75462;
;         from DOS Server Call (function 5D00h). Added function        ;75462;
;         SrvCallHandler, to allow wildcard operations for $unlink.    ;75462;
;         SrvCallHandler function requires minor modifications to      ;75462;
;         allow Server Call wildcard support for other DOS functions.  ;75462;
;**********************************************************************;
;
.xlist
;
; get the appropriate segment definitions
;
include v86seg.inc
.xcref
include basemaca.inc
include osmaca.inc
include oldmaca.inc
include argframe.inc
include demmac.inc
include inbuf.inc
include mvdmexp.inc
include demsvc.inc
include error.inc
include pdb.inc   ;59625;
.cref
.list
;       CpuMode 8086                                                 ;75462
.186                ; Allow extended realmode instructions.  Not     ;75462
                    ; supported by CpuMode macro.                    ;75462

        ReferV86    ExtErr_Locus,BYTE
        ReferV86    os2_handled,BYTE          ;mdr
        ReferV86    CurrentPDB,WORD           ;59625;
        ReferV86    User_In_AX,WORD        ; initial input user AX   ;75462;BClare
        ReferV86    SrvCallEntFLG,BYTE                               ;75462;BClare
        ReferV86    DMAADD,DWORD                                     ;75462;BClare

V86CODE    SEGMENT
        ASSUME  SS:NOTHING,CS:V86GROUP

        EXTRN   ECritDisk:NEAR
        EXTRN   LCritDisk:NEAR
        EXTRN   Sys_Return:NEAR
        EXTRN   Sys_Ret_OK:NEAR
        EXTRN   Sys_Ret_Err:NEAR
        EXTRN   RMDevCheckName:NEAR
;BD005        EXTRN   RMDevCheck:NEAR
        EXTRN   VSFNFromHandle:NEAR
        EXTRN   VMcheck_fname:NEAR                ; mdr
        EXTRN   VMcheck_drive:NEAR                ; mdr
        EXTRN   VMcheck_ioctl:NEAR                ; mdr
        EXTRN   VMcheck_handle:NEAR               ; mdr
        EXTRN   $Set_DMA:NEAR                                           ;75462;
        EXTRN   $Find_First:NEAR                                        ;75462;
        EXTRN   $Find_Next:NEAR                                         ;75462;
        EXTRN   $NameTrans:NEAR                                         ;75462;
                                                                        ;75462;
sTempPath       DB      128 dup (?)     ;Filespec to be deleted. This   ;75462
                                        ;is local to SrvCallHandler, but;75462
                                        ;it would eat stack space if    ;75462
                                        ;declared as LocalVar there.    ;75462
                                                                        ;75462;
SaveWINOS2Check DW      0               ;Saves ret val from INT 2F,160Ah;75462
                                        ;used in $Unlink and            ;75462
                                        ;SrvCallHandler                 ;75462

BREAK <$CURRENT_DIR - dump the current directory into user space>
;
;   Assembler usage:
;               LDS     SI,area
;               MOV     DL,drive
;               INT     21h
;           ; DS:SI is a pointer to 64 byte area that contains drive
;           ; current directory.
;   Error returns:
;           AX = error_invalid_drive
;

        procedure $CURRENT_DIR,NEAR
        call        VMcheck_drive       ; mdr return if dos drive
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
        EnterCrit   critDisk
        SVC     SVC_DEMQUERYCURRENTDIR  ; Call OS2 to do this for us
        LeaveCrit   critDisk

Entry   PathRet,near,local              ; All routines below exit through here
        jmp     Sys_Return
EndProc $Current_Dir


BREAK <$RmDir -- Remove a directory>

; Inputs:
;       DS:DX Points to asciz name
; Function:
;       Delete directory if empty
; Returns:
;       STD XENIX Return
;       AX = error_path_not_found If path bad
;       AX = error_access_denied If
;               Directory not empty
;               Path not directory
;               Root directory specified
;               Directory malformed (. and .. not first two entries)
;               User tries to delete a current directory
;       AX = error_current_directory

        procedure $RMDIR,NEAR
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

        call    VMcheck_fname           ; mdr  return if dos drive
;m        call    RMDevCheckName
;m        jnc     PathError               ; Error if a device is specified
        SVC     SVC_DEMDELETEDIR        ; Call OS2 to delete the directory
        jmp     PathRet

EndProc $RMDIR


BREAK <$ChDir -- Change current directory on a drive>

;
; $ChDir - Top-level change directory system call.  This call is responsible
; for setting up the CDS for the specified drive appropriately.
;
; Inputs:
;       DS:DX Points to asciz name
; Returns:
;       STD XENIX Return
;       AX = chdir_path_not_found if error

        procedure $CHDIR,NEAR
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

        call    VMcheck_fname           ; mdr  return if dos drive
;m        call    RMDevCheckName
;m        jnc     PathError               ; Error if a device is specified
        SVC     SVC_DEMSETCURRENTDIR
        jmp     PathRet


Entry   PathError
        error   ERROR_PATH_NOT_FOUND
EndProc $CHDIR

BREAK <$MkDir - Make a directory entry>
; Inputs:
;       DS:DX Points to asciz name
; Function:
;       Make a new directory
; Returns:
;       STD XENIX Return
;       AX = mkdir_path_not_found if path bad
;       AX = mkdir_access_denied  If
;               Directory cannot be created
;               Node already exists
;               Device name given
;               Disk or directory(root) full

Procedure $MKDIR,NEAR
        ASSUME  CS:V86GROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING

        call    VMcheck_fname           ; mdr  return if dos drive
;m        call    RMDevCheckName
;m        jnc     PathError           ; Error if a device is specified
        xor     bx,bx
        xor     si,si               ; No EA list

mkd10:  SVC     SVC_DEMCREATEDIR
        jmp     PathRet

;       $MKDIR2 - same as $MKDIR but allows setting EA
;
;       ENTRY   ds:dx -> ASCIIZ path
;               es:di -> EA structure (di = -1 means no EA)
;
;       EXIT    same as above

Entry   $MKDIR2,NEAR

        call    VMcheck_fname           ; mdr  return if dos drive
        cmp     di,-1                   ; any EA to set?
        je      $MKDIR                  ; no, do normal $mkdir

;m        SaveReg <es,di>                 ; save EA pointer
;m        call    RMDevCheckName
;m        RestoreReg <bx,si>              ; bx:si -> EA
;m        jnc     PathError               ; Error if a device is specified
        jmp     short mkd10

EndProc $MKDIR


BREAK <$UNLINK - delete a file entry>
;
;   Assembler usage:
;           LDS     DX, name
;           IF VIA SERVER DOS CALL
;            MOV     CX,SEARCH_ATTRIB
;           MOV     AH, Unlink
;           INT     21h
;
;   Error returns:
;           AX = error_file_not_found
;              = error_access_denied
;
;   Expanded logic to handle Wildcard deletes from Server Call           ;75462;
;   (INT 21 function 5D00 h). Change Team (BClare) 12-04-93.             ;75462;
;   Pseudocode:                                                          ;75462;
;       Save Registers that INT 2Fh trashes.                             ;75462;
;       Run INT  2F to check if Windows is active                        ;75462;
;       If called from server function ( SrvCallEntFlg=TRUE )            ;75462;
;           push registers for use by SrvCallHandler                     ;75462;
;           call SrvCallHandler                                          ;75462;
;                                                                        ;75462;
;       ELSE                                                             ;75462;
;           Delete File                                                  ;75462;
;       ENDIF                                                            ;75462;
;       Cleanup Stack                                                    ;75462;
;       Exit                                                             ;75462;
;
Procedure $Unlink

        call    VMcheck_fname           ; mdr  return if dos drive
        push    es                                              ;63221;59625
        push    ds                      ;Save regs before INT 2f trashes ;75462
        push    cx                                                       ;75462
        push    dx                                                       ;75462
        mov     es,[CurrentPDB]                                 ;63221;59625
        mov     es,es:[PDB_environ]     ;es:=CurrentPDB[002Ch]  ;63221;59625
        mov     ax,160Ah                ;determine if win run'g ;73751
        int     2Fh                     ;  retn AX=0 if win     ;73751
        cmp     SrvCallEntFlg,FALSE                                      ;75462;
        jz      short Not_ServCall                                       ;75462;
; We have entered $unlink from SRV_CALL ( in srvcall.asm )               ;75462;
; copy path in DS:DX to sTempPath.  This allows us to perform            ;75462;
; FindFirst/FindNext searches without destroying original search string. ;75462;
        pop     dx                                                       ;75462;
        pop     cx                                                       ;75462;
        pop     ds                                                       ;75462;
        mov     CS:[SaveWINOS2Check], AX                                 ;75462;
        call    SrvCallHandler                                           ;75462;
        jmp     short Unlink_Exit                                        ;75462;
Not_ServCall:   SVC     SVC_DEMDELETE
                pop     dx                                               ;75462;
                pop     cx                                               ;75462;
                pop     ds                                               ;75462;
Unlink_Exit:    pop     es                                                    ;59625
                jmp     Sys_Return
EndProc   $Unlink


BREAK <$RENAME - move directory entries around>
;
;   Assembler usage:
;           LDS     DX, source
;           LES     DI, dest
;           IF VIA SERVER DOS CALL
;            MOV     CX,SEARCH_ATTRIB
;           MOV     AH, Rename
;           INT     21h
;
;   Error returns:
;           AX = error_file_not_found
;              = error_not_same_device
;              = error_access_denied

Procedure $Rename
        call    VMcheck_fname           ; mdr  return if dos drive
        SVC     SVC_DEMRENAME
        jmp     Sys_Return
EndProc   $Rename

;***    $GSetMediaID - Int 21 Get/Set Media ID                  @3xb12
;
;       This routine allows the caller to query or modify the
;       media ID information.
;
;       ENTRY      AL = 00h - Get Media ID
;                       01h - Set Media ID
;                  BH = Reserved (must be 00h)
;                       or infolevel if nonzero
;                  BL = Drive Number (0=Default,1=A,2=B, ...)
;                  CX = Buffer size (only if BH<>0)
;                  DS:DX -> Buffer
;
;       EXIT       'C' clear if no error
;                  'C' set if error,  AX has error code
;
;       USES       AX,CX,DX,DS,ES,SI,DI
;
;       CALLS      GSetMediaID

        ASSUME  DS:NOTHING, ES:NOTHING
Procedure $GSetMediaID
        call    VMcheck_ioctl          ; mdr return if dos drive
        SVC     SVC_DEMGSETMEDIAID
        jmp     Sys_Return
EndProc   $GsetMediaID

BREAK <$EnumAttrib  - enumerate ext.attribs for a specific file>
; int 21 function corresponding to DosEnumAttribute API.
;
;   Assembler usage:
;           LDS     SI,parameter_packet
;           XOR     AL,AL               ; reserved value in AL
;           MOV     AH,EnumAttrib
;           INT     21h
;
;   Error returns:
;           AX = error_invalid_handle
;              = error_invalid_level
;              = error_file_not_found
;              = error_path_not_found
;              = error_invalid_name
;              = error_buffer_overflow
;
; NOTE: for parameter packet definition, look at EnumEAStruc structure in
;       src\dos\dosinc\argframe.inc.
;
        ASSUME  DS:NOTHING, ES:NOTHING
Procedure $EnumAttrib
        cmp     word ptr [si].EEA_iRefType,ENUMEA_REFTYPE_PATH
        je      short enat20

;       Handle based call; convert the fake handle to SFN

;mdr        push    ds
        lds     bx,[si].EEA_pFileRef            ; ptr to handle
        mov     bx,[bx]                         ; get the fake handle
        call    VMcheck_handle         ; mdr convert handle or return
;mdr        call    VSFNFromHandle                  ; bx = SFN
;mdr        pop     ds                              ;
;mdr.386p
;mdr        jc      Sys_Ret_Err                     ; invalid handle
;mdrCpuMode reset

;       Check if DOS device handle

;mdr        call    RMDevCheck
;mdr        jnz     short enat30                    ; skip if an RM device

enat10: SVC     SVC_DEMENUMATTRIB
        jmp     Sys_Return

;       Path based call; check if DOS device

enat20: push    ds
        push    si
        lds     dx,[si].EEA_pFileRef
        call    RMDevCheckName
        pop     si
        pop     ds
        jz      short enat10
enat30: lds     si,[si].EEA_pEnumCnt            ; return no EAs for DOS devices
.386p
        mov     dword ptr ds:[si],0
CpuMode reset
        jmp     Sys_Ret_OK

EndProc   $EnumAttrib

BREAK <$QMaxEASize  - query file system for max ea size supported >
;
;   Assembler usage:
;           LDS     SI, buffer
;           LES     DI, path_name
;           XOR AL,AL           ; reserved value in AL
;           MOV     AH, QMaxEASize
;           INT     21h
;
;   Error returns:
;           AX = error_invalid_parameter
;              = error_invalid_function
;              = error_invalid_fsd_name
;              = error_buffer_overflow
;
;
        ASSUME  DS:NOTHING, ES:NOTHING
Procedure $QMaxEASize

        SVC     SVC_DEMQMAXEASIZE
        jmp     Sys_Return

EndProc   $QMaxEASize

subttl  SrvCallHandler                                                   ;75462;
page                                                                     ;75462;
;                                                                        ;75462;
;  SrvCallHandler  -- Handle wildcard file processing for $unlink and    ;75462;
;                     other functions that are called from Srv_Call      ;75462;
;                                                                        ;75462;
;       Inputs --  AX = function number                                  ;75462;
;                  CL = file attributes                                  ;75462;
;               DS:DX = pointer to path/filename                         ;75462;
;           sTempPath = local var. in Code segment.  Copy area for the   ;75462;
;                       path/filename                                    ;75462;
;           WinOS2Flg = local var. in Code segment.  Result of INT 2Fh   ;75462;
;                       function 160Ah. = 0 if WIN-OS2 is active.        ;75462;
;                                                                        ;75462;
;       Internal variables:                                              ;75462;
;        pFileNameOfs = Offset of filename portion of sTempPath          ;75462;
;             TempDTA = Local DTA for $Find_first, $Find_Next.           ;75462;
;          pOldDTAOfs = pointer to Offset of Entry DTA                   ;75462;
;          pOldDTASeg = pointer to Segment of Entry DTA                  ;75462;
;                                                                        ;75462;
;       Output    No error (CF = 0 )                                     ;75462;
;           copy wildcard file/path request to holding variable.         ;75462;
;           parse path & filename from overall string                    ;75462;
;           Set the DTA to local area and other setup for $Find_First    ;75462;
;           Do $Find_First call                                          ;75462;
;           If Successful                                                ;75462;
;               While success  ( carry=0 )                               ;75462;
;                   copy found filename into holding string              ;75462;
;                   setup to perform file delete                         ;75462;
;                   delete file                                          ;75462;
;                   If delete fails, exit with error                     ;75462;
;                   setup to do $Find_Next                               ;75462;
;                   Do $Find_Next Call                                   ;75462;
;               EndWhile                                                 ;75462;
;               If $Find_Next failed with No_more_files (AX=12h)         ;75462;
;                   Clear error                                          ;75462;
;               Endif                                                    ;75462;
;           Endif                                                        ;75462;
;                                                                        ;75462;
Procedure SrvCallHandler                                                 ;75462;
        LocalVar        pFileNameOfs,WORD     ;Offset of filename portion;75462;
                                              ;of sTempPath              ;75462;
        LocalVar        TempDTA,43            ;Local DTA for $Find_First ;75462;
        LocalVar        pOldDTAOfs, WORD      ;Hold addr of orig. DTA    ;75462;
        LocalVar        pOldDTASeg, WORD      ;                          ;75462
                EnterProc                                                ;75462;
                push    ds                                               ;75462;
                push    cx                                               ;75462;
                mov     si,dx           ;Setup offset of source string   ;75462;
                mov     SrvCallEntFlg, FALSE                             ;75462;
                push    cs              ;setup destination string        ;75462;
                pop     es              ;need to ensure es==cs (dest.)   ;75462;
                lea     di, sTempPath                                    ;75462;
                                                                         ;75462;
                push    ax                                               ;75462;
                push    bx                                               ;75462;
                push    bp                                               ;75462;
                                                                         ;75462;
; Canonicalize path/filename.  Input is supposed to be canonicalized     ;75462;
; already, but this validates it.                                        ;75462;
; Change current value of User_In_AX (should be 41h) to allow $NameTrans ;75462;
; to handle errors correctly. 60h is value of NameTrans  DOS function.   ;75462;
                push    WORD PTR [User_In_AX]                            ;75462;
                mov     BYTE PTR [User_In_AX +1], 60h                    ;75462;
                call    $NameTrans                                       ;75462;
                pop     WORD PTR [User_In_AX]                            ;75462;
                pop     bp                                               ;75462;
                pop     bx                                               ;75462;
                pop     ax                                               ;75462;
                jnc     GetEndString    ;Stupid 8086 CPU mode            ;75462;
                                        ;requires jump around a jump!    ;75462;
                jmp     SCHandler_Exit  ;di now points to the beginning  ;75462;
                                        ;of the filespec. Now look for   ;75462;
                                        ;the end.                        ;75462;
GetEndString:   cld                                                      ;75462;
                mov     cx,(SIZE sTempPath) ;Buffer size                 ;75462;
                mov     al,0            ;search for end of string        ;75462;
                repne   scasb                                            ;75462;
                jz      CopyDone                                         ;75462;
                jmp     SCHandler_Err   ;buffer overflow: ERROR          ;75462;
                                        ;di now points to end of filespec;75462;
CopyDone:       std                     ;prepare to scan DOWNward        ;75462;
                lea     si,sTempPath    ;SI=start of path                ;75462;
                mov     al, '\'                                          ;75462;
                mov     cx, di                                           ;75462;
                sub     cx, si                                           ;75462;
                dec     di              ;DI now points at \0 byte        ;75462;
;Since our filespec is in canonical form, we are guaranteed to have a '\';75462;
;character in it.                                                          ;75462;
                                                                           ;75462;
ScanPath:         repne   scasb           ;Scan for '\'                    ;75462;
                  jz      EndPath                                          ;75462;
                  jmp     SCHandler_Err   ;didn't find one: ERROR          ;75462;
                                                                         ;75462;
EndPath:        inc     di              ;after increments:               ;75462;
                inc     di              ;di = first char in filename     ;75462;
                                        ;si = first char in path         ;75462;
                mov     pFileNameOfs,di ;save pointer to filename        ;75462;
SaveOldDTA:     mov     es, WORD PTR [DMAADD + 2]  ;Get current DTA      ;75462;
                mov     bx, WORD PTR [DMAADD]                            ;75462;
                mov     pOldDTASeg, es                                   ;75462;
                mov     pOldDTAOfs, bx                                   ;75462;
SetNewDTA:      push    cs                                               ;75462;
                pop     ds                                               ;75462;
                lea     dx, TempDTA                                      ;75462;
;    The fsfilter.sys version of $Set_DMA calls the original DOS int     ;75462;
;    21h handler.  For this to work, AX must have the correct function # ;75462;
                push    ax                                               ;75462;
                mov     ax, 1A00h       ;                                ;75462;
                call    $Set_DMA        ;new DTA=cs:TempDTA=DS:DX        ;75462;
                pop     ax                                                 ;75462;
;Ready to do findfirst ( more or less )                                    ;75462;
;Current es=cs=ds                                                          ;75462;
                pop     cx              ;restore original CX=file        ;75462;
                                        ;attribs.                        ;75462;
                push    cx              ;re-save file attribs            ;75462;
                lea     dx, sTempPath   ;DS:DX=canonical path string     ;75462;
; Change current value of User_In_AX (should be 41h) to allow $Find_First;75462;
; to handle errors correctly. 4Eh is value of Find_First DOS function.   ;75462;
                push    WORD PTR [User_In_AX]                            ;75462;
                mov     BYTE PTR [User_In_AX +1], 4Eh                    ;75462;
                call    $Find_First     ;Uses internal DS:DX, CX         ;75462;
                pop     WORD PTR [User_In_AX]                            ;75462;
                jc      FindFirst_Err                                    ;75462;
FindFiles:        push    ss                                               ;75462;
                  pop     ds                                               ;75462;
                  lea     si, TempDTA+1Eh ;offset of filename in DTA       ;75462;
                  mov     di, pFileNameOfs   ;offset of filename in string ;75462;
                  push    cs              ;path string is in CS            ;75462;
                  pop     es                                               ;75462;
                  mov     cx,0Dh          ;max length of filename          ;75462;
                  cld                                                      ;75462;
CopyFileName:     repnz   movsb           ;copy filename to pFileNameOfs   ;75462;
                  lea     dx, sTempPath   ;DS:DX = delete filespec         ;75462;
                  pop     cx              ;CX=file attribs                 ;75462;
                  push    cx              ;re-save file attribs            ;75462;
                  mov     es,[CurrentPDB]                                  ;75462;
                  mov     es,es:[PDB_environ]     ;es:=CurrentPDB[002Ch]   ;75462;
DoFunction41h:    cmp     [User_In_AX], 4100h                              ;75462;
                  jnz     short DoFunction00h     ;Error: Unsupported func.;75462;
                    mov     ax, CS:[SaveWINOS2Check] ;restore results from   ;75462;
                                                     ;Int 2Fh, func 160A     ;75462;
                                                     ;(from $UNLINK)         ;75462;
                    SVC     SVC_DEMDELETE                                    ;75462;
                    jc      RestoreDTA      ;exit on error. We only get      ;75462;
                          ;one return value, even though multiple results  ;75462;
                          ;are possible with wildcard filespecs. Best to   ;75462;
                          ;notify user of error while error info is still  ;75462;
                          ;intact.                                         ;75462;
                  ;;jmp   short DoFindNext  ;use if support for additional ;75462;
                                            ;functions is added later.     ;75462;
DoFunction00h:            ;Placeholder for handling additional DEM services;75462;
                          ;                                                ;75462;
DoFindNext:       pop     cx                                               ;75462;
                  push    cx                                               ;75462;
; Change current value of User_In_AX (should be 41h) to allow $Find_Next     ;75462;
; to handle errors correctly. 4Fh is value of Find_Next DOS function.        ;75462;
                  push    WORD PTR [User_In_AX]                            ;75462;
                  mov     BYTE PTR [User_In_AX +1], 4Fh                    ;75462;
                  call    $Find_Next                                       ;75462;
                  pop     WORD PTR [User_In_AX]                            ;75462;
                  jnc     FindFiles     ; end of loop                      ;75462;
; Fallthrough = $Find_Next failed ( =  out of files or ERROR )             ;75462;
                clc                     ; assume error = no more files     ;75462;
                cmp     ax,ERROR_NO_MORE_FILES; = No more files error = OK.    ;75462;
                je      short RestoreDTA; Go to cleanup & exit           ;75462;
                stc                     ; We had an unexpected error     ;75462;
                jmp     short RestoreDTA                                 ;75462;
SCHandler_Err:  mov     ax, ERROR_FILE_NOT_FOUND                         ;75462;
                stc                                                      ;75462;
                jmp     SCHandler_Exit  ;can't fallthrough because we    ;75462;
                                        ;don't have a DTA to restore     ;75462;
FindFirst_Err:  cmp     ax,ERROR_NO_MORE_FILES;                          ;75462;
                jnz     short RestoreDTA                                 ;75462;
                mov     ax,ERROR_FILE_NOT_FOUND ;change no_more_files to ;75462;
                                        ; file_not_found                 ;75462;
                stc                                                      ;75462;
RestoreDTA:     pushf                   ; save prev error info           ;75462;
                push      ax                                             ;75462;
                mov       ds,pOldDTASeg   ; restore orig DTA             ;75462;
                mov       dx,pOldDTAOfs                                  ;75462;
                mov       ax,1A00h        ; value for Set DTA func.      ;75462;
                call      $Set_DMA        ;                              ;75462;
                pop       ax              ;                              ;75462;
                popf                                                     ;75462;
SCHandler_Exit: pop       cx                                             ;75462;
                pop       ds                                             ;75462;
                LeaveProc       NoCheck                                  ;75462;
                ret                                                      ;75462;
EndProc         SrvCallHandler                                           ;75462;

V86CODE ENDS

        END
