00205 :
00206
00207 This function calls a
procedure in another thread/process by
using
00208 NtGetContext and NtSetContext. Parameters are passed to
the target
00209
procedure via
the nonvolatile registers (s0 - s5).
00210
00211 Arguments:
00212
00213 Process - Supplies an open handle to
the target process.
00214
00215 Thread - Supplies an open handle to
the target thread within
the target
00216 process.
00217
00218 CallSite - Supplies
the address of
the procedure to call in
the target
00219 process.
00220
00221 ArgumentCount - Supplies
the number of parameters to pass to
the
00222 target
procedure.
00223
00224 Arguments - Supplies a pointer to
the array of parameters to pass.
00225
00226 PassContext - Supplies a
boolean value that determines whether a parameter
00227
is to be passed that points to a context record. This parameter
is
00228 ignored on MIPS and Alpha hosts.
00229
00230 AlreadySuspended - Supplies a
boolean value that determines whether
the
00231 target thread
is already in a suspended or waiting state.
00232
00233 Return Value:
00234
00235
Status -
Status value.
00236
00237 --*/
00238
00239 {
00240
00241
NTSTATUS Status;
00242 CONTEXT Context;
00243 ULONG
Index;
00244 ULONGLONG NewSp;
00245
00246
if ((ArgumentCount > 6) ||
00247 (PassContext && (ArgumentCount > 5))) {
00248
return(STATUS_INVALID_PARAMETER);
00249 }
00250
00251
00252
00253
00254
00255
00256
if (AlreadySuspended ==
FALSE) {
00257
Status =
NtSuspendThread(Thread, NULL);
00258
if (
NT_SUCCESS(Status) ==
FALSE) {
00259
return(
Status);
00260 }
00261 }
00262
00263
00264
00265
00266
00267 Context.ContextFlags =
CONTEXT_FULL;
00268
Status =
NtGetContextThread(Thread, &Context);
00269
if (
NT_SUCCESS(Status) ==
FALSE) {
00270
if (AlreadySuspended ==
FALSE) {
00271
NtResumeThread(Thread, NULL);
00272 }
00273
return(
Status);
00274 }
00275
00276
if (AlreadySuspended) {
00277 Context.IntV0 = STATUS_ALERTED;
00278 }
00279
00280
00281
00282
00283
00284
00285 NewSp = Context.IntSp -
sizeof(CONTEXT);
00286
Status =
NtWriteVirtualMemory(Process, (PVOID)NewSp, &Context,
00287
sizeof(CONTEXT), NULL);
00288
if (
NT_SUCCESS(Status) ==
FALSE) {
00289
if (AlreadySuspended ==
FALSE) {
00290
NtResumeThread(Thread, NULL);
00291 }
00292
return(
Status);
00293 }
00294
00295
00296
00297
00298
00299
00300
00301 Context.IntSp = NewSp;
00302
00303
if (PassContext) {
00304 Context.IntS0 = NewSp;
00305
for (
Index = 0;
Index < ArgumentCount;
Index += 1) {
00306 (&Context.IntS1)[
Index] = (ULONGLONG)(LONG_PTR)Arguments[
Index];
00307 }
00308
00309 }
else {
00310
for (
Index = 0;
Index < ArgumentCount;
Index += 1) {
00311 (&Context.IntS0)[
Index] = (ULONGLONG)(LONG_PTR)Arguments[
Index];
00312 }
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 Context.Fir = (ULONGLONG)(LONG_PTR)CallSite;
00324
Status =
NtSetContextThread(Thread, &Context);
00325
if (AlreadySuspended ==
FALSE) {
00326
NtResumeThread(Thread, NULL);
00327 }
00328
return(
Status);
00329 }
}