[Wine-patches] [eterhack] [0008/0021] ntoskrnl.exe: Partially implement IoGetDeviceObjectPointer.

Alexander Morozov =?iso-8859-1?q?amorozov_=CE=C1_etersoft=2Eru?=
Ср Янв 28 21:10:05 MSK 2009


---
 dlls/ntoskrnl.exe/ntoskrnl.c |   27 ++++++++++++++++++++++-----
 server/device.c              |   40 ++++++++++++++++++++++++++++++++++++++++
 server/protocol.def          |    9 +++++++++
 3 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 3122911..cbfab26 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -48,6 +48,8 @@ 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
@@ -1399,8 +1401,24 @@ NTSTATUS WINAPI IoSetDeviceInterfaceState( PUNICODE_STRING SymbolicLinkName,
  */
 NTSTATUS  WINAPI IoGetDeviceObjectPointer( UNICODE_STRING *name, ACCESS_MASK access, PFILE_OBJECT *file, PDEVICE_OBJECT *device )
 {
-    FIXME( "stub: %s %x %p %p\n", debugstr_us(name), access, file, device );
-    return STATUS_NOT_IMPLEMENTED;
+    HANDLE manager = get_device_manager();
+    NTSTATUS status;
+
+    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->manager = wine_server_obj_handle( manager );
+        wine_server_add_data( req, name->Buffer + 8, name->Length - 8 * sizeof(WCHAR) );
+        status = wine_server_call( req );
+        *device = wine_server_get_ptr( reply->user_ptr );
+    }
+    SERVER_END_REQ;
+
+    return status;
 }
 
 
@@ -1421,7 +1439,6 @@ NTSTATUS WINAPI IoGetDeviceProperty( PDEVICE_OBJECT DeviceObject,
     {
     case DevicePropertyPhysicalDeviceObjectName:
     {
-        static const WCHAR device[] = {'\\','D','e','v','i','c','e','\\',0};
         WCHAR device_name[MAX_PATH];
         data_size_t len;
 
@@ -1435,10 +1452,10 @@ NTSTATUS WINAPI IoGetDeviceProperty( PDEVICE_OBJECT DeviceObject,
         }
         SERVER_END_REQ;
 
-        *ResultLength = len + sizeof(device);
+        *ResultLength = len + sizeof(deviceW);
         if (BufferLength >= *ResultLength)
         {
-            strcpyW( PropertyBuffer, device );
+            strcpyW( PropertyBuffer, deviceW );
             device_name[len / sizeof(WCHAR)] = 0;
             strcatW( PropertyBuffer, device_name );
         }
diff --git a/server/device.c b/server/device.c
index acfcd2b..6942565 100644
--- a/server/device.c
+++ b/server/device.c
@@ -34,6 +34,8 @@
 #include "request.h"
 #include "process.h"
 
+#include "wine/unicode.h"
+
 struct ioctl_call
 {
     struct object          obj;           /* object header */
@@ -579,3 +581,41 @@ DECL_HANDLER(get_device_name)
 
     release_object( device );
 }
+
+
+/* get the device with given name */
+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;
+
+    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)
+    {
+        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 );
+    if (!reply->user_ptr)
+        set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+}
diff --git a/server/protocol.def b/server/protocol.def
index 803885f..7aa6718 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3124,3 +3124,12 @@ enum message_type
 @REPLY
     VARARG(name,unicode_str);     /* device name */
 @END
+
+
+/* Get the device with given name */
+ на REQ(get_device)
+    obj_handle_t manager;         /* device manager */
+    VARARG(name,unicode_str);     /* device name */
+ на REPLY
+    client_ptr_t user_ptr;        /* opaque ptr for client side */
+ на END
-- 
1.6.0.2.GIT



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