Jacek Caban : win32u: Implement NtUserGetAtomName.

Alexandre Julliard julliard at winehq.org
Fri Mar 4 15:53:08 CST 2022


Module: wine
Branch: master
Commit: c722a0020b70ff3fc5e62509b71ff4d6040509d8
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c722a0020b70ff3fc5e62509b71ff4d6040509d8

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Mar  4 14:28:16 2022 +0100

win32u: Implement NtUserGetAtomName.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/win32u/class.c          | 25 ++++++++++++++++++
 dlls/win32u/clipboard.c      |  3 ++-
 dlls/win32u/ntuser_private.h |  2 ++
 dlls/win32u/syscall.c        |  1 +
 dlls/win32u/tests/win32u.c   | 62 ++++++++++++++++++++++++++++++++++++++++++++
 dlls/win32u/win32u.spec      |  2 +-
 include/ntuser.h             |  1 +
 7 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c
index 57f12932d13..b3511f615c6 100644
--- a/dlls/win32u/class.c
+++ b/dlls/win32u/class.c
@@ -165,3 +165,28 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs
 
     return STATUS_SUCCESS;
 }
+
+/***********************************************************************
+ *	     NtUserGetAtomName   (win32u.@)
+ */
+ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name )
+{
+    char buf[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)];
+    ATOM_BASIC_INFORMATION *abi = (ATOM_BASIC_INFORMATION *)buf;
+    UINT size;
+
+    if (!set_ntstatus( NtQueryInformationAtom( atom, AtomBasicInformation,
+                                               buf, sizeof(buf), NULL )))
+        return 0;
+
+    if (name->MaximumLength < sizeof(WCHAR))
+    {
+        SetLastError( ERROR_INSUFFICIENT_BUFFER );
+        return 0;
+    }
+
+    size = min( abi->NameLength, name->MaximumLength - sizeof(WCHAR) );
+    if (size) memcpy( name->Buffer, abi->Name, size );
+    name->Buffer[size / sizeof(WCHAR)] = 0;
+    return size / sizeof(WCHAR);
+}
diff --git a/dlls/win32u/clipboard.c b/dlls/win32u/clipboard.c
index dca01708803..e132f981344 100644
--- a/dlls/win32u/clipboard.c
+++ b/dlls/win32u/clipboard.c
@@ -28,6 +28,7 @@
 #endif
 
 #include "win32u_private.h"
+#include "ntuser_private.h"
 #include "wine/server.h"
 #include "wine/debug.h"
 
@@ -168,7 +169,7 @@ INT WINAPI NtUserGetPriorityClipboardFormat( UINT *list, INT count )
  */
 INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen )
 {
-    char buf[sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR)];
+    char buf[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)];
     ATOM_BASIC_INFORMATION *abi = (ATOM_BASIC_INFORMATION *)buf;
     UINT length = 0;
 
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index 686a4ab1130..2ada1c5b990 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -167,6 +167,8 @@ typedef struct tagWINDOWPROC
 #define WINPROC_HANDLE (~0u >> 16)
 #define BUILTIN_WINPROC(index) ((WNDPROC)(ULONG_PTR)((index) | (WINPROC_HANDLE << 16)))
 
+#define MAX_ATOM_LEN 255
+
 /* class.c */
 WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN;
 WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN;
diff --git a/dlls/win32u/syscall.c b/dlls/win32u/syscall.c
index 51b8d2216ce..48b5ad3979c 100644
--- a/dlls/win32u/syscall.c
+++ b/dlls/win32u/syscall.c
@@ -112,6 +112,7 @@ static void * const syscalls[] =
     NtUserCreateWindowStation,
     NtUserDestroyAcceleratorTable,
     NtUserFindExistingCursorIcon,
+    NtUserGetAtomName,
     NtUserGetClipboardFormatName,
     NtUserGetClipboardOwner,
     NtUserGetClipboardSequenceNumber,
diff --git a/dlls/win32u/tests/win32u.c b/dlls/win32u/tests/win32u.c
index 199a7600341..ef25939d10d 100644
--- a/dlls/win32u/tests/win32u.c
+++ b/dlls/win32u/tests/win32u.c
@@ -104,6 +104,67 @@ static void test_window_props(void)
     DestroyWindow( hwnd );
 }
 
+static void test_class(void)
+{
+    UNICODE_STRING name;
+    WCHAR buf[64];
+    WNDCLASSW cls;
+    ATOM class;
+    ULONG ret;
+
+    memset( &cls, 0, sizeof(cls) );
+    cls.style         = CS_HREDRAW | CS_VREDRAW;
+    cls.lpfnWndProc   = DefWindowProcW;
+    cls.hInstance     = GetModuleHandleW( NULL );
+    cls.hbrBackground = GetStockObject( WHITE_BRUSH );
+    cls.lpszMenuName  = 0;
+    cls.lpszClassName = L"test";
+
+    class = RegisterClassW( &cls );
+    ok( class, "RegisterClassW failed: %lu\n", GetLastError() );
+
+    memset( buf, 0xcc, sizeof(buf) );
+    name.Buffer = buf;
+    name.Length = 0xdead;
+    name.MaximumLength = sizeof(buf);
+    ret = NtUserGetAtomName( class, &name );
+    ok( ret == 4, "NtUserGetAtomName 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 = NtUserGetAtomName( class, &name );
+    ok( ret == 3, "NtUserGetAtomName 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 = NtUserGetAtomName( class, &name );
+    ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+        "NtUserGetAtomName returned %lx %lu\n", ret, GetLastError() );
+
+    ret = UnregisterClassW( L"test", GetModuleHandleW(NULL) );
+    ok( ret, "UnregisterClassW failed: %lu\n", GetLastError() );
+
+    memset( buf, 0xcc, sizeof(buf) );
+    name.Buffer = buf;
+    name.MaximumLength = sizeof(buf);
+    SetLastError( 0xdeadbeef );
+    ret = NtUserGetAtomName( class, &name );
+    ok( !ret && GetLastError() == ERROR_INVALID_HANDLE,
+        "NtUserGetAtomName returned %lx %lu\n", ret, GetLastError() );
+    ok( buf[0] == 0xcccc, "buf = %s\n", debugstr_w(buf) );
+
+}
+
 static BOOL WINAPI count_win( HWND hwnd, LPARAM lparam )
 {
     ULONG *cnt = (ULONG *)lparam;
@@ -293,6 +354,7 @@ START_TEST(win32u)
 
     test_NtUserEnumDisplayDevices();
     test_window_props();
+    test_class();
     test_NtUserBuildHwndList();
     test_cursoricon();
 
diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec
index c9e65de4c24..084c54caf5a 100644
--- a/dlls/win32u/win32u.spec
+++ b/dlls/win32u/win32u.spec
@@ -892,7 +892,7 @@
 @ stub NtUserGetAncestor
 @ stub NtUserGetAppImeLevel
 @ stdcall NtUserGetAsyncKeyState(long)
-@ stub NtUserGetAtomName
+@ stdcall -syscall NtUserGetAtomName(long ptr)
 @ stub NtUserGetAutoRotationState
 @ stub NtUserGetCIMSSM
 @ stub NtUserGetCPD
diff --git a/include/ntuser.h b/include/ntuser.h
index f0daa44f5ad..7f4b3db52d2 100644
--- a/include/ntuser.h
+++ b/include/ntuser.h
@@ -256,6 +256,7 @@ BOOL    WINAPI NtUserEnumDisplaySettings( UNICODE_STRING *device, DWORD mode,
 HICON   WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STRING *res_name,
                                              void *desc );
 SHORT   WINAPI NtUserGetAsyncKeyState( INT key );
+ULONG   WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name );
 INT     WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
 HWND    WINAPI NtUserGetClipboardOwner(void);
 DWORD   WINAPI NtUserGetClipboardSequenceNumber(void);




More information about the wine-cvs mailing list