From: Alex Ionescu Date: Sun, 4 Dec 2005 03:24:11 +0000 (+0000) Subject: - Fix KeAttackProcess, KeStackAttachProcess, KeUnstackDetachProcess and KeDetachProce... X-Git-Tag: backups/ros-branch-0_2_9@19949~87 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=0a36bfb449efda8088f90e321495954c0cb500ca - 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 --- diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index e2154a8614c..911e99b343b 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -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 diff --git a/reactos/include/ndk/haltypes.h b/reactos/include/ndk/haltypes.h index 38d1f61a576..006c8f6029e 100644 --- a/reactos/include/ndk/haltypes.h +++ b/reactos/include/ndk/haltypes.h @@ -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_ diff --git a/reactos/include/ndk/kdfuncs.h b/reactos/include/ndk/kdfuncs.h index c5c2a8de01e..9f12b27c820 100644 --- a/reactos/include/ndk/kdfuncs.h +++ b/reactos/include/ndk/kdfuncs.h @@ -105,6 +105,12 @@ BOOLEAN NTAPI KdPortEnableInterrupts(VOID); +BOOLEAN +NTAPI +KdDebuggerInitialize0( + IN PLOADER_PARAMETER_BLOCK LoaderBlock +); + #endif // diff --git a/reactos/include/ndk/kdtypes.h b/reactos/include/ndk/kdtypes.h index 073727db297..5b8285f7b89 100644 --- a/reactos/include/ndk/kdtypes.h +++ b/reactos/include/ndk/kdtypes.h @@ -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 diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index efa84fa12b3..9c3b321c3bc 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -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 diff --git a/reactos/include/ndk/pstypes.h b/reactos/include/ndk/pstypes.h index 1f366b0fa95..55df3f8b772 100644 --- a/reactos/include/ndk/pstypes.h +++ b/reactos/include/ndk/pstypes.h @@ -254,6 +254,7 @@ typedef struct _CLIENT_ID // // Descriptor Table Entry Definition // +#define _DESCRIPTOR_TABLE_ENTRY_DEFINED typedef struct _DESCRIPTOR_TABLE_ENTRY { ULONG Selector; diff --git a/reactos/include/ndk/rtlfuncs.h b/reactos/include/ndk/rtlfuncs.h index eb8771c7925..7d122beb713 100644 --- a/reactos/include/ndk/rtlfuncs.h +++ b/reactos/include/ndk/rtlfuncs.h @@ -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 // diff --git a/reactos/lib/ntdll/def/ntdll.def b/reactos/lib/ntdll/def/ntdll.def index 61a2bb7861b..b75f87e9f78 100644 --- a/reactos/lib/ntdll/def/ntdll.def +++ b/reactos/lib/ntdll/def/ntdll.def @@ -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 diff --git a/reactos/lib/rtl/network.c b/reactos/lib/rtl/network.c index 9c5832dd500..9884f59c50f 100644 --- a/reactos/lib/rtl/network.c +++ b/reactos/lib/rtl/network.c @@ -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 */ diff --git a/reactos/ntoskrnl/ke/process.c b/reactos/ntoskrnl/ke/process.c index e6f1c819b9a..70ced192422 100644 --- a/reactos/ntoskrnl/ke/process.c +++ b/reactos/ntoskrnl/ke/process.c @@ -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,98 +175,110 @@ KeSetProcess(PKPROCESS Process, return OldState; } +VOID +NTAPI +KiSwapProcess(PKPROCESS NewProcess, + PKPROCESS OldProcess) +{ + DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); + Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); +} + /* * @implemented */ VOID -STDCALL +NTAPI KeAttachProcess(PKPROCESS Process) { KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - + 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(); - 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); + /* Check if we're already in that process */ + if (Thread->ApcState.Process == Process) + { + /* Unlock the dispatcher, nothing to do */ KeReleaseDispatcherDatabaseLock(OldIrql); - } else { - + } + 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 -STDCALL -KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState) +NTAPI +KeDetachProcess (VOID) { + PKTHREAD Thread; + KIRQL OldIrql; + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + DPRINT("KeDetachProcess()\n"); - DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState); - - /* Increase Stack Count */ - Process->StackCount++; + /* Get Current Thread and lock the dispatcher */ + Thread = KeGetCurrentThread(); + OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Swap the APC Environment */ - KiMoveApcState(&Thread->ApcState, SavedApcState); + /* Check if it's attached */ + if (Thread->ApcStateIndex != OriginalApcEnvironment) + { + /* It is, decrease Stack Count */ + if(!(--Thread->ApcState.Process->StackCount)) + { + /* FIXME: Swap the process out */ + } - /* 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; + /* 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; - /* Update Environment Pointers if needed*/ - if (SavedApcState == &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); + } - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState; - Thread->ApcStateIndex = AttachedApcEnvironment; + /* Swap Processes */ + KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); } - /* 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, - PKPROCESS OldProcess) -{ - DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); - Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); + /* 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)) { - - DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n"); - KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); - } + /* 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); + } - /* Restore the Old APC State if a Process was present */ - if (ApcState->Process) { + /* Decrease Stack Count */ + if(!(--Thread->ApcState.Process->StackCount)) + { + /* FIXME: Swap the process out */ + } - KiMoveApcState(ApcState, &Thread->ApcState); + 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; + } - } else { + /* 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); + } - /* 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); } - /* 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 */ diff --git a/reactos/ntoskrnl/ntoskrnl.def b/reactos/ntoskrnl/ntoskrnl.def index 35da2554664..56f23eaa606 100644 --- a/reactos/ntoskrnl/ntoskrnl.def +++ b/reactos/ntoskrnl/ntoskrnl.def @@ -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