diff options
| author | Pierre Joye <pajoye@php.net> | 2010-09-01 09:49:53 +0000 |
|---|---|---|
| committer | Pierre Joye <pajoye@php.net> | 2010-09-01 09:49:53 +0000 |
| commit | dec8593fac062ce8689baea484f94a816713dcc6 (patch) | |
| tree | 34b469a1028f69869596b2f2210afca8ac716e1d /TSRM/tsrm_virtual_cwd.c | |
| parent | 70d7d86505545e8a228897d6220c6f5b1cb3f76f (diff) | |
| download | php-git-dec8593fac062ce8689baea484f94a816713dcc6.tar.gz | |
- add lstat support for Windows
Diffstat (limited to 'TSRM/tsrm_virtual_cwd.c')
| -rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 52 |
1 files changed, 46 insertions, 6 deletions
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 197948f598..48aeeb59c2 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -14,6 +14,7 @@ +----------------------------------------------------------------------+ | Authors: Andi Gutmans <andi@zend.com> | | Sascha Schumann <sascha@schumann.cx> | + | Pierre Joye <pierre@php.net> | +----------------------------------------------------------------------+ */ @@ -40,6 +41,10 @@ # endif #endif +#ifndef S_IFLNK +# define S_IFLNK 0120000 +#endif + #ifdef NETWARE #include <fsio.h> #endif @@ -202,7 +207,7 @@ static inline time_t FileTimeToUnixTime(const FILETIME FileTime) return (time_t)UnixTime; } -CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */ +CWD_API int php_sys_stat_ex(const char *path, struct stat *buf, int lstat) /* {{{ */ { WIN32_FILE_ATTRIBUTE_DATA data; __int64 t; @@ -247,9 +252,46 @@ CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */ free(tmp); } } + buf->st_uid = buf->st_gid = buf->st_ino = 0; - buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; - buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); + + if (lstat && data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { + /* File is a reparse point. Get the target */ + HANDLE hLink = NULL; + REPARSE_DATA_BUFFER * pbuffer; + unsigned int retlength = 0; + TSRM_ALLOCA_FLAG(use_heap_large); + + hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); + if(hLink == INVALID_HANDLE_VALUE) { + return -1; + } + + pbuffer = (REPARSE_DATA_BUFFER *)tsrm_do_alloca(MAXIMUM_REPARSE_DATA_BUFFER_SIZE, use_heap_large); + if(!DeviceIoControl(hLink, FSCTL_GET_REPARSE_POINT, NULL, 0, pbuffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &retlength, NULL)) { + tsrm_free_alloca(pbuffer, use_heap_large); + CloseHandle(hLink); + return -1; + } + + CloseHandle(hLink); + + if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + buf->st_mode = S_IFLNK; + buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); + } + +#if 0 /* Not used yet */ + else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { + buf->st_mode |=; + } +#endif + tsrm_free_alloca(pbuffer, use_heap_large); + } else { + buf->st_mode = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? (S_IFDIR|S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)) : S_IFREG; + buf->st_mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)) : (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6)|S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6)); + } + if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) { int len = strlen(path); @@ -1557,7 +1599,6 @@ CWD_API int virtual_stat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */ } /* }}} */ -#if !defined(TSRM_WIN32) CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ */ { cwd_state new_state; @@ -1569,13 +1610,12 @@ CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC) /* {{{ * return -1; } - retval = lstat(new_state.cwd, buf); + retval = php_sys_lstat(new_state.cwd, buf); CWD_STATE_FREE(&new_state); return retval; } /* }}} */ -#endif CWD_API int virtual_unlink(const char *path TSRMLS_DC) /* {{{ */ { |
