|
|
.xlist include kernel.inc include tdb.inc include pdb.inc include kdos.inc include eems.inc include protect.inc ifdef WOW include vint.inc endif .list
externFP LoadLibrary externFP LoadModule externFP GlobalFree, externFP GlobalFreeAll externFP GlobalCompact externFP FreeModule externFP GlobalDOSFree externFP FreeSelector externFP GetProcAddress ; WIN32S externFP ISetErrorMode ; WIN32S externFP ISetHandleCount
externFP ExitKernelThunk externNP DPMIProc
extrn BUNNY_351:FAR
ifdef WOW DRIVE_REMOTE equ 4 externW headTDB externFP lstrlen externFP WOWSetIdleHook externFP GetDriveType externFP WowShutdownTimer externFP WowTrimWorkingSet externB fShutdownTimerStarted externW cur_drive_owner endif
externW pStackBot ;externW pStackMin externW pStackTop
DataBegin
externB Kernel_flags externB num_tasks externB Kernel_InDOS externB Kernel_InINT24
externB WOAName externB grab_name externB fBooting externB graphics externB fExitOnLastApp
externW cur_dos_PDB externW Win_PDB externW headPDB externW topPDB externW curTDB externW curDTA externW PHTcount externW gmove_stack externW MyCSSeg externW wExitingTDB externD lpSystemDir
if KDEBUG externW allocTask endif
if ROM externD prevInt21Proc endif
externD lpint21 externD pExitProc if PMODE32 externD pDisplayCritSec externW PagingFlags externD lpReboot endif
ifdef FE_SB ifndef KOREA externD pJpnSysProc endif endif
DataEnd
sBegin DATA externW gmove_stack
ifdef PMODE32 ifndef WOW WIN32S = 1 ; enable code for Win32S support endif endif
ifdef WIN32S ; Win32S support selExecPE DW 0 offExecPE DW 0 endif
sEnd DATA
assumes DS,NOTHING sBegin CODE assumes CS,CODE
ife ROM externD prevInt21Proc endif
externNP Real_DOS externNP PathDrvDSDX externNP SetErrorDrvDSDX externNP SetCarryRet externNP ExitSchedule externNP UnlinkObject externNP final_call_for_DOS
externNP cmp_sel_address externNP free_sel externNP SegToSelector
if SDEBUG externNP DebugExitCall endif externNP DeleteTask
;-----------------------------------------------------------------------; ; Set_DTA (DOS Call 1Ah) ; ; ; ; Simply records on a task basis the DTA. ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Sat Jan 10, 1987 09:19:36p -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc Set_DTA,<PUBLIC,NEAR> cBegin nogen push es SetKernelDS es mov curDTA.off,dx mov curDTA.sel,ds mov es,curTDB UnSetKernelDS es cmp es:[TDB_sig],TDB_SIGNATURE jne Set_DTA_noTDB mov es:[TDB_DTA].off,dx mov es:[TDB_DTA].sel,ds Set_DTA_noTDB: pop es jmp final_call_for_DOS cEnd nogen
;-----------------------------------------------------------------------; ; SaveRegs ; ; ; ; Does what it says. ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Fri Jan 16, 1987 09:57:49p -by- David N. Weise [davidw] ; ; Added this nifty comment block. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc SaveRegs,<PUBLIC,NEAR> cBegin nogen
xchg dx, user_DX ; Return address in DX push es push bx push ax push cx push si push di and USER_FL,11111110b ; clc flag push dx mov dx, user_DX ; Rescue DX for what it's worth cld
ret cEnd nogen
;-----------------------------------------------------------------------; ; RestoreRegs ; ; ; ; Does what it says and (used to cli). ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Fri Jan 16, 1987 10:00:41p -by- David N. Weise [davidw] ; ; Added this nifty comment block. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc RestoreRegs,<PUBLIC,NEAR> cBegin nogen
pop di ; Return address xchg di, user_BP ; Insert for ret later, get saved BP mov bp, di dec bp pop di pop si pop cx pop ax pop bx pop es pop dx pop ds ret ; SP points to user_BP cEnd nogen
;-----------------------------------------------------------------------; ; ; ; Handle the Int21 func 67 call "Set Maximum Handle Count" ; ; ; ;-----------------------------------------------------------------------;
cProc SetMaxHandleCount,<PUBLIC,NEAR> cBegin nogen pop ds pop bp ; clean up stack dec bp
cmp bx, 255 ja smhc_err1
push bx push cx push dx
cCall ISetHandleCount,<bx> pop dx pop cx pop bx
cmp ax, bx ; did we get everything? jne smhc_err2 clc jmp smhcexit
smhc_err1: mov ax,4 ; too many open files stc ; set carry flag jmp smhcexit
smhc_err2: mov ax,8 ; not enough memory stc ; set carry flag smhcexit: STIRET ret
cEnd nogen
;-----------------------------------------------------------------------; ; Set_Vector (DOS Call 25h) ; ; Get_Vector (DOS Call 35h) ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Sat Jan 17, 1987 01:48:29a -by- David N. Weise [davidw] ; ; Added this nifty comment block. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc Set_Vector,<PUBLIC,NEAR> cBegin nogen push di push es call IsItIntercepted jnz notintercepted SetKernelDS es mov es, CurTDB ; We intercepted it, change UnSetKernelDS es ; vector in the TDB mov es:[di].off, dx mov es:[di].sel, ds jmps sv_done ; And just return notintercepted: SetKernelDS es cmp fBooting,1 jz sv_no_restrictions cmp graphics,0 ; in the stand alone OS/2 box? jz @F ;ifdef JAPAN ifdef NOT_USE_BY_NT_JAPANESE push ax push bx ; 04/23/91 -yukini mov bx,0 cCall [pJpnSysProc], <bx,ax> ; call System.JapanInquireSystem to ; get vector can be modified or not. test ax,ax pop bx pop ax jz sv_done ; jump if cannot be modified else cmp al,1Bh jz sv_done cmp al,1Ch jz sv_done endif @@: cmp al,21h ; trying to reset our traps? jz sv_done cmp al,24h ; trying to reset our traps? jz sv_done cmp al,2fh ; setting idle detect vector? jnz sv_no_restrictions ; no, proceed normally push ax push dx push ds cCall WOWSetIdleHook ; set the real hook back in Win32 pop ds pop dx pop ax jmp bodacious_cowboys sv_no_restrictions: cmp al,21h jnz bodacious_cowboys mov lpint21.off,dx mov lpint21.sel,ds bodacious_cowboys: call real_DOS
sv_done: pop es pop di pop ds pop bp ; clean up stack dec bp STIRET
cEnd nogen
assumes ds, nothing assumes es, nothing
cProc Get_Vector,<PUBLIC,NEAR> cBegin nogen pop ds pop bp ; clean up stack dec bp push di call IsItIntercepted jnz notintercepted1 push ds ; We intercepted it, get the SetKernelDS ; vector from the TDB mov ds, CurTDB UnSetKernelDS mov bx, [di] mov es, [di+2] pop ds pop di jmps gv_done notintercepted1: pop di call real_DOS gv_done: STIRET
cEnd nogen
cProc IsItIntercepted,<PUBLIC,NEAR> cBegin nogen mov di, TDB_INTVECS cmp al, 00h je yes_intercepted add di, 4 cmp al, 02h je yes_intercepted add di, 4 cmp al, 04h je yes_intercepted add di, 4 cmp al, 06h je yes_intercepted add di, 4 cmp al, 07h je yes_intercepted add di, 4 cmp al, 3Eh je yes_intercepted add di, 4 cmp al, 75h yes_intercepted: ret cEnd nogen
;-----------------------------------------------------------------------; ; ExecCall (DOS Call 4Bh) ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ; ; Added support for long command lines to WinOldApp. ; ; ; ; Sat Jan 17, 1987 01:39:44a -by- David N. Weise [davidw] ; ; Added this nifty comment block. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc ExecCall,<PUBLIC,NEAR> cBegin nogen call PathDrvDSDX ; Check drive jnc EC1 ; Drive OK call SetErrorDrvDSDX ; Set up errors jmp SetCarryRet ; Error
EC1: call SaveRegs call far ptr FarExecCall call RestoreRegs STIRET cEnd nogen
;-----------------------------------------------------------------------; ; TerminatePDB ; ; ; ; It calls DOS to terminate the current task. ; ; ; ; Arguments: ; ; DI = exit code ; ; Returns: ; ; nothing ; ; Error Returns: ; ; nothing ; ; Registers Preserved: ; ; none ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc TerminatePDB,<PUBLIC,NEAR> cBegin nogen
SetKernelDS ES mov bx, ds ; DS is PDB being terminated cmp cur_dos_PDB, bx ; Ensure DOS/anyone on the je short @F ; int 21h chain has correct PDB mov ah, 50h pushf call prevInt21Proc @@: mov ax, ds:[PDB_Parent_PID] ; Parent PDB mov Win_PDB, ax ; These will be changed by DOS mov cur_dos_PDB, ax
or Kernel_Flags[2],KF2_WIN_EXIT mov ax,di ; AL = exit code mov ah, 0 ; Alternative exit for PMODE which returns call real_DOS ; let DOS clean up UnSetKernelDS es
errn$ DosExitReturn
cEnd nogen
; ; The DOS terminate call above will return to ; the following label, DosExitReturn. This is ; a separate procedure in order to be declared FAR. ; assumes ds, nothing assumes es, nothing
cProc DosExitReturn,<PUBLIC,FAR> cBegin nogen
SetKernelDS ES mov Kernel_InDOS,0 mov Kernel_InINT24,0 and Kernel_Flags[2],NOT KF2_WIN_EXIT retn
cEnd nogen
;-----------------------------------------------------------------------; ; ExitCall (DOS Call 4Ch) ; ; ; ; It terminates the current task. ; ; ; ; Arguments: ; ; AL = exit code ; ; Returns: ; ; nothing ; ; Error Returns: ; ; nothing ; ; Registers Preserved: ; ; none ; ; Registers Destroyed: ; ; none ; ; Calls: ; ; TerminatePDB ; ; GlobalFreeAll ; ; UnlinkObject ; ; DeleteTask ; ; GlobalFree ; ; FreeModule ; ; History: ; ; ; ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ; ; Removed WinOldApp support. ; ; ; ; Sun Apr 26, 1987 03:20:05p -by- David N. Weise [davidw] ; ; Made it switch stacks to the temp_stack because of EMS. ; ; ; ; Mon Sep 29, 1986 04:06:08p -by- Charles Whitmer [chuckwh] ; ; Made it kill all threads in the current process. ; ; ; ; Mon Sep 29, 1986 03:27:12p -by- Charles Whitmer [chuckwh] ; ; Made it call UnlinkObject rather than do the work inline. ; ; ; ; Mon Sep 29, 1986 09:22:08a -by- Charles Whitmer [chuckwh] ; ; Documented it. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc ExitCall,<PUBLIC,NEAR> cBegin nogen
ifdef WOW ; Set to a Known DIR so that if an app was running over the network ; the user can disconnect once the app terminates. ; This also allows a subdirectory to be removed after a Win16 app ; had that dir as the current dir, but was terminated.
SetKernelDS
push ax push si push dx push ds
lds si,lpSystemDir ; ds:si points to system directory mov dl,[si] ; put drive letter into AL add dl,-65 ; subtract 'A' to get drive number mov ah,0Eh call real_DOS ; select disk
add si,2 ; let SI point to the first '\' past d:
mov al,[si + 1] ; save first character after '\' push ax
mov byte ptr [si + 1],0 ; null-terminate string after root dir mov dx,si mov ah,3Bh call real_DOS ; select directory
pop ax mov [si + 1],al ; restore string to its original state ; ; During task exit/abort ntdos $abort notifies the debugger of the ; "module unload" of the EXE using the full path to the EXE that ; follows the environment block. We don't want ntdos to make the ; module unload callout because we do it ourself during our ; DelModule of the EXE module. So we have a protocol, we zero ; the environment selector in our PDB, DPMI translates this to ; segment zero properly, and ntdos skips the callout if the environment ; segment is zero. ; pop ds ReSetKernelDS mov es,[curTDB] ; DS = current TDB mov es, es:[TDB_PDB] xor ax,ax mov word ptr es:[PDB_environ], ax
pop dx pop si pop ax endif
if SDEBUG ;** Save the TDB of the currently exiting task. We check for this ;** in DebugWrite so that we don't get recursive ;** debug strings at task exit time. This is a gross hack ;** for QCWin and their numerous param validation errors. mov bx,curTDB ;Get current task handle mov wExitingTDB,bx ;Save as exiting TDB cCall DebugExitCall ;Passes exit code in AL endif ; SDEBUG
if PMODE32 .386 smov fs, 0 smov gs, 0 .286p
xchg di,ax ; DI = exit code
cmp graphics,1 ; is there a display driver around? jnz @F mov ax,1 ifndef WOW ; WOW doesn't have a display dirver to call cCall pDisplayCritSec,<ax> ; tell display driver to shut up endif or Kernel_Flags[2],KF2_WIN386CRAZINESS @@: mov ds,curTDB ; DS = current TDB assumes ds,nothing else xchg di,ax ; DI = exit code mov ds,curTDB ; DS = current TDB UnSetKernelDS endif
; We may have gotten here due to stack checking. Let's make sure ; that we are on a stack we can deal with.
test ds:[TDB_flags],TDBF_OS2APP jz @F mov ax,sp mov ss:[pStackBot],ax @@: xor ax,ax mov ss:[pStackTop],ax
; remove the PDB from the chain
mov es,ds:[TDB_PDB] mov dx,PDB_Chain mov bx,dataOffset HeadPDB call UnlinkObject
xor si,si ; source of zero
; Dec total # of tasks, if last task in system, then quit Windows completely.
smov es,ds assumes es,nothing SetKernelDS ifdef WOW cmp fExitOnLastApp,0 ; Quit WOW when the last app dies ? jz @f
cmp num_tasks,2 ; Last Task (ingnoring WOWEXEC) ? jz last_task @@: endif dec num_tasks jnz not_the_last_task
last_task: IF PMODE32 ;** Unhook local reboot VxD stuff cmp WORD PTR lpReboot[2], 0 ;Reboot handler installed? je @F ;No push es mov ax, 0201h ;Reboot VxD #201: Set callback addr xor di, di ;Zero CS means no SYS VM local mov es, di call [lpReboot] ; reboot handler pop es @@: ENDIF
call BUNNY_351
ifndef WOW ; For WOW ex just want to get out of here - no need to call USER16 or GDI16 cCall pExitProc,<si,si> ; this does not return endif cCall ExitKernelThunk,<si>
assumes es, nothing not_the_last_task:
; Signal( hTask, SG_EXIT, ExitCode, 0, Queue ) if we have a user signal proc
push es cmp es:[si].TDB_USignalProc.sel,si jz no_signal_proc mov bx,SG_EXIT cCall es:[si].TDB_USignalProc,<es,bx,di,es:[si].TDB_Module,es:[si].TDB_Queue> no_signal_proc:
pop es
mov bl,6 DPMICALL 0202h ; DPMI get exception handler vector push cx push dx
mov cx,cs lea dx,exit_call_guts mov bl,6 DPMICALL 0203h ; DPMI set exception handler vector
pop dx pop cx ; ; Generate an invalid opcode exception fault. This causes DPMI to call ; our "exception handler." ; db 0fh,0ffh exit_call_guts: FSTI ; we're called with ints disabled mov bp,sp ; BP -> RETIP RETCS EC IP CS FL SP SS ; ; Restore the previous invalid exception handler vector. ; mov bl,6 DPMICALL 0203h ; ; Point the return stack at Kernel's temporary stack. ; mov ax,dataOffset gmove_stack mov [bp+12],ax mov ax,seg gmove_stack mov [bp+14],ax ; ; Replace the return address on the DPMI fault handler routine with ; our exit code. ; lea ax,ExitSchedule mov [bp+6],ax mov [bp+8],cs
push es
cCall GlobalFreeAll,<si> ; free up all task data pop es
; Remove from queue.
push es cCall DeleteTask,<es> pop es mov ds,es:[TDB_PDB] ; DS = current PDB
UnsetKernelDS ; DS is PDB to terminate
call TerminatePDB ; Call DOS to close down files etc.
ReSetKernelDS ES ; TerminatePDB returned with ES set
xor bp,bp ; set up valid frame mov ds,curTDB
; If this task has a PHT, decrement the PHT count and clear the pointer ; and zap the PHT pointer so we don't look at it anymore. ; NOTE - BP contains a convenient zero.
mov ax,ds:[TDB_PHT].sel or ax,ds:[TDB_PHT].off jz no_PHT mov ds:[TDB_PHT].sel,bp mov ds:[TDB_PHT].off,bp dec PHTcount ; dec # tasks with PHT's no_PHT: UnSetKernelDS es cCall FreeModule,<ds:[TDB_Module]> ; Free the module for this task xor ax,ax mov ds:[TDB_sig],ax ; Mark TDB as invalid
;** Nuke any JFN that is outside the PDB. We can tell that the ;** JFN points outside the PDB if the offset is zero. PDB ;** JFN's never have a zero offset and outside ones always do. push ds mov ds, ds:[TDB_PDB] cmp WORD PTR ds:[PDB_JFN_Pointer][0], 0 ;JFN pointer into PDB? jne EC_NoFreeJFN ;Yes, don't free anything push WORD PTR ds:[PDB_JFN_Table] ;Get our selector call GlobalDOSFree EC_NoFreeJFN:
SetKernelDS cmp num_tasks,1 ; Last task? (except wowexec) jne @f ; branch if not last task if 0 ; This code is unneeded because if we're a separate VDM, we exit above when ; the last task exited. cmp fExitOnLastApp, 0 ; Shared WOW? jne @F ; branch if not shared WOW endif
cCall WowShutdownTimer, <1> ; start shutdown timer mov fShutdownTimerStarted, 1 cCall GlobalCompact,<-1, -1> ; free up as many pages as possible cCall WowTrimWorkingSet ; trim working set to minimum @@: mov bx, topPDB mov Win_PDB, bx mov cur_dos_PDB, bx mov ah, 50h pushf call prevInt21Proc ; Set PDB to KERNEL's pop ds UnSetKernelDS xchg bx, ds:[TDB_PDB] cCall free_sel,<bx> ; Free the PDB selector
call far ptr FreeTDB ; Tosses PDB's memory SetKernelDS ifndef WOW mov curTDB,0 ; We can use this, setting curTDB = 0 else ;; We do this a little later - see tasking.asm exitschedule endif if PMODE32 ; in rmode as well in the next rev or PagingFlags, 8 ; to save a few bytes. endif
;** Task has been nuked. Clear the DebugWrite task exiting flag mov wExitingTDB,0
; fix current drive owner mov ax, cur_drive_owner cmp ax, curTDB jnz @f ; so it is the owner of a current drive -- nuke it mov cur_drive_owner, 0 @@:
if 0 ; We could call this on every task exit -- need to see if ; it slows down Winstone 94, if it's needed after we use MEM_RESET ; If you enable this call, disable the similar call just above. cCall WowTrimWorkingSet ; trim working set to minimum endif
retf ; To ExitSchedule cEnd nogen
assumes ds, nothing assumes es, nothing
cProc FreeTDB, <PUBLIC,FAR> cBegin nogen
cCall FreeSelector,<ds:[TDB_MPI_Sel]> mov ax,ds if KDEBUG ; ; If we're freeing the alloc break task, zero out the global. ; SetKernelDS cmp ax,allocTask jnz @F mov allocTask,0 @@: UnSetKernelDS endif smov ds,0 cCall GlobalDOSFree,<ax> ret
cEnd nogen
;-----------------------------------------------------------------------; ; set_PDB (DOS Call 50h) ; ; ; ; This is an undocumented DOS call to set the current PDB. ; ; DOS does not check for ^C's on this call, in fact it never turns ; ; on the interrupts. ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Fri Jan 23, 1987 07:07:14p -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc set_PDB,<PUBLIC,NEAR> cBegin nogen SetKernelDS mov cur_dos_PDB,bx mov Win_PDB,bx mov ds,curTDB assumes ds,nothing mov ds:[TDB_PDB],bx call real_DOS pop ds pop bp ; clean up stack dec bp STIRET cEnd nogen
;-----------------------------------------------------------------------; ; get_PDB ; ; ; ; This is an undocumented DOS call to set the current PDB. ; ; DOS does not check for ^C's on this call, in fact it never turns ; ; on the interrupts. ; ; Trapping this is superfluous is real mode but necessary in protect ; ; mode since the DOS extender may not be doing the segment ; ; translation properly. ; ; ; ; Entry: ; ; ; ; Returns: ; ; ; ; Registers Destroyed: ; ; ; ; History: ; ; Tue 13-Jun-1989 18:22:16 -by- David N. Weise [davidw] ; ; Wrote it. ; ;-----------------------------------------------------------------------;
assumes ds,nothing assumes es,nothing
cProc get_PDB,<PUBLIC,NEAR> cBegin nogen SetKernelDS call real_DOS mov bx,cur_dos_PDB pop ds pop bp ; clean up stack dec bp STIRET cEnd nogen
sEnd code
sBegin NRESCODE assumes cs, NRESCODE assumes ds, nothing assumes es, nothing
externNP MapDStoDATA
;-----------------------------------------------------------------------; ; BuildPDB ; ; ; ; ; ; Arguments: ; ; ; ; Returns: ; ; ; ; Error Returns: ; ; ; ; Registers Preserved: ; ; ; ; Registers Destroyed: ; ; ; ; Calls: ; ; ; ; History: ; ; ; ; Thu 04-Jan-1990 20:15:27 -by- David N. Weise [davidw] ; ; Made it avoid closing cached files if the PDB being copied is not ; ; the topPDB. This is for supporting inheriting a parents files. ; ; ; ; Mon 11-Sep-1989 19:13:52 -by- David N. Weise [davidw] ; ; Removed returning validity in AX, and removed copying of FCBs. ; ; ; ; Mon 07-Aug-1989 23:39:59 -by- David N. Weise [davidw] ; ; Added support for long command lines to WinOldApp. ; ; ; ; Sun Jan 18, 1987 00:27:52a -by- David N. Weise [davidw] ; ; Added this nifty comment block. ; ;-----------------------------------------------------------------------;
assumes ds, nothing assumes es, nothing
cProc BuildPDB,<PUBLIC,FAR>,<si,di> ParmW oldPDB ParmW newPDB ParmD ParmBlock ParmW newSize ParmW fWOA cBegin call MapDStoDATA ReSetKernelDS
push Win_PDB ; Save current PDB
mov bx,oldPDB ; set current PDB for copy mov Win_PDB, bx
mov dx,newPDB mov si,newSize mov ah,55h ; duplicate PDB int 21h
mov bx, oldPDB mov dx, newPDB mov cur_dos_PDB, dx ; DOS call 55h sets the PDB to this
nothing_to_close:
pop Win_PDB ; restore former PDB
xor di,di
mov cx, MyCSSeg mov ds,dx UnSetKernelDS mov es,dx add si,dx mov ax,oldPDB mov [di].PDB_Parent_PID,ax ; parent = OldPDB mov [di].PDB_Block_Len,si
mov [di].PDB_Exit.off,codeOffset DosExitReturn mov [di].PDB_Exit.sel, cx
; No private global heap yet.
mov [di].PDB_GlobalHeap.lo,di mov [di].PDB_GlobalHeap.hi,di
; Set up proper command line stuff.
lds si,ParmBlock lds si,ds:[si].lpcmdline ; command line mov di,PDB_DEF_DTA mov cx,di cmp fWOA,0 jz @F ; Winoldap can have long command line mov cx,ds:[si] ; get byte count cld movsb ; copy count byte inc cx inc si @@: rep movsb ; Store command line.
cEnd
cProc FarExecCall,<PUBLIC,FAR> cBegin nogen
; Check if file extension is .COM, .BAT, .PIF, if so it needs emulation...
cld les di,User_DSDX
ifdef WOW ; ; Wow LoadModule handles all forms of exec including ; pe images, com, bat, pif files etc. ; lds si,User_ESBX regptr esdx,es,dx regptr dssi,ds,si cCall LoadModule,<esdx,dssi> cmp ax, LME_MAXERR ; check for error... jae ex8 jmp short ex7 ; no, return error
else
mov cx,-1 xor al,al repnz scasb ; scan to end of string neg cx dec cx ; cx has length (including null) mov ax,es:[di-5] or ah,20h mov bx,es:[di-3] ; complete check for .COM or bx,2020h ; convert to lower case
cmp ax,'c.' ; check for .COM file extension jnz ex1b ; no match...attempt load module cmp bx,'mo' jz ex4 ; yes! go immediatly to GO
ex1b: cmp ax,'b.' ; check for .BAT extension... jnz ex1c cmp bx,'ta' jz ex4
ex1c: cmp ax,'p.' ; check for .PIF extension... jnz ex2 cmp bx,'fi' jz ex4
ex2: lds si,User_ESBX regptr esdx,es,dx regptr dssi,ds,si push cx ; save length of string cCall LoadModule,<esdx,dssi> pop cx cmp ax, LME_MAXERR ; check for error... jb ex3 jmp ex8 ex3: cmp ax, LME_INVEXE ; wrong format? jz ex4 cmp ax, LME_EXETYPE ; quick basic app jz ex4
cmp ax, LME_PE ; Win32 PE format jz @F jmp ex7 ; no, return error @@:
ifdef WIN32S push cx ; Win32S support - (AviN) 11-19-91
lds si,User_DSDX push ds push si lds si,User_ESBX push ds:[si+4] ; CmdLine sel push ds:[si+2] ; offset
les bx, ds:[si+6] ; FCB1 push es:[bx+2] ; nCmdShow
call FAR PTR ExecPE pop cx
cmp ax, 32 jbe @F jmp ex8 @@: cmp ax, 11 ; NOT PE je @F jmp ex7
@@:
; end of Win32S support endif
ex4:
; Run an old application ; ; If we are running in the OS/2 3x box, we do not support running old ; apps. If someone trys this, put up a nasty message and return with ; an error. (Thu 12-Nov-1987 : bobgu)
mov dx,cx ; save length of file name sub sp,256 ; make room for command line smov es,ss mov di,sp lds si,User_ESBX lds si,ds:[si].lpcmdline xor ax,ax xor cx,cx mov cl,ds:[si] inc cx movsb stosb rep movsb mov cx,dx lds si,User_DSDX rep movsb mov byte ptr es:[di][-1],10 ; terminate with line feed mov di,sp add es:[di],dx
mov bx,es push ds call MapDStoDATA smov es, ds pop ds ReSetKernelDS es
test Kernel_flags[2],KF2_DOSX ; DOSX winoldap doesn't need special jnz @F ; special handling mov ax,dataOffset grab_name push bx push dx push es cCall LoadLibrary,<es,ax> pop es pop dx pop bx cmp ax,32 jae @F add sp, 256 ; undo damage to stack jmps ex7 @@:
or Kernel_flags[1],KF1_WINOLDAP lds si,User_ESBX mov ds:[si].lpcmdline.off,di mov ds:[si].lpcmdline.sel,bx mov dx,dataOffset WOAName regptr esdx,es,dx regptr dssi,ds,si cCall LoadModule,<esdx,dssi> assumes es, nothing add sp,256 cmp ax,32 ; check for error... jae ex8 cmp ax,2 ; file not found? jnz ex7 ; no, return error mov al,23 ; flag WINOLDAP error
;; ndef wow endif
ex7: or User_FL,1 ; set carry flag or ax,ax ; out of memory? jnz ex8 mov ax,8h ; yes, return proper error code ex8: mov User_AX,ax ; return AX value
ret cEnd nogen
ifdef WIN32S SZW32SYS db "W32SYS.DLL", 0 ExecPEOrd equ 3
;-----------------------------------------------------------------------; ; ExecPE ; Get ExecPE address in W32SYS.DLL, and call it ; 11-13-91 AviN created ;-----------------------------------------------------------------------;
cProc ExecPE,<PUBLIC,FAR> cBegin nogen push ds mov ax, SEG selExecPE mov ds, ax
assumes DS, DATA
mov dx, selExecPE ; check for a valid address or dx, dx jnz ep_x
mov ax, offExecPE or ax, ax jnz ep_err ; already failed, don't try again
cCall ISetErrorMode, <8000h> push ax
lea ax, SZW32SYS cCall LoadLibrary,<cs, ax>
pop dx push ax cCall ISetErrorMode,<dx> ; restore original error mode pop ax
cmp ax, 32 jbe ep_err
push ax push 0 push ExecPEOrd cCall GetProcAddress or dx,dx jz ep_err mov selExecPE, dx mov offExecPE, ax ep_x:
pop ax ; saved DS push selExecPE ; jmp to ExecPE push offExecPE mov ds, ax retf
ep_err: ; if w32sys support no available return mov ax, 11 ; invalid module format mov offExecPE, ax ; and record for next time
pop ds retf 10 ; pop ExecPE parameters
assumes DS,NOTHING cEnd nogen endif
sEnd NRESCODE
sBegin MISCCODE assumes cs, misccode assumes ds, nothing assumes es, nothing
externNP MISCMapDStoDATA
;-----------------------------------------------------------------------; ; ; ; Get the Current PDB without doing a DOS call. ; ; ; ;-----------------------------------------------------------------------;
cProc GetCurrentPDB,<PUBLIC,FAR> cBegin nogen push ds call MISCMapDStoDATA ReSetKernelDS mov dx,TopPDB mov ds,curTDB UnSetKernelDS mov ax,ds:[TDB_PDB] pop ds ret cEnd nogen
sEnd MISCCODE
end
|