#include <winnls.h>
*/
-typedef HRESULT (WINAPI *MyPathCchCanonicalizeEx)(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags);
+typedef HRESULT (__stdcall *MyPathCchCanonicalizeEx)(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags);
static MyPathCchCanonicalizeEx canonicalize_path_w = NULL;
return ret_len;
}/*}}}*/
-PW32IO BOOL php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
+PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len)
{/*{{{*/
wchar_t *pos, *idx = *buf, canonicalw[MAXPATHLEN];
- size_t ret_len = len, canonicalw_len, shift;
+ size_t ret_len = len;
if (len >= MAXPATHLEN) {
- SET_ERRNO_FROM_WIN32_CODE(ERROR_BUFFER_OVERFLOW);
- return FALSE;
+ SET_ERRNO_FROM_WIN32_CODE(ERROR_BAD_LENGTH);
+ return PHP_WIN32_IOUTIL_NORM_FAIL;
}
while (NULL != (pos = wcschr(idx, PHP_WIN32_IOUTIL_FW_SLASHW)) && idx - *buf <= len) {
idx = pos++;
}
- shift = PHP_WIN32_IOUTIL_IS_LONG_PATHW(*buf, len) ? PHP_WIN32_IOUTIL_LONG_PATH_PREFIX_LENW : 0;
- if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf + shift, PATHCCH_ALLOW_LONG_PATHS)) {
- *new_len = ret_len;
- return FALSE;
+ if (S_OK != canonicalize_path_w(canonicalw, MAXPATHLEN, *buf, PATHCCH_ALLOW_LONG_PATHS)) {
+ return PHP_WIN32_IOUTIL_NORM_PARTIAL;
}
- canonicalw_len = wcslen(canonicalw);
- if (canonicalw_len + shift != len) {
- if (canonicalw_len > len) {
- *buf = realloc(*buf, (canonicalw_len + 1) * sizeof(wchar_t));
+ ret_len = wcslen(canonicalw);
+ if (ret_len != len) {
+ if (ret_len > len) {
+ wchar_t *tmp = realloc(*buf, (ret_len + 1) * sizeof(wchar_t));
+ if (!tmp) {
+ SET_ERRNO_FROM_WIN32_CODE(ERROR_NOT_ENOUGH_MEMORY);
+ return PHP_WIN32_IOUTIL_NORM_PARTIAL;
+ }
+ *buf = tmp;
}
- memmove(*buf + shift, canonicalw, (canonicalw_len + 1) * sizeof(wchar_t));
- ret_len = canonicalw_len + shift;
+ memmove(*buf, canonicalw, (ret_len + 1) * sizeof(wchar_t));
}
*new_len = ret_len;
- return TRUE;
+ return PHP_WIN32_IOUTIL_NORM_OK;
}/*}}}*/
-static HRESULT MyPathCchCanonicalizeExFallback(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags)
+static HRESULT __stdcall MyPathCchCanonicalizeExFallback(wchar_t *pszPathOut, size_t cchPathOut, const wchar_t *pszPathIn, unsigned long dwFlags)
{/*{{{*/
- cchPathOut = wcslen(pszPathIn);
- memmove(pszPathOut, pszPathIn, (cchPathOut + 1) * sizeof(wchar_t));
-
- return S_OK;
+ return -42;
}/*}}}*/
BOOL php_win32_ioutil_init(void)
PHP_WIN32_IOUTIL_IS_UTF8
} php_win32_ioutil_encoding;
+typedef enum {
+ PHP_WIN32_IOUTIL_NORM_OK,
+ PHP_WIN32_IOUTIL_NORM_PARTIAL,
+ PHP_WIN32_IOUTIL_NORM_FAIL,
+} php_win32_ioutil_normalization_result;
#define PHP_WIN32_IOUTIL_FW_SLASHW L'/'
#define PHP_WIN32_IOUTIL_FW_SLASH '/'
} \
} while (0);
-PW32IO BOOL php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len);
+PW32IO php_win32_ioutil_normalization_result php_win32_ioutil_normalize_path_w(wchar_t **buf, size_t len, size_t *new_len);
#ifdef PHP_EXPORTS
/* This symbols are needed only for the DllMain, but should not be exported
or be available when used with PHP binaries. */
return NULL;
}
+ /* The return can be ignored here, as the normalization can fail for
+ various reasons not directly related to the operation itself.
+ Partial normalization could still do a better job further. And
+ otherwise, the path might be unchanged which is ok if the path
+ was valid long one. */
(void)php_win32_ioutil_normalize_path_w(&mb, mb_len, &mb_len);
if (PHP_WIN32_IOUTIL_IS_LONG_PATHW(mb, mb_len)) {