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,
KeStackSwitchAndRet((PVOID)(OldStack + 1));
/* Should never return. */
- KeBugCheck(0);
+ KEBUGCHECK(0);
return(STATUS_UNSUCCESSFUL);
}
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)
{
StackSize,
0,
&StackArea,
+ FALSE,
FALSE);
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
+ MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status))
{
DPRINT("Failed to create thread stack\n");
KIRQL oldIrql;
NTSTATUS CallbackStatus;
NTW32CALL_SAVED_STATE SavedState;
+ PNTW32CALL_CALLBACK_STACK AssignedStack;
DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
RoutineIndex, Argument, ArgumentLength);
/* 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)));
* modified.
*/
KeLowerIrql(PASSIVE_LEVEL);
- PsFreeCallbackStack(NewStack);
+ InsertTailList(&CallbackStackListHead, &AssignedStack->ListEntry);
return(CallbackStatus);
}