mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
the callback management doesn't have to be serialized as it's only accessed by the thread itself
svn path=/trunk/; revision=13512
This commit is contained in:
parent
a780838c2e
commit
709af1f28a
4 changed files with 159 additions and 202 deletions
|
@ -8,7 +8,6 @@ typedef struct _W32THREAD
|
||||||
PVOID MessageQueue;
|
PVOID MessageQueue;
|
||||||
FAST_MUTEX WindowListLock;
|
FAST_MUTEX WindowListLock;
|
||||||
LIST_ENTRY WindowListHead;
|
LIST_ENTRY WindowListHead;
|
||||||
FAST_MUTEX W32CallbackListLock;
|
|
||||||
LIST_ENTRY W32CallbackListHead;
|
LIST_ENTRY W32CallbackListHead;
|
||||||
struct _KBDTABLES* KeyboardLayout;
|
struct _KBDTABLES* KeyboardLayout;
|
||||||
struct _DESKTOP_OBJECT* Desktop;
|
struct _DESKTOP_OBJECT* Desktop;
|
||||||
|
|
|
@ -51,7 +51,7 @@ static const INFORMATION_CLASS_INFO PsProcessInfoClass[] =
|
||||||
ICI_SQ_SAME( sizeof(PROCESS_WS_WATCH_INFORMATION), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessWorkingSetWatch */
|
ICI_SQ_SAME( sizeof(PROCESS_WS_WATCH_INFORMATION), sizeof(ULONG), ICIF_QUERY | ICIF_SET ), /* ProcessWorkingSetWatch */
|
||||||
ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessUserModeIOPL */
|
ICI_SQ_SAME( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessUserModeIOPL */
|
||||||
ICI_SQ_SAME( sizeof(BOOLEAN), sizeof(ULONG), ICIF_SET ), /* ProcessEnableAlignmentFaultFixup */
|
ICI_SQ_SAME( sizeof(BOOLEAN), sizeof(ULONG), ICIF_SET ), /* ProcessEnableAlignmentFaultFixup */
|
||||||
ICI_SQ_SAME( sizeof(PROCESS_PRIORITY_CLASS), sizeof(USHORT), ICIF_SET ), /* ProcessPriorityClass */
|
ICI_SQ_SAME( sizeof(PROCESS_PRIORITY_CLASS), sizeof(USHORT), ICIF_QUERY | ICIF_SET ), /* ProcessPriorityClass */
|
||||||
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessWx86Information */
|
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessWx86Information */
|
||||||
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessHandleCount */
|
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY ), /* ProcessHandleCount */
|
||||||
ICI_SQ_SAME( sizeof(KAFFINITY), sizeof(ULONG), ICIF_SET ), /* ProcessAffinityMask */
|
ICI_SQ_SAME( sizeof(KAFFINITY), sizeof(ULONG), ICIF_SET ), /* ProcessAffinityMask */
|
||||||
|
@ -1846,86 +1846,79 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
case ProcessDebugPort:
|
case ProcessDebugPort:
|
||||||
{
|
{
|
||||||
if(ProcessInformationLength != sizeof(HANDLE))
|
HANDLE PortHandle = NULL;
|
||||||
|
|
||||||
|
/* make a safe copy of the buffer on the stack */
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
PortHandle = *(PHANDLE)ProcessInformation;
|
||||||
|
Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
HANDLE PortHandle = NULL;
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
/* make a safe copy of the buffer on the stack */
|
if(NT_SUCCESS(Status))
|
||||||
_SEH_TRY
|
{
|
||||||
{
|
PEPORT DebugPort;
|
||||||
PortHandle = *(PHANDLE)ProcessInformation;
|
|
||||||
Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
|
/* in case we had success reading from the buffer, verify the provided
|
||||||
|
* LPC port handle
|
||||||
|
*/
|
||||||
|
Status = ObReferenceObjectByHandle(PortHandle,
|
||||||
|
0,
|
||||||
|
LpcPortObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID)&DebugPort,
|
||||||
|
NULL);
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PEPORT DebugPort;
|
/* lock the process to be thread-safe! */
|
||||||
|
|
||||||
/* in case we had success reading from the buffer, verify the provided
|
Status = PsLockProcess(Process, FALSE);
|
||||||
* LPC port handle
|
|
||||||
*/
|
|
||||||
Status = ObReferenceObjectByHandle(PortHandle,
|
|
||||||
0,
|
|
||||||
LpcPortObjectType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID)&DebugPort,
|
|
||||||
NULL);
|
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* lock the process to be thread-safe! */
|
/*
|
||||||
|
* according to "NT Native API" documentation, setting the debug
|
||||||
Status = PsLockProcess(Process, FALSE);
|
* port is only permitted once!
|
||||||
if(NT_SUCCESS(Status))
|
*/
|
||||||
|
if(Process->DebugPort == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/* keep the reference to the handle! */
|
||||||
* according to "NT Native API" documentation, setting the debug
|
Process->DebugPort = DebugPort;
|
||||||
* port is only permitted once!
|
|
||||||
*/
|
if(Process->Peb)
|
||||||
if(Process->DebugPort == NULL)
|
|
||||||
{
|
{
|
||||||
/* keep the reference to the handle! */
|
/* we're now debugging the process, so set the flag in the PEB
|
||||||
Process->DebugPort = DebugPort;
|
structure. However, to access it we need to attach to the
|
||||||
|
process so we're sure we're in the right context! */
|
||||||
if(Process->Peb)
|
|
||||||
{
|
|
||||||
/* we're now debugging the process, so set the flag in the PEB
|
|
||||||
structure. However, to access it we need to attach to the
|
|
||||||
process so we're sure we're in the right context! */
|
|
||||||
|
|
||||||
KeAttachProcess(&Process->Pcb);
|
KeAttachProcess(&Process->Pcb);
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Process->Peb->BeingDebugged = TRUE;
|
Process->Peb->BeingDebugged = TRUE;
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
DPRINT1("Trying to set the Peb->BeingDebugged field of process 0x%x failed, exception: 0x%x\n", Process, _SEH_GetExceptionCode());
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
KeDetachProcess();
|
|
||||||
}
|
}
|
||||||
Status = STATUS_SUCCESS;
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
DPRINT1("Trying to set the Peb->BeingDebugged field of process 0x%x failed, exception: 0x%x\n", Process, _SEH_GetExceptionCode());
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
else
|
Status = STATUS_SUCCESS;
|
||||||
{
|
|
||||||
ObDereferenceObject(DebugPort);
|
|
||||||
Status = STATUS_PORT_ALREADY_SET;
|
|
||||||
}
|
|
||||||
PsUnlockProcess(Process);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ObDereferenceObject(DebugPort);
|
ObDereferenceObject(DebugPort);
|
||||||
|
Status = STATUS_PORT_ALREADY_SET;
|
||||||
}
|
}
|
||||||
|
PsUnlockProcess(Process);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObDereferenceObject(DebugPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1934,67 +1927,60 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
case ProcessExceptionPort:
|
case ProcessExceptionPort:
|
||||||
{
|
{
|
||||||
if(ProcessInformationLength != sizeof(HANDLE))
|
HANDLE PortHandle = NULL;
|
||||||
{
|
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HANDLE PortHandle = NULL;
|
|
||||||
|
|
||||||
/* make a safe copy of the buffer on the stack */
|
/* make a safe copy of the buffer on the stack */
|
||||||
_SEH_TRY
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
PortHandle = *(PHANDLE)ProcessInformation;
|
PortHandle = *(PHANDLE)ProcessInformation;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
Status = _SEH_GetExceptionCode();
|
Status = _SEH_GetExceptionCode();
|
||||||
}
|
}
|
||||||
_SEH_END;
|
_SEH_END;
|
||||||
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
PEPORT ExceptionPort;
|
||||||
|
|
||||||
|
/* in case we had success reading from the buffer, verify the provided
|
||||||
|
* LPC port handle
|
||||||
|
*/
|
||||||
|
Status = ObReferenceObjectByHandle(PortHandle,
|
||||||
|
0,
|
||||||
|
LpcPortObjectType,
|
||||||
|
PreviousMode,
|
||||||
|
(PVOID)&ExceptionPort,
|
||||||
|
NULL);
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
PEPORT ExceptionPort;
|
/* lock the process to be thread-safe! */
|
||||||
|
|
||||||
/* in case we had success reading from the buffer, verify the provided
|
Status = PsLockProcess(Process, FALSE);
|
||||||
* LPC port handle
|
|
||||||
*/
|
|
||||||
Status = ObReferenceObjectByHandle(PortHandle,
|
|
||||||
0,
|
|
||||||
LpcPortObjectType,
|
|
||||||
PreviousMode,
|
|
||||||
(PVOID)&ExceptionPort,
|
|
||||||
NULL);
|
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* lock the process to be thread-safe! */
|
/*
|
||||||
|
* according to "NT Native API" documentation, setting the exception
|
||||||
Status = PsLockProcess(Process, FALSE);
|
* port is only permitted once!
|
||||||
if(NT_SUCCESS(Status))
|
*/
|
||||||
|
if(Process->ExceptionPort == NULL)
|
||||||
{
|
{
|
||||||
/*
|
/* keep the reference to the handle! */
|
||||||
* according to "NT Native API" documentation, setting the exception
|
Process->ExceptionPort = ExceptionPort;
|
||||||
* port is only permitted once!
|
Status = STATUS_SUCCESS;
|
||||||
*/
|
|
||||||
if(Process->ExceptionPort == NULL)
|
|
||||||
{
|
|
||||||
/* keep the reference to the handle! */
|
|
||||||
Process->ExceptionPort = ExceptionPort;
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ObDereferenceObject(ExceptionPort);
|
|
||||||
Status = STATUS_PORT_ALREADY_SET;
|
|
||||||
}
|
|
||||||
PsUnlockProcess(Process);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ObDereferenceObject(ExceptionPort);
|
ObDereferenceObject(ExceptionPort);
|
||||||
|
Status = STATUS_PORT_ALREADY_SET;
|
||||||
}
|
}
|
||||||
|
PsUnlockProcess(Process);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ObDereferenceObject(ExceptionPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2003,127 +1989,106 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
|
||||||
|
|
||||||
case ProcessAccessToken:
|
case ProcessAccessToken:
|
||||||
{
|
{
|
||||||
if(ProcessInformationLength != sizeof(PROCESS_ACCESS_TOKEN))
|
HANDLE TokenHandle = NULL;
|
||||||
|
|
||||||
|
/* make a safe copy of the buffer on the stack */
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
HANDLE TokenHandle = NULL;
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
/* make a safe copy of the buffer on the stack */
|
if(NT_SUCCESS(Status))
|
||||||
_SEH_TRY
|
{
|
||||||
{
|
/* in case we had success reading from the buffer, perform the actual task */
|
||||||
TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
|
Status = PspAssignPrimaryToken(Process, TokenHandle);
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if(NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
/* in case we had success reading from the buffer, perform the actual task */
|
|
||||||
Status = PspAssignPrimaryToken(Process, TokenHandle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ProcessDefaultHardErrorMode:
|
case ProcessDefaultHardErrorMode:
|
||||||
{
|
{
|
||||||
if(ProcessInformationLength != sizeof(UINT))
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
|
||||||
|
*(PLONG)ProcessInformation);
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
Status = _SEH_GetExceptionCode();
|
||||||
{
|
|
||||||
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
|
|
||||||
*(PLONG)ProcessInformation);
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
}
|
}
|
||||||
|
_SEH_END;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ProcessSessionInformation:
|
case ProcessSessionInformation:
|
||||||
{
|
{
|
||||||
if(ProcessInformationLength != sizeof(UINT))
|
PROCESS_SESSION_INFORMATION SessionInfo;
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Status = STATUS_INFO_LENGTH_MISMATCH;
|
/* copy the structure to the stack */
|
||||||
|
SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
PROCESS_SESSION_INFORMATION SessionInfo;
|
Status = _SEH_GetExceptionCode();
|
||||||
Status = STATUS_SUCCESS;
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* we successfully copied the structure to the stack, continue processing */
|
||||||
|
|
||||||
_SEH_TRY
|
/*
|
||||||
|
* setting the session id requires the SeTcbPrivilege!
|
||||||
|
*/
|
||||||
|
if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
|
||||||
|
PreviousMode))
|
||||||
{
|
{
|
||||||
/* copy the structure to the stack */
|
DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
|
||||||
SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
|
/* can't set the session id, bail! */
|
||||||
|
Status = STATUS_PRIVILEGE_NOT_HELD;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
|
/* FIXME - update the session id for the process token */
|
||||||
|
|
||||||
|
Status = PsLockProcess(Process, FALSE);
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* we successfully copied the structure to the stack, continue processing */
|
Process->SessionId = SessionInfo.SessionId;
|
||||||
|
|
||||||
/*
|
|
||||||
* setting the session id requires the SeTcbPrivilege!
|
|
||||||
*/
|
|
||||||
if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
|
|
||||||
PreviousMode))
|
|
||||||
{
|
|
||||||
DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
|
|
||||||
/* can't set the session id, bail! */
|
|
||||||
Status = STATUS_PRIVILEGE_NOT_HELD;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME - update the session id for the process token */
|
|
||||||
|
|
||||||
Status = PsLockProcess(Process, FALSE);
|
/* Update the session id in the PEB structure */
|
||||||
if(NT_SUCCESS(Status))
|
if(Process->Peb != NULL)
|
||||||
{
|
{
|
||||||
Process->SessionId = SessionInfo.SessionId;
|
/* we need to attach to the process to make sure we're in the right
|
||||||
|
context to access the PEB structure */
|
||||||
|
KeAttachProcess(&Process->Pcb);
|
||||||
|
|
||||||
/* Update the session id in the PEB structure */
|
_SEH_TRY
|
||||||
if(Process->Peb != NULL)
|
|
||||||
{
|
{
|
||||||
/* we need to attach to the process to make sure we're in the right
|
/* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
|
||||||
context to access the PEB structure */
|
|
||||||
KeAttachProcess(&Process->Pcb);
|
|
||||||
|
|
||||||
_SEH_TRY
|
Status = STATUS_SUCCESS;
|
||||||
{
|
|
||||||
/* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
|
|
||||||
|
|
||||||
Status = STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
KeDetachProcess();
|
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
PsUnlockProcess(Process);
|
KeDetachProcess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PsUnlockProcess(Process);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -178,7 +178,6 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
|
||||||
InitializeListHead(&Win32Thread->WindowListHead);
|
InitializeListHead(&Win32Thread->WindowListHead);
|
||||||
ExInitializeFastMutex(&Win32Thread->WindowListLock);
|
ExInitializeFastMutex(&Win32Thread->WindowListLock);
|
||||||
InitializeListHead(&Win32Thread->W32CallbackListHead);
|
InitializeListHead(&Win32Thread->W32CallbackListHead);
|
||||||
ExInitializeFastMutex(&Win32Thread->W32CallbackListLock);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -63,9 +63,7 @@ IntCbAllocateMemory(ULONG Size)
|
||||||
|
|
||||||
/* insert the callback memory into the thread's callback list */
|
/* insert the callback memory into the thread's callback list */
|
||||||
|
|
||||||
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
InsertTailList(&W32Thread->W32CallbackListHead, &Mem->ListEntry);
|
InsertTailList(&W32Thread->W32CallbackListHead, &Mem->ListEntry);
|
||||||
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
|
|
||||||
return (Mem + 1);
|
return (Mem + 1);
|
||||||
}
|
}
|
||||||
|
@ -84,9 +82,7 @@ IntCbFreeMemory(PVOID Data)
|
||||||
ASSERT(W32Thread);
|
ASSERT(W32Thread);
|
||||||
|
|
||||||
/* remove the memory block from the thread's callback list */
|
/* remove the memory block from the thread's callback list */
|
||||||
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
RemoveEntryList(&Mem->ListEntry);
|
RemoveEntryList(&Mem->ListEntry);
|
||||||
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
|
|
||||||
/* free memory */
|
/* free memory */
|
||||||
ExFreePool(Mem);
|
ExFreePool(Mem);
|
||||||
|
@ -98,7 +94,6 @@ IntCleanupThreadCallbacks(PW32THREAD W32Thread)
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntry;
|
||||||
PINT_CALLBACK_HEADER Mem;
|
PINT_CALLBACK_HEADER Mem;
|
||||||
|
|
||||||
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
while (!IsListEmpty(&W32Thread->W32CallbackListHead))
|
while (!IsListEmpty(&W32Thread->W32CallbackListHead))
|
||||||
{
|
{
|
||||||
CurrentEntry = RemoveHeadList(&W32Thread->W32CallbackListHead);
|
CurrentEntry = RemoveHeadList(&W32Thread->W32CallbackListHead);
|
||||||
|
@ -108,7 +103,6 @@ IntCleanupThreadCallbacks(PW32THREAD W32Thread)
|
||||||
/* free memory */
|
/* free memory */
|
||||||
ExFreePool(Mem);
|
ExFreePool(Mem);
|
||||||
}
|
}
|
||||||
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
Loading…
Reference in a new issue