mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[USER32]
- Implement LookupIconIdFromDirectoryEx. - Implement CopyImage - Finish Implementing LoadImage - Implement various functions. [WIN32SS] - Add a first working implementation for LR_SHARED cursors and icons.User32 support is there, but more work is needed in win32k. svn path=/trunk/; revision=57672
This commit is contained in:
parent
db13cd87ac
commit
4a467211be
10 changed files with 1495 additions and 390 deletions
|
@ -11,6 +11,10 @@ if(USE_DIBLIB)
|
||||||
add_subdirectory(gdi/diblib)
|
add_subdirectory(gdi/diblib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(USE_NEW_CURSORICON)
|
||||||
|
add_definitions(-DNEW_CURSORICON)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(gdi/gdi32)
|
add_subdirectory(gdi/gdi32)
|
||||||
add_subdirectory(reactx)
|
add_subdirectory(reactx)
|
||||||
add_subdirectory(user/user32)
|
add_subdirectory(user/user32)
|
||||||
|
@ -190,7 +194,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(USE_NEW_CURSORICON)
|
if(USE_NEW_CURSORICON)
|
||||||
add_definitions(-DNEW_CURSORICON)
|
|
||||||
list(APPEND SOURCE user/ntuser/cursoricon_new.c)
|
list(APPEND SOURCE user/ntuser/cursoricon_new.c)
|
||||||
else()
|
else()
|
||||||
list(APPEND SOURCE user/ntuser/cursoricon.c)
|
list(APPEND SOURCE user/ntuser/cursoricon.c)
|
||||||
|
|
|
@ -1659,8 +1659,8 @@ NtUserDestroyAcceleratorTable(
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserDestroyCursor(
|
NtUserDestroyCursor(
|
||||||
HANDLE Handle,
|
_In_ HANDLE Handle,
|
||||||
DWORD Unknown);
|
_In_ BOOL bForce);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1818,14 +1818,6 @@ NtUserFillWindow(
|
||||||
HDC hDC,
|
HDC hDC,
|
||||||
HBRUSH hBrush);
|
HBRUSH hBrush);
|
||||||
|
|
||||||
HICON
|
|
||||||
NTAPI
|
|
||||||
NtUserFindExistingCursorIcon(
|
|
||||||
HMODULE hModule,
|
|
||||||
HRSRC hRsrc,
|
|
||||||
LONG cx,
|
|
||||||
LONG cy);
|
|
||||||
|
|
||||||
HWND
|
HWND
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserFindWindowEx(
|
NtUserFindWindowEx(
|
||||||
|
@ -1998,12 +1990,12 @@ NtUserGetGUIThreadInfo(
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserGetIconInfo(
|
NtUserGetIconInfo(
|
||||||
HANDLE hCurIcon,
|
_In_ HANDLE hCurIcon,
|
||||||
PICONINFO IconInfo,
|
_Out_opt_ PICONINFO IconInfo,
|
||||||
PUNICODE_STRING lpInstName,
|
_Out_opt_ PUNICODE_STRING lpInstName,
|
||||||
PUNICODE_STRING lpResName,
|
_Out_opt_ PUNICODE_STRING lpResName,
|
||||||
LPDWORD pbpp,
|
_Out_opt_ LPDWORD pbpp,
|
||||||
BOOL bInternal);
|
_In_ BOOL bInternal);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -2743,9 +2735,17 @@ BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserSetCursorIconData(
|
NtUserSetCursorIconData(
|
||||||
_In_ HCURSOR hCursor,
|
_In_ HCURSOR hCursor,
|
||||||
_In_ HINSTANCE hinst,
|
_In_ PUNICODE_STRING pustrModule,
|
||||||
_In_ HRSRC hrsrc,
|
_In_ PUNICODE_STRING puSrcName,
|
||||||
_In_ PICONINFO pii);
|
_In_ PICONINFO pii);
|
||||||
|
|
||||||
|
HICON
|
||||||
|
NTAPI
|
||||||
|
NtUserFindExistingCursorIcon(
|
||||||
|
_In_ PUNICODE_STRING pustrModule,
|
||||||
|
_In_ PUNICODE_STRING pustrRsrc,
|
||||||
|
_In_ LONG cxDesired,
|
||||||
|
_In_ LONG cyDesired);
|
||||||
#else
|
#else
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -2756,6 +2756,14 @@ NtUserSetCursorIconData(
|
||||||
HMODULE hModule,
|
HMODULE hModule,
|
||||||
HRSRC hRsrc,
|
HRSRC hRsrc,
|
||||||
HRSRC hGroupRsrc);
|
HRSRC hGroupRsrc);
|
||||||
|
|
||||||
|
HICON
|
||||||
|
NTAPI
|
||||||
|
NtUserFindExistingCursorIcon(
|
||||||
|
HMODULE hModule,
|
||||||
|
HRSRC hRsrc,
|
||||||
|
LONG cx,
|
||||||
|
LONG cy);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
|
|
|
@ -88,8 +88,9 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{ union
|
{ union
|
||||||
{ ICONRESDIR icon;
|
{
|
||||||
CURSORDIR cursor;
|
ICONRESDIR icon;
|
||||||
|
CURSORDIR cursor;
|
||||||
} ResInfo;
|
} ResInfo;
|
||||||
WORD wPlanes;
|
WORD wPlanes;
|
||||||
WORD wBitCount;
|
WORD wBitCount;
|
||||||
|
|
|
@ -124,7 +124,7 @@ LookupFnIdToiCls(int FnId, int *iCls )
|
||||||
_Must_inspect_result_
|
_Must_inspect_result_
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
CaptureUnicodeStringOrAtom(
|
ProbeAndCaptureUnicodeStringOrAtom(
|
||||||
_Out_ PUNICODE_STRING pustrOut,
|
_Out_ PUNICODE_STRING pustrOut,
|
||||||
__in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
|
__in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
|
||||||
{
|
{
|
||||||
|
@ -2294,7 +2294,7 @@ NtUserUnregisterClass(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL Ret;
|
BOOL Ret;
|
||||||
|
|
||||||
Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassNameOrAtom);
|
Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassNameOrAtom);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Error capturing the class name\n");
|
ERR("Error capturing the class name\n");
|
||||||
|
@ -2346,7 +2346,7 @@ NtUserGetClassInfo(
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
_SEH2_END;
|
||||||
|
|
||||||
Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
|
Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Error capturing the class name\n");
|
ERR("Error capturing the class name\n");
|
||||||
|
@ -2480,7 +2480,7 @@ NtUserGetWOWClass(
|
||||||
RTL_ATOM ClassAtom = 0;
|
RTL_ATOM ClassAtom = 0;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = CaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
|
Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ERR("Error capturing the class name\n");
|
ERR("Error capturing the class name\n");
|
||||||
|
|
|
@ -59,4 +59,11 @@ IntCheckProcessDesktopClasses(IN PDESKTOP Desktop,
|
||||||
|
|
||||||
ULONG_PTR FASTCALL UserGetCPD(PVOID,GETCPD,ULONG_PTR);
|
ULONG_PTR FASTCALL UserGetCPD(PVOID,GETCPD,ULONG_PTR);
|
||||||
|
|
||||||
|
_Must_inspect_result_
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ProbeAndCaptureUnicodeStringOrAtom(
|
||||||
|
_Out_ PUNICODE_STRING pustrOut,
|
||||||
|
__in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe);
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -204,7 +204,7 @@ IntFindExistingCurIconObject(HMODULE hModule,
|
||||||
}
|
}
|
||||||
|
|
||||||
PCURICON_OBJECT
|
PCURICON_OBJECT
|
||||||
IntCreateCurIconHandle()
|
IntCreateCurIconHandle(DWORD dwNumber)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
HANDLE hCurIcon;
|
HANDLE hCurIcon;
|
||||||
|
@ -613,8 +613,8 @@ NtUserClipCursor(
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserDestroyCursor(
|
NtUserDestroyCursor(
|
||||||
HANDLE hCurIcon,
|
_In_ HANDLE hCurIcon,
|
||||||
DWORD Unknown)
|
_In_ BOOL bForce)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
|
@ -22,8 +22,8 @@ typedef struct _CURICON_OBJECT
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
HANDLE Self;
|
HANDLE Self;
|
||||||
LIST_ENTRY ProcessList;
|
LIST_ENTRY ProcessList;
|
||||||
HMODULE hModule;
|
UNICODE_STRING ustrModule;
|
||||||
HRSRC hRsrc;
|
UNICODE_STRING ustrRsrc;
|
||||||
SIZE Size;
|
SIZE Size;
|
||||||
BYTE Shadow;
|
BYTE Shadow;
|
||||||
BOOL bIcon;
|
BOOL bIcon;
|
||||||
|
@ -88,7 +88,7 @@ typedef struct _SYSTEM_CURSORINFO
|
||||||
} SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO;
|
} SYSTEM_CURSORINFO, *PSYSTEM_CURSORINFO;
|
||||||
|
|
||||||
BOOL InitCursorImpl(VOID);
|
BOOL InitCursorImpl(VOID);
|
||||||
PCURICON_OBJECT IntCreateCurIconHandle(VOID);
|
PCURICON_OBJECT IntCreateCurIconHandle(DWORD dwNumber);
|
||||||
VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process);
|
VOID FASTCALL IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process);
|
||||||
|
|
||||||
BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth,
|
BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth,
|
||||||
|
|
|
@ -169,47 +169,59 @@ ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCURICON_OBJECT FASTCALL
|
static
|
||||||
IntFindExistingCurIconObject(HMODULE hModule,
|
PCURICON_OBJECT
|
||||||
HRSRC hRsrc, LONG cx, LONG cy)
|
FASTCALL
|
||||||
|
IntFindExistingCurIconObject(
|
||||||
|
PUNICODE_STRING pustrModule,
|
||||||
|
PUNICODE_STRING pustrRsrc,
|
||||||
|
LONG cxDesired,
|
||||||
|
LONG cyDesired)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
|
|
||||||
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
|
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
|
||||||
{
|
{
|
||||||
|
/* See if module names match */
|
||||||
// if (NT_SUCCESS(UserReferenceObjectByPointer(Object, otCursorIcon))) // <- huh????
|
if(RtlCompareUnicodeString(pustrModule, &CurIcon->ustrModule, TRUE) == 0)
|
||||||
// UserReferenceObject( CurIcon);
|
|
||||||
// {
|
|
||||||
if ((CurIcon->hModule == hModule) && (CurIcon->hRsrc == hRsrc))
|
|
||||||
{
|
{
|
||||||
if (cx && ((cx != CurIcon->Size.cx) || (cy != CurIcon->Size.cy)))
|
/* They do. Now see if this is the same resource */
|
||||||
|
if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) && IS_INTRESOURCE(pustrRsrc->Buffer))
|
||||||
{
|
{
|
||||||
// UserDereferenceObject(CurIcon);
|
if(CurIcon->ustrRsrc.Buffer != pustrRsrc->Buffer)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer) || IS_INTRESOURCE(pustrRsrc->Buffer))
|
||||||
continue;
|
continue;
|
||||||
}
|
else if(RtlCompareUnicodeString(pustrRsrc, &CurIcon->ustrRsrc, TRUE) != 0)
|
||||||
if (! ReferenceCurIconByProcess(CurIcon))
|
continue;
|
||||||
|
|
||||||
|
if ((cxDesired == CurIcon->Size.cx) &&(cyDesired == CurIcon->Size.cy))
|
||||||
{
|
{
|
||||||
return NULL;
|
if (! ReferenceCurIconByProcess(CurIcon))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return CurIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CurIcon;
|
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
// UserDereferenceObject(CurIcon);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PCURICON_OBJECT
|
PCURICON_OBJECT
|
||||||
IntCreateCurIconHandle()
|
IntCreateCurIconHandle(DWORD dwNumber)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
|
BOOLEAN bIcon = dwNumber == 0;
|
||||||
HANDLE hCurIcon;
|
HANDLE hCurIcon;
|
||||||
|
|
||||||
|
if(dwNumber == 0)
|
||||||
|
dwNumber = 1;
|
||||||
|
|
||||||
CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
|
CurIcon = UserCreateObject(gHandleTable, NULL, NULL, &hCurIcon, otCursorIcon, FIELD_OFFSET(CURICON_OBJECT, aFrame[dwNumber]));
|
||||||
|
|
||||||
if (!CurIcon)
|
if (!CurIcon)
|
||||||
{
|
{
|
||||||
|
@ -218,6 +230,7 @@ IntCreateCurIconHandle()
|
||||||
}
|
}
|
||||||
|
|
||||||
CurIcon->Self = hCurIcon;
|
CurIcon->Self = hCurIcon;
|
||||||
|
CurIcon->bIcon = bIcon;
|
||||||
InitializeListHead(&CurIcon->ProcessList);
|
InitializeListHead(&CurIcon->ProcessList);
|
||||||
|
|
||||||
if (! ReferenceCurIconByProcess(CurIcon))
|
if (! ReferenceCurIconByProcess(CurIcon))
|
||||||
|
@ -234,7 +247,7 @@ IntCreateCurIconHandle()
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN FASTCALL
|
BOOLEAN FASTCALL
|
||||||
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
|
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi, BOOLEAN bForce)
|
||||||
{
|
{
|
||||||
PSYSTEM_CURSORINFO CurInfo;
|
PSYSTEM_CURSORINFO CurInfo;
|
||||||
HBITMAP bmpMask, bmpColor, bmpAlpha;
|
HBITMAP bmpMask, bmpColor, bmpAlpha;
|
||||||
|
@ -261,8 +274,18 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
|
||||||
{
|
{
|
||||||
/* This object doesn't belong to this process */
|
/* This object doesn't belong to this process */
|
||||||
EngSetLastError(ERROR_INVALID_HANDLE);
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
/* Caller expects us to dereference! */
|
||||||
|
UserDereferenceObject(CurIcon);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We found our process, but we're told to not destroy it in case it is shared */
|
||||||
|
if((CurIcon->ustrModule.Buffer != NULL) && !bForce)
|
||||||
|
{
|
||||||
|
/* Tests show this is a valid call */
|
||||||
|
UserDereferenceObject(CurIcon);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
|
ExFreeToPagedLookasideList(pgProcessLookasideList, Current);
|
||||||
|
|
||||||
|
@ -314,6 +337,11 @@ emptyList:
|
||||||
GreDeleteObject(bmpAlpha);
|
GreDeleteObject(bmpAlpha);
|
||||||
CurIcon->aFrame[0].hbmAlpha = NULL;
|
CurIcon->aFrame[0].hbmAlpha = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
|
||||||
|
ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
|
||||||
|
if(CurIcon->ustrModule.Buffer)
|
||||||
|
ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
|
||||||
|
|
||||||
/* We were given a pointer, no need to keep the reference anylonger! */
|
/* We were given a pointer, no need to keep the reference anylonger! */
|
||||||
UserDereferenceObject(CurIcon);
|
UserDereferenceObject(CurIcon);
|
||||||
|
@ -331,7 +359,7 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
|
||||||
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
LIST_FOR_EACH_SAFE(CurIcon, tmp, &gCurIconList, CURICON_OBJECT, ListEntry)
|
||||||
{
|
{
|
||||||
UserReferenceObject(CurIcon);
|
UserReferenceObject(CurIcon);
|
||||||
IntDestroyCurIconObject(CurIcon, Win32Process);
|
IntDestroyCurIconObject(CurIcon, Win32Process, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,12 +370,12 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserGetIconInfo(
|
NtUserGetIconInfo(
|
||||||
HANDLE hCurIcon,
|
_In_ HANDLE hCurIcon,
|
||||||
PICONINFO IconInfo,
|
_Out_opt_ PICONINFO IconInfo,
|
||||||
PUNICODE_STRING lpInstName, // Optional
|
_Out_opt_ PUNICODE_STRING lpModule, // Optional
|
||||||
PUNICODE_STRING lpResName, // Optional
|
_Out_opt_ PUNICODE_STRING lpResName, // Optional
|
||||||
LPDWORD pbpp, // Optional
|
_Out_opt_ LPDWORD pbpp, // Optional
|
||||||
BOOL bInternal)
|
_In_ BOOL bInternal)
|
||||||
{
|
{
|
||||||
ICONINFO ii;
|
ICONINFO ii;
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
|
@ -356,66 +384,145 @@ NtUserGetIconInfo(
|
||||||
DWORD colorBpp = 0;
|
DWORD colorBpp = 0;
|
||||||
|
|
||||||
TRACE("Enter NtUserGetIconInfo\n");
|
TRACE("Enter NtUserGetIconInfo\n");
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if (!IconInfo)
|
/* Check if something was actually asked */
|
||||||
|
if (!IconInfo && !lpModule && !lpResName)
|
||||||
{
|
{
|
||||||
|
WARN("Nothing to fill.\n");
|
||||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
goto leave;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UserEnterExclusive();
|
||||||
|
|
||||||
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
||||||
{
|
{
|
||||||
goto leave;
|
WARN("UserGetIconObject(0x%08x) Failed.\n", hCurIcon);
|
||||||
|
UserLeave();
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill data */
|
/* Give back the icon information */
|
||||||
ii.fIcon = CurIcon->bIcon;
|
if(IconInfo)
|
||||||
ii.xHotspot = CurIcon->ptlHotspot.x;
|
|
||||||
ii.yHotspot = CurIcon->ptlHotspot.y;
|
|
||||||
|
|
||||||
/* Copy bitmaps */
|
|
||||||
ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
|
|
||||||
ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
|
|
||||||
|
|
||||||
if (pbpp)
|
|
||||||
{
|
{
|
||||||
PSURFACE psurfBmp;
|
/* Fill data */
|
||||||
|
ii.fIcon = CurIcon->bIcon;
|
||||||
|
ii.xHotspot = CurIcon->ptlHotspot.x;
|
||||||
|
ii.yHotspot = CurIcon->ptlHotspot.y;
|
||||||
|
|
||||||
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
|
/* Copy bitmaps */
|
||||||
if (psurfBmp)
|
ii.hbmMask = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmMask);
|
||||||
{
|
GreSetObjectOwner(ii.hbmMask, GDI_OBJ_HMGR_POWNED);
|
||||||
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
|
ii.hbmColor = BITMAP_CopyBitmap(CurIcon->aFrame[0].hbmColor);
|
||||||
SURFACE_ShareUnlockSurface(psurfBmp);
|
GreSetObjectOwner(ii.hbmColor, GDI_OBJ_HMGR_POWNED);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Copy fields */
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
|
|
||||||
RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
|
|
||||||
|
|
||||||
if (pbpp)
|
if (pbpp)
|
||||||
{
|
{
|
||||||
ProbeForWrite(pbpp, sizeof(DWORD), 1);
|
PSURFACE psurfBmp;
|
||||||
*pbpp = colorBpp;
|
|
||||||
|
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
|
||||||
|
if (psurfBmp)
|
||||||
|
{
|
||||||
|
colorBpp = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
|
||||||
|
SURFACE_ShareUnlockSurface(psurfBmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Copy fields */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(IconInfo, sizeof(ICONINFO), 1);
|
||||||
|
RtlCopyMemory(IconInfo, &ii, sizeof(ICONINFO));
|
||||||
|
|
||||||
|
if (pbpp)
|
||||||
|
{
|
||||||
|
ProbeForWrite(pbpp, sizeof(DWORD), 1);
|
||||||
|
*pbpp = colorBpp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = _SEH2_GetExceptionCode();
|
WARN("Status: 0x%08x.\n", Status);
|
||||||
}
|
|
||||||
_SEH2_END
|
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
|
||||||
Ret = TRUE;
|
|
||||||
else
|
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
UserDereferenceObject(CurIcon);
|
/* Give back the module name */
|
||||||
|
if(lpModule)
|
||||||
|
{
|
||||||
|
if(!CurIcon->ustrModule.Buffer)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
/* Copy what we can */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(lpModule, sizeof(UNICODE_STRING), 1);
|
||||||
|
ProbeForWrite(lpModule->Buffer, lpModule->MaximumLength, 1);
|
||||||
|
lpModule->Length = min(lpModule->MaximumLength, CurIcon->ustrModule.Length);
|
||||||
|
RtlCopyMemory(lpModule->Buffer, CurIcon->ustrModule.Buffer, lpModule->Length);
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lpResName)
|
||||||
|
{
|
||||||
|
if(!CurIcon->ustrRsrc.Buffer)
|
||||||
|
{
|
||||||
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
/* Copy it */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(lpResName, sizeof(UNICODE_STRING), 1);
|
||||||
|
if(IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
|
||||||
|
{
|
||||||
|
lpResName->Buffer = CurIcon->ustrRsrc.Buffer;
|
||||||
|
lpResName->Length = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpResName->Length = min(lpResName->MaximumLength, CurIcon->ustrRsrc.Length);
|
||||||
|
RtlCopyMemory(lpResName->Buffer, CurIcon->ustrRsrc.Buffer, lpResName->Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = TRUE;
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
|
UserDereferenceObject(CurIcon);
|
||||||
|
|
||||||
TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret);
|
TRACE("Leave NtUserGetIconInfo, ret=%i\n", Ret);
|
||||||
UserLeave();
|
UserLeave();
|
||||||
|
|
||||||
|
@ -623,8 +730,8 @@ NtUserClipCursor(
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserDestroyCursor(
|
NtUserDestroyCursor(
|
||||||
HANDLE hCurIcon,
|
_In_ HANDLE hCurIcon,
|
||||||
DWORD Unknown)
|
_In_ BOOL bForce)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -638,7 +745,7 @@ NtUserDestroyCursor(
|
||||||
RETURN(FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
|
ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process(), bForce);
|
||||||
/* Note: IntDestroyCurIconObject will remove our reference for us! */
|
/* Note: IntDestroyCurIconObject will remove our reference for us! */
|
||||||
|
|
||||||
RETURN(ret);
|
RETURN(ret);
|
||||||
|
@ -654,36 +761,40 @@ CLEANUP:
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HICON
|
HICON
|
||||||
APIENTRY
|
NTAPI
|
||||||
NtUserFindExistingCursorIcon(
|
NtUserFindExistingCursorIcon(
|
||||||
HMODULE hModule,
|
_In_ PUNICODE_STRING pustrModule,
|
||||||
HRSRC hRsrc,
|
_In_ PUNICODE_STRING pustrRsrc,
|
||||||
LONG cx,
|
_In_ LONG cxDesired,
|
||||||
LONG cy)
|
_In_ LONG cyDesired)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
HANDLE Ret = (HANDLE)0;
|
HICON Ret = NULL;
|
||||||
DECLARE_RETURN(HICON);
|
UNICODE_STRING ustrModuleSafe, ustrRsrcSafe;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
TRACE("Enter NtUserFindExistingCursorIcon\n");
|
TRACE("Enter NtUserFindExistingCursorIcon\n");
|
||||||
|
|
||||||
|
/* Capture resource name (it can be an INTRESOURCE == ATOM) */
|
||||||
|
Status = ProbeAndCaptureUnicodeStringOrAtom(&ustrRsrcSafe, pustrRsrc);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
return NULL;
|
||||||
|
Status = ProbeAndCaptureUnicodeString(&ustrModuleSafe, UserMode, pustrModule);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
CurIcon = IntFindExistingCurIconObject(&ustrModuleSafe, &ustrRsrcSafe, cxDesired, cyDesired);
|
||||||
CurIcon = IntFindExistingCurIconObject(hModule, hRsrc, cx, cy);
|
|
||||||
if (CurIcon)
|
if (CurIcon)
|
||||||
{
|
|
||||||
Ret = CurIcon->Self;
|
Ret = CurIcon->Self;
|
||||||
|
|
||||||
// IntReleaseCurIconObject(CurIcon); // FIXME: Is this correct? Does IntFindExistingCurIconObject add a ref?
|
|
||||||
RETURN(Ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
|
|
||||||
RETURN((HANDLE)0);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
TRACE("Leave NtUserFindExistingCursorIcon, ret=%p\n",_ret_);
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
END_CLEANUP;
|
|
||||||
|
done:
|
||||||
|
if(!IS_INTRESOURCE(ustrRsrcSafe.Buffer))
|
||||||
|
ExFreePoolWithTag(ustrRsrcSafe.Buffer, TAG_STRING);
|
||||||
|
ReleaseCapturedUnicodeString(&ustrModuleSafe, UserMode);
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -920,12 +1031,6 @@ NtUserSetCursorContents(
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if(!Ret)
|
|
||||||
{
|
|
||||||
IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
|
|
||||||
CurIcon = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CurIcon)
|
if (CurIcon)
|
||||||
{
|
{
|
||||||
UserDereferenceObject(CurIcon);
|
UserDereferenceObject(CurIcon);
|
||||||
|
@ -942,33 +1047,35 @@ CLEANUP:
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
#ifdef NEW_CURSORICON
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
NtUserSetCursorIconData(
|
NtUserSetCursorIconData(
|
||||||
_In_ HCURSOR Handle,
|
_In_ HCURSOR Handle,
|
||||||
_In_ HINSTANCE hinst,
|
_In_opt_ PUNICODE_STRING pustrModule,
|
||||||
_In_ HRSRC hrsrc,
|
_In_opt_ PUNICODE_STRING pustrRsrc,
|
||||||
_In_ PICONINFO pIconInfo)
|
_In_ PICONINFO pIconInfo)
|
||||||
{
|
{
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
PSURFACE psurfBmp;
|
PSURFACE psurfBmp;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
BOOL Ret = FALSE;
|
BOOL Ret = FALSE;
|
||||||
DECLARE_RETURN(BOOL);
|
|
||||||
ICONINFO ii;
|
ICONINFO ii;
|
||||||
|
|
||||||
TRACE("Enter NtUserSetCursorIconData\n");
|
TRACE("Enter NtUserSetCursorIconData\n");
|
||||||
|
|
||||||
|
/* If a module name is provided, we need a resource name, and vice versa */
|
||||||
|
if((pustrModule && !pustrRsrc) || (!pustrModule && pustrRsrc))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
if (!(CurIcon = UserGetCurIconObject(Handle)))
|
if (!(CurIcon = UserGetCurIconObject(Handle)))
|
||||||
{
|
{
|
||||||
RETURN(FALSE);
|
UserLeave();
|
||||||
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurIcon->hModule = hinst;
|
|
||||||
CurIcon->hRsrc =hrsrc;
|
|
||||||
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
|
ProbeForRead(pIconInfo, sizeof(ICONINFO), 1);
|
||||||
|
@ -1014,29 +1121,38 @@ NtUserSetCursorIconData(
|
||||||
|
|
||||||
if (CurIcon->aFrame[0].hbmColor)
|
if (CurIcon->aFrame[0].hbmColor)
|
||||||
{
|
{
|
||||||
if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor)))
|
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmColor);
|
||||||
{
|
if(!psurfBmp)
|
||||||
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
|
|
||||||
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
|
|
||||||
SURFACE_ShareUnlockSurface(psurfBmp);
|
|
||||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
|
||||||
|
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy;
|
||||||
|
SURFACE_ShareUnlockSurface(psurfBmp);
|
||||||
|
GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask)))
|
psurfBmp = SURFACE_ShareLockSurface(CurIcon->aFrame[0].hbmMask);
|
||||||
{
|
if(!psurfBmp)
|
||||||
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
|
|
||||||
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
|
|
||||||
SURFACE_ShareUnlockSurface(psurfBmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
CurIcon->Size.cx = psurfBmp->SurfObj.sizlBitmap.cx;
|
||||||
|
CurIcon->Size.cy = psurfBmp->SurfObj.sizlBitmap.cy/2;
|
||||||
|
SURFACE_ShareUnlockSurface(psurfBmp);
|
||||||
}
|
}
|
||||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
||||||
|
|
||||||
|
if(pustrModule)
|
||||||
|
{
|
||||||
|
/* We use this convenient function, because INTRESOURCEs and ATOMs are the same */
|
||||||
|
Status = ProbeAndCaptureUnicodeStringOrAtom(&CurIcon->ustrRsrc, pustrRsrc);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
Status = ProbeAndCaptureUnicodeString(&CurIcon->ustrModule, UserMode, pustrModule);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
Ret = TRUE;
|
Ret = TRUE;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
@ -1055,97 +1171,17 @@ done:
|
||||||
GreDeleteObject(CurIcon->aFrame[0].hbmColor);
|
GreDeleteObject(CurIcon->aFrame[0].hbmColor);
|
||||||
CurIcon->aFrame[0].hbmColor = NULL;
|
CurIcon->aFrame[0].hbmColor = NULL;
|
||||||
}
|
}
|
||||||
|
if(!IS_INTRESOURCE(CurIcon->ustrRsrc.Buffer))
|
||||||
|
ExFreePoolWithTag(CurIcon->ustrRsrc.Buffer, TAG_STRING);
|
||||||
|
if(CurIcon->ustrModule.Buffer)
|
||||||
|
ReleaseCapturedUnicodeString(&CurIcon->ustrModule, UserMode);
|
||||||
}
|
}
|
||||||
RETURN(Ret);
|
|
||||||
|
|
||||||
CLEANUP:
|
TRACE("Leave NtUserSetCursorIconData, ret=%i\n",Ret);
|
||||||
TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
UserLeave();
|
||||||
END_CLEANUP;
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
BOOL
|
|
||||||
APIENTRY
|
|
||||||
NtUserSetCursorIconData(
|
|
||||||
HANDLE hCurIcon,
|
|
||||||
PBOOL fIcon,
|
|
||||||
POINT *Hotspot,
|
|
||||||
HMODULE hModule,
|
|
||||||
HRSRC hRsrc,
|
|
||||||
HRSRC hGroupRsrc)
|
|
||||||
{
|
|
||||||
PCURICON_OBJECT CurIcon;
|
|
||||||
NTSTATUS Status;
|
|
||||||
BOOL Ret = FALSE;
|
|
||||||
DECLARE_RETURN(BOOL);
|
|
||||||
|
|
||||||
TRACE("Enter NtUserSetCursorIconData\n");
|
|
||||||
UserEnterExclusive();
|
|
||||||
|
|
||||||
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
|
|
||||||
{
|
|
||||||
RETURN(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
CurIcon->hModule = hModule;
|
|
||||||
CurIcon->hRsrc = hRsrc;
|
|
||||||
CurIcon->hGroupRsrc = hGroupRsrc;
|
|
||||||
|
|
||||||
/* Copy fields */
|
|
||||||
if (fIcon)
|
|
||||||
{
|
|
||||||
Status = MmCopyFromCaller(&CurIcon->bIcon, fIcon, sizeof(BOOL));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!Hotspot)
|
|
||||||
Ret = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Hotspot)
|
|
||||||
{
|
|
||||||
Status = MmCopyFromCaller(&CurIcon->ptlHotspot, Hotspot, sizeof(POINT));
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fIcon && !Hotspot)
|
|
||||||
{
|
|
||||||
Ret = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
|
||||||
if(Ret)
|
|
||||||
{
|
|
||||||
/* This icon is shared now */
|
|
||||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmMask, GDI_OBJ_HMGR_PUBLIC);
|
|
||||||
if(CurIcon->aFrame[0].hbmColor)
|
|
||||||
{
|
|
||||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmColor, GDI_OBJ_HMGR_PUBLIC);
|
|
||||||
}
|
|
||||||
if(CurIcon->aFrame[0].hbmAlpha)
|
|
||||||
{
|
|
||||||
GreSetObjectOwner(CurIcon->aFrame[0].hbmAlpha, GDI_OBJ_HMGR_PUBLIC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UserDereferenceObject(CurIcon);
|
|
||||||
RETURN(Ret);
|
|
||||||
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
TRACE("Leave NtUserSetCursorIconData, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Mostly inspired from wine code.
|
/* Mostly inspired from wine code.
|
||||||
* We use low level functions because:
|
* We use low level functions because:
|
||||||
|
@ -1167,7 +1203,7 @@ UserDrawIconEx(
|
||||||
HBRUSH hbrFlickerFreeDraw,
|
HBRUSH hbrFlickerFreeDraw,
|
||||||
UINT diFlags)
|
UINT diFlags)
|
||||||
{
|
{
|
||||||
PSURFACE psurfDest, psurfMask, psurfColor, psurfOffScreen;
|
PSURFACE psurfDest, psurfMask, psurfColor; //, psurfOffScreen = NULL;
|
||||||
PDC pdc = NULL;
|
PDC pdc = NULL;
|
||||||
BOOL Ret = FALSE;
|
BOOL Ret = FALSE;
|
||||||
HBITMAP hbmMask, hbmColor, hbmAlpha;
|
HBITMAP hbmMask, hbmColor, hbmAlpha;
|
||||||
|
@ -1215,6 +1251,35 @@ UserDrawIconEx(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pdc = DC_LockDc(hDc);
|
||||||
|
if(!pdc)
|
||||||
|
{
|
||||||
|
ERR("Could not lock the destination DC.\n");
|
||||||
|
SURFACE_ShareUnlockSurface(psurfMask);
|
||||||
|
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/* Calculate destination rectangle */
|
||||||
|
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
||||||
|
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
||||||
|
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||||
|
|
||||||
|
/* Prepare the underlying surface */
|
||||||
|
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
||||||
|
|
||||||
|
/* We now have our destination surface and rectangle */
|
||||||
|
psurfDest = pdc->dclevel.pSurface;
|
||||||
|
|
||||||
|
if(psurfDest == NULL)
|
||||||
|
{
|
||||||
|
/* Empty DC */
|
||||||
|
DC_vFinishBlit(pdc, NULL);
|
||||||
|
DC_UnlockDc(pdc);
|
||||||
|
SURFACE_ShareUnlockSurface(psurfMask);
|
||||||
|
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set source rect */
|
/* Set source rect */
|
||||||
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
|
RECTL_vSetRect(&rcSrc, 0, 0, pIcon->Size.cx, pIcon->Size.cy);
|
||||||
|
|
||||||
|
@ -1239,7 +1304,8 @@ UserDrawIconEx(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Should we render off-screen? */
|
/* Should we render off-screen? */
|
||||||
bOffScreen = hbrFlickerFreeDraw && (GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
|
bOffScreen = hbrFlickerFreeDraw &&
|
||||||
|
(GDI_HANDLE_GET_TYPE(hbrFlickerFreeDraw) == GDI_OBJECT_TYPE_BRUSH);
|
||||||
|
|
||||||
if (bOffScreen)
|
if (bOffScreen)
|
||||||
{
|
{
|
||||||
|
@ -1252,21 +1318,18 @@ UserDrawIconEx(
|
||||||
if(!pbrush)
|
if(!pbrush)
|
||||||
{
|
{
|
||||||
ERR("Failed to get brush object.\n");
|
ERR("Failed to get brush object.\n");
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
goto Cleanup;
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 //We lock the hdc surface during the whole function it makes no sense to use an offscreen surface for "flicker free" drawing
|
||||||
psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
|
psurfOffScreen = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||||
cxWidth, cyHeight, psurfColor->SurfObj.iBitmapFormat,
|
cxWidth, cyHeight, psurfDest->SurfObj.iBitmapFormat,
|
||||||
0, 0, NULL);
|
0, 0, NULL);
|
||||||
if(!psurfOffScreen)
|
if(!psurfOffScreen)
|
||||||
{
|
{
|
||||||
ERR("Failed to allocate the off-screen surface.\n");
|
ERR("Failed to allocate the off-screen surface.\n");
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
|
||||||
BRUSH_ShareUnlockBrush(pbrush);
|
BRUSH_ShareUnlockBrush(pbrush);
|
||||||
return FALSE;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paint the brush */
|
/* Paint the brush */
|
||||||
|
@ -1292,52 +1355,45 @@ UserDrawIconEx(
|
||||||
if(!Ret)
|
if(!Ret)
|
||||||
{
|
{
|
||||||
ERR("Failed to paint the off-screen surface.\n");
|
ERR("Failed to paint the off-screen surface.\n");
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
goto Cleanup;
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
|
||||||
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We now have our destination surface */
|
/* We now have our destination surface */
|
||||||
psurfDest = psurfOffScreen;
|
psurfDest = psurfOffScreen;
|
||||||
|
#else
|
||||||
|
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||||
|
/* Paint the brush */
|
||||||
|
EBRUSHOBJ_vInit(&eboFill, pbrush, psurfDest, 0x00FFFFFF, 0, NULL);
|
||||||
|
|
||||||
|
Ret = IntEngBitBlt(&psurfDest->SurfObj,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
pdcClipObj,
|
||||||
|
NULL,
|
||||||
|
&rcDest,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&eboFill.BrushObject,
|
||||||
|
&pbrush->ptOrigin,
|
||||||
|
ROP4_PATCOPY);
|
||||||
|
|
||||||
|
/* Clean up everything */
|
||||||
|
EBRUSHOBJ_vCleanup(&eboFill);
|
||||||
|
BRUSH_ShareUnlockBrush(pbrush);
|
||||||
|
|
||||||
|
if(!Ret)
|
||||||
|
{
|
||||||
|
ERR("Failed to paint the off-screen surface.\n");
|
||||||
|
goto Cleanup;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* We directly draw to the DC */
|
/* We directly draw to the DC */
|
||||||
TRACE("Performing on screen rendering.\n");
|
TRACE("Performing on screen rendering.\n");
|
||||||
|
|
||||||
psurfOffScreen = NULL;
|
|
||||||
pdc = DC_LockDc(hDc);
|
|
||||||
if(!pdc)
|
|
||||||
{
|
|
||||||
ERR("Could not lock the destination DC.\n");
|
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Calculate destination rectangle */
|
|
||||||
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
|
||||||
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
|
||||||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
|
||||||
|
|
||||||
/* Prepare the underlying surface */
|
|
||||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
|
||||||
|
|
||||||
/* Get the clip object */
|
|
||||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||||
|
// psurfOffScreen = NULL;
|
||||||
/* We now have our destination surface and rectangle */
|
|
||||||
psurfDest = pdc->dclevel.pSurface;
|
|
||||||
|
|
||||||
if(psurfDest == NULL)
|
|
||||||
{
|
|
||||||
/* Empty DC */
|
|
||||||
DC_vFinishBlit(pdc, NULL);
|
|
||||||
DC_UnlockDc(pdc);
|
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now do the rendering */
|
/* Now do the rendering */
|
||||||
|
@ -1460,36 +1516,23 @@ NoAlpha:
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
#if 0
|
||||||
/* We're done. Was it a double buffered draw ? */
|
/* We're done. Was it a double buffered draw ? */
|
||||||
if(bOffScreen)
|
if(bOffScreen)
|
||||||
{
|
{
|
||||||
/* Yes. Draw it back to our DC */
|
/* Yes. Draw it back to our DC */
|
||||||
POINTL ptSrc = {0, 0};
|
POINTL ptSrc = {0, 0};
|
||||||
pdc = DC_LockDc(hDc);
|
|
||||||
if(!pdc)
|
|
||||||
{
|
|
||||||
ERR("Could not lock the destination DC.\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Calculate destination rectangle */
|
/* Calculate destination rectangle */
|
||||||
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
RECTL_vSetRect(&rcDest, xLeft, yTop, xLeft + cxWidth, yTop + cyHeight);
|
||||||
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
IntLPtoDP(pdc, (LPPOINT)&rcDest, 2);
|
||||||
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
RECTL_vOffsetRect(&rcDest, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
|
||||||
|
|
||||||
/* Prepare the underlying surface */
|
|
||||||
DC_vPrepareDCsForBlit(pdc, rcDest, NULL, rcDest);
|
|
||||||
|
|
||||||
/* Get the clip object */
|
/* Get the clip object */
|
||||||
pdcClipObj = pdc->rosdc.CombinedClip;
|
pdcClipObj = pdc->rosdc.CombinedClip;
|
||||||
|
|
||||||
/* We now have our destination surface and rectangle */
|
/* We now have our destination surface and rectangle */
|
||||||
psurfDest = pdc->dclevel.pSurface;
|
psurfDest = pdc->dclevel.pSurface;
|
||||||
if(!psurfDest)
|
|
||||||
{
|
|
||||||
/* So, you did all of this for an empty DC. */
|
|
||||||
DC_UnlockDc(pdc);
|
|
||||||
goto Cleanup2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Color translation */
|
/* Color translation */
|
||||||
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
|
EXLATEOBJ_vInitialize(&exlo, psurfOffScreen->ppal, psurfDest->ppal, 0x00FFFFFF, 0x00FFFFFF, 0);
|
||||||
|
@ -1509,18 +1552,20 @@ done:
|
||||||
|
|
||||||
EXLATEOBJ_vCleanup(&exlo);
|
EXLATEOBJ_vCleanup(&exlo);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if(pdc)
|
if(pdc)
|
||||||
{
|
{
|
||||||
DC_vFinishBlit(pdc, NULL);
|
DC_vFinishBlit(pdc, NULL);
|
||||||
DC_UnlockDc(pdc);
|
DC_UnlockDc(pdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cleanup2:
|
#if 0
|
||||||
/* Delete off screen rendering surface */
|
/* Delete off screen rendering surface */
|
||||||
if(psurfOffScreen)
|
if(psurfOffScreen)
|
||||||
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
|
GDIOBJ_vDeleteObject(&psurfOffScreen->BaseObject);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Unlock other surfaces */
|
/* Unlock other surfaces */
|
||||||
SURFACE_ShareUnlockSurface(psurfMask);
|
SURFACE_ShareUnlockSurface(psurfMask);
|
||||||
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
if(psurfColor) SURFACE_ShareUnlockSurface(psurfColor);
|
||||||
|
@ -1554,7 +1599,7 @@ NtUserDrawIconEx(
|
||||||
|
|
||||||
if (!(pIcon = UserGetCurIconObject(hIcon)))
|
if (!(pIcon = UserGetCurIconObject(hIcon)))
|
||||||
{
|
{
|
||||||
ERR("UserGetCurIconObject() failed!\n");
|
ERR("UserGetCurIconObject(0x%08x) failed!\n", hIcon);
|
||||||
UserLeave();
|
UserLeave();
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,7 @@ NtUserCallOneParam(
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
DWORD_PTR Result ;
|
DWORD_PTR Result ;
|
||||||
|
|
||||||
if (!(CurIcon = IntCreateCurIconHandle()))
|
if (!(CurIcon = IntCreateCurIconHandle((DWORD)Param)))
|
||||||
{
|
{
|
||||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue