Changed the create_file server request to take NtCreateFile flags
instead of CreateFileW ones (based on a patch by Eric Pouech).
This commit is contained in:
parent
410bdd365f
commit
014099caf5
|
@ -821,7 +821,8 @@ static HANDLE INT21_CreateMagicDeviceHandle( LPCWSTR name )
|
|||
req->access = GENERIC_READ|GENERIC_WRITE;
|
||||
req->inherit = 0;
|
||||
req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE;
|
||||
req->create = OPEN_ALWAYS;
|
||||
req->create = FILE_OPEN_IF;
|
||||
req->options = FILE_SYNCHRONOUS_IO_ALERT;
|
||||
req->attrs = 0;
|
||||
req->removable = 0;
|
||||
wine_server_add_data( req, unix_name, strlen(unix_name) );
|
||||
|
|
27
files/file.c
27
files/file.c
|
@ -184,8 +184,32 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
|
|||
UINT drive_type )
|
||||
{
|
||||
unsigned int err;
|
||||
UINT disp, options;
|
||||
HANDLE ret;
|
||||
|
||||
switch (creation)
|
||||
{
|
||||
case CREATE_ALWAYS: disp = FILE_OVERWRITE_IF; break;
|
||||
case CREATE_NEW: disp = FILE_CREATE; break;
|
||||
case OPEN_ALWAYS: disp = FILE_OPEN_IF; break;
|
||||
case OPEN_EXISTING: disp = FILE_OPEN; break;
|
||||
case TRUNCATE_EXISTING: disp = FILE_OVERWRITE; break;
|
||||
default:
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
options = 0;
|
||||
if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
|
||||
options |= FILE_DELETE_ON_CLOSE;
|
||||
if (!(attributes & FILE_FLAG_OVERLAPPED))
|
||||
options |= FILE_SYNCHRONOUS_IO_ALERT;
|
||||
if (attributes & FILE_FLAG_RANDOM_ACCESS)
|
||||
options |= FILE_RANDOM_ACCESS;
|
||||
attributes &= FILE_ATTRIBUTE_VALID_FLAGS;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
SERVER_START_REQ( create_file )
|
||||
|
@ -193,7 +217,8 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
|
|||
req->access = access;
|
||||
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
|
||||
req->sharing = sharing;
|
||||
req->create = creation;
|
||||
req->create = disp;
|
||||
req->options = options;
|
||||
req->attrs = attributes;
|
||||
req->removable = (drive_type == DRIVE_REMOVABLE || drive_type == DRIVE_CDROM);
|
||||
wine_server_add_data( req, filename, strlen(filename) );
|
||||
|
|
|
@ -751,6 +751,7 @@ struct create_file_request
|
|||
int inherit;
|
||||
unsigned int sharing;
|
||||
int create;
|
||||
unsigned int options;
|
||||
unsigned int attrs;
|
||||
int removable;
|
||||
/* VARARG(filename,string); */
|
||||
|
@ -3729,6 +3730,6 @@ union generic_reply
|
|||
struct set_global_windows_reply set_global_windows_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 133
|
||||
#define SERVER_PROTOCOL_VERSION 134
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -900,22 +900,54 @@ typedef struct _LDR_RESOURCE_INFO
|
|||
*/
|
||||
|
||||
/* flags for NtCreateFile and NtOpenFile */
|
||||
#define FILE_DIRECTORY_FLAG 0x00000001
|
||||
#define FILE_WRITE_THROUGH 0x00000002
|
||||
#define FILE_SEQUENTIAL_ONLY 0x00000004
|
||||
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||
#define FILE_DIRECTORY_FILE 0x00000001
|
||||
#define FILE_WRITE_THROUGH 0x00000002
|
||||
#define FILE_SEQUENTIAL_ONLY 0x00000004
|
||||
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
|
||||
#define FILE_NO_EA_KNOWLEDGE 0x00000200
|
||||
#define FILE_OPEN_FOR_RECOVERY 0x00000400
|
||||
#define FILE_RANDOM_ACCESS 0x00000800
|
||||
#define FILE_DELETE_ON_CLOSE 0x00001000
|
||||
#define FILE_OPEN_BY_FILE_ID 0x00002000
|
||||
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
|
||||
#define FILE_NO_COMPRESSION 0x00008000
|
||||
#define FILE_RESERVE_OPFILTER 0x00100000
|
||||
#define FILE_TRANSACTED_MODE 0x00200000
|
||||
#define FILE_OPEN_OFFLINE_FILE 0x00400000
|
||||
|
||||
#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7
|
||||
#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7
|
||||
|
||||
/* status for NtCreateFile or NtOpenFile */
|
||||
#define FILE_SUPERSEDED 0x00000000
|
||||
#define FILE_OPENED 0x00000001
|
||||
#define FILE_CREATED 0x00000002
|
||||
#define FILE_OVERWRITTEN 0x00000003
|
||||
#define FILE_EXISTS 0x00000004
|
||||
#define FILE_DOES_NOT_EXIST 0x00000005
|
||||
#define FILE_SUPERSEDED 0
|
||||
#define FILE_OPENED 1
|
||||
#define FILE_CREATED 2
|
||||
#define FILE_OVERWRITTEN 3
|
||||
#define FILE_EXISTS 4
|
||||
#define FILE_DOES_NOT_EXIST 5
|
||||
|
||||
/* disposition for NtCreateFile */
|
||||
#define FILE_SUPERSEDE 0
|
||||
#define FILE_OPEN 1
|
||||
#define FILE_CREATE 2
|
||||
#define FILE_OPEN_IF 3
|
||||
#define FILE_OVERWRITE 4
|
||||
#define FILE_OVERWRITE_IF 5
|
||||
#define FILE_MAXIMUM_DISPOSITION 5
|
||||
|
||||
/* Characteristics of a File System */
|
||||
#define FILE_REMOVABLE_MEDIA 0x00000001
|
||||
#define FILE_READ_ONLY_DEVICE 0x00000002
|
||||
#define FILE_FLOPPY_DISKETTE 0x00000004
|
||||
#define FILE_WRITE_ONE_MEDIA 0x00000008
|
||||
#define FILE_REMOTE_DEVICE 0x00000010
|
||||
#define FILE_DEVICE_IS_MOUNTED 0x00000020
|
||||
#define FILE_VIRTUAL_VOLUME 0x00000040
|
||||
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
#define INTERNAL_TS_ACTIVE_CONSOLE_ID ( *((volatile ULONG*)(0x7ffe02d8)) )
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include "winerror.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "handle.h"
|
||||
|
@ -57,9 +59,9 @@ struct file
|
|||
struct file *next; /* next file in hashing list */
|
||||
char *name; /* file name */
|
||||
unsigned int access; /* file access (GENERIC_READ/WRITE) */
|
||||
unsigned int flags; /* flags (FILE_FLAG_*) */
|
||||
unsigned int options; /* file options (FILE_DELETE_ON_CLOSE, FILE_SYNCHRONOUS...) */
|
||||
unsigned int sharing; /* file sharing mode */
|
||||
int removable; /* is file on removable media? */
|
||||
int removable; /* is file on removable media? */
|
||||
struct async_queue read_q;
|
||||
struct async_queue write_q;
|
||||
};
|
||||
|
@ -99,6 +101,11 @@ static const struct fd_ops file_fd_ops =
|
|||
file_queue_async /* queue_async */
|
||||
};
|
||||
|
||||
static inline int is_overlapped( const struct file *file )
|
||||
{
|
||||
return !(file->options & (FILE_SYNCHRONOUS_IO_ALERT | FILE_SYNCHRONOUS_IO_NONALERT));
|
||||
}
|
||||
|
||||
static int get_name_hash( const char *name )
|
||||
{
|
||||
int hash = 0;
|
||||
|
@ -133,8 +140,7 @@ static int check_sharing( const char *name, int hash, unsigned int access,
|
|||
|
||||
/* create a file from a file descriptor */
|
||||
/* if the function fails the fd is closed */
|
||||
static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing,
|
||||
unsigned int attrs, int removable )
|
||||
static struct file *create_file_for_fd( int fd, unsigned int access, unsigned int sharing )
|
||||
{
|
||||
struct file *file;
|
||||
|
||||
|
@ -143,14 +149,9 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in
|
|||
file->name = NULL;
|
||||
file->next = NULL;
|
||||
file->access = access;
|
||||
file->flags = attrs;
|
||||
file->options = FILE_SYNCHRONOUS_IO_NONALERT;
|
||||
file->sharing = sharing;
|
||||
file->removable = removable;
|
||||
if (file->flags & FILE_FLAG_OVERLAPPED)
|
||||
{
|
||||
init_async_queue (&file->read_q);
|
||||
init_async_queue (&file->write_q);
|
||||
}
|
||||
file->removable = 0;
|
||||
if (!(file->fd = create_anonymous_fd( &file_fd_ops, fd, &file->obj )))
|
||||
{
|
||||
release_object( file );
|
||||
|
@ -162,8 +163,8 @@ static struct file *create_file_for_fd( int fd, unsigned int access, unsigned in
|
|||
|
||||
|
||||
static struct file *create_file( const char *nameptr, size_t len, unsigned int access,
|
||||
unsigned int sharing, int create, unsigned int attrs,
|
||||
int removable )
|
||||
unsigned int sharing, int create, unsigned int options,
|
||||
unsigned int attrs, int removable )
|
||||
{
|
||||
struct file *file;
|
||||
int hash, flags;
|
||||
|
@ -180,11 +181,12 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a
|
|||
|
||||
switch(create)
|
||||
{
|
||||
case CREATE_NEW: flags = O_CREAT | O_EXCL; break;
|
||||
case CREATE_ALWAYS: flags = O_CREAT | O_TRUNC; break;
|
||||
case OPEN_ALWAYS: flags = O_CREAT; break;
|
||||
case TRUNCATE_EXISTING: flags = O_TRUNC; break;
|
||||
case OPEN_EXISTING: flags = 0; break;
|
||||
case FILE_CREATE: flags = O_CREAT | O_EXCL; break;
|
||||
case FILE_OVERWRITE_IF: /* FIXME: the difference is whether we trash existing attr or not */
|
||||
case FILE_SUPERSEDE: flags = O_CREAT | O_TRUNC; break;
|
||||
case FILE_OPEN: flags = 0; break;
|
||||
case FILE_OPEN_IF: flags = O_CREAT; break;
|
||||
case FILE_OVERWRITE: flags = O_TRUNC; break;
|
||||
default: set_error( STATUS_INVALID_PARAMETER ); goto error;
|
||||
}
|
||||
switch(access & (GENERIC_READ | GENERIC_WRITE))
|
||||
|
@ -203,13 +205,13 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a
|
|||
if (!(file = alloc_object( &file_ops ))) goto error;
|
||||
|
||||
file->access = access;
|
||||
file->flags = attrs;
|
||||
file->options = options;
|
||||
file->sharing = sharing;
|
||||
file->removable = removable;
|
||||
file->name = name;
|
||||
file->next = file_hash[hash];
|
||||
file_hash[hash] = file;
|
||||
if (file->flags & FILE_FLAG_OVERLAPPED)
|
||||
if (is_overlapped( file ))
|
||||
{
|
||||
init_async_queue (&file->read_q);
|
||||
init_async_queue (&file->write_q);
|
||||
|
@ -223,7 +225,7 @@ static struct file *create_file( const char *nameptr, size_t len, unsigned int a
|
|||
return NULL;
|
||||
}
|
||||
/* refuse to open a directory */
|
||||
if (S_ISDIR(mode) && !(file->flags & FILE_FLAG_BACKUP_SEMANTICS))
|
||||
if (S_ISDIR(mode) && !(options & FILE_OPEN_FOR_BACKUP_INTENT))
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
release_object( file );
|
||||
|
@ -262,14 +264,14 @@ struct file *create_temp_file( int access )
|
|||
return NULL;
|
||||
}
|
||||
unlink( tmpfn );
|
||||
return create_file_for_fd( fd, access, 0, 0, FALSE );
|
||||
return create_file_for_fd( fd, access, 0 );
|
||||
}
|
||||
|
||||
static void file_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct file *file = (struct file *)obj;
|
||||
assert( obj->ops == &file_ops );
|
||||
fprintf( stderr, "File fd=%p flags=%08x name='%s'\n", file->fd, file->flags, file->name );
|
||||
fprintf( stderr, "File fd=%p options=%08x name='%s'\n", file->fd, file->options, file->name );
|
||||
}
|
||||
|
||||
static int file_get_poll_events( struct fd *fd )
|
||||
|
@ -286,7 +288,7 @@ static void file_poll_event( struct fd *fd, int event )
|
|||
{
|
||||
struct file *file = get_fd_user( fd );
|
||||
assert( file->obj.ops == &file_ops );
|
||||
if ( file->flags & FILE_FLAG_OVERLAPPED )
|
||||
if (is_overlapped( file ))
|
||||
{
|
||||
if( IS_READY(file->read_q) && (POLLIN & event) )
|
||||
{
|
||||
|
@ -354,7 +356,7 @@ static int file_get_info( struct fd *fd, struct get_file_info_reply *reply, int
|
|||
reply->serial = 0; /* FIXME */
|
||||
}
|
||||
*flags = 0;
|
||||
if (file->flags & FILE_FLAG_OVERLAPPED) *flags |= FD_FLAG_OVERLAPPED;
|
||||
if (is_overlapped( file )) *flags |= FD_FLAG_OVERLAPPED;
|
||||
return FD_TYPE_DEFAULT;
|
||||
}
|
||||
|
||||
|
@ -366,7 +368,7 @@ static void file_queue_async(struct fd *fd, void *ptr, unsigned int status, int
|
|||
|
||||
assert( file->obj.ops == &file_ops );
|
||||
|
||||
if ( !(file->flags & FILE_FLAG_OVERLAPPED) )
|
||||
if (!is_overlapped( file ))
|
||||
{
|
||||
set_error ( STATUS_INVALID_HANDLE );
|
||||
return;
|
||||
|
@ -429,10 +431,10 @@ static void file_destroy( struct object *obj )
|
|||
while (*pptr && *pptr != file) pptr = &(*pptr)->next;
|
||||
assert( *pptr );
|
||||
*pptr = (*pptr)->next;
|
||||
if (file->flags & FILE_FLAG_DELETE_ON_CLOSE) unlink( file->name );
|
||||
if (file->options & FILE_DELETE_ON_CLOSE) unlink( file->name );
|
||||
free( file->name );
|
||||
}
|
||||
if (file->flags & FILE_FLAG_OVERLAPPED)
|
||||
if (is_overlapped( file ))
|
||||
{
|
||||
destroy_async_queue (&file->read_q);
|
||||
destroy_async_queue (&file->write_q);
|
||||
|
@ -462,6 +464,7 @@ void file_set_error(void)
|
|||
case ESPIPE: set_win32_error( ERROR_SEEK ); break;
|
||||
case ENOTEMPTY: set_error( STATUS_DIRECTORY_NOT_EMPTY ); break;
|
||||
case EIO: set_error( STATUS_ACCESS_VIOLATION ); break;
|
||||
case ENOTDIR: set_error( STATUS_NOT_A_DIRECTORY ); break;
|
||||
#ifdef EOVERFLOW
|
||||
case EOVERFLOW: set_error( STATUS_INVALID_PARAMETER ); break;
|
||||
#endif
|
||||
|
@ -600,7 +603,7 @@ DECL_HANDLER(create_file)
|
|||
|
||||
reply->handle = 0;
|
||||
if ((file = create_file( get_req_data(), get_req_data_size(), req->access,
|
||||
req->sharing, req->create, req->attrs, req->removable )))
|
||||
req->sharing, req->create, req->options, req->attrs, req->removable )))
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
|
||||
release_object( file );
|
||||
|
@ -619,8 +622,7 @@ DECL_HANDLER(alloc_file_handle)
|
|||
set_error( STATUS_INVALID_HANDLE );
|
||||
return;
|
||||
}
|
||||
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
0, FALSE )))
|
||||
if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE )))
|
||||
{
|
||||
reply->handle = alloc_handle( current->process, file, req->access, req->inherit );
|
||||
release_object( file );
|
||||
|
@ -665,7 +667,7 @@ DECL_HANDLER(lock_file)
|
|||
if ((file = get_file_obj( current->process, req->handle, 0 )))
|
||||
{
|
||||
reply->handle = lock_fd( file->fd, offset, count, req->shared, req->wait );
|
||||
reply->overlapped = (file->flags & FILE_FLAG_OVERLAPPED) != 0;
|
||||
reply->overlapped = is_overlapped( file );
|
||||
release_object( file );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -575,6 +575,7 @@ enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT };
|
|||
int inherit; /* inherit flag */
|
||||
unsigned int sharing; /* sharing flags */
|
||||
int create; /* file create action */
|
||||
unsigned int options; /* file options */
|
||||
unsigned int attrs; /* file attributes for creation */
|
||||
int removable; /* is file on removable media? */
|
||||
VARARG(filename,string); /* file name */
|
||||
|
|
|
@ -835,6 +835,7 @@ static void dump_create_file_request( const struct create_file_request *req )
|
|||
fprintf( stderr, " inherit=%d,", req->inherit );
|
||||
fprintf( stderr, " sharing=%08x,", req->sharing );
|
||||
fprintf( stderr, " create=%d,", req->create );
|
||||
fprintf( stderr, " options=%08x,", req->options );
|
||||
fprintf( stderr, " attrs=%08x,", req->attrs );
|
||||
fprintf( stderr, " removable=%d,", req->removable );
|
||||
fprintf( stderr, " filename=" );
|
||||
|
|
Loading…
Reference in New Issue