diff options
-rw-r--r-- | file_io/win32/filestat.c | 16 | ||||
-rw-r--r-- | file_io/win32/open.c | 25 | ||||
-rw-r--r-- | include/arch/win32/fileio.h | 7 |
3 files changed, 32 insertions, 16 deletions
diff --git a/file_io/win32/filestat.c b/file_io/win32/filestat.c index 429d26e72..cd4f6c2ac 100644 --- a/file_io/win32/filestat.c +++ b/file_io/win32/filestat.c @@ -191,11 +191,11 @@ static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname, * user, group or permissions. */ - if ((rv = apr_file_open(&thefile, fname, - ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0) - | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER)) - ? APR_READCONTROL : 0), - APR_OS_DEFAULT, pool)) == APR_SUCCESS) { + if ((rv = apr_file_open(&thefile, fname, APR_OPENINFO + | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0) + | ((wanted & (APR_FINFO_PROT | APR_FINFO_OWNER)) + ? APR_READCONTROL : 0), + APR_OS_DEFAULT, pool)) == APR_SUCCESS) { rv = apr_file_info_get(finfo, wanted, thefile); finfo->filehand = NULL; apr_file_close(thefile); @@ -205,9 +205,9 @@ static apr_status_t resolve_ident(apr_finfo_t *finfo, const char *fname, /* We have a backup plan. Perhaps we couldn't grab READ_CONTROL? * proceed without asking for that permission... */ - if ((rv = apr_file_open(&thefile, fname, - ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0), - APR_OS_DEFAULT, pool)) == APR_SUCCESS) { + if ((rv = apr_file_open(&thefile, fname, APR_OPENINFO + | ((wanted & APR_FINFO_LINK) ? APR_OPENLINK : 0), + APR_OS_DEFAULT, pool)) == APR_SUCCESS) { rv = apr_file_info_get(finfo, wanted & ~(APR_FINFO_PROT | APR_FINFO_OWNER), thefile); diff --git a/file_io/win32/open.c b/file_io/win32/open.c index ae15ed9a3..b0bb7da04 100644 --- a/file_io/win32/open.c +++ b/file_io/win32/open.c @@ -339,21 +339,36 @@ APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new, const char *fname, if (flag & APR_DELONCLOSE) { attributes |= FILE_FLAG_DELETE_ON_CLOSE; } + if (flag & APR_OPENLINK) { attributes |= FILE_FLAG_OPEN_REPARSE_POINT; } - if (!(flag & (APR_READ | APR_WRITE)) && (apr_os_level >= APR_WIN_NT)) { - /* We once failed here, but this is how one opens - * a directory as a file under winnt - */ - attributes |= FILE_FLAG_BACKUP_SEMANTICS; + + /* Without READ or WRITE, we fail unless apr called apr_file_open + * internally with the private APR_OPENINFO flag. + * + * With the APR_OPENINFO flag on NT, use the option flag + * FILE_FLAG_BACKUP_SEMANTICS to allow us to open directories. + * See the static resolve_ident() fn in file_io/win32/filestat.c + */ + if (!(flag & (APR_READ | APR_WRITE))) { + if (flag & APR_OPENINFO) { + if (apr_os_level >= APR_WIN_NT) { + attributes |= FILE_FLAG_BACKUP_SEMANTICS; + } + } + else { + return APR_EACCES; + } } + if (flag & APR_XTHREAD) { /* This win32 specific feature is required * to allow multiple threads to work with the file. */ attributes |= FILE_FLAG_OVERLAPPED; } + #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { diff --git a/include/arch/win32/fileio.h b/include/arch/win32/fileio.h index 58a5dba0a..d1aa721b0 100644 --- a/include/arch/win32/fileio.h +++ b/include/arch/win32/fileio.h @@ -133,9 +133,10 @@ void *res_name_from_filename(const char *file, int global, apr_pool_t *pool); #endif /* Internal Flags for apr_file_open */ -#define APR_OPENLINK 8192 /* Open a link itself, if supported */ -#define APR_READCONTROL 4096 /* Read the file's owner/perms */ -#define APR_WRITECONTROL 2048 /* Modifythe file's owner/perms */ +#define APR_OPENINFO 0x4000 /* Open without READ or WRITE access */ +#define APR_OPENLINK 0x2000 /* Open a link itself, if supported */ +#define APR_READCONTROL 0x1000 /* Read the file's owner/perms */ +#define APR_WRITECONTROL 0x0800 /* Modifythe file's owner/perms */ /* Entries missing from the MSVC 5.0 Win32 SDK: */ |