00359 :
00360
00361 This function either captures
the user mode state of
the current
00362 thread, or sets
the user mode state of
the current thread. The
00363 operation
type is determined by
the value of SystemArgument1.
A
00364 zero value
is used
for get context, and a nonzero value
is used
00365
for set context.
00366
00367 Arguments:
00368
00369 Apc - Supplies a pointer to
the APC
control object that caused entry
00370 into
this routine.
00371
00372 NormalRoutine - Supplies a pointer to
the normal routine function that
00373 was specified when
the APC was initialized. This parameter
is not
00374 used.
00375
00376 NormalContext - Supplies a pointer to an arbitrary data structure that
00377 was specified when
the APC was initialized. This parameter
is not
00378 used.
00379
00380 SystemArgument1, SystemArgument2 - Supplies a set of two pointer to two
00381 arguments that contain untyped data. These parameters are not used.
00382
00383 Return Value:
00384
00385 None.
00386
00387 --*/
00388
00389 {
00390
00391
PGETSETCONTEXT ContextBlock;
00392 KNONVOLATILE_CONTEXT_POINTERS ContextPointers;
00393 CONTEXT ContextRecord;
00394 ULONG_PTR ControlPc;
00395 FRAME_POINTERS EstablisherFrame;
00396 PRUNTIME_FUNCTION FunctionEntry;
00397 BOOLEAN InFunction;
00398
PETHREAD Thread;
00399 ULONGLONG TrapFrame1;
00400 ULONGLONG TrapFrame2;
00401
00402
00403
00404
00405
00406
00407 ContextBlock = CONTAINING_RECORD(Apc,
GETSETCONTEXT, Apc);
00408 Thread =
PsGetCurrentThread();
00409 TrapFrame1 = (ULONGLONG)(LONG_PTR)Thread->
Tcb.
InitialStack - KTRAP_FRAME_LENGTH;
00410
00411
00412
00413
00414
00415
00416 TrapFrame2 = TrapFrame1 - KTRAP_FRAME_LENGTH;
00417
00418
00419
00420
00421
00422
00423 RtlCaptureContext(&ContextRecord);
00424 ControlPc = (ULONG_PTR)ContextRecord.IntRa;
00425
00426
00427
00428
00429
00430
00431 ContextPointers.IntS0 = &ContextRecord.IntS0;
00432 ContextPointers.IntS1 = &ContextRecord.IntS1;
00433 ContextPointers.IntS2 = &ContextRecord.IntS2;
00434 ContextPointers.IntS3 = &ContextRecord.IntS3;
00435 ContextPointers.IntS4 = &ContextRecord.IntS4;
00436 ContextPointers.IntS5 = &ContextRecord.IntS5;
00437
00438 ContextPointers.FltF2 = &ContextRecord.FltF2;
00439 ContextPointers.FltF3 = &ContextRecord.FltF3;
00440 ContextPointers.FltF4 = &ContextRecord.FltF4;
00441 ContextPointers.FltF5 = &ContextRecord.FltF5;
00442 ContextPointers.FltF6 = &ContextRecord.FltF6;
00443 ContextPointers.FltF7 = &ContextRecord.FltF7;
00444 ContextPointers.FltF8 = &ContextRecord.FltF8;
00445 ContextPointers.FltF9 = &ContextRecord.FltF9;
00446
00447
00448
00449
00450
00451
00452
do {
00453
00454
00455
00456
00457
00458
00459 FunctionEntry =
RtlLookupFunctionEntry(ControlPc);
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
if (FunctionEntry !=
NULL) {
00470 ControlPc =
RtlVirtualUnwind(ControlPc,
00471 FunctionEntry,
00472 &ContextRecord,
00473 &InFunction,
00474 &EstablisherFrame,
00475 &ContextPointers);
00476
00477 }
else {
00478 ControlPc = (ULONG_PTR)ContextRecord.IntRa;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 }
while ((ContextRecord.IntSp != TrapFrame1) &&
00492 ((ContextRecord.IntSp < TrapFrame2) ||
00493 (ControlPc < PCR->SystemServiceDispatchStart) ||
00494 (ControlPc >= PCR->SystemServiceDispatchEnd)));
00495
00496
00497
00498
00499
00500
00501
if (Apc->SystemArgument1 != 0) {
00502
00503
00504
00505
00506
00507
PspSetContext((PKTRAP_FRAME)TrapFrame1,
00508 &ContextPointers,
00509 &ContextBlock->
Context,
00510 ContextBlock->
Mode);
00511
00512 }
else {
00513
00514
00515
00516
00517
00518
PspGetContext((PKTRAP_FRAME)TrapFrame1,
00519 &ContextPointers,
00520 &ContextBlock->
Context);
00521 }
00522
00523
KeSetEvent(&ContextBlock->
OperationComplete, 0, FALSE);
00524
return;
00525 }
}