10 #include <ndk/ntndk.h>
12 #include <rosrtl/thread.h>
15 RtlRosInitializeContext
17 IN HANDLE ProcessHandle
,
19 IN PVOID StartAddress
,
20 IN PINITIAL_TEB InitialTeb
,
21 IN ULONG ParameterCount
,
22 IN ULONG_PTR
* Parameters
25 static PVOID s_pRetAddr
= (PVOID
)0xDEADBEEF;
28 SIZE_T nParamsSize
= ParameterCount
* sizeof(ULONG_PTR
);
33 /* Intel x86: linear top-down stack, all parameters passed on the stack */
34 /* get the stack base and limit */
35 nErrCode
= RtlpRosGetStackLimits(InitialTeb
, &pStackBase
, &pStackLimit
);
38 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
40 /* validate the stack */
41 nErrCode
= RtlpRosValidateTopDownUserStack(pStackBase
, pStackLimit
);
44 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
46 /* too many parameters */
47 if((nParamsSize
+ sizeof(ULONG_PTR
)) > (SIZE_T
)((ULONG_PTR
)pStackBase
- (ULONG_PTR
)pStackLimit
))
48 return STATUS_STACK_OVERFLOW
;
50 memset(Context
, 0, sizeof(CONTEXT
));
52 /* initialize the context */
53 Context
->ContextFlags
= CONTEXT_FULL
;
54 Context
->FloatSave
.ControlWord
= FLOAT_SAVE_CONTROL
;
55 Context
->FloatSave
.StatusWord
= FLOAT_SAVE_STATUS
;
56 Context
->FloatSave
.TagWord
= FLOAT_SAVE_TAG
;
57 Context
->FloatSave
.DataSelector
= FLOAT_SAVE_DATA
;
58 Context
->Eip
= (ULONG_PTR
)StartAddress
;
59 Context
->SegGs
= USER_DS
;
60 Context
->SegFs
= TEB_SELECTOR
;
61 Context
->SegEs
= USER_DS
;
62 Context
->SegDs
= USER_DS
;
63 Context
->SegCs
= USER_CS
;
64 Context
->SegSs
= USER_DS
;
65 Context
->Esp
= (ULONG_PTR
)pStackBase
- (nParamsSize
+ sizeof(ULONG_PTR
));
66 Context
->EFlags
= ((ULONG_PTR
)1 << 1) | ((ULONG_PTR
)1 << 9);
68 /* write the parameters */
69 nErrCode
= NtWriteVirtualMemory
72 ((PUCHAR
)pStackBase
) - nParamsSize
,
79 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
81 /* write the return address */
82 return NtWriteVirtualMemory
85 ((PUCHAR
)pStackBase
) - (nParamsSize
+ sizeof(ULONG_PTR
)),