[Wine-patches] [eterhack 13/24] Fix problem with using IoGetDeviceObjectPointer for symbolic links.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Ср Мар 4 12:25:22 MSK 2009


---
 dlls/ntoskrnl.exe/ntoskrnl.c   |   11 +++++------
 include/wine/server_protocol.h |    4 +++-
 server/device.c                |   28 +++++++++++-----------------
 server/protocol.def            |    2 ++
 server/request.h               |    4 +++-
 server/trace.c                 |    2 ++
 6 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 097a696..a354b78 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -50,8 +50,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(ntoskrnl);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
 
-static const WCHAR deviceW[] = {'\\','D','e','v','i','c','e','\\',0};
-
 KSYSTEM_TIME KeTickCount = { 0, 0, 0 };
 
 typedef struct _KSERVICE_TABLE_DESCRIPTOR
@@ -1583,13 +1581,12 @@ NTSTATUS  WINAPI IoGetDeviceObjectPointer( UNICODE_STRING *name, ACCESS_MASK acc
 
     TRACE( "%s %x %p %p\n", debugstr_us(name), access, file, device );
 
-    if ((name->Length <= 8 * sizeof(WCHAR)) || strncmpW( name->Buffer, deviceW, 8 ))
-        return STATUS_OBJECT_PATH_SYNTAX_BAD;
-
     SERVER_START_REQ( get_device )
     {
+        req->attributes = OBJ_CASE_INSENSITIVE;
+        req->rootdir = 0;
         req->manager = wine_server_obj_handle( manager );
-        wine_server_add_data( req, name->Buffer + 8, name->Length - 8 * sizeof(WCHAR) );
+        wine_server_add_data( req, name->Buffer, name->Length );
         status = wine_server_call( req );
         *device = wine_server_get_ptr( reply->user_ptr );
     }
@@ -1607,6 +1604,8 @@ NTSTATUS WINAPI IoGetDeviceProperty( PDEVICE_OBJECT DeviceObject,
                                      ULONG BufferLength, PVOID PropertyBuffer,
                                      PULONG ResultLength )
 {
+    static const WCHAR deviceW[] = {'\\','D','e','v','i','c','e','\\',0};
+
     NTSTATUS status;
 
     TRACE( "%p %u %u %p %p\n", DeviceObject, DeviceProperty, BufferLength,
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 3e70299..43d7658 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -4510,6 +4510,8 @@ struct get_device_name_reply
 struct get_device_request
 {
     struct request_header __header;
+    unsigned int attributes;
+    obj_handle_t rootdir;
     obj_handle_t manager;
     /* VARARG(name,unicode_str); */
 };
@@ -5250,6 +5252,6 @@ union generic_reply
     struct get_device_reply get_device_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 10383
+#define SERVER_PROTOCOL_VERSION 10384
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/device.c b/server/device.c
index 6942565..23ef9c9 100644
--- a/server/device.c
+++ b/server/device.c
@@ -589,33 +589,27 @@ DECL_HANDLER(get_device)
     struct device *device;
     struct device_manager *manager;
     struct unicode_str name;
-    const WCHAR *device_name;
-    data_size_t device_name_len;
+    struct directory *root = NULL;
 
     reply->user_ptr = 0;
     get_req_unicode_str( &name );
-    if (!name.len)
-    {
-        set_error( STATUS_OBJECT_PATH_SYNTAX_BAD );
-        return;
-    }
 
     if (!(manager = (struct device_manager *)get_handle_obj( current->process, req->manager,
                                                              0, &device_manager_ops )))
         return;
 
-    LIST_FOR_EACH_ENTRY(device, &manager->devices, struct device, entry)
+    if (req->rootdir && !(root = get_directory_obj( current->process, req->rootdir, 0 )))
     {
-        device_name = get_object_name( &device->obj, &device_name_len );
-        if (device_name_len == name.len)
-            if (!strncmpW( device_name, name.str, device_name_len / sizeof(WCHAR) ))
-            {
-                reply->user_ptr = device->user_ptr;
-                break;
-            }
+        release_object( manager );
+        return;
+    }
+
+    if ((device = open_object_dir( root, &name, req->attributes, &device_ops )))
+    {
+        reply->user_ptr = device->user_ptr;
+        release_object( device );
     }
 
+    if (root) release_object( root );
     release_object( manager );
-    if (!reply->user_ptr)
-        set_error( STATUS_OBJECT_NAME_NOT_FOUND );
 }
diff --git a/server/protocol.def b/server/protocol.def
index 7aa6718..2bdb13e 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3128,6 +3128,8 @@ enum message_type
 
 /* Get the device with given name */
 @REQ(get_device)
+    unsigned int attributes;      /* object attributes */
+    obj_handle_t rootdir;         /* root directory */
     obj_handle_t manager;         /* device manager */
     VARARG(name,unicode_str);     /* device name */
 @REPLY
diff --git a/server/request.h b/server/request.h
index 1f9714c..4a9044f 100644
--- a/server/request.h
+++ b/server/request.h
@@ -1891,7 +1891,9 @@ C_ASSERT( FIELD_OFFSET(struct set_window_layered_info_request, flags) == 24 );
 C_ASSERT( sizeof(struct set_window_layered_info_request) == 32 );
 C_ASSERT( FIELD_OFFSET(struct get_device_name_request, handle) == 12 );
 C_ASSERT( sizeof(struct get_device_name_reply) == 8 );
-C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 12 );
+C_ASSERT( FIELD_OFFSET(struct get_device_request, attributes) == 12 );
+C_ASSERT( FIELD_OFFSET(struct get_device_request, rootdir) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_device_request, manager) == 20 );
 C_ASSERT( FIELD_OFFSET(struct get_device_reply, user_ptr) == 8 );
 C_ASSERT( sizeof(struct get_device_reply) == 16 );
 
diff --git a/server/trace.c b/server/trace.c
index 5a89e59..33a4467 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -4027,6 +4027,8 @@ static void dump_get_device_name_reply( const struct get_device_name_reply *req
 
 static void dump_get_device_request( const struct get_device_request *req )
 {
+    fprintf( stderr, " attributes=%08x,", req->attributes );
+    fprintf( stderr, " rootdir=%04x,", req->rootdir );
     fprintf( stderr, " manager=%04x,", req->manager );
     fprintf( stderr, " name=" );
     dump_varargs_unicode_str( cur_size );
-- 
1.6.1.3.GIT



Подробная информация о списке рассылки Wine-patches