;       SCCSID = @(#)dema.asm   6.9 91/12/04
PAGE    ,132
TITLE   dema - DOS Emulation Creation/Assembly Routines
NAME    dema
.386p

;***    dema.asm
;
;       SCCSID = @(#)dema.asm   6.9 91/12/04
;
;       Version 1.4.1.3, for src/dos/mvdm/dema.asm, dem, mer.krnl, currbld
;
;       Title:
;
;       DOS Emulation Creation/Assembly Routines
;
;       Description:
;
;       This module contains routines for DOS Emulation Creation
;       that cannot possibly be written in C due to the 0:32/16:16
;       interface conflict.
;
;       Public routines:
;
;           demOpenFile
;           demCloseFile
;           demReadFile
;           demSeekFile
;           demTransPath
;
;********************************************************************** ;BN011;
; Add new function. G.L.Fulk                                            ;BN011;
;********************************************************************** ;BN011;
; 21Nov91 - G.L.Fulk                                                    ;BN012;
; Add uppercase translation to demTransPath.                            ;BN012;
;********************************************************************** ;BN012;
; 28Aug92 - F. Miro'                                                    ;BN013;
; Updated code due interface changes to filesystem workers for          ;BN013;
; protected file handles                                                ;BN013;
;********************************************************************** ;BN013;
; 13Jul93 - G.L.Fulk                                                    ;70592;
; Change drive and sub-directory now.                                   ;70592;
;**********************************************************************
; 19Sep94 - bjn
; Change segment names for page tuning.
;**********************************************************************
; 19Jul96 - Gil Pratte - defect 141181
; Changed demSetPTDAFilesCount to return success or failure
;**********************************************************************

INCL_NONE       equ     1                       ; don't include everything
INCL_TYPES      equ     1                       ; include basic types
INCL_DEF        equ     1                       ; include typedef macros
INCL_VDHALL     equ     1                       ; include VDH services

.xlist
        include dosseg.inc
        include osmaca.inc
        include osconst.inc
        include infoseg.inc
        include dossymc.inc
        include sigdef.inc
        include except.inc
        include pgexport.inc
        include vmexport.inc
        include selxport.inc
        include tkexport.inc
        include dirent.inc
        include curdir.inc
        include find.inc
        include screen.inc
        include sft.inc
        include sem.inc
        include tkptda.inc
        include kmode.inc
        include seldesc.inc
        include mi.inc
        include mvdm.inc
        include opncreat.inc
        include filemode.inc
        include inbuf.inc
        include error.inc
        include dem.inc
.list

        CpuMode 386
        ModName dema

        ReferFlat       _pPTDACur,DWORD

        EXTRN16 DoOpenCreate
        EXTRN16 w_QFileInfo
        EXTRN16 w_Read
        EXTRN16 w_Close
        EXTRN16 w_LSeek
        EXTRN16 TransPath
        EXTRN16 StrCpy                                                  ;BN012;
        EXTRN16 w_Set_Default_Drive
        EXTRN   demExtHandle: near                                      ;BN011;
        EXTRN16 w_ChDir                                                 ;70592;
        EXTRN   _demStartSession_CDS_lowmem:BYTE                        ;70592;

DefCode IMPORT, GLOBAL
DefFn   demMapVirt
EndCode

DefCode EXPORT, SWAP, PASCAL
DefFn   demOpenFile
DefFn   demCloseFile
DefFn   demReadFile
DefFn   demSeekFile
DefFn   demTransPath
DefFn   demNoInheritFile
DefFn   demSetPTDAFilesCount                                            ;BN011;
DefFn   demSetCDS
EndCode

        FARCODE HIGH32
DefCode PRIVATE, SWAP, PASCAL
SWAP32_22 segment
;***LP+ demOpenFile - Open the a file or device
;
;       Open the a file or device and return its handle and length
;
;       INT PASCAL demOpenFile(pszFile, phFile, pcbFile);
;
;       ENTRY
;           pszFile
;               File pathname
;           phFile
;               Pointer to return file handle
;           pcbFile
;               Pointer to return file size.  If NULL, don't get file size.
;
;       EXIT
;           SUCCESS
;               AX = 0
;               *phFile = file handle
;               *cbFile = file size, in bytes
;
;           FAILURE
;               Returns non-zero error code in AX
;
;       CONTEXT
;           VDM Task
;
;       STEPS
;           Call DoOpenCreate to open the file
;           if SUCCESS -->
;               call w_QFileInfo to get file size
;           else
;               call w_Close
;
;       NOTES
;           None
;
;       WARNINGS
;           We consume a handle here, which we *must* relinquish before
;           we allow the VDM to proceed.
;
;       CALLS
;           DoOpenCreate
;           w_Close
;           w_QFileInfo
;
        ASSUME  DS:FLAT,ES:FLAT,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demOpenFile,near

ArgVar    dof_pszFile,DWORD
ArgVar    dof_phFile,DWORD
ArgVar    dof_pcbFile,DWORD
LocalVar  dof_hFile,DWORD
LocalVar  dof_inbuf,<size inbuf>

        EnterProc
        SaveReg <esi, edi, ebx, ds, es>
        mov     eax,[dof_pszFile]       ; (EAX) = linear address
        mov     ecx,MAXPATHLEN          ; (ECX) = size of alias
        xor     edx,edx                 ; (EDX) = selector index
        .errnz  ISELDEMTEMP
        call    demMapVirt              ; map the selector
        mov     ds,eax                  ; selector in DS points to paragraph
        ASSUME  ds:NOTHING
        xor     edx,edx                 ; (DS:DX) = path name

        mov     ah,attr_hidden+attr_system  ; allow hidden and system attr's
        mov     al,OPCR_SATTR_INDIRECT
        xor     ebx,ebx                 ; we're not creating a file
        mov     cx,exist_open+nexist_fail
        mov     di,open_for_read+sharing_deny_write
        xor     esi,esi                 ; no open mode 2
        CALL16  DoOpenCreate            ; open the file
        jc      short dofx              ; exit if error
        mov     [dof_hFile],eax         ; save handle for later
        mov     ebx,eax                 ; get handle in bx

        cmp     [dof_pcbFile],0         ; query the file size?
        je      short dof20             ;  no, jump to exit

        push    ss
        pop     ds
        ASSUME  ds:NOTHING
        lea     esi,[dof_inbuf]         ; (DS:SI) = address of buffer
        mov     cx,(size inbuf)
        mov     dx,QINFOLEV_DATE_TIME   ; also gets file end of data size
        xor     ax,ax                   ; fake filehandlelockID lowword (BN013)
        xor     di,di                   ; fake filehandlelockID highword (BN013)
        CALL16  w_QFileInfo             ; get the file information
        jnc     short dof10             ; proceed if OK

        mov     ebx,[dof_hFile]
        push    eax                     ; save error
        xor     cx,cx                   ; fake filehandlelockID lowword  (BN013)
        xor     dx,dx                   ; fake filehandlelockID highword (BN013)
        CALL16  w_Close                 ; close the file
        pop     eax                     ; get previous error
        jmp     short dofx

dof10:  FlatContext <ds>
        mov     eax,[dof_inbuf].inbuf_size ; (EAX) = the file size
        mov     ebx,[dof_pcbFile]       ; (EBX) = file size return pointer
        mov     [ebx],eax               ; store returned file size

dof20:  FlatContext <ds>
        mov     eax,[dof_hFile]         ; (EAX) = handle
        mov     ebx,[dof_phFile]        ; (EBX) = handle return pointer
        mov     [ebx],ax                ; store returned handle
        xor     eax,eax                 ; no error
dofx:   movzx   eax,ax                  ; (EAX) = error code
        RestoreReg <es, ds, ebx, edi, esi>
        ExitProc
EndProc demOpenFile

;***LP+ demCloseFile - close a file or device
;
;       Call w_Close to close the file or device
;
;       INT PASCAL demCloseFile(hFile);
;
;       ENTRY
;           hFile
;               handle to close
;
;       EXIT
;           SUCCESS
;               EAX = 0
;
;           FAILURE
;               Returns non-zero error code in EAX
;
;       CONTEXT
;           VDM Task
;
;       STEPS
;           Call w_Close to close the file
;
;       NOTES
;           None
;
;       WARNINGS
;           None
;
;       CALLS
;           w_Close
;
        ASSUME  DS:FLAT,ES:FLAT,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demCloseFile,near

ArgVar  dcf_hFile,DWORD

        EnterProc
        SaveReg <esi, edi, ebx, ds, es>
        mov     ebx,[dcf_hFile]         ; get the handle in BX
        push    cx
        push    dx
        xor     cx,cx                   ; fake filehandlelockID lowword  (BN013)
        xor     dx,dx                   ; fake filehandlelockID highword (BN013)
        CALL16  w_Close                 ; close it
        pop     dx                      ; get rid of filehandle lockID
        pop     cx                      ; get rid of filehandle lockID
        jc      short dcfx
        xor     eax,eax
dcfx:   movzx   eax,ax                  ; (EAX) = error code
        RestoreReg <es, ds, ebx, edi, esi>
        ExitProc
EndProc demCloseFile

;***LP+ demReadFile - read from a file or device
;
;       Call w_Read to read the opened file or device
;
;       INT PASCAL demReadFile(hFile, pBuffer, cbRead, pcbRead);
;
;       ENTRY
;           hFile
;               non-fake handle to read from
;           pBuffer
;               buffer into which to read the file
;           cbRead
;               number of bytes to read
;           pcbRead
;               number of bytes read
;
;       EXIT
;           SUCCESS
;               EAX = 0
;
;           FAILURE
;               Returns non-zero error code in EAX
;
;       CONTEXT
;           VDM Task
;
;       STEPS
;           Call w_Read to read from the file
;           if (EAX == NO_ERROR) AND (bytes_read != ulcbBuffer) -->
;               return ERROR_BUFFER_OVERFLOW
;           else
;               return EAX
;
;       NOTES
;           None
;
;       CALLS
;           w_Read
;
        ASSUME  DS:FLAT,ES:FLAT,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demReadFile,near

ArgVar  drf_hFile,DWORD
ArgVar  drf_pBuffer,DWORD
ArgVar  drf_cbRead,DWORD
ArgVar  drf_pcbRead,DWORD

        EnterProc
        SaveReg <esi, edi, ebx, ds, es>
        mov     eax,[drf_pBuffer]       ; (EAX) = linear address
        mov     ecx,[drf_cbRead]        ; (ECX) = transfer size
        xor     edx,edx                 ; (EDX) = selector index
        .errnz  ISELDEMTEMP
        call    demMapVirt              ; (AX) = selector
        mov     ds,eax
        ASSUME  ds:NOTHING
        xor     edx,edx                 ; (DS:DX) = buffer address

        mov     ecx,[drf_cbRead]        ; (CX) = transfer size
        mov     ebx,[drf_hFile]         ; (BX) = handle
        push    ebp
        xor     si,si                   ; fake filehandlelockID lowword  (BN013)
        xor     di,di                   ; fake filehandlelockID highword (BN013)
        CALL16  w_Read                  ; read the file
        ASSUME  ds:NOTHING,es:NOTHING
        pop     ebp
        jc      short drfx              ; skip if error

        FlatContext <ds>
        movzx   eax,ax                  ; (EAX) = number of bytes read
        mov     ebx,[drf_pcbRead]
        mov     [ebx],eax
        xor     eax,eax
drfx:   movzx   eax,ax
        RestoreReg <es, ds, ebx, edi, esi>
        ExitProc
EndProc demReadFile

;***LP+ demSeekFile - seek a file or device
;
;       Call w_LSeek to move the file position
;
;       INT PASCAL demSeekFile(hFile, ulSeekType, ulPos, pulPos);
;
;       ENTRY
;           hFile
;               handle of file
;           ulSeekType
;               type of seek
;           ulPos
;               position to move file pointer
;           pulPos
;               new position after seek
;
;       EXIT
;           SUCCESS
;               EAX = 0
;
;           FAILURE
;               Returns non-zero error code in EAX
;
;       CONTEXT
;           VDM Task
;
;       STEPS
;           Call w_LSeek to close the file
;
;       NOTES
;           None
;
;       WARNINGS
;           None
;
;       CALLS
;           w_LSeek
;
        ASSUME  DS:FLAT,ES:FLAT,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demSeekFile,near

ArgVar  dsf_hFile,DWORD
ArgVar  dsf_ulSeekType,DWORD
ArgVar  dsf_ulPos,DWORD
ArgVar  dsf_pulPos,DWORD

        EnterProc
        SaveReg <esi, edi, ebx, ds, es>
        mov     eax,[dsf_ulSeekType]
        mov     edx,[dsf_ulPos]
        shld    ecx,edx,16              ; (CX:DX) = position
        mov     ebx,[dsf_hFile]         ; get the handle in BX
        xor     di,di               ; fake low word of filehandlelockID  (BN013)
        xor     si,si               ; fake high word of filehandlelockID (BN013)
        CALL16  w_LSeek                 ; (DX:AX) = new position
        jc      short dsfx

        FlatContext <ds>
        mov     ebx,[dsf_pulPos]        ; (EBX) = pointer to put new position
        mov     [ebx].loword,ax
        mov     [ebx].hiword,dx
        xor     eax,eax
dsfx:   movzx   eax,ax
        RestoreReg <es, ds, ebx, edi, esi>
        ExitProc
EndProc demSeekFile

SWAP32_22 ENDS

SWAP32_23 segment
;***LP+ demTransPath - transpath a file name
;
;       INT PASCAL demTransPath(psz, ul);
;
;       ENTRY
;           psz
;               pointer to file name
;           ul
;               Stack buffer offset to put new string
;
;       EXIT
;           SUCCESS
;               EAX = 0
;
;           FAILURE
;               Returns non-zero error code in EAX
;
;       CONTEXT
;           VDM Task
;
;       STEPS
;           Make 16 bit selector alias
;           call TransPath
;
;       NOTES
;           None
;
;       CALLS
;           TransPath
;
        ASSUME  DS:FLAT,ES:FLAT,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demTransPath,near

ArgVar  dtp_psz,DWORD
ArgVar  dtp_ul,DWORD
LocalVar dummycds,<SIZE curdir>
LocalVar glf_openbuf,PMPATHLEN                                          ;BN012;

        EnterProc
        SaveReg <ebx, esi, edi>
        lea     ax,dummycds
        push    ebx                      ;### PTR B720732               ;BC012;
        mov     ebx,[_pTCBCur]           ;### PTR B720732
        mov     [ebx].TCBpTmpCDS.Offst,ax      ; Initialize ptda_pCDS ;#B720732
        lea     di,glf_openbuf                                          ;BN012;
        pop     ebx                      ;### PTR B720732               ;BC012;
        mov     eax,[dtp_psz]
        mov     ecx,10000h
        xor     edx,edx
        .errnz  ISELDEMTEMP
        call    demMapVirt
        mov     ds,eax
        xor     esi,esi                 ; (DS:ESI) = pointer to string
;BD012; mov     edi,[dtp_ul]            ;(DI)=SS relative offset of buf ;BD012;
        CALL16  TransPath
        jc      short dtp10
        lea     si,glf_openbuf                                          ;BN012;
        mov     edi,[dtp_ul]            ;(DI)=SS relative offset of buf ;BN012;
        push    ds                                                      ;BN012;
        pop     es                                                      ;BN012;
        CALL16  StrCpy                                                  ;BN012;
        TaskContext DS                                                  ;BN012;
        xor     eax,eax
dtp10:  movzx   eax,ax
        FlatContext <ds,es>,ecx
        RestoreReg <edi, esi, ebx>
        ExitProc
EndProc demTransPath

;***LP+ demNoInheritFile - Close all the files inherited from parent
;
;
;       ENTRY
;           None
;
;       EXIT
;           None
;
;       CONTEXT
;           VDM Creation
;
;       STEPS
;           Scan each entry in JFN and close ones which are open
;
;       NOTES
;           None
;
;       CALLS
;           w_Close
;
        ASSUME  DS:FLAT,ES:NOTHING,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demNoInheritFile,near
        EnterProc
        SaveReg <esi,ebx,es>
        mov     eax,[_pPTDACur]
        mov     bx,[eax].JFN_pTable.Segmt   ; JFN table address
        movzx   esi,[eax].JFN_pTable.Offst  ; JFN table address
        mov     es,bx
        movzx   ecx,[eax].JFN_Length        ; JFN table length
        xor     ebx,ebx
dni10:  cmp     word ptr es:[esi+ebx*2],0ffh
        je      short dni20                 ; Yes, Go check next

        SaveReg <ebx,ecx,edx,esi,ds,es>     ; added edx due to filehandlelockID (BN013)
        xor     cx,cx                       ; fake filehandlelockID lowword   (BN013)
        xor     dx,dx                       ; fake filehandlelockID highword  (BN013)
        CALL16  w_Close                     ; Perform the close
        RestoreReg <es,ds,esi,edx,ecx,ebx>  ; added edx due to filehandlelockID (BN013)
dni20:  inc     ebx
        loop    dni10                       ; loop for each JFN

        RestoreReg <es,ebx,esi>
        ExitProc
EndProc demNoInheritFile

;***LP+ demSetPTDAFilesCount - The the task PTDA JFN Table size         ;BN011;
;                                                                       ;BN011;
;                                                                       ;BN011;
;       ENTRY                                                           ;BN011;
;           parm1 = File size count                                     ;BN011;
;                                                                       ;BN011;
;       EXIT                                                            ;BN011;
;           Success:  eax = NO_ERROR                                    ;141181
;           Failure:  eax = NOT NO_ERROR                                ;141181
;                                                                       ;BN011;
;       CONTEXT                                                         ;BN011;
;           VDM Creation                                                ;BN011;
;                                                                       ;BN011;
;       STEPS                                                           ;BN011;
;           Call the MVDM worker for setting the JFN Table size         ;BN011;
;                                                                       ;BN011;
;       NOTES                                                           ;BN011;
;           None                                                        ;BN011;
;                                                                       ;BN011;
;       CALLS                                                           ;BN011;
;           demExtHandle                                                ;BN011;
;                                                                       ;BN011;
        ASSUME  DS:FLAT,ES:NOTHING,SS:NOTHING,FS:NOTHING,GS:NOTHING     ;BN011;

Procedure demSetPTDAFilesCount,near                                     ;BN011;
ArgVar  New_Files_Count,DWORD                                           ;BN011;
        EnterProc                                                       ;BN011;

;------ save registers                                                  ;BN011;
        push    ebx                                                     ;141181
        push    ecx                                                     ;141181
        push    edx                                                     ;141181
        push    edi                                                     ;141181
        push    esi                                                     ;141181
        push    es                                                      ;BN011;
        push    ds                                                      ;BN011;

;------ point "DS:[EBX].VSF_BX" at our parameter                        ;BN011;
        push    ss                                                      ;BN011;
        pop     ds                                                      ;BN011;
        lea     ebx,New_Files_Count                                     ;BN011;
        sub     ebx,vsf_bx                                              ;BN011;
                                                                        ;BN011;
;------ Call the MVDM worker                                            ;BN011;
        call    demExtHandle                                            ;BN011;
        mov     eax, NO_ERROR       ; Assume no error                   ;141181
        jnc     EXITSetFilesCount                                       ;141181
        mov     eax, NOT NO_ERROR   ; Error                             ;141181
EXITSetFilesCount:                                                      ;141181

;------ restore registers                                               ;BN011;
        pop     ds                                                      ;BN011;
        pop     es                                                      ;BN011;
        pop     esi                                                     ;141181
        pop     edi                                                     ;141181
        pop     edx                                                     ;141181
        pop     ecx                                                     ;141181
        pop     ebx                                                     ;141181

        ExitProc                                                        ;BN011;
EndProc demSetPTDAFilesCount                                            ;BN011;
SWAP32_23 ENDS

;***LP+ demSetCDS -
;
;
;       ENTRY
;           parm1 = File size count
;
;       EXIT
;           None
;
;       CONTEXT
;           VDM Creation
;
;       STEPS
;           Call the MVDM worker for setting the JFN Table size
;
;       NOTES
;           None
;
;       CALLS
;           demExtHandle
;
        ASSUME  DS:FLAT,ES:NOTHING,SS:NOTHING,FS:NOTHING,GS:NOTHING

Procedure demSetCDS,near
ArgVar  Old_CDS,DWORD
        EnterProc

;------ save registers
        pushad
        push    es
        push    ds

;------ Get the passed pointer
        mov     eax,Old_CDS

;------ Currently points to only the new changed drive
        mov     dl,[eax]
        and     dx,00DFh                ;zero DH and convert DL upcase  ;70592;
        sub     dl,'A'                                                  ;70592;
        push    eax                                                     ;70592;
        ;entry: DX=drive number (a=0 b=1...)                            ;70592;
        CALL16  w_Set_Default_Drive     ;filesys\getset2.asm            ;70592;
        ;exit:  NC=ok                                                   ;70592;
                                                                        ;70592;
;------ copy from high CDS to low CDS                                   ;70592;
        pop     esi                                                     ;70592;
        mov     edi,offset FLAT:_demStartSession_CDS_lowmem             ;70592;
        mov     ecx,68/4                                                ;70592;
        mov     eax,edi                                                 ;70592;
        cld                                                             ;70592;
        rep     movsd                                                   ;70592;
                                                                        ;70592;
        mov     ecx,68                                                  ;70592;
        xor     edx,edx                                                 ;70592;
        .errnz  ISELDEMTEMP                                             ;70592;
        ;entry: eax=linear address                                      ;70592;
        ;       ecx=size                                                ;70592;
        ;       edx=index of selector                                   ;70592;
        call    demMapVirt              ;mvdm\demfile2.asm              ;70592;
        ;exit:  NC, AX=selector                                         ;70592;
                                                                        ;70592;
        ;entry: DS:DX=asciiz                                            ;70592;
        mov     ds,ax                                                   ;70592;
        assume  ds:nothing                                              ;70592;
        xor     edx,edx                                                 ;70592;
        CALL16  w_ChDir                 ;filesys\path.asm               ;70592;
        ;exit:  NC=ok                                                   ;70592;

;------ restore registers
        pop     ds
        pop     es
        popad

        ExitProc
EndProc demSetCDS

EndCode
        end
