summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/kernel31/miscapi.asm
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/kernel31/miscapi.asm')
-rw-r--r--private/mvdm/wow16/kernel31/miscapi.asm569
1 files changed, 569 insertions, 0 deletions
diff --git a/private/mvdm/wow16/kernel31/miscapi.asm b/private/mvdm/wow16/kernel31/miscapi.asm
new file mode 100644
index 000000000..d96dfdf2a
--- /dev/null
+++ b/private/mvdm/wow16/kernel31/miscapi.asm
@@ -0,0 +1,569 @@
+
+
+.xlist
+include kernel.inc
+include pdb.inc
+include tdb.inc
+include newexe.inc
+include eems.inc
+.list
+
+externFP GlobalDOSAlloc
+externFP GlobalDOSFree
+externFP GetProfileString
+
+DataBegin
+
+externB kernel_flags
+externW MyCSAlias
+externW curTDB
+externW headTDB
+if 0 ; EarleH
+externW LastCriticalError
+endif
+externW LastExtendedError
+
+externD FatalExitProc
+
+if ROM
+externD PrevInt21Proc
+endif
+
+DataEnd
+
+sBegin CODE
+assumes CS,CODE
+assumes ds, nothing
+assumes es, nothing
+
+ife ROM
+externD PrevInt21Proc
+endif
+
+externNP SetOwner
+
+;-----------------------------------------------------------------------;
+; A20Proc ;
+; Enable / Disable the A20 line by calling an XMS driver ;
+; ;
+; Arguments: ;
+; ;
+; Returns: ;
+; ;
+; Error Returns: ;
+; ;
+; Registers Preserved: ;
+; ;
+; Registers Destroyed: ;
+; ;
+; Calls: ;
+; ;
+; History: ;
+; ;
+; Thu Mar 31, 1988 -by- Tony Gosling ;
+; ;
+;-----------------------------------------------------------------------;
+
+ assumes ds, nothing
+ assumes es, nothing
+
+cProc A20Proc,<PUBLIC,FAR>,<si,di>
+ parmW enable
+cBegin
+cEnd
+
+
+;**
+;
+; NETBIOSCALL -- Issue an INT 5C for caller
+;
+; This call is provided as a Kernel service to applications that
+; wish to issue NETBIOS INT 5Ch calls WITHOUT coding an INT 5Ch, which
+; is incompatible with protected mode.
+;
+; ENTRY:
+; All registers as for INT 5Ch
+;
+; EXIT:
+; All registers as for particular INT 5Ch call
+;
+; USES:
+; As per INT 5Ch call
+;
+;
+cProc NETBIOSCALL,<PUBLIC,FAR>
+cBegin
+ int 5Ch
+cEnd
+
+
+;**
+;
+; SetHandleCount -- Set the handle count in the PDB
+;
+; Sets the per process handle count to a new value
+; and allocates space for these file handles
+;
+; ENTRY:
+; nFiles - new number of file handles required
+;
+; EXIT:
+; returns new number of file handles
+;
+; USES:
+; C call
+;
+;
+cProc ISetHandleCount,<PUBLIC,FAR>,<di,si>
+ parmW nFiles
+cBegin
+ SetKernelDS
+ mov si, CurTDB
+ mov ds, si
+ UnSetKernelDS
+ mov ds, ds:[TDB_PDB]
+
+ ;** We allow no more than 255. Also, if something smaller than what
+ ;** we have, we just do nothing and respond with the number we
+ ;** already have.
+ mov ax, ds:[PDB_JFN_Length] ; How many now
+ cmp nFiles,255 ;Validate the parameter
+ jbe SHC_OK ;Parm OK
+
+IF KDEBUG
+ push ax
+ kerror ERR_PARAMETER,<SetHandleCount: Too many files requested:>,nFiles,0
+ pop ax
+ENDIF
+ mov nFiles,255 ;Force it to do no more than 255
+SHC_OK: mov bx, nFiles
+ cmp ax, bx ; Don't want more?
+ jae no_change
+
+ ;** Allocate memory for a new file handle table
+ add bx, 2
+ cCall GlobalDOSAlloc, <0, bx>
+ or ax, ax
+ jnz ok_we_got_it
+ mov ax, ds:[PDB_JFN_Length] ; Return original number
+ jmp SHORT no_change
+ok_we_got_it:
+
+ ;** Prepare the new table and update the PDB for the new table
+ cCall SetOwner,<ax,si> ;Hide it from GlobalFreeAll
+ mov es, ax ;Point to new table with ES
+ mov WORD PTR ds:[PDB_JFN_Pointer][2], dx ;Save seg address
+ xor di, di
+ mov si, word ptr ds:[PDB_JFN_Pointer] ;Offset of old table
+ mov cx, ds:[PDB_JFN_Length] ;Bytes to copy (one byte per handle)
+ mov WORD PTR ds:[PDB_JFN_Pointer][0], di ;Save new offset
+ mov bx, nFiles ;Save new number of files
+ mov ds:[PDB_JFN_Length], bx
+ push ds ;Save PDB selector for later
+
+ ;** We use the PDB selector to copy if we're copying the original
+ ;** table which is always in the PDB. Note that we only have a
+ ;** non-zero offset if the table is in the PDB. We can't save
+ ;** the selector in the table in this case until AFTER
+ or si, si ;Table in PDB?
+ jnz @F ;Yes
+ mov ds, WORD PTR ds:[PDB_JFN_Table] ;Get old selector to copy from
+@@:
+
+ ;** Copy the existing table into the new one
+ cld
+ rep movsb ;Copy existing files
+ mov al, -1
+ mov cx, nFiles
+ sub cx, di
+ rep stosb ;Pad new files with -1
+ mov ax, ds
+ pop bx ;Retrieve PDB selector
+ mov ds, bx
+ mov WORD PTR ds:[PDB_JFN_Table], es ;Save new selector
+
+ ;** We only free the old table if it wasn't in the PDB
+ cmp ax, bx ;Were we using the PDB selector?
+ je SHC_OldTableInPDB ;Yes. Don't free it
+ cCall GlobalDOSFree, <ax> ;Free old table
+SHC_OldTableInPDB:
+
+ mov ax, nFiles
+no_change:
+cEnd
+
+;-----------------------------------------------------------------------;
+; GetSetKernelDOSProc ;
+; Set the address kernel calls for DOS ;
+; ;
+; Arguments: ;
+; ;
+; Returns: ;
+; ;
+; Error Returns: ;
+; ;
+; Registers Preserved: ;
+; ;
+; Registers Destroyed: ;
+; ;
+; Calls: ;
+; ;
+; History: ;
+; ;
+; Fri Dec 31, 1990 -by- Tony Gosling ;
+; ;
+;-----------------------------------------------------------------------;
+
+ assumes ds, nothing
+ assumes es, nothing
+
+cProc GetSetKernelDOSProc,<PUBLIC,FAR>
+ parmD NewProc
+cBegin
+ SetKernelDS
+ife ROM
+ mov ds, MyCSAlias
+ assumes ds, CODE
+endif
+ mov ax, word ptr NewProc[0]
+ xchg ax, word ptr PrevInt21Proc[0]
+ mov dx, word ptr NewProc[2]
+ xchg dx, word ptr PrevInt21Proc[2]
+cEnd
+
+
+;-----------------------------------------------------------------------;
+; FatalExitHook ;
+; Hooks FatalExit ;
+; ;
+; Arguments: ;
+; ;
+; Returns: ;
+; ;
+; Error Returns: ;
+; ;
+; Registers Preserved: ;
+; ;
+; Registers Destroyed: ;
+; ;
+; Calls: ;
+; ;
+; History: ;
+; ;
+; Fri Dec 31, 1990 -by- Tony Gosling ;
+; ;
+;-----------------------------------------------------------------------;
+
+ assumes ds, nothing
+ assumes es, nothing
+
+cProc FatalExitHook,<PUBLIC,FAR>
+ parmD NewProc
+cBegin
+ SetKernelDS
+ mov ax, word ptr NewProc[0]
+ xchg ax, word ptr FatalExitProc[0]
+ mov dx, word ptr NewProc[2]
+ xchg dx, word ptr FatalExitProc[2]
+cEnd
+
+if 0 ; EarleH
+
+;-----------------------------------------------------------------------;
+; GetLastCriticalError ;
+; Get the last int 24h error and extended error code ;
+; ;
+; Arguments: ;
+; ;
+; Returns: ;
+; ;
+; Error Returns: ;
+; ;
+; Registers Preserved: ;
+; ;
+; Registers Destroyed: ;
+; ;
+; Calls: ;
+; ;
+; History: ;
+; ;
+; Fri Dec 31, 1990 -by- Tony Gosling ;
+; ;
+;-----------------------------------------------------------------------;
+
+ assumes ds, nothing
+ assumes es, nothing
+
+cProc GetLastCriticalError,<PUBLIC,FAR>
+cBegin
+ SetKernelDS
+ mov ax, -1
+ mov dx, ax
+ xchg ax, LastExtendedError
+ xchg dx, LastCriticalError
+cEnd
+endif ;0
+
+;-----------------------------------------------------------------------;
+; DWORD GetAppCompatFlags(HTASK hTask) ;
+; ;
+; Returns win.ini [Compatibility] flags for hTask (or current task ;
+; if hTask is NULL). ;
+; ;
+; Arguments: ;
+; ;
+; Returns: ;
+; ;
+; Error Returns: ;
+; ;
+; Registers Preserved: ;
+; ;
+; All but DX:AX ;
+; ;
+; Registers Destroyed: ;
+; ;
+; DX, AX ;
+; ;
+; Calls: ;
+; ;
+; History: ;
+; ;
+;-----------------------------------------------------------------------;
+
+ assumes ds, nothing
+ assumes es, nothing
+
+cProc GetAppCompatFlags,<PUBLIC,FAR>,<DS>
+parmW hTask
+cBegin
+ SetKernelDS
+ mov ax,hTask
+ or ax,ax
+ jnz got_tdb
+ mov ax,curTDB ; If no current task (e.g., during boot)
+ cwd ; just return 0L.
+ or ax,ax
+ jz gacf_exit
+got_tdb:
+ mov ds,ax
+ UnSetKernelDS
+ mov ax,ds:[TDB_CompatFlags]
+ mov dx,ds:[TDB_CompatFlags2]
+gacf_exit:
+ UnSetKernelDS
+cEnd
+
+; Simpler (faster) NEAR version for Kernel -- only works for current task!
+;
+; Preserves all regs except dx:ax
+;
+cProc MyGetAppCompatFlags,<PUBLIC,NEAR>
+cBegin nogen
+ push ds
+ SetKernelDS
+
+ mov ax, curTDB
+ cwd
+ or ax, ax ; No current task while booting
+ jz mygacf_exit
+
+ mov ds, ax
+ UnSetKernelDS
+ mov ax, ds:[TDB_CompatFlags]
+ mov dx, ds:[TDB_CompatFlags2]
+
+mygacf_exit:
+ pop ds
+ UnSetKernelDS
+ ret
+
+cEnd nogen
+
+ifdef WOW
+cProc MyGetAppWOWCompatFlags,<PUBLIC,NEAR>
+cBegin nogen
+ push ds
+ SetKernelDS
+
+ mov ax, curTDB
+ cwd
+ or ax, ax ; No current task while booting
+ jz wow_mygacf_exit
+
+ mov ds, ax
+ UnSetKernelDS
+ mov ax, ds:[TDB_WOWCompatFlags]
+ mov dx, ds:[TDB_WOWCompatFlags2]
+
+wow_mygacf_exit:
+ pop ds
+ UnSetKernelDS
+ ret
+
+cEnd nogen
+
+;
+; Returns WOW extended compatiblity flags
+;
+; Preserves all regs except dx:ax
+;
+cProc MyGetAppWOWCompatFlagsEx,<PUBLIC,FAR>
+cBegin nogen
+ push ds
+ SetKernelDS
+
+ mov ax, curTDB
+ cwd
+ or ax, ax ; No current task while booting
+ jz wow_mygacfex_exit
+
+ mov ds, ax
+ UnSetKernelDS
+ mov ax, ds:[TDB_WOWCompatFlagsEx]
+ mov dx, ds:[TDB_WOWCompatFlagsEx2]
+
+wow_mygacfex_exit:
+ pop ds
+ UnSetKernelDS
+ retf
+
+cEnd nogen
+
+
+;---------------------------------------------------------------------------
+; This gets called from FreeProcInstance. If the proc being freed is an
+; AbortProc that was set by the app, we reset it to NULL. This way we dont
+; callback to a proc that's garbage.
+;
+; This case happens with Aldus Pagemaker ver 5.0 when one prints to EPS file.
+; The app sets the AbortProc and then later calls freeprocinstance.
+; Subsequently when it make the call Escape(..OPENCHANNEL..) the callback
+; occurs and we die randomly.
+;
+; This solution is a general solution.
+; - Nanduri
+;---------------------------------------------------------------------------
+
+cProc HandleAbortProc, <PUBLIC,FAR>, <ds, ax>
+ ParmD pproc
+cBegin
+ SetKernelDS
+
+ mov ax, curTDB
+ or ax, ax ; No current task while booting
+ jz wow_aproc_exit
+
+ mov ds, ax
+ UnSetKernelDS
+ mov ax, ds:[TDB_vpfnAbortProc+2]
+ or ax, ax
+ je wow_aproc_exit ; sel = 0 - no abort proc. done
+ cmp ax, word ptr [pproc+2]
+ jnz wow_aproc_exit ; selectors don't match
+ mov ax, ds:[TDB_vpfnAbortProc]
+ cmp ax, word ptr [pproc]
+ jnz wow_aproc_exit ; offsets don't match
+
+ mov ds:[TDB_vpfnAbortProc], 0 ; set abort proc to NULL.
+ mov ds:[TDB_vpfnAbortProc+2], 0
+wow_aproc_exit:
+ UnSetKernelDS
+cEnd
+
+endif ; WOW
+
+sEnd CODE
+
+sBegin NRESCODE
+assumes CS,NRESCODE
+
+CompatSection DB 'Compatibility'
+DefVal DB 0
+
+cProc SetAppCompatFlags, <PUBLIC, NEAR>, <ds, es, si, di>
+ localV szHex,12 ; read string to here
+ localV key, <SIZE TDB_Modname + 2> ; ModName of loading app
+cBegin
+ xor ax, ax
+ cwd
+ cmp es:[TDB_ExpWinVer], 30Ah ; Hacks don't apply to 3.1 or above
+ jae sa_exit
+
+ push es ; Copy ModName to zero-terminate it
+ pop ds
+ lea si, es:[TDB_ModName]
+ push ss
+ pop es
+ lea di, key
+ mov cx, SIZE TDB_Modname
+ cld
+ rep movsb
+ stosb
+
+ push cs
+ push NREScodeoffset CompatSection
+
+ push ss
+ lea ax, key
+ push ax
+
+ push cs
+ push NREScodeoffset DefVal
+
+ push ss
+ lea ax, szHex
+ push ax
+
+ push 12
+
+ call GetProfileString
+ cwd
+ or ax, ax
+ jz sa_exit
+ xor dx,dx ; zero our value in dx:bx
+ xor bx,bx
+ push ss
+ pop ds
+ lea si, szHex
+
+ lodsw ; String starts with '0x'
+ and ah, not 20h
+ cmp ax, 'X0'
+ jnz sa_done
+sa_again:
+ lodsb
+ sub al, '0'
+ jc sa_done
+ cmp al, '9'-'0'
+ jbe @F
+ add al, '0'-'A'+10 ; map 'A'..F' to 10..15
+ ; (lower case guys are 0x20 apart!)
+@@:
+ add bx,bx ; value << 4;
+ adc dx,dx
+ add bx,bx
+ adc dx,dx
+ add bx,bx
+ adc dx,dx
+ add bx,bx
+ adc dx,dx
+
+ and al,0fh ; value |= (al & 0x0f);
+ or bl,al
+ jmps sa_again
+
+sa_done: ; DX:BX contains flags
+ mov ax, bx
+
+sa_exit: ; DX:AX contains flags, or 0x00000000
+cEnd
+
+
+cProc ValidateCodeSegments,<PUBLIC,FAR>
+cBegin nogen
+ ret
+cEnd nogen
+
+sEnd NRESCODE
+
+end