server: Introduce get_file_info request for server-side NtQueryInformationFile implementation.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2017-12-21 16:12:01 +01:00 committed by Alexandre Julliard
parent 514a157541
commit 6b08e60f03
16 changed files with 102 additions and 3 deletions

View File

@ -2198,6 +2198,22 @@ static NTSTATUS fill_name_info( const ANSI_STRING *unix_name, FILE_NAME_INFORMAT
return status;
}
static NTSTATUS server_get_file_info( HANDLE handle, IO_STATUS_BLOCK *io, void *buffer,
ULONG length, FILE_INFORMATION_CLASS info_class )
{
SERVER_START_REQ( get_file_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 );
io->Information = wine_server_reply_size( reply );
}
SERVER_END_REQ;
return io->u.Status;
}
/******************************************************************************
* NtQueryInformationFile [NTDLL.@]
* ZwQueryInformationFile [NTDLL.@]
@ -2307,7 +2323,10 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (class != FilePipeInformation && class != FilePipeLocalInformation)
{
if ((io->u.Status = server_get_unix_fd( hFile, 0, &fd, &needs_close, NULL, NULL )))
return io->u.Status;
{
if (io->u.Status != STATUS_BAD_DEVICE_TYPE) return io->u.Status;
return server_get_file_info( hFile, io, ptr, len, class );
}
}
switch (class)

View File

@ -1540,6 +1540,20 @@ struct flush_reply
};
struct get_file_info_request
{
struct request_header __header;
obj_handle_t handle;
unsigned int info_class;
char __pad_20[4];
};
struct get_file_info_reply
{
struct reply_header __header;
/* VARARG(data,bytes); */
};
struct get_volume_info_request
{
struct request_header __header;
@ -5649,6 +5663,7 @@ enum request
REQ_get_handle_fd,
REQ_get_directory_cache_entry,
REQ_flush,
REQ_get_file_info,
REQ_get_volume_info,
REQ_lock_file,
REQ_unlock_file,
@ -5944,6 +5959,7 @@ union generic_request
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_file_info_request get_file_info_request;
struct get_volume_info_request get_volume_info_request;
struct lock_file_request lock_file_request;
struct unlock_file_request unlock_file_request;
@ -6237,6 +6253,7 @@ union generic_reply
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_file_info_reply get_file_info_reply;
struct get_volume_info_reply get_volume_info_reply;
struct lock_file_reply lock_file_reply;
struct unlock_file_reply unlock_file_reply;
@ -6479,6 +6496,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 546
#define SERVER_PROTOCOL_VERSION 547
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -187,6 +187,7 @@ static const struct fd_ops dir_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -191,6 +191,7 @@ static const struct fd_ops console_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -209,6 +209,7 @@ static const struct fd_ops device_file_fd_ops =
device_file_read, /* read */
device_file_write, /* write */
device_file_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
device_file_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -2175,6 +2175,12 @@ int no_fd_flush( struct fd *fd, struct async *async )
return 0;
}
/* default get_file_info() routine */
void no_fd_get_file_info( struct fd *fd, unsigned int info_class )
{
set_error( STATUS_OBJECT_TYPE_MISMATCH );
}
/* default get_volume_info() routine */
void no_fd_get_volume_info( struct fd *fd, unsigned int info_class )
{
@ -2384,6 +2390,18 @@ DECL_HANDLER(flush)
release_object( fd );
}
/* query file info */
DECL_HANDLER(get_file_info)
{
struct fd *fd = get_handle_fd_obj( current->process, req->handle, 0 );
if (fd)
{
fd->fd_ops->get_file_info( fd, req->info_class );
release_object( fd );
}
}
/* query volume info */
DECL_HANDLER(get_volume_info)
{

View File

@ -107,6 +107,7 @@ static const struct fd_ops file_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
file_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -62,6 +62,8 @@ struct fd_ops
int (*write)(struct fd *, struct async *, file_pos_t );
/* flush the object buffers */
int (*flush)(struct fd *, struct async *);
/* query file info */
void (*get_file_info)( struct fd *, unsigned int );
/* query volume info */
void (*get_volume_info)( struct fd *, unsigned int );
/* perform an ioctl on the file */
@ -110,6 +112,7 @@ extern void fd_reselect_async( struct fd *fd, struct async_queue *queue );
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_file_info( struct fd *fd, unsigned int info_class );
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 );

View File

@ -104,6 +104,7 @@ static const struct fd_ops mailslot_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
mailslot_queue_async, /* queue_async */
@ -158,6 +159,7 @@ static const struct fd_ops mail_writer_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */
@ -212,6 +214,7 @@ static const struct fd_ops mailslot_device_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
default_fd_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -179,6 +179,7 @@ static const struct fd_ops mapping_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
no_fd_ioctl, /* ioctl */
no_fd_queue_async, /* queue_async */

View File

@ -183,6 +183,7 @@ static const struct fd_ops pipe_server_fd_ops =
pipe_end_read, /* read */
pipe_end_write, /* write */
pipe_end_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
pipe_end_get_volume_info, /* get_volume_info */
pipe_server_ioctl, /* ioctl */
no_fd_queue_async, /* queue_async */
@ -224,6 +225,7 @@ static const struct fd_ops pipe_client_fd_ops =
pipe_end_read, /* read */
pipe_end_write, /* write */
pipe_end_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
pipe_end_get_volume_info, /* get_volume_info */
pipe_client_ioctl, /* ioctl */
no_fd_queue_async, /* queue_async */
@ -271,6 +273,7 @@ static const struct fd_ops named_pipe_device_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
named_pipe_device_ioctl, /* ioctl */
default_fd_queue_async, /* queue_async */

View File

@ -1264,7 +1264,15 @@ enum server_fd_type
obj_handle_t event; /* event set when finished */
@END
/* Queries volume information */
/* Query file information */
@REQ(get_file_info)
obj_handle_t handle; /* handle to the file */
unsigned int info_class; /* queried information class */
@REPLY
VARARG(data,bytes); /* file info data */
@END
/* Query volume information */
@REQ(get_volume_info)
obj_handle_t handle; /* handle to the file */
unsigned int info_class; /* queried information class */

View File

@ -160,6 +160,7 @@ DECL_HANDLER(get_handle_unix_name);
DECL_HANDLER(get_handle_fd);
DECL_HANDLER(get_directory_cache_entry);
DECL_HANDLER(flush);
DECL_HANDLER(get_file_info);
DECL_HANDLER(get_volume_info);
DECL_HANDLER(lock_file);
DECL_HANDLER(unlock_file);
@ -454,6 +455,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_get_handle_fd,
(req_handler)req_get_directory_cache_entry,
(req_handler)req_flush,
(req_handler)req_get_file_info,
(req_handler)req_get_volume_info,
(req_handler)req_lock_file,
(req_handler)req_unlock_file,
@ -1032,6 +1034,10 @@ C_ASSERT( FIELD_OFFSET(struct flush_request, async) == 16 );
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_file_info_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_file_info_request, info_class) == 16 );
C_ASSERT( sizeof(struct get_file_info_request) == 24 );
C_ASSERT( sizeof(struct get_file_info_reply) == 8 );
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 );

View File

@ -114,6 +114,7 @@ static const struct fd_ops serial_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
serial_ioctl, /* ioctl */
serial_queue_async, /* queue_async */

View File

@ -167,6 +167,7 @@ static const struct fd_ops sock_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
sock_ioctl, /* ioctl */
sock_queue_async, /* queue_async */
@ -991,6 +992,7 @@ static const struct fd_ops ifchange_fd_ops =
no_fd_read, /* read */
no_fd_write, /* write */
no_fd_flush, /* flush */
no_fd_get_file_info, /* get_file_info */
no_fd_get_volume_info, /* get_volume_info */
no_fd_ioctl, /* ioctl */
NULL, /* queue_async */

View File

@ -1821,6 +1821,17 @@ static void dump_flush_reply( const struct flush_reply *req )
fprintf( stderr, " event=%04x", req->event );
}
static void dump_get_file_info_request( const struct get_file_info_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
fprintf( stderr, ", info_class=%08x", req->info_class );
}
static void dump_get_file_info_reply( const struct get_file_info_reply *req )
{
dump_varargs_bytes( " data=", cur_size );
}
static void dump_get_volume_info_request( const struct get_volume_info_request *req )
{
fprintf( stderr, " handle=%04x", req->handle );
@ -4558,6 +4569,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_handle_fd_request,
(dump_func)dump_get_directory_cache_entry_request,
(dump_func)dump_flush_request,
(dump_func)dump_get_file_info_request,
(dump_func)dump_get_volume_info_request,
(dump_func)dump_lock_file_request,
(dump_func)dump_unlock_file_request,
@ -4849,6 +4861,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_get_handle_fd_reply,
(dump_func)dump_get_directory_cache_entry_reply,
(dump_func)dump_flush_reply,
(dump_func)dump_get_file_info_reply,
(dump_func)dump_get_volume_info_reply,
(dump_func)dump_lock_file_reply,
NULL,
@ -5140,6 +5153,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"get_handle_fd",
"get_directory_cache_entry",
"flush",
"get_file_info",
"get_volume_info",
"lock_file",
"unlock_file",