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 }
}