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, parmW hExe parmW keepfh parmW fh cBegin cCall GetCachedFileHandle, cEnd cProc GetCachedFileHandle,, 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, 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,, 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,, 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,, 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