update for HEAD-2003091401
[reactos.git] / lib / rosrtl / thread / create.c
1 /* $Id$
2 */
3 /*
4 */
5
6 #include <stdarg.h>
7 #define NTOS_MODE_USER
8 #include <ntos.h>
9
10 #define NDEBUG
11 #include <ntdll/ntdll.h>
12
13 #include <rosrtl/thread.h>
14
15 NTSTATUS STDCALL
16 RtlRosCreateUserThread
17 (
18  IN HANDLE ProcessHandle,
19  IN POBJECT_ATTRIBUTES ObjectAttributes,
20  IN BOOLEAN CreateSuspended,
21  IN LONG StackZeroBits,
22  IN OUT PULONG StackReserve OPTIONAL,
23  IN OUT PULONG StackCommit OPTIONAL,
24  IN PVOID StartAddress,
25  OUT PHANDLE ThreadHandle OPTIONAL,
26  OUT PCLIENT_ID ClientId OPTIONAL,
27  IN ULONG ParameterCount,
28  IN ULONG_PTR * Parameters
29 )
30 {
31  USER_STACK usUserStack;
32  CONTEXT ctxInitialContext;
33  NTSTATUS nErrCode;
34  HANDLE hThread;
35  CLIENT_ID cidClientId;
36
37  if(ThreadHandle == NULL) ThreadHandle = &hThread;
38  if(ClientId == NULL) ClientId = &cidClientId;
39
40  /* allocate the stack for the thread */
41  nErrCode = RtlRosCreateStack
42  (
43   ProcessHandle,
44   &usUserStack,
45   StackZeroBits,
46   StackReserve,
47   StackCommit
48  );
49  
50  /* failure */
51  if(!NT_SUCCESS(nErrCode)) goto l_Fail;
52
53  /* initialize the registers and stack for the thread */
54  nErrCode = RtlRosInitializeContext
55  (
56   ProcessHandle,
57   &ctxInitialContext,
58   StartAddress,
59   &usUserStack,
60   ParameterCount,
61   Parameters
62  );
63
64  /* failure */
65  if(!NT_SUCCESS(nErrCode)) goto l_Fail;
66
67  /* create the thread object */
68  nErrCode = NtCreateThread
69  (
70   ThreadHandle,
71   THREAD_ALL_ACCESS,
72   ObjectAttributes,
73   ProcessHandle,
74   ClientId,
75   &ctxInitialContext,
76   &usUserStack,
77   CreateSuspended
78  );
79
80  /* failure */
81  if(!NT_SUCCESS(nErrCode)) goto l_Fail;
82
83  /* success */
84  return STATUS_SUCCESS;
85
86  /* failure */
87 l_Fail:
88  assert(!NT_SUCCESS(nErrCode));
89
90  /* deallocate the stack */
91  RtlRosDeleteStack(ProcessHandle, &usUserStack);
92  
93  return nErrCode;
94 }
95
96 NTSTATUS CDECL
97 RtlRosCreateUserThreadVa
98 (
99  IN HANDLE ProcessHandle,
100  IN POBJECT_ATTRIBUTES ObjectAttributes,
101  IN BOOLEAN CreateSuspended,
102  IN LONG StackZeroBits,
103  IN OUT PULONG StackReserve OPTIONAL,
104  IN OUT PULONG StackCommit OPTIONAL,
105  IN PVOID StartAddress,
106  OUT PHANDLE ThreadHandle OPTIONAL,
107  OUT PCLIENT_ID ClientId OPTIONAL,
108  IN ULONG ParameterCount,
109  ...
110 )
111 {
112  va_list vaArgs;
113  NTSTATUS nErrCode;
114  
115  va_start(vaArgs, ParameterCount);
116  
117  /*
118   FIXME: this code makes several non-portable assumptions:
119    - all parameters are passed on the stack
120    - the stack is a contiguous array of cells as large as an ULONG_PTR
121    - the stack grows downwards
122
123   This happens to work on the Intel x86, but is likely to bomb horribly on most
124   other platforms
125  */
126  nErrCode = RtlRosCreateUserThread
127  (
128   ProcessHandle,
129   ObjectAttributes,
130   CreateSuspended,
131   StackZeroBits,
132   StackReserve,
133   StackCommit,
134   StartAddress,
135   ThreadHandle,
136   ClientId,
137   ParameterCount,
138   (ULONG_PTR *)vaArgs
139  );
140
141  va_end(vaArgs);
142  
143  return nErrCode;
144 }
145
146 /* EOF */