[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