some more win32k 64 bit fixes
[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 STDCALL
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 DPRINT("%s(%08lx) called\n", __FUNCTION__, Peb);
80
81 /* Normalize and get the Process Parameters */
82 ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
83 ASSERT(ProcessParameters);
84
85 /* Allocate memory for the argument list, enough for 512 tokens */
86 //FIXME: what if 512 is not enough????
87 ArgumentList = RtlAllocateHeap(RtlGetProcessHeap(), 0, 512 * sizeof(PCHAR));
88 if (!ArgumentList)
89 {
90 DPRINT1("ERR: no mem!");
91 Status = STATUS_NO_MEMORY;
92 goto fail;
93 }
94
95 /* Use a null pointer as default */
96 argv = &NullPointer;
97 envp = &NullPointer;
98
99 /* Set the first pointer to NULL, and set the argument array to the buffer */
100 *ArgumentList = NULL;
101 argv = ArgumentList;
102
103 /* Get the pointer to the Command Line */
104 CmdLineString = &ProcessParameters->CommandLine;
105
106 /* If we don't have a command line, use the image path instead */
107 if (!CmdLineString->Buffer || !CmdLineString->Length)
108 {
109 CmdLineString = &ProcessParameters->ImagePathName;
110 }
111
112 /* Convert it to an ANSI string */
113 Status = RtlUnicodeStringToAnsiString(&AnsiCmdLine, CmdLineString, TRUE);
114 if (!NT_SUCCESS(Status))
115 {
116 DPRINT1("ERR: no mem(guess)\n");
117 goto fail;
118 }
119
120 /* Save parameters for parsing */
121 Source = AnsiCmdLine.Buffer;
122 Length = AnsiCmdLine.Length;
123
124 /* Ensure it's valid */
125 if (Source)
126 {
127 /* Allocate a buffer for the destination */
128 Destination = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + sizeof(WCHAR));
129 if (!Destination)
130 {
131 DPRINT1("ERR: no mem!");
132 Status = STATUS_NO_MEMORY;
133 goto fail;
134 }
135
136 /* Start parsing */
137 while (*Source)
138 {
139 /* Skip the white space. */
140 while (*Source && *Source <= ' ') Source++;
141
142 /* Copy until the next white space is reached */
143 if (*Source)
144 {
145 /* Save one token pointer */
146 *ArgumentList++ = Destination;
147
148 /* Increase one token count */
149 argc++;
150
151 /* Copy token until white space */
152 while (*Source > ' ') *Destination++ = *Source++;
153
154 /* Null terminate it */
155 *Destination++ = '\0';
156 }
157 }
158 }
159
160 /* Null terminate the token pointer list */
161 *ArgumentList++ = NULL;
162
163 /* Now handle the enviornment, point the envp at our current list location. */
164 envp = ArgumentList;
165
166 if (ProcessParameters->Environment)
167 {
168 EnvironmentStringToUnicodeString(ProcessParameters->Environment, &UnicodeEnvironment);
169 Status = RtlUnicodeStringToAnsiString (& AnsiEnvironment, & UnicodeEnvironment, TRUE);
170 if (!NT_SUCCESS(Status))
171 {
172 DPRINT1("ERR: no mem(guess)\n");
173 goto fail;
174 }
175
176 ASSERT(AnsiEnvironment.Buffer);
177
178 Source = AnsiEnvironment.Buffer;
179 while (*Source)
180 {
181 /* Save a pointer to this token */
182 *ArgumentList++ = Source;
183
184 /* Keep looking for another variable */
185 while (*Source++);
186 }
187
188 /* Null terminate the list again */
189 *ArgumentList++ = NULL;
190 }
191 /* Breakpoint if we were requested to do so */
192 if (ProcessParameters->DebugFlags) DbgBreakPoint();
193
194 /* Call the Main Function */
195 Status = _main(argc, argv, envp, ProcessParameters->DebugFlags);
196
197 fail:
198 /* We're done here */
199 NtTerminateProcess(NtCurrentProcess(), Status);
200 }
201
202 /* EOF */