mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
- Fix KeAttackProcess, KeStackAttachProcess, KeUnstackDetachProcess and KeDetachProcess. The code was brain-dead and I must've been drunk when I first wrote it.
- Update some NDK definitions and some fixes. - Update HAL Private Dispatch Table to 2.0 - Make RtlIpv* API definitions more correct. svn path=/trunk/; revision=19847
This commit is contained in:
parent
deca81698a
commit
0a36bfb449
11 changed files with 347 additions and 236 deletions
|
@ -110,6 +110,7 @@ Author:
|
|||
#define KPCR_GDT 0x3C
|
||||
#define KPCR_TSS 0x40
|
||||
#define KPCR_SET_MEMBER 0x48
|
||||
#define KPCR_NUMBER 0x51
|
||||
#define KPCR_CURRENT_THREAD 0x124
|
||||
#define KPCR_PROCESSOR_NUMBER 0x130
|
||||
#define KPCR_PRCB_SET_MEMBER 0x134
|
||||
|
|
|
@ -61,10 +61,29 @@ typedef enum _FIRMWARE_ENTRY
|
|||
//
|
||||
// Hal Private dispatch Table
|
||||
//
|
||||
#define HAL_PRIVATE_DISPATCH_VERSION 1
|
||||
#define HAL_PRIVATE_DISPATCH_VERSION 2
|
||||
typedef struct _HAL_PRIVATE_DISPATCH
|
||||
{
|
||||
ULONG Version;
|
||||
PVOID HalHandlerForBus;
|
||||
PVOID HalHandlerForBus2;
|
||||
PVOID HalLocateHiberRanges;
|
||||
PVOID HalRegisterBusHandler;
|
||||
PVOID HalSetWakeEnable;
|
||||
PVOID HalSetWakeAlarm;
|
||||
PVOID HalTranslateBusAddress;
|
||||
PVOID HalTranslateBusAddress2;
|
||||
PVOID HalHaltSystem;
|
||||
PVOID Null;
|
||||
PVOID Null2;
|
||||
PVOID HalAllocateMapRegisters;
|
||||
PVOID KdSetupPciDeviceForDebugging;
|
||||
PVOID KdReleasePciDeviceforDebugging;
|
||||
PVOID KdGetAcpiTablePhase0;
|
||||
PVOID HalReferenceHandler;
|
||||
PVOID HalVectorToIDTEntry;
|
||||
PVOID MatchAll;
|
||||
PVOID KdUnmapVirtualAddress;
|
||||
} HAL_PRIVATE_DISPATCH, *PHAL_PRIVATE_DISPATCH;
|
||||
|
||||
#ifndef _REACTOS_
|
||||
|
|
|
@ -105,6 +105,12 @@ BOOLEAN
|
|||
NTAPI
|
||||
KdPortEnableInterrupts(VOID);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KdDebuggerInitialize0(
|
||||
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
|
|
|
@ -49,6 +49,8 @@ Author:
|
|||
//
|
||||
#define BREAKPOINT_PRINT 1
|
||||
#define BREAKPOINT_PROMPT 2
|
||||
#define BREAKPOINT_LOAD_SYMBOLS 3
|
||||
#define BREAKPOINT_UNLOAD_SYMBOLS 4
|
||||
|
||||
//
|
||||
// Debug Control Codes for NtSystemDebugcontrol
|
||||
|
|
|
@ -704,7 +704,11 @@ typedef struct _KSERVICE_TABLE_DESCRIPTOR
|
|||
//
|
||||
// Exported Loader Parameter Block
|
||||
//
|
||||
#ifdef _REACTOS_
|
||||
extern LOADER_PARAMETER_BLOCK NTSYSAPI KeLoaderBlock;
|
||||
#else
|
||||
extern PLOADER_PARAMETER_BLOCK NTSYSAPI KeLoaderBlock;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Exported Hardware Data
|
||||
|
|
|
@ -254,6 +254,7 @@ typedef struct _CLIENT_ID
|
|||
//
|
||||
// Descriptor Table Entry Definition
|
||||
//
|
||||
#define _DESCRIPTOR_TABLE_ENTRY_DEFINED
|
||||
typedef struct _DESCRIPTOR_TABLE_ENTRY
|
||||
{
|
||||
ULONG Selector;
|
||||
|
|
|
@ -2282,6 +2282,45 @@ RtlIpv4StringToAddressW(
|
|||
OUT PULONG IpAddr
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressA(
|
||||
IN LPSTR Name,
|
||||
OUT PULONG Unknown,
|
||||
OUT PVOID IpAddr
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressW(
|
||||
IN LPWSTR Name,
|
||||
OUT PULONG Unknown,
|
||||
OUT PVOID IpAddr
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressExA(
|
||||
IN LPSTR AddressName,
|
||||
IN PVOID Address,
|
||||
IN PULONG ScopeId,
|
||||
IN PWORD Port
|
||||
);
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressExW(
|
||||
IN LPWSTR AddressName,
|
||||
IN PVOID Address,
|
||||
IN PULONG ScopeId,
|
||||
IN PWORD Port
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// Time Functions
|
||||
//
|
||||
|
|
|
@ -521,10 +521,10 @@ RtlIpv6AddressToStringA@8
|
|||
RtlIpv6AddressToStringExA@16
|
||||
RtlIpv6AddressToStringExW@16
|
||||
RtlIpv6AddressToStringW@8
|
||||
RtlIpv6StringToAddressA@16
|
||||
RtlIpv6StringToAddressA@12
|
||||
RtlIpv6StringToAddressExA@16
|
||||
RtlIpv6StringToAddressExW@16
|
||||
RtlIpv6StringToAddressW@16
|
||||
RtlIpv6StringToAddressW@12
|
||||
RtlIsDosDeviceName_U@4
|
||||
RtlIsGenericTableEmpty@4
|
||||
RtlIsGenericTableEmptyAvl@4
|
||||
|
|
|
@ -233,15 +233,12 @@ RtlIpv6AddressToStringExW(
|
|||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressA(
|
||||
IN LPSTR IpString,
|
||||
IN ULONG Base,
|
||||
OUT PVOID PtrToIpAddr,
|
||||
OUT ULONG IpAddr
|
||||
)
|
||||
RtlIpv6StringToAddressA(IN LPSTR Name,
|
||||
OUT PULONG Unknown,
|
||||
OUT PVOID IpAddr)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -249,15 +246,13 @@ RtlIpv6StringToAddressA(
|
|||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressExA(
|
||||
IN LPSTR IpString,
|
||||
IN ULONG Base,
|
||||
OUT PULONG IpAddr,
|
||||
OUT PULONG Port
|
||||
)
|
||||
RtlIpv6StringToAddressExA(IN LPSTR AddressName,
|
||||
IN PVOID Address,
|
||||
IN PULONG ScopeId,
|
||||
IN PWORD Port)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -265,15 +260,12 @@ RtlIpv6StringToAddressExA(
|
|||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressW(
|
||||
IN LPWSTR IpString,
|
||||
IN ULONG Base,
|
||||
OUT PVOID PtrToIpAddr,
|
||||
OUT ULONG IpAddr
|
||||
)
|
||||
RtlIpv6StringToAddressW(IN LPWSTR Name,
|
||||
OUT PULONG Unknown,
|
||||
OUT PVOID IpAddr)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -281,16 +273,13 @@ RtlIpv6StringToAddressW(
|
|||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
RtlIpv6StringToAddressExW(
|
||||
IN LPWSTR IpString,
|
||||
IN ULONG Base,
|
||||
OUT PULONG IpAddr,
|
||||
OUT PULONG Port
|
||||
)
|
||||
RtlIpv6StringToAddressExW(IN LPWSTR AddressName,
|
||||
IN PVOID Address,
|
||||
IN PULONG ScopeId,
|
||||
IN PWORD Port)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PROJECT: ReactOS Kernel
|
||||
* FILE: ntoskrnl/ke/process.c
|
||||
* PURPOSE: Attaching/Detaching and System Call Tables
|
||||
*
|
||||
* PROGRAMMERS: Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable)
|
||||
* Gregor Anich (Bugfixes to Attach Functions)
|
||||
* PURPOSE: Kernel Process Management and System Call Tables
|
||||
* PROGRAMMERS: Alex Ionescu
|
||||
* Gregor Anich
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
@ -19,7 +18,8 @@
|
|||
|
||||
KSERVICE_TABLE_DESCRIPTOR
|
||||
__declspec(dllexport)
|
||||
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
|
||||
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] =
|
||||
{
|
||||
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
|
@ -27,7 +27,8 @@ KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
|
|||
};
|
||||
|
||||
KSERVICE_TABLE_DESCRIPTOR
|
||||
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
|
||||
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] =
|
||||
{
|
||||
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
{ NULL, NULL, 0, NULL },
|
||||
|
@ -36,8 +37,18 @@ KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static __inline void
|
||||
UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
|
||||
PKPROCESS
|
||||
STDCALL
|
||||
KeGetCurrentProcess(VOID)
|
||||
{
|
||||
return(&(PsGetCurrentProcess()->Pcb));
|
||||
}
|
||||
|
||||
static __inline
|
||||
VOID
|
||||
NTAPI
|
||||
UpdatePageDirs(IN PKTHREAD Thread,
|
||||
IN PKPROCESS Process)
|
||||
{
|
||||
/*
|
||||
* The stack and the thread structure of the current process may be
|
||||
|
@ -53,24 +64,66 @@ UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
|
|||
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Returns a pointer to the current process
|
||||
*/
|
||||
PKPROCESS
|
||||
STDCALL
|
||||
KeGetCurrentProcess(VOID)
|
||||
VOID
|
||||
NTAPI
|
||||
KiAttachProcess(PKTHREAD Thread,
|
||||
PKPROCESS Process,
|
||||
KIRQL OldIrql,
|
||||
PRKAPC_STATE SavedApcState)
|
||||
{
|
||||
return(&(PsGetCurrentProcess()->Pcb));
|
||||
ASSERT(Process != Thread->ApcState.Process);
|
||||
DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n",
|
||||
Thread, Process, SavedApcState);
|
||||
|
||||
/* Increase Stack Count */
|
||||
Process->StackCount++;
|
||||
|
||||
/* Swap the APC Environment */
|
||||
KiMoveApcState(&Thread->ApcState, SavedApcState);
|
||||
|
||||
/* Reinitialize Apc State */
|
||||
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
|
||||
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
|
||||
Thread->ApcState.Process = Process;
|
||||
Thread->ApcState.KernelApcInProgress = FALSE;
|
||||
Thread->ApcState.KernelApcPending = FALSE;
|
||||
Thread->ApcState.UserApcPending = FALSE;
|
||||
|
||||
/* Update Environment Pointers if needed*/
|
||||
if (SavedApcState == &Thread->SavedApcState)
|
||||
{
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStateIndex = AttachedApcEnvironment;
|
||||
}
|
||||
|
||||
/* Check if the process is paged in */
|
||||
if (Process->State == ProcessInMemory)
|
||||
{
|
||||
/* FIXME: Scan the Ready Thread List once new scheduler is in */
|
||||
|
||||
/* Swap the Processes */
|
||||
KiSwapProcess(Process, SavedApcState->Process);
|
||||
|
||||
/* Return to old IRQL*/
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT1("Errr. ReactOS doesn't support paging out processes yet...\n");
|
||||
DbgBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeInitializeProcess(PKPROCESS Process,
|
||||
KPRIORITY Priority,
|
||||
KAFFINITY Affinity,
|
||||
LARGE_INTEGER DirectoryTableBase)
|
||||
{
|
||||
DPRINT("KeInitializeProcess. Process: %x, DirectoryTableBase: %x\n", Process, DirectoryTableBase);
|
||||
DPRINT("KeInitializeProcess. Process: %x, DirectoryTableBase: %x\n",
|
||||
Process, DirectoryTableBase);
|
||||
|
||||
/* Initialize the Dispatcher Header */
|
||||
KeInitializeDispatcherHeader(&Process->Header,
|
||||
|
@ -94,7 +147,7 @@ KeInitializeProcess(PKPROCESS Process,
|
|||
}
|
||||
|
||||
ULONG
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeSetProcess(PKPROCESS Process,
|
||||
KPRIORITY Increment)
|
||||
{
|
||||
|
@ -109,8 +162,8 @@ KeSetProcess(PKPROCESS Process,
|
|||
|
||||
/* Signal the Process */
|
||||
Process->Header.SignalState = TRUE;
|
||||
if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE) {
|
||||
|
||||
if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE)
|
||||
{
|
||||
/* Satisfy waits */
|
||||
KiWaitTest((PVOID)Process, Increment);
|
||||
}
|
||||
|
@ -122,86 +175,8 @@ KeSetProcess(PKPROCESS Process,
|
|||
return OldState;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KeAttachProcess(PKPROCESS Process)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
|
||||
DPRINT("KeAttachProcess: %x\n", Process);
|
||||
|
||||
/* Make sure that we are in the right page directory */
|
||||
UpdatePageDirs(Thread, Process);
|
||||
|
||||
/* Lock Dispatcher */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
/* Crash system if DPC is being executed! */
|
||||
if (KeIsExecutingDpc()) {
|
||||
|
||||
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
|
||||
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
||||
}
|
||||
|
||||
/* Check if the Target Process is already attached */
|
||||
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
|
||||
|
||||
DPRINT("Process already Attached. Exitting\n");
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
} else {
|
||||
|
||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState)
|
||||
{
|
||||
|
||||
DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
|
||||
|
||||
/* Increase Stack Count */
|
||||
Process->StackCount++;
|
||||
|
||||
/* Swap the APC Environment */
|
||||
KiMoveApcState(&Thread->ApcState, SavedApcState);
|
||||
|
||||
/* Reinitialize Apc State */
|
||||
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
|
||||
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
|
||||
Thread->ApcState.Process = Process;
|
||||
Thread->ApcState.KernelApcInProgress = FALSE;
|
||||
Thread->ApcState.KernelApcPending = FALSE;
|
||||
Thread->ApcState.UserApcPending = FALSE;
|
||||
|
||||
/* Update Environment Pointers if needed*/
|
||||
if (SavedApcState == &Thread->SavedApcState) {
|
||||
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStateIndex = AttachedApcEnvironment;
|
||||
}
|
||||
|
||||
/* Swap the Processes */
|
||||
DPRINT("Swapping\n");
|
||||
KiSwapProcess(Process, SavedApcState->Process);
|
||||
|
||||
/* Return to old IRQL*/
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(ApcLock);
|
||||
|
||||
DPRINT("KiAttachProcess Completed Sucesfully\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KiSwapProcess(PKPROCESS NewProcess,
|
||||
PKPROCESS OldProcess)
|
||||
{
|
||||
|
@ -209,11 +184,101 @@ KiSwapProcess(PKPROCESS NewProcess,
|
|||
Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeAttachProcess(PKPROCESS Process)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKTHREAD Thread;
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
DPRINT("KeAttachProcess: %x\n", Process);
|
||||
|
||||
/* Make sure that we are in the right page directory */
|
||||
Thread = KeGetCurrentThread();
|
||||
UpdatePageDirs(Thread, Process);
|
||||
|
||||
/* Lock Dispatcher */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
||||
/* Check if we're already in that process */
|
||||
if (Thread->ApcState.Process == Process)
|
||||
{
|
||||
/* Unlock the dispatcher, nothing to do */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
else if ((Thread->ApcStateIndex != OriginalApcEnvironment) ||
|
||||
(KeIsExecutingDpc()))
|
||||
{
|
||||
/* Executing a DPC or already attached, crash! */
|
||||
KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT,
|
||||
(ULONG_PTR)Process,
|
||||
(ULONG_PTR)Thread->ApcState.Process,
|
||||
Thread->ApcStateIndex,
|
||||
KeIsExecutingDpc());
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Legit attach attempt: do it! */
|
||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
KeDetachProcess (VOID)
|
||||
{
|
||||
PKTHREAD Thread;
|
||||
KIRQL OldIrql;
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
DPRINT("KeDetachProcess()\n");
|
||||
|
||||
/* Get Current Thread and lock the dispatcher */
|
||||
Thread = KeGetCurrentThread();
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
||||
/* Check if it's attached */
|
||||
if (Thread->ApcStateIndex != OriginalApcEnvironment)
|
||||
{
|
||||
/* It is, decrease Stack Count */
|
||||
if(!(--Thread->ApcState.Process->StackCount))
|
||||
{
|
||||
/* FIXME: Swap the process out */
|
||||
}
|
||||
|
||||
/* Restore the APC State */
|
||||
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
||||
Thread->SavedApcState.Process = NULL;
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
|
||||
Thread->ApcStateIndex = OriginalApcEnvironment;
|
||||
|
||||
/* Check if we have pending APCs */
|
||||
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
|
||||
{
|
||||
/* What do you know, we do! Request them to be delivered */
|
||||
Thread->ApcState.KernelApcPending = TRUE;
|
||||
HalRequestSoftwareInterrupt(APC_LEVEL);
|
||||
}
|
||||
|
||||
/* Swap Processes */
|
||||
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
|
||||
}
|
||||
|
||||
/* Unlock Dispatcher */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeIsAttachedProcess(VOID)
|
||||
{
|
||||
/* Return the APC State */
|
||||
|
@ -224,137 +289,122 @@ KeIsAttachedProcess(VOID)
|
|||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeStackAttachProcess(IN PKPROCESS Process,
|
||||
OUT PRKAPC_STATE ApcState)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
PKTHREAD Thread;
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/* Make sure that we are in the right page directory */
|
||||
Thread = KeGetCurrentThread();
|
||||
UpdatePageDirs(Thread, Process);
|
||||
|
||||
/* Acquire the dispatcher lock */
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
/* Crash system if DPC is being executed! */
|
||||
if (KeIsExecutingDpc()) {
|
||||
|
||||
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
|
||||
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
||||
if (KeIsExecutingDpc())
|
||||
{
|
||||
/* Executing a DPC, crash! */
|
||||
KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT,
|
||||
(ULONG_PTR)Process,
|
||||
(ULONG_PTR)Thread->ApcState.Process,
|
||||
Thread->ApcStateIndex,
|
||||
KeIsExecutingDpc());
|
||||
}
|
||||
|
||||
/* Check if the Target Process is already attached */
|
||||
if (Thread->ApcState.Process == Process) {
|
||||
|
||||
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
|
||||
|
||||
} else {
|
||||
|
||||
/* Check if the Current Thread is already attached and call the Internal Function*/
|
||||
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
|
||||
/* Check if we are already in the target process */
|
||||
if (Thread->ApcState.Process == Process)
|
||||
{
|
||||
/* Unlock the dispatcher database */
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
/* Set magic value so we don't crash later when detaching */
|
||||
ApcState->Process = (PKPROCESS)1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if the Current Thread is already attached */
|
||||
if (Thread->ApcStateIndex != OriginalApcEnvironment)
|
||||
{
|
||||
/* We're already attached, so save the APC State into what we got */
|
||||
KiAttachProcess(Thread, Process, OldIrql, ApcState);
|
||||
} else {
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We're not attached, so save the APC State into SavedApcState */
|
||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||
ApcState->Process = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
KeDetachProcess (VOID)
|
||||
{
|
||||
PKTHREAD Thread;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KeDetachProcess()\n");
|
||||
|
||||
/* Get Current Thread and Lock */
|
||||
Thread = KeGetCurrentThread();
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
/* Check if it's attached */
|
||||
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
|
||||
|
||||
if (Thread->ApcStateIndex == OriginalApcEnvironment) {
|
||||
|
||||
DPRINT1("Invalid detach (thread was not attached)\n");
|
||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
||||
}
|
||||
|
||||
/* Decrease Stack Count */
|
||||
Thread->ApcState.Process->StackCount--;
|
||||
|
||||
/* Restore the APC State */
|
||||
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
||||
Thread->SavedApcState.Process = NULL;
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
|
||||
Thread->ApcStateIndex = OriginalApcEnvironment;
|
||||
|
||||
/* Swap Processes */
|
||||
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
|
||||
|
||||
/* Unlock Dispatcher */
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KeUnstackDetachProcess (
|
||||
IN PRKAPC_STATE ApcState
|
||||
)
|
||||
NTAPI
|
||||
KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
PKTHREAD Thread;
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
/*
|
||||
* If the special "We tried to attach to the process already being
|
||||
* attached to" flag is there, don't do anything
|
||||
*/
|
||||
if (ApcState->Process == (PKPROCESS)1) return;
|
||||
|
||||
/* Get the current thread and acquire the dispatcher lock */
|
||||
Thread = KeGetCurrentThread();
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
||||
|
||||
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
|
||||
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
|
||||
/* Check for magic value meaning we were already in the same process */
|
||||
if (ApcState->Process != (PKPROCESS)1)
|
||||
{
|
||||
/*
|
||||
* Check if the process isn't attacked, or has a Kernel APC in progress
|
||||
* or has pending APC of any kind.
|
||||
*/
|
||||
if ((Thread->ApcStateIndex == OriginalApcEnvironment) ||
|
||||
(Thread->ApcState.KernelApcInProgress) ||
|
||||
(!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) ||
|
||||
(!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])))
|
||||
{
|
||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
||||
}
|
||||
|
||||
DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
|
||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
||||
/* Decrease Stack Count */
|
||||
if(!(--Thread->ApcState.Process->StackCount))
|
||||
{
|
||||
/* FIXME: Swap the process out */
|
||||
}
|
||||
|
||||
if (ApcState->Process != NULL)
|
||||
{
|
||||
/* Restore the APC State */
|
||||
KiMoveApcState(ApcState, &Thread->ApcState);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The ApcState parameter is useless, so use the saved data and reset it */
|
||||
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
||||
Thread->SavedApcState.Process = NULL;
|
||||
Thread->ApcStateIndex = OriginalApcEnvironment;
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
|
||||
}
|
||||
|
||||
/* Check if we have pending APCs */
|
||||
if (IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
|
||||
{
|
||||
/* What do you know, we do! Request them to be delivered */
|
||||
Thread->ApcState.KernelApcPending = TRUE;
|
||||
HalRequestSoftwareInterrupt(APC_LEVEL);
|
||||
}
|
||||
|
||||
/* Swap Processes */
|
||||
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
|
||||
}
|
||||
|
||||
/* Restore the Old APC State if a Process was present */
|
||||
if (ApcState->Process) {
|
||||
|
||||
KiMoveApcState(ApcState, &Thread->ApcState);
|
||||
|
||||
} else {
|
||||
|
||||
/* The ApcState parameter is useless, so use the saved data and reset it */
|
||||
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
|
||||
Thread->SavedApcState.Process = NULL;
|
||||
Thread->ApcStateIndex = OriginalApcEnvironment;
|
||||
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
|
||||
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
|
||||
}
|
||||
|
||||
/* Swap Processes */
|
||||
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
|
||||
|
||||
/* Return to old IRQL*/
|
||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
|
||||
|
@ -362,7 +412,7 @@ KeUnstackDetachProcess (
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeAddSystemServiceTable(PULONG_PTR Base,
|
||||
PULONG Count OPTIONAL,
|
||||
ULONG Limit,
|
||||
|
@ -390,7 +440,7 @@ KeAddSystemServiceTable(PULONG_PTR Base,
|
|||
* @implemented
|
||||
*/
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
NTAPI
|
||||
KeRemoveSystemServiceTable(IN ULONG Index)
|
||||
{
|
||||
/* Make sure the Index is valid */
|
||||
|
|
|
@ -1117,10 +1117,10 @@ RtlIpv6AddressToStringA@8
|
|||
RtlIpv6AddressToStringExA@16
|
||||
RtlIpv6AddressToStringExW@16
|
||||
RtlIpv6AddressToStringW@8
|
||||
RtlIpv6StringToAddressA@16
|
||||
RtlIpv6StringToAddressA@12
|
||||
RtlIpv6StringToAddressExA@16
|
||||
RtlIpv6StringToAddressExW@16
|
||||
RtlIpv6StringToAddressW@16
|
||||
RtlIpv6StringToAddressW@12
|
||||
RtlIsGenericTableEmpty@4
|
||||
RtlIsGenericTableEmptyAvl@4
|
||||
RtlIsNameLegalDOS8Dot3@12
|
||||
|
|
Loading…
Reference in a new issue