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