mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented RtlCreateUserProcess() and RtlCreateUserThread().
svn path=/trunk/; revision=636
This commit is contained in:
parent
4027ccab60
commit
40bd704148
9 changed files with 833 additions and 16 deletions
|
@ -1,15 +1,27 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
#define NR_THREADS (0x1000)
|
#define NR_THREADS (0x5)
|
||||||
|
|
||||||
ULONG thread_main(PVOID param)
|
DWORD WINAPI
|
||||||
|
thread_main1(LPVOID param)
|
||||||
{
|
{
|
||||||
|
printf("Thread 1 running (Counter %lu)\n", (DWORD)param);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
DWORD WINAPI
|
||||||
|
thread_main2(LPVOID param)
|
||||||
{
|
{
|
||||||
unsigned int i=0;
|
printf("Thread 2 running (Counter %lu)\n", (DWORD)param);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
DWORD id;
|
DWORD id;
|
||||||
|
|
||||||
printf("Creating %d threads\n",NR_THREADS);
|
printf("Creating %d threads\n",NR_THREADS);
|
||||||
|
@ -17,9 +29,20 @@ int main()
|
||||||
{
|
{
|
||||||
CreateThread(NULL,
|
CreateThread(NULL,
|
||||||
0,
|
0,
|
||||||
thread_main,
|
thread_main1,
|
||||||
NULL,
|
(LPVOID)i,
|
||||||
|
0,
|
||||||
|
&id);
|
||||||
|
|
||||||
|
CreateThread(NULL,
|
||||||
|
0,
|
||||||
|
thread_main2,
|
||||||
|
(LPVOID)i,
|
||||||
0,
|
0,
|
||||||
&id);
|
&id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sleep (5000);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -808,4 +808,47 @@ RtlDenormalizeProcessParams (
|
||||||
IN OUT PSTARTUP_ARGUMENT pArgument
|
IN OUT PSTARTUP_ARGUMENT pArgument
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WINAPI
|
||||||
|
RtlInitializeContext(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
IN PCONTEXT Context,
|
||||||
|
IN HANDLE DebugPort,
|
||||||
|
IN PVOID StartAddress,
|
||||||
|
IN OUT PINITIAL_TEB InitialTeb
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
WINAPI
|
||||||
|
RtlCreateUserThread(
|
||||||
|
IN HANDLE ProcessHandle,
|
||||||
|
IN PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
IN BOOLEAN CreateSuspended,
|
||||||
|
IN LONG StackZeroBits,
|
||||||
|
IN OUT PULONG StackReserved,
|
||||||
|
IN OUT PULONG StackCommit,
|
||||||
|
IN PVOID StartAddress,
|
||||||
|
IN HANDLE DebugPort,
|
||||||
|
IN OUT PHANDLE ThreadHandle,
|
||||||
|
IN OUT PCLIENT_ID ClientId
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
STDCALL
|
||||||
|
RtlCreateUserProcess(PUNICODE_STRING ApplicationName,
|
||||||
|
PSECURITY_DESCRIPTOR ProcessSd,
|
||||||
|
PSECURITY_DESCRIPTOR ThreadSd,
|
||||||
|
WINBOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
// LPVOID lpEnvironment,
|
||||||
|
// LPCWSTR lpCurrentDirectory,
|
||||||
|
// LPSTARTUPINFO lpStartupInfo,
|
||||||
|
PCLIENT_ID ClientId,
|
||||||
|
PHANDLE ProcessHandle,
|
||||||
|
PHANDLE ThreadHandle);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __DDK_RTL_H */
|
#endif /* __DDK_RTL_H */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: ntdll.def,v 1.13 1999/08/29 06:59:04 ea Exp $
|
; $Id: ntdll.def,v 1.14 1999/09/04 18:32:57 ekohl Exp $
|
||||||
;
|
;
|
||||||
; ReactOS Operating System
|
; ReactOS Operating System
|
||||||
;
|
;
|
||||||
|
@ -431,6 +431,8 @@ RtlAppendUnicodeStringToString
|
||||||
RtlAppendUnicodeToString
|
RtlAppendUnicodeToString
|
||||||
RtlCharToInteger
|
RtlCharToInteger
|
||||||
RtlCreateHeap@24
|
RtlCreateHeap@24
|
||||||
|
RtlCreateUserProcess@32
|
||||||
|
RtlCreateUserThread@40
|
||||||
RtlCompactHeap@8
|
RtlCompactHeap@8
|
||||||
RtlCompareString
|
RtlCompareString
|
||||||
RtlCompareUnicodeString
|
RtlCompareUnicodeString
|
||||||
|
@ -447,6 +449,7 @@ RtlFreeHeap@12
|
||||||
RtlFreeUnicodeString
|
RtlFreeUnicodeString
|
||||||
RtlGetProcessHeap@0
|
RtlGetProcessHeap@0
|
||||||
RtlInitAnsiString
|
RtlInitAnsiString
|
||||||
|
RtlInitializeContext@20
|
||||||
RtlInitString
|
RtlInitString
|
||||||
RtlInitUnicodeString
|
RtlInitUnicodeString
|
||||||
RtlIntegerToUnicodeString
|
RtlIntegerToUnicodeString
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
; $Id: ntdll.edf,v 1.4 1999/08/29 06:59:04 ea Exp $
|
; $Id: ntdll.edf,v 1.5 1999/09/04 18:32:57 ekohl Exp $
|
||||||
;
|
;
|
||||||
; ReactOS Operating System
|
; ReactOS Operating System
|
||||||
;
|
;
|
||||||
|
@ -431,6 +431,8 @@ RtlAppendUnicodeStringToString
|
||||||
RtlAppendUnicodeToString
|
RtlAppendUnicodeToString
|
||||||
RtlCharToInteger
|
RtlCharToInteger
|
||||||
RtlCreateHeap=RtlCreateHeap@24
|
RtlCreateHeap=RtlCreateHeap@24
|
||||||
|
RtlCreateUserProcess=RtlCreateUserProcess@32
|
||||||
|
RtlCreateUserThread=RtlCreateUserThread@40
|
||||||
RtlCompactHeap=RtlCompactHeap@8
|
RtlCompactHeap=RtlCompactHeap@8
|
||||||
RtlCompareString
|
RtlCompareString
|
||||||
RtlCompareUnicodeString
|
RtlCompareUnicodeString
|
||||||
|
@ -447,6 +449,7 @@ RtlFreeHeap=RtlFreeHeap@12
|
||||||
RtlFreeUnicodeString
|
RtlFreeUnicodeString
|
||||||
RtlGetProcessHeap=RtlGetProcessHeap@0
|
RtlGetProcessHeap=RtlGetProcessHeap@0
|
||||||
RtlInitAnsiString
|
RtlInitAnsiString
|
||||||
|
RtlInitializeContext=RtlInitializeContext@20
|
||||||
RtlInitString
|
RtlInitString
|
||||||
RtlInitUnicodeString
|
RtlInitUnicodeString
|
||||||
RtlIntegerToUnicodeString
|
RtlIntegerToUnicodeString
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.22 1999/08/29 13:44:57 dwelch Exp $
|
# $Id: makefile,v 1.23 1999/09/04 18:35:48 ekohl Exp $
|
||||||
#
|
#
|
||||||
# ReactOS Operating System
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -24,7 +24,8 @@ endif
|
||||||
all: $(DLLTARGET)
|
all: $(DLLTARGET)
|
||||||
|
|
||||||
RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \
|
RTL_OBJECTS = rtl/critical.o rtl/error.o rtl/heap.o rtl/largeint.o \
|
||||||
rtl/mem.o rtl/namespc.o rtl/security.o rtl/unicode.o
|
rtl/mem.o rtl/namespc.o rtl/security.o rtl/unicode.o \
|
||||||
|
rtl/thread.o rtl/process.o
|
||||||
|
|
||||||
STDLIB_OBJECTS = stdlib/atoi.o stdlib/atol.o stdlib/splitp.o \
|
STDLIB_OBJECTS = stdlib/atoi.o stdlib/atol.o stdlib/splitp.o \
|
||||||
stdlib/strtol.o stdlib/strtoul.o
|
stdlib/strtol.o stdlib/strtoul.o
|
||||||
|
|
403
reactos/lib/ntdll/rtl/process.c
Normal file
403
reactos/lib/ntdll/rtl/process.c
Normal file
|
@ -0,0 +1,403 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS system libraries
|
||||||
|
* FILE: lib/ntdll/rtl/process.c
|
||||||
|
* PURPOSE: Process functions
|
||||||
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
||||||
|
* UPDATE HISTORY:
|
||||||
|
* Created 01/11/98
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ****************************************************************/
|
||||||
|
|
||||||
|
#define WIN32_NO_PEHDR
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
//#include <windows.h>
|
||||||
|
//#include <kernel32/proc.h>
|
||||||
|
//#include <kernel32/thread.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pe.h>
|
||||||
|
#include <internal/i386/segment.h>
|
||||||
|
#include <ntdll/ldr.h>
|
||||||
|
#include <internal/teb.h>
|
||||||
|
#include <ntdll/base.h>
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#define STACK_TOP (0xb0000000)
|
||||||
|
|
||||||
|
static HANDLE STDCALL
|
||||||
|
RtlpCreateFirstThread(HANDLE ProcessHandle,
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
||||||
|
DWORD dwStackSize,
|
||||||
|
LPTHREAD_START_ROUTINE lpStartAddress,
|
||||||
|
LPVOID lpParameter,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPDWORD lpThreadId,
|
||||||
|
PWSTR lpCommandLine,
|
||||||
|
HANDLE NTDllSectionHandle,
|
||||||
|
HANDLE SectionHandle,
|
||||||
|
PVOID ImageBase)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE ThreadHandle;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
CONTEXT ThreadContext;
|
||||||
|
INITIAL_TEB InitialTeb;
|
||||||
|
BOOLEAN CreateSuspended = FALSE;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
ULONG BytesWritten;
|
||||||
|
HANDLE DupNTDllSectionHandle, DupSectionHandle;
|
||||||
|
|
||||||
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||||
|
ObjectAttributes.RootDirectory = NULL;
|
||||||
|
ObjectAttributes.ObjectName = NULL;
|
||||||
|
ObjectAttributes.Attributes = 0;
|
||||||
|
// ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||||
|
ObjectAttributes.SecurityDescriptor = SecurityDescriptor;
|
||||||
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
if ((dwCreationFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED)
|
||||||
|
CreateSuspended = TRUE;
|
||||||
|
else
|
||||||
|
CreateSuspended = FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)(STACK_TOP - dwStackSize);
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&BaseAddress,
|
||||||
|
0,
|
||||||
|
(PULONG)&dwStackSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
memset(&ThreadContext,0,sizeof(CONTEXT));
|
||||||
|
ThreadContext.Eip = (ULONG)lpStartAddress;
|
||||||
|
ThreadContext.SegGs = USER_DS;
|
||||||
|
ThreadContext.SegFs = USER_DS;
|
||||||
|
ThreadContext.SegEs = USER_DS;
|
||||||
|
ThreadContext.SegDs = USER_DS;
|
||||||
|
ThreadContext.SegCs = USER_CS;
|
||||||
|
ThreadContext.SegSs = USER_DS;
|
||||||
|
ThreadContext.Esp = STACK_TOP - 16;
|
||||||
|
ThreadContext.EFlags = (1<<1) + (1<<9);
|
||||||
|
|
||||||
|
DPRINT("ThreadContext.Eip %x\n",ThreadContext.Eip);
|
||||||
|
|
||||||
|
NtDuplicateObject(NtCurrentProcess(),
|
||||||
|
&SectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
&DupSectionHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
NtDuplicateObject(NtCurrentProcess(),
|
||||||
|
&NTDllSectionHandle,
|
||||||
|
ProcessHandle,
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
DUPLICATE_SAME_ACCESS);
|
||||||
|
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 4),
|
||||||
|
&DupNTDllSectionHandle,
|
||||||
|
sizeof(DupNTDllSectionHandle),
|
||||||
|
&BytesWritten);
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 8),
|
||||||
|
&ImageBase,
|
||||||
|
sizeof(ImageBase),
|
||||||
|
&BytesWritten);
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)(STACK_TOP - 12),
|
||||||
|
&DupSectionHandle,
|
||||||
|
sizeof(DupSectionHandle),
|
||||||
|
&BytesWritten);
|
||||||
|
|
||||||
|
|
||||||
|
Status = NtCreateThread(&ThreadHandle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
ProcessHandle,
|
||||||
|
&ClientId,
|
||||||
|
&ThreadContext,
|
||||||
|
&InitialTeb,
|
||||||
|
CreateSuspended);
|
||||||
|
if ( lpThreadId != NULL )
|
||||||
|
memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
||||||
|
|
||||||
|
return ThreadHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
RtlpMapFile(PUNICODE_STRING ApplicationName,
|
||||||
|
PIMAGE_NT_HEADERS Headers,
|
||||||
|
PIMAGE_DOS_HEADER DosHeader,
|
||||||
|
PHANDLE Section)
|
||||||
|
{
|
||||||
|
HANDLE hFile;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
LARGE_INTEGER FileOffset;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
hFile = NULL;
|
||||||
|
*Section = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
DPRINT("ApplicationName %w\n", ApplicationName->Buffer);
|
||||||
|
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
|
ApplicationName,
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Status = NtReadFile(hFile,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
DosHeader,
|
||||||
|
sizeof(IMAGE_DOS_HEADER),
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
FileOffset.u.LowPart = DosHeader->e_lfanew;
|
||||||
|
FileOffset.u.HighPart = 0;
|
||||||
|
|
||||||
|
Status = NtReadFile(hFile,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&IoStatusBlock,
|
||||||
|
Headers,
|
||||||
|
sizeof(IMAGE_NT_HEADERS),
|
||||||
|
&FileOffset,
|
||||||
|
NULL);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Status = NtCreateSection(Section,
|
||||||
|
SECTION_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
PAGE_EXECUTE,
|
||||||
|
SEC_IMAGE,
|
||||||
|
hFile);
|
||||||
|
NtClose(hFile);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
RtlpCreatePeb(HANDLE ProcessHandle, PUNICODE_STRING CommandLine)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID PebBase;
|
||||||
|
ULONG PebSize;
|
||||||
|
NT_PEB Peb;
|
||||||
|
ULONG BytesWritten;
|
||||||
|
PVOID StartupInfoBase;
|
||||||
|
ULONG StartupInfoSize;
|
||||||
|
PROCESSINFOW StartupInfo;
|
||||||
|
|
||||||
|
PebBase = (PVOID)PEB_BASE;
|
||||||
|
PebSize = 0x1000;
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&PebBase,
|
||||||
|
0,
|
||||||
|
&PebSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return(Status);
|
||||||
|
|
||||||
|
memset(&Peb, 0, sizeof(Peb));
|
||||||
|
Peb.StartupInfo = (PPROCESSINFOW)PEB_STARTUPINFO;
|
||||||
|
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)PEB_BASE,
|
||||||
|
&Peb,
|
||||||
|
sizeof(Peb),
|
||||||
|
&BytesWritten);
|
||||||
|
|
||||||
|
StartupInfoBase = (PVOID)PEB_STARTUPINFO;
|
||||||
|
StartupInfoSize = 0x1000;
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&StartupInfoBase,
|
||||||
|
0,
|
||||||
|
&StartupInfoSize,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return(Status);
|
||||||
|
|
||||||
|
memset(&StartupInfo, 0, sizeof(StartupInfo));
|
||||||
|
wcscpy(StartupInfo.CommandLine, CommandLine->Buffer);
|
||||||
|
|
||||||
|
DPRINT("StartupInfoSize %x\n",StartupInfoSize);
|
||||||
|
NtWriteVirtualMemory(ProcessHandle,
|
||||||
|
(PVOID)PEB_STARTUPINFO,
|
||||||
|
&StartupInfo,
|
||||||
|
StartupInfoSize,
|
||||||
|
&BytesWritten);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
RtlCreateUserProcess(PUNICODE_STRING ApplicationName,
|
||||||
|
PSECURITY_DESCRIPTOR ProcessSd,
|
||||||
|
PSECURITY_DESCRIPTOR ThreadSd,
|
||||||
|
WINBOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
// LPVOID lpEnvironment,
|
||||||
|
// LPCWSTR lpCurrentDirectory,
|
||||||
|
// LPSTARTUPINFO lpStartupInfo,
|
||||||
|
PCLIENT_ID ClientId,
|
||||||
|
PHANDLE ProcessHandle,
|
||||||
|
PHANDLE ThreadHandle)
|
||||||
|
{
|
||||||
|
HANDLE hSection, hProcess, hThread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LPTHREAD_START_ROUTINE lpStartAddress = NULL;
|
||||||
|
LPVOID lpParameter = NULL;
|
||||||
|
WCHAR TempCommandLine[256];
|
||||||
|
PVOID BaseAddress;
|
||||||
|
LARGE_INTEGER SectionOffset;
|
||||||
|
IMAGE_NT_HEADERS Headers;
|
||||||
|
IMAGE_DOS_HEADER DosHeader;
|
||||||
|
HANDLE NTDllSection;
|
||||||
|
ULONG InitialViewSize;
|
||||||
|
PROCESS_BASIC_INFORMATION ProcessBasicInfo;
|
||||||
|
CLIENT_ID LocalClientId;
|
||||||
|
ULONG retlen;
|
||||||
|
|
||||||
|
DPRINT("RtlCreateUserProcess(ApplicationName '%w')\n",
|
||||||
|
ApplicationName->Buffer);
|
||||||
|
|
||||||
|
Status = RtlpMapFile(ApplicationName,
|
||||||
|
&Headers,
|
||||||
|
&DosHeader,
|
||||||
|
&hSection);
|
||||||
|
|
||||||
|
Status = NtCreateProcess(&hProcess,
|
||||||
|
PROCESS_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NtCurrentProcess(),
|
||||||
|
bInheritHandles,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
NtQueryInformationProcess(hProcess,
|
||||||
|
ProcessBasicInformation,
|
||||||
|
&ProcessBasicInfo,
|
||||||
|
sizeof(ProcessBasicInfo),
|
||||||
|
&retlen);
|
||||||
|
DPRINT("ProcessBasicInfo.UniqueProcessId %d\n",
|
||||||
|
ProcessBasicInfo.UniqueProcessId);
|
||||||
|
LocalClientId.UniqueProcess = ProcessBasicInfo.UniqueProcessId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Map NT DLL into the process
|
||||||
|
*/
|
||||||
|
Status = LdrMapNTDllForProcess(hProcess,
|
||||||
|
&NTDllSection);
|
||||||
|
|
||||||
|
InitialViewSize = DosHeader.e_lfanew + sizeof(IMAGE_NT_HEADERS)
|
||||||
|
+ sizeof(IMAGE_SECTION_HEADER) * Headers.FileHeader.NumberOfSections;
|
||||||
|
|
||||||
|
BaseAddress = (PVOID)Headers.OptionalHeader.ImageBase;
|
||||||
|
SectionOffset.QuadPart = 0;
|
||||||
|
Status = NtMapViewOfSection(hSection,
|
||||||
|
hProcess,
|
||||||
|
&BaseAddress,
|
||||||
|
0,
|
||||||
|
InitialViewSize,
|
||||||
|
&SectionOffset,
|
||||||
|
&InitialViewSize,
|
||||||
|
0,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
DPRINT("Creating peb\n");
|
||||||
|
RtlpCreatePeb(hProcess, ApplicationName);
|
||||||
|
|
||||||
|
DPRINT("Creating thread for process\n");
|
||||||
|
lpStartAddress = (LPTHREAD_START_ROUTINE)
|
||||||
|
((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(NTDLL_BASE))->
|
||||||
|
AddressOfEntryPoint +
|
||||||
|
((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(NTDLL_BASE))->ImageBase;
|
||||||
|
hThread = RtlpCreateFirstThread(hProcess,
|
||||||
|
ThreadSd,
|
||||||
|
Headers.OptionalHeader.SizeOfStackReserve,
|
||||||
|
lpStartAddress,
|
||||||
|
lpParameter,
|
||||||
|
dwCreationFlags,
|
||||||
|
&LocalClientId.UniqueThread,
|
||||||
|
TempCommandLine,
|
||||||
|
NTDllSection,
|
||||||
|
hSection,
|
||||||
|
(PVOID)Headers.OptionalHeader.ImageBase);
|
||||||
|
|
||||||
|
if ( hThread == NULL )
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
if (ClientId)
|
||||||
|
{
|
||||||
|
ClientId->UniqueProcess = LocalClientId.UniqueProcess;
|
||||||
|
ClientId->UniqueThread = LocalClientId.UniqueThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ProcessHandle)
|
||||||
|
*ProcessHandle = hProcess;
|
||||||
|
|
||||||
|
if (ThreadHandle)
|
||||||
|
*ThreadHandle = hThread;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
302
reactos/lib/ntdll/rtl/thread.c
Normal file
302
reactos/lib/ntdll/rtl/thread.c
Normal file
|
@ -0,0 +1,302 @@
|
||||||
|
|
||||||
|
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/i386/segment.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//#define NDEBUG
|
||||||
|
#include <ntdll/ntdll.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
RtlpAllocateThreadStack(HANDLE ProcessHandle,
|
||||||
|
PULONG StackReserve,
|
||||||
|
PULONG StackCommit,
|
||||||
|
ULONG StackZeroBits,
|
||||||
|
PINITIAL_TEB InitialTeb)
|
||||||
|
{
|
||||||
|
PVOID StackBase; /* ebp-4 */
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS Status; /* register */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
Status = NtQuerySystemInformation(...);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
if (ProcessHandle == CurrentProcess)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&StackBase,
|
||||||
|
ZeroBits,
|
||||||
|
StackReserve,
|
||||||
|
MEM_RESERVE,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&StackBase,
|
||||||
|
0,
|
||||||
|
StackCommit,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
InitialTeb->... = StackBase; /* + 0x0C */
|
||||||
|
|
||||||
|
if (bProtect)
|
||||||
|
{
|
||||||
|
|
||||||
|
Status = NtProtectVirtualMemory(ProcessHandle,
|
||||||
|
&StackBase,
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* NOTE: This is a simplified implementation */
|
||||||
|
|
||||||
|
StackBase = 0;
|
||||||
|
|
||||||
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&StackBase,
|
||||||
|
0,
|
||||||
|
StackCommit,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
InitialTeb->StackBase = StackBase;
|
||||||
|
InitialTeb->StackCommit = StackCommit;
|
||||||
|
|
||||||
|
/* End of simplified implementation */
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
RtlpFreeThreadStack(HANDLE ProcessHandle,
|
||||||
|
PINITIAL_TEB InitialTeb)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
ULONG RegionSize;
|
||||||
|
|
||||||
|
RegionSize = 0;
|
||||||
|
|
||||||
|
Status = NtFreeVirtualMemory(ProcessHandle,
|
||||||
|
InitialTeb->StackBase,
|
||||||
|
&RegionSize,
|
||||||
|
MEM_RELEASE);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
InitialTeb->StackBase = NULL;
|
||||||
|
/* ... */
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
RtlCreateUserThread(HANDLE ProcessHandle,
|
||||||
|
SECURITY_DESCRIPTOR *SecurityDescriptor,
|
||||||
|
BOOLEAN CreateSuspended,
|
||||||
|
LONG StackZeroBits,
|
||||||
|
PULONG StackReserved,
|
||||||
|
PULONG StackCommit,
|
||||||
|
PVOID StartAddress,
|
||||||
|
HANDLE DebugPort,
|
||||||
|
PHANDLE ThreadHandle,
|
||||||
|
PCLIENT_ID ClientId)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
HANDLE LocalThreadHandle;
|
||||||
|
CLIENT_ID LocalClientId;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
INITIAL_TEB InitialTeb;
|
||||||
|
CONTEXT Context;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
/* create thread stack */
|
||||||
|
Status = RtlpAllocateThreadStack(ProcessHandle,
|
||||||
|
StackReserved,
|
||||||
|
StackCommit,
|
||||||
|
StackZeroBits,
|
||||||
|
&InitialTeb);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
|
||||||
|
/* initialize thread context */
|
||||||
|
RtlInitializeContext (ProcessHandle,
|
||||||
|
&Context,
|
||||||
|
DebugPort,
|
||||||
|
StartAddress,
|
||||||
|
&InitialTeb);
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
|
||||||
|
/* initalize object attributes */
|
||||||
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||||
|
ObjectAttributes.RootDirectory = NULL;
|
||||||
|
ObjectAttributes.ObjectName = NULL;
|
||||||
|
ObjectAttributes.Attributes = 0;
|
||||||
|
ObjectAttributes.SecurityDescriptor = SecurityDescriptor;
|
||||||
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
Status = NtCreateThread (&LocalThreadHandle,
|
||||||
|
0x1F03FF, /* ??? */
|
||||||
|
&ObjectAttributes,
|
||||||
|
ProcessHandle,
|
||||||
|
&LocalClientId,
|
||||||
|
&Context,
|
||||||
|
&InitialTeb,
|
||||||
|
CreateSuspended);
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* free thread stack */
|
||||||
|
RtlpFreeThreadStack (ProcessHandle,
|
||||||
|
&InitialTeb);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Begin of test code */
|
||||||
|
|
||||||
|
HANDLE LocalThreadHandle;
|
||||||
|
CLIENT_ID LocalClientId;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
INITIAL_TEB InitialTeb;
|
||||||
|
CONTEXT ThreadContext;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
||||||
|
ObjectAttributes.RootDirectory = NULL;
|
||||||
|
ObjectAttributes.ObjectName = NULL;
|
||||||
|
// ObjectAttributes.Attributes = 0;
|
||||||
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
||||||
|
ObjectAttributes.SecurityDescriptor = SecurityDescriptor;
|
||||||
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
BaseAddress = 0;
|
||||||
|
ZwAllocateVirtualMemory(ProcessHandle,
|
||||||
|
&BaseAddress,
|
||||||
|
0,
|
||||||
|
StackCommit,
|
||||||
|
MEM_COMMIT,
|
||||||
|
PAGE_READWRITE);
|
||||||
|
|
||||||
|
|
||||||
|
memset(&ThreadContext,0,sizeof(CONTEXT));
|
||||||
|
ThreadContext.Eip = (LONG)StartAddress;
|
||||||
|
ThreadContext.SegGs = USER_DS;
|
||||||
|
ThreadContext.SegFs = USER_DS;
|
||||||
|
ThreadContext.SegEs = USER_DS;
|
||||||
|
ThreadContext.SegDs = USER_DS;
|
||||||
|
ThreadContext.SegCs = USER_CS;
|
||||||
|
ThreadContext.SegSs = USER_DS;
|
||||||
|
ThreadContext.Esp = (ULONG)(BaseAddress + *StackCommit);
|
||||||
|
ThreadContext.EFlags = (1<<1) + (1<<9);
|
||||||
|
|
||||||
|
|
||||||
|
Status = NtCreateThread(&LocalThreadHandle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
&ObjectAttributes,
|
||||||
|
ProcessHandle,
|
||||||
|
&LocalClientId,
|
||||||
|
&ThreadContext,
|
||||||
|
&InitialTeb,
|
||||||
|
CreateSuspended);
|
||||||
|
|
||||||
|
// if ( lpThreadId != NULL )
|
||||||
|
// memcpy(lpThreadId, &ClientId.UniqueThread,sizeof(ULONG));
|
||||||
|
|
||||||
|
/* End of test code */
|
||||||
|
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
|
||||||
|
/* return thread handle */
|
||||||
|
if (ThreadHandle)
|
||||||
|
*ThreadHandle = LocalThreadHandle;
|
||||||
|
|
||||||
|
/* return client id */
|
||||||
|
if (ClientId)
|
||||||
|
{
|
||||||
|
ClientId->UniqueProcess = LocalClientId.UniqueProcess;
|
||||||
|
ClientId->UniqueThread = LocalClientId.UniqueThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT("Checkpoint\n");
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
RtlInitializeContext(HANDLE ProcessHandle,
|
||||||
|
PCONTEXT Context,
|
||||||
|
HANDLE DebugPort,
|
||||||
|
PVOID StartAddress,
|
||||||
|
PINITIAL_TEB InitialTeb)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* NOTE: This is a simplified implementation */
|
||||||
|
|
||||||
|
memset (Context, 0, sizeof(CONTEXT));
|
||||||
|
|
||||||
|
/* #if __X86__ */
|
||||||
|
Context->Eip = (ULONG)StartAddress;
|
||||||
|
Context->SegGs = USER_DS;
|
||||||
|
Context->SegFs = USER_DS; /* USER_FS */
|
||||||
|
Context->SegEs = USER_DS;
|
||||||
|
Context->SegDs = USER_DS;
|
||||||
|
Context->SegCs = USER_CS;
|
||||||
|
Context->SegSs = USER_DS;
|
||||||
|
Context->Esp = InitialTeb->StackBase - InitialTeb->StackCommit;
|
||||||
|
Context->EFlags = (1<<1)+(1<<9);
|
||||||
|
/* #endif */
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* End of simplified implementation */
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: init.c,v 1.2 1999/06/08 22:44:19 ea Exp $
|
/* $Id: init.c,v 1.3 1999/09/04 18:38:02 ekohl Exp $
|
||||||
*
|
*
|
||||||
* init.c - Session Manager initialization
|
* init.c - Session Manager initialization
|
||||||
*
|
*
|
||||||
|
@ -34,25 +34,45 @@ InitSessionManager(
|
||||||
HANDLE Children[]
|
HANDLE Children[]
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UNICODE_STRING CmdLineW;
|
||||||
|
|
||||||
/* FIXME: Create the \SmApiPort object (LPC) */
|
/* FIXME: Create the \SmApiPort object (LPC) */
|
||||||
/* FIXME: Create two thread for \SmApiPort */
|
/* FIXME: Create two thread for \SmApiPort */
|
||||||
/* FIXME: Create the system environment variables */
|
/* FIXME: Create the system environment variables */
|
||||||
/* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
|
/* FIXME: Define symbolic links to kernel devices (MS-DOS names) */
|
||||||
/* FIXME: Create pagination files (if any) other than the first one */
|
/* FIXME: Create paging files (if any) other than the first one */
|
||||||
/* FIXME: Load the well known DLLs */
|
/* FIXME: Load the well known DLLs */
|
||||||
/* FIXME: Load the kernel mode driver win32k.sys */
|
/* FIXME: Load the kernel mode driver win32k.sys */
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* Start the Win32 subsystem (csrss.exe) */
|
/* Start the Win32 subsystem (csrss.exe) */
|
||||||
Status = NtCreateProcess(
|
Status = NtCreateProcess(
|
||||||
L"\\??\\C:\\reactos\\system\\csrss.exe",
|
L"\\??\\C:\\reactos\\system32\\csrss.exe",
|
||||||
& Children[CHILD_CSRSS]
|
& Children[CHILD_CSRSS]
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Start the simple shell (shell.exe) */
|
||||||
|
RtlInitUnicodeString(&CmdLineW,
|
||||||
|
L"\\??\\C:\\reactos\\system32\\shell.exe");
|
||||||
|
Status = RtlCreateUserProcess(&CmdLineW,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
&Children[0],
|
||||||
|
NULL);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
/* Start winlogon.exe */
|
/* Start winlogon.exe */
|
||||||
Status = NtCreateProcess(
|
Status = NtCreateProcess(
|
||||||
L"\\??\\C:\\reactos\\system\\winlogon.exe",
|
L"\\??\\C:\\reactos\\system32\\winlogon.exe",
|
||||||
& Children[CHILD_WINLOGON]
|
& Children[CHILD_WINLOGON]
|
||||||
);
|
);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -62,6 +82,7 @@ InitSessionManager(
|
||||||
);
|
);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* FIXME: Create the \DbgSsApiPort object (LPC) */
|
/* FIXME: Create the \DbgSsApiPort object (LPC) */
|
||||||
/* FIXME: Create the \DbgUiApiPort object (LPC) */
|
/* FIXME: Create the \DbgUiApiPort object (LPC) */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: smss.c,v 1.2 1999/06/08 22:44:19 ea Exp $
|
/* $Id: smss.c,v 1.3 1999/09/04 18:38:02 ekohl Exp $
|
||||||
*
|
*
|
||||||
* smss.c - Session Manager
|
* smss.c - Session Manager
|
||||||
*
|
*
|
||||||
|
@ -53,11 +53,21 @@ NtProcessStartup( PSTARTUP_ARGUMENT StartupArgument )
|
||||||
|
|
||||||
DisplayString( L"Session Manager\n" );
|
DisplayString( L"Session Manager\n" );
|
||||||
|
|
||||||
|
|
||||||
if (TRUE == InitSessionManager(Children))
|
if (TRUE == InitSessionManager(Children))
|
||||||
{
|
{
|
||||||
LARGE_INTEGER Time = {{(DWORD)-1,(DWORD)-1}}; /* infinite? */
|
LARGE_INTEGER Time = {{(DWORD)-1,(DWORD)-1}}; /* infinite? */
|
||||||
NTSTATUS wws;
|
NTSTATUS wws;
|
||||||
|
|
||||||
|
DisplayString( L"SM: Waiting for process termination...\n" );
|
||||||
|
|
||||||
|
wws = NtWaitForSingleObject (
|
||||||
|
Children[0],
|
||||||
|
TRUE, /* alertable */
|
||||||
|
& Time
|
||||||
|
);
|
||||||
|
|
||||||
|
#if 0
|
||||||
wws = NtWaitForMultipleObjects (
|
wws = NtWaitForMultipleObjects (
|
||||||
((LONG) sizeof Children / sizeof (HANDLE)),
|
((LONG) sizeof Children / sizeof (HANDLE)),
|
||||||
Children,
|
Children,
|
||||||
|
@ -65,17 +75,25 @@ NtProcessStartup( PSTARTUP_ARGUMENT StartupArgument )
|
||||||
TRUE, /* alertable */
|
TRUE, /* alertable */
|
||||||
& Time
|
& Time
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
if (!NT_SUCCESS(wws))
|
if (!NT_SUCCESS(wws))
|
||||||
{
|
{
|
||||||
DisplayString( L"SM: NtWaitForMultipleObjects failed!\n" );
|
DisplayString( L"SM: NtWaitForMultipleObjects failed!\n" );
|
||||||
/* FIXME: CRASH THE SYSTEM (BSOD) */
|
/* FIXME: CRASH THE SYSTEM (BSOD) */
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisplayString( L"SM: Process terminated!\n" );
|
||||||
|
/* FIXME: CRASH THE SYSTEM (BSOD) */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DisplayString( L"SM: initialization failed!\n" );
|
DisplayString( L"SM: initialization failed!\n" );
|
||||||
/* FIXME: CRASH SYSTEM (BSOD)*/
|
/* FIXME: CRASH SYSTEM (BSOD)*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK: CSRSS asked to shutdown the system;
|
* OK: CSRSS asked to shutdown the system;
|
||||||
* We die.
|
* We die.
|
||||||
|
|
Loading…
Reference in a new issue