ReactOS  0.4.14-dev-57-g333b8f1
entry_point.c
Go to the documentation of this file.
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 #define NTOS_MODE_USER
14 // #include <ndk/psfuncs.h>
15 #include <ndk/rtlfuncs.h>
16 
18 __cdecl
19 _main(
20  int argc,
21  char *argv[],
22  char *envp[],
23  ULONG DebugFlag
24 );
25 
26 #define NDEBUG
27 #include <debug.h>
28 
29 /* FUNCTIONS ****************************************************************/
30 
31 static
33 {
34  if (wsIn)
35  {
36  PWCHAR CurrentChar = wsIn;
37 
38  while (*CurrentChar)
39  {
40  while (*CurrentChar++);
41  }
42  /* Double NULL-termination at end */
43  CurrentChar++;
44 
45  usOut->Buffer = wsIn;
46  /* FIXME: the last (double) nullterm should perhaps not be included in Length
47  * but only in MaximumLength. -Gunnar */
48  usOut->MaximumLength = usOut->Length = (CurrentChar-wsIn) * sizeof(WCHAR);
49  }
50  else
51  {
52  usOut->Buffer = NULL;
53  usOut->Length = usOut->MaximumLength = 0;
54  }
55 }
56 
57 VOID
58 NTAPI
60 {
62  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
63  PUNICODE_STRING CmdLineString;
64  ANSI_STRING AnsiCmdLine;
65  UNICODE_STRING UnicodeEnvironment;
66  ANSI_STRING AnsiEnvironment;
67  PCHAR NullPointer = NULL;
68  INT argc = 0;
69  PCHAR *argv;
70  PCHAR *envp;
71  PCHAR *ArgumentList;
73  ULONG Length;
74  ASSERT(Peb);
75 
76 #ifdef _M_ARM // Huge achievement
77  DPRINT1("%s(%08lx) called\n", __FUNCTION__, Peb);
78  while (TRUE);
79 #endif
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!");
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!");
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 environment, 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 */
200 }
201 
202 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
static int argc
Definition: ServiceArgs.c:12
NTSTATUS __cdecl _main(int argc, char *argv[], char *envp[], ULONG DebugFlag)
#define TRUE
Definition: types.h:120
PPEB Peb
Definition: dllmain.c:27
#define __cdecl
Definition: accygwin.h:79
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI NtProcessStartup(PPEB Peb)
Definition: entry_point.c:59
uint16_t * PWCHAR
Definition: typedefs.h:54
#define argv
Definition: mplay32.c:18
void DbgBreakPoint()
Definition: mach.c:553
#define FASTCALL
Definition: nt_native.h:50
int32_t INT
Definition: typedefs.h:56
static VOID FASTCALL EnvironmentStringToUnicodeString(PWCHAR wsIn, PUNICODE_STRING usOut)
Definition: entry_point.c:32
NTSYSAPI PRTL_USER_PROCESS_PARAMETERS NTAPI RtlNormalizeProcessParams(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
UNICODE_STRING ImagePathName
Definition: btrfs_drv.h:1805
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1817
UNICODE_STRING CommandLine
Definition: btrfs_drv.h:1806
Status
Definition: gdiplustypes.h:24
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define __FUNCTION__
Definition: types.h:112