Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com ---
Notes: v3 -> v4: new patch
dlls/ntdll/unix/sync.c | 50 ++++++++---------------------------------- server/directory.c | 40 ++++----------------------------- server/protocol.def | 14 ++---------- 3 files changed, 15 insertions(+), 89 deletions(-)
diff --git a/dlls/ntdll/unix/sync.c b/dlls/ntdll/unix/sync.c index cce1ac6f264..1c7d8cb000d 100644 --- a/dlls/ntdll/unix/sync.c +++ b/dlls/ntdll/unix/sync.c @@ -1110,61 +1110,23 @@ NTSTATUS WINAPI NtQueryDirectoryObject( HANDLE handle, DIRECTORY_BASIC_INFORMATI ULONG size, BOOLEAN single_entry, BOOLEAN restart, ULONG *context, ULONG *ret_size ) { - unsigned int i, count, pos, used_size, used_count; + unsigned int i, count, total_len, pos, used_size, used_count; ULONG index = restart ? 0 : *context; struct directory_entry *entries; NTSTATUS status; char *p;
- 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;
@@ -1224,6 +1186,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 = (char *)p - (char *)buffer; return status; diff --git a/server/directory.c b/server/directory.c index f35e5f35ede..2abac6c2fa7 100644 --- a/server/directory.c +++ b/server/directory.c @@ -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) { diff --git a/server/protocol.def b/server/protocol.def index 7a06a6e8455..4530b172263 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3283,24 +3283,14 @@ struct handle_info @REQ(get_directory_entries) obj_handle_t handle; /* handle to the directory */ unsigned int index; /* index of first entry */ + unsigned int max_count; /* maximum number of entries to return */ @REPLY + data_size_t total_len; /* total length needed for strings */ 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 */ -@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 */ -@END - - /* Create a symbolic link object */ @REQ(create_symlink) unsigned int access; /* access flags */