- Fix KeAttackProcess, KeStackAttachProcess, KeUnstackDetachProcess and KeDetachProce...
authorAlex Ionescu <aionescu@gmail.com>
Sun, 4 Dec 2005 03:24:11 +0000 (03:24 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 4 Dec 2005 03:24:11 +0000 (03:24 +0000)
- 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

reactos/include/ndk/asm.h
reactos/include/ndk/haltypes.h
reactos/include/ndk/kdfuncs.h
reactos/include/ndk/kdtypes.h
reactos/include/ndk/ketypes.h
reactos/include/ndk/pstypes.h
reactos/include/ndk/rtlfuncs.h
reactos/lib/ntdll/def/ntdll.def
reactos/lib/rtl/network.c
reactos/ntoskrnl/ke/process.c
reactos/ntoskrnl/ntoskrnl.def

index e2154a8..911e99b 100644 (file)
@@ -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
index 38d1f61..006c8f6 100644 (file)
@@ -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_
index c5c2a8d..9f12b27 100644 (file)
@@ -105,6 +105,12 @@ BOOLEAN
 NTAPI
 KdPortEnableInterrupts(VOID);
 
+BOOLEAN
+NTAPI
+KdDebuggerInitialize0(
+    IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
 #endif
 
 //
index 073727d..5b8285f 100644 (file)
@@ -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
index efa84fa..9c3b321 100644 (file)
@@ -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
index 1f366b0..55df3f8 100644 (file)
@@ -254,6 +254,7 @@ typedef struct _CLIENT_ID
 //
 // Descriptor Table Entry Definition
 //
+#define _DESCRIPTOR_TABLE_ENTRY_DEFINED
 typedef struct _DESCRIPTOR_TABLE_ENTRY
 {
     ULONG Selector;
index eb8771c..7d122be 100644 (file)
@@ -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
 //
index 61a2bb7..b75f87e 100644 (file)
@@ -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
index 9c5832d..9884f59 100644 (file)
@@ -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 */
index e6f1c81..70ced19 100644 (file)
@@ -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 */
index 35da255..56f23ea 100644 (file)
@@ -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