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