FString I_GetLongPathName(FString shortpath) { static TOptWin32Proc<DWORD (WINAPI*)(LPCTSTR, LPTSTR, DWORD)> GetLongPathNameA("kernel32.dll", "GetLongPathNameA"); // Doesn't exist on NT4 if (GetLongPathName == NULL) return shortpath; DWORD buffsize = GetLongPathNameA.Call(shortpath.GetChars(), NULL, 0); if (buffsize == 0) { // nothing to change (it doesn't exist, maybe?) return shortpath; } TCHAR *buff = new TCHAR[buffsize]; DWORD buffsize2 = GetLongPathNameA.Call(shortpath.GetChars(), buff, buffsize); if (buffsize2 >= buffsize) { // Failure! Just return the short path delete[] buff; return shortpath; } FString longpath(buff, buffsize2); delete[] buff; return longpath; }
bool GetKnownFolder(int shell_folder, REFKNOWNFOLDERID known_folder, bool create, FString &path) { static TOptWin32Proc<GKFP> SHGetKnownFolderPath("shell32.dll", "SHGetKnownFolderPath"); char pathstr[MAX_PATH]; // SHGetKnownFolderPath knows about more folders than SHGetFolderPath, but is // new to Vista, hence the reason we support both. if (SHGetKnownFolderPath == NULL) { static TOptWin32Proc<HRESULT(WINAPI*)(HWND, int, HANDLE, DWORD, LPTSTR)> SHGetFolderPathA("shell32.dll", "SHGetFolderPathA"); // NT4 doesn't even have this function. if (SHGetFolderPathA == NULL) return false; if (shell_folder < 0) { // Not supported by SHGetFolderPath return false; } if (create) { shell_folder |= CSIDL_FLAG_CREATE; } if (FAILED(SHGetFolderPathA.Call(NULL, shell_folder, NULL, 0, pathstr))) { return false; } path = pathstr; return true; } else { PWSTR wpath; if (FAILED(SHGetKnownFolderPath.Call(known_folder, create ? KF_FLAG_CREATE : 0, NULL, &wpath))) { return false; } // FIXME: Support Unicode, at least for filenames. This function // has no MBCS equivalent, so we have to convert it since we don't // support Unicode. :( bool converted = false; if (WideCharToMultiByte(GetACP(), WC_NO_BEST_FIT_CHARS, wpath, -1, pathstr, countof(pathstr), NULL, NULL) > 0) { path = pathstr; converted = true; } CoTaskMemFree(wpath); return converted; } }