Changed the create_file server request to take NtCreateFile flags
instead of CreateFileW ones (based on a patch by Eric Pouech).
diff --git a/server/file.c b/server/file.c
index 4dfff91..a22d269 100644
--- a/server/file.c
+++ b/server/file.c
@@ -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 *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 @@
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 @@
/* 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 @@
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( 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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 );
}
}