Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

context.c File Reference

#include <ntos.h>

Go to the source code of this file.

Functions

VOID RtlInitializeContext (IN HANDLE Process, OUT PCONTEXT Context, IN PVOID Parameter OPTIONAL, IN PVOID InitialPc OPTIONAL, IN PVOID InitialSp OPTIONAL)
NTSTATUS RtlRemoteCall (HANDLE Process, HANDLE Thread, PVOID CallSite, ULONG ArgumentCount, PULONG Arguments, BOOLEAN PassContext, BOOLEAN AlreadySuspended)


Function Documentation

VOID RtlInitializeContext IN HANDLE  Process,
OUT PCONTEXT  Context,
IN PVOID Parameter  OPTIONAL,
IN PVOID InitialPc  OPTIONAL,
IN PVOID InitialSp  OPTIONAL
 

Definition at line 28 of file rtl/mips/context.c.

References CONTEXT_FULL, and RtlRaiseStatus().

00038 : 00039 00040 This function initializes a context structure so that it can be used in 00041 a subsequent call to NtCreateThread. 00042 00043 Arguments: 00044 00045 Context - Supplies a pointer to a context record that is to be initialized. 00046 00047 InitialPc - Supplies an initial program counter value. 00048 00049 InitialSp - Supplies an initial stack pointer value. 00050 00051 Return Value: 00052 00053 Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly 00054 aligned. 00055 00056 Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly 00057 aligned. 00058 00059 --*/ 00060 00061 { 00062 00063 // 00064 // Check for proper initial stack and PC alignment. 00065 // 00066 00067 if (((ULONG)InitialSp & 0x7) != 0) { 00068 RtlRaiseStatus(STATUS_BAD_INITIAL_STACK); 00069 } 00070 if (((ULONG)InitialPc & 0x3) != 0) { 00071 RtlRaiseStatus(STATUS_BAD_INITIAL_PC); 00072 } 00073 00074 // 00075 // Initialize the integer registers to contain their register number. 00076 // 00077 00078 Context->XIntZero = 0; 00079 Context->XIntAt = 1; 00080 Context->XIntV0 = 2; 00081 Context->XIntV1 = 3; 00082 Context->XIntA0 = 4; 00083 Context->XIntA1 = 5; 00084 Context->XIntA2 = 6; 00085 Context->XIntA3 = 7; 00086 Context->XIntT0 = 8; 00087 Context->XIntT1 = 9; 00088 Context->XIntT2 = 10; 00089 Context->XIntT3 = 11; 00090 Context->XIntT4 = 12; 00091 Context->XIntT5 = 13; 00092 Context->XIntT6 = 14; 00093 Context->XIntT7 = 15; 00094 Context->XIntS0 = 16; 00095 Context->XIntS1 = 17; 00096 Context->XIntS2 = 18; 00097 Context->XIntS3 = 19; 00098 Context->XIntS4 = 20; 00099 Context->XIntS5 = 21; 00100 Context->XIntS6 = 22; 00101 Context->XIntS7 = 23; 00102 Context->XIntT8 = 24; 00103 Context->XIntT9 = 25; 00104 Context->XIntS8 = 30; 00105 Context->XIntLo = 0; 00106 Context->XIntHi = 0; 00107 00108 // 00109 // Initialize the floating point registers to contain zero in their upper 00110 // half and the integer value of their register number in the lower half. 00111 // 00112 00113 Context->FltF0 = 0; 00114 Context->FltF1 = 0; 00115 Context->FltF2 = 2; 00116 Context->FltF3 = 0; 00117 Context->FltF4 = 4; 00118 Context->FltF5 = 0; 00119 Context->FltF6 = 6; 00120 Context->FltF7 = 0; 00121 Context->FltF8 = 8; 00122 Context->FltF9 = 0; 00123 Context->FltF10 = 10; 00124 Context->FltF11 = 0; 00125 Context->FltF12 = 12; 00126 Context->FltF13 = 0; 00127 Context->FltF14 = 14; 00128 Context->FltF15 = 0; 00129 Context->FltF16 = 16; 00130 Context->FltF17 = 0; 00131 Context->FltF18 = 18; 00132 Context->FltF19 = 0; 00133 Context->FltF20 = 20; 00134 Context->FltF21 = 0; 00135 Context->FltF22 = 22; 00136 Context->FltF23 = 0; 00137 Context->FltF24 = 24; 00138 Context->FltF25 = 0; 00139 Context->FltF26 = 26; 00140 Context->FltF27 = 0; 00141 Context->FltF28 = 28; 00142 Context->FltF29 = 0; 00143 Context->FltF30 = 30; 00144 Context->FltF31 = 0; 00145 Context->Fsr = 0; 00146 00147 // 00148 // Initialize the control registers. 00149 // 00150 // N.B. The register gp is estabished at thread startup by the loader. 00151 // 00152 00153 Context->XIntGp = 0; 00154 Context->XIntSp = (LONG)InitialSp; 00155 Context->XIntRa = 1; 00156 Context->Fir = (ULONG)InitialPc; 00157 Context->Psr = 0; 00158 Context->ContextFlags = CONTEXT_FULL; 00159 00160 // 00161 // Set the initial context of the thread in a machine specific way. 00162 // 00163 00164 Context->XIntA0 = (LONG)Parameter; 00165 Context->XIntSp -= KTRAP_FRAME_ARGUMENTS; 00166 }

NTSTATUS RtlRemoteCall HANDLE  Process,
HANDLE  Thread,
PVOID  CallSite,
ULONG  ArgumentCount,
PULONG  Arguments,
BOOLEAN  PassContext,
BOOLEAN  AlreadySuspended
 

Definition at line 169 of file rtl/mips/context.c.

References CONTEXT_FULL, FALSE, NT_SUCCESS, NtGetContextThread(), NtResumeThread(), NtSetContextThread(), NTSTATUS(), NtSuspendThread(), NtWriteVirtualMemory(), NULL, and Status.

00181 : 00182 00183 This function calls a procedure in another thread/process, by using 00184 NtGetContext and NtSetContext. Parameters are passed to the target 00185 procedure via the nonvolatile registers (s0 - s7). 00186 00187 Arguments: 00188 00189 Process - Supplies an open handle to the target process. 00190 00191 Thread - Supplies an open handle to the target thread within the target 00192 process. 00193 00194 CallSize - Supplies the address of the procedure to call in the target 00195 process. 00196 00197 ArgumentCount - Supplies the number of 32 bit parameters to pass to the 00198 target procedure. 00199 00200 Arguments - Supplies a pointer to the array of 32 bit parameters to pass. 00201 00202 PassContext - Supplies a boolean value that determines whether a parameter 00203 is to be passed that points to a context record. This parameter is 00204 ignored on MIPS hosts. 00205 00206 AlreadySuspended - Supplies a boolean value that determines whether the 00207 target thread is already in a suspended or waiting state. 00208 00209 Return Value: 00210 00211 Status - Status value 00212 00213 --*/ 00214 00215 { 00216 00217 NTSTATUS Status; 00218 CONTEXT Context; 00219 ULONG NewSp; 00220 00221 if (ArgumentCount > 8) { 00222 return(STATUS_INVALID_PARAMETER); 00223 } 00224 00225 // 00226 // If necessary, suspend the target thread before getting the thread's 00227 // current state. 00228 // 00229 00230 if (AlreadySuspended == FALSE) { 00231 Status = NtSuspendThread(Thread, NULL); 00232 if (NT_SUCCESS(Status) == FALSE) { 00233 return(Status); 00234 } 00235 } 00236 00237 // 00238 // Get the cuurent state of the target thread. 00239 // 00240 00241 Context.ContextFlags = CONTEXT_FULL; 00242 Status = NtGetContextThread(Thread, &Context); 00243 if (NT_SUCCESS(Status) == FALSE) { 00244 if (AlreadySuspended == FALSE) { 00245 NtResumeThread(Thread, NULL); 00246 } 00247 00248 return Status; 00249 } 00250 00251 if (AlreadySuspended) { 00252 Context.XIntV0 = (LONG)STATUS_ALERTED; 00253 } 00254 00255 // 00256 // Pass the parameters to the other thread via the non-volatile registers 00257 // s0 - s7. The context record is passed on the stack of the target thread. 00258 // 00259 00260 NewSp = (ULONG)(Context.XIntSp - sizeof(CONTEXT)); 00261 Status = NtWriteVirtualMemory(Process, 00262 (PVOID)NewSp, 00263 &Context, 00264 sizeof(CONTEXT), 00265 NULL); 00266 00267 if (NT_SUCCESS(Status) == FALSE) { 00268 if (AlreadySuspended == FALSE) { 00269 NtResumeThread(Thread, NULL); 00270 } 00271 00272 return Status; 00273 } 00274 00275 Context.XIntSp = (LONG)NewSp; 00276 if (PassContext) { 00277 Context.XIntS0 = (LONG)NewSp; 00278 RtlMoveMemory(&Context.XIntS1, Arguments, ArgumentCount * sizeof(ULONG)); 00279 00280 } else { 00281 RtlMoveMemory(&Context.XIntS0, Arguments, ArgumentCount * sizeof(ULONG)); 00282 } 00283 00284 // 00285 // Set the address of the target code into FIR and set the thread context 00286 // to cause the target procedure to be executed. 00287 // 00288 00289 Context.Fir = (ULONG)CallSite;; 00290 Status = NtSetContextThread(Thread, &Context); 00291 if (AlreadySuspended == FALSE) { 00292 NtResumeThread(Thread, NULL); 00293 } 00294 00295 return Status; 00296 } }


Generated on Sat May 15 19:43:16 2004 for test by doxygen 1.3.7