[USER32][NTUSER] Implement (NtUser)SetClassLongPtr(A/W)

This commit is contained in:
Timo Kreuzer 2024-09-09 18:30:15 +03:00
parent 53b304e6a9
commit 201f00ab6f
5 changed files with 772 additions and 723 deletions

View file

@ -3015,11 +3015,22 @@ NtUserSetCapture(
ULONG_PTR ULONG_PTR
NTAPI NTAPI
NtUserSetClassLong( NtUserSetClassLong(
HWND hWnd, _In_ HWND hWnd,
INT Offset, _In_ INT Offset,
ULONG_PTR dwNewLong, _In_ ULONG dwNewLong,
BOOL Ansi); _In_ BOOL Ansi);
#ifdef _WIN64
ULONG_PTR
APIENTRY
NtUserSetClassLongPtr(
_In_ HWND hWnd,
_In_ INT Offset,
_In_ ULONG_PTR dwNewLong,
_In_ BOOL Ansi);
#endif // _WIN64
WORD WORD
NTAPI NTAPI
NtUserSetClassWord( NtUserSetClassWord(
@ -3085,11 +3096,6 @@ NtUserFindExistingCursorIcon(
_In_ PUNICODE_STRING pustrRsrc, _In_ PUNICODE_STRING pustrRsrc,
_In_ FINDEXISTINGCURICONPARAM *param); _In_ FINDEXISTINGCURICONPARAM *param);
LONG_PTR
APIENTRY
NtUserSetClassLongPtr(
VOID);
DWORD DWORD
NTAPI NTAPI
NtUserSetDbgTag( NtUserSetDbgTag(

View file

@ -7,6 +7,8 @@
*/ */
#include <win32k.h> #include <win32k.h>
#include <unaligned.h>
DBG_DEFAULT_CHANNEL(UserClass); DBG_DEFAULT_CHANNEL(UserClass);
static PWSTR ControlsList[] = static PWSTR ControlsList[] =
@ -1865,11 +1867,37 @@ IntSetClassMenuName(IN PCLS Class,
return Ret; return Ret;
} }
static inline
ULONG_PTR
IntGetSetClassLongPtr(PCLS Class, ULONG Index, ULONG_PTR NewValue, ULONG Size)
{
PVOID Address = (PUCHAR)(&Class[1]) + Index;
ULONG_PTR OldValue;
#ifdef _WIN64
if (Size == sizeof(LONG))
{
/* Values might be unaligned */
OldValue = ReadUnalignedU32(Address);
WriteUnalignedU32(Address, NewValue);
}
else
#endif
{
/* Values might be unaligned */
OldValue = ReadUnalignedUlongPtr(Address);
WriteUnalignedUlongPtr(Address, NewValue);
}
return OldValue;
}
ULONG_PTR ULONG_PTR
UserSetClassLongPtr(IN PCLS Class, UserSetClassLongPtr(IN PCLS Class,
IN INT Index, IN INT Index,
IN ULONG_PTR NewLong, IN ULONG_PTR NewLong,
IN BOOL Ansi) IN BOOL Ansi,
IN ULONG Size)
{ {
ULONG_PTR Ret = 0; ULONG_PTR Ret = 0;
@ -1880,30 +1908,22 @@ UserSetClassLongPtr(IN PCLS Class,
if (Index >= 0) if (Index >= 0)
{ {
PULONG_PTR Data;
TRACE("SetClassLong(%d, %x)\n", Index, NewLong); TRACE("SetClassLong(%d, %x)\n", Index, NewLong);
if (((ULONG)Index + sizeof(ULONG_PTR)) < (ULONG)Index || if (((ULONG)Index + Size) < (ULONG)Index ||
((ULONG)Index + sizeof(ULONG_PTR)) > (ULONG)Class->cbclsExtra) ((ULONG)Index + Size) > (ULONG)Class->cbclsExtra)
{ {
EngSetLastError(ERROR_INVALID_PARAMETER); EngSetLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index); Ret = IntGetSetClassLongPtr(Class, Index, NewLong, Size);
/* FIXME: Data might be a unaligned pointer! Might be a problem on
certain architectures, maybe using RtlCopyMemory is a
better choice for those architectures! */
Ret = *Data;
*Data = NewLong;
/* Update the clones */ /* Update the clones */
Class = Class->pclsClone; Class = Class->pclsClone;
while (Class != NULL) while (Class != NULL)
{ {
*(PULONG_PTR)((ULONG_PTR)(Class + 1) + Index) = NewLong; IntGetSetClassLongPtr(Class, Index, NewLong, Size);
Class = Class->pclsNext; Class = Class->pclsNext;
} }
@ -2583,10 +2603,11 @@ InvalidParameter:
} }
ULONG_PTR APIENTRY ULONG_PTR APIENTRY
NtUserSetClassLong(HWND hWnd, IntNtUserSetClassLongPtr(HWND hWnd,
INT Offset, INT Offset,
ULONG_PTR dwNewLong, ULONG_PTR dwNewLong,
BOOL Ansi) BOOL Ansi,
ULONG Size)
{ {
PPROCESSINFO pi; PPROCESSINFO pi;
PWND Window; PWND Window;
@ -2655,7 +2676,8 @@ InvalidParameter:
Ret = UserSetClassLongPtr(Window->pcls, Ret = UserSetClassLongPtr(Window->pcls,
Offset, Offset,
dwNewLong, dwNewLong,
Ansi); Ansi,
Size);
switch(Offset) switch(Offset)
{ {
case GCLP_HICONSM: case GCLP_HICONSM:
@ -2679,6 +2701,32 @@ Cleanup:
return Ret; return Ret;
} }
ULONG_PTR
APIENTRY
NtUserSetClassLong(
_In_ HWND hWnd,
_In_ INT Offset,
_In_ ULONG dwNewLong,
_In_ BOOL Ansi)
{
return IntNtUserSetClassLongPtr(hWnd, Offset, dwNewLong, Ansi, sizeof(LONG));
}
#ifdef _WIN64
ULONG_PTR
APIENTRY
NtUserSetClassLongPtr(
_In_ HWND hWnd,
_In_ INT Offset,
_In_ ULONG_PTR dwNewLong,
_In_ BOOL Ansi)
{
return IntNtUserSetClassLongPtr(hWnd, Offset, dwNewLong, Ansi, sizeof(LONG_PTR));
}
#endif // _WIN64
WORD WORD
APIENTRY APIENTRY
NtUserSetClassWord( NtUserSetClassWord(

View file

@ -949,15 +949,6 @@ BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
return FALSE; return FALSE;
} }
LONG_PTR
APIENTRY
NtUserSetClassLongPtr(
VOID)
{
STUB;
return 0;
}
// Yes, I know, these do not belong here, just tell me where to put them // Yes, I know, these do not belong here, just tell me where to put them
BOOL BOOL
APIENTRY APIENTRY

View file

@ -1607,8 +1607,10 @@ SetClassLongPtrA(HWND hWnd,
INT nIndex, INT nIndex,
LONG_PTR dwNewLong) LONG_PTR dwNewLong)
{ {
UNIMPLEMENTED; return NtUserSetClassLongPtr(hWnd,
return 0; nIndex,
dwNewLong,
TRUE);
} }
/* /*
@ -1620,8 +1622,10 @@ SetClassLongPtrW(HWND hWnd,
INT nIndex, INT nIndex,
LONG_PTR dwNewLong) LONG_PTR dwNewLong)
{ {
UNIMPLEMENTED; return NtUserSetClassLongPtr(hWnd,
return 0; nIndex,
dwNewLong,
FALSE);
} }
#endif // _WIN64 #endif // _WIN64

File diff suppressed because it is too large Load diff