mirror of
https://github.com/reactos/reactos.git
synced 2024-11-05 22:26:39 +00:00
206 lines
5.3 KiB
C
206 lines
5.3 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS
|
|
* FILE: lib/nt/entry_point.c
|
|
* PURPOSE: Native NT Runtime Library
|
|
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
/* PSDK/NDK Headers */
|
|
#define WIN32_NO_STATUS
|
|
#include <stdio.h>
|
|
//#include <windows.h>
|
|
#define NTOS_MODE_USER
|
|
#include <ndk/psfuncs.h>
|
|
#include <ndk/rtlfuncs.h>
|
|
|
|
NTSTATUS
|
|
__cdecl
|
|
_main(
|
|
int argc,
|
|
char *argv[],
|
|
char *envp[],
|
|
ULONG DebugFlag
|
|
);
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
static
|
|
VOID FASTCALL EnvironmentStringToUnicodeString (PWCHAR wsIn, PUNICODE_STRING usOut)
|
|
{
|
|
if (wsIn)
|
|
{
|
|
PWCHAR CurrentChar = wsIn;
|
|
|
|
while (*CurrentChar)
|
|
{
|
|
while(*CurrentChar++);
|
|
}
|
|
/* double nullterm at end */
|
|
CurrentChar++;
|
|
|
|
usOut->Buffer = wsIn;
|
|
/* FIXME: the last (double) nullterm should perhaps not be included in Length
|
|
* but only in MaximumLength. -Gunnar */
|
|
usOut->MaximumLength = usOut->Length = (CurrentChar-wsIn) * sizeof(WCHAR);
|
|
}
|
|
else
|
|
{
|
|
usOut->Buffer = NULL;
|
|
usOut->Length = usOut->MaximumLength = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
WINAPI
|
|
NtProcessStartup(PPEB Peb)
|
|
{
|
|
NTSTATUS Status;
|
|
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
|
|
PUNICODE_STRING CmdLineString;
|
|
ANSI_STRING AnsiCmdLine;
|
|
UNICODE_STRING UnicodeEnvironment;
|
|
ANSI_STRING AnsiEnvironment;
|
|
PCHAR NullPointer = NULL;
|
|
INT argc = 0;
|
|
PCHAR *argv;
|
|
PCHAR *envp;
|
|
PCHAR *ArgumentList;
|
|
PCHAR Source, Destination;
|
|
ULONG Length;
|
|
ASSERT(Peb);
|
|
|
|
#ifdef _M_ARM // Huge achievement
|
|
DPRINT1("%s(%08lx) called\n", __FUNCTION__, Peb);
|
|
while (TRUE);
|
|
#endif
|
|
|
|
/* Normalize and get the Process Parameters */
|
|
ProcessParameters = RtlNormalizeProcessParams(Peb->ProcessParameters);
|
|
ASSERT(ProcessParameters);
|
|
|
|
/* Allocate memory for the argument list, enough for 512 tokens */
|
|
//FIXME: what if 512 is not enough????
|
|
ArgumentList = RtlAllocateHeap(RtlGetProcessHeap(), 0, 512 * sizeof(PCHAR));
|
|
if (!ArgumentList)
|
|
{
|
|
DPRINT1("ERR: no mem!");
|
|
Status = STATUS_NO_MEMORY;
|
|
goto fail;
|
|
}
|
|
|
|
/* Use a null pointer as default */
|
|
argv = &NullPointer;
|
|
envp = &NullPointer;
|
|
|
|
/* Set the first pointer to NULL, and set the argument array to the buffer */
|
|
*ArgumentList = NULL;
|
|
argv = ArgumentList;
|
|
|
|
/* Get the pointer to the Command Line */
|
|
CmdLineString = &ProcessParameters->CommandLine;
|
|
|
|
/* If we don't have a command line, use the image path instead */
|
|
if (!CmdLineString->Buffer || !CmdLineString->Length)
|
|
{
|
|
CmdLineString = &ProcessParameters->ImagePathName;
|
|
}
|
|
|
|
/* Convert it to an ANSI string */
|
|
Status = RtlUnicodeStringToAnsiString(&AnsiCmdLine, CmdLineString, TRUE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("ERR: no mem(guess)\n");
|
|
goto fail;
|
|
}
|
|
|
|
/* Save parameters for parsing */
|
|
Source = AnsiCmdLine.Buffer;
|
|
Length = AnsiCmdLine.Length;
|
|
|
|
/* Ensure it's valid */
|
|
if (Source)
|
|
{
|
|
/* Allocate a buffer for the destination */
|
|
Destination = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length + sizeof(WCHAR));
|
|
if (!Destination)
|
|
{
|
|
DPRINT1("ERR: no mem!");
|
|
Status = STATUS_NO_MEMORY;
|
|
goto fail;
|
|
}
|
|
|
|
/* Start parsing */
|
|
while (*Source)
|
|
{
|
|
/* Skip the white space. */
|
|
while (*Source && *Source <= ' ') Source++;
|
|
|
|
/* Copy until the next white space is reached */
|
|
if (*Source)
|
|
{
|
|
/* Save one token pointer */
|
|
*ArgumentList++ = Destination;
|
|
|
|
/* Increase one token count */
|
|
argc++;
|
|
|
|
/* Copy token until white space */
|
|
while (*Source > ' ') *Destination++ = *Source++;
|
|
|
|
/* Null terminate it */
|
|
*Destination++ = '\0';
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Null terminate the token pointer list */
|
|
*ArgumentList++ = NULL;
|
|
|
|
/* Now handle the environment, point the envp at our current list location. */
|
|
envp = ArgumentList;
|
|
|
|
if (ProcessParameters->Environment)
|
|
{
|
|
EnvironmentStringToUnicodeString(ProcessParameters->Environment, &UnicodeEnvironment);
|
|
Status = RtlUnicodeStringToAnsiString (& AnsiEnvironment, & UnicodeEnvironment, TRUE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("ERR: no mem(guess)\n");
|
|
goto fail;
|
|
}
|
|
|
|
ASSERT(AnsiEnvironment.Buffer);
|
|
|
|
Source = AnsiEnvironment.Buffer;
|
|
while (*Source)
|
|
{
|
|
/* Save a pointer to this token */
|
|
*ArgumentList++ = Source;
|
|
|
|
/* Keep looking for another variable */
|
|
while (*Source++);
|
|
}
|
|
|
|
/* Null terminate the list again */
|
|
*ArgumentList++ = NULL;
|
|
}
|
|
/* Breakpoint if we were requested to do so */
|
|
if (ProcessParameters->DebugFlags) DbgBreakPoint();
|
|
|
|
/* Call the Main Function */
|
|
Status = _main(argc, argv, envp, ProcessParameters->DebugFlags);
|
|
|
|
fail:
|
|
/* We're done here */
|
|
NtTerminateProcess(NtCurrentProcess(), Status);
|
|
}
|
|
|
|
/* EOF */
|