00485 :
00486
00487 This function either captures
the user mode state of
the current
00488 thread, or sets
the user mode state of
the current thread. The
00489 operation
type is determined by
the value of SystemArgument1.
A
00490 zero value
is used
for get context, and a nonzero value
is used
00491
for set context.
00492
00493 Arguments:
00494
00495 Apc - Supplies a pointer to
the APC
control object that caused entry
00496 into
this routine.
00497
00498 NormalRoutine - Supplies a pointer to
the normal routine function that
00499 was specified when
the APC was initialized. This parameter
is not
00500 used.
00501
00502 NormalContext - Supplies a pointer to an arbitrary data structure that
00503 was specified when
the APC was initialized. This parameter
is not
00504 used.
00505
00506 SystemArgument1, SystemArgument2 - Supplies a set of two pointer to two
00507 arguments that contain untyped data. These parameters are not used.
00508
00509 Return Value:
00510
00511 None.
00512
00513 --*/
00514
00515 {
00516
00517
PGETSETCONTEXT ContextBlock;
00518 KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
00519 CONTEXT ContextRecord;
00520 ULONG ControlPc;
00521 ULONG EstablisherFrame;
00522 PRUNTIME_FUNCTION FunctionEntry;
00523 BOOLEAN InFunction;
00524
PETHREAD Thread;
00525 ULONG TrapFrame1;
00526 ULONG TrapFrame2;
00527
00528
00529
00530
00531
00532
00533 ContextBlock = CONTAINING_RECORD(Apc,
GETSETCONTEXT, Apc);
00534 Thread =
PsGetCurrentThread();
00535 TrapFrame1 = (ULONG)Thread->
Tcb.
InitialStack - KTRAP_FRAME_LENGTH;
00536 TrapFrame2 = (ULONG)Thread->
Tcb.
InitialStack - KTRAP_FRAME_LENGTH - KTRAP_FRAME_ARGUMENTS;
00537
00538
00539
00540
00541
00542
00543 RtlCaptureContext(&ContextRecord);
00544 ControlPc = (ULONG)ContextRecord.XIntRa;
00545
00546
00547
00548
00549
00550
00551 ContextPointers.XIntS0 = &ContextRecord.XIntS0;
00552 ContextPointers.XIntS1 = &ContextRecord.XIntS1;
00553 ContextPointers.XIntS2 = &ContextRecord.XIntS2;
00554 ContextPointers.XIntS3 = &ContextRecord.XIntS3;
00555 ContextPointers.XIntS4 = &ContextRecord.XIntS4;
00556 ContextPointers.XIntS5 = &ContextRecord.XIntS5;
00557 ContextPointers.XIntS6 = &ContextRecord.XIntS6;
00558 ContextPointers.XIntS7 = &ContextRecord.XIntS7;
00559
00560 ContextPointers.FltF20 = &ContextRecord.FltF20;
00561 ContextPointers.FltF21 = &ContextRecord.FltF21;
00562 ContextPointers.FltF22 = &ContextRecord.FltF22;
00563 ContextPointers.FltF23 = &ContextRecord.FltF23;
00564 ContextPointers.FltF24 = &ContextRecord.FltF24;
00565 ContextPointers.FltF25 = &ContextRecord.FltF25;
00566 ContextPointers.FltF26 = &ContextRecord.FltF26;
00567 ContextPointers.FltF27 = &ContextRecord.FltF27;
00568 ContextPointers.FltF28 = &ContextRecord.FltF28;
00569 ContextPointers.FltF29 = &ContextRecord.FltF29;
00570 ContextPointers.FltF30 = &ContextRecord.FltF30;
00571 ContextPointers.FltF31 = &ContextRecord.FltF31;
00572
00573
00574
00575
00576
00577
00578
do {
00579
00580
00581
00582
00583
00584
00585 FunctionEntry =
RtlLookupFunctionEntry(ControlPc);
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
if (FunctionEntry !=
NULL) {
00596 ControlPc =
RtlVirtualUnwind(ControlPc | 1,
00597 FunctionEntry,
00598 &ContextRecord,
00599 &InFunction,
00600 &EstablisherFrame,
00601 &ContextPointers);
00602
00603 }
else {
00604 ControlPc = (ULONG)ContextRecord.XIntRa;
00605 }
00606
00607 }
while (((ULONG)ContextRecord.XIntSp != TrapFrame1) &&
00608 (((ULONG)ContextRecord.XIntSp != TrapFrame2) ||
00609 (ControlPc < PCR->SystemServiceDispatchStart) ||
00610 (ControlPc >= PCR->SystemServiceDispatchEnd)));
00611
00612
00613
00614
00615
00616
00617
if (Apc->SystemArgument1 != 0) {
00618
00619
00620
00621
00622
00623
PspSetContext((PKTRAP_FRAME)TrapFrame1,
00624 &ContextPointers,
00625 &ContextBlock->
Context,
00626 ContextBlock->
Mode);
00627
00628 }
else {
00629
00630
00631
00632
00633
00634
PspGetContext((PKTRAP_FRAME)TrapFrame1,
00635 &ContextPointers,
00636 &ContextBlock->
Context);
00637 }
00638
00639
KeSetEvent(&ContextBlock->
OperationComplete, 0, FALSE);
00640
return;
00641 }
}