00396 :
00397
00398 This function either captures
the user mode state of
the current
00399 thread, or sets
the user mode state of
the current thread. The
00400 operation
type is determined by
the value of SystemArgument1.
A
00401 zero value
is used
for get context, and a nonzero value
is used
00402
for set context.
00403
00404 Arguments:
00405
00406 Apc - Supplies a pointer to
the APC
control object that caused entry
00407 into
this routine.
00408
00409 NormalRoutine - Supplies a pointer to
the normal routine function that
00410 was specified when
the APC was initialized. This parameter
is not
00411 used.
00412
00413 NormalContext - Supplies a pointer to an arbitrary data structure that
00414 was specified when
the APC was initialized. This parameter
is not
00415 used.
00416
00417 SystemArgument1, SystemArgument2 - Supplies a set of two pointer to two
00418 arguments that contain untyped data. These parameters are not used.
00419
00420 Return Value:
00421
00422 None.
00423
00424 --*/
00425
00426 {
00427
00428
PGETSETCONTEXT ContextBlock;
00429 KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
00430 CONTEXT ContextRecord;
00431 ULONG ControlPc;
00432 ULONG EstablisherFrame;
00433 PRUNTIME_FUNCTION FunctionEntry;
00434 BOOLEAN InFunction;
00435
PETHREAD Thread;
00436 ULONG TrapFrame1;
00437 ULONG TrapFrame2;
00438
00439
00440
00441
00442
00443
00444 ContextBlock = CONTAINING_RECORD(Apc,
GETSETCONTEXT, Apc);
00445 Thread =
PsGetCurrentThread();
00446 TrapFrame1 = (ULONG)Thread->
Tcb.
InitialStack - (KTRAP_FRAME_LENGTH +
00447
sizeof(KEXCEPTION_FRAME) + (2 *
sizeof(ULONG)));
00448 TrapFrame2 = (ULONG)Thread->
Tcb.
InitialStack - (KTRAP_FRAME_LENGTH +
00449
sizeof(KEXCEPTION_FRAME) +
STK_MIN_FRAME +
00450 (10 *
sizeof(ULONG)));
00451
00452
00453
00454
00455
00456
00457 RtlCaptureContext(&ContextRecord);
00458 ControlPc = ContextRecord.Lr;
00459
00460
00461
00462
00463
00464
00465 ContextPointers.IntegerContext[13] = &ContextRecord.Gpr13;
00466 ContextPointers.IntegerContext[14] = &ContextRecord.Gpr14;
00467 ContextPointers.IntegerContext[15] = &ContextRecord.Gpr15;
00468 ContextPointers.IntegerContext[16] = &ContextRecord.Gpr16;
00469 ContextPointers.IntegerContext[17] = &ContextRecord.Gpr17;
00470 ContextPointers.IntegerContext[18] = &ContextRecord.Gpr18;
00471 ContextPointers.IntegerContext[19] = &ContextRecord.Gpr19;
00472 ContextPointers.IntegerContext[20] = &ContextRecord.Gpr20;
00473 ContextPointers.IntegerContext[21] = &ContextRecord.Gpr21;
00474 ContextPointers.IntegerContext[22] = &ContextRecord.Gpr22;
00475 ContextPointers.IntegerContext[23] = &ContextRecord.Gpr23;
00476 ContextPointers.IntegerContext[24] = &ContextRecord.Gpr24;
00477 ContextPointers.IntegerContext[25] = &ContextRecord.Gpr25;
00478 ContextPointers.IntegerContext[26] = &ContextRecord.Gpr26;
00479 ContextPointers.IntegerContext[27] = &ContextRecord.Gpr27;
00480 ContextPointers.IntegerContext[28] = &ContextRecord.Gpr28;
00481 ContextPointers.IntegerContext[29] = &ContextRecord.Gpr29;
00482 ContextPointers.IntegerContext[30] = &ContextRecord.Gpr30;
00483 ContextPointers.IntegerContext[31] = &ContextRecord.Gpr31;
00484
00485 ContextPointers.FloatingContext[14] = &ContextRecord.Fpr14;
00486 ContextPointers.FloatingContext[15] = &ContextRecord.Fpr15;
00487 ContextPointers.FloatingContext[16] = &ContextRecord.Fpr16;
00488 ContextPointers.FloatingContext[17] = &ContextRecord.Fpr17;
00489 ContextPointers.FloatingContext[18] = &ContextRecord.Fpr18;
00490 ContextPointers.FloatingContext[19] = &ContextRecord.Fpr19;
00491 ContextPointers.FloatingContext[20] = &ContextRecord.Fpr20;
00492 ContextPointers.FloatingContext[21] = &ContextRecord.Fpr21;
00493 ContextPointers.FloatingContext[22] = &ContextRecord.Fpr22;
00494 ContextPointers.FloatingContext[23] = &ContextRecord.Fpr23;
00495 ContextPointers.FloatingContext[24] = &ContextRecord.Fpr24;
00496 ContextPointers.FloatingContext[25] = &ContextRecord.Fpr25;
00497 ContextPointers.FloatingContext[26] = &ContextRecord.Fpr26;
00498 ContextPointers.FloatingContext[27] = &ContextRecord.Fpr27;
00499 ContextPointers.FloatingContext[28] = &ContextRecord.Fpr28;
00500 ContextPointers.FloatingContext[29] = &ContextRecord.Fpr29;
00501 ContextPointers.FloatingContext[30] = &ContextRecord.Fpr30;
00502 ContextPointers.FloatingContext[31] = &ContextRecord.Fpr31;
00503
00504
00505
00506
00507
00508
00509
do {
00510
00511
00512
00513
00514
00515
00516 FunctionEntry =
RtlLookupFunctionEntry(ControlPc);
00517
00518
00519
00520
00521
00522
00523 ControlPc =
RtlVirtualUnwind(ControlPc,
00524 FunctionEntry,
00525 &ContextRecord,
00526 &InFunction,
00527 &EstablisherFrame,
00528 &ContextPointers,
00529 (ULONG)Thread->
Tcb.
StackLimit,
00530 (ULONG)Thread->
Tcb.
InitialStack);
00531
00532 }
while ((ContextRecord.Gpr1 >= (ULONG)Thread->
Tcb.
StackLimit) &&
00533 (ContextRecord.Gpr1 < (ULONG)Thread->
Tcb.
InitialStack));
00534
00535
00536
00537
00538
00539
00540
if (Apc->SystemArgument1 != 0) {
00541
00542
00543
00544
00545
00546
PspSetContext((PKTRAP_FRAME)TrapFrame1,
00547 &ContextPointers,
00548 &ContextBlock->
Context,
00549 ContextBlock->
Mode);
00550
00551 }
else {
00552
00553
00554
00555
00556
00557
PspGetContext((PKTRAP_FRAME)TrapFrame1,
00558 &ContextPointers,
00559 &ContextBlock->
Context);
00560 }
00561
00562
KeSetEvent(&ContextBlock->
OperationComplete, 0, FALSE);
00563
return;
00564 }
}