2 * COPYRIGHT: See COPYING in the top level directory
4 * FILE: lib/nt/entry_point.c
5 * PURPOSE: Native NT Runtime Library
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
9 /* INCLUDES ******************************************************************/
11 /* PSDK/NDK Headers */
12 #define WIN32_NO_STATUS
15 #define NTOS_MODE_USER
16 #include <ndk/ntndk.h>
30 /* FUNCTIONS ****************************************************************/
33 VOID FASTCALL
EnvironmentStringToUnicodeString (PWCHAR wsIn
, PUNICODE_STRING usOut
)
37 PWCHAR CurrentChar
= wsIn
;
41 while(*CurrentChar
++);
43 /* double nullterm at end */
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
);
54 usOut
->Length
= usOut
->MaximumLength
= 0;
62 NtProcessStartup(PPEB Peb
)
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
;
75 PCHAR Source
, Destination
;
79 #ifdef _M_ARM // Huge achievement
80 DPRINT1("%s(%08lx) called\n", __FUNCTION__
, Peb
);
84 /* Normalize and get the Process Parameters */
85 ProcessParameters
= RtlNormalizeProcessParams(Peb
->ProcessParameters
);
86 ASSERT(ProcessParameters
);
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
));
93 DPRINT1("ERR: no mem!");
94 Status
= STATUS_NO_MEMORY
;
98 /* Use a null pointer as default */
102 /* Set the first pointer to NULL, and set the argument array to the buffer */
103 *ArgumentList
= NULL
;
106 /* Get the pointer to the Command Line */
107 CmdLineString
= &ProcessParameters
->CommandLine
;
109 /* If we don't have a command line, use the image path instead */
110 if (!CmdLineString
->Buffer
|| !CmdLineString
->Length
)
112 CmdLineString
= &ProcessParameters
->ImagePathName
;
115 /* Convert it to an ANSI string */
116 Status
= RtlUnicodeStringToAnsiString(&AnsiCmdLine
, CmdLineString
, TRUE
);
117 if (!NT_SUCCESS(Status
))
119 DPRINT1("ERR: no mem(guess)\n");
123 /* Save parameters for parsing */
124 Source
= AnsiCmdLine
.Buffer
;
125 Length
= AnsiCmdLine
.Length
;
127 /* Ensure it's valid */
130 /* Allocate a buffer for the destination */
131 Destination
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Length
+ sizeof(WCHAR
));
134 DPRINT1("ERR: no mem!");
135 Status
= STATUS_NO_MEMORY
;
142 /* Skip the white space. */
143 while (*Source
&& *Source
<= ' ') Source
++;
145 /* Copy until the next white space is reached */
148 /* Save one token pointer */
149 *ArgumentList
++ = Destination
;
151 /* Increase one token count */
154 /* Copy token until white space */
155 while (*Source
> ' ') *Destination
++ = *Source
++;
157 /* Null terminate it */
158 *Destination
++ = '\0';
163 /* Null terminate the token pointer list */
164 *ArgumentList
++ = NULL
;
166 /* Now handle the enviornment, point the envp at our current list location. */
169 if (ProcessParameters
->Environment
)
171 EnvironmentStringToUnicodeString(ProcessParameters
->Environment
, &UnicodeEnvironment
);
172 Status
= RtlUnicodeStringToAnsiString (& AnsiEnvironment
, & UnicodeEnvironment
, TRUE
);
173 if (!NT_SUCCESS(Status
))
175 DPRINT1("ERR: no mem(guess)\n");
179 ASSERT(AnsiEnvironment
.Buffer
);
181 Source
= AnsiEnvironment
.Buffer
;
184 /* Save a pointer to this token */
185 *ArgumentList
++ = Source
;
187 /* Keep looking for another variable */
191 /* Null terminate the list again */
192 *ArgumentList
++ = NULL
;
194 /* Breakpoint if we were requested to do so */
195 if (ProcessParameters
->DebugFlags
) DbgBreakPoint();
197 /* Call the Main Function */
198 Status
= _main(argc
, argv
, envp
, ProcessParameters
->DebugFlags
);
201 /* We're done here */
202 NtTerminateProcess(NtCurrentProcess(), Status
);