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:
Thomas Bluemel 2005-02-12 20:37:04 +00:00
parent a780838c2e
commit 709af1f28a
4 changed files with 159 additions and 202 deletions

View file

@ -8,7 +8,6 @@ typedef struct _W32THREAD
PVOID MessageQueue;
FAST_MUTEX WindowListLock;
LIST_ENTRY WindowListHead;
FAST_MUTEX W32CallbackListLock;
LIST_ENTRY W32CallbackListHead;
struct _KBDTABLES* KeyboardLayout;
struct _DESKTOP_OBJECT* Desktop;

View file

@ -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( 0 /* FIXME */, sizeof(ULONG), ICIF_SET ), /* ProcessUserModeIOPL */
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 ), /* ProcessHandleCount */
ICI_SQ_SAME( sizeof(KAFFINITY), sizeof(ULONG), ICIF_SET ), /* ProcessAffinityMask */
@ -1846,86 +1846,79 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
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 */
_SEH_TRY
{
PortHandle = *(PHANDLE)ProcessInformation;
Status = (PortHandle != NULL ? STATUS_SUCCESS : STATUS_INVALID_PARAMETER);
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
if(NT_SUCCESS(Status))
{
PEPORT DebugPort;
/* 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))
{
PEPORT DebugPort;
/* lock the process to be thread-safe! */
/* in case we had success reading from the buffer, verify the provided
* LPC port handle
*/
Status = ObReferenceObjectByHandle(PortHandle,
0,
LpcPortObjectType,
PreviousMode,
(PVOID)&DebugPort,
NULL);
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
{
/* lock the process to be thread-safe! */
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
/*
* according to "NT Native API" documentation, setting the debug
* port is only permitted once!
*/
if(Process->DebugPort == NULL)
{
/*
* according to "NT Native API" documentation, setting the debug
* port is only permitted once!
*/
if(Process->DebugPort == NULL)
/* keep the reference to the handle! */
Process->DebugPort = DebugPort;
if(Process->Peb)
{
/* keep the reference to the handle! */
Process->DebugPort = DebugPort;
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! */
/* 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);
_SEH_TRY
{
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();
KeAttachProcess(&Process->Pcb);
_SEH_TRY
{
Process->Peb->BeingDebugged = TRUE;
}
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
{
ObDereferenceObject(DebugPort);
Status = STATUS_PORT_ALREADY_SET;
}
PsUnlockProcess(Process);
Status = STATUS_SUCCESS;
}
else
{
ObDereferenceObject(DebugPort);
Status = STATUS_PORT_ALREADY_SET;
}
PsUnlockProcess(Process);
}
else
{
ObDereferenceObject(DebugPort);
}
}
}
@ -1934,67 +1927,60 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
case ProcessExceptionPort:
{
if(ProcessInformationLength != sizeof(HANDLE))
{
Status = STATUS_INFO_LENGTH_MISMATCH;
}
else
{
HANDLE PortHandle = NULL;
HANDLE PortHandle = NULL;
/* make a safe copy of the buffer on the stack */
_SEH_TRY
{
PortHandle = *(PHANDLE)ProcessInformation;
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
/* make a safe copy of the buffer on the stack */
_SEH_TRY
{
PortHandle = *(PHANDLE)ProcessInformation;
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_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))
{
PEPORT ExceptionPort;
/* lock the process to be thread-safe! */
/* in case we had success reading from the buffer, verify the provided
* LPC port handle
*/
Status = ObReferenceObjectByHandle(PortHandle,
0,
LpcPortObjectType,
PreviousMode,
(PVOID)&ExceptionPort,
NULL);
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
{
/* lock the process to be thread-safe! */
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
/*
* according to "NT Native API" documentation, setting the exception
* port is only permitted once!
*/
if(Process->ExceptionPort == NULL)
{
/*
* according to "NT Native API" documentation, setting the exception
* port is only permitted once!
*/
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);
/* keep the reference to the handle! */
Process->ExceptionPort = ExceptionPort;
Status = STATUS_SUCCESS;
}
else
{
ObDereferenceObject(ExceptionPort);
Status = STATUS_PORT_ALREADY_SET;
}
PsUnlockProcess(Process);
}
else
{
ObDereferenceObject(ExceptionPort);
}
}
}
@ -2003,127 +1989,106 @@ NtSetInformationProcess(IN HANDLE ProcessHandle,
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 */
_SEH_TRY
{
TokenHandle = ((PPROCESS_ACCESS_TOKEN)ProcessInformation)->Token;
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);
}
if(NT_SUCCESS(Status))
{
/* in case we had success reading from the buffer, perform the actual task */
Status = PspAssignPrimaryToken(Process, TokenHandle);
}
break;
}
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
{
InterlockedExchange((LONG*)&Process->DefaultHardErrorProcessing,
*(PLONG)ProcessInformation);
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
break;
}
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 = STATUS_SUCCESS;
Status = _SEH_GetExceptionCode();
}
_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 */
SessionInfo = *(PPROCESS_SESSION_INFORMATION)ProcessInformation;
DPRINT1("NtSetInformationProcess: Caller requires the SeTcbPrivilege privilege for setting ProcessSessionInformation!\n");
/* 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))
{
/* we successfully copied the structure to the stack, continue processing */
/*
* 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 */
Process->SessionId = SessionInfo.SessionId;
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
/* Update the session id in the PEB structure */
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 */
if(Process->Peb != NULL)
_SEH_TRY
{
/* we need to attach to the process to make sure we're in the right
context to access the PEB structure */
KeAttachProcess(&Process->Pcb);
/* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
_SEH_TRY
{
/* FIXME: Process->Peb->SessionId = SessionInfo.SessionId; */
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
KeDetachProcess();
Status = STATUS_SUCCESS;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
}
_SEH_END;
PsUnlockProcess(Process);
KeDetachProcess();
}
PsUnlockProcess(Process);
}
}
break;

View file

@ -178,7 +178,6 @@ Win32kThreadCallback (struct _ETHREAD *Thread,
InitializeListHead(&Win32Thread->WindowListHead);
ExInitializeFastMutex(&Win32Thread->WindowListLock);
InitializeListHead(&Win32Thread->W32CallbackListHead);
ExInitializeFastMutex(&Win32Thread->W32CallbackListLock);
}
else
{

View file

@ -63,9 +63,7 @@ IntCbAllocateMemory(ULONG Size)
/* insert the callback memory into the thread's callback list */
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
InsertTailList(&W32Thread->W32CallbackListHead, &Mem->ListEntry);
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
return (Mem + 1);
}
@ -84,9 +82,7 @@ IntCbFreeMemory(PVOID Data)
ASSERT(W32Thread);
/* remove the memory block from the thread's callback list */
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
RemoveEntryList(&Mem->ListEntry);
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
/* free memory */
ExFreePool(Mem);
@ -98,7 +94,6 @@ IntCleanupThreadCallbacks(PW32THREAD W32Thread)
PLIST_ENTRY CurrentEntry;
PINT_CALLBACK_HEADER Mem;
ExAcquireFastMutex(&W32Thread->W32CallbackListLock);
while (!IsListEmpty(&W32Thread->W32CallbackListHead))
{
CurrentEntry = RemoveHeadList(&W32Thread->W32CallbackListHead);
@ -108,7 +103,6 @@ IntCleanupThreadCallbacks(PW32THREAD W32Thread)
/* free memory */
ExFreePool(Mem);
}
ExReleaseFastMutex(&W32Thread->W32CallbackListLock);
}
/* FUNCTIONS *****************************************************************/