[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
NTAPI
NtUserSetClassLong(
HWND hWnd,
INT Offset,
ULONG_PTR dwNewLong,
BOOL Ansi);
_In_ HWND hWnd,
_In_ INT Offset,
_In_ ULONG dwNewLong,
_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
NTAPI
NtUserSetClassWord(
@ -3085,11 +3096,6 @@ NtUserFindExistingCursorIcon(
_In_ PUNICODE_STRING pustrRsrc,
_In_ FINDEXISTINGCURICONPARAM *param);
LONG_PTR
APIENTRY
NtUserSetClassLongPtr(
VOID);
DWORD
NTAPI
NtUserSetDbgTag(

View File

@ -7,6 +7,8 @@
*/
#include <win32k.h>
#include <unaligned.h>
DBG_DEFAULT_CHANNEL(UserClass);
static PWSTR ControlsList[] =
@ -1865,11 +1867,37 @@ IntSetClassMenuName(IN PCLS Class,
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
UserSetClassLongPtr(IN PCLS Class,
IN INT Index,
IN ULONG_PTR NewLong,
IN BOOL Ansi)
IN BOOL Ansi,
IN ULONG Size)
{
ULONG_PTR Ret = 0;
@ -1880,30 +1908,22 @@ UserSetClassLongPtr(IN PCLS Class,
if (Index >= 0)
{
PULONG_PTR Data;
TRACE("SetClassLong(%d, %x)\n", Index, NewLong);
if (((ULONG)Index + sizeof(ULONG_PTR)) < (ULONG)Index ||
((ULONG)Index + sizeof(ULONG_PTR)) > (ULONG)Class->cbclsExtra)
if (((ULONG)Index + Size) < (ULONG)Index ||
((ULONG)Index + Size) > (ULONG)Class->cbclsExtra)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
/* 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;
Ret = IntGetSetClassLongPtr(Class, Index, NewLong, Size);
/* Update the clones */
Class = Class->pclsClone;
while (Class != NULL)
{
*(PULONG_PTR)((ULONG_PTR)(Class + 1) + Index) = NewLong;
IntGetSetClassLongPtr(Class, Index, NewLong, Size);
Class = Class->pclsNext;
}
@ -2583,10 +2603,11 @@ InvalidParameter:
}
ULONG_PTR APIENTRY
NtUserSetClassLong(HWND hWnd,
IntNtUserSetClassLongPtr(HWND hWnd,
INT Offset,
ULONG_PTR dwNewLong,
BOOL Ansi)
BOOL Ansi,
ULONG Size)
{
PPROCESSINFO pi;
PWND Window;
@ -2655,7 +2676,8 @@ InvalidParameter:
Ret = UserSetClassLongPtr(Window->pcls,
Offset,
dwNewLong,
Ansi);
Ansi,
Size);
switch(Offset)
{
case GCLP_HICONSM:
@ -2679,6 +2701,32 @@ Cleanup:
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
APIENTRY
NtUserSetClassWord(

View File

@ -949,15 +949,6 @@ BOOL APIENTRY NtUserGetUpdatedClipboardFormats(
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
BOOL
APIENTRY

View File

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

File diff suppressed because it is too large Load Diff