f8eefdd4f58f9a7ec6386b1b8a2cd458ab36e8da
[reactos.git] / reactos / lib / rosrtl / thread / i386 / context.c
1 /* $Id$
2 */
3 /*
4 */
5
6 #include <string.h>
7
8 #include <windows.h>
9 #define NTOS_MODE_USER
10 #include <ndk/ntndk.h>
11
12 #include <rosrtl/thread.h>
13
14 NTSTATUS NTAPI
15 RtlRosInitializeContext
16 (
17 IN HANDLE ProcessHandle,
18 OUT PCONTEXT Context,
19 IN PVOID StartAddress,
20 IN PINITIAL_TEB InitialTeb,
21 IN ULONG ParameterCount,
22 IN ULONG_PTR * Parameters
23 )
24 {
25 static PVOID s_pRetAddr = (PVOID)0xDEADBEEF;
26
27 ULONG nDummy;
28 SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
29 NTSTATUS nErrCode;
30 PVOID pStackBase;
31 PVOID pStackLimit;
32
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);
36
37 /* failure */
38 if(!NT_SUCCESS(nErrCode)) return nErrCode;
39
40 /* validate the stack */
41 nErrCode = RtlpRosValidateTopDownUserStack(pStackBase, pStackLimit);
42
43 /* failure */
44 if(!NT_SUCCESS(nErrCode)) return nErrCode;
45
46 /* too many parameters */
47 if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)((ULONG_PTR)pStackBase - (ULONG_PTR)pStackLimit))
48 return STATUS_STACK_OVERFLOW;
49
50 memset(Context, 0, sizeof(CONTEXT));
51
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);
67
68 /* write the parameters */
69 nErrCode = NtWriteVirtualMemory
70 (
71 ProcessHandle,
72 ((PUCHAR)pStackBase) - nParamsSize,
73 Parameters,
74 nParamsSize,
75 &nDummy
76 );
77
78 /* failure */
79 if(!NT_SUCCESS(nErrCode)) return nErrCode;
80
81 /* write the return address */
82 return NtWriteVirtualMemory
83 (
84 ProcessHandle,
85 ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
86 &s_pRetAddr,
87 sizeof(s_pRetAddr),
88 &nDummy
89 );
90 }
91
92 /* EOF */