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);
#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 INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
......@@ -1212,47 +1191,8 @@ INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
*/
INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
{
CLASS *class;
INT ret;
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;
UNICODE_STRING name = { .Buffer = buffer, .MaximumLength = count * sizeof(WCHAR) };
return NtUserGetClassName( hwnd, FALSE, &name );
}
......
......@@ -29,8 +29,10 @@
#define WIN32_NO_STATUS
#include "win32u_private.h"
#include "ntuser_private.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(class);
WINE_DECLARE_DEBUG_CHANNEL(win);
#define MAX_WINPROCS 4096
......@@ -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.@)
*/
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;
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
#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 */
WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) 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;
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) 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 */
......@@ -113,6 +113,7 @@ static void * const syscalls[] =
NtUserDestroyAcceleratorTable,
NtUserFindExistingCursorIcon,
NtUserGetAtomName,
NtUserGetClassName,
NtUserGetClipboardFormatName,
NtUserGetClipboardOwner,
NtUserGetClipboardSequenceNumber,
......
......@@ -110,6 +110,7 @@ static void test_class(void)
WCHAR buf[64];
WNDCLASSW cls;
ATOM class;
HWND hwnd;
ULONG ret;
memset( &cls, 0, sizeof(cls) );
......@@ -123,6 +124,9 @@ static void test_class(void)
class = RegisterClassW( &cls );
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) );
name.Buffer = buf;
name.Length = 0xdead;
......@@ -151,6 +155,36 @@ static void test_class(void)
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"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) );
ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() );
......
......@@ -899,7 +899,7 @@
@ stub NtUserGetCaretBlinkTime
@ stub NtUserGetCaretPos
@ stub NtUserGetClassInfoEx
@ stub NtUserGetClassName
@ stdcall -syscall NtUserGetClassName(long long ptr)
@ stub NtUserGetClipCursor
@ stub NtUserGetClipboardAccessToken
@ stub NtUserGetClipboardData
......
......@@ -219,7 +219,7 @@ static BOOL is_desktop_window( HWND hwnd )
* 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.
*/
static WND *get_win_ptr( HWND hwnd )
WND *get_win_ptr( HWND hwnd )
{
WND *win;
......@@ -248,7 +248,7 @@ HWND is_current_thread_window( HWND hwnd )
}
/* see IsWindow */
static BOOL is_window( HWND hwnd )
BOOL is_window( HWND hwnd )
{
WND *win;
BOOL ret;
......
......@@ -257,6 +257,7 @@ HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STR
void *desc );
SHORT WINAPI NtUserGetAsyncKeyState( INT key );
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 );
HWND WINAPI NtUserGetClipboardOwner(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