From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/class.c | 52 ++++++++++++++++++++++++++++++++++++++------- server/atom.c | 12 +++++++++++ server/protocol.def | 9 ++++++++ 3 files changed, 65 insertions(+), 8 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c index 1180a62d055..abe94e6be62 100644 --- a/dlls/win32u/class.c +++ b/dlls/win32u/class.c @@ -302,6 +302,21 @@ ATOM get_int_atom_value( UNICODE_STRING *name ) return ret; }
+static ULONG integral_atom_name( WCHAR *buffer, ULONG len, RTL_ATOM atom ) +{ + char tmp[16]; + int ret = snprintf( tmp, sizeof(tmp), "#%u", atom ); + + len /= sizeof(WCHAR); + if (len) + { + if (len <= ret) ret = len - 1; + ascii_to_unicode( buffer, tmp, ret ); + buffer[ret] = 0; + } + return ret * sizeof(WCHAR); +} + /*********************************************************************** * get_class_ptr */ @@ -575,13 +590,34 @@ ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDC */ 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; + WCHAR buffer[MAX_ATOM_LEN]; + UINT size = 0;
- if (!set_ntstatus( NtQueryInformationAtom( atom, AtomBasicInformation, - buf, sizeof(buf), NULL ))) - return 0; + if (atom < MAXINTATOM) + { + if (!atom) + { + set_ntstatus( STATUS_INVALID_PARAMETER ); + return 0; + } + + size = integral_atom_name( buffer, sizeof(buffer), atom ); + } + else + { + SERVER_START_REQ( get_user_atom_name ) + { + req->atom = atom; + wine_server_set_reply( req, buffer, sizeof(buffer) ); + if (!wine_server_call_err( req )) + { + size = wine_server_reply_size( reply ); + buffer[size / sizeof(WCHAR)] = 0; + } + } + SERVER_END_REQ; + if (!size) return 0; + }
if (name->MaximumLength < sizeof(WCHAR)) { @@ -589,8 +625,8 @@ ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name ) return 0; }
- size = min( abi->NameLength, name->MaximumLength - sizeof(WCHAR) ); - if (size) memcpy( name->Buffer, abi->Name, size ); + size = min( size, name->MaximumLength - sizeof(WCHAR) ); + if (size) memcpy( name->Buffer, buffer, size ); name->Buffer[size / sizeof(WCHAR)] = 0; return size / sizeof(WCHAR); } diff --git a/server/atom.c b/server/atom.c index 3a0992e33d5..4fd9df14526 100644 --- a/server/atom.c +++ b/server/atom.c @@ -326,3 +326,15 @@ DECL_HANDLER(get_atom_information) } else reply->count = -1; } + +/* get a user atom name */ +DECL_HANDLER(get_user_atom_name) +{ + struct atom_entry *entry; + + if ((entry = get_atom_entry( global_table, req->atom ))) + { + set_reply_data( (void *)entry->str, min( entry->len, get_reply_max_size() )); + reply->total = entry->len; + } +} diff --git a/server/protocol.def b/server/protocol.def index 66d9f3e930b..cccb924e612 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2233,6 +2233,15 @@ struct process_info @END
+/* Get a user atom name */ +@REQ(get_user_atom_name) + atom_t atom; /* atom handle */ +@REPLY + data_size_t total; /* actual length of atom name */ + VARARG(name,unicode_str); /* atom name */ +@END + + /* Get a handle for the current thread message queue */ @REQ(get_msg_queue_handle) @REPLY