windows-nt/Source/XPSP1/NT/base/mvdm/wow16/kernel31/ldcache.asm
2020-09-26 16:20:57 +08:00

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