server: Generalize get_directory_entries to single_entry case.

This commit is contained in:
Zebediah Figura 2022-04-16 11:26:19 -05:00 committed by Alexandre Julliard
parent af4f252ac4
commit be427c312b
6 changed files with 25 additions and 141 deletions

View file

@ -1143,59 +1143,21 @@ NTSTATUS WINAPI NtQueryDirectoryObject( HANDLE handle, DIRECTORY_BASIC_INFORMATI
ULONG size, BOOLEAN single_entry, BOOLEAN restart,
ULONG *context, ULONG *ret_size )
{
unsigned int status, i, count, pos, used_size, used_count, strpool_head;
unsigned int status, i, count, total_len, pos, used_size, used_count, strpool_head;
ULONG index = restart ? 0 : *context;
struct directory_entry *entries;
if (single_entry)
{
SERVER_START_REQ( get_directory_entry )
{
req->handle = wine_server_obj_handle( handle );
req->index = index;
if (size >= 2 * sizeof(*buffer) + 2 * sizeof(WCHAR))
wine_server_set_reply( req, buffer + 2, size - 2 * sizeof(*buffer) - 2 * sizeof(WCHAR) );
if (!(status = wine_server_call( req )))
{
buffer->ObjectName.Buffer = (WCHAR *)(buffer + 2);
buffer->ObjectName.Length = reply->name_len;
buffer->ObjectName.MaximumLength = reply->name_len + sizeof(WCHAR);
buffer->ObjectTypeName.Buffer = (WCHAR *)(buffer + 2) + reply->name_len/sizeof(WCHAR) + 1;
buffer->ObjectTypeName.Length = wine_server_reply_size( reply ) - reply->name_len;
buffer->ObjectTypeName.MaximumLength = buffer->ObjectTypeName.Length + sizeof(WCHAR);
/* make room for the terminating null */
memmove( buffer->ObjectTypeName.Buffer, buffer->ObjectTypeName.Buffer - 1,
buffer->ObjectTypeName.Length );
buffer->ObjectName.Buffer[buffer->ObjectName.Length/sizeof(WCHAR)] = 0;
buffer->ObjectTypeName.Buffer[buffer->ObjectTypeName.Length/sizeof(WCHAR)] = 0;
memset( &buffer[1], 0, sizeof(buffer[1]) );
*context = index + 1;
}
else if (status == STATUS_NO_MORE_ENTRIES)
{
if (size > sizeof(*buffer))
memset( buffer, 0, sizeof(*buffer) );
if (ret_size) *ret_size = sizeof(*buffer);
}
if (ret_size && (!status || status == STATUS_BUFFER_TOO_SMALL))
*ret_size = 2 * sizeof(*buffer) + reply->total_len + 2 * sizeof(WCHAR);
}
SERVER_END_REQ;
return status;
}
if (!(entries = malloc( size ))) return STATUS_NO_MEMORY;
SERVER_START_REQ( get_directory_entries )
{
req->handle = wine_server_obj_handle( handle );
req->index = index;
req->max_count = single_entry ? 1 : UINT_MAX;
wine_server_set_reply( req, entries, size );
status = wine_server_call( req );
count = reply->count;
total_len = reply->total_len;
}
SERVER_END_REQ;
@ -1260,6 +1222,12 @@ NTSTATUS WINAPI NtQueryDirectoryObject( HANDLE handle, DIRECTORY_BASIC_INFORMATI
return STATUS_NO_MORE_ENTRIES;
}
if (single_entry && !used_count)
{
if (ret_size) *ret_size = 2 * sizeof(*buffer) + 2 * sizeof(WCHAR) + total_len;
return STATUS_BUFFER_TOO_SMALL;
}
*context = index + used_count;
if (ret_size) *ret_size = strpool_head;
return status;

View file

@ -4857,32 +4857,14 @@ struct get_directory_entries_request
struct request_header __header;
obj_handle_t handle;
unsigned int index;
char __pad_20[4];
unsigned int max_count;
};
struct get_directory_entries_reply
{
struct reply_header __header;
data_size_t total_len;
unsigned int count;
/* VARARG(entries,directory_entries); */
char __pad_12[4];
};
struct get_directory_entry_request
{
struct request_header __header;
obj_handle_t handle;
unsigned int index;
char __pad_20[4];
};
struct get_directory_entry_reply
{
struct reply_header __header;
data_size_t total_len;
data_size_t name_len;
/* VARARG(name,unicode_str,name_len); */
/* VARARG(type,unicode_str); */
};
@ -5915,7 +5897,6 @@ enum request
REQ_create_directory,
REQ_open_directory,
REQ_get_directory_entries,
REQ_get_directory_entry,
REQ_create_symlink,
REQ_open_symlink,
REQ_query_symlink,
@ -6208,7 +6189,6 @@ union generic_request
struct create_directory_request create_directory_request;
struct open_directory_request open_directory_request;
struct get_directory_entries_request get_directory_entries_request;
struct get_directory_entry_request get_directory_entry_request;
struct create_symlink_request create_symlink_request;
struct open_symlink_request open_symlink_request;
struct query_symlink_request query_symlink_request;
@ -6499,7 +6479,6 @@ union generic_reply
struct create_directory_reply create_directory_reply;
struct open_directory_reply open_directory_reply;
struct get_directory_entries_reply get_directory_entries_reply;
struct get_directory_entry_reply get_directory_entry_reply;
struct create_symlink_reply create_symlink_reply;
struct open_symlink_reply open_symlink_reply;
struct query_symlink_reply query_symlink_reply;
@ -6555,7 +6534,7 @@ union generic_reply
/* ### protocol_version begin ### */
#define SERVER_PROTOCOL_VERSION 805
#define SERVER_PROTOCOL_VERSION 806
/* ### protocol_version end ### */

View file

@ -545,8 +545,10 @@ DECL_HANDLER(get_directory_entries)
unsigned int i;
char *buffer;
reply->total_len = 0;
size = 0;
for (i = 0; ; i++)
for (i = 0; i < req->max_count; i++)
{
const struct unicode_str *type_name;
data_size_t name_len;
@ -557,6 +559,7 @@ DECL_HANDLER(get_directory_entries)
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 (size + entry_size > get_reply_max_size())
@ -607,41 +610,6 @@ DECL_HANDLER(get_directory_entries)
}
}
/* get a directory entry by index */
DECL_HANDLER(get_directory_entry)
{
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)
{
data_size_t name_len;
const struct unicode_str *type_name = &obj->ops->type->name;
const WCHAR *name = get_object_name( obj, &name_len );
reply->total_len = name_len + type_name->len;
if (reply->total_len <= 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 );
}
}
else set_error( STATUS_BUFFER_TOO_SMALL );
release_object( obj );
}
else set_error( STATUS_NO_MORE_ENTRIES );
release_object( dir );
}
}
/* query object type name information */
DECL_HANDLER(get_object_type)
{

View file

@ -3419,21 +3419,11 @@ struct handle_info
@REQ(get_directory_entries)
obj_handle_t handle; /* handle to the directory */
unsigned int index; /* index of first entry */
@REPLY
unsigned int count; /* number of entries returned */
VARARG(entries,directory_entries);
@END
/* Get a directory entry by index */
@REQ(get_directory_entry)
obj_handle_t handle; /* handle to the directory */
unsigned int index; /* entry index */
unsigned int max_count; /* maximum number of entries to return */
@REPLY
data_size_t total_len; /* total length needed for strings */
data_size_t name_len; /* length of the entry name in bytes */
VARARG(name,unicode_str,name_len); /* entry name */
VARARG(type,unicode_str); /* entry type */
unsigned int count; /* number of entries returned */
VARARG(entries,directory_entries);
@END

View file

@ -353,7 +353,6 @@ DECL_HANDLER(set_mailslot_info);
DECL_HANDLER(create_directory);
DECL_HANDLER(open_directory);
DECL_HANDLER(get_directory_entries);
DECL_HANDLER(get_directory_entry);
DECL_HANDLER(create_symlink);
DECL_HANDLER(open_symlink);
DECL_HANDLER(query_symlink);
@ -645,7 +644,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_create_directory,
(req_handler)req_open_directory,
(req_handler)req_get_directory_entries,
(req_handler)req_get_directory_entry,
(req_handler)req_create_symlink,
(req_handler)req_open_symlink,
(req_handler)req_query_symlink,
@ -2098,15 +2096,11 @@ C_ASSERT( FIELD_OFFSET(struct open_directory_reply, handle) == 8 );
C_ASSERT( sizeof(struct open_directory_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_request, index) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_request, max_count) == 20 );
C_ASSERT( sizeof(struct get_directory_entries_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_reply, count) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_reply, total_len) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entries_reply, count) == 12 );
C_ASSERT( sizeof(struct get_directory_entries_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_request, index) == 16 );
C_ASSERT( sizeof(struct get_directory_entry_request) == 24 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_reply, total_len) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_directory_entry_reply, name_len) == 12 );
C_ASSERT( sizeof(struct get_directory_entry_reply) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_symlink_request, access) == 12 );
C_ASSERT( sizeof(struct create_symlink_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct create_symlink_reply, handle) == 8 );

View file

@ -4123,26 +4123,14 @@ static void dump_get_directory_entries_request( const struct get_directory_entri
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", index=%08x", req->index );
fprintf( stderr, ", max_count=%08x", req->max_count );
}
static void dump_get_directory_entries_reply( const struct get_directory_entries_reply *req )
{
fprintf( stderr, " count=%08x", req->count );
dump_varargs_directory_entries( ", entries=", cur_size );
}
static void dump_get_directory_entry_request( const struct get_directory_entry_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", index=%08x", req->index );
}
static void dump_get_directory_entry_reply( const struct get_directory_entry_reply *req )
{
fprintf( stderr, " total_len=%u", req->total_len );
fprintf( stderr, ", name_len=%u", req->name_len );
dump_varargs_unicode_str( ", name=", min(cur_size,req->name_len) );
dump_varargs_unicode_str( ", type=", cur_size );
fprintf( stderr, ", count=%08x", req->count );
dump_varargs_directory_entries( ", entries=", cur_size );
}
static void dump_create_symlink_request( const struct create_symlink_request *req )
@ -4883,7 +4871,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_directory_request,
(dump_func)dump_open_directory_request,
(dump_func)dump_get_directory_entries_request,
(dump_func)dump_get_directory_entry_request,
(dump_func)dump_create_symlink_request,
(dump_func)dump_open_symlink_request,
(dump_func)dump_query_symlink_request,
@ -5172,7 +5159,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_create_directory_reply,
(dump_func)dump_open_directory_reply,
(dump_func)dump_get_directory_entries_reply,
(dump_func)dump_get_directory_entry_reply,
(dump_func)dump_create_symlink_reply,
(dump_func)dump_open_symlink_reply,
(dump_func)dump_query_symlink_reply,
@ -5461,7 +5447,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"create_directory",
"open_directory",
"get_directory_entries",
"get_directory_entry",
"create_symlink",
"open_symlink",
"query_symlink",