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; 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;

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( 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;

View file

@ -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
{ {

View file

@ -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 *****************************************************************/