update for HEAD-2003091401
[reactos.git] / ntoskrnl / ps / w32call.c
index c3530c2..49da0e4 100644 (file)
@@ -46,8 +46,22 @@ typedef struct _NTW32CALL_SAVED_STATE
   PVOID SavedCallbackStack;
 } NTW32CALL_SAVED_STATE, *PNTW32CALL_SAVED_STATE;
 
+typedef struct
+{
+  PVOID BaseAddress;
+  LIST_ENTRY ListEntry;
+} NTW32CALL_CALLBACK_STACK, *PNTW32CALL_CALLBACK_STACK;
+
+static LIST_ENTRY CallbackStackListHead;
+
 /* FUNCTIONS ***************************************************************/
 
+VOID
+PsInitialiseW32Call(VOID)
+{
+  InitializeListHead(&CallbackStackListHead);
+}
+
 NTSTATUS STDCALL
 NtCallbackReturn (PVOID                Result,
                  ULONG         ResultLength,
@@ -117,7 +131,7 @@ NtCallbackReturn (PVOID             Result,
   KeStackSwitchAndRet((PVOID)(OldStack + 1));
 
   /* Should never return. */
-  KeBugCheck(0);
+  KEBUGCHECK(0);
   return(STATUS_UNSUCCESSFUL);
 }
 
@@ -145,6 +159,22 @@ PsFreeCallbackStack(PVOID StackLimit)
   MmUnlockAddressSpace(MmGetKernelAddressSpace());
 }
 
+VOID
+PsFreeCallbackStacks(VOID)
+{
+  PLIST_ENTRY CurrentListEntry;
+  PNTW32CALL_CALLBACK_STACK Current;
+
+  while (!IsListEmpty(&CallbackStackListHead))
+    {
+      CurrentListEntry = RemoveHeadList(&CallbackStackListHead);
+      Current = CONTAINING_RECORD(CurrentListEntry, NTW32CALL_CALLBACK_STACK,
+                                 ListEntry);
+      PsFreeCallbackStack(Current->BaseAddress);
+      ExFreePool(Current);
+    }
+}
+
 PVOID STATIC
 PsAllocateCallbackStack(ULONG StackSize)
 {
@@ -162,8 +192,9 @@ PsAllocateCallbackStack(ULONG StackSize)
                              StackSize,
                              0,
                              &StackArea,
+                             FALSE,
                              FALSE);
-  MmUnlockAddressSpace(MmGetKernelAddressSpace());  
+  MmUnlockAddressSpace(MmGetKernelAddressSpace());
   if (!NT_SUCCESS(Status))
     {
       DPRINT("Failed to create thread stack\n");
@@ -201,6 +232,7 @@ NtW32Call (IN ULONG RoutineIndex,
   KIRQL oldIrql;
   NTSTATUS CallbackStatus;
   NTW32CALL_SAVED_STATE SavedState;
+  PNTW32CALL_CALLBACK_STACK AssignedStack;
 
   DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
          RoutineIndex, Argument, ArgumentLength);
@@ -209,7 +241,22 @@ NtW32Call (IN ULONG RoutineIndex,
 
   /* Set up the new kernel and user environment. */
   StackSize = (ULONG)(Thread->Tcb.StackBase - Thread->Tcb.StackLimit);  
-  NewStack = PsAllocateCallbackStack(StackSize);
+  if (IsListEmpty(&CallbackStackListHead))
+    {
+      NewStack = PsAllocateCallbackStack(StackSize);
+      AssignedStack = ExAllocatePool(NonPagedPool,
+                                    sizeof(NTW32CALL_CALLBACK_STACK));
+      AssignedStack->BaseAddress = NewStack;
+    }
+  else
+    {
+      PLIST_ENTRY StackEntry;      
+
+      StackEntry = RemoveHeadList(&CallbackStackListHead);
+      AssignedStack = CONTAINING_RECORD(StackEntry, NTW32CALL_CALLBACK_STACK, 
+                                       ListEntry);
+      NewStack = AssignedStack->BaseAddress;
+    }
   /* FIXME: Need to check whether we were interrupted from v86 mode. */
   memcpy(NewStack + StackSize - sizeof(KTRAP_FRAME), Thread->Tcb.TrapFrame,
         sizeof(KTRAP_FRAME) - (4 * sizeof(DWORD)));
@@ -244,7 +291,7 @@ NtW32Call (IN ULONG RoutineIndex,
    * modified.
    */
   KeLowerIrql(PASSIVE_LEVEL);
-  PsFreeCallbackStack(NewStack);
+  InsertTailList(&CallbackStackListHead, &AssignedStack->ListEntry);
   return(CallbackStatus);
 }