mirror of
https://github.com/php/php-src.git
synced 2026-04-07 16:13:32 +02:00
- use php_sys_readlink
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
|
||||
/*
|
||||
TODO:
|
||||
- Create php_readlink, php_link and php_symlink in win32/link.c
|
||||
- Create php_readlink (done), php_link and php_symlink in win32/link.c
|
||||
- Expose them (PHPAPI) so extensions developers can use them
|
||||
- define link/readlink/symlink to their php_ equivalent and use them in ext/standart/link.c
|
||||
- this file is then useless and we have a portable link API
|
||||
@@ -62,73 +62,22 @@ TODO:
|
||||
Return the target of a symbolic link */
|
||||
PHP_FUNCTION(readlink)
|
||||
{
|
||||
HINSTANCE kernel32;
|
||||
char *link;
|
||||
int link_len;
|
||||
TCHAR Path[MAXPATHLEN];
|
||||
char path_resolved[MAXPATHLEN];
|
||||
HANDLE hFile;
|
||||
DWORD dwRet;
|
||||
|
||||
typedef BOOL (WINAPI *gfpnh_func)(HANDLE, LPTSTR, DWORD, DWORD);
|
||||
gfpnh_func pGetFinalPathNameByHandle;
|
||||
|
||||
kernel32 = LoadLibrary("kernel32.dll");
|
||||
|
||||
if (kernel32) {
|
||||
pGetFinalPathNameByHandle = (gfpnh_func)GetProcAddress(kernel32, "GetFinalPathNameByHandleA");
|
||||
if (pGetFinalPathNameByHandle == NULL) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call GetFinalPathNameByHandleA");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
} else {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call get a handle on kernel32.dll");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
char target[MAXPATHLEN];
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (php_check_open_basedir(link TSRMLS_CC)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
if (!expand_filepath(link, path_resolved TSRMLS_CC)) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
hFile = CreateFile(path_resolved, // file to open
|
||||
GENERIC_READ, // open for reading
|
||||
FILE_SHARE_READ, // share for reading
|
||||
NULL, // default security
|
||||
OPEN_EXISTING, // existing file only
|
||||
FILE_FLAG_BACKUP_SEMANTICS, // normal file
|
||||
NULL); // no attr. template
|
||||
|
||||
if( hFile == INVALID_HANDLE_VALUE) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open file (error %d)", GetLastError());
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
dwRet = pGetFinalPathNameByHandle(hFile, Path, MAXPATHLEN, VOLUME_NAME_DOS);
|
||||
if(dwRet >= MAXPATHLEN) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't resolve the full path, the path exceeds the MAX_PATH_LEN (%d) limit", MAXPATHLEN);
|
||||
if (OPENBASEDIR_CHECKPATH(link)) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
CloseHandle(hFile);
|
||||
|
||||
/* Append NULL to the end of the string */
|
||||
Path[dwRet] = '\0';
|
||||
|
||||
if(dwRet > 4) {
|
||||
/* Skip first 4 characters if they are "\??\" */
|
||||
if(Path[0] == '\\' && Path[1] == '\\' && Path[2] == '?' && Path[3] == '\\') {
|
||||
RETURN_STRING(Path + 4, 1);
|
||||
}
|
||||
} else {
|
||||
RETURN_STRING(Path, 1);
|
||||
if (php_sys_readlink(link, target, MAXPATHLEN) == -1) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "readlink failed to read the symbolic link (%s), error %d)", link, GetLastError());
|
||||
}
|
||||
RETURN_STRING(target, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user