Commit a58483c9 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

win32u: Move GetClassLong implementation from user32.

parent 8fe050fb
......@@ -50,38 +50,6 @@ static inline const char *debugstr_us( const UNICODE_STRING *us )
return debugstr_wn( us->Buffer, us->Length / sizeof(WCHAR) );
}
/***********************************************************************
* get_class_ptr
*/
static CLASS *get_class_ptr( HWND hwnd, BOOL write_access )
{
WND *ptr = WIN_GetPtr( hwnd );
if (ptr)
{
if (ptr != WND_OTHER_PROCESS && ptr != WND_DESKTOP) return ptr->class;
if (!write_access) return CLASS_OTHER_PROCESS;
/* modifying classes in other processes is not allowed */
if (ptr == WND_DESKTOP || IsWindow( hwnd ))
{
SetLastError( ERROR_ACCESS_DENIED );
return NULL;
}
}
SetLastError( ERROR_INVALID_WINDOW_HANDLE );
return NULL;
}
/***********************************************************************
* release_class_ptr
*/
static inline void release_class_ptr( CLASS *ptr )
{
USER_Unlock();
}
/***********************************************************************
* get_int_atom_value
......@@ -555,172 +523,7 @@ BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
*/
WORD WINAPI GetClassWord( HWND hwnd, INT offset )
{
CLASS *class;
WORD retvalue = 0;
if (offset < 0) return GetClassLongA( hwnd, offset );
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == CLASS_OTHER_PROCESS)
{
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = offset;
req->extra_size = sizeof(retvalue);
if (!wine_server_call_err( req ))
memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) );
}
SERVER_END_REQ;
return retvalue;
}
if (offset <= class->cbClsExtra - sizeof(WORD))
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
else
SetLastError( ERROR_INVALID_INDEX );
release_class_ptr( class );
return retvalue;
}
/***********************************************************************
* CLASS_GetClassLong
*
* Implementation of GetClassLong(Ptr)A/W
*/
static ULONG_PTR CLASS_GetClassLong( HWND hwnd, INT offset, UINT size,
BOOL unicode )
{
CLASS *class;
ULONG_PTR retvalue = 0;
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == CLASS_OTHER_PROCESS)
{
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = (offset >= 0) ? offset : -1;
req->extra_size = (offset >= 0) ? size : 0;
if (!wine_server_call_err( req ))
{
switch(offset)
{
case GCLP_HBRBACKGROUND:
case GCLP_HCURSOR:
case GCLP_HICON:
case GCLP_HICONSM:
case GCLP_WNDPROC:
case GCLP_MENUNAME:
FIXME( "offset %d (%s) not supported on other process window %p\n",
offset, SPY_GetClassLongOffsetName(offset), hwnd );
SetLastError( ERROR_INVALID_HANDLE );
break;
case GCL_STYLE:
retvalue = reply->old_style;
break;
case GCL_CBWNDEXTRA:
retvalue = reply->old_win_extra;
break;
case GCL_CBCLSEXTRA:
retvalue = reply->old_extra;
break;
case GCLP_HMODULE:
retvalue = (ULONG_PTR)wine_server_get_ptr( reply->old_instance );
break;
case GCW_ATOM:
retvalue = reply->old_atom;
break;
default:
if (offset >= 0)
{
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, &reply->old_extra_value, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, &reply->old_extra_value,
sizeof(ULONG_PTR) );
}
else SetLastError( ERROR_INVALID_INDEX );
break;
}
}
}
SERVER_END_REQ;
return retvalue;
}
if (offset >= 0)
{
if (offset <= class->cbClsExtra - size)
{
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, (char *)(class + 1) + offset, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(ULONG_PTR) );
}
else
SetLastError( ERROR_INVALID_INDEX );
release_class_ptr( class );
return retvalue;
}
switch(offset)
{
case GCLP_HBRBACKGROUND:
retvalue = (ULONG_PTR)class->hbrBackground;
break;
case GCLP_HCURSOR:
retvalue = (ULONG_PTR)class->hCursor;
break;
case GCLP_HICON:
retvalue = (ULONG_PTR)class->hIcon;
break;
case GCLP_HICONSM:
retvalue = (ULONG_PTR)(class->hIconSm ? class->hIconSm : class->hIconSmIntern);
break;
case GCL_STYLE:
retvalue = class->style;
break;
case GCL_CBWNDEXTRA:
retvalue = class->cbWndExtra;
break;
case GCL_CBCLSEXTRA:
retvalue = class->cbClsExtra;
break;
case GCLP_HMODULE:
retvalue = class->instance;
break;
case GCLP_WNDPROC:
retvalue = (ULONG_PTR)WINPROC_GetProc( class->winproc, unicode );
break;
case GCLP_MENUNAME:
if (unicode)
retvalue = (ULONG_PTR)class->menu_name.nameW;
else
retvalue = (ULONG_PTR)class->menu_name.nameA;
break;
case GCW_ATOM:
retvalue = class->atomName;
break;
default:
SetLastError( ERROR_INVALID_INDEX );
break;
}
release_class_ptr( class );
return retvalue;
return NtUserCallHwndParam( hwnd, offset, NtUserGetClassWord );
}
......@@ -729,7 +532,7 @@ static ULONG_PTR CLASS_GetClassLong( HWND hwnd, INT offset, UINT size,
*/
DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
{
return CLASS_GetClassLong( hwnd, offset, sizeof(DWORD), TRUE );
return NtUserCallHwndParam( hwnd, offset, NtUserGetClassLongW );
}
......@@ -739,7 +542,7 @@ DWORD WINAPI GetClassLongW( HWND hwnd, INT offset )
*/
DWORD WINAPI GetClassLongA( HWND hwnd, INT offset )
{
return CLASS_GetClassLong( hwnd, offset, sizeof(DWORD), FALSE );
return NtUserCallHwndParam( hwnd, offset, NtUserGetClassLongA );
}
......@@ -1013,7 +816,7 @@ BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
*/
ULONG_PTR WINAPI GetClassLongPtrA( HWND hwnd, INT offset )
{
return CLASS_GetClassLong( hwnd, offset, sizeof(ULONG_PTR), FALSE );
return NtUserCallHwndParam( hwnd, offset, NtUserGetClassLongPtrA );
}
/***********************************************************************
......@@ -1021,7 +824,7 @@ ULONG_PTR WINAPI GetClassLongPtrA( HWND hwnd, INT offset )
*/
ULONG_PTR WINAPI GetClassLongPtrW( HWND hwnd, INT offset )
{
return CLASS_GetClassLong( hwnd, offset, sizeof(ULONG_PTR), TRUE );
return NtUserCallHwndParam( hwnd, offset, NtUserGetClassLongPtrW );
}
/***********************************************************************
......
......@@ -41,24 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(message);
#define DEBUG_SPY 0
static const char * const ClassLongOffsetNames[] =
{
"GCLP_MENUNAME", /* -8 */
"GCLP_HBRBACKGROUND", /* -10 */
"GCLP_HCURSOR", /* -12 */
"GCLP_HICON", /* -14 */
"GCLP_HMODULE", /* -16 */
"GCL_CBWNDEXTRA", /* -18 */
"GCL_CBCLSEXTRA", /* -20 */
"?",
"GCLP_WNDPROC", /* -24 */
"GCL_STYLE", /* -26 */
"?",
"?",
"GCW_ATOM", /* -32 */
"GCLP_HICONSM", /* -34 */
};
static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] =
{
"WM_NULL", /* 0x00 */
......@@ -2117,23 +2099,6 @@ static const USER_MSG *SPY_Bsearch_Msg( const USER_MSG *msgs, UINT count, UINT c
}
/***********************************************************************
* SPY_GetClassLongOffsetName
*
* Gets the name of a class long offset.
*/
const char *SPY_GetClassLongOffsetName( INT offset )
{
INT index;
if (offset < 0 && offset % 2 == 0 && ((index = -(offset + 8) / 2) <
ARRAY_SIZE(ClassLongOffsetNames)))
{
return ClassLongOffsetNames[index];
}
return "?";
}
/***********************************************************************
* SPY_GetClassName
*
* Sets the value of "wnd_class" member of the instance structure.
......
......@@ -178,7 +178,6 @@ BOOL WINAPI User32CallWindowsHook( const struct win_hook_params *params, ULONG s
#define SPY_RESULT_OK 0x0001
#define SPY_RESULT_DEFWND 0x0002
extern const char *SPY_GetClassLongOffsetName( INT offset ) DECLSPEC_HIDDEN;
extern const char *SPY_GetMsgName( UINT msg, HWND hWnd ) DECLSPEC_HIDDEN;
extern const char *SPY_GetVKeyName(WPARAM wParam) DECLSPEC_HIDDEN;
extern void SPY_EnterMessage( INT iFlag, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN;
......
......@@ -724,3 +724,172 @@ WORD WINAPI NtUserSetClassWord( HWND hwnd, INT offset, WORD newval )
release_class_ptr( class );
return retval;
}
static ULONG_PTR get_class_long_size( HWND hwnd, INT offset, UINT size, BOOL ansi )
{
CLASS *class;
ULONG_PTR retvalue = 0;
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == OBJ_OTHER_PROCESS)
{
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = (offset >= 0) ? offset : -1;
req->extra_size = (offset >= 0) ? size : 0;
if (!wine_server_call_err( req ))
{
switch(offset)
{
case GCLP_HBRBACKGROUND:
case GCLP_HCURSOR:
case GCLP_HICON:
case GCLP_HICONSM:
case GCLP_WNDPROC:
case GCLP_MENUNAME:
FIXME( "offset %d not supported on other process window %p\n", offset, hwnd );
SetLastError( ERROR_INVALID_HANDLE );
break;
case GCL_STYLE:
retvalue = reply->old_style;
break;
case GCL_CBWNDEXTRA:
retvalue = reply->old_win_extra;
break;
case GCL_CBCLSEXTRA:
retvalue = reply->old_extra;
break;
case GCLP_HMODULE:
retvalue = (ULONG_PTR)wine_server_get_ptr( reply->old_instance );
break;
case GCW_ATOM:
retvalue = reply->old_atom;
break;
default:
if (offset >= 0)
{
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, &reply->old_extra_value, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, &reply->old_extra_value,
sizeof(ULONG_PTR) );
}
else SetLastError( ERROR_INVALID_INDEX );
break;
}
}
}
SERVER_END_REQ;
return retvalue;
}
if (offset >= 0)
{
if (offset <= class->cbClsExtra - size)
{
if (size == sizeof(DWORD))
{
DWORD retdword;
memcpy( &retdword, (char *)(class + 1) + offset, sizeof(DWORD) );
retvalue = retdword;
}
else
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(ULONG_PTR) );
}
else
SetLastError( ERROR_INVALID_INDEX );
release_class_ptr( class );
return retvalue;
}
switch(offset)
{
case GCLP_HBRBACKGROUND:
retvalue = (ULONG_PTR)class->hbrBackground;
break;
case GCLP_HCURSOR:
retvalue = (ULONG_PTR)class->hCursor;
break;
case GCLP_HICON:
retvalue = (ULONG_PTR)class->hIcon;
break;
case GCLP_HICONSM:
retvalue = (ULONG_PTR)(class->hIconSm ? class->hIconSm : class->hIconSmIntern);
break;
case GCL_STYLE:
retvalue = class->style;
break;
case GCL_CBWNDEXTRA:
retvalue = class->cbWndExtra;
break;
case GCL_CBCLSEXTRA:
retvalue = class->cbClsExtra;
break;
case GCLP_HMODULE:
retvalue = class->instance;
break;
case GCLP_WNDPROC:
retvalue = (ULONG_PTR)get_winproc( class->winproc, ansi );
break;
case GCLP_MENUNAME:
retvalue = ansi ? (ULONG_PTR)class->menu_name.nameA : (ULONG_PTR)class->menu_name.nameW;
break;
case GCW_ATOM:
retvalue = class->atomName;
break;
default:
SetLastError( ERROR_INVALID_INDEX );
break;
}
release_class_ptr( class );
return retvalue;
}
DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi )
{
return get_class_long_size( hwnd, offset, sizeof(DWORD), ansi );
}
ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi )
{
return get_class_long_size( hwnd, offset, sizeof(ULONG_PTR), ansi );
}
WORD get_class_word( HWND hwnd, INT offset )
{
CLASS *class;
WORD retvalue = 0;
if (offset < 0) return get_class_long( hwnd, offset, TRUE );
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == OBJ_OTHER_PROCESS)
{
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = offset;
req->extra_size = sizeof(retvalue);
if (!wine_server_call_err( req ))
memcpy( &retvalue, &reply->old_extra_value, sizeof(retvalue) );
}
SERVER_END_REQ;
return retvalue;
}
if (offset <= class->cbClsExtra - sizeof(WORD))
memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
else
SetLastError( ERROR_INVALID_INDEX );
release_class_ptr( class );
return retvalue;
}
......@@ -204,6 +204,9 @@ typedef struct tagCLASS
/* class.c */
WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN;
WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN;
DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
WORD get_class_word( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;
/* cursoricon.c */
HICON alloc_cursoricon_handle( BOOL is_icon ) DECLSPEC_HIDDEN;
......
......@@ -185,7 +185,7 @@ struct unix_funcs
BOOL (WINAPI *pNtGdiWidenPath)( HDC hdc );
HKL (WINAPI *pNtUserActivateKeyboardLayout)( HKL layout, UINT flags );
DWORD (WINAPI *pNtUserCallHwnd)( HWND hwnd, DWORD code );
DWORD (WINAPI *pNtUserCallHwndParam)( HWND hwnd, DWORD_PTR param, DWORD code );
ULONG_PTR (WINAPI *pNtUserCallHwndParam)( HWND hwnd, DWORD_PTR param, DWORD code );
LRESULT (WINAPI *pNtUserCallNextHookEx)( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
ULONG_PTR (WINAPI *pNtUserCallNoParam)( ULONG code );
ULONG_PTR (WINAPI *pNtUserCallOneParam)( ULONG_PTR arg, ULONG code );
......
......@@ -443,10 +443,20 @@ DWORD WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
/*****************************************************************************
* NtUserCallHwndParam (win32u.@)
*/
DWORD WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
{
switch (code)
{
case NtUserGetClassLongA:
return get_class_long( hwnd, param, TRUE );
case NtUserGetClassLongW:
return get_class_long( hwnd, param, FALSE );
case NtUserGetClassLongPtrA:
return get_class_long_ptr( hwnd, param, TRUE );
case NtUserGetClassLongPtrW:
return get_class_long_ptr( hwnd, param, FALSE );
case NtUserGetClassWord:
return get_class_word( hwnd, param );
case NtUserGetWindowThread:
return get_window_thread( hwnd, (DWORD *)param );
default:
......
......@@ -731,7 +731,7 @@ DWORD WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
return unix_funcs->pNtUserCallHwnd( hwnd, code );
}
DWORD WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserCallHwndParam( hwnd, param, code );
......
......@@ -145,6 +145,11 @@ enum
/* NtUserCallHwndParam codes, not compatible with Windows */
enum
{
NtUserGetClassLongA,
NtUserGetClassLongW,
NtUserGetClassLongPtrA,
NtUserGetClassLongPtrW,
NtUserGetClassWord,
NtUserGetWindowThread,
};
......@@ -233,7 +238,7 @@ BOOL WINAPI NtUserAttachThreadInput( DWORD from, DWORD to, BOOL attach );
NTSTATUS WINAPI NtUserBuildHwndList( HDESK desktop, ULONG unk2, ULONG unk3, ULONG unk4,
ULONG thread_id, ULONG count, HWND *buffer, ULONG *size );
DWORD WINAPI NtUserCallHwnd( HWND hwnd, DWORD code );
DWORD WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code );
ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code );
LRESULT WINAPI NtUserCallNextHookEx( HHOOK hhook, INT code, WPARAM wparam, LPARAM lparam );
ULONG_PTR WINAPI NtUserCallNoParam( ULONG code );
ULONG_PTR WINAPI NtUserCallOneParam( ULONG_PTR arg, ULONG code );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment