changed handle management of cursors/icons

svn path=/trunk/; revision=6934
This commit is contained in:
Thomas Bluemel 2003-12-09 19:34:33 +00:00
parent 6bb203a698
commit d7faa0cc7a
4 changed files with 83 additions and 217 deletions

View file

@ -17,14 +17,6 @@ typedef struct _CURSORCLIP_INFO
UINT Bottom; UINT Bottom;
} CURSORCLIP_INFO, *PCURSORCLIP_INFO; } CURSORCLIP_INFO, *PCURSORCLIP_INFO;
typedef struct _CURICONS
{
FAST_MUTEX LockHandles;
PVOID Handles;
PVOID Objects;
UINT Count;
} CURICONS, *PCURICONS;
typedef struct _SYSTEM_CURSORINFO typedef struct _SYSTEM_CURSORINFO
{ {
BOOL Enabled; BOOL Enabled;
@ -34,7 +26,7 @@ typedef struct _SYSTEM_CURSORINFO
BOOL SafetySwitch, SafetySwitch2; BOOL SafetySwitch, SafetySwitch2;
FAST_MUTEX CursorMutex; FAST_MUTEX CursorMutex;
CURSORCLIP_INFO CursorClipInfo; CURSORCLIP_INFO CursorClipInfo;
CURICONS CurIcons; PVOID CurIconHandleTable;
PVOID CurrentCursorObject; PVOID CurrentCursorObject;
BYTE ShowingCursor; BYTE ShowingCursor;
UINT DblClickSpeed; UINT DblClickSpeed;

View file

@ -5,7 +5,7 @@
typedef struct _CURICON_OBJECT typedef struct _CURICON_OBJECT
{ {
HICON Handle; HANDLE Handle;
PW32PROCESS Process; PW32PROCESS Process;
HMODULE hModule; HMODULE hModule;
HRSRC hRsrc; HRSRC hRsrc;
@ -17,8 +17,8 @@ typedef struct _CURICON_OBJECT
HCURSOR FASTCALL IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange); HCURSOR FASTCALL IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL ForceChange);
BOOL FASTCALL IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject); BOOL FASTCALL IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject);
PCURICON_OBJECT FASTCALL IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HICON hIcon); PCURICON_OBJECT FASTCALL IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle);
VOID FASTCALL IntReleaseCurIconObject(PWINSTATION_OBJECT WinStaObject); VOID FASTCALL IntReleaseCurIconObject(PCURICON_OBJECT Object);
PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject); PCURICON_OBJECT FASTCALL IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject);
#endif /* _WIN32K_CURSORICON_H */ #endif /* _WIN32K_CURSORICON_H */

View file

@ -12,6 +12,7 @@ typedef enum {
otWindow, otWindow,
otMenu, otMenu,
otAcceleratorTable, otAcceleratorTable,
otCursorIcon
} USER_OBJECT_TYPE; } USER_OBJECT_TYPE;
typedef struct _USER_OBJECT_HEADER typedef struct _USER_OBJECT_HEADER

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: cursoricon.c,v 1.29 2003/12/08 22:51:11 gvg Exp $ */ /* $Id: cursoricon.c,v 1.30 2003/12/09 19:34:33 weiden Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
@ -44,6 +44,28 @@
#define NDEBUG #define NDEBUG
#include <win32k/debug1.h> #include <win32k/debug1.h>
PCURICON_OBJECT FASTCALL
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
{
PCURICON_OBJECT Object;
PUSER_HANDLE_TABLE HandleTable;
HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
if(!NT_SUCCESS(ObmReferenceObjectByHandle(HandleTable, Handle, otCursorIcon,
(PVOID*)&Object)))
{
return FALSE;
}
return Object;
}
VOID FASTCALL
IntReleaseCurIconObject(PCURICON_OBJECT Object)
{
ObmDereferenceObject(Object);
}
HBITMAP FASTCALL HBITMAP FASTCALL
IntCopyBitmap(HBITMAP bmp) IntCopyBitmap(HBITMAP bmp)
{ {
@ -199,239 +221,92 @@ IntSetCursor(PWINSTATION_OBJECT WinStaObject, PCURICON_OBJECT NewCursor, BOOL Fo
BOOL FASTCALL BOOL FASTCALL
IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject) IntSetupCurIconHandles(PWINSTATION_OBJECT WinStaObject)
{ {
PCURICONS Cursors; if((WinStaObject->SystemCursor.CurIconHandleTable = (PVOID)ObmCreateHandleTable()))
Cursors = &WinStaObject->SystemCursor.CurIcons;
ExInitializeFastMutex(&Cursors->LockHandles);
Cursors->Handles = ExAllocatePool(NonPagedPool, 2 * MAXCURICONHANDLES * sizeof(PCURICON_OBJECT));
if(Cursors->Handles)
{ {
RtlZeroMemory(Cursors->Handles, 2 * MAXCURICONHANDLES * sizeof(PCURICON_OBJECT)); ObmInitializeHandleTable((PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable);
Cursors->Objects = (PVOID)(Cursors->Handles + MAXCURICONHANDLES);
} }
else return (WinStaObject->SystemCursor.CurIconHandleTable != NULL);
Cursors->Objects = NULL;
Cursors->Count = 0;
return (Cursors->Handles != NULL);
}
PVOID FASTCALL
IntFindFreeHandleSlot(PCURICONS Cursors, UINT *Index)
{
UINT i;
PVOID *CurIconObject = Cursors->Handles;
if(Cursors->Count >= MAXCURICONHANDLES)
{
return NULL;
}
for(i = 0; i <= MAXCURICONHANDLES; i++)
{
CurIconObject++;
if(*CurIconObject == NULL)
{
*Index = i;
return CurIconObject;
}
}
return NULL;
}
PCURICON_OBJECT FASTCALL
IntFindByHandle(PCURICONS Cursors, HICON hIcon)
{
UINT i, c = 0;
PVOID *CurIconObject, *Objects;
if(!hIcon)
return NULL;
CurIconObject = Cursors->Handles;
Objects = Cursors->Objects;
for(i = 0; i <= MAXCURICONHANDLES; i++)
{
CurIconObject++;
if(*CurIconObject == hIcon)
{
return (PCURICON_OBJECT)(*(Objects + i));
}
if(*CurIconObject)
{
/* no more handles */
if(++c >= Cursors->Count)
return NULL;
}
}
return NULL;
}
PCURICON_OBJECT FASTCALL
IntGetCurIconObject(PWINSTATION_OBJECT WinStaObject, HICON hIcon)
{
PCURICONS Cursors;
PCURICON_OBJECT CurIconObject = NULL;
Cursors = &WinStaObject->SystemCursor.CurIcons;
ExAcquireFastMutex(&Cursors->LockHandles);
CurIconObject = IntFindByHandle(Cursors, hIcon);
if(!CurIconObject)
ExReleaseFastMutex(&Cursors->LockHandles);
return CurIconObject;
} }
PCURICON_OBJECT FASTCALL PCURICON_OBJECT FASTCALL
IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule, IntFindExistingCurIconObject(PWINSTATION_OBJECT WinStaObject, HMODULE hModule,
HRSRC hRsrc) HRSRC hRsrc)
{ {
UINT i, c = 0; PUSER_HANDLE_TABLE HandleTable;
PVOID *Objects; PLIST_ENTRY CurrentEntry;
PCURICON_OBJECT Obj; PUSER_HANDLE_BLOCK Current;
PCURICONS Cursors = &WinStaObject->SystemCursor.CurIcons; PCURICON_OBJECT Object;
ULONG i;
Objects = Cursors->Objects; HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
ExAcquireFastMutex(&HandleTable->ListLock);
ExAcquireFastMutex(&Cursors->LockHandles); CurrentEntry = HandleTable->ListHead.Flink;
while(CurrentEntry != &HandleTable->ListHead)
for(i = 0; i <= MAXCURICONHANDLES; i++)
{ {
Obj = (PCURICON_OBJECT)(*Objects); Current = CONTAINING_RECORD(CurrentEntry, USER_HANDLE_BLOCK, ListEntry);
if(Obj) for(i = 0; i < HANDLE_BLOCK_ENTRIES; i++)
{ {
if((Obj->hModule == hModule) && (Obj->hRsrc == hRsrc)) Object = (PCURICON_OBJECT)Current->Handles[i].ObjectBody;
if(Object && (Object->hModule == hModule) && (Object->hRsrc == hRsrc))
{ {
return Obj; ExReleaseFastMutex(&HandleTable->ListLock);
} return Object;
/* no more handles */
if(++c > Cursors->Count)
{
ExReleaseFastMutex(&Cursors->LockHandles);
return NULL;
} }
} }
Objects++;
} }
ExReleaseFastMutex(&Cursors->LockHandles); ExReleaseFastMutex(&HandleTable->ListLock);
return NULL; return NULL;
} }
VOID FASTCALL
IntReleaseCurIconObject(PWINSTATION_OBJECT WinStaObject)
{
ExReleaseFastMutex(&WinStaObject->SystemCursor.CurIcons.LockHandles);
}
PCURICON_OBJECT FASTCALL PCURICON_OBJECT FASTCALL
IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject) IntCreateCurIconHandle(PWINSTATION_OBJECT WinStaObject)
{ {
PCURICONS Cursors; PUSER_HANDLE_TABLE HandleTable;
PVOID *Handle, *Objects; PCURICON_OBJECT Object;
UINT i; HANDLE Handle;
PCURICON_OBJECT CurIconObject = NULL;
Cursors = &WinStaObject->SystemCursor.CurIcons; HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
ExAcquireFastMutex(&Cursors->LockHandles); Object = ObmCreateObject(HandleTable, &Handle, otCursorIcon, sizeof(CURICON_OBJECT));
Handle = IntFindFreeHandleSlot(Cursors, &i); if(!Object)
if(!Handle)
{ {
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY); SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL; return FALSE;
} }
/* create a new handle */ Object->Handle = Handle;
CurIconObject = ExAllocatePool(NonPagedPool, sizeof(CURICON_OBJECT)); Object->Process = PsGetWin32Process();
if(!CurIconObject)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
RtlZeroMemory(CurIconObject, sizeof(CURICON_OBJECT));
CurIconObject->Handle = (HICON)(i + 1); return Object;
CurIconObject->Process = PsGetWin32Process();
Objects = Cursors->Objects;
*Handle = (PVOID)CurIconObject->Handle;
*(Objects + i) = (PVOID)CurIconObject;
Cursors->Count++;
return CurIconObject;
} }
BOOL FASTCALL BOOL FASTCALL
IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HCURSOR hCursor) IntDestroyCurIconObject(PWINSTATION_OBJECT WinStaObject, HANDLE Handle)
{ {
UINT i, c = 0; PUSER_HANDLE_TABLE HandleTable;
PVOID *CurIconObject, *Objects; PCURICON_OBJECT Object;
PCURICON_OBJECT Cursor; NTSTATUS Status;
PSYSTEM_CURSORINFO CurInfo;
if(!hCursor) HandleTable = (PUSER_HANDLE_TABLE)WinStaObject->SystemCursor.CurIconHandleTable;
return FALSE;
CurInfo = &WinStaObject->SystemCursor; Status = ObmReferenceObjectByHandle(HandleTable, Handle, otCursorIcon, (PVOID*)&Object);
ExAcquireFastMutex(&CurInfo->CurIcons.LockHandles); if(!NT_SUCCESS(Status))
CurIconObject = CurInfo->CurIcons.Handles;
Objects = CurInfo->CurIcons.Objects;
for(i = 0; i <= MAXCURICONHANDLES; i++)
{ {
CurIconObject++; return FALSE;
if(*CurIconObject == hCursor)
{
Cursor = (PCURICON_OBJECT)(*(Objects + i));
if(CurInfo->CurrentCursorObject == Cursor)
{
IntSetCursor(WinStaObject, NULL, FALSE);
CurInfo->CurrentCursorObject = NULL;
}
/* remove from table */
*CurIconObject = NULL;
*(Objects + i) = NULL;
CurInfo->CurIcons.Count--;
/* free bitmaps */
if(Cursor->IconInfo.hbmMask)
NtGdiDeleteObject(Cursor->IconInfo.hbmMask);
if(Cursor->IconInfo.hbmColor)
NtGdiDeleteObject(Cursor->IconInfo.hbmColor);
/* free object */
ExFreePool(Cursor);
ExReleaseFastMutex(&CurInfo->CurIcons.LockHandles);
return TRUE;
}
if(*CurIconObject)
{
/* no more handles */
if(++c >= CurInfo->CurIcons.Count)
{
ExReleaseFastMutex(&CurInfo->CurIcons.LockHandles);
return FALSE;
}
}
} }
ExReleaseFastMutex(&CurInfo->CurIcons.LockHandles); /* Delete the bitmaps */
return FALSE; if(Object->IconInfo.hbmMask)
NtGdiDeleteObject(Object->IconInfo.hbmMask);
if(Object->IconInfo.hbmColor)
NtGdiDeleteObject(Object->IconInfo.hbmColor);
ObmDereferenceObject(Object);
return NT_SUCCESS(ObmCloseHandle(HandleTable, Handle));
} }
/* /*
@ -498,7 +373,7 @@ NtUserCreateCursorIconHandle(PICONINFO IconInfo, BOOL Indirect)
} }
} }
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -557,7 +432,7 @@ NtUserGetIconInfo(
SetLastWin32Error(ERROR_INVALID_PARAMETER); SetLastWin32Error(ERROR_INVALID_PARAMETER);
} }
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -619,7 +494,7 @@ NtUserGetIconSize(
BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor); BITMAPOBJ_UnlockBitmap(CurIconObject->IconInfo.hbmColor);
done: done:
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -830,7 +705,7 @@ NtUserFindExistingCursorIcon(
{ {
Ret = CurIconObject->Handle; Ret = CurIconObject->Handle;
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -926,7 +801,7 @@ NtUserSetCursor(
if(CurIconObject) if(CurIconObject)
{ {
OldCursor = IntSetCursor(WinStaObject, CurIconObject, FALSE); OldCursor = IntSetCursor(WinStaObject, CurIconObject, FALSE);
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
} }
else else
SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE); SetLastWin32Error(ERROR_INVALID_CURSOR_HANDLE);
@ -995,7 +870,7 @@ NtUserSetCursorIconContents(
Ret = TRUE; Ret = TRUE;
done: done:
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -1082,7 +957,7 @@ NtUserSetCursorIconData(
} }
done: done:
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
ObDereferenceObject(WinStaObject); ObDereferenceObject(WinStaObject);
return Ret; return Ret;
} }
@ -1102,9 +977,7 @@ NtUserSetSystemCursor(
HCURSOR hcur, HCURSOR hcur,
DWORD id) DWORD id)
{ {
BOOL res = FALSE; return FALSE;
return res;
} }
@ -1159,7 +1032,7 @@ NtUserDrawIconEx(
{ {
hbmMask = CurIconObject->IconInfo.hbmMask; hbmMask = CurIconObject->IconInfo.hbmMask;
hbmColor = CurIconObject->IconInfo.hbmColor; hbmColor = CurIconObject->IconInfo.hbmColor;
IntReleaseCurIconObject(WinStaObject); IntReleaseCurIconObject(CurIconObject);
if(istepIfAniCur) if(istepIfAniCur)
DbgPrint("NtUserDrawIconEx: istepIfAniCur is not supported!\n"); DbgPrint("NtUserDrawIconEx: istepIfAniCur is not supported!\n");