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

win32u: Move NtUserGetClassName implementation from user32.

parent c722a002
...@@ -40,27 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(class); ...@@ -40,27 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(class);
#define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */ #define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */
typedef struct tagCLASS
{
struct list entry; /* Entry in class list */
UINT style; /* Class style */
BOOL local; /* Local class? */
WNDPROC winproc; /* Window procedure */
INT cbClsExtra; /* Class extra bytes */
INT cbWndExtra; /* Window extra bytes */
LPWSTR menuName; /* Default menu name (Unicode followed by ASCII) */
struct dce *dce; /* Opaque pointer to class DCE */
HINSTANCE hInstance; /* Module that created the task */
HICON hIcon; /* Default icon */
HICON hIconSm; /* Default small icon */
HICON hIconSmIntern; /* Internal small icon, derived from hIcon */
HCURSOR hCursor; /* Default cursor */
HBRUSH hbrBackground; /* Default background */
ATOM atomName; /* Name of the class */
WCHAR name[MAX_ATOM_LEN + 1];
WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */
} CLASS;
static struct list class_list = LIST_INIT( class_list ); static struct list class_list = LIST_INIT( class_list );
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
...@@ -1212,47 +1191,8 @@ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count ) ...@@ -1212,47 +1191,8 @@ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
*/ */
INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count ) INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
{ {
CLASS *class; UNICODE_STRING name = { .Buffer = buffer, .MaximumLength = count * sizeof(WCHAR) };
INT ret; return NtUserGetClassName( hwnd, FALSE, &name );
TRACE("%p %p %d\n", hwnd, buffer, count);
if (count <= 0) return 0;
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == CLASS_OTHER_PROCESS)
{
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
ATOM atom = 0;
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = -1;
req->extra_size = 0;
if (!wine_server_call_err( req ))
atom = reply->base_atom;
}
SERVER_END_REQ;
ret = GlobalGetAtomNameW( atom, tmpbuf, MAX_ATOM_LEN + 1 );
if (ret)
{
ret = min(count - 1, ret);
memcpy(buffer, tmpbuf, ret * sizeof(WCHAR));
buffer[ret] = 0;
}
}
else
{
/* Return original name class was registered with. */
lstrcpynW( buffer, class->basename, count );
release_class_ptr( class );
ret = lstrlenW( buffer );
}
return ret;
} }
......
...@@ -29,8 +29,10 @@ ...@@ -29,8 +29,10 @@
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#include "win32u_private.h" #include "win32u_private.h"
#include "ntuser_private.h" #include "ntuser_private.h"
#include "wine/server.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(class);
WINE_DECLARE_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(win);
#define MAX_WINPROCS 4096 #define MAX_WINPROCS 4096
...@@ -167,6 +169,38 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs ...@@ -167,6 +169,38 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs
} }
/*********************************************************************** /***********************************************************************
* get_class_ptr
*/
static CLASS *get_class_ptr( HWND hwnd, BOOL write_access )
{
WND *ptr = get_win_ptr( hwnd );
if (ptr)
{
if (ptr != WND_OTHER_PROCESS && ptr != WND_DESKTOP) return ptr->class;
if (!write_access) return OBJ_OTHER_PROCESS;
/* modifying classes in other processes is not allowed */
if (ptr == WND_DESKTOP || is_window( 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();
}
/***********************************************************************
* NtUserGetAtomName (win32u.@) * NtUserGetAtomName (win32u.@)
*/ */
ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ) ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name )
...@@ -190,3 +224,46 @@ ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ) ...@@ -190,3 +224,46 @@ ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name )
name->Buffer[size / sizeof(WCHAR)] = 0; name->Buffer[size / sizeof(WCHAR)] = 0;
return size / sizeof(WCHAR); return size / sizeof(WCHAR);
} }
/***********************************************************************
* NtUserGetClassName (win32u.@)
*/
INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name )
{
CLASS *class;
int ret;
TRACE( "%p %x %p\n", hwnd, real, name );
if (name->MaximumLength <= sizeof(WCHAR))
{
SetLastError( ERROR_INSUFFICIENT_BUFFER );
return 0;
}
if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
if (class == OBJ_OTHER_PROCESS)
{
ATOM atom = 0;
SERVER_START_REQ( set_class_info )
{
req->window = wine_server_user_handle( hwnd );
req->flags = 0;
req->extra_offset = -1;
req->extra_size = 0;
if (!wine_server_call_err( req ))
atom = reply->base_atom;
}
SERVER_END_REQ;
return NtUserGetAtomName( atom, name );
}
ret = min( name->MaximumLength / sizeof(WCHAR) - 1, lstrlenW(class->basename) );
if (ret) memcpy( name->Buffer, class->basename, ret * sizeof(WCHAR) );
name->Buffer[ret] = 0;
release_class_ptr( class );
return ret;
}
...@@ -169,6 +169,27 @@ typedef struct tagWINDOWPROC ...@@ -169,6 +169,27 @@ typedef struct tagWINDOWPROC
#define MAX_ATOM_LEN 255 #define MAX_ATOM_LEN 255
typedef struct tagCLASS
{
struct list entry; /* Entry in class list */
UINT style; /* Class style */
BOOL local; /* Local class? */
WNDPROC winproc; /* Window procedure */
INT cbClsExtra; /* Class extra bytes */
INT cbWndExtra; /* Window extra bytes */
LPWSTR menuName; /* Default menu name (Unicode followed by ASCII) */
struct dce *dce; /* Opaque pointer to class DCE */
HINSTANCE hInstance; /* Module that created the task */
HICON hIcon; /* Default icon */
HICON hIconSm; /* Default small icon */
HICON hIconSmIntern; /* Internal small icon, derived from hIcon */
HCURSOR hCursor; /* Default cursor */
HBRUSH hbrBackground; /* Default background */
ATOM atomName; /* Name of the class */
WCHAR name[MAX_ATOM_LEN + 1];
WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */
} CLASS;
/* class.c */ /* class.c */
WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN; WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN;
WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN; WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN;
...@@ -185,4 +206,7 @@ void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN; ...@@ -185,4 +206,7 @@ void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN; void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN; void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
WND *get_win_ptr( HWND hwnd ) DECLSPEC_HIDDEN;
BOOL is_window( HWND hwnd ) DECLSPEC_HIDDEN;
#endif /* __WINE_NTUSER_PRIVATE_H */ #endif /* __WINE_NTUSER_PRIVATE_H */
...@@ -113,6 +113,7 @@ static void * const syscalls[] = ...@@ -113,6 +113,7 @@ static void * const syscalls[] =
NtUserDestroyAcceleratorTable, NtUserDestroyAcceleratorTable,
NtUserFindExistingCursorIcon, NtUserFindExistingCursorIcon,
NtUserGetAtomName, NtUserGetAtomName,
NtUserGetClassName,
NtUserGetClipboardFormatName, NtUserGetClipboardFormatName,
NtUserGetClipboardOwner, NtUserGetClipboardOwner,
NtUserGetClipboardSequenceNumber, NtUserGetClipboardSequenceNumber,
......
...@@ -110,6 +110,7 @@ static void test_class(void) ...@@ -110,6 +110,7 @@ static void test_class(void)
WCHAR buf[64]; WCHAR buf[64];
WNDCLASSW cls; WNDCLASSW cls;
ATOM class; ATOM class;
HWND hwnd;
ULONG ret; ULONG ret;
memset( &cls, 0, sizeof(cls) ); memset( &cls, 0, sizeof(cls) );
...@@ -123,6 +124,9 @@ static void test_class(void) ...@@ -123,6 +124,9 @@ static void test_class(void)
class = RegisterClassW( &cls ); class = RegisterClassW( &cls );
ok( class, "RegisterClassW failed: %lu\n", GetLastError() ); ok( class, "RegisterClassW failed: %lu\n", GetLastError() );
hwnd = CreateWindowW( L"test", L"test name", WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, NULL, 0 );
memset( buf, 0xcc, sizeof(buf) ); memset( buf, 0xcc, sizeof(buf) );
name.Buffer = buf; name.Buffer = buf;
name.Length = 0xdead; name.Length = 0xdead;
...@@ -151,6 +155,36 @@ static void test_class(void) ...@@ -151,6 +155,36 @@ static void test_class(void)
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"NtUserGetAtomName returned %lx %lu\n", ret, GetLastError() ); "NtUserGetAtomName returned %lx %lu\n", ret, GetLastError() );
memset( buf, 0xcc, sizeof(buf) );
name.Buffer = buf;
name.Length = 0xdead;
name.MaximumLength = sizeof(buf);
ret = NtUserGetClassName( hwnd, FALSE, &name );
ok( ret == 4, "NtUserGetClassName returned %lu\n", ret );
ok( name.Length == 0xdead, "Length = %u\n", name.Length );
ok( name.MaximumLength == sizeof(buf), "MaximumLength = %u\n", name.MaximumLength );
ok( !wcscmp( buf, L"test" ), "buf = %s\n", debugstr_w(buf) );
memset( buf, 0xcc, sizeof(buf) );
name.Buffer = buf;
name.Length = 0xdead;
name.MaximumLength = 8;
ret = NtUserGetClassName( hwnd, FALSE, &name );
ok( ret == 3, "NtUserGetClassName returned %lu\n", ret );
ok( name.Length == 0xdead, "Length = %u\n", name.Length );
ok( name.MaximumLength == 8, "MaximumLength = %u\n", name.MaximumLength );
ok( !wcscmp( buf, L"tes" ), "buf = %s\n", debugstr_w(buf) );
memset( buf, 0xcc, sizeof(buf) );
name.Buffer = buf;
name.MaximumLength = 1;
SetLastError( 0xdeadbeef );
ret = NtUserGetClassName( hwnd, FALSE, &name );
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"NtUserGetClassName returned %lx %lu\n", ret, GetLastError() );
DestroyWindow( hwnd );
ret = UnregisterClassW( L"test", GetModuleHandleW(NULL) ); ret = UnregisterClassW( L"test", GetModuleHandleW(NULL) );
ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() ); ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() );
......
...@@ -899,7 +899,7 @@ ...@@ -899,7 +899,7 @@
@ stub NtUserGetCaretBlinkTime @ stub NtUserGetCaretBlinkTime
@ stub NtUserGetCaretPos @ stub NtUserGetCaretPos
@ stub NtUserGetClassInfoEx @ stub NtUserGetClassInfoEx
@ stub NtUserGetClassName @ stdcall -syscall NtUserGetClassName(long long ptr)
@ stub NtUserGetClipCursor @ stub NtUserGetClipCursor
@ stub NtUserGetClipboardAccessToken @ stub NtUserGetClipboardAccessToken
@ stub NtUserGetClipboardData @ stub NtUserGetClipboardData
......
...@@ -219,7 +219,7 @@ static BOOL is_desktop_window( HWND hwnd ) ...@@ -219,7 +219,7 @@ static BOOL is_desktop_window( HWND hwnd )
* or WND_OTHER_PROCESS if handle may be valid in other process. * or WND_OTHER_PROCESS if handle may be valid in other process.
* If ret value is a valid pointer, it must be released with WIN_ReleasePtr. * If ret value is a valid pointer, it must be released with WIN_ReleasePtr.
*/ */
static WND *get_win_ptr( HWND hwnd ) WND *get_win_ptr( HWND hwnd )
{ {
WND *win; WND *win;
...@@ -248,7 +248,7 @@ HWND is_current_thread_window( HWND hwnd ) ...@@ -248,7 +248,7 @@ HWND is_current_thread_window( HWND hwnd )
} }
/* see IsWindow */ /* see IsWindow */
static BOOL is_window( HWND hwnd ) BOOL is_window( HWND hwnd )
{ {
WND *win; WND *win;
BOOL ret; BOOL ret;
......
...@@ -257,6 +257,7 @@ HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STR ...@@ -257,6 +257,7 @@ HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STR
void *desc ); void *desc );
SHORT WINAPI NtUserGetAsyncKeyState( INT key ); SHORT WINAPI NtUserGetAsyncKeyState( INT key );
ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ); ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name );
INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name );
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen ); INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
HWND WINAPI NtUserGetClipboardOwner(void); HWND WINAPI NtUserGetClipboardOwner(void);
DWORD WINAPI NtUserGetClipboardSequenceNumber(void); DWORD WINAPI NtUserGetClipboardSequenceNumber(void);
......
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