385 lines
8.2 KiB
NASM
385 lines
8.2 KiB
NASM
|
TITLE LDCACHE - Segment and File Handle Caching procedures
|
||
|
|
||
|
.xlist
|
||
|
include kernel.inc
|
||
|
include newexe.inc
|
||
|
include tdb.inc
|
||
|
|
||
|
.list
|
||
|
|
||
|
DataBegin
|
||
|
|
||
|
externW hExeHead
|
||
|
|
||
|
externW topPDB
|
||
|
externW Win_PDB
|
||
|
externW curTDB
|
||
|
externW cur_dos_PDB
|
||
|
externB fhCache
|
||
|
externW fhCacheLen
|
||
|
externW fhCacheEnd
|
||
|
externW fhcStealNext
|
||
|
|
||
|
DataEnd
|
||
|
|
||
|
externFP MyOpenFile
|
||
|
externFP Int21Handler
|
||
|
|
||
|
sBegin CODE
|
||
|
assumes CS,CODE
|
||
|
assumes DS,NOTHING
|
||
|
assumes ES,NOTHING
|
||
|
|
||
|
externNP real_DOS
|
||
|
|
||
|
;-----------------------------------------------------------------------;
|
||
|
; GetCachedFileHandle ;
|
||
|
; ;
|
||
|
; Look for the file handle for an EXE file in the cache of file ;
|
||
|
; handles. Sets current PDB to that of KERNEL to access the file. ;
|
||
|
; A handle NOT to free in order to satisfy the request can also ;
|
||
|
; be given. ;
|
||
|
; ;
|
||
|
; Arguments: ;
|
||
|
; parmW hExe handle of EXE file ;
|
||
|
; parmW keepfh file handle not to change ;
|
||
|
; parmW fh file handle if file already open ;
|
||
|
; ;
|
||
|
; Returns: ;
|
||
|
; AX == file handle ;
|
||
|
; ;
|
||
|
; Error Returns: ;
|
||
|
; ;
|
||
|
; Registers Preserved: ;
|
||
|
; ;
|
||
|
; Registers Destroyed: ;
|
||
|
; ;
|
||
|
; Calls: ;
|
||
|
; real_DOS ;
|
||
|
; ;
|
||
|
; History: ;
|
||
|
; Wed 18-Oct-1989 20:40:51 -by- David N. Weise [davidw] ;
|
||
|
; Added the feature of not closing a specified handle. ;
|
||
|
;-----------------------------------------------------------------------;
|
||
|
|
||
|
assumes ds, nothing
|
||
|
assumes es, nothing
|
||
|
ifdef WOW
|
||
|
.286
|
||
|
else
|
||
|
endif
|
||
|
|
||
|
cProc FarGetCachedFileHandle,<PUBLIC,FAR>
|
||
|
parmW hExe
|
||
|
parmW keepfh
|
||
|
parmW fh
|
||
|
cBegin
|
||
|
cCall GetCachedFileHandle,<hExe,keepfh,fh>
|
||
|
cEnd
|
||
|
|
||
|
|
||
|
cProc GetCachedFileHandle,<PUBLIC,NEAR>,<bx,di,ds,es>
|
||
|
parmW hExe
|
||
|
parmW keepfh
|
||
|
parmW fh ; -1 if file not open
|
||
|
localW fhcFreeEntry
|
||
|
cBegin
|
||
|
SetKernelDS
|
||
|
mov fhcFreeEntry, 0
|
||
|
|
||
|
mov bx, topPDB
|
||
|
|
||
|
;;; cmp bx, Win_PDB
|
||
|
;;; je gcfh_okPDB ; Don't bother setting if already this
|
||
|
;;; mov cur_dos_PDB, bx
|
||
|
;;; mov Win_PDB, bx ; Run on kernel's PDB for a while
|
||
|
;;; mov ah, 50h ; set PDB
|
||
|
;;; call real_DOS
|
||
|
;;;gcfh_okPDB:
|
||
|
|
||
|
mov Win_PDB, bx ; Run on kernel's PDB for a while
|
||
|
|
||
|
mov ax, hExe ; look for this EXE in the file
|
||
|
mov es, ax ; handle cache
|
||
|
mov cx, fhCacheLen
|
||
|
mov di, dataOffset fhCache
|
||
|
gcfh_searchfh:
|
||
|
mov bx, [di.CacheExe]
|
||
|
cmp ax, bx
|
||
|
jne @F
|
||
|
jmps gcfh_found
|
||
|
@@:
|
||
|
or bx, bx ; Free entry?
|
||
|
jnz gcfh_searchnext
|
||
|
cmp fhcFreeEntry, bx ; already have a free entry?
|
||
|
jne gcfh_searchnext
|
||
|
mov fhcFreeEntry, di ; Save index for free entry
|
||
|
gcfh_searchnext:
|
||
|
add di, size fhCacheStruc
|
||
|
loop gcfh_searchfh
|
||
|
; EXE not already in the cache
|
||
|
mov di, fhcFreeEntry ; Did we find a free entry?
|
||
|
or di, di
|
||
|
jz gcfh_stealone ; no, steal one
|
||
|
mov fhcFreeEntry, -1 ; Flag to steal one if the open fails
|
||
|
jmps gcfh_openit ; (due to out of file handles)
|
||
|
|
||
|
gcfh_stealone: ; No free entry, pick one on first come,
|
||
|
mov cx, fhcStealNext ; first served basis
|
||
|
gcfh_stealnext:
|
||
|
mov di, cx
|
||
|
add cx, 4 ; Calculate next index in CX
|
||
|
cmp cx, fhCacheEnd
|
||
|
jb gcfh_oknext
|
||
|
mov cx, dataoffset fhCache ; Start back at the beginning
|
||
|
gcfh_oknext:
|
||
|
mov bx, [di.Cachefh]
|
||
|
or bx, bx ; If no file handle,
|
||
|
jz gcfh_stealnext ; on to next cache entry
|
||
|
cmp bx, keepfh ; If handle not to free
|
||
|
jz gcfh_stealnext ; on to next cache entry
|
||
|
mov fhcStealNext, cx
|
||
|
|
||
|
mov ah, 3Eh
|
||
|
DOSCALL ; Close this file handle
|
||
|
mov fhcFreeEntry, di
|
||
|
|
||
|
gcfh_openit:
|
||
|
push ds
|
||
|
mov ax, fh
|
||
|
cmp ax, -1 ; File already open?
|
||
|
jne gcfh_opened ; yes, just put in cache
|
||
|
|
||
|
mov dx,es:[ne_pfileinfo]
|
||
|
regptr esdx,es,dx
|
||
|
; mov bx,OF_SHARE_DENY_WRITE or OF_REOPEN or OF_PROMPT or OF_VERIFY or OF_CANCEL
|
||
|
;;; mov bx,OF_REOPEN or OF_PROMPT or OF_VERIFY or OF_CANCEL
|
||
|
if 1
|
||
|
smov ds,es
|
||
|
add dx, opFile
|
||
|
;;; test es:[ne_flags],NEAPPLOADER
|
||
|
;;; jnz @F
|
||
|
if SHARE_AWARE
|
||
|
mov ax, 3DA0h ; open for read, deny write, no inherit
|
||
|
else
|
||
|
mov ax, 3D80h ; open for read, no inherit
|
||
|
endif
|
||
|
DOSCALL
|
||
|
jnc gcfh_opened
|
||
|
;;;@@:
|
||
|
mov ax, 3DC0h ; try share deny none
|
||
|
DOSCALL
|
||
|
jnc gcfh_opened
|
||
|
else
|
||
|
mov bx,OF_REOPEN or OF_VERIFY
|
||
|
push es
|
||
|
cCall MyOpenFile,<esdx,esdx,bx>
|
||
|
pop es
|
||
|
cmp ax, -1
|
||
|
jne gcfh_opened
|
||
|
endif
|
||
|
pop ds
|
||
|
cmp fhcFreeEntry, -1 ; This was a free cache entry?
|
||
|
je gcfh_stealone ; yes, have run out of file handles
|
||
|
mov ax, -1 ; fix bug #6774 donc
|
||
|
jmps gcfh_exit ; no, a real failure
|
||
|
gcfh_found:
|
||
|
mov ax, [di.Cachefh]
|
||
|
jmps gcfh_exit
|
||
|
gcfh_opened:
|
||
|
pop ds
|
||
|
mov [di.Cachefh], ax
|
||
|
mov [di.CacheExe], es
|
||
|
|
||
|
gcfh_exit:
|
||
|
cEnd
|
||
|
|
||
|
|
||
|
;-----------------------------------------------------------------------;
|
||
|
; CloseCachedFileHandle ;
|
||
|
; ;
|
||
|
; Close the EXE file with the given file handle. ;
|
||
|
; Actually does delays closing the file until the handle is needed. ;
|
||
|
; Resets the current PDB to that of the current task. ;
|
||
|
; ;
|
||
|
; Arguments: ;
|
||
|
; parmW fh file handle being 'closed' ;
|
||
|
; ;
|
||
|
; Returns: ;
|
||
|
; none ;
|
||
|
; ;
|
||
|
; Error Returns: ;
|
||
|
; ;
|
||
|
; Registers Preserved: ;
|
||
|
; ;
|
||
|
; Registers Destroyed: ;
|
||
|
; AX ;
|
||
|
; ;
|
||
|
; Calls: ;
|
||
|
; real_DOS ;
|
||
|
; ;
|
||
|
; History: ;
|
||
|
; ;
|
||
|
;-----------------------------------------------------------------------;
|
||
|
|
||
|
assumes ds,nothing
|
||
|
assumes es,nothing
|
||
|
|
||
|
cProc CloseCachedFileHandle,<PUBLIC,NEAR>,<bx,ds,es>
|
||
|
parmW fh
|
||
|
cBegin
|
||
|
;;; SetKernelDS
|
||
|
;;; mov es, curTDB
|
||
|
;;; mov bx, es:[TDB_PDB]
|
||
|
;;; cmp bx, Win_PDB
|
||
|
;;; je ccfh_okPDB
|
||
|
;;; mov Win_PDB, bx
|
||
|
;;; mov cur_dos_PDB, bx
|
||
|
;;; mov ah, 50h
|
||
|
;;; call real_DOS
|
||
|
;;;ccfh_okPDB:
|
||
|
cEnd
|
||
|
|
||
|
;-----------------------------------------------------------------------;
|
||
|
; FlushCachedFileHandle ;
|
||
|
; ;
|
||
|
; Look for the file handle for an EXE file in the cache of file handles ;
|
||
|
; If it is found, close the file. ;
|
||
|
; ;
|
||
|
; Arguments: ;
|
||
|
; parmW hExe handle of EXE file ;
|
||
|
; ;
|
||
|
; Returns: ;
|
||
|
; ;
|
||
|
; Error Returns: ;
|
||
|
; ;
|
||
|
; Registers Preserved: ;
|
||
|
; ;
|
||
|
; Registers Destroyed: ;
|
||
|
; ;
|
||
|
; Calls: ;
|
||
|
; real_DOS ;
|
||
|
; ;
|
||
|
; History: ;
|
||
|
; ;
|
||
|
;-----------------------------------------------------------------------;
|
||
|
|
||
|
assumes ds, nothing
|
||
|
assumes es, nothing
|
||
|
|
||
|
cProc FlushCachedFileHandle,<PUBLIC,FAR>,<ax,bx,cx,di>
|
||
|
parmW hExe
|
||
|
cBegin
|
||
|
SetKernelDS
|
||
|
mov ax, hExe
|
||
|
or ax, ax ; make sure we really
|
||
|
jz fcfh_exit ; have a hExe
|
||
|
mov cx, fhCacheLen
|
||
|
mov di, dataOffset fhCache
|
||
|
fcfh_search:
|
||
|
cmp ax, [di.CacheExe]
|
||
|
je fcfh_found
|
||
|
add di, size fhCacheStruc
|
||
|
loop fcfh_search
|
||
|
jmps fcfh_exit ; Not cached, nothing to do
|
||
|
fcfh_found:
|
||
|
|
||
|
;;; mov bx, topPDB
|
||
|
;;; cmp bx, cur_dos_PDB
|
||
|
;;; je fcfh_okPDB
|
||
|
;;; mov cur_dos_PDB, bx
|
||
|
;;; mov ah, 50h ; set PDB
|
||
|
;;; call real_DOS
|
||
|
;;;fcfh_okPDB:
|
||
|
|
||
|
push Win_PDB ; Save 'current' PDB
|
||
|
|
||
|
mov bx, topPDB
|
||
|
mov Win_PDB, bx ; Run on kernel's PDB for a while
|
||
|
|
||
|
mov bx, [di.Cachefh]
|
||
|
mov ah, 3Eh ; Close the file
|
||
|
DOSCALL
|
||
|
xor ax, ax
|
||
|
mov [di.Cachefh], ax ; mark cache entry free
|
||
|
mov [di.CacheExe], ax
|
||
|
|
||
|
;;; push es
|
||
|
;;; mov es, curTDB ; and reset the PDB
|
||
|
;;; mov bx, es:[TDB_PDB]
|
||
|
;;; pop es
|
||
|
;;; cmp bx, Win_PDB
|
||
|
;;; je fcfh_exit
|
||
|
;;; mov Win_PDB, bx
|
||
|
;;; mov cur_dos_PDB, bx
|
||
|
;;; mov ah, 50h
|
||
|
;;; call real_DOS
|
||
|
|
||
|
pop Win_PDB ; Restore original PDB
|
||
|
|
||
|
fcfh_exit:
|
||
|
cEnd
|
||
|
|
||
|
|
||
|
;-----------------------------------------------------------------------;
|
||
|
; CloseCachedFiles ;
|
||
|
; ;
|
||
|
; Close all the cached files on a duplicate PDB ;
|
||
|
; Leaves PDB set to new PDB ;
|
||
|
; ;
|
||
|
; Arguments: ;
|
||
|
; parmW pdb new PDB ;
|
||
|
; ;
|
||
|
; Returns: ;
|
||
|
; ;
|
||
|
; Error Returns: ;
|
||
|
; ;
|
||
|
; Registers Preserved: ;
|
||
|
; ;
|
||
|
; Registers Destroyed: ;
|
||
|
; ;
|
||
|
; Calls: ;
|
||
|
; real_DOS ;
|
||
|
; ;
|
||
|
; History: ;
|
||
|
; ;
|
||
|
;-----------------------------------------------------------------------;
|
||
|
|
||
|
assumes ds, nothing
|
||
|
assumes es, nothing
|
||
|
|
||
|
cProc CloseCachedFiles,<PUBLIC,FAR>,<ax,bx,cx,di,ds>
|
||
|
parmW pdb
|
||
|
cBegin
|
||
|
SetKernelDS
|
||
|
mov bx, pdb
|
||
|
mov Win_PDB, bx
|
||
|
;;; mov ah, 50h
|
||
|
;;; call real_DOS ; Run on the new guy
|
||
|
|
||
|
mov dx, bx
|
||
|
mov cx, fhCacheLen
|
||
|
mov di, dataOffset fhCache
|
||
|
ccf_search:
|
||
|
mov bx, [di.Cachefh]
|
||
|
or bx, bx
|
||
|
je ccf_next
|
||
|
mov ah, 3Eh ; Close the file
|
||
|
call real_DOS
|
||
|
|
||
|
cmp dx,topPDB ; If closing cached files on
|
||
|
jne ccf_next ; the kernel's PDB, mark the
|
||
|
xor ax,ax ; cache entry as free
|
||
|
mov [di.Cachefh], ax
|
||
|
mov [di.CacheExe], ax
|
||
|
|
||
|
ccf_next:
|
||
|
add di, size fhCacheStruc
|
||
|
loop ccf_search
|
||
|
|
||
|
cEnd
|
||
|
|
||
|
sEnd CODE
|
||
|
|
||
|
end
|