mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 00:45:24 +00:00
- Massive re-write of some parts of Ps, based on a patch I wrote almost a year ago and peer-reviewed with Thomas and Filip. Causes some shutdown regressions and process leaks (will fix). Needs more work. Changelog:
- Architectural changes to match information in Windows Internals 4 and other documented sources of information (Windows Internals II by Probert). Code should match Win2003 layout. - Handle almost any possible process/thread sub structure and add its cleanup code stubs, so that when we actually implement them, we won't forget to clean them up in the process code. - Add interlocked usage of process and thread flags in order to make everything more thread-safe. - Better handle cases where threads die instantly, race conditions, and other weird issues. - Better handle process termination and thread termination. - Implement NtCreateProcessEx and update PspCreateProcess/NtCreateProcess. - Improve cleanup of process object in PspProcessDelete. - Optimize some things like User Thread startup. - Add some extra asserts, paged_code checks and also user-mode security check. - Implement helper API PsGetNextProcessThread - Optimize thread reaper (thanks Filip) - Do proper referencing/dereferencing of thread/processes (thanks Thomas) - Document FIXMEs needed for Ps code to be up to standards and complete. svn path=/trunk/; revision=22976
This commit is contained in:
parent
d5dbbd1211
commit
f4539b7037
32 changed files with 1941 additions and 1022 deletions
|
@ -54,4 +54,18 @@ DbgkCreateThread(PVOID StartAddress)
|
|||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkExitProcess(IN NTSTATUS ExitStatus)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkExitThread(IN NTSTATUS ExitStatus)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -14,8 +14,17 @@
|
|||
#include <internal/debug.h>
|
||||
|
||||
POBJECT_TYPE DbgkDebugObjectType;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
||||
IN PEPROCESS Parent)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtCreateDebugObject(OUT PHANDLE DebugHandle,
|
||||
|
|
|
@ -153,7 +153,7 @@ ShutdownThreadMain(PVOID Context)
|
|||
sizeof(PCH))]);
|
||||
}
|
||||
|
||||
PiShutdownProcessManager();
|
||||
PspShutdownProcessManager();
|
||||
Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
|
||||
|
||||
|
|
|
@ -5,6 +5,21 @@ VOID
|
|||
STDCALL
|
||||
DbgkCreateThread(PVOID StartAddress);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkExitProcess(IN NTSTATUS ExitStatus);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkExitThread(IN NTSTATUS ExitStatus);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(
|
||||
IN PEPROCESS Process,
|
||||
IN PEPROCESS Parent
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -498,7 +498,8 @@ ULONG
|
|||
STDCALL
|
||||
KeSetProcess(
|
||||
struct _KPROCESS* Process,
|
||||
KPRIORITY Increment
|
||||
KPRIORITY Increment,
|
||||
BOOLEAN InWait
|
||||
);
|
||||
|
||||
VOID
|
||||
|
|
|
@ -88,7 +88,7 @@ LpcSendTerminationPort(
|
|||
LARGE_INTEGER CreationTime
|
||||
);
|
||||
|
||||
/* Code in ntoskrnl/lpc/close.h */
|
||||
/* Code in ntoskrnl/lpc/close.c */
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
|
@ -104,6 +104,10 @@ VOID
|
|||
STDCALL
|
||||
LpcpDeletePort(IN PVOID ObjectBody);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LpcExitThread(IN PETHREAD Thread);
|
||||
|
||||
/* Code in ntoskrnl/lpc/queue.c */
|
||||
|
||||
VOID
|
||||
|
|
|
@ -619,7 +619,7 @@ MmShowOutOfSpaceMessagePagingFile(VOID);
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
MmCreateProcessAddressSpace(
|
||||
IN struct _EPROCESS* Process,
|
||||
IN PEPROCESS Process,
|
||||
IN PROS_SECTION_OBJECT Section OPTIONAL
|
||||
);
|
||||
|
||||
|
@ -627,7 +627,7 @@ NTSTATUS
|
|||
STDCALL
|
||||
MmCreatePeb(struct _EPROCESS *Process);
|
||||
|
||||
struct _TEB*
|
||||
PTEB
|
||||
STDCALL
|
||||
MmCreateTeb(
|
||||
struct _EPROCESS *Process,
|
||||
|
@ -639,9 +639,21 @@ VOID
|
|||
STDCALL
|
||||
MmDeleteTeb(
|
||||
struct _EPROCESS *Process,
|
||||
struct _TEB* Teb
|
||||
PTEB Teb
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmCleanProcessAddressSpace(IN PEPROCESS Process);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmDeleteProcessAddressSpace(IN PEPROCESS Process);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
MmGetSessionLocaleId(VOID);
|
||||
|
||||
/* i386/pfault.c *************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -101,6 +101,26 @@ InterlockedAnd(IN OUT LONG volatile *Target,
|
|||
return j;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
LONG
|
||||
InterlockedOr(IN OUT LONG volatile *Target,
|
||||
IN LONG Set)
|
||||
{
|
||||
LONG i;
|
||||
LONG j;
|
||||
|
||||
j = *Target;
|
||||
do {
|
||||
i = j;
|
||||
j = InterlockedCompareExchange((PLONG)Target,
|
||||
i | Set,
|
||||
i);
|
||||
|
||||
} while (i != j);
|
||||
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* generic information class probing code
|
||||
*/
|
||||
|
|
|
@ -198,6 +198,17 @@ ObpReapObject(
|
|||
IN PVOID Unused
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObDereferenceDeviceMap(IN PEPROCESS Process);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObInheritDeviceMap(
|
||||
IN PEPROCESS Parent,
|
||||
IN PEPROCESS Process
|
||||
);
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
ObpSetPermanentObject(
|
||||
|
@ -211,9 +222,12 @@ ObpDeleteNameCheck(
|
|||
IN PVOID Object
|
||||
);
|
||||
|
||||
//
|
||||
// Security functions
|
||||
//
|
||||
VOID
|
||||
NTAPI
|
||||
ObClearProcessHandleTable(IN PEPROCESS Process);
|
||||
|
||||
/* Security descriptor cache functions */
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObpInitSdCache(
|
||||
|
|
|
@ -14,4 +14,8 @@ NTSTATUS
|
|||
NTAPI
|
||||
PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopCleanupPowerState(IN PPOWER_STATE PowerState);
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_PO_H */
|
||||
|
|
|
@ -40,7 +40,7 @@ PiInitProcessManager(VOID);
|
|||
|
||||
VOID
|
||||
NTAPI
|
||||
PiShutdownProcessManager(VOID);
|
||||
PspShutdownProcessManager(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
|
@ -172,6 +172,13 @@ PspAssignPrimaryToken(
|
|||
HANDLE TokenHandle
|
||||
);
|
||||
|
||||
PETHREAD
|
||||
NTAPI
|
||||
PsGetNextProcessThread(
|
||||
IN PEPROCESS Process,
|
||||
IN PETHREAD Thread OPTIONAL
|
||||
);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
PsExitSpecialApc(
|
||||
|
@ -218,14 +225,15 @@ VOID
|
|||
STDCALL
|
||||
PspExitThread(NTSTATUS ExitStatus);
|
||||
|
||||
VOID
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
PspTerminateThreadByPointer(
|
||||
PETHREAD Thread,
|
||||
NTSTATUS ExitStatus
|
||||
NTSTATUS ExitStatus,
|
||||
BOOLEAN bSelf
|
||||
);
|
||||
|
||||
VOID
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PsUnfreezeOtherThread(PETHREAD Thread);
|
||||
|
||||
|
@ -287,9 +295,10 @@ VOID
|
|||
NTAPI
|
||||
PsInitialiseSuspendImplementation(VOID);
|
||||
|
||||
NTSTATUS
|
||||
VOID
|
||||
STDCALL
|
||||
PspExitProcess(PEPROCESS Process);
|
||||
PspExitProcess(BOOLEAN LastThread,
|
||||
PEPROCESS Process);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
|
@ -376,4 +385,34 @@ VOID
|
|||
NTAPI
|
||||
PsUnlockProcess(PEPROCESS Process);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspRemoveProcessFromJob(
|
||||
IN PEPROCESS Process,
|
||||
IN PEJOB Job
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspDeleteLdt(IN PEPROCESS Process);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspDeleteVdmObjects(IN PEPROCESS Process);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspDeleteProcessSecurity(IN PEPROCESS Process);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspDeleteThreadSecurity(IN PETHREAD Thread);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspExitProcessFromJob(
|
||||
IN PEJOB Job,
|
||||
IN PEPROCESS Process
|
||||
);
|
||||
|
||||
#endif /* __INCLUDE_INTERNAL_PS_H */
|
||||
|
|
|
@ -136,6 +136,14 @@ PTOKEN
|
|||
STDCALL
|
||||
SepCreateSystemProcessToken(VOID);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
SeDetailedAuditingWithToken(IN PTOKEN Token);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
SeAuditProcessExit(IN PEPROCESS Process);
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
SeExchangePrimaryToken(
|
||||
|
|
|
@ -156,4 +156,7 @@
|
|||
#define TAG_LPC_MESSAGE TAG('L', 'p', 'c', 'M')
|
||||
#define TAG_LPC_ZONE TAG('L', 'p', 'c', 'Z')
|
||||
|
||||
/* Se Process Audit */
|
||||
#define TAG_SEPA TAG('S', 'e', 'P', 'a')
|
||||
|
||||
#endif /* _NTOSKRNL_TAG_H */
|
||||
|
|
|
@ -22,7 +22,7 @@ extern EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
|
|||
LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
|
||||
static ULONG PriorityListMask = 0;
|
||||
ULONG IdleProcessorMask = 0;
|
||||
extern PETHREAD PspReaperList;
|
||||
extern LIST_ENTRY PspReaperListHead;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -1383,34 +1383,56 @@ KeTerminateThread(IN KPRIORITY Increment)
|
|||
{
|
||||
KIRQL OldIrql;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
PKPROCESS Process = Thread->ApcState.Process;
|
||||
PLIST_ENTRY *ListHead;
|
||||
PETHREAD Entry, SavedEntry;
|
||||
PETHREAD *ThreadAddr;
|
||||
DPRINT("Terminating\n");
|
||||
|
||||
/* Lock the Dispatcher Database and the APC Queue */
|
||||
DPRINT("Terminating\n");
|
||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
ASSERT(Thread->SwapBusy == FALSE);
|
||||
|
||||
/* Remove the thread from the list */
|
||||
RemoveEntryList(&Thread->ThreadListEntry);
|
||||
/* Make sure we won't get Swapped */
|
||||
Thread->SwapBusy = TRUE;
|
||||
|
||||
/* Insert into the Reaper List */
|
||||
DPRINT("List: %p\n", PspReaperList);
|
||||
((PETHREAD)Thread)->ReaperLink = PspReaperList;
|
||||
PspReaperList = (PETHREAD)Thread;
|
||||
DPRINT("List: %p\n", PspReaperList);
|
||||
/* Save the Kernel and User Times */
|
||||
Process->KernelTime += Thread->KernelTime;
|
||||
Process->UserTime += Thread->UserTime;
|
||||
|
||||
/* Check if it's active */
|
||||
if (PspReaping == FALSE) {
|
||||
/* Get the current entry and our Port */
|
||||
Entry = (PETHREAD)PspReaperListHead.Flink;
|
||||
ThreadAddr = &((PETHREAD)Thread)->ReaperLink;
|
||||
|
||||
/* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */
|
||||
PspReaping = TRUE;
|
||||
DPRINT("Terminating\n");
|
||||
/* Add it to the reaper's list */
|
||||
do
|
||||
{
|
||||
/* Get the list head */
|
||||
ListHead = &PspReaperListHead.Flink;
|
||||
|
||||
/* Link ourselves */
|
||||
*ThreadAddr = Entry;
|
||||
SavedEntry = Entry;
|
||||
|
||||
/* Now try to do the exchange */
|
||||
Entry = InterlockedCompareExchangePointer(ListHead, ThreadAddr, Entry);
|
||||
|
||||
/* Break out if the change was succesful */
|
||||
} while (Entry != SavedEntry);
|
||||
|
||||
/* Check if the reaper wasn't active */
|
||||
if (!Entry)
|
||||
{
|
||||
/* Activate it as a work item, directly through its Queue */
|
||||
KiInsertQueue(&ExWorkerQueue[HyperCriticalWorkQueue].WorkerQueue,
|
||||
&PspReaperWorkItem.List,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* Handle Kernel Queues */
|
||||
if (Thread->Queue) {
|
||||
|
||||
if (Thread->Queue)
|
||||
{
|
||||
DPRINT("Waking Queue\n");
|
||||
RemoveEntryList(&Thread->QueueListEntry);
|
||||
KiWakeQueue(Thread->Queue);
|
||||
|
@ -1418,12 +1440,19 @@ KeTerminateThread(IN KPRIORITY Increment)
|
|||
|
||||
/* Signal the thread */
|
||||
Thread->DispatcherHeader.SignalState = TRUE;
|
||||
if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) {
|
||||
|
||||
if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE)
|
||||
{
|
||||
/* Satisfy waits */
|
||||
KiWaitTest((PVOID)Thread, Increment);
|
||||
}
|
||||
|
||||
/* Remove the thread from the list */
|
||||
RemoveEntryList(&Thread->ThreadListEntry);
|
||||
|
||||
/* Set us as terminated, decrease the Process's stack count */
|
||||
Thread->State = Terminated;
|
||||
Process->StackCount--;
|
||||
|
||||
/* Find a new Thread */
|
||||
KiDispatchThreadNoLock(Terminated);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,8 @@ KeInitializeProcess(PKPROCESS Process,
|
|||
ULONG
|
||||
NTAPI
|
||||
KeSetProcess(PKPROCESS Process,
|
||||
KPRIORITY Increment)
|
||||
KPRIORITY Increment,
|
||||
BOOLEAN InWait)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
ULONG OldState;
|
||||
|
|
|
@ -16,6 +16,24 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
LpcExitThread(IN PETHREAD Thread)
|
||||
{
|
||||
/* Make sure that the Reply Chain is empty */
|
||||
if (!IsListEmpty(&Thread->LpcReplyChain))
|
||||
{
|
||||
/* It's not, remove the entry */
|
||||
RemoveEntryList(&Thread->LpcReplyChain);
|
||||
}
|
||||
|
||||
/* Set the thread in exit mode */
|
||||
Thread->LpcExitThreadCalled = TRUE;
|
||||
Thread->LpcReplyMessageId = 0;
|
||||
|
||||
/* FIXME: Reply to the LpcReplyMessage */
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* NAME
|
||||
*
|
||||
|
|
|
@ -15,37 +15,6 @@
|
|||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NAME
|
||||
* LpcSendTerminationPort/2
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* ARGUMENTS
|
||||
*
|
||||
* RETURN VALUE
|
||||
*
|
||||
* REVISIONS
|
||||
*/
|
||||
NTSTATUS STDCALL
|
||||
LpcSendTerminationPort (IN PEPORT Port,
|
||||
IN LARGE_INTEGER CreateTime)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
CLIENT_DIED_MSG Msg;
|
||||
|
||||
#ifdef __USE_NT_LPC__
|
||||
Msg.h.u2.s2.Type = LPC_CLIENT_DIED;
|
||||
#endif
|
||||
Msg.h.u1.s1.TotalLength = sizeof(Msg);
|
||||
Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
|
||||
Msg.CreateTime = CreateTime;
|
||||
Status = LpcRequestPort (Port, &Msg.h);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* NAME
|
||||
* LpcSendDebugMessagePort/3
|
||||
|
|
|
@ -22,66 +22,12 @@ ULONG MmUserProbeAddress = 0;
|
|||
PVOID MmHighestUserAddress = NULL;
|
||||
PBOOLEAN Mm64BitPhysicalAddress = FALSE;
|
||||
PVOID MmSystemRangeStart = NULL;
|
||||
ULONG MmReadClusterSize;
|
||||
|
||||
MM_STATS MmStats;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmReleaseMmInfo(PEPROCESS Process)
|
||||
{
|
||||
PVOID Address;
|
||||
PMEMORY_AREA MemoryArea;
|
||||
|
||||
DPRINT("MmReleaseMmInfo(Process %x (%s))\n", Process,
|
||||
Process->ImageFileName);
|
||||
|
||||
MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
|
||||
while ((MemoryArea = ((PMADDRESS_SPACE)&Process->VadRoot)->MemoryAreaRoot) != NULL)
|
||||
{
|
||||
switch (MemoryArea->Type)
|
||||
{
|
||||
case MEMORY_AREA_SECTION_VIEW:
|
||||
Address = (PVOID)MemoryArea->StartingAddress;
|
||||
MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
MmUnmapViewOfSection((PEPROCESS)Process, Address);
|
||||
MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||
case MEMORY_AREA_PEB_OR_TEB:
|
||||
MmFreeVirtualMemory(Process, MemoryArea);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SHARED_DATA:
|
||||
case MEMORY_AREA_NO_ACCESS:
|
||||
MmFreeMemoryArea((PMADDRESS_SPACE)&Process->VadRoot,
|
||||
MemoryArea,
|
||||
NULL,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_MDL_MAPPING:
|
||||
KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES);
|
||||
break;
|
||||
|
||||
default:
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
Mmi386ReleaseMmInfo(Process);
|
||||
|
||||
MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
MmDestroyAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
|
||||
DPRINT("Finished MmReleaseMmInfo()\n");
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,33 @@ extern ULONG NtGlobalFlag;
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
LCID
|
||||
NTAPI
|
||||
MmGetSessionLocaleId(VOID)
|
||||
{
|
||||
PEPROCESS Process;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Get the current process */
|
||||
Process = PsGetCurrentProcess();
|
||||
|
||||
/* Check if it's the Session Leader */
|
||||
if (Process->Vm.Flags.SessionLeader)
|
||||
{
|
||||
/* Make sure it has a valid Session */
|
||||
if (Process->Session)
|
||||
{
|
||||
/* Get the Locale ID */
|
||||
#if ROS_HAS_SESSIONS
|
||||
return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Not a session leader, return the default */
|
||||
return PsDefaultThreadLocaleId;
|
||||
}
|
||||
|
||||
PVOID
|
||||
STDCALL
|
||||
MiCreatePebOrTeb(PEPROCESS Process,
|
||||
|
@ -489,6 +516,9 @@ MmCreateProcessAddressSpace(IN PEPROCESS Process,
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* The process now has an address space */
|
||||
Process->HasAddressSpace = TRUE;
|
||||
|
||||
/* Check if there's a Section Object */
|
||||
if (Section)
|
||||
{
|
||||
|
@ -559,3 +589,64 @@ exit:
|
|||
/* Return status to caller */
|
||||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmCleanProcessAddressSpace(IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME: Add part of MmDeleteProcessAddressSpace here */
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmDeleteProcessAddressSpace(PEPROCESS Process)
|
||||
{
|
||||
PVOID Address;
|
||||
PMEMORY_AREA MemoryArea;
|
||||
|
||||
DPRINT("MmDeleteProcessAddressSpace(Process %x (%s))\n", Process,
|
||||
Process->ImageFileName);
|
||||
|
||||
MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
|
||||
while ((MemoryArea = ((PMADDRESS_SPACE)&Process->VadRoot)->MemoryAreaRoot) != NULL)
|
||||
{
|
||||
switch (MemoryArea->Type)
|
||||
{
|
||||
case MEMORY_AREA_SECTION_VIEW:
|
||||
Address = (PVOID)MemoryArea->StartingAddress;
|
||||
MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
MmUnmapViewOfSection(Process, Address);
|
||||
MmLockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_VIRTUAL_MEMORY:
|
||||
case MEMORY_AREA_PEB_OR_TEB:
|
||||
MmFreeVirtualMemory(Process, MemoryArea);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_SHARED_DATA:
|
||||
case MEMORY_AREA_NO_ACCESS:
|
||||
MmFreeMemoryArea((PMADDRESS_SPACE)&Process->VadRoot,
|
||||
MemoryArea,
|
||||
NULL,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_MDL_MAPPING:
|
||||
KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES);
|
||||
break;
|
||||
|
||||
default:
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
Mmi386ReleaseMmInfo(Process);
|
||||
|
||||
MmUnlockAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
MmDestroyAddressSpace((PMADDRESS_SPACE)&Process->VadRoot);
|
||||
|
||||
DPRINT("Finished MmReleaseMmInfo()\n");
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -979,6 +979,14 @@ Language=English
|
|||
SPIN_LOCK_INIT_FAILURE
|
||||
.
|
||||
|
||||
MessageId=0x94
|
||||
Severity=Success
|
||||
Facility=System
|
||||
SymbolicName=KERNEL_STACK_LOCKED_AT_EXIT
|
||||
Language=English
|
||||
KERNEL_STACK_LOCKED_AT_EXIT
|
||||
.
|
||||
|
||||
MessageId=0x96
|
||||
Severity=Success
|
||||
Facility=System
|
||||
|
@ -1085,6 +1093,23 @@ Language=English
|
|||
certain\n conditions. There is absolutely no warranty for ReactOS.\n
|
||||
.
|
||||
|
||||
MessageId=0xE9
|
||||
Severity=Success
|
||||
Facility=System
|
||||
SymbolicName=ACTIVE_EX_WORKER_THREAD_TERMINATION
|
||||
Language=English
|
||||
ACTIVE_EX_WORKER_THREAD_TERMINATION
|
||||
.
|
||||
|
||||
MessageId=0xEF
|
||||
Severity=Success
|
||||
Facility=System
|
||||
SymbolicName=CRITICAL_PROCESS_DIED
|
||||
Language=English
|
||||
CRITICAL_PROCESS_DIED
|
||||
.
|
||||
|
||||
|
||||
MessageId=0xFC
|
||||
Severity=Success
|
||||
Facility=System
|
||||
|
|
|
@ -244,7 +244,7 @@ ObpCloseHandleTableEntry(IN PHANDLE_TABLE HandleTable,
|
|||
//
|
||||
// WE DONT CLOSE REGISTRY HANDLES BECAUSE CM IS BRAINDEAD
|
||||
//
|
||||
DPRINT1("NOT CLOSING THE KEY\n");
|
||||
DPRINT("NOT CLOSING THE KEY\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1119,6 +1119,13 @@ ObpDuplicateHandleCallback(IN PHANDLE_TABLE HandleTable,
|
|||
return Ret;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObClearProcessHandleTable(IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpCreateHandleTable
|
||||
*
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#define NTDDI_VERSION NTDDI_WINXP
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -20,6 +21,49 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
|||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObDereferenceDeviceMap(IN PEPROCESS Process)
|
||||
{
|
||||
//KIRQL OldIrql;
|
||||
PDEVICE_MAP DeviceMap = Process->DeviceMap;
|
||||
|
||||
/* FIXME: We don't use Process Devicemaps yet */
|
||||
if (DeviceMap)
|
||||
{
|
||||
/* FIXME: Acquire the DeviceMap Spinlock */
|
||||
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
|
||||
|
||||
/* Delete the device map link and dereference it */
|
||||
Process->DeviceMap = NULL;
|
||||
if (--DeviceMap->ReferenceCount)
|
||||
{
|
||||
/* Nobody is referencing it anymore, unlink the DOS directory */
|
||||
DeviceMap->DosDevicesDirectory->DeviceMap = NULL;
|
||||
|
||||
/* FIXME: Release the DeviceMap Spinlock */
|
||||
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
|
||||
|
||||
/* Dereference the DOS Devices Directory and free the Device Map */
|
||||
ObDereferenceObject(DeviceMap->DosDevicesDirectory);
|
||||
ExFreePool(DeviceMap);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: Release the DeviceMap Spinlock */
|
||||
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObInheritDeviceMap(IN PEPROCESS Parent,
|
||||
IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME: Devicemap Support */
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpDeleteNameCheck
|
||||
*
|
||||
|
|
|
@ -90,7 +90,7 @@ ObfDereferenceObject(IN PVOID Object)
|
|||
|
||||
if (Header->PointerCount < Header->HandleCount)
|
||||
{
|
||||
DPRINT1("Misbehaving object: %wZ\n", &Header->Type->Name);
|
||||
DPRINT("Misbehaving object: %wZ\n", &Header->Type->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ ObfDereferenceObject(IN PVOID Object)
|
|||
/* Sanity check */
|
||||
if (Header->HandleCount)
|
||||
{
|
||||
DPRINT1("Misbehaving object: %wZ\n", &Header->Type->Name);
|
||||
DPRINT("Misbehaving object: %wZ\n", &Header->Type->Name);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,6 +183,13 @@ PoSetDeviceBusy(
|
|||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PopCleanupPowerState(IN PPOWER_STATE PowerState)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
|
|
@ -4,16 +4,14 @@
|
|||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ps/job.c
|
||||
* PURPOSE: Job Native Functions
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) (stubs)
|
||||
* Thomas Weidenmueller <w3seek@reactos.com>
|
||||
*/
|
||||
|
||||
/* Note: Jobs are only supported on Win2K+ */
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#define NDEBUG
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
|
@ -39,7 +37,8 @@ static GENERIC_MAPPING PiJobMapping =
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID STDCALL
|
||||
VOID
|
||||
NTAPI
|
||||
PiDeleteJob ( PVOID ObjectBody )
|
||||
{
|
||||
PEJOB Job = (PEJOB)ObjectBody;
|
||||
|
@ -89,8 +88,7 @@ PsInitJobManagment ( VOID )
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspAssignProcessToJob (
|
||||
PEPROCESS Process,
|
||||
PspAssignProcessToJob(PEPROCESS Process,
|
||||
PEJOB Job)
|
||||
{
|
||||
DPRINT("PspAssignProcessToJob() is unimplemented!\n");
|
||||
|
@ -99,8 +97,7 @@ PspAssignProcessToJob (
|
|||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PspTerminateJobObject (
|
||||
PEJOB Job,
|
||||
PspTerminateJobObject(PEJOB Job,
|
||||
KPROCESSOR_MODE AccessMode,
|
||||
NTSTATUS ExitStatus )
|
||||
{
|
||||
|
@ -108,6 +105,21 @@ PspTerminateJobObject (
|
|||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspRemoveProcessFromJob(IN PEPROCESS Process,
|
||||
IN PEJOB Job)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspExitProcessFromJob(IN PEJOB Job,
|
||||
IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
|
@ -547,8 +559,7 @@ PsGetJobUIRestrictionsClass ( PEJOB Job )
|
|||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
PsSetJobUIRestrictionsClass (
|
||||
PEJOB Job,
|
||||
PsSetJobUIRestrictionsClass(PEJOB Job,
|
||||
ULONG UIRestrictionsClass)
|
||||
{
|
||||
ASSERT(Job);
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -64,15 +64,6 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID);
|
|||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PiShutdownProcessManager(VOID)
|
||||
{
|
||||
DPRINT("PiShutdownProcessManager()\n");
|
||||
|
||||
PspKillMostProcesses();
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
|
|
|
@ -39,6 +39,40 @@ PspUnlockProcessSecurityShared(PEPROCESS Process)
|
|||
KeLeaveGuardedRegion();
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspDeleteProcessSecurity(IN PEPROCESS Process)
|
||||
{
|
||||
/* Check if we have a token */
|
||||
if (Process->Token.Object)
|
||||
{
|
||||
/* Deassign it */
|
||||
SeDeassignPrimaryToken(Process);
|
||||
Process->Token.Object = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PspDeleteThreadSecurity(IN PETHREAD Thread)
|
||||
{
|
||||
/* Check if we have active impersonation info */
|
||||
if (Thread->ActiveImpersonationInfo)
|
||||
{
|
||||
/* Dereference its token */
|
||||
ObDereferenceObject(Thread->ImpersonationInfo->Token);
|
||||
}
|
||||
|
||||
/* Check if we have impersonation info */
|
||||
if (Thread->ImpersonationInfo)
|
||||
{
|
||||
/* Free it */
|
||||
ExFreePool(Thread->ImpersonationInfo);
|
||||
Thread->ActiveImpersonationInfo = FALSE;
|
||||
Thread->ImpersonationInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ps/thread.c
|
||||
* PURPOSE: Thread managment
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
* Phillip Susi
|
||||
* PURPOSE: Process Manager: Thread Management
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
* Thomas Weidenmueller (w3seek@reactos.org
|
||||
*/
|
||||
|
||||
/*
|
||||
* Alex FIXMEs:
|
||||
* - CRITICAL: NtCurrentTeb returns KPCR.
|
||||
* - CRITICAL: Verify rundown APIs (ex/rundown.c) and use them where necessary.
|
||||
* - MAJOR: Implement Pushlocks and use them as process lock.
|
||||
* - MAJOR: Implement Safe Referencing (See PsGetNextProcess/Thread).
|
||||
* - MAJOR: Implement Fast Referencing (mostly for tokens).
|
||||
* - MAJOR: Use Guarded Mutex instead of Fast Mutex for Active Process Locks.
|
||||
* - Generate process cookie for user-more thread.
|
||||
* - Add security calls where necessary.
|
||||
* - KeInit/StartThread for better isolation of code
|
||||
*/
|
||||
|
||||
/* INCLUDES ****************************************************************/
|
||||
|
@ -19,83 +31,112 @@
|
|||
extern LIST_ENTRY PsActiveProcessHead;
|
||||
extern PEPROCESS PsIdleProcess;
|
||||
extern PVOID PspSystemDllEntryPoint;
|
||||
extern PVOID PspSystemDllBase;
|
||||
extern PHANDLE_TABLE PspCidTable;
|
||||
|
||||
extern BOOLEAN CcPfEnablePrefetcher;
|
||||
extern ULONG MmReadClusterSize;
|
||||
POBJECT_TYPE PsThreadType = NULL;
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
PspThreadSpecialApc(PKAPC Apc,
|
||||
PKNORMAL_ROUTINE* NormalRoutine,
|
||||
PVOID* NormalContext,
|
||||
PVOID* SystemArgument1,
|
||||
PVOID* SystemArgument2)
|
||||
{
|
||||
ExFreePool(Apc);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PspUserThreadStartup(PKSTART_ROUTINE StartRoutine,
|
||||
PVOID StartContext)
|
||||
{
|
||||
PKAPC ThreadApc;
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
PETHREAD Thread;
|
||||
PTEB Teb;
|
||||
BOOLEAN DeadThread = FALSE;
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("I am a new USER thread. This is my start routine: %p. This my context: %p."
|
||||
"This is my IRQL: %d. This is my Thread Pointer: %x.\n", StartRoutine,
|
||||
StartContext, KeGetCurrentIrql(), Thread);
|
||||
/* Go to Passive Level */
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
Thread = PsGetCurrentThread();
|
||||
|
||||
if (!Thread->Terminated) {
|
||||
|
||||
/* Allocate the APC */
|
||||
ThreadApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('T', 'h', 'r','d'));
|
||||
|
||||
/* Initialize it */
|
||||
KeInitializeApc(ThreadApc,
|
||||
&Thread->Tcb,
|
||||
OriginalApcEnvironment,
|
||||
PspThreadSpecialApc,
|
||||
NULL,
|
||||
PspSystemDllEntryPoint,
|
||||
UserMode,
|
||||
NULL);
|
||||
|
||||
/* Insert it into the queue */
|
||||
KeInsertQueueApc(ThreadApc, NULL, NULL, IO_NO_INCREMENT);
|
||||
Thread->Tcb.ApcState.UserApcPending = TRUE;
|
||||
/* Check if the thread is dead */
|
||||
if (Thread->DeadThread)
|
||||
{
|
||||
/* Remember that we're dead */
|
||||
DPRINT1("This thread is already dead\n");
|
||||
DeadThread = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get the Locale ID and save Preferred Proc */
|
||||
Teb = NtCurrentTeb(); /* FIXME: This returns KPCR!!! */
|
||||
//Teb->CurrentLocale = MmGetSessionLocaleId();
|
||||
//Teb->IdealProcessor = Thread->Tcb.IdealProcessor;
|
||||
}
|
||||
|
||||
/* Go to Passive Level and notify debugger */
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
DbgkCreateThread(StartContext);
|
||||
/* Check if this is a system thread, or if we're hiding */
|
||||
if ((Thread->SystemThread) || (Thread->HideFromDebugger))
|
||||
{
|
||||
/* Notify the debugger */
|
||||
DbgkCreateThread(StartContext);
|
||||
}
|
||||
|
||||
/* Make sure we're not already dead */
|
||||
if (!DeadThread)
|
||||
{
|
||||
/* Check if the Prefetcher is enabled */
|
||||
if (CcPfEnablePrefetcher)
|
||||
{
|
||||
/* FIXME: Prepare to prefetch this process */
|
||||
}
|
||||
|
||||
/* Raise to APC */
|
||||
KfRaiseIrql(APC_LEVEL);
|
||||
|
||||
/* Queue the User APC */
|
||||
KiInitializeUserApc(NULL,
|
||||
(PVOID)((ULONG_PTR)Thread->Tcb.InitialStack -
|
||||
sizeof(KTRAP_FRAME) -
|
||||
sizeof(FX_SAVE_AREA)),
|
||||
PspSystemDllEntryPoint,
|
||||
NULL,
|
||||
PspSystemDllBase,
|
||||
NULL);
|
||||
|
||||
/* Lower it back to passive */
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're dead, kill us now */
|
||||
PspTerminateThreadByPointer(Thread, STATUS_THREAD_IS_TERMINATING, TRUE);
|
||||
}
|
||||
|
||||
/* Do we have a cookie set yet? */
|
||||
if (!SharedUserData->Cookie)
|
||||
{
|
||||
/* FIXME: Generate cookie */
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PspSystemThreadStartup(PKSTART_ROUTINE StartRoutine,
|
||||
PVOID StartContext)
|
||||
{
|
||||
PETHREAD Thread = PsGetCurrentThread();
|
||||
PETHREAD Thread;
|
||||
|
||||
/* Unlock the dispatcher Database */
|
||||
KeLowerIrql(PASSIVE_LEVEL);
|
||||
Thread = PsGetCurrentThread();
|
||||
|
||||
/* Make sure it's not terminated by now */
|
||||
if (!Thread->Terminated) {
|
||||
|
||||
/* Call it */
|
||||
(StartRoutine)(StartContext);
|
||||
/* Make sure the thread isn't gone */
|
||||
if (!(Thread->Terminated) || !(Thread->DeadThread))
|
||||
{
|
||||
/* Call it the Start Routine */
|
||||
StartRoutine(StartContext);
|
||||
}
|
||||
|
||||
/* Exit the thread */
|
||||
PspExitThread(STATUS_SUCCESS);
|
||||
PspTerminateThreadByPointer(Thread, STATUS_SUCCESS, TRUE);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
|
@ -117,46 +158,54 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
NTSTATUS Status;
|
||||
HANDLE_TABLE_ENTRY CidEntry;
|
||||
ULONG_PTR KernelStack;
|
||||
PAGED_CODE();
|
||||
|
||||
/* If we were called from PsCreateSystemThread, then we're kernel mode */
|
||||
if (StartRoutine) PreviousMode = KernelMode;
|
||||
|
||||
/* Reference the Process by handle or pointer, depending on what we got */
|
||||
DPRINT("PspCreateThread: %x, %x, %x\n", ProcessHandle, TargetProcess, ThreadContext);
|
||||
if (ProcessHandle) {
|
||||
|
||||
if (ProcessHandle)
|
||||
{
|
||||
/* Normal thread or System Thread */
|
||||
DPRINT("Referencing Parent Process\n");
|
||||
Status = ObReferenceObjectByHandle(ProcessHandle,
|
||||
PROCESS_CREATE_THREAD,
|
||||
PsProcessType,
|
||||
PreviousMode,
|
||||
(PVOID*)&Process,
|
||||
NULL);
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* System thread inside System Process, or Normal Thread with a bug */
|
||||
if (StartRoutine) {
|
||||
|
||||
if (StartRoutine)
|
||||
{
|
||||
/* Reference the Process by Pointer */
|
||||
DPRINT("Referencing Parent System Process\n");
|
||||
ObReferenceObject(TargetProcess);
|
||||
Process = TargetProcess;
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fake ObReference returning this */
|
||||
Status = STATUS_INVALID_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for success */
|
||||
if(!NT_SUCCESS(Status)) {
|
||||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Invalid Process Handle, or no handle given\n");
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Also make sure that User-Mode isn't trying to create a system thread */
|
||||
if ((PreviousMode != KernelMode) && (Process == PsInitialSystemProcess))
|
||||
{
|
||||
ObDereferenceObject(Process);
|
||||
return STATUS_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
/* Create Thread Object */
|
||||
DPRINT("Creating Thread Object\n");
|
||||
Status = ObCreateObject(PreviousMode,
|
||||
PsThreadType,
|
||||
ObjectAttributes,
|
||||
|
@ -166,69 +215,61 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
0,
|
||||
0,
|
||||
(PVOID*)&Thread);
|
||||
|
||||
/* Check for success */
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
|
||||
/* Dereference the Process */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* We failed; dereference the process and exit */
|
||||
DPRINT1("Failed to Create Thread Object\n");
|
||||
ObDereferenceObject(Process);
|
||||
return(Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Zero the Object entirely */
|
||||
DPRINT("Cleaning Thread Object\n");
|
||||
RtlZeroMemory(Thread, sizeof(ETHREAD));
|
||||
|
||||
/* Set the Process CID */
|
||||
Thread->ThreadsProcess = Process;
|
||||
Thread->Cid.UniqueProcess = Process->UniqueProcessId;
|
||||
|
||||
/* Create Cid Handle */
|
||||
DPRINT("Creating Thread Handle (CID)\n");
|
||||
CidEntry.Object = Thread;
|
||||
CidEntry.GrantedAccess = 0;
|
||||
Thread->Cid.UniqueThread = ExCreateHandle(PspCidTable, &CidEntry);
|
||||
if (!Thread->Cid.UniqueThread) {
|
||||
|
||||
if (!Thread->Cid.UniqueThread)
|
||||
{
|
||||
/* We couldn't create the CID, dereference everything and fail */
|
||||
DPRINT1("Failed to create Thread Handle (CID)\n");
|
||||
ObDereferenceObject(Process);
|
||||
ObDereferenceObject(Thread);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* Initialize Lists */
|
||||
DPRINT("Initialliazing Thread Lists and Locks\n");
|
||||
/* Save the read cluster size */
|
||||
Thread->ReadClusterSize = MmReadClusterSize;
|
||||
|
||||
/* Initialize the LPC Reply Semaphore */
|
||||
KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, MAXLONG);
|
||||
|
||||
/* Initialize the list heads and locks */
|
||||
InitializeListHead(&Thread->LpcReplyChain);
|
||||
InitializeListHead(&Thread->IrpList);
|
||||
InitializeListHead(&Thread->PostBlockList);
|
||||
InitializeListHead(&Thread->ActiveTimerListHead);
|
||||
KeInitializeSpinLock(&Thread->ActiveTimerListLock);
|
||||
|
||||
/* Initialize LPC */
|
||||
DPRINT("Initialliazing Thread Semaphore\n");
|
||||
KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, MAXLONG);
|
||||
|
||||
/* Allocate Stack for non-GUI Thread */
|
||||
DPRINT("Initialliazing Thread Stack\n");
|
||||
KernelStack = (ULONG_PTR)MmCreateKernelStack(FALSE) + KERNEL_STACK_SIZE;
|
||||
|
||||
/* Set the Process CID */
|
||||
DPRINT("Initialliazing Thread PID and Parent Process\n");
|
||||
Thread->Cid.UniqueProcess = Process->UniqueProcessId;
|
||||
Thread->ThreadsProcess = Process;
|
||||
|
||||
/* Now let the kernel initialize the context */
|
||||
if (ThreadContext) {
|
||||
|
||||
/* User-mode Thread */
|
||||
|
||||
/* Create Teb */
|
||||
DPRINT("Initialliazing Thread PEB\n");
|
||||
if (ThreadContext)
|
||||
{
|
||||
/* User-mode Thread, create Teb */
|
||||
TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb);
|
||||
|
||||
/* Set the Start Addresses */
|
||||
DPRINT("Initialliazing Thread Start Addresses :%x, %x\n", ThreadContext->Eip, ThreadContext->Eax);
|
||||
Thread->StartAddress = (PVOID)ThreadContext->Eip;
|
||||
Thread->Win32StartAddress = (PVOID)ThreadContext->Eax;
|
||||
|
||||
/* Let the kernel intialize the Thread */
|
||||
DPRINT("Initialliazing Kernel Thread\n");
|
||||
KeInitializeThread(&Process->Pcb,
|
||||
&Thread->Tcb,
|
||||
PspUserThreadStartup,
|
||||
|
@ -237,16 +278,14 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
ThreadContext,
|
||||
TebBase,
|
||||
(PVOID)KernelStack);
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* System Thread */
|
||||
DPRINT("Initialliazing Thread Start Address :%x\n", StartRoutine);
|
||||
Thread->StartAddress = StartRoutine;
|
||||
Thread->SystemThread = TRUE;
|
||||
InterlockedOr(&Thread->CrossThreadFlags, 0x10);
|
||||
|
||||
/* Let the kernel intialize the Thread */
|
||||
DPRINT("Initialliazing Kernel Thread\n");
|
||||
KeInitializeThread(&Process->Pcb,
|
||||
&Thread->Tcb,
|
||||
PspSystemThreadStartup,
|
||||
|
@ -262,61 +301,63 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
* Note, this is the ETHREAD Thread List. It is removed in
|
||||
* ps/kill.c!PspExitThread.
|
||||
*/
|
||||
DPRINT("Inserting into Process Thread List \n");
|
||||
InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
|
||||
Process->ActiveThreads++;
|
||||
|
||||
/* Notify WMI */
|
||||
//WmiTraceProcess(Process, TRUE);
|
||||
//WmiTraceThread(Thread, InitialTeb, TRUE);
|
||||
|
||||
/* Notify Thread Creation */
|
||||
DPRINT("Running Thread Notify \n");
|
||||
PspRunCreateThreadNotifyRoutines(Thread, TRUE);
|
||||
|
||||
/* Suspend the Thread if we have to */
|
||||
if (CreateSuspended) {
|
||||
|
||||
DPRINT("Suspending Thread\n");
|
||||
if (CreateSuspended)
|
||||
{
|
||||
KeSuspendThread(&Thread->Tcb);
|
||||
}
|
||||
|
||||
/* Check if we were already terminated */
|
||||
if (Thread->Terminated)
|
||||
{
|
||||
/* Force us to wake up to terminate */
|
||||
KeForceResumeThread(&Thread->Tcb);
|
||||
}
|
||||
|
||||
/* Reference ourselves as a keep-alive */
|
||||
ObReferenceObject(Thread);
|
||||
|
||||
/* Insert the Thread into the Object Manager */
|
||||
DPRINT("Inserting Thread\n");
|
||||
Status = ObInsertObject((PVOID)Thread,
|
||||
NULL,
|
||||
DesiredAccess,
|
||||
0,
|
||||
NULL,
|
||||
&hThread);
|
||||
|
||||
/* Return Cid and Handle */
|
||||
DPRINT("All worked great!\n");
|
||||
if(NT_SUCCESS(Status)) {
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
if(ClientId != NULL) {
|
||||
|
||||
*ClientId = Thread->Cid;
|
||||
}
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* Wrap in SEH to protect against bad user-mode pointers */
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Return Cid and Handle */
|
||||
if(ClientId) *ClientId = Thread->Cid;
|
||||
*ThreadHandle = hThread;
|
||||
|
||||
} _SEH_HANDLE {
|
||||
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
|
||||
} _SEH_END;
|
||||
}
|
||||
_SEH_END;
|
||||
}
|
||||
|
||||
/* FIXME: SECURITY */
|
||||
|
||||
/* Dispatch thread */
|
||||
DPRINT("About to dispatch the thread: %x!\n", &Thread->Tcb);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
KiUnblockThread(&Thread->Tcb, NULL, 0);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
/* Return */
|
||||
DPRINT("Returning\n");
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -324,7 +365,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
|||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsCreateSystemThread(PHANDLE ThreadHandle,
|
||||
ACCESS_MASK DesiredAccess,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
|
@ -335,10 +376,11 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
|
|||
{
|
||||
PEPROCESS TargetProcess = NULL;
|
||||
HANDLE Handle = ProcessHandle;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Check if we have a handle. If not, use the System Process */
|
||||
if (!ProcessHandle) {
|
||||
|
||||
if (!ProcessHandle)
|
||||
{
|
||||
Handle = NULL;
|
||||
TargetProcess = PsInitialSystemProcess;
|
||||
}
|
||||
|
@ -361,7 +403,7 @@ PsCreateSystemThread(PHANDLE ThreadHandle,
|
|||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
||||
OUT PETHREAD *Thread)
|
||||
{
|
||||
|
@ -369,7 +411,6 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
|||
PETHREAD FoundThread;
|
||||
NTSTATUS Status = STATUS_INVALID_PARAMETER;
|
||||
PAGED_CODE();
|
||||
|
||||
KeEnterCriticalRegion();
|
||||
|
||||
/* Get the CID Handle Entry */
|
||||
|
@ -392,9 +433,8 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
|||
ExUnlockHandleTableEntry(PspCidTable, CidEntry);
|
||||
}
|
||||
|
||||
KeLeaveCriticalRegion();
|
||||
|
||||
/* Return to caller */
|
||||
KeLeaveCriticalRegion();
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -402,7 +442,7 @@ PsLookupThreadByThreadId(IN HANDLE ThreadId,
|
|||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetCurrentThreadId(VOID)
|
||||
{
|
||||
return(PsGetCurrentThread()->Cid.UniqueThread);
|
||||
|
@ -412,7 +452,7 @@ PsGetCurrentThreadId(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
ULONG
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadFreezeCount(PETHREAD Thread)
|
||||
{
|
||||
return Thread->Tcb.FreezeCount;
|
||||
|
@ -422,7 +462,7 @@ PsGetThreadFreezeCount(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadHardErrorsAreDisabled(PETHREAD Thread)
|
||||
{
|
||||
return Thread->HardErrorsAreDisabled;
|
||||
|
@ -432,7 +472,7 @@ PsGetThreadHardErrorsAreDisabled(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadId(PETHREAD Thread)
|
||||
{
|
||||
return Thread->Cid.UniqueThread;
|
||||
|
@ -442,7 +482,7 @@ PsGetThreadId(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
PEPROCESS
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadProcess(PETHREAD Thread)
|
||||
{
|
||||
return Thread->ThreadsProcess;
|
||||
|
@ -452,7 +492,7 @@ PsGetThreadProcess(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadProcessId(PETHREAD Thread)
|
||||
{
|
||||
return Thread->Cid.UniqueProcess;
|
||||
|
@ -462,7 +502,7 @@ PsGetThreadProcessId(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
HANDLE
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadSessionId(PETHREAD Thread)
|
||||
{
|
||||
return (HANDLE)Thread->ThreadsProcess->Session;
|
||||
|
@ -472,7 +512,7 @@ PsGetThreadSessionId(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
PTEB
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadTeb(PETHREAD Thread)
|
||||
{
|
||||
return Thread->Tcb.Teb;
|
||||
|
@ -482,7 +522,7 @@ PsGetThreadTeb(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetThreadWin32Thread(PETHREAD Thread)
|
||||
{
|
||||
return Thread->Tcb.Win32Thread;
|
||||
|
@ -492,7 +532,7 @@ PsGetThreadWin32Thread(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
KPROCESSOR_MODE
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetCurrentThreadPreviousMode(VOID)
|
||||
{
|
||||
return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||
|
@ -502,7 +542,7 @@ PsGetCurrentThreadPreviousMode(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetCurrentThreadStackBase(VOID)
|
||||
{
|
||||
return PsGetCurrentThread()->Tcb.StackBase;
|
||||
|
@ -512,7 +552,7 @@ PsGetCurrentThreadStackBase(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
PVOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsGetCurrentThreadStackLimit(VOID)
|
||||
{
|
||||
return (PVOID)PsGetCurrentThread()->Tcb.StackLimit;
|
||||
|
@ -522,7 +562,7 @@ PsGetCurrentThreadStackLimit(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsIsThreadTerminating(IN PETHREAD Thread)
|
||||
{
|
||||
return (Thread->Terminated ? TRUE : FALSE);
|
||||
|
@ -532,7 +572,7 @@ PsIsThreadTerminating(IN PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsIsSystemThread(PETHREAD Thread)
|
||||
{
|
||||
return (Thread->SystemThread ? TRUE: FALSE);
|
||||
|
@ -542,7 +582,7 @@ PsIsSystemThread(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsIsThreadImpersonating(PETHREAD Thread)
|
||||
{
|
||||
return Thread->ActiveImpersonationInfo;
|
||||
|
@ -552,7 +592,7 @@ PsIsThreadImpersonating(PETHREAD Thread)
|
|||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsSetThreadHardErrorsAreDisabled(PETHREAD Thread,
|
||||
BOOLEAN HardErrorsAreDisabled)
|
||||
{
|
||||
|
@ -563,7 +603,7 @@ PsSetThreadHardErrorsAreDisabled(PETHREAD Thread,
|
|||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
PsSetThreadWin32Thread(PETHREAD Thread,
|
||||
PVOID Win32Thread)
|
||||
{
|
||||
|
@ -571,7 +611,7 @@ PsSetThreadWin32Thread(PETHREAD Thread,
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
NtCreateThread(OUT PHANDLE ThreadHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||
|
@ -582,55 +622,53 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
|
|||
IN BOOLEAN CreateSuspended)
|
||||
{
|
||||
INITIAL_TEB SafeInitialTeb;
|
||||
CONTEXT SafeContext;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
|
||||
ThreadHandle,ThreadContext);
|
||||
|
||||
if(KeGetPreviousMode() != KernelMode) {
|
||||
|
||||
if (ThreadContext == NULL) {
|
||||
/* Check if this was from user-mode */
|
||||
if(KeGetPreviousMode() != KernelMode)
|
||||
{
|
||||
/* Make sure that we got a context */
|
||||
if (!ThreadContext)
|
||||
{
|
||||
DPRINT1("No context for User-Mode Thread!!\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
_SEH_TRY {
|
||||
|
||||
/* Protect checks */
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Make sure the handle pointer we got is valid */
|
||||
ProbeForWriteHandle(ThreadHandle);
|
||||
|
||||
if(ClientId != NULL) {
|
||||
|
||||
ProbeForWrite(ClientId,
|
||||
sizeof(CLIENT_ID),
|
||||
sizeof(ULONG));
|
||||
/* Check if the caller wants a client id */
|
||||
if(ClientId)
|
||||
{
|
||||
/* Make sure we can write to it */
|
||||
ProbeForWrite(ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
|
||||
}
|
||||
|
||||
if(ThreadContext != NULL) {
|
||||
/* Make sure that the entire context is readable */
|
||||
ProbeForRead(ThreadContext, sizeof(CONTEXT), sizeof(ULONG));
|
||||
|
||||
ProbeForRead(ThreadContext,
|
||||
sizeof(CONTEXT),
|
||||
sizeof(ULONG));
|
||||
SafeContext = *ThreadContext;
|
||||
ThreadContext = &SafeContext;
|
||||
}
|
||||
|
||||
ProbeForRead(InitialTeb,
|
||||
sizeof(INITIAL_TEB),
|
||||
sizeof(ULONG));
|
||||
/* Check the Initial TEB */
|
||||
ProbeForRead(InitialTeb, sizeof(INITIAL_TEB), sizeof(ULONG));
|
||||
SafeInitialTeb = *InitialTeb;
|
||||
InitialTeb = &SafeInitialTeb;
|
||||
|
||||
} _SEH_HANDLE {
|
||||
|
||||
}
|
||||
_SEH_HANDLE
|
||||
{
|
||||
Status = _SEH_GetExceptionCode();
|
||||
}
|
||||
_SEH_END;
|
||||
|
||||
} _SEH_END;
|
||||
|
||||
/* Handle any failures in our SEH checks */
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use the Initial TEB as is */
|
||||
SafeInitialTeb = *InitialTeb;
|
||||
}
|
||||
|
||||
/* Call the shared function */
|
||||
return PspCreateThread(ThreadHandle,
|
||||
|
@ -640,7 +678,7 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
|
|||
NULL,
|
||||
ClientId,
|
||||
ThreadContext,
|
||||
InitialTeb,
|
||||
&SafeInitialTeb,
|
||||
CreateSuspended,
|
||||
NULL,
|
||||
NULL);
|
||||
|
@ -650,7 +688,7 @@ NtCreateThread(OUT PHANDLE ThreadHandle,
|
|||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
NtOpenThread(OUT PHANDLE ThreadHandle,
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
|
@ -724,19 +762,14 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
|||
DesiredAccess,
|
||||
NULL,
|
||||
&hThread);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Could not open object by name\n");
|
||||
if (!NT_SUCCESS(Status)) DPRINT1("Could not open object by name\n");
|
||||
}
|
||||
}
|
||||
else if (ClientId != NULL)
|
||||
{
|
||||
/* Open by Thread ID */
|
||||
if (ClientId->UniqueProcess)
|
||||
{
|
||||
/* Get the Process */
|
||||
DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
|
||||
Status = PsLookupProcessThreadByCid(ClientId,
|
||||
NULL,
|
||||
&Thread);
|
||||
|
@ -744,7 +777,6 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
|||
else
|
||||
{
|
||||
/* Get the Process */
|
||||
DPRINT("Opening by Thread ID: %x\n", ClientId->UniqueThread);
|
||||
Status = PsLookupThreadByThreadId(ClientId->UniqueThread,
|
||||
&Thread);
|
||||
}
|
||||
|
@ -777,11 +809,13 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
|||
return STATUS_INVALID_PARAMETER_MIX;
|
||||
}
|
||||
|
||||
/* Write back the handle */
|
||||
/* Check for success */
|
||||
if(NT_SUCCESS(Status))
|
||||
{
|
||||
/* Protect against bad user-mode pointers */
|
||||
_SEH_TRY
|
||||
{
|
||||
/* Write back the handle */
|
||||
*ThreadHandle = hThread;
|
||||
}
|
||||
_SEH_HANDLE
|
||||
|
@ -796,7 +830,7 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
NtYieldExecution(VOID)
|
||||
{
|
||||
KiDispatchThread(Ready);
|
||||
|
@ -804,7 +838,7 @@ NtYieldExecution(VOID)
|
|||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NTAPI
|
||||
NtTestAlert(VOID)
|
||||
{
|
||||
/* Check and Alert Thread if needed */
|
||||
|
@ -815,7 +849,7 @@ NtTestAlert(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
KPROCESSOR_MODE
|
||||
STDCALL
|
||||
NTAPI
|
||||
ExGetPreviousMode (VOID)
|
||||
{
|
||||
return (KPROCESSOR_MODE)PsGetCurrentThread()->Tcb.PreviousMode;
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
static PKWIN32_PROCESS_CALLOUT PspWin32ProcessCallback = NULL;
|
||||
static PKWIN32_THREAD_CALLOUT PspWin32ThreadCallback = NULL;
|
||||
PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout = NULL;
|
||||
PKWIN32_THREAD_CALLOUT PspW32ThreadCallout = NULL;
|
||||
extern PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse;
|
||||
extern PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete;
|
||||
extern PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete;
|
||||
|
@ -53,8 +53,8 @@ VOID
|
|||
STDCALL
|
||||
PsEstablishWin32Callouts(PWIN32_CALLOUTS_FPNS CalloutData)
|
||||
{
|
||||
PspWin32ProcessCallback = CalloutData->ProcessCallout;
|
||||
PspWin32ThreadCallback = CalloutData->ThreadCallout;
|
||||
PspW32ProcessCallout = CalloutData->ProcessCallout;
|
||||
PspW32ThreadCallout = CalloutData->ThreadCallout;
|
||||
ExpWindowStationObjectParse = CalloutData->WindowStationParseProcedure;
|
||||
ExpWindowStationObjectDelete = CalloutData->WindowStationDeleteProcedure;
|
||||
ExpDesktopObjectDelete = CalloutData->DesktopDeleteProcedure;
|
||||
|
@ -79,7 +79,7 @@ PsConvertToGuiThread(VOID)
|
|||
}
|
||||
|
||||
/* Make sure win32k is here */
|
||||
if (!PspWin32ProcessCallback)
|
||||
if (!PspW32ProcessCallout)
|
||||
{
|
||||
DPRINT1("Danger: Win32K call attempted but Win32k not ready!\n");
|
||||
return STATUS_ACCESS_DENIED;
|
||||
|
@ -122,7 +122,7 @@ PsConvertToGuiThread(VOID)
|
|||
if (!Process->Win32Process)
|
||||
{
|
||||
/* Now tell win32k about us */
|
||||
Status = PspWin32ProcessCallback(Process, TRUE);
|
||||
Status = PspW32ProcessCallout(Process, TRUE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Danger: Win32k wasn't happy about us!\n");
|
||||
|
@ -135,7 +135,7 @@ PsConvertToGuiThread(VOID)
|
|||
ASSERT(Thread->Tcb.Win32Thread == 0);
|
||||
|
||||
/* Tell Win32k about our thread */
|
||||
Status = PspWin32ThreadCallback(Thread, PsW32ThreadCalloutInitialize);
|
||||
Status = PspW32ThreadCallout(Thread, PsW32ThreadCalloutInitialize);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Revert our table */
|
||||
|
@ -147,39 +147,6 @@ PsConvertToGuiThread(VOID)
|
|||
return Status;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PsTerminateWin32Process (PEPROCESS Process)
|
||||
{
|
||||
if (Process->Win32Process == NULL)
|
||||
return;
|
||||
|
||||
if (PspWin32ProcessCallback != NULL)
|
||||
{
|
||||
PspWin32ProcessCallback (Process, FALSE);
|
||||
}
|
||||
|
||||
/* don't delete the W32PROCESS structure at this point, wait until the
|
||||
EPROCESS structure is being freed */
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
PsTerminateWin32Thread (PETHREAD Thread)
|
||||
{
|
||||
if (Thread->Tcb.Win32Thread != NULL)
|
||||
{
|
||||
if (PspWin32ThreadCallback != NULL)
|
||||
{
|
||||
PspWin32ThreadCallback (Thread, PsW32ThreadCalloutExit);
|
||||
}
|
||||
|
||||
/* don't delete the W32THREAD structure at this point, wait until the
|
||||
ETHREAD structure is being freed */
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtW32Call(IN ULONG RoutineIndex,
|
||||
|
|
|
@ -13,6 +13,22 @@
|
|||
#include <ntoskrnl.h>
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* INTERNAL *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
SeDetailedAuditingWithToken(IN PTOKEN Token)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
SeAuditProcessExit(IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
|
|
Loading…
Reference in a new issue