11 #include <napi/i386/segment.h>
12 #include <napi/i386/floatsave.h>
14 #include <rosrtl/thread.h>
17 RtlRosInitializeContext
19 IN HANDLE ProcessHandle,
21 IN PVOID StartAddress,
22 IN PUSER_STACK UserStack,
23 IN ULONG ParameterCount,
24 IN ULONG_PTR * Parameters
27 static PVOID s_pRetAddr = (PVOID)0xDEADBEEF;
30 SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
35 /* Intel x86: linear top-down stack, all parameters passed on the stack */
36 /* get the stack base and limit */
37 nErrCode = RtlpRosGetStackLimits(UserStack, &pStackBase, &pStackLimit);
40 if(!NT_SUCCESS(nErrCode)) return nErrCode;
42 /* validate the stack */
43 nErrCode = RtlpRosValidateTopDownUserStack(pStackBase, pStackLimit);
46 if(!NT_SUCCESS(nErrCode)) return nErrCode;
48 /* too many parameters */
49 if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)(pStackBase - pStackLimit))
50 return STATUS_STACK_OVERFLOW;
52 memset(Context, 0, sizeof(CONTEXT));
54 /* initialize the context */
55 Context->ContextFlags = CONTEXT_FULL;
56 Context->FloatSave.ControlWord = FLOAT_SAVE_CONTROL;
57 Context->FloatSave.StatusWord = FLOAT_SAVE_STATUS;
58 Context->FloatSave.TagWord = FLOAT_SAVE_TAG;
59 Context->FloatSave.DataSelector = FLOAT_SAVE_DATA;
60 Context->Eip = (ULONG_PTR)StartAddress;
61 Context->SegGs = USER_DS;
62 Context->SegFs = TEB_SELECTOR;
63 Context->SegEs = USER_DS;
64 Context->SegDs = USER_DS;
65 Context->SegCs = USER_CS;
66 Context->SegSs = USER_DS;
67 Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR));
68 Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
70 /* write the parameters */
71 nErrCode = NtWriteVirtualMemory
74 ((PUCHAR)pStackBase) - nParamsSize,
81 if(!NT_SUCCESS(nErrCode)) return nErrCode;
83 /* write the return address */
84 return NtWriteVirtualMemory
87 ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),