[PATCH v2 4/4] ntdll: Implement reading multiple entries in NtQueryDirectoryObject.
Jinoh Kang
jinoh.kang.kr at gmail.com
Sat Apr 16 01:42:11 CDT 2022
On 4/13/22 12:00, Zebediah Figura wrote:
> diff --git a/server/directory.c b/server/directory.c
> index 23d7eb0a2b7..52033ca5e9e 100644
> --- a/server/directory.c
> +++ b/server/directory.c
> @@ -533,32 +533,76 @@ DECL_HANDLER(open_directory)
> }
>
> /* get a directory entry by index */
> -DECL_HANDLER(get_directory_entry)
> +DECL_HANDLER(get_directory_entries)
> {
> struct directory *dir = (struct directory *)get_handle_obj( current->process, req->handle,
> DIRECTORY_QUERY, &directory_ops );
> if (dir)
> {
> - struct object *obj = find_object_index( dir->entries, req->index );
> - if (obj)
> + struct directory_entry *entry;
> + struct object *obj;
> + data_size_t size;
> + unsigned int i;
> + char *buffer;
> +
> + reply->total_len = 0;
> +
> + size = 0;
> + for (i = 0; i < req->max_count; ++i)
> {
> + const struct unicode_str *type_name;
> data_size_t name_len;
> - const struct unicode_str *type_name = &obj->ops->type->name;
> - const WCHAR *name = get_object_name( obj, &name_len );
> + size_t entry_size;
>
> - reply->total_len = name_len + type_name->len;
> + if (!(obj = find_object_index( dir->entries, req->index + i )))
> + break;
> + type_name = &obj->ops->type->name;
> + get_object_name( obj, &name_len );
> + entry_size = (sizeof(*entry) + name_len + type_name->len + 3) & ~3;
> + reply->total_len += name_len + type_name->len;
> + release_object( obj );
>
> - if (reply->total_len <= get_reply_max_size())
> + if (size + entry_size > get_reply_max_size())
> {
> - void *ptr = set_reply_data_size( reply->total_len );
> - if (ptr)
> - {
> - reply->name_len = name_len;
> - memcpy( ptr, name, name_len );
> - memcpy( (char *)ptr + name_len, type_name->str, type_name->len );
> - }
> + set_error( STATUS_MORE_ENTRIES );
> + break;
> + }
> + size += entry_size;
> + }
> + reply->count = i;
> +
> + if (!(buffer = set_reply_data_size( size )))
> + {
> + release_object( dir );
> + return;
> + }
> +
> + size = 0;
> + for (i = 0; i < reply->count; ++i)
> + {
> + const struct unicode_str *type_name;
> + data_size_t name_len;
> + const WCHAR *name;
> +
> + obj = find_object_index( dir->entries, req->index + i );
> + assert( obj );
> + type_name = &obj->ops->type->name;
> + name = get_object_name( obj, &name_len );
> +
> + entry = (struct directory_entry *)(buffer + size);
> + entry->name_len = name_len;
> + entry->type_len = type_name->len;
> +
> + size += sizeof(entry);
s/sizeof(entry)/sizeof(*entry)/
> + memcpy( buffer + size, name, name_len );
> + size += name_len;
> + memcpy( buffer + size, type_name->str, type_name->len );
> + size += type_name->len;
> + if (size & 3)
> + {
> + memset( buffer + size, 0, 4 - (size & 3) );
> + size += 4 - (size & 3);
> }
> - else set_error( STATUS_BUFFER_TOO_SMALL );
>
> release_object( obj );
> }
--
Sincerely,
Jinoh Kang
More information about the wine-devel
mailing list