10 #include <rosrtl/thread.h>
14 RtlRosInitializeContext
16 IN HANDLE ProcessHandle
,
18 IN PVOID StartAddress
,
19 IN PINITIAL_TEB InitialTeb
,
20 IN ULONG ParameterCount
,
21 IN ULONG_PTR
* Parameters
24 static PVOID s_pRetAddr
= (PVOID
)0xDEADBEEF;
27 SIZE_T nParamsSize
= ParameterCount
* sizeof(ULONG_PTR
);
32 /* Intel x86: linear top-down stack, all parameters passed on the stack */
33 /* get the stack base and limit */
34 nErrCode
= RtlpRosGetStackLimits(InitialTeb
, &pStackBase
, &pStackLimit
);
37 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
39 /* validate the stack */
40 nErrCode
= RtlpRosValidateTopDownUserStack(pStackBase
, pStackLimit
);
43 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
45 /* too many parameters */
46 if((nParamsSize
+ sizeof(ULONG_PTR
)) > (SIZE_T
)((ULONG_PTR
)pStackBase
- (ULONG_PTR
)pStackLimit
))
47 return STATUS_STACK_OVERFLOW
;
49 memset(Context
, 0, sizeof(CONTEXT
));
51 /* initialize the context */
52 Context
->ContextFlags
= CONTEXT_FULL
;
53 Context
->FloatSave
.ControlWord
= FLOAT_SAVE_CONTROL
;
54 Context
->FloatSave
.StatusWord
= FLOAT_SAVE_STATUS
;
55 Context
->FloatSave
.TagWord
= FLOAT_SAVE_TAG
;
56 Context
->FloatSave
.DataSelector
= FLOAT_SAVE_DATA
;
57 Context
->Eip
= (ULONG_PTR
)StartAddress
;
58 Context
->SegGs
= USER_DS
;
59 Context
->SegFs
= TEB_SELECTOR
;
60 Context
->SegEs
= USER_DS
;
61 Context
->SegDs
= USER_DS
;
62 Context
->SegCs
= USER_CS
;
63 Context
->SegSs
= USER_DS
;
64 Context
->Esp
= (ULONG_PTR
)pStackBase
- (nParamsSize
+ sizeof(ULONG_PTR
));
65 Context
->EFlags
= ((ULONG_PTR
)1 << 1) | ((ULONG_PTR
)1 << 9);
67 /* write the parameters */
68 nErrCode
= NtWriteVirtualMemory
71 ((PUCHAR
)pStackBase
) - nParamsSize
,
78 if(!NT_SUCCESS(nErrCode
)) return nErrCode
;
80 /* write the return address */
81 return NtWriteVirtualMemory
84 ((PUCHAR
)pStackBase
) - (nParamsSize
+ sizeof(ULONG_PTR
)),