mirror of
https://github.com/reactos/reactos.git
synced 2025-06-14 07:08:30 +00:00
[WIN32K]
- Properly handle deletion of cursor/Icon objects - Gracefully change object owner when process closes - Remove useless check in a macro svn path=/trunk/; revision=57641
This commit is contained in:
parent
2108e7256c
commit
b6e5342bce
4 changed files with 64 additions and 52 deletions
|
@ -163,6 +163,6 @@ BOOL NTAPI W32kDosPathNameToNtPathName(PCWSTR, PUNICODE_STRING);
|
||||||
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \
|
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \
|
||||||
for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \
|
for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \
|
||||||
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \
|
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \
|
||||||
&(cursor)->field != (list) && ((&((cursor)->field)) != NULL); \
|
&(cursor)->field != (list); \
|
||||||
(cursor) = (cursor2), \
|
(cursor) = (cursor2), \
|
||||||
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field))
|
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field))
|
||||||
|
|
|
@ -234,55 +234,54 @@ IntCreateCurIconHandle()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FASTCALL
|
BOOLEAN FASTCALL
|
||||||
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOL ProcessCleanup)
|
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
|
||||||
{
|
{
|
||||||
PSYSTEM_CURSORINFO CurInfo;
|
PSYSTEM_CURSORINFO CurInfo;
|
||||||
HBITMAP bmpMask, bmpColor;
|
HBITMAP bmpMask, bmpColor;
|
||||||
BOOLEAN Ret;
|
BOOLEAN Ret, bListEmpty, bFound = FALSE;
|
||||||
PCURICON_PROCESS Current = NULL;
|
PCURICON_PROCESS Current = NULL;
|
||||||
PPROCESSINFO W32Process = PsGetCurrentProcessWin32Process();
|
|
||||||
|
|
||||||
/* Private objects can only be destroyed by their own process */
|
/* For handles created without any data (error handling) */
|
||||||
if (NULL == CurIcon->hModule)
|
if(IsListEmpty(&CurIcon->ProcessList))
|
||||||
{
|
goto emptyList;
|
||||||
ASSERT(CurIcon->ProcessList.Flink->Flink == &CurIcon->ProcessList);
|
|
||||||
Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS, ListEntry);
|
|
||||||
if (Current->Process != W32Process)
|
|
||||||
{
|
|
||||||
ERR("Trying to destroy private icon/cursor of another process\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (! ProcessCleanup)
|
|
||||||
{
|
|
||||||
TRACE("Trying to destroy shared icon/cursor\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now find this process in the list of processes referencing this object and
|
/* Now find this process in the list of processes referencing this object and
|
||||||
remove it from that list */
|
remove it from that list */
|
||||||
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
||||||
{
|
{
|
||||||
if (Current->Process == W32Process)
|
if (Current->Process == ppi)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&Current->ListEntry);
|
bFound = TRUE;
|
||||||
|
bListEmpty = RemoveEntryList(&Current->ListEntry);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!bFound)
|
||||||
|
{
|
||||||
|
/* This object doesn't belong to this process */
|
||||||
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
|
ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
|
||||||
|
|
||||||
/* If there are still processes referencing this object we can't destroy it yet */
|
/* If there are still processes referencing this object we can't destroy it yet */
|
||||||
if (! IsListEmpty(&CurIcon->ProcessList))
|
if (!bListEmpty)
|
||||||
{
|
{
|
||||||
|
if(CurIcon->head.ppi == ppi)
|
||||||
|
{
|
||||||
|
/* Set the first process of the list as owner */
|
||||||
|
Current = CONTAINING_RECORD(CurIcon->ProcessList.Flink, CURICON_PROCESS, ListEntry);
|
||||||
|
UserSetObjectOwner(CurIcon, otCursorIcon, Current->Process);
|
||||||
|
}
|
||||||
|
UserDereferenceObject(CurIcon);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emptyList:
|
||||||
if (! ProcessCleanup)
|
/* Remove it from the list */
|
||||||
{
|
|
||||||
RemoveEntryList(&CurIcon->ListEntry);
|
RemoveEntryList(&CurIcon->ListEntry);
|
||||||
}
|
|
||||||
|
|
||||||
CurInfo = IntGetSysCursorInfo();
|
CurInfo = IntGetSysCursorInfo();
|
||||||
|
|
||||||
|
@ -320,33 +319,13 @@ VOID FASTCALL
|
||||||
IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
|
IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon, tmp;
|
PCURICON_OBJECT CurIcon, tmp;
|
||||||
PCURICON_PROCESS ProcessData;
|
|
||||||
|
|
||||||
|
/* Run through the list of icon objects */
|
||||||
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
||||||
{
|
{
|
||||||
UserReferenceObject(CurIcon);
|
UserReferenceObject(CurIcon);
|
||||||
// if(NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon)))
|
IntDestroyCurIconObject(CurIcon, Win32Process);
|
||||||
{
|
|
||||||
LIST_FOR_EACH(ProcessData, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
|
|
||||||
{
|
|
||||||
if (Win32Process == ProcessData->Process)
|
|
||||||
{
|
|
||||||
RemoveEntryList(&CurIcon->ListEntry);
|
|
||||||
IntDestroyCurIconObject(CurIcon, TRUE);
|
|
||||||
CurIcon = NULL;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// UserDereferenceObject(Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurIcon)
|
|
||||||
{
|
|
||||||
UserDereferenceObject(CurIcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -649,7 +628,7 @@ NtUserDestroyCursor(
|
||||||
RETURN(FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = IntDestroyCurIconObject(CurIcon, FALSE);
|
ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
|
||||||
/* Note: IntDestroyCurIconObject will remove our reference for us! */
|
/* Note: IntDestroyCurIconObject will remove our reference for us! */
|
||||||
|
|
||||||
RETURN(ret);
|
RETURN(ret);
|
||||||
|
|
|
@ -516,6 +516,38 @@ UserReferenceObjectByHandle(HANDLE handle, USER_OBJECT_TYPE type)
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
UserSetObjectOwner(PVOID obj, USER_OBJECT_TYPE type, PVOID owner)
|
||||||
|
{
|
||||||
|
PUSER_HANDLE_ENTRY entry = handle_to_entry(gHandleTable, ((PHEAD)obj)->h );
|
||||||
|
PPROCESSINFO ppi, oldppi;
|
||||||
|
|
||||||
|
/* This must be called with a valid object */
|
||||||
|
ASSERT(entry);
|
||||||
|
|
||||||
|
/* For now, only supported for CursorIcon object */
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case otCursorIcon:
|
||||||
|
ppi = (PPROCESSINFO)owner;
|
||||||
|
entry->pi = ppi;
|
||||||
|
oldppi = ((PPROCMARKHEAD)obj)->ppi;
|
||||||
|
((PPROCMARKHEAD)obj)->ppi = ppi;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(FALSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldppi->UserHandleCount--;
|
||||||
|
ppi->UserHandleCount++;
|
||||||
|
#if DBG
|
||||||
|
oldppi->DbgHandleCount[type]--;
|
||||||
|
ppi->DbgHandleCount[type]++;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtUserValidateHandleSecure
|
* NtUserValidateHandleSecure
|
||||||
*
|
*
|
||||||
|
|
|
@ -40,6 +40,7 @@ PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE, HANDLE, USER_OBJECT_TYPE);
|
||||||
BOOL FASTCALL UserCreateHandleTable(VOID);
|
BOOL FASTCALL UserCreateHandleTable(VOID);
|
||||||
BOOL FASTCALL UserObjectInDestroy(HANDLE);
|
BOOL FASTCALL UserObjectInDestroy(HANDLE);
|
||||||
void DbgUserDumpHandleTable();
|
void DbgUserDumpHandleTable();
|
||||||
|
VOID FASTCALL UserSetObjectOwner(PVOID obj, USER_OBJECT_TYPE type, PVOID owner);
|
||||||
|
|
||||||
static __inline VOID
|
static __inline VOID
|
||||||
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
|
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue