summaryrefslogtreecommitdiff
path: root/TSRM/tsrm_virtual_cwd.c
diff options
context:
space:
mode:
authorPierre Joye <pajoye@php.net>2010-09-01 09:49:53 +0000
committerPierre Joye <pajoye@php.net>2010-09-01 09:49:53 +0000
commitdec8593fac062ce8689baea484f94a816713dcc6 (patch)
tree34b469a1028f69869596b2f2210afca8ac716e1d /TSRM/tsrm_virtual_cwd.c
parent70d7d86505545e8a228897d6220c6f5b1cb3f76f (diff)
downloadphp-git-dec8593fac062ce8689baea484f94a816713dcc6.tar.gz
- add lstat support for Windows
Diffstat (limited to 'TSRM/tsrm_virtual_cwd.c')
-rw-r--r--TSRM/tsrm_virtual_cwd.c52
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) /* {{{ */
{