mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +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 <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;
|
||||
|
||||
printf("Creating %d threads\n",NR_THREADS);
|
||||
|
@ -17,9 +29,20 @@ int main()
|
|||
{
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main,
|
||||
NULL,
|
||||
thread_main1,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
|
||||
CreateThread(NULL,
|
||||
0,
|
||||
thread_main2,
|
||||
(LPVOID)i,
|
||||
0,
|
||||
&id);
|
||||
}
|
||||
|
||||
Sleep (5000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -808,4 +808,47 @@ RtlDenormalizeProcessParams (
|
|||
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 */
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
@ -431,6 +431,8 @@ RtlAppendUnicodeStringToString
|
|||
RtlAppendUnicodeToString
|
||||
RtlCharToInteger
|
||||
RtlCreateHeap@24
|
||||
RtlCreateUserProcess@32
|
||||
RtlCreateUserThread@40
|
||||
RtlCompactHeap@8
|
||||
RtlCompareString
|
||||
RtlCompareUnicodeString
|
||||
|
@ -447,6 +449,7 @@ RtlFreeHeap@12
|
|||
RtlFreeUnicodeString
|
||||
RtlGetProcessHeap@0
|
||||
RtlInitAnsiString
|
||||
RtlInitializeContext@20
|
||||
RtlInitString
|
||||
RtlInitUnicodeString
|
||||
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
|
||||
;
|
||||
|
@ -431,6 +431,8 @@ RtlAppendUnicodeStringToString
|
|||
RtlAppendUnicodeToString
|
||||
RtlCharToInteger
|
||||
RtlCreateHeap=RtlCreateHeap@24
|
||||
RtlCreateUserProcess=RtlCreateUserProcess@32
|
||||
RtlCreateUserThread=RtlCreateUserThread@40
|
||||
RtlCompactHeap=RtlCompactHeap@8
|
||||
RtlCompareString
|
||||
RtlCompareUnicodeString
|
||||
|
@ -447,6 +449,7 @@ RtlFreeHeap=RtlFreeHeap@12
|
|||
RtlFreeUnicodeString
|
||||
RtlGetProcessHeap=RtlGetProcessHeap@0
|
||||
RtlInitAnsiString
|
||||
RtlInitializeContext=RtlInitializeContext@20
|
||||
RtlInitString
|
||||
RtlInitUnicodeString
|
||||
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
|
||||
#
|
||||
|
@ -24,7 +24,8 @@ endif
|
|||
all: $(DLLTARGET)
|
||||
|
||||
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/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
|
||||
*
|
||||
|
@ -34,25 +34,45 @@ InitSessionManager(
|
|||
HANDLE Children[]
|
||||
)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
UNICODE_STRING CmdLineW;
|
||||
|
||||
/* FIXME: Create the \SmApiPort object (LPC) */
|
||||
/* FIXME: Create two thread for \SmApiPort */
|
||||
/* FIXME: Create the system environment variables */
|
||||
/* 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 kernel mode driver win32k.sys */
|
||||
|
||||
#if 0
|
||||
/* Start the Win32 subsystem (csrss.exe) */
|
||||
Status = NtCreateProcess(
|
||||
L"\\??\\C:\\reactos\\system\\csrss.exe",
|
||||
L"\\??\\C:\\reactos\\system32\\csrss.exe",
|
||||
& 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))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#if 0
|
||||
/* Start winlogon.exe */
|
||||
Status = NtCreateProcess(
|
||||
L"\\??\\C:\\reactos\\system\\winlogon.exe",
|
||||
L"\\??\\C:\\reactos\\system32\\winlogon.exe",
|
||||
& Children[CHILD_WINLOGON]
|
||||
);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -62,6 +82,7 @@ InitSessionManager(
|
|||
);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
/* FIXME: Create the \DbgSsApiPort object (LPC) */
|
||||
/* FIXME: Create the \DbgUiApiPort object (LPC) */
|
||||
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
|
||||
*
|
||||
|
@ -53,11 +53,21 @@ NtProcessStartup( PSTARTUP_ARGUMENT StartupArgument )
|
|||
|
||||
DisplayString( L"Session Manager\n" );
|
||||
|
||||
|
||||
if (TRUE == InitSessionManager(Children))
|
||||
{
|
||||
LARGE_INTEGER Time = {{(DWORD)-1,(DWORD)-1}}; /* infinite? */
|
||||
NTSTATUS wws;
|
||||
|
||||
|
||||
DisplayString( L"SM: Waiting for process termination...\n" );
|
||||
|
||||
wws = NtWaitForSingleObject (
|
||||
Children[0],
|
||||
TRUE, /* alertable */
|
||||
& Time
|
||||
);
|
||||
|
||||
#if 0
|
||||
wws = NtWaitForMultipleObjects (
|
||||
((LONG) sizeof Children / sizeof (HANDLE)),
|
||||
Children,
|
||||
|
@ -65,17 +75,25 @@ NtProcessStartup( PSTARTUP_ARGUMENT StartupArgument )
|
|||
TRUE, /* alertable */
|
||||
& Time
|
||||
);
|
||||
#endif
|
||||
if (!NT_SUCCESS(wws))
|
||||
{
|
||||
DisplayString( L"SM: NtWaitForMultipleObjects failed!\n" );
|
||||
/* FIXME: CRASH THE SYSTEM (BSOD) */
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayString( L"SM: Process terminated!\n" );
|
||||
/* FIXME: CRASH THE SYSTEM (BSOD) */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayString( L"SM: initialization failed!\n" );
|
||||
/* FIXME: CRASH SYSTEM (BSOD)*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OK: CSRSS asked to shutdown the system;
|
||||
* We die.
|
||||
|
|
Loading…
Reference in a new issue