- Go away STDCALL, time has come for WINAPI and NTAPI
[reactos.git] / reactos / lib / sdk / nt / entry_point.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS
4 * FILE: lib/nt/entry_point.c
5 * PURPOSE: Native NT Runtime Library
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 /* PSDK/NDK Headers */
12 #define WIN32_NO_STATUS
13 #include <stdio.h>
14 #include <windows.h>
15 #define NTOS_MODE_USER
16 #include <ndk/ntndk.h>
17
18 NTSTATUS
19 __cdecl
20 _main(
21 int argc,
22 char *argv[],
23 char *envp[],
24 ULONG DebugFlag
25 );
26
27 #define NDEBUG
28 #include <debug.h>
29
30 /* FUNCTIONS ****************************************************************/
31
32 static
33 VOID FASTCALL EnvironmentStringToUnicodeString (PWCHAR wsIn, PUNICODE_STRING usOut)
34 {
35 if (wsIn)
36 {
37 PWCHAR CurrentChar = wsIn;
38
39 while (*CurrentChar)
40 {
41 while(*CurrentChar++);
42 }
43 /* double nullterm at end */
44 CurrentChar++;
45
46 usOut->Buffer = wsIn;
47 /* FIXME: the last (double) nullterm should perhaps not be included in Length
48 * but only in MaximumLength. -Gunnar */
49 usOut->MaximumLength = usOut->Length = (CurrentChar-wsIn) * sizeof(WCHAR);
50 }
51 else
52 {
53 usOut->Buffer = NULL;
54 usOut->Length = usOut->MaximumLength = 0;
55 }
56 }
57
58
59
60 VOID
61 WINAPI
62 NtProcessStartup(PPEB Peb)
63 {
64 NTSTATUS Status;
65 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
66 PUNICODE_STRING CmdLineString;
67 ANSI_STRING AnsiCmdLine;
68 UNICODE_STRING UnicodeEnvironment;
69 ANSI_STRING AnsiEnvironment;
70 PCHAR NullPointer = NULL;
71 INT argc = 0;
72 PCHAR *argv;
73 PCHAR *envp;
74 PCHAR *ArgumentList;
75 PCHAR Source, Destination;
76 ULONG Length;
77 ASSERT(Peb);
78
79 #ifdef _M_ARM // Huge achievement
80 DPRINT1("%s(%08lx) called\n", __FUNCTION__, Peb);
81 while (TRUE);
82 #endif
83
84 /* Normalize and get the Process Parameters */
85 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
86 ASSERT(ProcessParameters);
87
88 /* Allocate memory for the argument list, enough for 512 tokens */
89 //FIXME: what if 512 is not enough????
90 ArgumentList = RtlAllocateHeap(RtlGetProcessHeap(), 0, 512 * sizeof(PCHAR));
91 if (!ArgumentList)
92 {
93 DPRINT1("ERR: no mem!");
94 Status = STATUS_NO_MEMORY;
95 goto fail;
96 }
97
98 /* Use a null pointer as default */
99 argv = &NullPointer;
100 envp = &NullPointer;
101
102 /* Set the first pointer to NULL, and set the argument array to the buffer */
103 *ArgumentList = NULL;
104 argv = ArgumentList;
105
106 /* Get the pointer to the Command Line */
107 CmdLineString = &ProcessParameters->CommandLine;
108
109 /* If we don't have a command line, use the image path instead */
110 if (!CmdLineString->Buffer || !CmdLineString->Length)
111 {
112 CmdLineString = &ProcessParameters->ImagePathName;
113 }
114
115 /* Convert it to an ANSI string */
116 Status = RtlUnicodeStringToAnsiString(&AnsiCmdLine, CmdLineString, TRUE);
117 if (!NT_SUCCESS(Status))
118 {
119 DPRINT1("ERR: no mem(guess)\n");
120 goto fail;
121 }
122
123 /* Save parameters for parsing */
124 Source = AnsiCmdLine.Buffer;
125 Length = AnsiCmdLine.Length;
126
127 /* Ensure it's valid */
128 if (Source)
129 {
130 /* Allocate a buffer for the destination */
131 Destination = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + sizeof(WCHAR));
132 if (!Destination)
133 {
134 DPRINT1("ERR: no mem!");
135 Status = STATUS_NO_MEMORY;
136 goto fail;
137 }
138
139 /* Start parsing */
140 while (*Source)
141 {
142 /* Skip the white space. */
143 while (*Source && *Source <= ' ') Source++;
144
145 /* Copy until the next white space is reached */
146 if (*Source)
147 {
148 /* Save one token pointer */
149 *ArgumentList++ = Destination;
150
151 /* Increase one token count */
152 argc++;
153
154 /* Copy token until white space */
155 while (*Source > ' ') *Destination++ = *Source++;
156
157 /* Null terminate it */
158 *Destination++ = '\0';
159 }
160 }
161 }
162
163 /* Null terminate the token pointer list */
164 *ArgumentList++ = NULL;
165
166 /* Now handle the enviornment, point the envp at our current list location. */
167 envp = ArgumentList;
168
169 if (ProcessParameters->Environment)
170 {
171 EnvironmentStringToUnicodeString(ProcessParameters->Environment, &UnicodeEnvironment);
172 Status = RtlUnicodeStringToAnsiString (& AnsiEnvironment, & UnicodeEnvironment, TRUE);
173 if (!NT_SUCCESS(Status))
174 {
175 DPRINT1("ERR: no mem(guess)\n");
176 goto fail;
177 }
178
179 ASSERT(AnsiEnvironment.Buffer);
180
181 Source = AnsiEnvironment.Buffer;
182 while (*Source)
183 {
184 /* Save a pointer to this token */
185 *ArgumentList++ = Source;
186
187 /* Keep looking for another variable */
188 while (*Source++);
189 }
190
191 /* Null terminate the list again */
192 *ArgumentList++ = NULL;
193 }
194 /* Breakpoint if we were requested to do so */
195 if (ProcessParameters->DebugFlags) DbgBreakPoint();
196
197 /* Call the Main Function */
198 Status = _main(argc, argv, envp, ProcessParameters->DebugFlags);
199
200 fail:
201 /* We're done here */
202 NtTerminateProcess(NtCurrentProcess(), Status);
203 }
204
205 /* EOF */