diff options
Diffstat (limited to 'src/VBox/Runtime/r3/win/path-win.cpp')
-rw-r--r-- | src/VBox/Runtime/r3/win/path-win.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/VBox/Runtime/r3/win/path-win.cpp b/src/VBox/Runtime/r3/win/path-win.cpp index df85a2121..9f24ad5f4 100644 --- a/src/VBox/Runtime/r3/win/path-win.cpp +++ b/src/VBox/Runtime/r3/win/path-win.cpp @@ -1,4 +1,4 @@ -/* $Id: path-win.cpp $ */ +/* $Id: path-win.cpp 36879 2011-04-29 09:15:52Z vboxsync $ */ /** @file * IPRT - Path manipulation. */ @@ -30,11 +30,13 @@ *******************************************************************************/ #define LOG_GROUP RTLOGGROUP_PATH #include <Windows.h> +#include <Shlobj.h> #include <iprt/path.h> #include <iprt/assert.h> #include <iprt/string.h> #include <iprt/time.h> +#include <iprt/ldr.h> #include <iprt/mem.h> #include <iprt/param.h> #include <iprt/log.h> @@ -42,6 +44,9 @@ #include "internal/path.h" #include "internal/fs.h" +/* Needed for lazy loading SHGetFolderPathW in RTPathUserDocuments(). */ +typedef HRESULT FNSHGETFOLDERPATHW(HWND, int, HANDLE, DWORD, LPWSTR); +typedef FNSHGETFOLDERPATHW *PFNSHGETFOLDERPATHW; /** * Get the real (no symlinks, no . or .. components) path, must exist. @@ -181,6 +186,40 @@ RTDECL(int) RTPathUserHome(char *pszPath, size_t cchPath) } +RTDECL(int) RTPathUserDocuments(char *pszPath, size_t cchPath) +{ + /* + * Validate input + */ + AssertPtrReturn(pszPath, VERR_INVALID_POINTER); + AssertReturn(cchPath, VERR_INVALID_PARAMETER); + + RTLDRMOD hShell32; + int rc = RTLdrLoad("Shell32.dll", &hShell32); + if (RT_SUCCESS(rc)) + { + PFNSHGETFOLDERPATHW pfnSHGetFolderPathW; + rc = RTLdrGetSymbol(hShell32, "SHGetFolderPathW", (void**)&pfnSHGetFolderPathW); + if (RT_SUCCESS(rc)) + { + RTUTF16 wszPath[RTPATH_MAX]; + HRESULT hrc = pfnSHGetFolderPathW(0, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, wszPath); + if ( hrc == S_OK /* Found */ + || hrc == S_FALSE) /* Found, but doesn't exist */ + { + /* + * Convert and return. + */ + RTLdrClose(hShell32); + return RTUtf16ToUtf8Ex(&wszPath[0], RTSTR_MAX, &pszPath, cchPath, NULL); + } + } + RTLdrClose(hShell32); + } + return VERR_PATH_NOT_FOUND; +} + + RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs) { return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK); |