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