server: Allow server side NtQueryVolumeInformationFile implementation.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index c12110e..217b678 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -3212,8 +3212,21 @@
struct stat st;
static int once;
- if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )) != STATUS_SUCCESS)
+ io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL );
+ if (io->u.Status == STATUS_BAD_DEVICE_TYPE)
+ {
+ SERVER_START_REQ( get_volume_info )
+ {
+ req->handle = wine_server_obj_handle( handle );
+ req->info_class = info_class;
+ wine_server_set_reply( req, buffer, length );
+ io->u.Status = wine_server_call( req );
+ if (!io->u.Status) io->Information = wine_server_reply_size( reply );
+ }
+ SERVER_END_REQ;
return io->u.Status;
+ }
+ else if (io->u.Status) return io->u.Status;
io->u.Status = STATUS_NOT_IMPLEMENTED;
io->Information = 0;
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 71137f8..2bc2779 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1536,6 +1536,19 @@
};
+struct get_volume_info_request
+{
+ struct request_header __header;
+ obj_handle_t handle;
+ unsigned int info_class;
+ char __pad_20[4];
+};
+struct get_volume_info_reply
+{
+ struct reply_header __header;
+ /* VARARG(data,bytes); */
+};
+
struct lock_file_request
{
@@ -5632,6 +5645,7 @@
REQ_get_handle_fd,
REQ_get_directory_cache_entry,
REQ_flush,
+ REQ_get_volume_info,
REQ_lock_file,
REQ_unlock_file,
REQ_create_socket,
@@ -5926,6 +5940,7 @@
struct get_handle_fd_request get_handle_fd_request;
struct get_directory_cache_entry_request get_directory_cache_entry_request;
struct flush_request flush_request;
+ struct get_volume_info_request get_volume_info_request;
struct lock_file_request lock_file_request;
struct unlock_file_request unlock_file_request;
struct create_socket_request create_socket_request;
@@ -6218,6 +6233,7 @@
struct get_handle_fd_reply get_handle_fd_reply;
struct get_directory_cache_entry_reply get_directory_cache_entry_reply;
struct flush_reply flush_reply;
+ struct get_volume_info_reply get_volume_info_reply;
struct lock_file_reply lock_file_reply;
struct unlock_file_reply unlock_file_reply;
struct create_socket_reply create_socket_reply;
@@ -6459,6 +6475,6 @@
struct terminate_job_reply terminate_job_reply;
};
-#define SERVER_PROTOCOL_VERSION 542
+#define SERVER_PROTOCOL_VERSION 543
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/change.c b/server/change.c
index 4dd7933..c5c88da 100644
--- a/server/change.c
+++ b/server/change.c
@@ -187,6 +187,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/console.c b/server/console.c
index 5b69e76..cb6410b 100644
--- a/server/console.c
+++ b/server/console.c
@@ -191,6 +191,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/device.c b/server/device.c
index 192395d..90a4b6e 100644
--- a/server/device.c
+++ b/server/device.c
@@ -209,6 +209,7 @@
device_file_read, /* read */
device_file_write, /* write */
device_file_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
device_file_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/fd.c b/server/fd.c
index 9322e2c..fa2b18a 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -2175,6 +2175,12 @@
return 0;
}
+/* default get_volume_info() routine */
+void no_fd_get_volume_info( struct fd *fd, unsigned int info_class )
+{
+ set_error( STATUS_OBJECT_TYPE_MISMATCH );
+}
+
/* default ioctl() routine */
int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
{
@@ -2378,6 +2384,18 @@
release_object( fd );
}
+/* query volume info */
+DECL_HANDLER(get_volume_info)
+{
+ struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
+
+ if (fd)
+ {
+ fd->fd_ops->get_volume_info( fd, req->info_class );
+ release_object( fd );
+ }
+}
+
/* open a file object */
DECL_HANDLER(open_file_object)
{
diff --git a/server/file.c b/server/file.c
index 39c8150..6c036ac 100644
--- a/server/file.c
+++ b/server/file.c
@@ -107,6 +107,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
file_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/file.h b/server/file.h
index 15b60b7..403da65 100644
--- a/server/file.h
+++ b/server/file.h
@@ -62,6 +62,8 @@
int (*write)(struct fd *, struct async *, file_pos_t );
/* flush the object buffers */
int (*flush)(struct fd *, struct async *);
+ /* query volume info */
+ void (*get_volume_info)( struct fd *, unsigned int );
/* perform an ioctl on the file */
int (*ioctl)(struct fd *fd, ioctl_code_t code, struct async *async );
/* queue an async operation */
@@ -108,6 +110,7 @@
extern int no_fd_read( struct fd *fd, struct async *async, file_pos_t pos );
extern int no_fd_write( struct fd *fd, struct async *async, file_pos_t pos );
extern int no_fd_flush( struct fd *fd, struct async *async );
+extern void no_fd_get_volume_info( struct fd *fd, unsigned int info_class );
extern int no_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern int default_fd_ioctl( struct fd *fd, ioctl_code_t code, struct async *async );
extern void no_fd_queue_async( struct fd *fd, struct async *async, int type, int count );
diff --git a/server/mailslot.c b/server/mailslot.c
index d7affa5..9fafedb 100644
--- a/server/mailslot.c
+++ b/server/mailslot.c
@@ -104,6 +104,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
mailslot_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
@@ -157,6 +158,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
@@ -210,6 +212,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/mapping.c b/server/mapping.c
index b2d334c..57641d1 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -143,6 +143,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
no_fd_ioctl, /* ioctl */
no_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/named_pipe.c b/server/named_pipe.c
index 9cd424f..6dd2fd6 100644
--- a/server/named_pipe.c
+++ b/server/named_pipe.c
@@ -196,6 +196,7 @@
pipe_end_read, /* read */
pipe_end_write, /* write */
pipe_server_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
pipe_server_ioctl, /* ioctl */
pipe_end_queue_async, /* queue_async */
pipe_end_reselect_async /* reselect_async */
@@ -239,6 +240,7 @@
pipe_end_read, /* read */
pipe_end_write, /* write */
pipe_client_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
pipe_client_ioctl, /* ioctl */
pipe_end_queue_async, /* queue_async */
pipe_end_reselect_async /* reselect_async */
@@ -285,6 +287,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
named_pipe_device_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
default_fd_reselect_async /* reselect_async */
diff --git a/server/protocol.def b/server/protocol.def
index b0372a2..2e74d60 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -1259,6 +1259,13 @@
obj_handle_t event; /* event set when finished */
@END
+/* Queries volume information */
+@REQ(get_volume_info)
+ obj_handle_t handle; /* handle to the file */
+ unsigned int info_class; /* queried information class */
+@REPLY
+ VARARG(data,bytes); /* volume info data */
+@END
/* Lock a region of a file */
@REQ(lock_file)
diff --git a/server/request.h b/server/request.h
index a6ca556..7747ce3 100644
--- a/server/request.h
+++ b/server/request.h
@@ -160,6 +160,7 @@
DECL_HANDLER(get_handle_fd);
DECL_HANDLER(get_directory_cache_entry);
DECL_HANDLER(flush);
+DECL_HANDLER(get_volume_info);
DECL_HANDLER(lock_file);
DECL_HANDLER(unlock_file);
DECL_HANDLER(create_socket);
@@ -453,6 +454,7 @@
(req_handler)req_get_handle_fd,
(req_handler)req_get_directory_cache_entry,
(req_handler)req_flush,
+ (req_handler)req_get_volume_info,
(req_handler)req_lock_file,
(req_handler)req_unlock_file,
(req_handler)req_create_socket,
@@ -1029,6 +1031,10 @@
C_ASSERT( sizeof(struct flush_request) == 56 );
C_ASSERT( FIELD_OFFSET(struct flush_reply, event) == 8 );
C_ASSERT( sizeof(struct flush_reply) == 16 );
+C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, handle) == 12 );
+C_ASSERT( FIELD_OFFSET(struct get_volume_info_request, info_class) == 16 );
+C_ASSERT( sizeof(struct get_volume_info_request) == 24 );
+C_ASSERT( sizeof(struct get_volume_info_reply) == 8 );
C_ASSERT( FIELD_OFFSET(struct lock_file_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct lock_file_request, offset) == 16 );
C_ASSERT( FIELD_OFFSET(struct lock_file_request, count) == 24 );
diff --git a/server/serial.c b/server/serial.c
index 85dd104..f7aaebb 100644
--- a/server/serial.c
+++ b/server/serial.c
@@ -114,6 +114,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
serial_ioctl, /* ioctl */
serial_queue_async, /* queue_async */
serial_reselect_async /* reselect_async */
diff --git a/server/sock.c b/server/sock.c
index cc9bbcc..1e12618 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -167,6 +167,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
sock_ioctl, /* ioctl */
sock_queue_async, /* queue_async */
sock_reselect_async /* reselect_async */
@@ -990,6 +991,7 @@
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
+ no_fd_get_volume_info, /* get_volume_info */
no_fd_ioctl, /* ioctl */
NULL, /* queue_async */
NULL /* reselect_async */
diff --git a/server/trace.c b/server/trace.c
index 2aa934c..6662d9a 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1807,6 +1807,17 @@
fprintf( stderr, " event=%04x", req->event );
}
+static void dump_get_volume_info_request( const struct get_volume_info_request *req )
+{
+ fprintf( stderr, " handle=%04x", req->handle );
+ fprintf( stderr, ", info_class=%08x", req->info_class );
+}
+
+static void dump_get_volume_info_reply( const struct get_volume_info_reply *req )
+{
+ dump_varargs_bytes( " data=", cur_size );
+}
+
static void dump_lock_file_request( const struct lock_file_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
@@ -4533,6 +4544,7 @@
(dump_func)dump_get_handle_fd_request,
(dump_func)dump_get_directory_cache_entry_request,
(dump_func)dump_flush_request,
+ (dump_func)dump_get_volume_info_request,
(dump_func)dump_lock_file_request,
(dump_func)dump_unlock_file_request,
(dump_func)dump_create_socket_request,
@@ -4823,6 +4835,7 @@
(dump_func)dump_get_handle_fd_reply,
(dump_func)dump_get_directory_cache_entry_reply,
(dump_func)dump_flush_reply,
+ (dump_func)dump_get_volume_info_reply,
(dump_func)dump_lock_file_reply,
NULL,
(dump_func)dump_create_socket_reply,
@@ -5113,6 +5126,7 @@
"get_handle_fd",
"get_directory_cache_entry",
"flush",
+ "get_volume_info",
"lock_file",
"unlock_file",
"create_socket",