server: Add support for returning the object name in NtQueryObject.
diff --git a/server/handle.c b/server/handle.c
index 3baaa6d..4e52f0e 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -593,11 +593,14 @@
DECL_HANDLER(get_object_info)
{
struct object *obj;
+ WCHAR *name;
if (!(obj = get_handle_obj( current->process, req->handle, 0, NULL ))) return;
reply->access = get_handle_access( current->process, req->handle );
reply->ref_count = obj->refcount;
+ if ((name = get_object_full_name( obj, &reply->total )))
+ set_reply_data_ptr( name, min( reply->total, get_reply_max_size() ));
release_object( obj );
}
diff --git a/server/object.c b/server/object.c
index f08548c..d2a3930 100644
--- a/server/object.c
+++ b/server/object.c
@@ -171,6 +171,35 @@
return ptr->name;
}
+/* get the full path name of an existing object */
+WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len )
+{
+ static const WCHAR backslash = '\\';
+ struct object *ptr = obj;
+ data_size_t len = 0;
+ char *ret;
+
+ while (ptr && ptr->name)
+ {
+ struct object_name *name = ptr->name;
+ len += name->len + sizeof(WCHAR);
+ ptr = name->parent;
+ }
+ if (!len) return NULL;
+ if (!(ret = malloc( len ))) return NULL;
+
+ *ret_len = len;
+ while (obj && obj->name)
+ {
+ struct object_name *name = obj->name;
+ memcpy( ret + len - name->len, name->name, name->len );
+ len -= name->len + sizeof(WCHAR);
+ memcpy( ret + len, &backslash, sizeof(WCHAR) );
+ obj = name->parent;
+ }
+ return (WCHAR *)ret;
+}
+
/* allocate and initialize an object */
void *alloc_object( const struct object_ops *ops )
{
diff --git a/server/object.h b/server/object.h
index a5d0ffd..01dc00e 100644
--- a/server/object.h
+++ b/server/object.h
@@ -115,6 +115,7 @@
extern void *memdup( const void *data, size_t len );
extern void *alloc_object( const struct object_ops *ops );
extern const WCHAR *get_object_name( struct object *obj, data_size_t *len );
+extern WCHAR *get_object_full_name( struct object *obj, data_size_t *ret_len );
extern void dump_object_name( struct object *obj );
extern void *create_object( struct namespace *namespace, const struct object_ops *ops,
const struct unicode_str *name, struct object *parent );
diff --git a/server/protocol.def b/server/protocol.def
index bba6788..04f6e2b 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3061,6 +3061,8 @@
@REPLY
unsigned int access; /* granted access mask */
unsigned int ref_count; /* object ref count */
+ data_size_t total; /* total needed size for name */
+ VARARG(name,unicode_str); /* object name */
@END
diff --git a/server/request.h b/server/request.h
index ca5fc88..41c6409 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1817,7 +1817,8 @@
C_ASSERT( FIELD_OFFSET(struct get_object_info_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, access) == 8 );
C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, ref_count) == 12 );
-C_ASSERT( sizeof(struct get_object_info_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_object_info_reply, total) == 16 );
+C_ASSERT( sizeof(struct get_object_info_reply) == 24 );
C_ASSERT( FIELD_OFFSET(struct unlink_object_request, handle) == 12 );
C_ASSERT( sizeof(struct unlink_object_request) == 16 );
C_ASSERT( FIELD_OFFSET(struct get_token_impersonation_level_request, handle) == 12 );
diff --git a/server/trace.c b/server/trace.c
index df47e8f..03e4c04 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -3600,6 +3600,8 @@
{
fprintf( stderr, " access=%08x", req->access );
fprintf( stderr, ", ref_count=%08x", req->ref_count );
+ fprintf( stderr, ", total=%u", req->total );
+ dump_varargs_unicode_str( ", name=", cur_size );
}
static void dump_unlink_object_request( const struct unlink_object_request *req )