diff --git a/dlls/ntdll/atom.c b/dlls/ntdll/atom.c index 8bb66d33fc4..b8487a259dc 100644 --- a/dlls/ntdll/atom.c +++ b/dlls/ntdll/atom.c @@ -54,7 +54,7 @@ static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom ) if (HIWORD( atomstr )) { const WCHAR* ptr = atomstr; - if (!len) return STATUS_INVALID_PARAMETER; + if (!len) return STATUS_OBJECT_NAME_INVALID; if (*ptr++ == '#') { @@ -70,7 +70,7 @@ static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom ) } else atom = LOWORD( atomstr ); done: - if (atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER; + if (!atom || atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER; *pAtom = atom; return STATUS_SUCCESS; } @@ -140,11 +140,11 @@ NTSTATUS WINAPI RtlQueryAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom, UL { if (*len > wlen) { - *len = wlen; memcpy( name, full_name, wlen ); name[wlen / sizeof(WCHAR)] = 0; } else status = STATUS_BUFFER_TOO_SMALL; + *len = wlen; } TRACE( "%p %x -> %s (%lu)\n", @@ -196,7 +196,7 @@ NTSTATUS WINAPI RtlAddAtomToAtomTable( RTL_ATOM_TABLE table, const WCHAR* name, if (!table) status = STATUS_INVALID_PARAMETER; else { - size_t len = strlenW(name); + size_t len = HIWORD(name) ? strlenW(name) : 0; status = is_integral_atom( name, len, atom ); if (status == STATUS_MORE_ENTRIES) { @@ -226,7 +226,7 @@ NTSTATUS WINAPI RtlLookupAtomInAtomTable( RTL_ATOM_TABLE table, const WCHAR* nam if (!table) status = STATUS_INVALID_PARAMETER; else { - size_t len = strlenW(name); + size_t len = HIWORD(name) ? strlenW(name) : 0; status = is_integral_atom( name, len, atom ); if (status == STATUS_MORE_ENTRIES) { @@ -271,19 +271,19 @@ NTSTATUS WINAPI RtlEmptyAtomTable( RTL_ATOM_TABLE table, BOOLEAN delete_pinned ) */ NTSTATUS WINAPI RtlPinAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom ) { - NTSTATUS status = STATUS_INVALID_PARAMETER; + NTSTATUS status; - if (table && atom >= MAXINTATOM) + if (!table) return STATUS_INVALID_PARAMETER; + if (atom < MAXINTATOM) return STATUS_SUCCESS; + + SERVER_START_REQ( set_atom_information ) { - SERVER_START_REQ( set_atom_information ) - { - req->table = table; - req->atom = atom; - req->pinned = TRUE; - status = wine_server_call( req ); - } - SERVER_END_REQ; + req->table = table; + req->atom = atom; + req->pinned = TRUE; + status = wine_server_call( req ); } + SERVER_END_REQ; return status; } diff --git a/server/atom.c b/server/atom.c index 83c80702992..52797cac650 100644 --- a/server/atom.c +++ b/server/atom.c @@ -253,10 +253,12 @@ static atom_t add_atom( struct atom_table *table, const WCHAR *str, size_t len ) } /* delete an atom from the table */ -static void delete_atom( struct atom_table *table, atom_t atom ) +static void delete_atom( struct atom_table *table, atom_t atom, int if_pinned ) { struct atom_entry *entry = get_atom_entry( table, atom ); - if (entry && !--entry->count) + if (!entry) return; + if (entry->pinned && !if_pinned) set_error( STATUS_WAS_LOCKED ); + else if (!--entry->count) { if (entry->next) entry->next->prev = entry->prev; if (entry->prev) entry->prev->next = entry->next; @@ -328,7 +330,7 @@ int grab_global_atom( atom_t atom ) /* decrement the ref count of a global atom; used for window properties */ void release_global_atom( atom_t atom ) { - if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom ); + if (atom >= MIN_STR_ATOM) delete_atom( global_table, atom, 1 ); } /* add a global atom */ @@ -348,7 +350,7 @@ DECL_HANDLER(delete_atom) struct atom_table *table = get_table( req->table ); if (table) { - delete_atom( table, req->atom ); + delete_atom( table, req->atom, 0 ); release_object( table ); } } @@ -376,7 +378,7 @@ DECL_HANDLER(get_atom_information) { size_t len = entry->len * sizeof(WCHAR); if (len <= get_reply_max_size()) set_reply_data( entry->str, len ); - else set_error( STATUS_BUFFER_OVERFLOW ); + else if (get_reply_max_size()) set_error( STATUS_BUFFER_OVERFLOW ); reply->count = entry->count; reply->pinned = entry->pinned; }