[PATCH v5 3/3] server: Generalize get_directory_entries to single_entry case.
Jinoh Kang
jinoh.kang.kr at gmail.com
Sun May 8 09:02:10 CDT 2022
From: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
Notes:
v3 -> v4: new patch
v4 -> v5: fix author
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 */
- at REQ(get_directory_entry)
- obj_handle_t handle; /* handle to the directory */
- unsigned int index; /* entry index */
- at 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 */
- at END
-
-
/* Create a symbolic link object */
@REQ(create_symlink)
unsigned int access; /* access flags */
--
2.34.1
More information about the wine-devel
mailing list