mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 12:24:48 +00:00

* drivers/dd/floppy/floppy.c: Changed PAGESIZE to PAGE_SIZE. * drivers/fs/cdfs/fcb.c: Ditto. * drivers/fs/cdfs/fsctl.c: Ditto. * drivers/fs/cdfs/rw.c: Ditto. * drivers/fs/ext2/dir.c: Ditto. * drivers/fs/ext2/inode.c: Ditto. * drivers/fs/ext2/rw.c: Ditto. * drivers/fs/ext2/super.c: Ditto. * drivers/fs/minix/blockdev.c: Ditto. * drivers/fs/minix/cache.c: Ditto. * drivers/fs/minix/inode.c: Ditto. * drivers/fs/minix/rw.c: Ditto. * drivers/fs/ntfs/fcb.c: Ditto. * drivers/fs/ntfs/ntfs.h: Ditto. * drivers/fs/vfat/create.c: Ditto. * drivers/fs/vfat/direntry.c: Ditto. * drivers/fs/vfat/dirwr.c: Ditto. * drivers/fs/vfat/fat.c: Ditto. * drivers/fs/vfat/fcb.c: Ditto. * drivers/fs/vfat/fsctl.c: Ditto. * drivers/fs/vfat/rw.c: Ditto. * drivers/storage/class2/class2.c: Ditto. * drivers/storage/scsiport/scsiport.c: Ditto. * hal/halx86/adapter.c: Ditto. * hal/halx86/mp.c: Ditto. * include/ddk/mmfuncs.h: Ditto. * include/ddk/mmtypes.h: Ditto. * include/ddk/i386/pagesize.h: Ditto. * include/ntdll/pagesize.h: Ditto. * lib/kernel32/process/create.c: Ditto. * lib/kernel32/thread/thread.c: Ditto. * lib/ntdll/ldr/utils.c: Ditto. * lib/ntdll/rtl/env.c: Ditto. * lib/ntdll/rtl/heap.c: Ditto. * lib/ntdll/rtl/ppb.c: Ditto. * lib/ntdll/rtl/process.c: Ditto. * lib/ntdll/rtl/thread.c: Ditto. * ntoskrnl/cc/copy.c: Ditto. * ntoskrnl/cc/view.c: Ditto. * ntoskrnl/ex/sysinfo.c: Ditto. * ntoskrnl/include/internal/i386/mm.h: Ditto. * ntoskrnl/io/mdl.c: Ditto. * ntoskrnl/ke/kthread.c: Ditto. * ntoskrnl/ke/i386/kernel.c: Ditto. * ntoskrnl/ldr/init.c: Ditto. * ntoskrnl/ldr/loader.c: Ditto. * ntoskrnl/mm/anonmem.c: Ditto. * ntoskrnl/mm/cont.c: Ditto. * ntoskrnl/mm/freelist.c: Ditto. * ntoskrnl/mm/iospace.c: Ditto. * ntoskrnl/mm/kmap.c: Ditto. * ntoskrnl/mm/marea.c: Ditto. * ntoskrnl/mm/mdl.c: Ditto. * ntoskrnl/mm/mminit.c: Ditto. * ntoskrnl/mm/ncache.c: Ditto. * ntoskrnl/mm/npool.c: Ditto. * ntoskrnl/mm/pagefile.c: Ditto. * ntoskrnl/mm/pageop.c: Ditto. * ntoskrnl/mm/section.c: Ditto. * ntoskrnl/mm/slab.c: Ditto. * ntoskrnl/mm/i386/page.c: Ditto. * ntoskrnl/ob/handle.c: Ditto. * ntoskrnl/ps/create.c: Ditto. * ntoskrnl/ps/process.c: Ditto. * ntoskrnl/ps/w32call.c: Ditto. * subsys/win32k/include/object.h: Ditto. svn path=/trunk/; revision=3594
273 lines
7.2 KiB
C
273 lines
7.2 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* PURPOSE: Rtl user thread functions
|
|
* FILE: lib/ntdll/rtl/thread.c
|
|
* PROGRAMER: Eric Kohl
|
|
* REVISION HISTORY:
|
|
* 09/07/99: Created
|
|
* 09/10/99: Cleanup and full stack support.
|
|
*/
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
#include <ddk/ntddk.h>
|
|
#include <napi/i386/segment.h>
|
|
#include <napi/teb.h>
|
|
#include <ntdll/rtl.h>
|
|
|
|
#define NDEBUG
|
|
#include <ntdll/ntdll.h>
|
|
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
RtlCreateUserThread(HANDLE ProcessHandle,
|
|
PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
BOOLEAN CreateSuspended,
|
|
LONG StackZeroBits,
|
|
PULONG StackReserve,
|
|
PULONG StackCommit,
|
|
PTHREAD_START_ROUTINE StartAddress,
|
|
PVOID Parameter,
|
|
PHANDLE ThreadHandle,
|
|
PCLIENT_ID ClientId)
|
|
{
|
|
HANDLE LocalThreadHandle;
|
|
CLIENT_ID LocalClientId;
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
INITIAL_TEB InitialTeb;
|
|
CONTEXT ThreadContext;
|
|
ULONG OldPageProtection;
|
|
NTSTATUS Status;
|
|
|
|
/* initialize initial teb */
|
|
if ((StackReserve != NULL) && (*StackReserve > 0x100000))
|
|
InitialTeb.StackReserve = *StackReserve;
|
|
else
|
|
InitialTeb.StackReserve = 0x100000; /* 1MByte */
|
|
|
|
/* FIXME: use correct commit size */
|
|
#if 0
|
|
if ((StackCommit != NULL) && (*StackCommit > PAGE_SIZE))
|
|
InitialTeb.StackCommit = *StackCommit;
|
|
else
|
|
InitialTeb.StackCommit = PAGE_SIZE;
|
|
#endif
|
|
InitialTeb.StackCommit = InitialTeb.StackReserve - PAGE_SIZE;
|
|
|
|
/* add size of guard page */
|
|
InitialTeb.StackCommit += PAGE_SIZE;
|
|
|
|
/* Reserve stack */
|
|
InitialTeb.StackAllocate = NULL;
|
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
|
&InitialTeb.StackAllocate,
|
|
0,
|
|
&InitialTeb.StackReserve,
|
|
MEM_RESERVE,
|
|
PAGE_READWRITE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT("Error reserving stack space!\n");
|
|
return(Status);
|
|
}
|
|
|
|
DPRINT("StackAllocate: %p ReserveSize: 0x%lX\n",
|
|
InitialTeb.StackAllocate, InitialTeb.StackReserve);
|
|
|
|
InitialTeb.StackBase = (PVOID)((ULONG)InitialTeb.StackAllocate + InitialTeb.StackReserve);
|
|
InitialTeb.StackLimit = (PVOID)((ULONG)InitialTeb.StackBase - InitialTeb.StackCommit);
|
|
|
|
DPRINT("StackBase: %p StackCommit: 0x%lX\n",
|
|
InitialTeb.StackBase, InitialTeb.StackCommit);
|
|
|
|
/* Commit stack */
|
|
Status = NtAllocateVirtualMemory(ProcessHandle,
|
|
&InitialTeb.StackLimit,
|
|
0,
|
|
&InitialTeb.StackCommit,
|
|
MEM_COMMIT,
|
|
PAGE_READWRITE);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* release the stack space */
|
|
NtFreeVirtualMemory(ProcessHandle,
|
|
InitialTeb.StackAllocate,
|
|
&InitialTeb.StackReserve,
|
|
MEM_RELEASE);
|
|
|
|
DPRINT("Error comitting stack page!\n");
|
|
return(Status);
|
|
}
|
|
|
|
DPRINT("StackLimit: %p\nStackCommit: 0x%lX\n",
|
|
InitialTeb.StackLimit,
|
|
InitialTeb.StackCommit);
|
|
|
|
/* Protect guard page */
|
|
Status = NtProtectVirtualMemory(ProcessHandle,
|
|
InitialTeb.StackLimit,
|
|
PAGE_SIZE,
|
|
PAGE_GUARD | PAGE_READWRITE,
|
|
&OldPageProtection);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* release the stack space */
|
|
NtFreeVirtualMemory(ProcessHandle,
|
|
InitialTeb.StackAllocate,
|
|
&InitialTeb.StackReserve,
|
|
MEM_RELEASE);
|
|
|
|
DPRINT("Error protecting guard page!\n");
|
|
return(Status);
|
|
}
|
|
|
|
/* initialize thread context */
|
|
RtlInitializeContext(ProcessHandle,
|
|
&ThreadContext,
|
|
Parameter,
|
|
StartAddress,
|
|
&InitialTeb);
|
|
|
|
/* create the thread */
|
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
ObjectAttributes.RootDirectory = NULL;
|
|
ObjectAttributes.ObjectName = NULL;
|
|
ObjectAttributes.Attributes = OBJ_INHERIT;
|
|
ObjectAttributes.SecurityDescriptor = SecurityDescriptor;
|
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
|
|
|
Status = NtCreateThread(&LocalThreadHandle,
|
|
THREAD_ALL_ACCESS,
|
|
&ObjectAttributes,
|
|
ProcessHandle,
|
|
&LocalClientId,
|
|
&ThreadContext,
|
|
&InitialTeb,
|
|
CreateSuspended);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
/* release the stack space */
|
|
NtFreeVirtualMemory(ProcessHandle,
|
|
InitialTeb.StackAllocate,
|
|
&InitialTeb.StackReserve,
|
|
MEM_RELEASE);
|
|
|
|
DPRINT("Error creating thread!\n");
|
|
return(Status);
|
|
}
|
|
|
|
/* return committed stack size */
|
|
if (StackCommit)
|
|
*StackCommit = InitialTeb.StackCommit;
|
|
|
|
/* return reserved stack size */
|
|
if (StackReserve)
|
|
*StackReserve = InitialTeb.StackReserve;
|
|
|
|
/* return thread handle */
|
|
if (ThreadHandle)
|
|
*ThreadHandle = LocalThreadHandle;
|
|
|
|
/* return client id */
|
|
if (ClientId)
|
|
{
|
|
ClientId->UniqueProcess = LocalClientId.UniqueProcess;
|
|
ClientId->UniqueThread = LocalClientId.UniqueThread;
|
|
}
|
|
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
RtlInitializeContext(HANDLE ProcessHandle,
|
|
PCONTEXT Context,
|
|
PVOID Parameter,
|
|
PTHREAD_START_ROUTINE StartAddress,
|
|
PINITIAL_TEB InitialTeb)
|
|
{
|
|
ULONG Buffer[2];
|
|
ULONG BytesWritten;
|
|
NTSTATUS Status;
|
|
|
|
memset (Context, 0, sizeof(CONTEXT));
|
|
Context->Eip = (LONG)StartAddress;
|
|
Context->SegGs = USER_DS;
|
|
Context->SegFs = TEB_SELECTOR;
|
|
Context->SegEs = USER_DS;
|
|
Context->SegDs = USER_DS;
|
|
Context->SegCs = USER_CS;
|
|
Context->SegSs = USER_DS;
|
|
Context->Esp = (ULONG)InitialTeb->StackBase - 8;
|
|
Context->EFlags = (1<<1) + (1<<9);
|
|
|
|
/* prepare the thread stack for execution */
|
|
if (ProcessHandle == NtCurrentProcess())
|
|
{
|
|
*((PULONG)(InitialTeb->StackBase - 4)) = (ULONG)Parameter;
|
|
*((PULONG)(InitialTeb->StackBase - 8)) = 0xdeadbeef;
|
|
}
|
|
else
|
|
{
|
|
Buffer[0] = (ULONG)Parameter;
|
|
Buffer[1] = 0xdeadbeef;
|
|
|
|
Status = NtWriteVirtualMemory(ProcessHandle,
|
|
(PVOID)((ULONG)InitialTeb->StackBase - 8),
|
|
Buffer,
|
|
2 * sizeof(ULONG),
|
|
&BytesWritten);
|
|
return Status;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
NTSTATUS STDCALL
|
|
RtlFreeUserThreadStack(HANDLE ProcessHandle,
|
|
HANDLE ThreadHandle)
|
|
{
|
|
THREAD_BASIC_INFORMATION ThreadInfo;
|
|
NTSTATUS Status;
|
|
ULONG BytesRead;
|
|
ULONG RegionSize;
|
|
PVOID StackBase;
|
|
PTEB Teb;
|
|
|
|
Status = NtQueryInformationThread(ThreadHandle,
|
|
ThreadBasicInformation,
|
|
&ThreadInfo,
|
|
sizeof(THREAD_BASIC_INFORMATION),
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
return(Status);
|
|
|
|
if (ThreadInfo.TebBaseAddress == NULL)
|
|
return(Status);
|
|
|
|
Teb = (PTEB)ThreadInfo.TebBaseAddress;
|
|
Status = NtReadVirtualMemory(ProcessHandle,
|
|
&Teb->DeallocationStack,
|
|
&StackBase,
|
|
sizeof(PVOID),
|
|
&BytesRead);
|
|
if (!NT_SUCCESS(Status))
|
|
return(Status);
|
|
|
|
if (StackBase == NULL)
|
|
return(Status);
|
|
|
|
RegionSize = 0;
|
|
Status = NtFreeVirtualMemory(ProcessHandle,
|
|
StackBase,
|
|
&RegionSize,
|
|
MEM_RELEASE);
|
|
return(Status);
|
|
}
|
|
|
|
/* EOF */
|