mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:52:54 +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_GDT 0x3C
|
||||||
#define KPCR_TSS 0x40
|
#define KPCR_TSS 0x40
|
||||||
#define KPCR_SET_MEMBER 0x48
|
#define KPCR_SET_MEMBER 0x48
|
||||||
|
#define KPCR_NUMBER 0x51
|
||||||
#define KPCR_CURRENT_THREAD 0x124
|
#define KPCR_CURRENT_THREAD 0x124
|
||||||
#define KPCR_PROCESSOR_NUMBER 0x130
|
#define KPCR_PROCESSOR_NUMBER 0x130
|
||||||
#define KPCR_PRCB_SET_MEMBER 0x134
|
#define KPCR_PRCB_SET_MEMBER 0x134
|
||||||
|
|
|
@ -61,10 +61,29 @@ typedef enum _FIRMWARE_ENTRY
|
||||||
//
|
//
|
||||||
// Hal Private dispatch Table
|
// Hal Private dispatch Table
|
||||||
//
|
//
|
||||||
#define HAL_PRIVATE_DISPATCH_VERSION 1
|
#define HAL_PRIVATE_DISPATCH_VERSION 2
|
||||||
typedef struct _HAL_PRIVATE_DISPATCH
|
typedef struct _HAL_PRIVATE_DISPATCH
|
||||||
{
|
{
|
||||||
ULONG Version;
|
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;
|
} HAL_PRIVATE_DISPATCH, *PHAL_PRIVATE_DISPATCH;
|
||||||
|
|
||||||
#ifndef _REACTOS_
|
#ifndef _REACTOS_
|
||||||
|
|
|
@ -105,6 +105,12 @@ BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
KdPortEnableInterrupts(VOID);
|
KdPortEnableInterrupts(VOID);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
KdDebuggerInitialize0(
|
||||||
|
IN PLOADER_PARAMETER_BLOCK LoaderBlock
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -49,6 +49,8 @@ Author:
|
||||||
//
|
//
|
||||||
#define BREAKPOINT_PRINT 1
|
#define BREAKPOINT_PRINT 1
|
||||||
#define BREAKPOINT_PROMPT 2
|
#define BREAKPOINT_PROMPT 2
|
||||||
|
#define BREAKPOINT_LOAD_SYMBOLS 3
|
||||||
|
#define BREAKPOINT_UNLOAD_SYMBOLS 4
|
||||||
|
|
||||||
//
|
//
|
||||||
// Debug Control Codes for NtSystemDebugcontrol
|
// Debug Control Codes for NtSystemDebugcontrol
|
||||||
|
|
|
@ -704,7 +704,11 @@ typedef struct _KSERVICE_TABLE_DESCRIPTOR
|
||||||
//
|
//
|
||||||
// Exported Loader Parameter Block
|
// Exported Loader Parameter Block
|
||||||
//
|
//
|
||||||
|
#ifdef _REACTOS_
|
||||||
extern LOADER_PARAMETER_BLOCK NTSYSAPI KeLoaderBlock;
|
extern LOADER_PARAMETER_BLOCK NTSYSAPI KeLoaderBlock;
|
||||||
|
#else
|
||||||
|
extern PLOADER_PARAMETER_BLOCK NTSYSAPI KeLoaderBlock;
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Exported Hardware Data
|
// Exported Hardware Data
|
||||||
|
|
|
@ -254,6 +254,7 @@ typedef struct _CLIENT_ID
|
||||||
//
|
//
|
||||||
// Descriptor Table Entry Definition
|
// Descriptor Table Entry Definition
|
||||||
//
|
//
|
||||||
|
#define _DESCRIPTOR_TABLE_ENTRY_DEFINED
|
||||||
typedef struct _DESCRIPTOR_TABLE_ENTRY
|
typedef struct _DESCRIPTOR_TABLE_ENTRY
|
||||||
{
|
{
|
||||||
ULONG Selector;
|
ULONG Selector;
|
||||||
|
|
|
@ -2282,6 +2282,45 @@ RtlIpv4StringToAddressW(
|
||||||
OUT PULONG IpAddr
|
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
|
// Time Functions
|
||||||
//
|
//
|
||||||
|
|
|
@ -521,10 +521,10 @@ RtlIpv6AddressToStringA@8
|
||||||
RtlIpv6AddressToStringExA@16
|
RtlIpv6AddressToStringExA@16
|
||||||
RtlIpv6AddressToStringExW@16
|
RtlIpv6AddressToStringExW@16
|
||||||
RtlIpv6AddressToStringW@8
|
RtlIpv6AddressToStringW@8
|
||||||
RtlIpv6StringToAddressA@16
|
RtlIpv6StringToAddressA@12
|
||||||
RtlIpv6StringToAddressExA@16
|
RtlIpv6StringToAddressExA@16
|
||||||
RtlIpv6StringToAddressExW@16
|
RtlIpv6StringToAddressExW@16
|
||||||
RtlIpv6StringToAddressW@16
|
RtlIpv6StringToAddressW@12
|
||||||
RtlIsDosDeviceName_U@4
|
RtlIsDosDeviceName_U@4
|
||||||
RtlIsGenericTableEmpty@4
|
RtlIsGenericTableEmpty@4
|
||||||
RtlIsGenericTableEmptyAvl@4
|
RtlIsGenericTableEmptyAvl@4
|
||||||
|
|
|
@ -233,15 +233,12 @@ RtlIpv6AddressToStringExW(
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlIpv6StringToAddressA(
|
RtlIpv6StringToAddressA(IN LPSTR Name,
|
||||||
IN LPSTR IpString,
|
OUT PULONG Unknown,
|
||||||
IN ULONG Base,
|
OUT PVOID IpAddr)
|
||||||
OUT PVOID PtrToIpAddr,
|
|
||||||
OUT ULONG IpAddr
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -249,15 +246,13 @@ RtlIpv6StringToAddressA(
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlIpv6StringToAddressExA(
|
RtlIpv6StringToAddressExA(IN LPSTR AddressName,
|
||||||
IN LPSTR IpString,
|
IN PVOID Address,
|
||||||
IN ULONG Base,
|
IN PULONG ScopeId,
|
||||||
OUT PULONG IpAddr,
|
IN PWORD Port)
|
||||||
OUT PULONG Port
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -265,15 +260,12 @@ RtlIpv6StringToAddressExA(
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlIpv6StringToAddressW(
|
RtlIpv6StringToAddressW(IN LPWSTR Name,
|
||||||
IN LPWSTR IpString,
|
OUT PULONG Unknown,
|
||||||
IN ULONG Base,
|
OUT PVOID IpAddr)
|
||||||
OUT PVOID PtrToIpAddr,
|
|
||||||
OUT ULONG IpAddr
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -281,16 +273,13 @@ RtlIpv6StringToAddressW(
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
RtlIpv6StringToAddressExW(
|
RtlIpv6StringToAddressExW(IN LPWSTR AddressName,
|
||||||
IN LPWSTR IpString,
|
IN PVOID Address,
|
||||||
IN ULONG Base,
|
IN PULONG ScopeId,
|
||||||
OUT PULONG IpAddr,
|
IN PWORD Port)
|
||||||
OUT PULONG Port
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS Kernel
|
||||||
* FILE: ntoskrnl/ke/process.c
|
* FILE: ntoskrnl/ke/process.c
|
||||||
* PURPOSE: Attaching/Detaching and System Call Tables
|
* PURPOSE: Kernel Process Management and System Call Tables
|
||||||
*
|
* PROGRAMMERS: Alex Ionescu
|
||||||
* PROGRAMMERS: Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable)
|
* Gregor Anich
|
||||||
* Gregor Anich (Bugfixes to Attach Functions)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -19,7 +18,8 @@
|
||||||
|
|
||||||
KSERVICE_TABLE_DESCRIPTOR
|
KSERVICE_TABLE_DESCRIPTOR
|
||||||
__declspec(dllexport)
|
__declspec(dllexport)
|
||||||
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
|
KeServiceDescriptorTable[SSDT_MAX_ENTRIES] =
|
||||||
|
{
|
||||||
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
||||||
{ NULL, NULL, 0, NULL },
|
{ NULL, NULL, 0, NULL },
|
||||||
{ NULL, NULL, 0, NULL },
|
{ NULL, NULL, 0, NULL },
|
||||||
|
@ -27,7 +27,8 @@ KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
KSERVICE_TABLE_DESCRIPTOR
|
KSERVICE_TABLE_DESCRIPTOR
|
||||||
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
|
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] =
|
||||||
|
{
|
||||||
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
|
||||||
{ NULL, NULL, 0, NULL },
|
{ NULL, NULL, 0, NULL },
|
||||||
{ NULL, NULL, 0, NULL },
|
{ NULL, NULL, 0, NULL },
|
||||||
|
@ -36,8 +37,18 @@ KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
static __inline void
|
PKPROCESS
|
||||||
UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
|
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
|
* 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));
|
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
VOID
|
||||||
* FUNCTION: Returns a pointer to the current process
|
NTAPI
|
||||||
*/
|
KiAttachProcess(PKTHREAD Thread,
|
||||||
PKPROCESS
|
PKPROCESS Process,
|
||||||
STDCALL
|
KIRQL OldIrql,
|
||||||
KeGetCurrentProcess(VOID)
|
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
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KeInitializeProcess(PKPROCESS Process,
|
KeInitializeProcess(PKPROCESS Process,
|
||||||
KPRIORITY Priority,
|
KPRIORITY Priority,
|
||||||
KAFFINITY Affinity,
|
KAFFINITY Affinity,
|
||||||
LARGE_INTEGER DirectoryTableBase)
|
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 */
|
/* Initialize the Dispatcher Header */
|
||||||
KeInitializeDispatcherHeader(&Process->Header,
|
KeInitializeDispatcherHeader(&Process->Header,
|
||||||
|
@ -94,7 +147,7 @@ KeInitializeProcess(PKPROCESS Process,
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
STDCALL
|
NTAPI
|
||||||
KeSetProcess(PKPROCESS Process,
|
KeSetProcess(PKPROCESS Process,
|
||||||
KPRIORITY Increment)
|
KPRIORITY Increment)
|
||||||
{
|
{
|
||||||
|
@ -109,8 +162,8 @@ KeSetProcess(PKPROCESS Process,
|
||||||
|
|
||||||
/* Signal the Process */
|
/* Signal the Process */
|
||||||
Process->Header.SignalState = TRUE;
|
Process->Header.SignalState = TRUE;
|
||||||
if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE) {
|
if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE)
|
||||||
|
{
|
||||||
/* Satisfy waits */
|
/* Satisfy waits */
|
||||||
KiWaitTest((PVOID)Process, Increment);
|
KiWaitTest((PVOID)Process, Increment);
|
||||||
}
|
}
|
||||||
|
@ -122,86 +175,8 @@ KeSetProcess(PKPROCESS Process,
|
||||||
return OldState;
|
return OldState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
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
|
|
||||||
KiSwapProcess(PKPROCESS NewProcess,
|
KiSwapProcess(PKPROCESS NewProcess,
|
||||||
PKPROCESS OldProcess)
|
PKPROCESS OldProcess)
|
||||||
{
|
{
|
||||||
|
@ -209,11 +184,101 @@ KiSwapProcess(PKPROCESS NewProcess,
|
||||||
Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
NTAPI
|
||||||
KeIsAttachedProcess(VOID)
|
KeIsAttachedProcess(VOID)
|
||||||
{
|
{
|
||||||
/* Return the APC State */
|
/* Return the APC State */
|
||||||
|
@ -224,137 +289,122 @@ KeIsAttachedProcess(VOID)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KeStackAttachProcess(IN PKPROCESS Process,
|
KeStackAttachProcess(IN PKPROCESS Process,
|
||||||
OUT PRKAPC_STATE ApcState)
|
OUT PRKAPC_STATE ApcState)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PKTHREAD Thread = KeGetCurrentThread();
|
PKTHREAD Thread;
|
||||||
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
/* Make sure that we are in the right page directory */
|
/* Make sure that we are in the right page directory */
|
||||||
|
Thread = KeGetCurrentThread();
|
||||||
UpdatePageDirs(Thread, Process);
|
UpdatePageDirs(Thread, Process);
|
||||||
|
|
||||||
|
/* Acquire the dispatcher lock */
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
|
||||||
|
|
||||||
/* Crash system if DPC is being executed! */
|
/* Crash system if DPC is being executed! */
|
||||||
if (KeIsExecutingDpc()) {
|
if (KeIsExecutingDpc())
|
||||||
|
{
|
||||||
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
|
/* Executing a DPC, crash! */
|
||||||
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
|
KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT,
|
||||||
|
(ULONG_PTR)Process,
|
||||||
|
(ULONG_PTR)Thread->ApcState.Process,
|
||||||
|
Thread->ApcStateIndex,
|
||||||
|
KeIsExecutingDpc());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the Target Process is already attached */
|
/* Check if we are already in the target process */
|
||||||
if (Thread->ApcState.Process == Process) {
|
if (Thread->ApcState.Process == Process)
|
||||||
|
{
|
||||||
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
|
/* Unlock the dispatcher database */
|
||||||
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
} else {
|
|
||||||
|
|
||||||
/* Check if the Current Thread is already attached and call the Internal Function*/
|
|
||||||
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
|
|
||||||
|
|
||||||
|
/* 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);
|
KiAttachProcess(Thread, Process, OldIrql, ApcState);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We're not attached, so save the APC State into SavedApcState */
|
||||||
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
|
||||||
ApcState->Process = NULL;
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KeUnstackDetachProcess (
|
KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
|
||||||
IN PRKAPC_STATE ApcState
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PKTHREAD Thread;
|
PKTHREAD Thread;
|
||||||
|
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
/*
|
/* Get the current thread and acquire the dispatcher lock */
|
||||||
* 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;
|
|
||||||
|
|
||||||
Thread = KeGetCurrentThread();
|
Thread = KeGetCurrentThread();
|
||||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||||
KeAcquireSpinLockAtDpcLevel(&Thread->ApcQueueLock);
|
|
||||||
|
|
||||||
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
|
/* Check for magic value meaning we were already in the same process */
|
||||||
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
|
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");
|
/* Decrease Stack Count */
|
||||||
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
|
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*/
|
/* Return to old IRQL*/
|
||||||
KeReleaseSpinLockFromDpcLevel(&Thread->ApcQueueLock);
|
|
||||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -362,7 +412,7 @@ KeUnstackDetachProcess (
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
NTAPI
|
||||||
KeAddSystemServiceTable(PULONG_PTR Base,
|
KeAddSystemServiceTable(PULONG_PTR Base,
|
||||||
PULONG Count OPTIONAL,
|
PULONG Count OPTIONAL,
|
||||||
ULONG Limit,
|
ULONG Limit,
|
||||||
|
@ -390,7 +440,7 @@ KeAddSystemServiceTable(PULONG_PTR Base,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
STDCALL
|
NTAPI
|
||||||
KeRemoveSystemServiceTable(IN ULONG Index)
|
KeRemoveSystemServiceTable(IN ULONG Index)
|
||||||
{
|
{
|
||||||
/* Make sure the Index is valid */
|
/* Make sure the Index is valid */
|
||||||
|
|
|
@ -1117,10 +1117,10 @@ RtlIpv6AddressToStringA@8
|
||||||
RtlIpv6AddressToStringExA@16
|
RtlIpv6AddressToStringExA@16
|
||||||
RtlIpv6AddressToStringExW@16
|
RtlIpv6AddressToStringExW@16
|
||||||
RtlIpv6AddressToStringW@8
|
RtlIpv6AddressToStringW@8
|
||||||
RtlIpv6StringToAddressA@16
|
RtlIpv6StringToAddressA@12
|
||||||
RtlIpv6StringToAddressExA@16
|
RtlIpv6StringToAddressExA@16
|
||||||
RtlIpv6StringToAddressExW@16
|
RtlIpv6StringToAddressExW@16
|
||||||
RtlIpv6StringToAddressW@16
|
RtlIpv6StringToAddressW@12
|
||||||
RtlIsGenericTableEmpty@4
|
RtlIsGenericTableEmpty@4
|
||||||
RtlIsGenericTableEmptyAvl@4
|
RtlIsGenericTableEmptyAvl@4
|
||||||
RtlIsNameLegalDOS8Dot3@12
|
RtlIsNameLegalDOS8Dot3@12
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue