00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
#include <ntos.h>
00026 
00027 
VOID
00028 RtlInitializeContext(
00029     IN HANDLE Process,
00030     OUT PCONTEXT Context,
00031     IN PVOID Parameter OPTIONAL,
00032     IN PVOID InitialPc OPTIONAL,
00033     IN PVOID InitialSp OPTIONAL
00034     )
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 {
00062 
00063     
00064     
00065     
00066 
00067     
if (((ULONG)InitialSp & 0x7) != 0) {
00068         
RtlRaiseStatus(STATUS_BAD_INITIAL_STACK);
00069     }
00070     
if (((ULONG)InitialPc & 0x3) != 0) {
00071         
RtlRaiseStatus(STATUS_BAD_INITIAL_PC);
00072     }
00073 
00074     
00075     
00076     
00077 
00078     Context->XIntZero = 0;
00079     Context->XIntAt = 1;
00080     Context->XIntV0 = 2;
00081     Context->XIntV1 = 3;
00082     Context->XIntA0 = 4;
00083     Context->XIntA1 = 5;
00084     Context->XIntA2 = 6;
00085     Context->XIntA3 = 7;
00086     Context->XIntT0 = 8;
00087     Context->XIntT1 = 9;
00088     Context->XIntT2 = 10;
00089     Context->XIntT3 = 11;
00090     Context->XIntT4 = 12;
00091     Context->XIntT5 = 13;
00092     Context->XIntT6 = 14;
00093     Context->XIntT7 = 15;
00094     Context->XIntS0 = 16;
00095     Context->XIntS1 = 17;
00096     Context->XIntS2 = 18;
00097     Context->XIntS3 = 19;
00098     Context->XIntS4 = 20;
00099     Context->XIntS5 = 21;
00100     Context->XIntS6 = 22;
00101     Context->XIntS7 = 23;
00102     Context->XIntT8 = 24;
00103     Context->XIntT9 = 25;
00104     Context->XIntS8 = 30;
00105     Context->XIntLo = 0;
00106     Context->XIntHi = 0;
00107 
00108     
00109     
00110     
00111     
00112 
00113     Context->FltF0 = 0;
00114     Context->FltF1 = 0;
00115     Context->FltF2 = 2;
00116     Context->FltF3 = 0;
00117     Context->FltF4 = 4;
00118     Context->FltF5 = 0;
00119     Context->FltF6 = 6;
00120     Context->FltF7 = 0;
00121     Context->FltF8 = 8;
00122     Context->FltF9 = 0;
00123     Context->FltF10 = 10;
00124     Context->FltF11 = 0;
00125     Context->FltF12 = 12;
00126     Context->FltF13 = 0;
00127     Context->FltF14 = 14;
00128     Context->FltF15 = 0;
00129     Context->FltF16 = 16;
00130     Context->FltF17 = 0;
00131     Context->FltF18 = 18;
00132     Context->FltF19 = 0;
00133     Context->FltF20 = 20;
00134     Context->FltF21 = 0;
00135     Context->FltF22 = 22;
00136     Context->FltF23 = 0;
00137     Context->FltF24 = 24;
00138     Context->FltF25 = 0;
00139     Context->FltF26 = 26;
00140     Context->FltF27 = 0;
00141     Context->FltF28 = 28;
00142     Context->FltF29 = 0;
00143     Context->FltF30 = 30;
00144     Context->FltF31 = 0;
00145     Context->Fsr = 0;
00146 
00147     
00148     
00149     
00150     
00151     
00152 
00153     Context->XIntGp = 0;
00154     Context->XIntSp = (LONG)InitialSp;
00155     Context->XIntRa = 1;
00156     Context->Fir = (ULONG)InitialPc;
00157     Context->Psr = 0;
00158     Context->ContextFlags = 
CONTEXT_FULL;
00159 
00160     
00161     
00162     
00163 
00164     Context->XIntA0 = (LONG)Parameter;
00165     Context->XIntSp -= KTRAP_FRAME_ARGUMENTS;
00166 }
00167 
00168 
NTSTATUS
00169 RtlRemoteCall(
00170     HANDLE Process,
00171     HANDLE Thread,
00172     PVOID CallSite,
00173     ULONG ArgumentCount,
00174     PULONG Arguments,
00175     BOOLEAN PassContext,
00176     BOOLEAN AlreadySuspended
00177     )
00178 
00179 
00180 
00181 
00182 
00183 
00184 
00185 
00186 
00187 
00188 
00189 
00190 
00191 
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 {
00216 
00217     
NTSTATUS Status;
00218     CONTEXT Context;
00219     ULONG NewSp;
00220 
00221     
if (ArgumentCount > 8) {
00222         
return(STATUS_INVALID_PARAMETER);
00223     }
00224 
00225     
00226     
00227     
00228     
00229 
00230     
if (AlreadySuspended == 
FALSE) {
00231         
Status = 
NtSuspendThread(Thread, 
NULL);
00232         
if (
NT_SUCCESS(
Status) == 
FALSE) {
00233             
return(
Status);
00234         }
00235     }
00236 
00237     
00238     
00239     
00240 
00241     Context.ContextFlags = 
CONTEXT_FULL;
00242     
Status = 
NtGetContextThread(Thread, &Context);
00243     
if (
NT_SUCCESS(
Status) == 
FALSE) {
00244         
if (AlreadySuspended == 
FALSE) {
00245             
NtResumeThread(Thread, 
NULL);
00246         }
00247 
00248         
return Status;
00249     }
00250 
00251     
if (AlreadySuspended) {
00252         Context.XIntV0 = (LONG)STATUS_ALERTED;
00253     }
00254 
00255     
00256     
00257     
00258     
00259 
00260     NewSp = (ULONG)(Context.XIntSp - 
sizeof(CONTEXT));
00261     
Status = 
NtWriteVirtualMemory(Process,
00262                                   (PVOID)NewSp,
00263                                   &Context,
00264                                   
sizeof(CONTEXT),
00265                                   
NULL);
00266 
00267     
if (
NT_SUCCESS(
Status) == 
FALSE) {
00268         
if (AlreadySuspended == 
FALSE) {
00269             
NtResumeThread(Thread, 
NULL);
00270         }
00271 
00272         
return Status;
00273     }
00274 
00275     Context.XIntSp = (LONG)NewSp;
00276     
if (PassContext) {
00277         Context.XIntS0 = (LONG)NewSp;
00278         RtlMoveMemory(&Context.XIntS1, Arguments, ArgumentCount * 
sizeof(ULONG));
00279 
00280     } 
else {
00281         RtlMoveMemory(&Context.XIntS0, Arguments, ArgumentCount * 
sizeof(ULONG));
00282     }
00283 
00284     
00285     
00286     
00287     
00288 
00289     Context.Fir = (ULONG)CallSite;;
00290     
Status = 
NtSetContextThread(Thread, &Context);
00291     
if (AlreadySuspended == 
FALSE) {
00292         
NtResumeThread(Thread, 
NULL);
00293     }
00294 
00295     
return Status;
00296 }