DosQueryThreadContext

Query context of a suspended thread.

Syntax
DosQueryThreadContext(tid, level, pcxt)

Parameters

 * tid (TID) - input: Thread identity.
 * level (ULONG) - input: Level of information desired:
 * CONTEXT_CONTROL (0x00000001) Control registers: SS:ESP, CS:EIP, EFLAGS and EBP
 * CONTEXT_INTEGER (0x00000002) EAX, EBX, ECX, EDX, ESI and EDI
 * CONTEXT_SEGMENTS (0x00000004) Segment registers: DS, ES, FS, and GS
 * CONTEXT_FLOATING_POINT (0x00000008) Numeric coprocessor state
 * CONTEXT_FULL All of the above


 * pcxt (PCONTEXTRECORD) - in/out: Thread context record.

Return Code

 * ulrc (APIRET) - returns:DosQueryThreadContext returns one of the following values:
 * 0 NO_ERROR
 * 87 ERROR_INVALID_PARAMETER
 * 90 ERROR_NOT_FROZEN
 * 115 ERROR_PROTECTION_VIOLATION
 * 309 ERROR_INVALID_THREADID

Remarks
DosQueryThreadContext returns the context record of a suspended thread. A thread may be suspended by using DosSuspendThread or DosEnterCritSec. If DosSuspendThread is used, the caller must allow some time for OS/2 to suspend the thread before querying its context.

Note: Values from the thread context should be used only when the state of the target thread is known.

Example Code
This example uses DosQueryThreadContext to query the context of a suspended thread. 
 * 1) define INCL_DOSEXCEPTIONS
 * 2) define INCL_DOSPROCESS
 * 3) define INCL_DOSERRORS
 * 4) include 
 * 5) include 

VOID _System CntThreadProc( ULONG LoopMax );            /* Count Thread */ VOID PrintContextRecord( CONTEXTRECORD *pThread );

int main(VOID) {   TID        tidCntThread = 0;   /* ID returned for newly created thread */ PFNTHREAD pfnCntThread = &CntThreadProc; /* Address of Thread program */ ULONG     ulLoopMax    = 500000;     /* Parameter to thread routine   */ APIRET    rc           = NO_ERROR;   /* Return code                   */

/* Thread Context Record */ CONTEXTRECORD Thread_cxt= {0,{0,0,0,0,0,0,0}, {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0},                               {0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}},                                0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

rc = DosCreateThread(&tidCntThread, /* Thread ID (return by function) */                         pfnCntThread,   /* Address of thread program      */                         ulLoopMax,      /* Parameter passed to ThreadProc */                         CREATE_READY |  /* Thread is ready when created   */                         STACK_SPARSE,   /* Do not pre_commit stack pages  */                         8192L);         /* Stack size, rounded to page bdy*/ if (rc != NO_ERROR) { printf("DosCreateThread error: return code = %u\n",rc); return 1; }

rc = DosSuspendThread (tidCntThread); if (rc != NO_ERROR) printf("DosSuspendThread error: return code = %u\n",rc); else {          /* Wait for thread to suspend */

printf("Waiting 5 seconds for thread to suspend...\n"); rc = DosSleep(5000);

rc = DosQueryThreadContext (tidCntThread,                                   CONTEXT_FULL,                                    &Thread_cxt); if (rc != NO_ERROR) printf("DosQueryThreadContext error: return code = %u\n",rc); else PrintContextRecord( &Thread_cxt );

rc = DosResumeThread (tidCntThread); if (rc != NO_ERROR) { printf("DosResumeThread error: return code = %u\n",rc); return 1; }   }

printf("Waiting for thread to complete...\n");

rc = DosWaitThread ( &tidCntThread, DCWW_WAIT ); if (rc != NO_ERROR) { printf("DosWaitThread error: return code = %u\n",rc); return 1; }

printf("Thread has completed!\n"); return NO_ERROR; }

VOID _System CntThreadProc( ULONG LoopMax ) /* Count Thread */ {   ULONG  ulCount = 0, i      = 0, j      = 1, k      = 1, l      = 0; double w      = 0.0, y      = 0.0, z      = 0.0;

for (l=0; l < 20; l++) {     for (i=0; i < LoopMax; i++) {       w = 1.00 / 2.00; y = 2.00 * 2.00; z = 3.00 / 6.00; j = j + i;       k = k * i;      } }

return; }

VOID PrintContextRecord( CONTEXTRECORD *pThread ) {      int i = 0;

printf("\nRegisters for CONTEXT_CONTROL level:\n"); printf(" EBP= 0x%08x\t",pThread->ctx_RegEbp); printf("EIP= 0x%08x\t",pThread->ctx_RegEip); printf("CS= 0x%08x\n",pThread->ctx_SegCs); printf(" EFLAGS = 0x%08x\t",pThread->ctx_EFlags); printf("ESP= 0x%08x\t",pThread->ctx_RegEsp); printf("SS= 0x%08x\n",pThread->ctx_SegSs);

printf("\nRegisters for CONTEXT_INTEGER level:\n"); printf(" EAX= 0x%08x\t",pThread->ctx_RegEax); printf("EBX= 0x%08x\t",pThread->ctx_RegEbx); printf("ECX= 0x%08x\n",pThread->ctx_RegEcx); printf(" EDX= 0x%08x\t",pThread->ctx_RegEdx); printf("ESI= 0x%08x\t",pThread->ctx_RegEsi); printf("EDI= 0x%08x\n",pThread->ctx_RegEdi);

printf("\nRegisters for CONTEXT_SEGMENTS level:\n"); printf(" DS= 0x%08x\t",pThread->ctx_SegDs); printf("ES= 0x%08x\t",pThread->ctx_SegEs); printf("FS= 0x%08x\t",pThread->ctx_SegFs); printf("GS= 0x%08x\n",pThread->ctx_SegGs);

printf("\nRegisters for CONTEXT_FLOATING_POINT level:\n"); printf(" - Coprocessor stack register (exponent,hisig:losig):\n"); for (i=0;i<8;i++) {         printf("    ctx_stack[%d]=0x%08x ,0x%08x :0x%08x \n",i,                  pThread->ctx_stack[i].signexp,                  pThread->ctx_stack[i].hisig,                  pThread->ctx_stack[i].losig); }      printf("  - Other element\n"); for (i=0;i<7;i++) {         printf("    ctx_env[%d]=0x%08x \n",i ,pThread->ctx_env[i]); }

return; }



Related Functions

 * DosCreateThread
 * DosEnterCritSec
 * DosResumeThread
 * DosSuspendThread