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 PINITIAL_TEB InitialTeb
,
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(InitialTeb
, &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
)),