48
- Create php_readlink, php_link and php_symlink in win32/link.c
48
- Create php_readlink (done), php_link and php_symlink in win32/link.c
49
49
- Expose them (PHPAPI) so extensions developers can use them
50
50
- define link/readlink/symlink to their php_ equivalent and use them in ext/standart/link.c
51
51
- this file is then useless and we have a portable link API
54
#ifndef VOLUME_NAME_NT
55
#define VOLUME_NAME_NT 0x2
58
#ifndef VOLUME_NAME_DOS
59
#define VOLUME_NAME_DOS 0x0
62
54
/* {{{ proto string readlink(string filename)
63
55
Return the target of a symbolic link */
64
56
PHP_FUNCTION(readlink)
69
TCHAR Path[MAXPATHLEN];
70
char path_resolved[MAXPATHLEN];
74
typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD);
75
gfpnh_func pGetFinalPathNameByHandle;
77
kernel32 = LoadLibrary("kernel32.dll");
80
pGetFinalPathNameByHandle = (gfpnh_func)GetProcAddress(kernel32, "GetFinalPathNameByHandleA");
81
if (pGetFinalPathNameByHandle == NULL) {
82
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call GetFinalPathNameByHandleA");
86
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call get a handle on kernel32.dll");
60
char target[MAXPATHLEN];
90
62
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
94
66
if (OPENBASEDIR_CHECKPATH(link)) {
97
if (!expand_filepath(link, path_resolved TSRMLS_CC)) {
98
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
101
hFile = CreateFile(path_resolved, // file to open
102
GENERIC_READ, // open for reading
103
FILE_SHARE_READ, // share for reading
104
NULL, // default security
105
OPEN_EXISTING, // existing file only
106
FILE_FLAG_BACKUP_SEMANTICS, // normal file
107
NULL); // no attr. template
109
if( hFile == INVALID_HANDLE_VALUE) {
110
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open file (error %d)", GetLastError());
114
dwRet = pGetFinalPathNameByHandle(hFile, Path, MAXPATHLEN, VOLUME_NAME_DOS);
115
if(dwRet >= MAXPATHLEN) {
116
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't resolve the full path, the path exceeds the MAX_PATH_LEN (%d) limit", MAXPATHLEN);
122
/* Append NULL to the end of the string */
126
/* Skip first 4 characters if they are "\??\" */
127
if(Path[0] == '\\' && Path[1] == '\\' && Path[2] == '?' && Path[3] == '\\') {
128
RETURN_STRING(Path + 4, 1);
131
RETURN_STRING(Path, 1);
70
if (php_sys_readlink(link, target, MAXPATHLEN) == -1) {
71
php_error_docref(NULL TSRMLS_CC, E_WARNING, "readlink failed to read the symbolic link (%s), error %d)", link, GetLastError());
73
RETURN_STRING(target, 1);