update for HEAD-2003091401
[reactos.git] / 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 PUSER_STACK UserStack,
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(UserStack, &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 */