/* INCLUDES ****************************************************************/
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <kernel32/proc.h>
-#include <kernel32/thread.h>
-#include <wchar.h>
-#include <string.h>
-#include <napi/i386/segment.h>
-#include <ntdll/ldr.h>
-#include <napi/teb.h>
-#include <ntdll/base.h>
-#include <ntdll/rtl.h>
-#include <csrss/csrss.h>
-#include <ntdll/csr.h>
+#include <k32.h>
#define NDEBUG
#include <kernel32/kernel32.h>
-#include <kernel32/error.h>
/* FUNCTIONS ****************************************************************/
return Result;
}
+static int _except_recursion_trap = 0;
-static\r
-EXCEPTION_DISPOSITION\r
-__cdecl\r
-_except_handler(\r
- struct _EXCEPTION_RECORD *ExceptionRecord,\r
- void * EstablisherFrame,\r
- struct _CONTEXT *ContextRecord,\r
- void * DispatcherContext )\r
-{\r
- DPRINT("Process terminated abnormally...\n");\r
-\r
- if (/* FIXME: */ TRUE) /* Not a service */\r
- {\r
- ExitProcess(0);
+struct _CONTEXT;
+struct __EXCEPTION_RECORD;
+
+static
+EXCEPTION_DISPOSITION
+__cdecl
+_except_handler(
+ struct _EXCEPTION_RECORD *ExceptionRecord,
+ void * EstablisherFrame,
+ struct _CONTEXT *ContextRecord,
+ void * DispatcherContext )
+{
+ DPRINT("Process terminated abnormally...\n");
+
+ if (++_except_recursion_trap > 3) {
+ DPRINT("_except_handler(...) appears to be recursing.\n");
+ DPRINT("Process HALTED.\n");
+ for (;;) {}
+ }
+
+ if (/* FIXME: */ TRUE) /* Not a service */
+ {
+ DPRINT(" calling ExitProcess(0) no, lets try ExitThread . . .\n");
+ //ExitProcess(0);
+ ExitThread(0);
}
else
{
+ DPRINT(" calling ExitThread(0) . . .\n");
ExitThread(0);
}
+ DPRINT(" We should not get to here !!!\n");
/* We should not get to here */
return ExceptionContinueSearch;
-}\r
+}
VOID STDCALL
BaseProcessStart(LPTHREAD_START_ROUTINE lpStartAddress,
- DWORD lpParameter)
+ DWORD lpParameter)
{
UINT uExitCode = 0;
+ DPRINT("\nBaseProcessStart(..) - setting up exception frame.\n\n");
+
__try1(_except_handler)
{
- uExitCode = (lpStartAddress)(lpParameter);
+ uExitCode = (lpStartAddress)((PVOID)lpParameter);
} __except1
{
}
+ DPRINT("\nBaseProcessStart(..) - cleaned up exception frame.\n\n");
+
ExitThread(uExitCode);
}
/* create the PPB */
PpbBase = NULL;
- PpbSize = Ppb->AllocationSize;\r
+ PpbSize = Ppb->AllocationSize;
Status = NtAllocateVirtualMemory(ProcessHandle,
&PpbBase,
0,
return(Status);
}
- DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength);
+ //DPRINT("Ppb->MaximumLength %x\n", Ppb->MaximumLength);
NtWriteVirtualMemory(ProcessHandle,
PpbBase,
Ppb,
- Ppb->AllocationSize,\r
+ Ppb->AllocationSize,
&BytesWritten);
/* write pointer to environment */
{
s = TempApplicationNameW;
}
- s = wcsrchr(TempApplicationNameW, L'.');
+ s = wcsrchr(s, L'.');
if (s == NULL)
wcscat(TempApplicationNameW, L".exe");
}
hSection = KlMapFile (ImagePathName);
if (hSection == NULL)
{
- return FALSE;
+/////////////////////////////////////////
+ /*
+ * Inspect the image to determine executable flavour
+ */
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING ApplicationNameString;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
+ IMAGE_DOS_HEADER DosHeader;
+ IO_STATUS_BLOCK Iosb;
+ LARGE_INTEGER Offset;
+ HANDLE hFile = NULL;
+
+ DPRINT("Inspecting Image Header for image type id\n");
+
+ // Find the application name
+ if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpApplicationName,
+ &ApplicationNameString, NULL, NULL)) {
+ return FALSE;
+ }
+ DPRINT("ApplicationName %S\n",ApplicationNameString.Buffer);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &ApplicationNameString,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ SecurityDescriptor);
+
+ // Try to open the executable
+ Status = NtOpenFile(&hFile,
+ SYNCHRONIZE|FILE_EXECUTE|FILE_READ_DATA,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_DELETE|FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE);
+
+ RtlFreeUnicodeString(&ApplicationNameString);
+
+ if (!NT_SUCCESS(Status)) {
+ DPRINT("Failed to open file\n");
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ // Read the dos header
+ Offset.QuadPart = 0;
+ Status = ZwReadFile(hFile,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ &DosHeader,
+ sizeof(DosHeader),
+ &Offset,
+ 0);
+
+ if (!NT_SUCCESS(Status)) {
+ DPRINT("Failed to read from file\n");
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+ if (Iosb.Information != sizeof(DosHeader)) {
+ DPRINT("Failed to read dos header from file\n");
+ SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
+ return FALSE;
+ }
+
+ // Check the DOS signature
+ if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
+ DPRINT("Failed dos magic check\n");
+ SetLastErrorByStatus(STATUS_INVALID_IMAGE_FORMAT);
+ return FALSE;
+ }
+ NtClose(hFile);
+
+ DPRINT("Launching VDM...\n");
+ return CreateProcessW(L"ntvdm.exe",
+ (LPWSTR)lpApplicationName,
+ lpProcessAttributes,
+ lpThreadAttributes,
+ bInheritHandles,
+ dwCreationFlags,
+ lpEnvironment,
+ lpCurrentDirectory,
+ lpStartupInfo,
+ lpProcessInformation);
}
-
+/////////////////////////////////////////
/*
* Create a new process
*/
RuntimeInfo_U.Buffer = RtlAllocateHeap(GetProcessHeap(), 0, RuntimeInfo_U.Length);
memcpy(RuntimeInfo_U.Buffer, lpStartupInfo->lpReserved2, lpStartupInfo->cbReserved2);
}
- }
+ }
/*
* Create the PPB
if (lpStartupInfo && lpStartupInfo->lpReserved2)
RtlFreeHeap(GetProcessHeap(), 0, RuntimeInfo_U.Buffer);
-
+
/*
* Translate some handles for the new process
*/
- if (Ppb->CurrentDirectoryHandle)\r
+ if (Ppb->CurrentDirectoryHandle)
{
- Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->CurrentDirectoryHandle,\r
+ Status = NtDuplicateObject (NtCurrentProcess(),
+ Ppb->CurrentDirectoryHandle,
hProcess,
- &Ppb->CurrentDirectoryHandle,\r
+ &Ppb->CurrentDirectoryHandle,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
- if (Ppb->hConsole)\r
+ if (Ppb->hConsole)
{
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hConsole,\r
+ Ppb->hConsole,
hProcess,
- &Ppb->hConsole,\r
+ &Ppb->hConsole,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
// Set the child console handles
- Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;\r
- Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;\r
- Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;\r
+ Ppb->hStdInput = NtCurrentPeb()->ProcessParameters->hStdInput;
+ Ppb->hStdOutput = NtCurrentPeb()->ProcessParameters->hStdOutput;
+ Ppb->hStdError = NtCurrentPeb()->ProcessParameters->hStdError;
if (lpStartupInfo && (lpStartupInfo->dwFlags & STARTF_USESTDHANDLES))
{
if (lpStartupInfo->hStdInput)
- Ppb->hStdInput = lpStartupInfo->hStdInput;\r
+ Ppb->hStdInput = lpStartupInfo->hStdInput;
if (lpStartupInfo->hStdOutput)
- Ppb->hStdOutput = lpStartupInfo->hStdOutput;\r
+ Ppb->hStdOutput = lpStartupInfo->hStdOutput;
if (lpStartupInfo->hStdError)
- Ppb->hStdError = lpStartupInfo->hStdError;\r
+ Ppb->hStdError = lpStartupInfo->hStdError;
}
- if (IsConsoleHandle(Ppb->hStdInput))\r
+ if (IsConsoleHandle(Ppb->hStdInput))
{
- Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;\r
+ Ppb->hStdInput = CsrReply.Data.CreateProcessReply.InputHandle;
}
else
{
DPRINT("Duplicate input handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdInput,\r
+ Ppb->hStdInput,
hProcess,
- &Ppb->hStdInput,\r
+ &Ppb->hStdInput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
}
}
- if (IsConsoleHandle(Ppb->hStdOutput))\r
+ if (IsConsoleHandle(Ppb->hStdOutput))
{
- Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;\r
+ Ppb->hStdOutput = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate output handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdOutput,\r
+ Ppb->hStdOutput,
hProcess,
- &Ppb->hStdOutput,\r
+ &Ppb->hStdOutput,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
DPRINT("NtDuplicateObject failed, status %x\n", Status);
}
}
- if (IsConsoleHandle(Ppb->hStdError))\r
+ if (IsConsoleHandle(Ppb->hStdError))
{
- Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle;\r
+ Ppb->hStdError = CsrReply.Data.CreateProcessReply.OutputHandle;
}
else
{
DPRINT("Duplicate error handle\n");
Status = NtDuplicateObject (NtCurrentProcess(),
- Ppb->hStdError,\r
+ Ppb->hStdError,
hProcess,
- &Ppb->hStdError,\r
+ &Ppb->hStdError,
0,
TRUE,
DUPLICATE_SAME_ACCESS);
*/
if (lpStartupInfo)
{
- Ppb->dwFlags = lpStartupInfo->dwFlags;\r
- if (Ppb->dwFlags & STARTF_USESHOWWINDOW)\r
+ Ppb->dwFlags = lpStartupInfo->dwFlags;
+ if (Ppb->dwFlags & STARTF_USESHOWWINDOW)
{
- Ppb->wShowWindow = lpStartupInfo->wShowWindow;\r
+ Ppb->wShowWindow = lpStartupInfo->wShowWindow;
}
else
{
- Ppb->wShowWindow = SW_SHOWDEFAULT;\r
+ Ppb->wShowWindow = SW_SHOWDEFAULT;
}
- Ppb->dwX = lpStartupInfo->dwX;\r
- Ppb->dwY = lpStartupInfo->dwY;\r
- Ppb->dwXSize = lpStartupInfo->dwXSize;\r
- Ppb->dwYSize = lpStartupInfo->dwYSize;\r
- Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;\r
+ Ppb->dwX = lpStartupInfo->dwX;
+ Ppb->dwY = lpStartupInfo->dwY;
+ Ppb->dwXSize = lpStartupInfo->dwXSize;
+ Ppb->dwYSize = lpStartupInfo->dwYSize;
+ Ppb->dwFillAttribute = lpStartupInfo->dwFillAttribute;
}
else
{