win32u: Move NtUserGetClassName implementation from user32.
Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c722a0020b
commit
cc4fb58d04
|
@ -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
|
||||
|
@ -166,6 +168,38 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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.@)
|
||||
*/
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue