blob: 396d28555989cbfdeed7b525c8c2968a9ab8eb47 [file] [log] [blame] [raw]
#include <windows.h>
#include <nt.h>
#include <string.h>
#include <wchar.h>
#define malloc(S) RtlAllocateHeap(Heap, 0, S)
#define realloc(P, S) RtlReAllocateHeap(Heap, 0, P, S)
#define free(P) RtlFreeHeap(Heap, 0, P)
extern int main(int, char **, char **);
static void *Heap;
static void (**exit_functions)(void) = NULL;
int atexit(void (*function)(void)) {
if(!function) return -1;
if(!exit_functions) {
exit_functions = malloc(2 * sizeof(void (*)(void)));
if(!exit_functions) return -1;
exit_functions[0] = function;
exit_functions[1] = NULL;
return 0;
}
int i = 0;
while(exit_functions[i]) {
if(exit_functions[i] == function) return 0;
}
void (**p)(void) = realloc(exit_functions, (i + 2) * sizeof(void (*)(void)));
if(!p) return -1;
exit_functions = p;
exit_functions[i++] = function;
exit_functions[i] = NULL;
return 0;
}
void exit(int status) {
while(exit_functions) (*exit_functions++)();
NtTerminateProcess((void *)-1, status);
while(1);
}
void __main() {}
static int _parse_tokens(char *string, char ***tokens, int length) {
/* Extract whitespace- and quotes- delimited tokens from the given string
and put them into the tokens array. Returns number of tokens
extracted. Length specifies the current size of tokens[].
THIS METHOD MODIFIES string. */
const char *whitespace = " \t\r\n";
char *tokenEnd;
const char *quoteCharacters = "\"\'";
char *end = string + strlen(string);
if (!string) return length;
while(1) {
const char *q;
/* Skip over initial whitespace. */
string += strspn(string, whitespace);
if(!*string) break;
for(q = quoteCharacters; *q; ++q) {
if(*string == *q) break;
}
if(*q) {
/* Token is quoted. */
char quote = *string++;
tokenEnd = strchr(string, quote);
/* If there is no endquote, the token is the rest of the string. */
if(!tokenEnd) tokenEnd = end;
} else {
tokenEnd = string + strcspn(string, whitespace);
}
*tokenEnd = 0;
{
char **new_tokens;
int newlen = length + 1;
new_tokens = realloc(*tokens, (newlen + 1) * sizeof(char *));
if(!new_tokens) {
/* Out of memory. */
return -1;
}
*tokens = new_tokens;
(*tokens)[length] = string;
length = newlen;
}
if(tokenEnd == end) break;
string = tokenEnd + 1;
}
return length;
}
static void _getmainargs(int *argc, char ***argv, wchar_t *wcommandline) {
int commandline_len = 0;
if(wcommandline) commandline_len = wcslen(wcommandline) * 2;
*argv = malloc(sizeof (char *) * 1);
if(!*argv) ExitProcess(-1);
**argv = malloc(commandline_len + 1);
if(!**argv) ExitProcess(-1);
if(commandline_len > 0) {
char *argv0 = **argv;
wcstombs(argv0, wcommandline, commandline_len + 1);
*argc = _parse_tokens(argv0, argv, 0);
if(*argc < 0) ExitProcess(-1);
}
(*argv)[*argc] = 0;
return;
}
void NtProcessStartup() {
int _argc = 0;
char **_argv = 0;
char **_envp = 0;
PROCESS_BASIC_INFORMATION pbi;
RTL_USER_PROCESS_PARAMETERS *process_parameters;
NtQueryInformationProcess((void *)-1, ProcessBasicInformation, &pbi, sizeof pbi, NULL);
process_parameters = RtlNormalizeProcessParams(pbi.PebBaseAddress->ProcessParameters);
Heap = pbi.PebBaseAddress->ProcessHeap = RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
_getmainargs(&_argc, &_argv, process_parameters->CommandLine.Buffer);
wchar_t *s = process_parameters->Environment;
if(s) {
char **e = _envp = malloc(256 * sizeof(char *));
while(*s && e - _envp < 256 - 1) {
size_t len = wcslen(s) * 2;
*e = malloc(len * sizeof(char));
wcstombs(*e++, s, len);
while(*s++);
}
*e = NULL;
}
exit(main(_argc, _argv, _envp));
}