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