diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index 8515468e6..bde05a643 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -866,7 +866,7 @@ static bool _CheckIniFile(LPWSTR lpszFile, LPCWSTR lpszModule) result = true; } // Application Data (%APPDATA%) - if (!result && GetKnownFolderPath(FOLDERID_RoamingAppData, tchBuild, COUNTOF(tchBuild))) { + if (!result && PathGetKnownFolder(FOLDERID_RoamingAppData, tchBuild, COUNTOF(tchBuild))) { PathAppend(tchBuild, Path_Get(hPathExpanded)); if (PathIsExistingFile(tchBuild)) { StringCchCopy(lpszFile, MAX_PATH, tchBuild); @@ -874,7 +874,7 @@ static bool _CheckIniFile(LPWSTR lpszFile, LPCWSTR lpszModule) } } // Home (%HOMEPATH%) user's profile dir - if (!result && GetKnownFolderPath(FOLDERID_Profile, tchBuild, COUNTOF(tchBuild))) { + if (!result && PathGetKnownFolder(FOLDERID_Profile, tchBuild, COUNTOF(tchBuild))) { PathAppend(tchBuild, Path_Get(hPathExpanded)); if (PathIsExistingFile(tchBuild)) { StringCchCopy(lpszFile, MAX_PATH, tchBuild); @@ -1364,12 +1364,12 @@ void LoadSettings() Defaults.EFR_Data.fuFlags = 0; Settings.EFR_Data.fuFlags = (UINT)IniSectionGetInt(IniSecSettings, L"efrData_fuFlags", (int)Defaults.EFR_Data.fuFlags); - GetKnownFolderPath(FOLDERID_Desktop, Defaults.OpenWithDir, COUNTOF(Defaults.OpenWithDir)); + PathGetKnownFolder(FOLDERID_Desktop, Defaults.OpenWithDir, COUNTOF(Defaults.OpenWithDir)); if (IniSectionGetStringNoQuotes(IniSecSettings, L"OpenWithDir", Defaults.OpenWithDir, Settings.OpenWithDir, COUNTOF(Settings.OpenWithDir))) { PathAbsoluteFromApp(Settings.OpenWithDir, NULL, COUNTOF(Settings.OpenWithDir), true); } - GetKnownFolderPath(FOLDERID_Favorites, Defaults.FavoritesDir, COUNTOF(Defaults.FavoritesDir)); + PathGetKnownFolder(FOLDERID_Favorites, Defaults.FavoritesDir, COUNTOF(Defaults.FavoritesDir)); if (IniSectionGetStringNoQuotes(IniSecSettings, L"Favorites", Defaults.FavoritesDir, Settings.FavoritesDir, COUNTOF(Settings.FavoritesDir))) { PathAbsoluteFromApp(Settings.FavoritesDir, NULL, COUNTOF(Settings.FavoritesDir), true); } diff --git a/src/DynStrg.c b/src/DynStrg.c index bf2b5455d..c5c49780a 100644 --- a/src/DynStrg.c +++ b/src/DynStrg.c @@ -98,6 +98,8 @@ inline static void FreeBuffer(wchar_t * pstr) { } FreeMemStrg(pstr); } + +// ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- inline static void FreeBufferW(STRINGW* pstr) { @@ -984,8 +986,7 @@ wchar_t* STRAPI StrgWriteAccessBuf(HSTRINGW hstr, size_t min_len) if (pstr->alloc_length <= min_len) { size_t old_len = 0; - wchar_t* pOld = CopyOldDataW(pstr, &old_len); - FreeBufferW(pstr); + wchar_t* const pOld = CopyOldDataW(pstr, &old_len); SetCopyW(pstr, min_len, pOld); FreeBuffer(pOld); } @@ -998,10 +999,12 @@ void STRAPI StrgSanitize(HSTRINGW hstr) STRINGW* pstr = ToWStrg(hstr); if (!pstr) return; - // ensure buffer limit + + // ensure buffer limits + pstr->alloc_length = (SizeOfMemStrg(pstr->data) / sizeof(wchar_t)); ptrdiff_t const len = (ptrdiff_t)pstr->alloc_length - 1; if (len > 0) { - pstr->data[len] = L'\0'; + pstr->data[len] = L'\0'; // terminating zero } pstr->data_length = StrlenW(pstr->data); } diff --git a/src/Helpers.h b/src/Helpers.h index 45b90f8b2..0bb01d72e 100644 --- a/src/Helpers.h +++ b/src/Helpers.h @@ -780,7 +780,7 @@ inline int GetHexDigitW(const WCHAR ch) void UrlEscapeEx(LPCWSTR lpURL, LPWSTR lpEscaped, DWORD* pcchEscaped, bool bEscReserved); void UrlUnescapeEx(LPWSTR lpURL, LPWSTR lpUnescaped, DWORD* pcchUnescaped); -int ReadStrgsFromCSV(LPCWSTR wchCSVStrg, prefix_t sMatrix[], int iCount, int iLen, LPCWSTR sDefault); +int ReadStrgsFromCSV(LPCWSTR wchCSVStrg, prefix_t sMatrix[], int iCount, int iLen, LPCWSTR sDefault); size_t ReadVectorFromString(LPCWSTR wchStrg, int iVector[], size_t iCount, int iMin, int iMax, int iDefault, bool ordered); size_t NormalizeColumnVector(LPSTR chStrg_in, LPWSTR wchStrg_out, size_t iCount); diff --git a/src/PathLib.c b/src/PathLib.c index ce132df84..a8ef4a965 100644 --- a/src/PathLib.c +++ b/src/PathLib.c @@ -120,7 +120,6 @@ #define NP3_PATH_LIB_IMPLEMENTATION 1 -#include "DynStrg.h" #include "PathLib.h" @@ -139,7 +138,10 @@ const wchar_t* const PATHLONG_PREFIX = L"\\\\?\\"; #define PATHLONG_PREFIX_LEN (COUNTOF(PATHLONG_PREFIX) - 1) -#define PATHLONG_MAX_CCH PATHCCH_MAX_CCH +#define PATHLONG_MAX_CCH PATHCCH_MAX_CCH +// TODO: ... +#define limit_len(len) (((len) < PATHLONG_MAX_CCH) ? (len) : (PATHLONG_MAX_CCH - 1)) + #define IS_VALID_HANDLE(HNDL) ((HNDL) && ((HNDL) != INVALID_HANDLE_VALUE)) @@ -279,10 +281,10 @@ bool PTHAPI Path_Append(HPATHL hpth, HPATHL hmore) DWORD const dwFlags = PATHCCH_ALLOW_LONG_PATHS; // Windows 10, version 1703: // PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS | PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH - bool const bOK = SUCCEEDED(PathCchAppendEx(wbuf, cch, wmore, dwFlags)); + bool const res = SUCCEEDED(PathCchAppendEx(wbuf, cch, wmore, dwFlags)); StrgSanitize(hstr); - return bOK; + return res; } // ---------------------------------------------------------------------------- @@ -308,10 +310,10 @@ bool PTHAPI Path_Canonicalize(HPATHL hpth_out, HPATHL hpth_in) // Windows 10, version 1703: // PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS | PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH // PATHCCH_ENSURE_TRAILING_SLASH - bool const bOK = SUCCEEDED(PathCchCanonicalizeEx(wbuf_out, cch_out, wbuf_in, dwFlags)); + bool const res = SUCCEEDED(PathCchCanonicalizeEx(wbuf_out, cch_out, wbuf_in, dwFlags)); StrgSanitize(hstr_out); - return bOK; + return res; } // ---------------------------------------------------------------------------- @@ -361,21 +363,8 @@ void PTHAPI Path_ExpandEnvStrings(HPATHL hpth) HSTRINGW hstr = ToHStrgW(hpth); if (!hstr) return; - - LPCWSTR const path_buf = StrgGet(hstr); - - HSTRINGW hstr_exp = StrgCreate(); - - size_t const min_len = max(ExpandEnvironmentStringsW(path_buf, NULL, 0), MAX_PATH); - LPWSTR expth_buf = StrgWriteAccessBuf(hstr_exp, min_len); - - DWORD const nSize = (DWORD)StrgGetAllocLength(hstr_exp); - ExpandEnvironmentStringsW(path_buf, expth_buf, nSize); - StrgSanitize(hstr_exp); - StrgSet(hstr, expth_buf); - - StrgDestroy(hstr_exp); + ExpandEnvironmentStrg(hstr); } // ---------------------------------------------------------------------------- @@ -417,10 +406,225 @@ bool PTHAPI Path_IsExistingFile(HPATHL hpth) // ---------------------------------------------------------------------------- +void PTHAPI Path_GetModuleFileName(HPATHL hpth_out) +{ + HSTRINGW hmod_str = ToHStrgW(hpth_out); + wchar_t* const buf = StrgWriteAccessBuf(hmod_str, PATHLONG_MAX_CCH); + GetModuleFileNameW(NULL, buf, PATHLONG_MAX_CCH); + StrgSanitize(hmod_str); + StrgFreeExtra(hmod_str); +} +// ---------------------------------------------------------------------------- +// ============================================================================ +// Old Stuff in INTERMEDIATE DEV state +// ============================================================================ + + +//============================================================================= +// +// ExpandEnvironmentStringsEx() +// +void PTHAPI ExpandEnvironmentStrg(HSTRINGW hstr_in_out) +{ + HSTRINGW const hstr_cpy = StrgCopy(hstr_in_out); // no inplace substitution possible + + size_t const min_len = ExpandEnvironmentStringsW(StrgGet(hstr_in_out), NULL, 0); + LPWSTR buf_io = StrgWriteAccessBuf(hstr_in_out, min_len); + DWORD const cch_io = (DWORD)StrgGetAllocLength(hstr_in_out); + + if (ExpandEnvironmentStringsW(StrgGet(hstr_cpy), buf_io, cch_io)) { + StrgSanitize(hstr_in_out); + } + StrgDestroy(hstr_cpy); +} + +void PTHAPI ExpandEnvironmentStringsEx(LPWSTR lpSrc, size_t cchSrc) +{ + HSTRINGW hstr = StrgCreate(); + StrgSet(hstr, lpSrc); + ExpandEnvironmentStrg(hstr); + const wchar_t* buf = StrgGet(hstr); + if (buf) { + StringCchCopyW(lpSrc, cchSrc, buf); + } + StrgDestroy(hstr); +} + + +//============================================================================= +// +// GetLongPathNameEx() +// + +DWORD PTHAPI Path_GetLongPathNameEx(HPATHL hpth_in_out) +{ + HSTRINGW hstr_io = ToHStrgW(hpth_in_out); + if (!hstr_io) + return 0UL; + + DWORD const len = (size_t)GetLongPathNameW(StrgGet(hstr_io), NULL, 0); + wchar_t* const buf = StrgWriteAccessBuf(hstr_io, (size_t)len); + + DWORD const dwRet = GetLongPathNameW(buf, buf, len); + StrgSanitize(hstr_io); + + if (dwRet > 2UL) { + wchar_t* const pos = wcschr(buf, L':'); + if (pos && (pos > buf)) { + CharUpperBuffW(pos - 1, 1); + } + } + return dwRet; +} + + +DWORD PTHAPI GetLongPathNameEx(LPWSTR lpszPath, DWORD cchBuffer) +{ + HPATHL hpth = Path_Allocate(lpszPath); + DWORD const dwRet = Path_GetLongPathNameEx(hpth); + if (dwRet) { + StringCchCopyW(lpszPath, cchBuffer, Path_Get(hpth)); + } + Path_Release(hpth); + return dwRet; +} + + +//============================================================================= +// +// GetKnownFolderPath() +// + +bool PTHAPI Path_GetKnownFolder(REFKNOWNFOLDERID rfid, HPATHL hpth_out) +{ + HSTRINGW hstr_out = ToHStrgW(hpth_out); + PWSTR pszPath = NULL; + const DWORD dwFlags = KF_FLAG_NO_ALIAS; + //(KF_FLAG_DEFAULT_PATH | KF_FLAG_NOT_PARENT_RELATIVE | KF_FLAG_NO_ALIAS); + HRESULT const hr = SHGetKnownFolderPath(rfid, dwFlags, NULL, &pszPath); + if (SUCCEEDED(hr) && pszPath) { + StrgSet(hstr_out, pszPath); + CoTaskMemFree(pszPath); + return true; + } + return false; +} + +bool PTHAPI PathGetKnownFolder(REFKNOWNFOLDERID rfid, LPWSTR lpOutPath, size_t cchOut) +{ + HPATHL hpth = Path_Allocate(NULL); + bool const res = Path_GetKnownFolder(rfid, hpth); + if (res) { + StringCchCopyW(lpOutPath, cchOut, Path_Get(hpth)); + } + Path_Release(hpth); + return res; +} + + +//============================================================================= +// +// PathCanonicalizeEx() +// + +inline static bool _PathIsRelative(HPATHL hpth) +{ + HSTRINGW hstr = ToHStrgW(hpth); + if (!hstr) + return true; + + HSTRINGW cpy = StrgCopy(hstr); + + bool res = false; + if (StrgGetLength(cpy) >= MAX_PATH) { + // hack for MAX_PATH limit + wchar_t* const buf = (wchar_t* const)StrgGet(cpy); + buf[MAX_PATH] = L'\0'; + size_t const pos = StrgReverseFind(cpy, L'\\'); + if (pos != STRINGW_INVALID_IDX) { + buf[pos] = L'\0'; + res = PathIsRelativeW(StrgGet(cpy)); + } + } + else { + res = PathIsRelativeW(StrgGet(cpy)); + } + + StrgDestroy(cpy); + return res; +} + + +bool PTHAPI Path_CanonicalizeEx(HPATHL hpth_in_out) +{ + HSTRINGW hstr_io = ToHStrgW(hpth_in_out); + if (!hstr_io) + return false; + + ExpandEnvironmentStrg(hstr_io); // inplace hpth_in_out + + bool res = false; + if (_PathIsRelative(hpth_in_out)) { + + HPATHL hmod_pth = Path_Allocate(NULL); + Path_GetModuleFileName(hmod_pth); + Path_RemoveFileSpec(hmod_pth); + Path_Append(hmod_pth, hpth_in_out); + res = Path_Canonicalize(hpth_in_out, hmod_pth); + + Path_Release(hmod_pth); + } + else { + HPATHL const pth_cpy = Path_Allocate(StrgGet(hstr_io)); + res = Path_Canonicalize(hpth_in_out, pth_cpy); + Path_Release(pth_cpy); + } + return res; +} + +bool PTHAPI PathCanonicalizeEx(LPWSTR lpszPath, size_t cchPath) +{ + HPATHL hpth = Path_Allocate(lpszPath); + bool const res = Path_CanonicalizeEx(hpth); + if (res) { + StringCchCopyW(lpszPath, cchPath, Path_Get(hpth)); + } + Path_Release(hpth); + return res; +} + + + +//============================================================================= +// +// PathGetModuleDirectory() +// +void PTHAPI Path_GetAppDirectory(HPATHL hpth_out) +{ + HPATHL hmod_pth = Path_Allocate(NULL); + Path_GetModuleFileName(hmod_pth); + Path_RemoveFileSpec(hmod_pth); + Path_Canonicalize(hpth_out, hmod_pth); + Path_Release(hmod_pth); +} + +void PTHAPI PathGetAppDirectory(LPWSTR lpszDest, DWORD cchDest) +{ + HPATHL hpth = Path_Allocate(NULL); + Path_GetAppDirectory(hpth); + const wchar_t* buf = Path_Get(hpth); + if (buf) { + StringCchCopyW(lpszDest, cchDest, buf); + } + Path_Release(hpth); +} + + + // ============================================================================ // Some Old MAX_PATH stuff @@ -428,36 +632,6 @@ bool PTHAPI Path_IsExistingFile(HPATHL hpth) // ============================================================================ -//============================================================================= -// -// GetKnownFolderPath() -// -bool PTHAPI GetKnownFolderPath(REFKNOWNFOLDERID rfid, LPWSTR lpOutPath, size_t cchCount) -{ - //const DWORD dwFlags = (KF_FLAG_DEFAULT_PATH | KF_FLAG_NOT_PARENT_RELATIVE | KF_FLAG_NO_ALIAS); - const DWORD dwFlags = KF_FLAG_NO_ALIAS; - - PWSTR pszPath = NULL; - HRESULT hr = SHGetKnownFolderPath(rfid, dwFlags, NULL, &pszPath); - if (SUCCEEDED(hr) && pszPath) { - StringCchCopy(lpOutPath, cchCount, pszPath); - CoTaskMemFree(pszPath); - return true; - } - return false; -} - -//============================================================================= -// -// PathGetModuleDirectory() -// -void PTHAPI PathGetAppDirectory(LPWSTR lpszDest, DWORD cchDest) -{ - GetModuleFileName(NULL, lpszDest, cchDest); - PathRemoveFileSpec(lpszDest); - PathCanonicalizeEx(lpszDest, cchDest); -} - //============================================================================= // // PathRelativeToApp() @@ -477,7 +651,7 @@ void PTHAPI PathRelativeToApp( PathGetAppDirectory(wchAppDir, COUNTOF(wchAppDir)); (void)GetWindowsDirectory(wchWinDir, COUNTOF(wchWinDir)); - GetKnownFolderPath(&FOLDERID_Documents, wchUserFiles, COUNTOF(wchUserFiles)); + PathGetKnownFolder(&FOLDERID_Documents, wchUserFiles, COUNTOF(wchUserFiles)); if (bUnexpandMyDocs && !PathIsRelative(lpszSrc) && @@ -530,7 +704,7 @@ void PTHAPI PathAbsoluteFromApp(LPWSTR lpszSrc, LPWSTR lpszDest, int cchDest, bo } if (StrCmpNI(lpszSrc, L"%CSIDL:MYDOCUMENTS%", CONSTSTRGLEN("%CSIDL:MYDOCUMENTS%")) == 0) { - GetKnownFolderPath(&FOLDERID_Documents, wchPath, COUNTOF(wchPath)); + PathGetKnownFolder(&FOLDERID_Documents, wchPath, COUNTOF(wchPath)); PathAppend(wchPath, lpszSrc + CONSTSTRGLEN("%CSIDL:MYDOCUMENTS%")); } else { @@ -695,7 +869,7 @@ bool PTHAPI PathCreateDeskLnk(LPCWSTR pszDocument, LPCWSTR pszDescription) StringCchCopy(tchArguments, COUNTOF(tchArguments), L"-n "); StringCchCat(tchArguments, COUNTOF(tchArguments), tchDocTemp); - GetKnownFolderPath(&FOLDERID_Desktop, tchLinkDir, COUNTOF(tchLinkDir)); + PathGetKnownFolder(&FOLDERID_Desktop, tchLinkDir, COUNTOF(tchLinkDir)); // Try to construct a valid filename... if (!SHGetNewLinkInfo(pszDocument, tchLinkDir, tchLnkFileName, &fMustCopy, SHGNLI_PREFIXNAME)) { @@ -785,66 +959,6 @@ bool PTHAPI PathCreateFavLnk(LPCWSTR pszName, LPCWSTR pszTarget, LPCWSTR pszDir) } -//============================================================================= -// -// ExpandEnvironmentStringsEx() -// -void PTHAPI ExpandEnvironmentStringsEx(LPWSTR lpSrc, size_t cchSrc) -{ - HSTRINGW hstr_exp = StrgCreate(); - size_t const min_len = ExpandEnvironmentStringsW(lpSrc, NULL, 0); - LPWSTR exp_buf = StrgWriteAccessBuf(hstr_exp, min_len); - DWORD const cchexp = (DWORD)StrgGetAllocLength(hstr_exp); - - if (ExpandEnvironmentStringsW(lpSrc, exp_buf, cchexp)) { - StrgSanitize(hstr_exp); - StringCchCopyNW(lpSrc, cchSrc, exp_buf, StrgGetAllocLength(hstr_exp)); - } - StrgDestroy(hstr_exp); -} - - - -//============================================================================= -// -// PathCanonicalizeEx() -// -bool PTHAPI PathCanonicalizeEx(LPWSTR lpszPath, size_t cchPath) -{ - WCHAR filePath[MAX_PATH] = { L'\0' }; - StringCchCopyN(filePath, COUNTOF(filePath), lpszPath, cchPath); - - ExpandEnvironmentStringsEx(filePath, COUNTOF(filePath)); - - if (PathIsRelative(filePath)) { - WCHAR tchModule[MAX_PATH] = { L'\0' }; - GetModuleFileName(NULL, tchModule, COUNTOF(tchModule)); - PathRemoveFileSpec(tchModule); - PathAppend(tchModule, lpszPath); - StringCchCopyN(filePath, COUNTOF(filePath), tchModule, COUNTOF(tchModule)); - } - return PathCanonicalize(lpszPath, filePath); -} - - -//============================================================================= -// -// GetLongPathNameEx() -// -DWORD PTHAPI GetLongPathNameEx(LPWSTR lpszPath, DWORD cchBuffer) -{ - DWORD const dwRet = GetLongPathNameW(lpszPath, lpszPath, cchBuffer); - if (dwRet) { - if (PathGetDriveNumber(lpszPath) != -1) { - CharUpperBuff(lpszPath, 1); - } - } - return dwRet; -} - - - - //============================================================================= // // _SHGetFileInfoEx() diff --git a/src/PathLib.h b/src/PathLib.h index 6722b7f43..683c73b41 100644 --- a/src/PathLib.h +++ b/src/PathLib.h @@ -5,6 +5,8 @@ #define PATHCCH_NO_DEPRECATE 1 ///#include +#include "DynStrg.h" + /**************************************************/ /* Declared in WINNT.H */ @@ -41,6 +43,7 @@ bool PTHAPI Path_RemoveFileSpec(HPATHL hpth); bool PTHAPI Path_RenameExtension(HPATHL hpth, const wchar_t* ext); void PTHAPI Path_ExpandEnvStrings(HPATHL hpth); bool PTHAPI Path_IsExistingFile(HPATHL hpth); +void PTHAPI Path_GetModuleFileName(HPATHL hpth_out); // ------------------------------------------------------- @@ -69,12 +72,32 @@ inline bool PathIsExistingFile(LPCWSTR pszPath) return (PathFileExists(pszPath) && !PathIsDirectory(pszPath)); } + + +// ============================================================================ +// Duplicates for INTERMEDIATE DEV +// ============================================================================ + +void PTHAPI ExpandEnvironmentStrg(HSTRINGW hstr); +void PTHAPI ExpandEnvironmentStringsEx(LPWSTR lpSrc, size_t cchSrc); + +DWORD PTHAPI Path_GetLongPathNameEx(HPATHL hpth_in_out); +DWORD PTHAPI GetLongPathNameEx(LPWSTR lpszPath, DWORD cchBuffer); + +bool PTHAPI Path_GetKnownFolder(REFKNOWNFOLDERID rfid, HPATHL hpth_out); +bool PTHAPI PathGetKnownFolder(REFKNOWNFOLDERID, LPWSTR lpOutPath, size_t cchOut); + +bool PTHAPI Path_CanonicalizeEx(HPATHL hpth_in_out); +bool PTHAPI PathCanonicalizeEx(LPWSTR lpszPath, size_t cchPath); + +void PTHAPI Path_GetAppDirectory(HPATHL hpth_out); +void PTHAPI PathGetAppDirectory(LPWSTR lpszDest, DWORD cchDest); + + // ============================================================================ // Some Old MAX_PATH stuff // ============================================================================ -bool PTHAPI GetKnownFolderPath(REFKNOWNFOLDERID, LPWSTR lpOutPath, size_t cchCount); -void PTHAPI PathGetAppDirectory(LPWSTR lpszDest, DWORD cchDest); void PTHAPI PathRelativeToApp(LPWSTR lpszSrc, LPWSTR lpszDest, int cchDest, bool, bool, bool); void PTHAPI PathAbsoluteFromApp(LPWSTR lpszSrc, LPWSTR lpszDest, int cchDest, bool); @@ -84,9 +107,6 @@ bool PTHAPI PathIsLnkToDirectory(LPCWSTR pszPath, LPWSTR pszResPath, int cchRe bool PTHAPI PathCreateDeskLnk(LPCWSTR pszDocument, LPCWSTR pszDescription); bool PTHAPI PathCreateFavLnk(LPCWSTR pszName, LPCWSTR pszTarget, LPCWSTR pszDir); -void PTHAPI ExpandEnvironmentStringsEx(LPWSTR lpSrc, size_t cchSrc); -bool PTHAPI PathCanonicalizeEx(LPWSTR lpszPath, size_t cchPath); -DWORD PTHAPI GetLongPathNameEx(LPWSTR lpszPath, DWORD cchBuffer); void PTHAPI PathGetDisplayName(LPWSTR lpszDestPath, DWORD cchDestBuffer, LPCWSTR lpszSourcePath); DWORD PTHAPI NormalizePathEx(LPWSTR lpszPath, DWORD cchBuffer, LPCWSTR lpszWorkDir, bool bRealPath, bool bSearchPathIfRelative);