Added support for FILE_DIRECTORY_FILE and FILE_NON_DIRECTORY_FILE open
options.
This commit is contained in:
parent
5d617e8f79
commit
684b65cd52
|
@ -204,6 +204,8 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing,
|
|||
options = 0;
|
||||
if (attributes & FILE_FLAG_BACKUP_SEMANTICS)
|
||||
options |= FILE_OPEN_FOR_BACKUP_INTENT;
|
||||
else
|
||||
options |= FILE_NON_DIRECTORY_FILE;
|
||||
if (attributes & FILE_FLAG_DELETE_ON_CLOSE)
|
||||
options |= FILE_DELETE_ON_CLOSE;
|
||||
if (!(attributes & FILE_FLAG_OVERLAPPED))
|
||||
|
|
43
server/fd.c
43
server/fd.c
|
@ -26,6 +26,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -43,6 +44,10 @@
|
|||
#include "process.h"
|
||||
#include "request.h"
|
||||
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
|
||||
/* Because of the stupid Posix locking semantics, we need to keep
|
||||
* track of all file descriptors referencing a given file, and not
|
||||
* close a single one until all the locks are gone (sigh).
|
||||
|
@ -415,7 +420,10 @@ static void inode_destroy( struct object *obj )
|
|||
/* make sure it is still the same file */
|
||||
struct stat st;
|
||||
if (!stat( fd->unlink, &st ) && st.st_dev == inode->dev && st.st_ino == inode->ino)
|
||||
unlink( fd->unlink );
|
||||
{
|
||||
if (S_ISDIR(st.st_mode)) rmdir( fd->unlink );
|
||||
else unlink( fd->unlink );
|
||||
}
|
||||
}
|
||||
free( fd );
|
||||
}
|
||||
|
@ -907,13 +915,15 @@ static int check_sharing( struct fd *fd, unsigned int access, unsigned int shari
|
|||
/* the fd must have been created with alloc_fd */
|
||||
/* on error the fd object is released */
|
||||
struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
||||
unsigned int access, unsigned int sharing, const char *unlink_name )
|
||||
unsigned int access, unsigned int sharing, unsigned int options )
|
||||
{
|
||||
struct stat st;
|
||||
struct closed_fd *closed_fd;
|
||||
const char *unlink_name = "";
|
||||
|
||||
assert( fd->unix_fd == -1 );
|
||||
|
||||
if (options & FILE_DELETE_ON_CLOSE) unlink_name = name;
|
||||
if (!(closed_fd = mem_alloc( sizeof(*closed_fd) + strlen(unlink_name) )))
|
||||
{
|
||||
release_object( fd );
|
||||
|
@ -931,7 +941,20 @@ struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
|||
fstat( fd->unix_fd, &st );
|
||||
*mode = st.st_mode;
|
||||
|
||||
if (S_ISREG(st.st_mode)) /* only bother with an inode for normal files */
|
||||
/* check directory options */
|
||||
if ((options & FILE_DIRECTORY_FILE) && !S_ISDIR(st.st_mode))
|
||||
{
|
||||
set_error( STATUS_NOT_A_DIRECTORY );
|
||||
goto error;
|
||||
}
|
||||
if ((options & FILE_NON_DIRECTORY_FILE) && S_ISDIR(st.st_mode))
|
||||
{
|
||||
set_error( STATUS_FILE_IS_A_DIRECTORY );
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* only bother with an inode for normal files and directories */
|
||||
if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))
|
||||
{
|
||||
struct inode *inode = get_inode( st.st_dev, st.st_ino );
|
||||
|
||||
|
@ -940,9 +963,7 @@ struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
|||
/* we can close the fd because there are no others open on the same file,
|
||||
* otherwise we wouldn't have failed to allocate a new inode
|
||||
*/
|
||||
release_object( fd );
|
||||
free( closed_fd );
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
fd->inode = inode;
|
||||
fd->closed = closed_fd;
|
||||
|
@ -957,15 +978,19 @@ struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
|||
}
|
||||
else
|
||||
{
|
||||
free( closed_fd );
|
||||
if (unlink_name[0]) /* we can't unlink special files */
|
||||
{
|
||||
release_object( fd );
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
goto error;
|
||||
}
|
||||
free( closed_fd );
|
||||
}
|
||||
return fd;
|
||||
|
||||
error:
|
||||
release_object( fd );
|
||||
free( closed_fd );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create an fd for an anonymous file */
|
||||
|
|
|
@ -167,8 +167,7 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int
|
|||
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
|
||||
if (!(file->fd = alloc_fd( &file_fd_ops, &file->obj )) ||
|
||||
!(file->fd = open_fd( file->fd, name, flags | O_NONBLOCK | O_LARGEFILE,
|
||||
&mode, access, sharing,
|
||||
(options & FILE_DELETE_ON_CLOSE) ? name : "" )))
|
||||
&mode, access, sharing, options )))
|
||||
{
|
||||
free( name );
|
||||
release_object( file );
|
||||
|
@ -176,13 +175,6 @@ static struct object *create_file( const char *nameptr, size_t len, unsigned int
|
|||
}
|
||||
free( name );
|
||||
|
||||
/* refuse to open a directory */
|
||||
if (S_ISDIR(mode) && !(options & FILE_OPEN_FOR_BACKUP_INTENT))
|
||||
{
|
||||
set_error( STATUS_ACCESS_DENIED );
|
||||
release_object( file );
|
||||
return NULL;
|
||||
}
|
||||
/* check for serial port */
|
||||
if (S_ISCHR(mode) && is_serial_fd( file->fd ))
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ struct fd_ops
|
|||
|
||||
extern struct fd *alloc_fd( const struct fd_ops *fd_user_ops, struct object *user );
|
||||
extern struct fd *open_fd( struct fd *fd, const char *name, int flags, mode_t *mode,
|
||||
unsigned int access, unsigned int sharing, const char *unlink_name );
|
||||
unsigned int access, unsigned int sharing, unsigned int options );
|
||||
extern struct fd *create_anonymous_fd( const struct fd_ops *fd_user_ops,
|
||||
int unix_fd, struct object *user );
|
||||
extern void *get_fd_user( struct fd *fd );
|
||||
|
|
|
@ -3082,6 +3082,7 @@ static const char *get_status_name( unsigned int status )
|
|||
NAME(DIRECTORY_NOT_EMPTY),
|
||||
NAME(DISK_FULL),
|
||||
NAME(DLL_NOT_FOUND),
|
||||
NAME(FILE_IS_A_DIRECTORY),
|
||||
NAME(FILE_LOCK_CONFLICT),
|
||||
NAME(INVALID_FILE_FOR_SECTION),
|
||||
NAME(INVALID_HANDLE),
|
||||
|
@ -3089,6 +3090,7 @@ static const char *get_status_name( unsigned int status )
|
|||
NAME(KEY_DELETED),
|
||||
NAME(MEDIA_WRITE_PROTECTED),
|
||||
NAME(MUTANT_NOT_OWNED),
|
||||
NAME(NOT_A_DIRECTORY),
|
||||
NAME(NOT_IMPLEMENTED),
|
||||
NAME(NOT_REGISTRY_FILE),
|
||||
NAME(NO_DATA_DETECTED),
|
||||
|
|
Loading…
Reference in New Issue