mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:35:42 +00:00
Don't destroy cursors/icons prematurely.
svn path=/trunk/; revision=12742
This commit is contained in:
parent
c60f00807e
commit
8c1121a5be
5 changed files with 322 additions and 170 deletions
|
@ -28,8 +28,6 @@ typedef struct _W32PROCESS
|
|||
LIST_ENTRY MenuListHead;
|
||||
FAST_MUTEX PrivateFontListLock;
|
||||
LIST_ENTRY PrivateFontListHead;
|
||||
FAST_MUTEX CursorIconListLock;
|
||||
LIST_ENTRY CursorIconListHead;
|
||||
struct _KBDTABLES* KeyboardLayout;
|
||||
ULONG Flags;
|
||||
LONG GDIObjects;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: bitmap.c,v 1.34 2004/12/19 05:00:22 royce Exp $
|
||||
/* $Id$
|
||||
*
|
||||
* PROJECT: ReactOS user32.dll
|
||||
* FILE: lib/user32/windows/input.c
|
||||
|
@ -149,7 +149,7 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
|
|||
hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE)ResIcon,
|
||||
SizeofResource(hinst, h2Resource), FALSE, 0x00030000,
|
||||
32, 32, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
||||
if (hIcon)
|
||||
if (hIcon && 0 != (fuLoad & LR_SHARED))
|
||||
{
|
||||
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
|
||||
(HRSRC)NULL);
|
||||
|
@ -157,100 +157,98 @@ LoadCursorImage(HINSTANCE hinst, LPCWSTR lpszName, UINT fuLoad)
|
|||
|
||||
return hIcon;
|
||||
}
|
||||
else
|
||||
|
||||
if (fuLoad & LR_SHARED)
|
||||
{
|
||||
if (fuLoad & LR_SHARED)
|
||||
{
|
||||
DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
|
||||
}
|
||||
DbgPrint("FIXME: need LR_SHARED support loading cursor images from files\n");
|
||||
}
|
||||
|
||||
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(hFile);
|
||||
if (hSection == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle(hSection);
|
||||
if (IconDIR == NULL || 0 != IconDIR->idReserved
|
||||
|| (IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a handle to the screen dc, the icon we create is going to be
|
||||
* compatable with it.
|
||||
*/
|
||||
hScreenDc = CreateCompatibleDC(0);
|
||||
if (hScreenDc == NULL)
|
||||
{
|
||||
UnmapViewOfFile(IconDIR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fuLoad & LR_MONOCHROME)
|
||||
{
|
||||
ColorBits = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
|
||||
/*
|
||||
* FIXME:
|
||||
* Remove this after proper support for alpha icons will be finished.
|
||||
*/
|
||||
if (ColorBits > 8)
|
||||
ColorBits = 8;
|
||||
}
|
||||
|
||||
/* Pick the best size. */
|
||||
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
|
||||
if (!dirEntry)
|
||||
{
|
||||
UnmapViewOfFile(IconDIR);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
|
||||
memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
|
||||
hFile = CreateFileW(lpszName, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
if (hFile == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//at this point we have a copy of the icon image to play with
|
||||
hSection = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
|
||||
CloseHandle(hFile);
|
||||
if (hSection == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
|
||||
IconDIR = MapViewOfFile(hSection, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle(hSection);
|
||||
if (IconDIR == NULL || 0 != IconDIR->idReserved
|
||||
|| (IMAGE_ICON != IconDIR->idType && IMAGE_CURSOR != IconDIR->idType))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
/*
|
||||
* Get a handle to the screen dc, the icon we create is going to be
|
||||
* compatable with it.
|
||||
*/
|
||||
hScreenDc = CreateCompatibleDC(0);
|
||||
if (hScreenDc == NULL)
|
||||
{
|
||||
UnmapViewOfFile(IconDIR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fuLoad & LR_MONOCHROME)
|
||||
{
|
||||
ColorBits = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ColorBits = GetDeviceCaps(hScreenDc, BITSPIXEL);
|
||||
/*
|
||||
* FIXME:
|
||||
* Remove this after proper support for alpha icons will be finished.
|
||||
*/
|
||||
if (ColorBits > 8)
|
||||
ColorBits = 8;
|
||||
}
|
||||
|
||||
/* Pick the best size. */
|
||||
dirEntry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon(IconDIR, 32, 32, ColorBits);
|
||||
if (!dirEntry)
|
||||
{
|
||||
UnmapViewOfFile(IconDIR);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
SafeIconImage = RtlAllocateHeap(GetProcessHeap(), 0, dirEntry->dwBytesInRes);
|
||||
memcpy(SafeIconImage, ((PBYTE)IconDIR) + dirEntry->dwImageOffset, dirEntry->dwBytesInRes);
|
||||
|
||||
/* at this point we have a copy of the icon image to play with */
|
||||
|
||||
SafeIconImage->icHeader.biHeight = SafeIconImage->icHeader.biHeight /2;
|
||||
|
||||
if (SafeIconImage->icHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BITMAPCOREHEADER* Core = (BITMAPCOREHEADER*)SafeIconImage;
|
||||
ColorCount = (Core->bcBitCount <= 8) ? (1 << Core->bcBitCount) : 0;
|
||||
HeaderSize = sizeof(BITMAPCOREHEADER) + ColorCount * sizeof(RGBTRIPLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
ColorCount = SafeIconImage->icHeader.biClrUsed;
|
||||
if (ColorCount == 0 && SafeIconImage->icHeader.biBitCount <= 8)
|
||||
{
|
||||
ColorCount = 1 << SafeIconImage->icHeader.biBitCount;
|
||||
}
|
||||
HeaderSize = sizeof(BITMAPINFOHEADER) + ColorCount * sizeof(RGBQUAD);
|
||||
}
|
||||
}
|
||||
|
||||
//make data point to the start of the XOR image data
|
||||
Data = (PBYTE)SafeIconImage + HeaderSize;
|
||||
/* make data point to the start of the XOR image data */
|
||||
Data = (PBYTE)SafeIconImage + HeaderSize;
|
||||
|
||||
hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
|
||||
DeleteDC(hScreenDc);
|
||||
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
||||
return hIcon;
|
||||
hIcon = ICON_CreateCursorFromData(hScreenDc, Data, SafeIconImage, 32, 32, dirEntry->Info.cursor.wXHotspot, dirEntry->Info.cursor.wYHotspot);
|
||||
DeleteDC(hScreenDc);
|
||||
RtlFreeHeap(GetProcessHeap(), 0, SafeIconImage);
|
||||
return hIcon;
|
||||
}
|
||||
|
||||
|
||||
|
@ -326,7 +324,7 @@ LoadIconImage(HINSTANCE hinst, LPCWSTR lpszName, INT width, INT height, UINT fuL
|
|||
hIcon = (HANDLE)CreateIconFromResourceEx((PBYTE) ResIcon,
|
||||
SizeofResource(hinst, h2Resource), TRUE, 0x00030000,
|
||||
width, height, fuLoad & (LR_DEFAULTCOLOR | LR_MONOCHROME));
|
||||
if(hIcon)
|
||||
if (hIcon && 0 != (fuLoad & LR_SHARED))
|
||||
{
|
||||
NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hinst, (HRSRC)hfRes,
|
||||
(HRSRC)NULL);
|
||||
|
|
|
@ -3,11 +3,18 @@
|
|||
|
||||
#define MAXCURICONHANDLES 4096
|
||||
|
||||
typedef struct _CURICON_OBJECT
|
||||
typedef struct tagCURICON_PROCESS
|
||||
{
|
||||
HANDLE Self;
|
||||
LIST_ENTRY ListEntry;
|
||||
PW32PROCESS Process;
|
||||
} CURICON_PROCESS, *PCURICON_PROCESS;
|
||||
|
||||
typedef struct _CURICON_OBJECT
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
HANDLE Self;
|
||||
FAST_MUTEX Lock;
|
||||
LIST_ENTRY ProcessList;
|
||||
HMODULE hModule;
|
||||
HRSRC hRsrc;
|
||||
HRSRC hGroupRsrc;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: dllmain.c,v 1.86 2004/12/29 19:55:01 gvg Exp $
|
||||
/* $Id$
|
||||
*
|
||||
* Entry Point for win32k.sys
|
||||
*/
|
||||
|
@ -71,9 +71,6 @@ Win32kProcessCallback (struct _EPROCESS *Process,
|
|||
InitializeListHead(&Win32Process->PrivateFontListHead);
|
||||
ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
|
||||
|
||||
InitializeListHead(&Win32Process->CursorIconListHead);
|
||||
ExInitializeFastMutex(&Win32Process->CursorIconListLock);
|
||||
|
||||
Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
|
||||
|
||||
/* setup process flags */
|
||||
|
|
|
@ -16,9 +16,32 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: cursoricon.c,v 1.5 2004/12/30 02:32:18 navaraf Exp $ */
|
||||
|
||||
/*
|
||||
* We handle two types of cursors/icons:
|
||||
* - Private
|
||||
* Loaded without LR_SHARED flag
|
||||
* Private to a process
|
||||
* Can be deleted by calling NtDestroyCursorIcon()
|
||||
* CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc set to NULL
|
||||
* - Shared
|
||||
* Loaded with LR_SHARED flag
|
||||
* Possibly shared by multiple processes
|
||||
* Immune to NtDestroyCursorIcon()
|
||||
* CurIcon->hModule, CurIcon->hRsrc and CurIcon->hGroupRsrc are valid
|
||||
* There's a M:N relationship between processes and (shared) cursor/icons.
|
||||
* A process can have multiple cursor/icons and a cursor/icon can be used
|
||||
* by multiple processes. To keep track of this we keep a list of all
|
||||
* cursor/icons (CurIconList) and per cursor/icon we keep a list of
|
||||
* CURICON_PROCESS structs starting at CurIcon->ProcessList.
|
||||
*/
|
||||
|
||||
#include <w32k.h>
|
||||
|
||||
static PAGED_LOOKASIDE_LIST ProcessLookasideList;
|
||||
static LIST_ENTRY CurIconList;
|
||||
static FAST_MUTEX CurIconListLock;
|
||||
|
||||
PCURICON_OBJECT FASTCALL
|
||||
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
|
||||
{
|
||||
|
@ -248,6 +271,61 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor,
|
|||
BOOL FASTCALL
|
||||
IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject)
|
||||
{
|
||||
ExInitializePagedLookasideList(&ProcessLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(CURICON_PROCESS),
|
||||
0,
|
||||
128);
|
||||
InitializeListHead(&CurIconList);
|
||||
ExInitializeFastMutex(&CurIconListLock);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to register that this object is in use by the current
|
||||
* process. The only way to do that seems to be to walk the list
|
||||
* of cursor/icon objects starting at W32Process->CursorIconListHead.
|
||||
* If the object is already present in the list, we don't have to do
|
||||
* anything, if it's not present we add it and inc the ProcessCount
|
||||
* in the object. Having to walk the list kind of sucks, but that's
|
||||
* life...
|
||||
*/
|
||||
static BOOLEAN FASTCALL
|
||||
ReferenceCurIconByProcess(PCURICON_OBJECT Object)
|
||||
{
|
||||
PW32PROCESS Win32Process;
|
||||
PLIST_ENTRY Search;
|
||||
PCURICON_PROCESS Current;
|
||||
|
||||
Win32Process = PsGetWin32Process();
|
||||
|
||||
ExAcquireFastMutex(&Object->Lock);
|
||||
Search = Object->ProcessList.Flink;
|
||||
while (Search != &Object->ProcessList)
|
||||
{
|
||||
Current = CONTAINING_RECORD(Search, CURICON_PROCESS, ListEntry);
|
||||
if (Current->Process == Win32Process)
|
||||
{
|
||||
/* Already registered for this process */
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
return TRUE;
|
||||
}
|
||||
Search = Search->Flink;
|
||||
}
|
||||
|
||||
/* Not registered yet */
|
||||
Current = ExAllocateFromPagedLookasideList(&ProcessLookasideList);
|
||||
if (NULL == Current)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
InsertHeadList(&Object->ProcessList, &Current->ListEntry);
|
||||
Current->Process = Win32Process;
|
||||
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -255,41 +333,35 @@ PCURICON_OBJECT FASTCALL
|
|||
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule,
|
||||
HRSRC hRsrc, LONG cx, LONG cy)
|
||||
{
|
||||
PUSER_HANDLE_TABLE HandleTable;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PUSER_HANDLE_BLOCK Current;
|
||||
PCURICON_OBJECT Object;
|
||||
ULONG i;
|
||||
|
||||
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->HandleTable;
|
||||
ObmpLockHandleTable(HandleTable);
|
||||
|
||||
CurrentEntry = HandleTable->ListHead.Flink;
|
||||
while(CurrentEntry != &HandleTable->ListHead)
|
||||
|
||||
ExAcquireFastMutex(&CurIconListLock);
|
||||
|
||||
CurrentEntry = CurIconList.Flink;
|
||||
while (CurrentEntry != &CurIconList)
|
||||
{
|
||||
Current = CONTAINING_RECORD(CurrentEntry, USER_HANDLE_BLOCK, ListEntry);
|
||||
for(i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
|
||||
{
|
||||
Object = (PCURICON_OBJECT)Current->Handles[i].ObjectBody;
|
||||
if(Object && (ObmReferenceObjectByPointer(Object, otCursorIcon) == STATUS_SUCCESS))
|
||||
{
|
||||
if((Object->hModule == hModule) && (Object->hRsrc == hRsrc))
|
||||
{
|
||||
if(cx && ((cx != Object->Size.cx) || (cy != Object->Size.cy)))
|
||||
{
|
||||
ObmDereferenceObject(Object);
|
||||
continue;
|
||||
}
|
||||
ObmpUnlockHandleTable(HandleTable);
|
||||
return Object;
|
||||
}
|
||||
ObmDereferenceObject(Object);
|
||||
}
|
||||
}
|
||||
Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
if((Object->hModule == hModule) && (Object->hRsrc == hRsrc))
|
||||
{
|
||||
if(cx && ((cx != Object->Size.cx) || (cy != Object->Size.cy)))
|
||||
{
|
||||
ObmDereferenceObject(Object);
|
||||
continue;
|
||||
}
|
||||
if (! ReferenceCurIconByProcess(Object))
|
||||
{
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
return NULL;
|
||||
}
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
return Object;
|
||||
}
|
||||
}
|
||||
|
||||
ObmpUnlockHandleTable(HandleTable);
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -298,7 +370,6 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
|
|||
{
|
||||
PCURICON_OBJECT Object;
|
||||
HANDLE Handle;
|
||||
PW32PROCESS Win32Process;
|
||||
|
||||
Object = ObmCreateObject(WinStaObject->HandleTable, &Handle, otCursorIcon, sizeof(CURICON_OBJECT));
|
||||
|
||||
|
@ -308,38 +379,89 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
Win32Process = PsGetWin32Process();
|
||||
|
||||
IntLockProcessCursorIcons(Win32Process);
|
||||
InsertTailList(&Win32Process->CursorIconListHead, &Object->ListEntry);
|
||||
IntUnLockProcessCursorIcons(Win32Process);
|
||||
|
||||
Object->Self = Handle;
|
||||
Object->Process = PsGetWin32Process();
|
||||
|
||||
ExInitializeFastMutex(&Object->Lock);
|
||||
InitializeListHead(&Object->ProcessList);
|
||||
|
||||
if (! ReferenceCurIconByProcess(Object))
|
||||
{
|
||||
DPRINT1("Failed to add process\n");
|
||||
ObmCloseHandle(WinStaObject->HandleTable, Handle);
|
||||
ObmDereferenceObject(Object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ExAcquireFastMutex(&CurIconListLock);
|
||||
InsertHeadList(&CurIconList, &Object->ListEntry);
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
|
||||
ObmDereferenceObject(Object);
|
||||
|
||||
return Object;
|
||||
}
|
||||
|
||||
BOOL FASTCALL
|
||||
IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL RemoveFromProcess)
|
||||
BOOLEAN FASTCALL
|
||||
IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT Object, BOOL ProcessCleanup)
|
||||
{
|
||||
PSYSTEM_CURSORINFO CurInfo;
|
||||
PCURICON_OBJECT Object;
|
||||
HBITMAP bmpMask, bmpColor;
|
||||
NTSTATUS Status;
|
||||
BOOL Ret;
|
||||
|
||||
Status = ObmReferenceObjectByHandle(WinStaObject->HandleTable, Handle, otCursorIcon, (PVOID*)&Object);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (Object->Process != PsGetWin32Process())
|
||||
{
|
||||
ObmDereferenceObject(Object);
|
||||
return FALSE;
|
||||
}
|
||||
BOOLEAN Ret;
|
||||
PLIST_ENTRY Search;
|
||||
PCURICON_PROCESS Current;
|
||||
PW32PROCESS W32Process = PsGetWin32Process();
|
||||
|
||||
ExAcquireFastMutex(&Object->Lock);
|
||||
|
||||
/* Private objects can only be destroyed by their own process */
|
||||
if (NULL == Object->hModule)
|
||||
{
|
||||
ASSERT(Object->ProcessList.Flink->Flink == &Object->ProcessList);
|
||||
Current = CONTAINING_RECORD(Object->ProcessList.Flink, CURICON_PROCESS, ListEntry);
|
||||
if (Current->Process != W32Process)
|
||||
{
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
DPRINT1("Trying to destroy private icon/cursor of another process\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (! ProcessCleanup)
|
||||
{
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
DPRINT("Trying to destroy shared icon/cursor\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Now find this process in the list of processes referencing this object and
|
||||
remove it from that list */
|
||||
Search = Object->ProcessList.Flink;
|
||||
while (Search != &Object->ProcessList)
|
||||
{
|
||||
Current = CONTAINING_RECORD(Object->ProcessList.Flink, CURICON_PROCESS, ListEntry);
|
||||
if (Current->Process == W32Process)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Search = Search->Flink;
|
||||
}
|
||||
ASSERT(Search != &Object->ProcessList);
|
||||
RemoveEntryList(Search);
|
||||
ExFreeToPagedLookasideList(&ProcessLookasideList, Current);
|
||||
|
||||
/* If there are still processes referencing this object we can't destroy it yet */
|
||||
if (! IsListEmpty(&Object->ProcessList))
|
||||
{
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
|
||||
if (! ProcessCleanup)
|
||||
{
|
||||
ExAcquireFastMutex(&CurIconListLock);
|
||||
RemoveEntryList(&Object->ListEntry);
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
}
|
||||
|
||||
CurInfo = IntGetSysCursorInfo(WinStaObject);
|
||||
|
||||
|
@ -351,15 +473,8 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL Rem
|
|||
|
||||
bmpMask = Object->IconInfo.hbmMask;
|
||||
bmpColor = Object->IconInfo.hbmColor;
|
||||
|
||||
if (Object->Process && RemoveFromProcess)
|
||||
{
|
||||
IntLockProcessCursorIcons(Object->Process);
|
||||
RemoveEntryList(&Object->ListEntry);
|
||||
IntUnLockProcessCursorIcons(Object->Process);
|
||||
}
|
||||
|
||||
Ret = NT_SUCCESS(ObmCloseHandle(WinStaObject->HandleTable, Handle));
|
||||
Ret = NT_SUCCESS(ObmCloseHandle(WinStaObject->HandleTable, Object->Self));
|
||||
|
||||
/* delete bitmaps */
|
||||
if(bmpMask)
|
||||
|
@ -372,8 +487,6 @@ IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle, BOOL Rem
|
|||
GDIOBJ_SetOwnership(bmpColor, PsGetCurrentProcess());
|
||||
NtGdiDeleteObject(bmpColor);
|
||||
}
|
||||
|
||||
ObmDereferenceObject(Object);
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
@ -382,23 +495,50 @@ VOID FASTCALL
|
|||
IntCleanupCurIcons(struct _EPROCESS *Process, PW32PROCESS Win32Process)
|
||||
{
|
||||
PWINSTATION_OBJECT WinStaObject;
|
||||
PCURICON_OBJECT Current;
|
||||
PLIST_ENTRY CurrentEntry, NextEntry;
|
||||
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PCURICON_OBJECT Object;
|
||||
PLIST_ENTRY ProcessEntry;
|
||||
PCURICON_PROCESS ProcessData;
|
||||
|
||||
WinStaObject = IntGetWinStaObj();
|
||||
if(WinStaObject != NULL)
|
||||
if(WinStaObject == NULL)
|
||||
{
|
||||
CurrentEntry = Win32Process->CursorIconListHead.Flink;
|
||||
while(CurrentEntry != &Win32Process->CursorIconListHead)
|
||||
{
|
||||
NextEntry = CurrentEntry->Flink;
|
||||
Current = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
||||
RemoveEntryList(&Current->ListEntry);
|
||||
IntDestroyCurIconObject(WinStaObject, Current->Self, FALSE);
|
||||
CurrentEntry = NextEntry;
|
||||
}
|
||||
ObDereferenceObject(WinStaObject);
|
||||
return;
|
||||
}
|
||||
|
||||
ExAcquireFastMutex(&CurIconListLock);
|
||||
|
||||
CurrentEntry = CurIconList.Flink;
|
||||
while (CurrentEntry != &CurIconList)
|
||||
{
|
||||
Object = CONTAINING_RECORD(CurrentEntry, CURICON_OBJECT, ListEntry);
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
if(NT_SUCCESS(ObmReferenceObjectByPointer(Object, otCursorIcon)))
|
||||
{
|
||||
ExAcquireFastMutex(&Object->Lock);
|
||||
ProcessEntry = Object->ProcessList.Flink;
|
||||
while (ProcessEntry != &Object->ProcessList)
|
||||
{
|
||||
ProcessData = CONTAINING_RECORD(ProcessEntry, CURICON_PROCESS, ListEntry);
|
||||
if (Win32Process == ProcessData->Process)
|
||||
{
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
RemoveEntryList(&Object->ListEntry);
|
||||
IntDestroyCurIconObject(WinStaObject, Object, TRUE);
|
||||
break;
|
||||
}
|
||||
ProcessEntry = ProcessEntry->Flink;
|
||||
}
|
||||
if (ProcessEntry == &Object->ProcessList)
|
||||
{
|
||||
ExReleaseFastMutex(&Object->Lock);
|
||||
}
|
||||
ObmDereferenceObject(Object);
|
||||
}
|
||||
}
|
||||
|
||||
ExReleaseFastMutex(&CurIconListLock);
|
||||
ObDereferenceObject(WinStaObject);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -729,6 +869,8 @@ NtUserDestroyCursorIcon(
|
|||
DWORD Unknown)
|
||||
{
|
||||
PWINSTATION_OBJECT WinStaObject;
|
||||
PCURICON_OBJECT Object;
|
||||
NTSTATUS Status;
|
||||
|
||||
WinStaObject = IntGetWinStaObj();
|
||||
if(WinStaObject == NULL)
|
||||
|
@ -736,14 +878,24 @@ NtUserDestroyCursorIcon(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if(IntDestroyCurIconObject(WinStaObject, Handle, TRUE))
|
||||
Status = ObmReferenceObjectByHandle(WinStaObject->HandleTable, Handle, otCursorIcon, (PVOID*)&Object);
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(WinStaObject);
|
||||
SetLastNtError(Status);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(IntDestroyCurIconObject(WinStaObject, Object, FALSE))
|
||||
{
|
||||
ObmDereferenceObject(Object);
|
||||
ObDereferenceObject(WinStaObject);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
||||
ObmDereferenceObject(Object);
|
||||
ObDereferenceObject(WinStaObject);
|
||||
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue