;       SCCSID = @(#)ptthunk.asm        6.3 91/11/13

TITLE   PTTHUNK - API and debugger support for DosPtrace

;**     PTTHUNK.ASM - API and debugger support for DosPtrace.
;
;       SCCSID = @(#)ptthunk.asm        6.3 91/11/13
;
;       THIS IS AN OS/2 VERSION 2.x SPECIFIC FILE
;
;       IBM/Microsoft Confidential
;
;       Copyright (c) IBM Corporation 1987, 1989
;       Copyright (c) Microsoft Corporation 1987, 1989
;
;       All Rights Reserved
;
;
;       See Ptrace.INC for structures and equates used when debugging,
;       this is the INC version of PTRACE.H.
;
;---------------------------------------------------------------------------
;       MODIFICATION HISTORY
;
;   Change                                                               Chg
;   Activity      Date    BY   Reason                                    Num
;   --------      ----    ---  -------                                   ---
;   DCR 1372    10/19/91  ARJ  Added for DOSPTRACE Support NEW           NEW
;----------------------------------------------------------------------------
;
.xlist
include basemaca.inc
include fnotask.inc
include osmaca.inc
include dossymc.inc
include ostypes.inc
include dosseg.inc
include error.inc
include error2.inc
include mi.inc
include protmode.inc
include proc.inc
include kmode.inc
include sysentry.inc
include ordinals.inc
include struc.inc
include osconst.inc
include sigdef.inc
include except.inc
include infoseg.inc
include pgexport.inc
include vmowner.inc
include vmexport.inc
include dirent.inc
include screen.inc
include sem.inc
include tkexport.inc
include tkptda.inc
include ptrace.inc
include seldesc.inc

.list

        ModName ,FNO_PTTHUNK_ASM

        CpuMode 386

        FARCODE         HIGH32
        EXTRN32         _VMAllocKHB
        EXTRN32         _VMFreeKHB
        EXTRN32         _TKProbeBuff
        EXTRN32         _PTSelToLin
        EXTRN32         _PTraceCmd

        ReferFlat       _pPTDACur,DWORD

;**********  Start 16 bit code segement  *****************************
        FARCODE HIGH3

HIGH3CODE SEGMENT

;***    w_Ptrace is the 16 bit routine invoked by the DosPtrace Command
;
;       API.ASM perform the following functions before calling this routine.
;               RPL Stamp BX
;               SI  = Offset of the uPTB from the User
;               BX  = Selector of the uPTB from the User
;
;       This code will perform the following functions:
;
;               Zero out the high order bits of ESI and EBX
;               This will allow the 16 bit routine to call a
;               32 bit worker passing a 32 bit address.
;
;               CALL VR2_Ptrace <0,0> (I did not know how to get around this)
;               NOTE: ESI and EBX were set up before this call. The
;                     thing VR2_Ptrace must do is to save these registers.
;
;               When we return to this routine every thing should be set
;               therefore we exit to the user without any checking.
;
;*****************************************************************************

Procedure       w_Ptrace, faronly
        ASSUME  DS:NOTHING, ES:NOTHING, FS:NOTHING, GS:NOTHING, SS:TASKAREA

        movzx     esi, si              ; zero out the high order bits
        movzx     ebx, bx              ; zero out the high order bits

        FlatContext <ds,es>
        CALL32    VR2_Ptrace           ; call 32 bit worker

        retf

EndProc  w_Ptrace

HIGH3CODE ENDS
;**********  End   16 bit code segement  *****************************

;**********  Start 32 bit code segement  *****************************
        FARCODE HIGH32
HIGH32CODE SEGMENT

;***    VR2_Ptrace - Is the THUNK routine to convert a DosPtrace
;                    command into a DosDebug command
;
;       BX must already be RPL stamped.
;
;       This code will perform the following functions:
;
;       Save ESI and EBX in local variables.
;
;       Get Storage for the kPTB (kernal Ptrace Buffer) using VMALLOCKHB
;       If I can not get the storage I exit.
;
;       Save the 16 bit pointes to the uPTB (users PTrace Buffer) in the kPTB
;
;       Call PTSelToLin to convert the 16:16 seg offset of the uPTB
;       into a 32 bit Linear address. If the conversion
;       fails return ERROR_INVALID_PARAMETER.
;
;       Verify we can read and write to the uPTB by calling
;       TKPROBEBUF with the TK_UM_SELPROBE option.
;       If the selector is invalid return Error_Invalid_Parameter.
;
;       Call PTRACE.C to Process the command.
;
;       Free the storage by calling VMFreeKHB
;
;       ENTRY   (BX:SI) -> uPTB
;
;       EXIT    Carry clear : success
;                   (AX) = 0
;               Carry set : error
;                   (AX) = Error Code
;                          uPTB invalid (unchanged)
;
;       USES    EAX, EBX, ECX, EDX, DI, ESI, DS, ES, Flags

Procedure       VR2_Ptrace,far32
        ASSUME  DS:FLAT, ES:FLAT, FS:NOTHING, GS:NOTHING, SS:NOTHING

        LocalVar        uSEL,DWORD      ; Users Selector is assigned bx
        LocalVar        uOFF,DWORD      ; Users Offset is assigned si
        LocalVar        pkPTB,DWORD     ; pointer to kernal Heap Block Info
        LocalVar        PT_RC,DWORD     ; Return code to pass the user

        EnterProc       <>              ; set up stack frame

        movzx   esi, si                 ; Save offset to uPTB
        mov     [uOFF], esi

        movzx   ebx, bx                 ; Save Selector to uPTB
        mov     [uSEL], ebx

;  Get Storage for kPTB (kernal PTrace Buffer) using VMAllocKHB
;       Input
;          hkh       public resident read and write
;          cb        PTWrkArea
;          hobOwner  DBGKDBTMPOWNER (0xff66 - kernal debug block)
;          fl        0
;          ppbData   pkPTB address of new buffer
;       Destroys - Written in C  (VMKRH.C)

        xor     eax,eax
        mov     pkPTB,eax
        SSToDS  ecx,pkPTB
        mov     eax,PTWrkArea

        FlatContext <ds,es>
        CCALL32 _VMAllocKHB <VM_HKH_PUB_RESRW, eax, DBGKDBTMPOWNER, \
                0, ecx>                 ; Allocate resident heap buffer

        mov     [PT_RC],eax             ; save orginal return code
        or      eax,eax                 ; test for success
        jnz     PTsetRC                 ; exit now

;  The storage we acquired is good we can read and write to it

        xor     edx,edx
        mov     edx,[pkPTB]             ; put address of storage in edx

;  Save 16 bit pointers to the Users input buffer in kPTB

        xor     eax,eax
        mov     eax,[uOFF]              ; Save offset to uPTB
        mov     ecx,eax                 ; used in PTSELToLIN
        mov     [edx].uPTBOff,eax       ; should never be more than 16 bits

        xor     eax,eax
        mov     eax,[uSEL]              ; Save Selector to uPTB
        mov     ebx,eax                 ; used in PTSELToLIN
        mov     [edx].uPTBSel,eax       ; should never be more than 16 bits

;  Find the 32 bit LINEAR address of the uPTB
;       Input
;         pkPTB.dbgeePTDA  _pPTDACur
;         pkPTB.uPTBSel    16 bit selector
;         pkPTB.uPTBOff    16 bit offset
;         EDX             pointer to kPTB.ulPTBAddr (returned linear address)
;       Destroys - WRITTEN IN C  (PTCNVRT.C)  (EAX ECX EDX FLAGS)

        xor     eax,eax
        mov     eax,_pPTDACur           ; Save the current PTDA

        lea     edx, [edx].ulPTBAddr    ; pointer to return linear addr

        CCALL32 _PTSelToLin <eax, ebx, ecx, edx>

        mov     [PT_RC],eax             ; save orginal return code
        or      eax,eax                 ; test for success
        jnz     PTFREE                  ; exit now

;  Verify we can read and write to the USERs Buffer (uPTB)
;  Write is required to return info to the USER
;       Input
;          pUserBuff pkPTB.ulPTBAddr
;          length    42
;          flags     TK_UM_WRITE
;       Destroys - EAX ECX EDX FLAGS  (TKUMEM2.ASM)

;  Restore pointer to kPTB

        xor     edx,edx
        mov     edx,[pkPTB]             ; put address of storage in edx

        mov     edx,[edx].ulPTBAddr     ; put address of storage in edx
        xor     eax,eax
        mov     ax,uPTB_size            ; length of buffer

        CCALL32 _TKProbeBuff <edx, eax, TK_UM_WRITE>   ; check buffer

        mov     [PT_RC],eax             ; save orginal return code
        or      eax,eax                 ; test for success
        jnz     PTFREE                  ; exit now

;  The storage we acquired is good we can read and write to it

;  Call PTraceCmd to process the Command, this routine is in PTrace.C
;  the kPTB should have the other major fields initilized by now
;       Input
;         pkPTB           Pointer to kPTB
;       Destroys - WRITTEN IN C  (PTTRACE.C)  (ALL)

        xor     edx, edx
        mov     edx, [pkPTB]            ; linear addr of kPTB

        CCALL32 _PTraceCmd,<edx>

        mov     [PT_RC],eax             ; save orginal return code

PTFREE:

;  All return codes and fields should be set before you get here and
;  USERs orginal PTB buffer should also be restored before you get here

;  Free the storage we got with VMAllocKHB
;  If the storage is not freeded there is no recovery plan
;  the free module should take an internal error before returning
;       Input
;          hkh       public resident read and write
;          ppbData   edx pointer to storage to be freed
;       Destroys - Written in C  (VMKRH.C)

        mov     edx, [pkPTB]      ; linear addr of kPTB

        CCALL32 _VMFreeKHB <VM_HKH_PUB_RESRW, edx> ; free the storage

        mov     eax,[PT_RC]       ; restore orginal return code then exit

PTsetRC:
        or      eax,eax           ; is there an error ?
        jz      short PTEXIT      ; No Error GO TO EXIT
        stc                       ; Yes there is an error turn on Carry Flag

PTEXIT:

        LeaveProc                  ; ThaTs All FOLKs
        ret

EndProc  VR2_Ptrace

;**************************            ****************************

;***    PTModifyDesc - Modify fields in a descriptor
;
;       ENTRY:  sel - selector to be modified
;               laddr - linear address to set
;               limit - limit to set
;               pptda - pointer to target tasks ptda
;       EXIT:   NONE
;       USES:   eax,ecx
;
Procedure _PTModifyDesc,near
        ASSUME DS:FLAT, ES:FLAT, FS:NOTHING, GS:NOTHING, SS:NOTHING

        ArgVar  ptdesc_sel,   DWORD
        ArgVar  ptdesc_laddr, DWORD
        ArgVar  ptdesc_limit, DWORD
        ArgVar  ptdesc_pptda, DWORD

        EnterProc

        mov     eax,[ptdesc_sel]                ; (eax) = selector to set

        mov     ecx,[ptdesc_pptda]              ; (ecx) = pptda
        mov     ecx,[ecx].ptda_ldtaddr          ; (ecx) = pointer to ldt
        and     eax,RPL_CLR - TABLE_MASK        ; clear rpl and table bit
        add     ecx,eax                         ; (ecx) = pointer to descriptor

;       Here we need to modify the starting linear address of the segment
;       in the descriptor.

        mov     eax,[ptdesc_laddr]              ; (eax) = linear address to set
        mov     [ecx].d_loaddr,ax
        mov     eax,[ptdesc_limit]              ; (eax) = limit to set
        mov     [ecx].d_limit,ax
        xor     eax,eax                         ; Always return ZERO

        LeaveProc                               ; ThaTs All FOLKs
        ret

EndProc _PTModifyDesc

HIGH32CODE ends
;**********  End   32 bit code segement  *****************************

        END
