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
14 //#include <windows.h>
15 #define NTOS_MODE_USER
16 #include <ndk/psfuncs.h>
17 #include <ndk/rtlfuncs.h>
31 /* FUNCTIONS ****************************************************************/
34 VOID FASTCALL
EnvironmentStringToUnicodeString (PWCHAR wsIn
, PUNICODE_STRING usOut
)
38 PWCHAR CurrentChar
= wsIn
;
42 while(*CurrentChar
++);
44 /* double nullterm at end */
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
);
55 usOut
->Length
= usOut
->MaximumLength
= 0;
63 NtProcessStartup(PPEB Peb
)
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
;
76 PCHAR Source
, Destination
;
80 #ifdef _M_ARM // Huge achievement
81 DPRINT1("%s(%08lx) called\n", __FUNCTION__
, Peb
);
85 /* Normalize and get the Process Parameters */
86 ProcessParameters
= RtlNormalizeProcessParams(Peb
->ProcessParameters
);
87 ASSERT(ProcessParameters
);
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
));
94 DPRINT1("ERR: no mem!");
95 Status
= STATUS_NO_MEMORY
;
99 /* Use a null pointer as default */
103 /* Set the first pointer to NULL, and set the argument array to the buffer */
104 *ArgumentList
= NULL
;
107 /* Get the pointer to the Command Line */
108 CmdLineString
= &ProcessParameters
->CommandLine
;
110 /* If we don't have a command line, use the image path instead */
111 if (!CmdLineString
->Buffer
|| !CmdLineString
->Length
)
113 CmdLineString
= &ProcessParameters
->ImagePathName
;
116 /* Convert it to an ANSI string */
117 Status
= RtlUnicodeStringToAnsiString(&AnsiCmdLine
, CmdLineString
, TRUE
);
118 if (!NT_SUCCESS(Status
))
120 DPRINT1("ERR: no mem(guess)\n");
124 /* Save parameters for parsing */
125 Source
= AnsiCmdLine
.Buffer
;
126 Length
= AnsiCmdLine
.Length
;
128 /* Ensure it's valid */
131 /* Allocate a buffer for the destination */
132 Destination
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Length
+ sizeof(WCHAR
));
135 DPRINT1("ERR: no mem!");
136 Status
= STATUS_NO_MEMORY
;
143 /* Skip the white space. */
144 while (*Source
&& *Source
<= ' ') Source
++;
146 /* Copy until the next white space is reached */
149 /* Save one token pointer */
150 *ArgumentList
++ = Destination
;
152 /* Increase one token count */
155 /* Copy token until white space */
156 while (*Source
> ' ') *Destination
++ = *Source
++;
158 /* Null terminate it */
159 *Destination
++ = '\0';
164 /* Null terminate the token pointer list */
165 *ArgumentList
++ = NULL
;
167 /* Now handle the environment, point the envp at our current list location. */
170 if (ProcessParameters
->Environment
)
172 EnvironmentStringToUnicodeString(ProcessParameters
->Environment
, &UnicodeEnvironment
);
173 Status
= RtlUnicodeStringToAnsiString (& AnsiEnvironment
, & UnicodeEnvironment
, TRUE
);
174 if (!NT_SUCCESS(Status
))
176 DPRINT1("ERR: no mem(guess)\n");
180 ASSERT(AnsiEnvironment
.Buffer
);
182 Source
= AnsiEnvironment
.Buffer
;
185 /* Save a pointer to this token */
186 *ArgumentList
++ = Source
;
188 /* Keep looking for another variable */
192 /* Null terminate the list again */
193 *ArgumentList
++ = NULL
;
195 /* Breakpoint if we were requested to do so */
196 if (ProcessParameters
->DebugFlags
) DbgBreakPoint();
198 /* Call the Main Function */
199 Status
= _main(argc
, argv
, envp
, ProcessParameters
->DebugFlags
);
202 /* We're done here */
203 NtTerminateProcess(NtCurrentProcess(), Status
);