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 DPRINT("%s(%08lx) called\n", __FUNCTION__
, Peb
);
81 /* Normalize and get the Process Parameters */
82 ProcessParameters
= RtlNormalizeProcessParams(Peb
->ProcessParameters
);
83 ASSERT(ProcessParameters
);
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
));
90 DPRINT1("ERR: no mem!");
91 Status
= STATUS_NO_MEMORY
;
95 /* Use a null pointer as default */
99 /* Set the first pointer to NULL, and set the argument array to the buffer */
100 *ArgumentList
= NULL
;
103 /* Get the pointer to the Command Line */
104 CmdLineString
= &ProcessParameters
->CommandLine
;
106 /* If we don't have a command line, use the image path instead */
107 if (!CmdLineString
->Buffer
|| !CmdLineString
->Length
)
109 CmdLineString
= &ProcessParameters
->ImagePathName
;
112 /* Convert it to an ANSI string */
113 Status
= RtlUnicodeStringToAnsiString(&AnsiCmdLine
, CmdLineString
, TRUE
);
114 if (!NT_SUCCESS(Status
))
116 DPRINT1("ERR: no mem(guess)\n");
120 /* Save parameters for parsing */
121 Source
= AnsiCmdLine
.Buffer
;
122 Length
= AnsiCmdLine
.Length
;
124 /* Ensure it's valid */
127 /* Allocate a buffer for the destination */
128 Destination
= RtlAllocateHeap(RtlGetProcessHeap(), 0, Length
+ sizeof(WCHAR
));
131 DPRINT1("ERR: no mem!");
132 Status
= STATUS_NO_MEMORY
;
139 /* Skip the white space. */
140 while (*Source
&& *Source
<= ' ') Source
++;
142 /* Copy until the next white space is reached */
145 /* Save one token pointer */
146 *ArgumentList
++ = Destination
;
148 /* Increase one token count */
151 /* Copy token until white space */
152 while (*Source
> ' ') *Destination
++ = *Source
++;
154 /* Null terminate it */
155 *Destination
++ = '\0';
160 /* Null terminate the token pointer list */
161 *ArgumentList
++ = NULL
;
163 /* Now handle the enviornment, point the envp at our current list location. */
166 if (ProcessParameters
->Environment
)
168 EnvironmentStringToUnicodeString(ProcessParameters
->Environment
, &UnicodeEnvironment
);
169 Status
= RtlUnicodeStringToAnsiString (& AnsiEnvironment
, & UnicodeEnvironment
, TRUE
);
170 if (!NT_SUCCESS(Status
))
172 DPRINT1("ERR: no mem(guess)\n");
176 ASSERT(AnsiEnvironment
.Buffer
);
178 Source
= AnsiEnvironment
.Buffer
;
181 /* Save a pointer to this token */
182 *ArgumentList
++ = Source
;
184 /* Keep looking for another variable */
188 /* Null terminate the list again */
189 *ArgumentList
++ = NULL
;
191 /* Breakpoint if we were requested to do so */
192 if (ProcessParameters
->DebugFlags
) DbgBreakPoint();
194 /* Call the Main Function */
195 Status
= _main(argc
, argv
, envp
, ProcessParameters
->DebugFlags
);
198 /* We're done here */
199 NtTerminateProcess(NtCurrentProcess(), Status
);