From 3a9653d24ea2fd878f86fb7b0889814fbfc5d851 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Mon, 3 Nov 2014 13:29:18 +0000 Subject: [PATCH] [SHELL32] * Move shellpath.cpp to the wine folder. * Rename shellpath.cpp to shellpath.c. * Partially sync shellpath.c with Wine 1.7.27. CORE-8540 svn path=/branches/shell-experiments/; revision=65221 --- dll/win32/shell32/CMakeLists.txt | 2 +- dll/win32/shell32/dialogs/filedefext.cpp | 2 +- dll/win32/shell32/openwithmenu.cpp | 2 +- dll/win32/shell32/pidl.h | 12 +- .../{shellpath.cpp => wine/shellpath.c} | 1483 ++++++++++++----- 5 files changed, 1081 insertions(+), 420 deletions(-) rename dll/win32/shell32/{shellpath.cpp => wine/shellpath.c} (54%) diff --git a/dll/win32/shell32/CMakeLists.txt b/dll/win32/shell32/CMakeLists.txt index 114fb4f5ef5..678a503a078 100644 --- a/dll/win32/shell32/CMakeLists.txt +++ b/dll/win32/shell32/CMakeLists.txt @@ -45,7 +45,6 @@ list(APPEND SOURCE shellitem.cpp shelllink.cpp shellord.cpp - shellpath.cpp shellreg.cpp folders/desktop.cpp folders/fs.cpp @@ -77,6 +76,7 @@ add_library(shell32 SHARED ${SOURCE} wine/shell32_main.c wine/shellole.c + wine/shellpath.c wine/shellstring.c vista.c shell32.rc diff --git a/dll/win32/shell32/dialogs/filedefext.cpp b/dll/win32/shell32/dialogs/filedefext.cpp index 82a666435cb..473d9f78902 100644 --- a/dll/win32/shell32/dialogs/filedefext.cpp +++ b/dll/win32/shell32/dialogs/filedefext.cpp @@ -23,7 +23,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); -BOOL PathIsExeW(LPCWSTR lpszPath); +EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath); BOOL CFileVersionInfo::Load(LPCWSTR pwszPath) { diff --git a/dll/win32/shell32/openwithmenu.cpp b/dll/win32/shell32/openwithmenu.cpp index b73a41e94c8..6ce733b082f 100644 --- a/dll/win32/shell32/openwithmenu.cpp +++ b/dll/win32/shell32/openwithmenu.cpp @@ -29,7 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); // "NoInternetOpenWith"=dword:00000001 // -BOOL PathIsExeW(LPCWSTR lpszPath); +EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath); class COpenWithList { diff --git a/dll/win32/shell32/pidl.h b/dll/win32/shell32/pidl.h index 71fcd5cb47f..82a2fc7f413 100644 --- a/dll/win32/shell32/pidl.h +++ b/dll/win32/shell32/pidl.h @@ -35,6 +35,10 @@ #ifndef __WINE_PIDL_H #define __WINE_PIDL_H +#ifdef __cplusplus +extern "C" { +#endif + /* * the pidl does cache fileattributes to speed up SHGetAttributes when * displaying a big number of files. @@ -213,8 +217,8 @@ DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize); BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); -EXTERN_C BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); -EXTERN_C void _ILGetFileType (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); +BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); +void _ILGetFileType (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); DWORD _ILGetFileAttributes (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize); BOOL _ILGetFileDateTime (LPCITEMIDLIST pidl, FILETIME *ft); @@ -301,4 +305,8 @@ LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, const CIDA * cida); BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type); +#ifdef __cplusplus +} /* extern "C" */ +#endif + #endif /* __WINE_PIDL_H */ diff --git a/dll/win32/shell32/shellpath.cpp b/dll/win32/shell32/wine/shellpath.c similarity index 54% rename from dll/win32/shell32/shellpath.cpp rename to dll/win32/shell32/wine/shellpath.c index 7d2c2f0d8bb..4255e6a21a6 100644 --- a/dll/win32/shell32/shellpath.cpp +++ b/dll/win32/shell32/wine/shellpath.c @@ -24,40 +24,57 @@ * */ -#include "precomp.h" +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COBJMACROS +#include + +#include +#include +#include +#include +#include #include +#include +#include + +#include "pidl.h" +#include "shell32_main.h" +#include "shresdef.h" WINE_DEFAULT_DEBUG_CHANNEL(shell); +static const BOOL is_win64 = sizeof(void *) > sizeof(int); + /* - ########## Combining and Constructing paths ########## + ########## Combining and Constructing paths ########## */ /************************************************************************* - * PathAppend [SHELL32.36] + * PathAppend [SHELL32.36] */ BOOL WINAPI PathAppendAW( - LPVOID lpszPath1, - LPCVOID lpszPath2) + LPVOID lpszPath1, + LPCVOID lpszPath2) { - if (SHELL_OsIsUnicode()) - return PathAppendW((LPWSTR)lpszPath1, (LPCWSTR)lpszPath2); - return PathAppendA((LPSTR)lpszPath1, (LPCSTR)lpszPath2); + if (SHELL_OsIsUnicode()) + return PathAppendW(lpszPath1, lpszPath2); + return PathAppendA(lpszPath1, lpszPath2); } /************************************************************************* - * PathBuildRoot [SHELL32.30] + * PathBuildRoot [SHELL32.30] */ LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive) { - if(SHELL_OsIsUnicode()) - return PathBuildRootW((LPWSTR)lpszPath, drive); - return PathBuildRootA((LPSTR)lpszPath, drive); + if(SHELL_OsIsUnicode()) + return PathBuildRootW(lpszPath, drive); + return PathBuildRootA(lpszPath, drive); } /************************************************************************* - * PathGetExtensionA [internal] + * PathGetExtensionA [internal] * * NOTES * exported by ordinal @@ -65,21 +82,21 @@ LPVOID WINAPI PathBuildRootAW(LPVOID lpszPath, int drive) */ static LPSTR PathGetExtensionA(LPCSTR lpszPath) { - TRACE("(%s)\n",lpszPath); + TRACE("(%s)\n",lpszPath); - lpszPath = PathFindExtensionA(lpszPath); - return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath); + lpszPath = PathFindExtensionA(lpszPath); + return (LPSTR)(*lpszPath?(lpszPath+1):lpszPath); } /************************************************************************* - * PathGetExtensionW [internal] + * PathGetExtensionW [internal] */ static LPWSTR PathGetExtensionW(LPCWSTR lpszPath) { - TRACE("(%s)\n",debugstr_w(lpszPath)); + TRACE("(%s)\n",debugstr_w(lpszPath)); - lpszPath = PathFindExtensionW(lpszPath); - return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath); + lpszPath = PathFindExtensionW(lpszPath); + return (LPWSTR)(*lpszPath?(lpszPath+1):lpszPath); } /************************************************************************* @@ -95,13 +112,13 @@ EXTERN_C LPVOID WINAPI SHPathGetExtensionW(LPCWSTR lpszPath, DWORD void1, DWORD */ BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath) { - if (SHELL_OsIsUnicode()) - return PathRemoveFileSpecW((LPWSTR)lpszPath); - return PathRemoveFileSpecA((LPSTR)lpszPath); + if (SHELL_OsIsUnicode()) + return PathRemoveFileSpecW(lpszPath); + return PathRemoveFileSpecA(lpszPath); } /* - Path Manipulations + Path Manipulations */ /************************************************************************* @@ -109,14 +126,14 @@ BOOL WINAPI PathRemoveFileSpecAW(LPVOID lpszPath) */ static void PathGetShortPathA(LPSTR pszPath) { - CHAR path[MAX_PATH]; + CHAR path[MAX_PATH]; - TRACE("%s\n", pszPath); + TRACE("%s\n", pszPath); - if (GetShortPathNameA(pszPath, path, MAX_PATH)) - { - lstrcpyA(pszPath, path); - } + if (GetShortPathNameA(pszPath, path, MAX_PATH)) + { + lstrcpyA(pszPath, path); + } } /************************************************************************* @@ -124,216 +141,231 @@ static void PathGetShortPathA(LPSTR pszPath) */ static void PathGetShortPathW(LPWSTR pszPath) { - WCHAR path[MAX_PATH]; + WCHAR path[MAX_PATH]; - TRACE("%s\n", debugstr_w(pszPath)); + TRACE("%s\n", debugstr_w(pszPath)); - if (GetShortPathNameW(pszPath, path, MAX_PATH)) - { - wcscpy(pszPath, path); - } + if (GetShortPathNameW(pszPath, path, MAX_PATH)) + { + lstrcpyW(pszPath, path); + } } /************************************************************************* * PathGetShortPath [SHELL32.92] */ -EXTERN_C VOID WINAPI PathGetShortPathAW(LPVOID pszPath) +VOID WINAPI PathGetShortPathAW(LPVOID pszPath) { - if(SHELL_OsIsUnicode()) - PathGetShortPathW((LPWSTR)pszPath); - PathGetShortPathA((LPSTR)pszPath); + if(SHELL_OsIsUnicode()) + PathGetShortPathW(pszPath); + PathGetShortPathA(pszPath); } /* - ########## Path Testing ########## + ########## Path Testing ########## */ /************************************************************************* - * PathIsRoot [SHELL32.29] + * PathIsRoot [SHELL32.29] */ BOOL WINAPI PathIsRootAW(LPCVOID lpszPath) { - if (SHELL_OsIsUnicode()) - return PathIsRootW((LPWSTR)lpszPath); - return PathIsRootA((LPSTR)lpszPath); + if (SHELL_OsIsUnicode()) + return PathIsRootW(lpszPath); + return PathIsRootA(lpszPath); } /************************************************************************* - * PathIsExeA [internal] + * PathIsExeA [internal] */ static BOOL PathIsExeA (LPCSTR lpszPath) { - LPCSTR lpszExtension = PathGetExtensionA(lpszPath); + LPCSTR lpszExtension = PathGetExtensionA(lpszPath); int i; static const char * const lpszExtensions[] = {"exe", "com", "pif", "cmd", "bat", "scf", "scr", NULL }; - TRACE("path=%s\n",lpszPath); + TRACE("path=%s\n",lpszPath); - for(i=0; lpszExtensions[i]; i++) - if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE; + for(i=0; lpszExtensions[i]; i++) + if (!lstrcmpiA(lpszExtension,lpszExtensions[i])) return TRUE; - return FALSE; + return FALSE; } /************************************************************************* - * PathIsExeW [internal] + * PathIsExeW [internal] */ BOOL PathIsExeW (LPCWSTR lpszPath) { - LPCWSTR lpszExtension = PathGetExtensionW(lpszPath); + LPCWSTR lpszExtension = PathGetExtensionW(lpszPath); int i; static const WCHAR lpszExtensions[][4] = {{'e','x','e','\0'}, {'c','o','m','\0'}, {'p','i','f','\0'}, {'c','m','d','\0'}, {'b','a','t','\0'}, {'s','c','f','\0'}, {'s','c','r','\0'}, {'\0'} }; - TRACE("path=%s\n",debugstr_w(lpszPath)); + TRACE("path=%s\n",debugstr_w(lpszPath)); - for(i=0; lpszExtensions[i][0]; i++) - if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE; + for(i=0; lpszExtensions[i][0]; i++) + if (!strcmpiW(lpszExtension,lpszExtensions[i])) return TRUE; - return FALSE; + return FALSE; } /************************************************************************* - * PathIsExe [SHELL32.43] + * PathIsExe [SHELL32.43] */ BOOL WINAPI PathIsExeAW (LPCVOID path) { - if (SHELL_OsIsUnicode()) - return PathIsExeW ((LPWSTR)path); - return PathIsExeA((LPSTR)path); + if (SHELL_OsIsUnicode()) + return PathIsExeW (path); + return PathIsExeA(path); } /************************************************************************* - * PathFileExists [SHELL32.45] + * PathFileExists [SHELL32.45] */ BOOL WINAPI PathFileExistsAW (LPCVOID lpszPath) { - if (SHELL_OsIsUnicode()) - return PathFileExistsW ((LPWSTR)lpszPath); - return PathFileExistsA ((LPSTR)lpszPath); + if (SHELL_OsIsUnicode()) + return PathFileExistsW (lpszPath); + return PathFileExistsA (lpszPath); } /************************************************************************* - * PathIsSameRoot [SHELL32.650] + * PathIsSameRoot [SHELL32.650] */ BOOL WINAPI PathIsSameRootAW(LPCVOID lpszPath1, LPCVOID lpszPath2) { - if (SHELL_OsIsUnicode()) - return PathIsSameRootW((LPCWSTR)lpszPath1, (LPCWSTR)lpszPath2); - return PathIsSameRootA((LPCSTR)lpszPath1, (LPCSTR)lpszPath2); + if (SHELL_OsIsUnicode()) + return PathIsSameRootW(lpszPath1, lpszPath2); + return PathIsSameRootA(lpszPath1, lpszPath2); } /************************************************************************* - * IsLFNDriveA [SHELL32.41] + * IsLFNDriveA [SHELL32.41] */ -EXTERN_C BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath) +BOOL WINAPI IsLFNDriveA(LPCSTR lpszPath) { - DWORD fnlen; + DWORD fnlen; if (!GetVolumeInformationA(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0)) - return FALSE; + return FALSE; return fnlen > 12; } /************************************************************************* - * IsLFNDriveW [SHELL32.42] + * IsLFNDriveW [SHELL32.42] */ -EXTERN_C BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath) +BOOL WINAPI IsLFNDriveW(LPCWSTR lpszPath) { - DWORD fnlen; + DWORD fnlen; if (!GetVolumeInformationW(lpszPath, NULL, 0, NULL, &fnlen, NULL, NULL, 0)) - return FALSE; + return FALSE; return fnlen > 12; } /************************************************************************* - * IsLFNDrive [SHELL32.119] + * IsLFNDrive [SHELL32.119] */ -EXTERN_C BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath) +BOOL WINAPI IsLFNDriveAW(LPCVOID lpszPath) { - if (SHELL_OsIsUnicode()) - return IsLFNDriveW((LPCWSTR)lpszPath); - return IsLFNDriveA((LPCSTR)lpszPath); + if (SHELL_OsIsUnicode()) + return IsLFNDriveW(lpszPath); + return IsLFNDriveA(lpszPath); } /* - ########## Creating Something Unique ########## + ########## Creating Something Unique ########## */ /************************************************************************* - * PathMakeUniqueNameA [internal] + * PathMakeUniqueNameA [internal] */ static BOOL PathMakeUniqueNameA( - LPSTR lpszBuffer, - DWORD dwBuffSize, - LPCSTR lpszShortName, - LPCSTR lpszLongName, - LPCSTR lpszPathName) + LPSTR lpszBuffer, + DWORD dwBuffSize, + LPCSTR lpszShortName, + LPCSTR lpszLongName, + LPCSTR lpszPathName) { - FIXME("%p %u %s %s %s stub\n", - lpszBuffer, dwBuffSize, debugstr_a(lpszShortName), - debugstr_a(lpszLongName), debugstr_a(lpszPathName)); - return TRUE; + FIXME("%p %u %s %s %s stub\n", + lpszBuffer, dwBuffSize, debugstr_a(lpszShortName), + debugstr_a(lpszLongName), debugstr_a(lpszPathName)); + return TRUE; } /************************************************************************* - * PathMakeUniqueNameW [internal] + * PathMakeUniqueNameW [internal] */ static BOOL PathMakeUniqueNameW( - LPWSTR lpszBuffer, - DWORD dwBuffSize, - LPCWSTR lpszShortName, - LPCWSTR lpszLongName, - LPCWSTR lpszPathName) + LPWSTR lpszBuffer, + DWORD dwBuffSize, + LPCWSTR lpszShortName, + LPCWSTR lpszLongName, + LPCWSTR lpszPathName) { - FIXME("%p %u %s %s %s stub\n", - lpszBuffer, dwBuffSize, debugstr_w(lpszShortName), - debugstr_w(lpszLongName), debugstr_w(lpszPathName)); - return TRUE; + FIXME("%p %u %s %s %s stub\n", + lpszBuffer, dwBuffSize, debugstr_w(lpszShortName), + debugstr_w(lpszLongName), debugstr_w(lpszPathName)); + return TRUE; } /************************************************************************* - * PathMakeUniqueName [SHELL32.47] + * PathMakeUniqueName [SHELL32.47] */ BOOL WINAPI PathMakeUniqueNameAW( - LPVOID lpszBuffer, - DWORD dwBuffSize, - LPCVOID lpszShortName, - LPCVOID lpszLongName, - LPCVOID lpszPathName) + LPVOID lpszBuffer, + DWORD dwBuffSize, + LPCVOID lpszShortName, + LPCVOID lpszLongName, + LPCVOID lpszPathName) { - if (SHELL_OsIsUnicode()) - return PathMakeUniqueNameW((LPWSTR)lpszBuffer, dwBuffSize, (LPCWSTR)lpszShortName, (LPCWSTR)lpszLongName, (LPCWSTR)lpszPathName); - return PathMakeUniqueNameA((LPSTR)lpszBuffer, dwBuffSize, (LPCSTR)lpszShortName, (LPCSTR)lpszLongName, (LPCSTR)lpszPathName); + if (SHELL_OsIsUnicode()) + return PathMakeUniqueNameW(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName); + return PathMakeUniqueNameA(lpszBuffer,dwBuffSize, lpszShortName,lpszLongName,lpszPathName); } /************************************************************************* * PathYetAnotherMakeUniqueName [SHELL32.75] - * - * NOTES - * exported by ordinal */ -BOOL WINAPI PathYetAnotherMakeUniqueName( - LPWSTR lpszBuffer, - LPCWSTR lpszPathName, - LPCWSTR lpszShortName, - LPCWSTR lpszLongName) +BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname) { - FIXME("(%p, %s, %s ,%s):stub.\n", - lpszBuffer, debugstr_w(lpszPathName), debugstr_w(lpszShortName), debugstr_w(lpszLongName)); + WCHAR pathW[MAX_PATH], retW[MAX_PATH]; + const WCHAR *file, *ext; + int i = 2; + + TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname)); + + file = longname ? longname : shortname; + PathCombineW(pathW, path, file); + strcpyW(retW, pathW); + PathRemoveExtensionW(pathW); + + ext = PathFindExtensionW(file); + + /* now try to make it unique */ + while (PathFileExistsW(retW)) + { + static const WCHAR fmtW[] = {'%','s',' ','(','%','d',')','%','s',0}; + + sprintfW(retW, fmtW, pathW, i, ext); + i++; + } + + strcpyW(buffer, retW); + TRACE("ret - %s\n", debugstr_w(buffer)); + return TRUE; } - /* - ########## cleaning and resolving paths ########## + ########## cleaning and resolving paths ########## */ /************************************************************************* - * PathCleanupSpec [SHELL32.171] + * PathCleanupSpec [SHELL32.171] * * lpszFile is changed in place. */ @@ -350,7 +382,7 @@ int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW ) TRACE("Cleanup %s\n",debugstr_w(lpszFileW)); if (lpszPathW) - length = wcslen(lpszPathW); + length = strlenW(lpszPathW); while (*p) { @@ -407,132 +439,120 @@ int WINAPI PathCleanupSpec( LPCWSTR lpszPathW, LPWSTR lpszFileW ) } /************************************************************************* - * PathQualifyA [SHELL32] + * PathQualifyA [SHELL32] */ static BOOL PathQualifyA(LPCSTR pszPath) { - FIXME("%s\n",pszPath); - return 0; + FIXME("%s\n",pszPath); + return FALSE; } /************************************************************************* - * PathQualifyW [SHELL32] + * PathQualifyW [SHELL32] */ static BOOL PathQualifyW(LPCWSTR pszPath) { - FIXME("%s\n",debugstr_w(pszPath)); - return 0; + FIXME("%s\n",debugstr_w(pszPath)); + return FALSE; } /************************************************************************* - * PathQualify [SHELL32.49] + * PathQualify [SHELL32.49] */ BOOL WINAPI PathQualifyAW(LPCVOID pszPath) { - if (SHELL_OsIsUnicode()) - return PathQualifyW((LPCWSTR)pszPath); - return PathQualifyA((LPCSTR)pszPath); + if (SHELL_OsIsUnicode()) + return PathQualifyW(pszPath); + return PathQualifyA(pszPath); } -/************************************************************************* - * PathResolveA [SHELL32.51] - */ -static BOOL PathResolveA( - LPSTR lpszPath, - LPCSTR *alpszPaths, - DWORD dwFlags) +static BOOL PathResolveA(LPSTR path, LPCSTR *paths, DWORD flags) { - FIXME("(%s,%p,0x%08x),stub!\n", - lpszPath, *alpszPaths, dwFlags); - return 0; + FIXME("(%s,%p,0x%08x),stub!\n", debugstr_a(path), paths, flags); + return FALSE; } -/************************************************************************* - * PathResolveW [SHELL32] - */ -static BOOL PathResolveW( - LPWSTR lpszPath, - LPCWSTR *alpszPaths, - DWORD dwFlags) +static BOOL PathResolveW(LPWSTR path, LPCWSTR *paths, DWORD flags) { - FIXME("(%s,%p,0x%08x),stub!\n", - debugstr_w(lpszPath), debugstr_w(*alpszPaths), dwFlags); - return 0; + FIXME("(%s,%p,0x%08x),stub!\n", debugstr_w(path), paths, flags); + return FALSE; } /************************************************************************* * PathResolve [SHELL32.51] */ -BOOL WINAPI PathResolveAW( - LPVOID lpszPath, - LPCVOID *alpszPaths, - DWORD dwFlags) +BOOL WINAPI PathResolveAW(LPVOID path, LPCVOID *paths, DWORD flags) { if (SHELL_OsIsUnicode()) - return PathResolveW((LPWSTR)lpszPath, (LPCWSTR *)alpszPaths, dwFlags); - return PathResolveA((LPSTR)lpszPath, (LPCSTR *)alpszPaths, dwFlags); + return PathResolveW(path, (LPCWSTR*)paths, flags); + else + return PathResolveA(path, (LPCSTR*)paths, flags); } /************************************************************************* -* PathProcessCommandA [SHELL32.653] +* PathProcessCommandA */ static LONG PathProcessCommandA ( - LPCSTR lpszPath, - LPSTR lpszBuff, - DWORD dwBuffSize, - DWORD dwFlags) + LPCSTR lpszPath, + LPSTR lpszBuff, + DWORD dwBuffSize, + DWORD dwFlags) { - FIXME("%s %p 0x%04x 0x%04x stub\n", - lpszPath, lpszBuff, dwBuffSize, dwFlags); - if(!lpszPath) return -1; - if(lpszBuff) strcpy(lpszBuff, lpszPath); - return strlen(lpszPath); + FIXME("%s %p 0x%04x 0x%04x stub\n", + lpszPath, lpszBuff, dwBuffSize, dwFlags); + if(!lpszPath) return -1; + if(lpszBuff) strcpy(lpszBuff, lpszPath); + return strlen(lpszPath); } /************************************************************************* -* PathProcessCommandW +* PathProcessCommandW */ static LONG PathProcessCommandW ( - LPCWSTR lpszPath, - LPWSTR lpszBuff, - DWORD dwBuffSize, - DWORD dwFlags) + LPCWSTR lpszPath, + LPWSTR lpszBuff, + DWORD dwBuffSize, + DWORD dwFlags) { - FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n", - debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags); - if(!lpszPath) return -1; - if(lpszBuff) wcscpy(lpszBuff, lpszPath); - return wcslen(lpszPath); + FIXME("(%s, %p, 0x%04x, 0x%04x) stub\n", + debugstr_w(lpszPath), lpszBuff, dwBuffSize, dwFlags); + if(!lpszPath) return -1; + if(lpszBuff) strcpyW(lpszBuff, lpszPath); + return strlenW(lpszPath); } /************************************************************************* -* PathProcessCommand (SHELL32.653) +* PathProcessCommand (SHELL32.653) */ LONG WINAPI PathProcessCommandAW ( - LPCVOID lpszPath, - LPVOID lpszBuff, - DWORD dwBuffSize, - DWORD dwFlags) + LPCVOID lpszPath, + LPVOID lpszBuff, + DWORD dwBuffSize, + DWORD dwFlags) { - if (SHELL_OsIsUnicode()) - return PathProcessCommandW((LPCWSTR)lpszPath, (LPWSTR)lpszBuff, dwBuffSize, dwFlags); - return PathProcessCommandA((LPCSTR)lpszPath, (LPSTR)lpszBuff, dwBuffSize, dwFlags); + if (SHELL_OsIsUnicode()) + return PathProcessCommandW(lpszPath, lpszBuff, dwBuffSize, dwFlags); + return PathProcessCommandA(lpszPath, lpszBuff, dwBuffSize, dwFlags); } /* - ########## special ########## + ########## special ########## */ static const WCHAR szCurrentVersion[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\0'}; static const WCHAR Administrative_ToolsW[] = {'A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'}; static const WCHAR AppDataW[] = {'A','p','p','D','a','t','a','\0'}; +static const WCHAR AppData_LocalLowW[] = {'A','p','p','D','a','t','a','\\','L','o','c','a','l','L','o','w','\0'}; +static const WCHAR Application_DataW[] = {'A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\0'}; static const WCHAR CacheW[] = {'C','a','c','h','e','\0'}; static const WCHAR CD_BurningW[] = {'C','D',' ','B','u','r','n','i','n','g','\0'}; static const WCHAR Common_Administrative_ToolsW[] = {'C','o','m','m','o','n',' ','A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'}; static const WCHAR Common_AppDataW[] = {'C','o','m','m','o','n',' ','A','p','p','D','a','t','a','\0'}; static const WCHAR Common_DesktopW[] = {'C','o','m','m','o','n',' ','D','e','s','k','t','o','p','\0'}; static const WCHAR Common_DocumentsW[] = {'C','o','m','m','o','n',' ','D','o','c','u','m','e','n','t','s','\0'}; +static const WCHAR Common_FavoritesW[] = {'C','o','m','m','o','n',' ','F','a','v','o','r','i','t','e','s','\0'}; static const WCHAR CommonFilesDirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r','\0'}; +static const WCHAR CommonFilesDirX86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')','\0'}; static const WCHAR CommonMusicW[] = {'C','o','m','m','o','n','M','u','s','i','c','\0'}; static const WCHAR CommonPicturesW[] = {'C','o','m','m','o','n','P','i','c','t','u','r','e','s','\0'}; static const WCHAR Common_ProgramsW[] = {'C','o','m','m','o','n',' ','P','r','o','g','r','a','m','s','\0'}; @@ -540,44 +560,73 @@ static const WCHAR Common_StartUpW[] = {'C','o','m','m','o','n',' ','S','t','a', static const WCHAR Common_Start_MenuW[] = {'C','o','m','m','o','n',' ','S','t','a','r','t',' ','M','e','n','u','\0'}; static const WCHAR Common_TemplatesW[] = {'C','o','m','m','o','n',' ','T','e','m','p','l','a','t','e','s','\0'}; static const WCHAR CommonVideoW[] = {'C','o','m','m','o','n','V','i','d','e','o','\0'}; +static const WCHAR ContactsW[] = {'C','o','n','t','a','c','t','s','\0'}; static const WCHAR CookiesW[] = {'C','o','o','k','i','e','s','\0'}; static const WCHAR DesktopW[] = {'D','e','s','k','t','o','p','\0'}; +static const WCHAR DocumentsW[] = {'D','o','c','u','m','e','n','t','s','\0'}; +static const WCHAR DownloadsW[] = {'D','o','w','n','l','o','a','d','s','\0'}; static const WCHAR FavoritesW[] = {'F','a','v','o','r','i','t','e','s','\0'}; static const WCHAR FontsW[] = {'F','o','n','t','s','\0'}; static const WCHAR HistoryW[] = {'H','i','s','t','o','r','y','\0'}; +static const WCHAR LinksW[] = {'L','i','n','k','s','\0'}; static const WCHAR Local_AppDataW[] = {'L','o','c','a','l',' ','A','p','p','D','a','t','a','\0'}; +static const WCHAR Local_Settings_Application_DataW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\0'}; +static const WCHAR Local_Settings_CD_BurningW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','A','p','p','l','i','c','a','t','i','o','n',' ','D','a','t','a','\\','M','i','c','r','o','s','o','f','t','\\','C','D',' ','B','u','r','n','i','n','g','\0'}; +static const WCHAR Local_Settings_HistoryW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','H','i','s','t','o','r','y','\0'}; +static const WCHAR Local_Settings_Temporary_Internet_FilesW[] = {'L','o','c','a','l',' ','S','e','t','t','i','n','g','s','\\','T','e','m','p','o','r','a','r','y',' ','I','n','t','e','r','n','e','t',' ','F','i','l','e','s','\0'}; +static const WCHAR Microsoft_Windows_GameExplorerW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','G','a','m','e','E','x','p','l','o','r','e','r','\0'}; +static const WCHAR Microsoft_Windows_LibrariesW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','L','i','b','r','a','r','i','e','s','\0'}; +static const WCHAR Microsoft_Windows_RingtonesW[] = {'M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','R','i','n','g','t','o','n','e','s','\0'}; +static const WCHAR MusicW[] = {'M','u','s','i','c','\0'}; +static const WCHAR Music_PlaylistsW[] = {'M','u','s','i','c','\\','P','l','a','y','l','i','s','t','s','\0'}; +static const WCHAR Music_Sample_MusicW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','M','u','s','i','c','\0'}; +static const WCHAR Music_Sample_PlaylistsW[] = {'M','u','s','i','c','\\','S','a','m','p','l','e',' ','P','l','a','y','l','i','s','t','s','\0'}; +static const WCHAR My_DocumentsW[] = {'M','y',' ','D','o','c','u','m','e','n','t','s','\0'}; static const WCHAR My_MusicW[] = {'M','y',' ','M','u','s','i','c','\0'}; static const WCHAR My_PicturesW[] = {'M','y',' ','P','i','c','t','u','r','e','s','\0'}; static const WCHAR My_VideoW[] = {'M','y',' ','V','i','d','e','o','\0'}; static const WCHAR NetHoodW[] = {'N','e','t','H','o','o','d','\0'}; +static const WCHAR OEM_LinksW[] = {'O','E','M',' ','L','i','n','k','s','\0'}; static const WCHAR PersonalW[] = {'P','e','r','s','o','n','a','l','\0'}; +static const WCHAR PicturesW[] = {'P','i','c','t','u','r','e','s','\0'}; +static const WCHAR Pictures_Sample_PicturesW[] = {'P','i','c','t','u','r','e','s','\\','S','a','m','p','l','e',' ','P','i','c','t','u','r','e','s','\0'}; +static const WCHAR Pictures_Slide_ShowsW[] = {'P','i','c','t','u','r','e','s','\\','S','l','i','d','e',' ','S','h','o','w','s','\0'}; static const WCHAR PrintHoodW[] = {'P','r','i','n','t','H','o','o','d','\0'}; +static const WCHAR Program_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s','\0'}; +static const WCHAR Program_Files_Common_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s','\\','C','o','m','m','o','n',' ','F','i','l','e','s','\0'}; +static const WCHAR Program_Files_x86W[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\0'}; +static const WCHAR Program_Files_x86_Common_FilesW[] = {'P','r','o','g','r','a','m',' ','F','i','l','e','s',' ','(','x','8','6',')','\\','C','o','m','m','o','n',' ','F','i','l','e','s','\0'}; static const WCHAR ProgramFilesDirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r','\0'}; +static const WCHAR ProgramFilesDirX86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')','\0'}; static const WCHAR ProgramsW[] = {'P','r','o','g','r','a','m','s','\0'}; static const WCHAR RecentW[] = {'R','e','c','e','n','t','\0'}; static const WCHAR ResourcesW[] = {'R','e','s','o','u','r','c','e','s','\0'}; +static const WCHAR Saved_GamesW[] = {'S','a','v','e','d',' ','G','a','m','e','s','\0'}; +static const WCHAR SearchesW[] = {'S','e','a','r','c','h','e','s','\0'}; static const WCHAR SendToW[] = {'S','e','n','d','T','o','\0'}; static const WCHAR StartUpW[] = {'S','t','a','r','t','U','p','\0'}; static const WCHAR Start_MenuW[] = {'S','t','a','r','t',' ','M','e','n','u','\0'}; +static const WCHAR Start_Menu_ProgramsW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\0'}; +static const WCHAR Start_Menu_Admin_ToolsW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\\','A','d','m','i','n','i','s','t','r','a','t','i','v','e',' ','T','o','o','l','s','\0'}; +static const WCHAR Start_Menu_StartupW[] = {'S','t','a','r','t',' ','M','e','n','u','\\','P','r','o','g','r','a','m','s','\\','S','t','a','r','t','U','p','\0'}; static const WCHAR TemplatesW[] = {'T','e','m','p','l','a','t','e','s','\0'}; +static const WCHAR UsersW[] = {'U','s','e','r','s','\0'}; +static const WCHAR UsersPublicW[] = {'U','s','e','r','s','\\','P','u','b','l','i','c','\0'}; +static const WCHAR VideosW[] = {'V','i','d','e','o','s','\0'}; +static const WCHAR Videos_Sample_VideosW[] = {'V','i','d','e','o','s','\\','S','a','m','p','l','e',' ','V','i','d','e','o','s','\0'}; static const WCHAR DefaultW[] = {'.','D','e','f','a','u','l','t','\0'}; static const WCHAR AllUsersProfileW[] = {'%','A','L','L','U','S','E','R','S','P','R','O','F','I','L','E','%','\0'}; static const WCHAR UserProfileW[] = {'%','U','S','E','R','P','R','O','F','I','L','E','%','\0'}; static const WCHAR SystemDriveW[] = {'%','S','y','s','t','e','m','D','r','i','v','e','%','\0'}; -static const WCHAR szSHFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'}; -static const WCHAR szSHUserFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'}; - -#if 0 static const WCHAR ProfileListW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','P','r','o','f','i','l','e','L','i','s','t',0}; static const WCHAR ProfilesDirectoryW[] = {'P','r','o','f','i','l','e','s','D','i','r','e','c','t','o','r','y',0}; static const WCHAR AllUsersProfileValueW[] = {'A','l','l','U','s','e','r','s','P','r','o','f','i','l','e','\0'}; -static const WCHAR szDefaultProfileDirW[] = {'p','r','o','f','i','l','e','s','\0'}; -static const WCHAR AllUsersW[] = {'A','l','l',' ','U','s','e','r','s','\0'}; -#endif - -/* This defaults to L"Documents and Settings" on Windows 2000/XP, but we're - * acting more Windows 9x-like for now. - */ +static const WCHAR szSHFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'}; +static const WCHAR szSHUserFolders[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s','\0'}; +static const WCHAR szDefaultProfileDirW[] = {'u','s','e','r','s',0}; +static const WCHAR szKnownFolderDescriptions[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','F','o','l','d','e','r','D','e','s','c','r','i','p','t','i','o','n','s','\0'}; +static const WCHAR szKnownFolderRedirections[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','E','x','p','l','o','r','e','r','\\','U','s','e','r',' ','S','h','e','l','l',' ','F','o','l','d','e','r','s',0}; +static const WCHAR AllUsersW[] = {'P','u','b','l','i','c',0}; typedef enum _CSIDL_Type { CSIDL_Type_User, @@ -587,10 +636,19 @@ typedef enum _CSIDL_Type { CSIDL_Type_NonExistent, CSIDL_Type_WindowsPath, CSIDL_Type_SystemPath, + CSIDL_Type_SystemX86Path, } CSIDL_Type; +#define CSIDL_CONTACTS 0x0043 +#define CSIDL_DOWNLOADS 0x0047 +#define CSIDL_LINKS 0x004d +#define CSIDL_APPDATA_LOCALLOW 0x004e +#define CSIDL_SAVED_GAMES 0x0062 +#define CSIDL_SEARCHES 0x0063 + typedef struct { + const KNOWNFOLDERID *id; CSIDL_Type type; LPCWSTR szValueName; LPCWSTR szDefaultPath; /* fallback string or resource ID */ @@ -599,322 +657,699 @@ typedef struct static const CSIDL_DATA CSIDL_Data[] = { { /* 0x00 - CSIDL_DESKTOP */ + &FOLDERID_Desktop, CSIDL_Type_User, DesktopW, MAKEINTRESOURCEW(IDS_DESKTOPDIRECTORY) }, { /* 0x01 - CSIDL_INTERNET */ + &FOLDERID_InternetFolder, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x02 - CSIDL_PROGRAMS */ + &FOLDERID_Programs, CSIDL_Type_User, ProgramsW, - MAKEINTRESOURCEW(IDS_PROGRAMS) + Start_Menu_ProgramsW }, { /* 0x03 - CSIDL_CONTROLS (.CPL files) */ + &FOLDERID_ControlPanelFolder, CSIDL_Type_SystemPath, NULL, NULL }, { /* 0x04 - CSIDL_PRINTERS */ + &FOLDERID_PrintersFolder, CSIDL_Type_SystemPath, NULL, NULL }, { /* 0x05 - CSIDL_PERSONAL */ + &FOLDERID_Documents, CSIDL_Type_User, PersonalW, MAKEINTRESOURCEW(IDS_PERSONAL) }, { /* 0x06 - CSIDL_FAVORITES */ + &FOLDERID_Favorites, CSIDL_Type_User, FavoritesW, - MAKEINTRESOURCEW(IDS_FAVORITES) + FavoritesW }, { /* 0x07 - CSIDL_STARTUP */ + &FOLDERID_Startup, CSIDL_Type_User, StartUpW, - MAKEINTRESOURCEW(IDS_STARTUP) + Start_Menu_StartupW }, { /* 0x08 - CSIDL_RECENT */ + &FOLDERID_Recent, CSIDL_Type_User, RecentW, - MAKEINTRESOURCEW(IDS_RECENT) + RecentW }, { /* 0x09 - CSIDL_SENDTO */ + &FOLDERID_SendTo, CSIDL_Type_User, SendToW, - MAKEINTRESOURCEW(IDS_SENDTO) + SendToW }, { /* 0x0a - CSIDL_BITBUCKET - Recycle Bin */ + &FOLDERID_RecycleBinFolder, CSIDL_Type_Disallowed, NULL, NULL, }, { /* 0x0b - CSIDL_STARTMENU */ + &FOLDERID_StartMenu, CSIDL_Type_User, Start_MenuW, - MAKEINTRESOURCEW(IDS_STARTMENU) + Start_MenuW }, { /* 0x0c - CSIDL_MYDOCUMENTS */ + &GUID_NULL, CSIDL_Type_Disallowed, /* matches WinXP--can't get its path */ NULL, NULL }, { /* 0x0d - CSIDL_MYMUSIC */ + &FOLDERID_Music, CSIDL_Type_User, My_MusicW, MAKEINTRESOURCEW(IDS_MYMUSIC) }, { /* 0x0e - CSIDL_MYVIDEO */ + &FOLDERID_Videos, CSIDL_Type_User, My_VideoW, MAKEINTRESOURCEW(IDS_MYVIDEO) }, { /* 0x0f - unassigned */ + &GUID_NULL, CSIDL_Type_Disallowed, NULL, NULL, }, { /* 0x10 - CSIDL_DESKTOPDIRECTORY */ + &FOLDERID_Desktop, CSIDL_Type_User, DesktopW, MAKEINTRESOURCEW(IDS_DESKTOPDIRECTORY) }, { /* 0x11 - CSIDL_DRIVES */ + &FOLDERID_ComputerFolder, CSIDL_Type_Disallowed, NULL, NULL, }, { /* 0x12 - CSIDL_NETWORK */ + &FOLDERID_NetworkFolder, CSIDL_Type_Disallowed, NULL, NULL, }, { /* 0x13 - CSIDL_NETHOOD */ + &FOLDERID_NetHood, CSIDL_Type_User, NetHoodW, - MAKEINTRESOURCEW(IDS_NETHOOD) + NetHoodW }, { /* 0x14 - CSIDL_FONTS */ + &FOLDERID_Fonts, CSIDL_Type_WindowsPath, FontsW, FontsW }, { /* 0x15 - CSIDL_TEMPLATES */ + &FOLDERID_Templates, CSIDL_Type_User, TemplatesW, - MAKEINTRESOURCEW(IDS_TEMPLATES) + TemplatesW }, { /* 0x16 - CSIDL_COMMON_STARTMENU */ + &FOLDERID_CommonStartMenu, CSIDL_Type_AllUsers, Common_Start_MenuW, - MAKEINTRESOURCEW(IDS_STARTMENU) + Start_MenuW }, { /* 0x17 - CSIDL_COMMON_PROGRAMS */ + &FOLDERID_CommonPrograms, CSIDL_Type_AllUsers, Common_ProgramsW, - MAKEINTRESOURCEW(IDS_PROGRAMS) + Start_Menu_ProgramsW }, { /* 0x18 - CSIDL_COMMON_STARTUP */ + &FOLDERID_CommonStartup, CSIDL_Type_AllUsers, Common_StartUpW, - MAKEINTRESOURCEW(IDS_STARTUP) + Start_Menu_StartupW }, { /* 0x19 - CSIDL_COMMON_DESKTOPDIRECTORY */ + &FOLDERID_PublicDesktop, CSIDL_Type_AllUsers, Common_DesktopW, - MAKEINTRESOURCEW(IDS_DESKTOP) + MAKEINTRESOURCEW(IDS_DESKTOPDIRECTORY) }, { /* 0x1a - CSIDL_APPDATA */ + &FOLDERID_RoamingAppData, CSIDL_Type_User, AppDataW, - MAKEINTRESOURCEW(IDS_APPDATA) + Application_DataW }, { /* 0x1b - CSIDL_PRINTHOOD */ + &FOLDERID_PrintHood, CSIDL_Type_User, PrintHoodW, - MAKEINTRESOURCEW(IDS_PRINTHOOD) + PrintHoodW }, { /* 0x1c - CSIDL_LOCAL_APPDATA */ + &FOLDERID_LocalAppData, CSIDL_Type_User, Local_AppDataW, - MAKEINTRESOURCEW(IDS_LOCAL_APPDATA) + Local_Settings_Application_DataW }, { /* 0x1d - CSIDL_ALTSTARTUP */ + &GUID_NULL, CSIDL_Type_NonExistent, NULL, NULL }, { /* 0x1e - CSIDL_COMMON_ALTSTARTUP */ + &GUID_NULL, CSIDL_Type_NonExistent, NULL, NULL }, { /* 0x1f - CSIDL_COMMON_FAVORITES */ + &FOLDERID_Favorites, CSIDL_Type_AllUsers, - FavoritesW, - MAKEINTRESOURCEW(IDS_FAVORITES) + Common_FavoritesW, + FavoritesW }, { /* 0x20 - CSIDL_INTERNET_CACHE */ + &FOLDERID_InternetCache, CSIDL_Type_User, CacheW, - MAKEINTRESOURCEW(IDS_INTERNET_CACHE) + Local_Settings_Temporary_Internet_FilesW }, { /* 0x21 - CSIDL_COOKIES */ + &FOLDERID_Cookies, CSIDL_Type_User, CookiesW, - MAKEINTRESOURCEW(IDS_COOKIES) + CookiesW }, { /* 0x22 - CSIDL_HISTORY */ + &FOLDERID_History, CSIDL_Type_User, HistoryW, - MAKEINTRESOURCEW(IDS_HISTORY) + Local_Settings_HistoryW }, { /* 0x23 - CSIDL_COMMON_APPDATA */ + &FOLDERID_ProgramData, CSIDL_Type_AllUsers, Common_AppDataW, - MAKEINTRESOURCEW(IDS_APPDATA) + Application_DataW }, { /* 0x24 - CSIDL_WINDOWS */ + &FOLDERID_Windows, CSIDL_Type_WindowsPath, NULL, NULL }, { /* 0x25 - CSIDL_SYSTEM */ + &FOLDERID_System, CSIDL_Type_SystemPath, NULL, NULL }, { /* 0x26 - CSIDL_PROGRAM_FILES */ + &FOLDERID_ProgramFiles, CSIDL_Type_CurrVer, ProgramFilesDirW, - MAKEINTRESOURCEW(IDS_PROGRAM_FILES) + Program_FilesW }, { /* 0x27 - CSIDL_MYPICTURES */ + &FOLDERID_Pictures, CSIDL_Type_User, My_PicturesW, MAKEINTRESOURCEW(IDS_MYPICTURES) }, { /* 0x28 - CSIDL_PROFILE */ + &FOLDERID_Profile, CSIDL_Type_User, NULL, NULL }, { /* 0x29 - CSIDL_SYSTEMX86 */ - CSIDL_Type_NonExistent, + &FOLDERID_SystemX86, + CSIDL_Type_SystemX86Path, NULL, NULL }, { /* 0x2a - CSIDL_PROGRAM_FILESX86 */ - CSIDL_Type_NonExistent, - NULL, - NULL + &FOLDERID_ProgramFilesX86, + CSIDL_Type_CurrVer, + ProgramFilesDirX86W, + Program_Files_x86W }, { /* 0x2b - CSIDL_PROGRAM_FILES_COMMON */ + &FOLDERID_ProgramFilesCommon, CSIDL_Type_CurrVer, CommonFilesDirW, - MAKEINTRESOURCEW(IDS_PROGRAM_FILES_COMMON) + Program_Files_Common_FilesW }, { /* 0x2c - CSIDL_PROGRAM_FILES_COMMONX86 */ - CSIDL_Type_NonExistent, - NULL, - NULL + &FOLDERID_ProgramFilesCommonX86, + CSIDL_Type_CurrVer, + CommonFilesDirX86W, + Program_Files_x86_Common_FilesW }, { /* 0x2d - CSIDL_COMMON_TEMPLATES */ + &FOLDERID_CommonTemplates, CSIDL_Type_AllUsers, Common_TemplatesW, - MAKEINTRESOURCEW(IDS_TEMPLATES) + TemplatesW }, { /* 0x2e - CSIDL_COMMON_DOCUMENTS */ + &FOLDERID_PublicDocuments, CSIDL_Type_AllUsers, Common_DocumentsW, - MAKEINTRESOURCEW(IDS_COMMON_DOCUMENTS) + DocumentsW }, { /* 0x2f - CSIDL_COMMON_ADMINTOOLS */ + &FOLDERID_CommonAdminTools, CSIDL_Type_AllUsers, Common_Administrative_ToolsW, - MAKEINTRESOURCEW(IDS_ADMINTOOLS) + Start_Menu_Admin_ToolsW }, { /* 0x30 - CSIDL_ADMINTOOLS */ + &FOLDERID_AdminTools, CSIDL_Type_User, Administrative_ToolsW, - MAKEINTRESOURCEW(IDS_ADMINTOOLS) + Start_Menu_Admin_ToolsW }, { /* 0x31 - CSIDL_CONNECTIONS */ + &FOLDERID_ConnectionsFolder, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x32 - unassigned */ + &GUID_NULL, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x33 - unassigned */ + &GUID_NULL, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x34 - unassigned */ + &GUID_NULL, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x35 - CSIDL_COMMON_MUSIC */ + &FOLDERID_PublicMusic, CSIDL_Type_AllUsers, CommonMusicW, - MAKEINTRESOURCEW(IDS_COMMON_MUSIC) + MusicW }, { /* 0x36 - CSIDL_COMMON_PICTURES */ + &FOLDERID_PublicPictures, CSIDL_Type_AllUsers, CommonPicturesW, - MAKEINTRESOURCEW(IDS_COMMON_PICTURES) + PicturesW }, { /* 0x37 - CSIDL_COMMON_VIDEO */ + &FOLDERID_PublicVideos, CSIDL_Type_AllUsers, CommonVideoW, - MAKEINTRESOURCEW(IDS_COMMON_VIDEO) + VideosW }, { /* 0x38 - CSIDL_RESOURCES */ + &FOLDERID_ResourceDir, CSIDL_Type_WindowsPath, NULL, ResourcesW }, { /* 0x39 - CSIDL_RESOURCES_LOCALIZED */ + &FOLDERID_LocalizedResourcesDir, CSIDL_Type_NonExistent, NULL, NULL }, { /* 0x3a - CSIDL_COMMON_OEM_LINKS */ - CSIDL_Type_NonExistent, + &FOLDERID_CommonOEMLinks, + CSIDL_Type_AllUsers, NULL, - NULL + OEM_LinksW }, { /* 0x3b - CSIDL_CDBURN_AREA */ + &FOLDERID_CDBurning, CSIDL_Type_User, CD_BurningW, - MAKEINTRESOURCEW(IDS_CDBURN_AREA) + Local_Settings_CD_BurningW }, { /* 0x3c unassigned */ + &GUID_NULL, CSIDL_Type_Disallowed, NULL, NULL }, { /* 0x3d - CSIDL_COMPUTERSNEARME */ + &GUID_NULL, CSIDL_Type_Disallowed, /* FIXME */ NULL, NULL }, { /* 0x3e - CSIDL_PROFILES */ + &GUID_NULL, CSIDL_Type_Disallowed, /* oddly, this matches WinXP */ NULL, NULL + }, + { /* 0x3f */ + &FOLDERID_AddNewPrograms, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x40 */ + &FOLDERID_AppUpdates, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x41 */ + &FOLDERID_ChangeRemovePrograms, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x42 */ + &FOLDERID_ConflictFolder, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x43 - CSIDL_CONTACTS */ + &FOLDERID_Contacts, + CSIDL_Type_User, + NULL, + ContactsW + }, + { /* 0x44 */ + &FOLDERID_DeviceMetadataStore, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x45 */ + &GUID_NULL, + CSIDL_Type_User, + NULL, + DocumentsW + }, + { /* 0x46 */ + &FOLDERID_DocumentsLibrary, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x47 - CSIDL_DOWNLOADS */ + &FOLDERID_Downloads, + CSIDL_Type_User, + NULL, + DownloadsW + }, + { /* 0x48 */ + &FOLDERID_Games, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x49 */ + &FOLDERID_GameTasks, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x4a */ + &FOLDERID_HomeGroup, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x4b */ + &FOLDERID_ImplicitAppShortcuts, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x4c */ + &FOLDERID_Libraries, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x4d - CSIDL_LINKS */ + &FOLDERID_Links, + CSIDL_Type_User, + NULL, + LinksW + }, + { /* 0x4e - CSIDL_APPDATA_LOCALLOW */ + &FOLDERID_LocalAppDataLow, + CSIDL_Type_User, + NULL, + AppData_LocalLowW + }, + { /* 0x4f */ + &FOLDERID_MusicLibrary, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x50 */ + &FOLDERID_OriginalImages, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x51 */ + &FOLDERID_PhotoAlbums, + CSIDL_Type_User, + NULL, + Pictures_Slide_ShowsW + }, + { /* 0x52 */ + &FOLDERID_PicturesLibrary, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x53 */ + &FOLDERID_Playlists, + CSIDL_Type_User, + NULL, + Music_PlaylistsW + }, + { /* 0x54 */ + &FOLDERID_ProgramFilesX64, + CSIDL_Type_NonExistent, + NULL, + NULL + }, + { /* 0x55 */ + &FOLDERID_ProgramFilesCommonX64, + CSIDL_Type_NonExistent, + NULL, + NULL + }, + { /* 0x56 */ + &FOLDERID_Public, + CSIDL_Type_CurrVer, /* FIXME */ + NULL, + UsersPublicW + }, + { /* 0x57 */ + &FOLDERID_PublicDownloads, + CSIDL_Type_AllUsers, + NULL, + DownloadsW + }, + { /* 0x58 */ + &FOLDERID_PublicGameTasks, + CSIDL_Type_AllUsers, + NULL, + Microsoft_Windows_GameExplorerW + }, + { /* 0x59 */ + &FOLDERID_PublicLibraries, + CSIDL_Type_AllUsers, + NULL, + Microsoft_Windows_LibrariesW + }, + { /* 0x5a */ + &FOLDERID_PublicRingtones, + CSIDL_Type_AllUsers, + NULL, + Microsoft_Windows_RingtonesW + }, + { /* 0x5b */ + &FOLDERID_QuickLaunch, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x5c */ + &FOLDERID_RecordedTVLibrary, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x5d */ + &FOLDERID_Ringtones, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x5e */ + &FOLDERID_SampleMusic, + CSIDL_Type_AllUsers, + NULL, + Music_Sample_MusicW + }, + { /* 0x5f */ + &FOLDERID_SamplePictures, + CSIDL_Type_AllUsers, + NULL, + Pictures_Sample_PicturesW + }, + { /* 0x60 */ + &FOLDERID_SamplePlaylists, + CSIDL_Type_AllUsers, + NULL, + Music_Sample_PlaylistsW + }, + { /* 0x61 */ + &FOLDERID_SampleVideos, + CSIDL_Type_AllUsers, + NULL, + Videos_Sample_VideosW + }, + { /* 0x62 - CSIDL_SAVED_GAMES */ + &FOLDERID_SavedGames, + CSIDL_Type_User, + NULL, + Saved_GamesW + }, + { /* 0x63 - CSIDL_SEARCHES */ + &FOLDERID_SavedSearches, + CSIDL_Type_User, + NULL, + SearchesW + }, + { /* 0x64 */ + &FOLDERID_SEARCH_CSC, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x65 */ + &FOLDERID_SEARCH_MAPI, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x66 */ + &FOLDERID_SearchHome, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x67 */ + &FOLDERID_SidebarDefaultParts, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x68 */ + &FOLDERID_SidebarParts, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x69 */ + &FOLDERID_SyncManagerFolder, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x6a */ + &FOLDERID_SyncResultsFolder, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x6b */ + &FOLDERID_SyncSetupFolder, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x6c */ + &FOLDERID_UserPinned, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x6d */ + &FOLDERID_UserProfiles, + CSIDL_Type_CurrVer, + UsersW, + UsersW + }, + { /* 0x6e */ + &FOLDERID_UserProgramFiles, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x6f */ + &FOLDERID_UserProgramFilesCommon, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL + }, + { /* 0x70 */ + &FOLDERID_UsersFiles, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x71 */ + &FOLDERID_UsersLibraries, + CSIDL_Type_Disallowed, + NULL, + NULL + }, + { /* 0x72 */ + &FOLDERID_VideosLibrary, + CSIDL_Type_Disallowed, /* FIXME */ + NULL, + NULL } }; +static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest); + /* Gets the value named value from the registry key * rootKey\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders * (or from rootKey\userPrefix\... if userPrefix is not NULL) into path, which @@ -930,7 +1365,7 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, HRESULT hr; WCHAR shellFolderPath[MAX_PATH], userShellFolderPath[MAX_PATH]; LPCWSTR pShellFolderPath, pUserShellFolderPath; - DWORD dwDisp, dwType, dwPathLen; + DWORD dwType, dwPathLen = MAX_PATH; HKEY userShellFolderKey, shellFolderKey; TRACE("%p,%s,%s,%p\n",rootKey, debugstr_w(userPrefix), debugstr_w(value), @@ -938,13 +1373,13 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, if (userPrefix) { - wcscpy(shellFolderPath, userPrefix); + strcpyW(shellFolderPath, userPrefix); PathAddBackslashW(shellFolderPath); - wcscat(shellFolderPath, szSHFolders); + strcatW(shellFolderPath, szSHFolders); pShellFolderPath = shellFolderPath; - wcscpy(userShellFolderPath, userPrefix); + strcpyW(userShellFolderPath, userPrefix); PathAddBackslashW(userShellFolderPath); - wcscat(userShellFolderPath, szSHUserFolders); + strcatW(userShellFolderPath, szSHUserFolders); pUserShellFolderPath = userShellFolderPath; } else @@ -953,14 +1388,12 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, pShellFolderPath = szSHFolders; } - if (RegCreateKeyExW(rootKey, pShellFolderPath, 0, NULL, 0, KEY_SET_VALUE, - NULL, &shellFolderKey, &dwDisp)) + if (RegCreateKeyW(rootKey, pShellFolderPath, &shellFolderKey)) { TRACE("Failed to create %s\n", debugstr_w(pShellFolderPath)); return E_FAIL; } - if (RegCreateKeyExW(rootKey, pUserShellFolderPath, 0, NULL, 0, - KEY_QUERY_VALUE, NULL, &userShellFolderKey, &dwDisp)) + if (RegCreateKeyW(rootKey, pUserShellFolderPath, &userShellFolderKey)) { TRACE("Failed to create %s\n", debugstr_w(pUserShellFolderPath)); @@ -968,25 +1401,21 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, return E_FAIL; } - dwPathLen = MAX_PATH * sizeof(WCHAR); - if (!RegQueryValueExW(userShellFolderKey, value, NULL, &dwType, (LPBYTE)path, &dwPathLen) && (dwType == REG_EXPAND_SZ || dwType == REG_SZ)) { LONG ret; - dwPathLen /= sizeof(WCHAR); - - path[dwPathLen] = '\0'; + path[dwPathLen / sizeof(WCHAR)] = '\0'; if (dwType == REG_EXPAND_SZ && path[0] == '%') { WCHAR szTemp[MAX_PATH]; - dwPathLen = ExpandEnvironmentStringsW(path, szTemp, MAX_PATH); - lstrcpynW(path, szTemp, dwPathLen); + _SHExpandEnvironmentStrings(path, szTemp); + lstrcpynW(path, szTemp, MAX_PATH); } - - ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path, dwPathLen * sizeof(WCHAR)); + ret = RegSetValueExW(shellFolderKey, value, 0, REG_SZ, (LPBYTE)path, + (strlenW(path) + 1) * sizeof(WCHAR)); if (ret != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(ret); else @@ -994,7 +1423,6 @@ static HRESULT _SHGetUserShellFolderPath(HKEY rootKey, LPCWSTR userPrefix, } else hr = E_FAIL; - RegCloseKey(shellFolderKey); RegCloseKey(userShellFolderKey); TRACE("returning 0x%08x\n", hr); @@ -1030,7 +1458,26 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) if (!pszPath) return E_INVALIDARG; + if (!is_win64) + { + BOOL is_wow64; + switch (folder) + { + case CSIDL_PROGRAM_FILES: + case CSIDL_PROGRAM_FILESX86: + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + folder = is_wow64 ? CSIDL_PROGRAM_FILESX86 : CSIDL_PROGRAM_FILES; + break; + case CSIDL_PROGRAM_FILES_COMMON: + case CSIDL_PROGRAM_FILES_COMMONX86: + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + folder = is_wow64 ? CSIDL_PROGRAM_FILES_COMMONX86 : CSIDL_PROGRAM_FILES_COMMON; + break; + } + } + +#ifdef __REACTOS__ /* FIXME: Inspect */ if (RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hKey) == ERROR_SUCCESS) { /* FIXME assume MAX_PATH size */ @@ -1042,6 +1489,7 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) } RegCloseKey(hKey); } +#endif if (CSIDL_Data[folder].szDefaultPath && IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath)) @@ -1069,13 +1517,13 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) switch (CSIDL_Data[folder].type) { case CSIDL_Type_User: - wcscpy(pszPath, UserProfileW); + strcpyW(pszPath, UserProfileW); break; case CSIDL_Type_AllUsers: - wcscpy(pszPath, AllUsersProfileW); + strcpyW(pszPath, AllUsersProfileW); break; case CSIDL_Type_CurrVer: - wcscpy(pszPath, SystemDriveW); + strcpyW(pszPath, SystemDriveW); break; default: ; /* no corresponding env. var, do nothing */ @@ -1083,7 +1531,7 @@ static HRESULT _SHGetDefaultValue(BYTE folder, LPWSTR pszPath) if (pDefaultPath) { PathAddBackslashW(pszPath); - wcscat(pszPath, pDefaultPath); + strcatW(pszPath, pDefaultPath); } } TRACE("returning 0x%08x\n", hr); @@ -1115,10 +1563,8 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, else { HKEY hKey; - DWORD dwDisp; - if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szCurrentVersion, 0, - NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, &dwDisp)) + if (RegCreateKeyW(HKEY_LOCAL_MACHINE, szCurrentVersion, &hKey)) hr = E_FAIL; else { @@ -1130,8 +1576,22 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, { hr = _SHGetDefaultValue(folder, pszPath); dwType = REG_EXPAND_SZ; - RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType, - (LPBYTE)pszPath, (wcslen(pszPath)+1)*sizeof(WCHAR)); + switch (folder) + { + case CSIDL_PROGRAM_FILESX86: + case CSIDL_PROGRAM_FILES_COMMONX86: + /* these two should never be set on 32-bit setups */ + if (!is_win64) + { + BOOL is_wow64; + IsWow64Process( GetCurrentProcess(), &is_wow64 ); + if (!is_wow64) break; + } + /* fall through */ + default: + RegSetValueExW(hKey, CSIDL_Data[folder].szValueName, 0, dwType, + (LPBYTE)pszPath, (strlenW(pszPath)+1)*sizeof(WCHAR)); + } } else { @@ -1145,6 +1605,39 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, return hr; } +static LPWSTR _GetUserSidStringFromToken(HANDLE Token) +{ + char InfoBuffer[64]; + PTOKEN_USER UserInfo; + DWORD InfoSize; + LPWSTR SidStr; + + UserInfo = (PTOKEN_USER) InfoBuffer; + if (! GetTokenInformation(Token, TokenUser, InfoBuffer, sizeof(InfoBuffer), + &InfoSize)) + { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return NULL; + UserInfo = HeapAlloc(GetProcessHeap(), 0, InfoSize); + if (UserInfo == NULL) + return NULL; + if (! GetTokenInformation(Token, TokenUser, UserInfo, InfoSize, + &InfoSize)) + { + HeapFree(GetProcessHeap(), 0, UserInfo); + return NULL; + } + } + + if (! ConvertSidToStringSidW(UserInfo->User.Sid, &SidStr)) + SidStr = NULL; + + if (UserInfo != (PTOKEN_USER) InfoBuffer) + HeapFree(GetProcessHeap(), 0, UserInfo); + + return SidStr; +} + /* Gets the user's path (unexpanded) for the CSIDL with index folder: * If SHGFP_TYPE_DEFAULT is set, calls _SHGetDefaultValue for it. Otherwise * calls _SHGetUserShellFolderPath for it. Where it looks depends on hToken: @@ -1156,16 +1649,16 @@ static HRESULT _SHGetCurrentVersionPath(DWORD dwFlags, BYTE folder, static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, LPWSTR pszPath) { + const WCHAR *szValueName; + WCHAR buffer[40]; HRESULT hr; TRACE("%p,0x%08x,0x%02x,%p\n", hToken, dwFlags, folder, pszPath); if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) return E_INVALIDARG; - if (CSIDL_Data[folder].type != CSIDL_Type_User) return E_INVALIDARG; - if (!pszPath) return E_INVALIDARG; @@ -1173,69 +1666,51 @@ static HRESULT _SHGetUserProfilePath(HANDLE hToken, DWORD dwFlags, BYTE folder, { if (hToken != NULL && hToken != (HANDLE)-1) { - FIXME("unsupported for user other than current or default\n"); - return E_FAIL; + FIXME("unsupported for user other than current or default\n"); + return E_FAIL; } hr = _SHGetDefaultValue(folder, pszPath); } else { - LPWSTR userPrefix; + LPCWSTR userPrefix = NULL; HKEY hRootKey; if (hToken == (HANDLE)-1) { - /* Get the folder of the default user */ hRootKey = HKEY_USERS; - userPrefix = (LPWSTR)DefaultW; + userPrefix = DefaultW; } - else if(!hToken) - { - /* Get the folder of the current user */ + else if (hToken == NULL) hRootKey = HKEY_CURRENT_USER; - userPrefix = NULL; - } else { - /* Get the folder of the specified user */ - DWORD InfoLength; - PTOKEN_USER UserInfo; - hRootKey = HKEY_USERS; - - GetTokenInformation(hToken, TokenUser, NULL, 0, &InfoLength); - UserInfo = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), 0, InfoLength); - - if(!GetTokenInformation(hToken, TokenUser, UserInfo, InfoLength, &InfoLength)) + userPrefix = _GetUserSidStringFromToken(hToken); + if (userPrefix == NULL) { - WARN("GetTokenInformation failed for %x!\n", hToken); - HeapFree(GetProcessHeap(), 0, UserInfo); - return E_FAIL; + hr = E_FAIL; + goto error; } - - if(!ConvertSidToStringSidW(UserInfo->User.Sid, &userPrefix)) - { - WARN("ConvertSidToStringSidW failed for %x!\n", hToken); - HeapFree(GetProcessHeap(), 0, UserInfo); - return E_FAIL; - } - - HeapFree(GetProcessHeap(), 0, UserInfo); } - hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, CSIDL_Data[folder].szValueName, pszPath); - - /* Free the memory allocated by ConvertSidToStringSidW */ - if(hToken && hToken != (HANDLE)-1) - LocalFree(userPrefix); + /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */ + szValueName = CSIDL_Data[folder].szValueName; + if (!szValueName) + { + StringFromGUID2( CSIDL_Data[folder].id, buffer, 39 ); + szValueName = &buffer[0]; + } + hr = _SHGetUserShellFolderPath(hRootKey, userPrefix, szValueName, pszPath); if (FAILED(hr) && hRootKey != HKEY_LOCAL_MACHINE) - hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, CSIDL_Data[folder].szValueName, pszPath); - + hr = _SHGetUserShellFolderPath(HKEY_LOCAL_MACHINE, NULL, szValueName, pszPath); if (FAILED(hr)) hr = _SHGetDefaultValue(folder, pszPath); + if (userPrefix != NULL && userPrefix != DefaultW) + LocalFree((HLOCAL) userPrefix); } - +error: TRACE("returning 0x%08x (output path is %s)\n", hr, debugstr_w(pszPath)); return hr; } @@ -1272,10 +1747,169 @@ static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, return hr; } +static HRESULT _SHOpenProfilesKey(PHKEY pKey) +{ + LONG lRet; + DWORD disp; + + lRet = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ProfileListW, 0, NULL, 0, + KEY_ALL_ACCESS, NULL, pKey, &disp); + return HRESULT_FROM_WIN32(lRet); +} + +/* Reads the value named szValueName from the key profilesKey (assumed to be + * opened by _SHOpenProfilesKey) into szValue, which is assumed to be MAX_PATH + * WCHARs in length. If it doesn't exist, returns szDefault (and saves + * szDefault to the registry). + */ +static HRESULT _SHGetProfilesValue(HKEY profilesKey, LPCWSTR szValueName, + LPWSTR szValue, LPCWSTR szDefault) +{ + HRESULT hr; + DWORD type, dwPathLen = MAX_PATH * sizeof(WCHAR); + LONG lRet; + + TRACE("%p,%s,%p,%s\n", profilesKey, debugstr_w(szValueName), szValue, + debugstr_w(szDefault)); + lRet = RegQueryValueExW(profilesKey, szValueName, NULL, &type, + (LPBYTE)szValue, &dwPathLen); + if (!lRet && (type == REG_SZ || type == REG_EXPAND_SZ) && dwPathLen + && *szValue) + { + dwPathLen /= sizeof(WCHAR); + szValue[dwPathLen] = '\0'; + hr = S_OK; + } + else + { + /* Missing or invalid value, set a default */ + lstrcpynW(szValue, szDefault, MAX_PATH); + TRACE("Setting missing value %s to %s\n", debugstr_w(szValueName), + debugstr_w(szValue)); + lRet = RegSetValueExW(profilesKey, szValueName, 0, REG_EXPAND_SZ, + (LPBYTE)szValue, + (strlenW(szValue) + 1) * sizeof(WCHAR)); + if (lRet) + hr = HRESULT_FROM_WIN32(lRet); + else + hr = S_OK; + } + TRACE("returning 0x%08x (output value is %s)\n", hr, debugstr_w(szValue)); + return hr; +} + +/* Attempts to expand environment variables from szSrc into szDest, which is + * assumed to be MAX_PATH characters in length. Before referring to the + * environment, handles a few variables directly, because the environment + * variables may not be set when this is called (as during Wine's installation + * when default values are being written to the registry). + * The directly handled environment variables, and their source, are: + * - ALLUSERSPROFILE, USERPROFILE: reads from the registry + * - SystemDrive: uses GetSystemDirectoryW and uses the drive portion of its + * path + * If one of the directly handled environment variables is expanded, only + * expands a single variable, and only in the beginning of szSrc. + */ +static HRESULT _SHExpandEnvironmentStrings(LPCWSTR szSrc, LPWSTR szDest) +{ + HRESULT hr; + WCHAR szTemp[MAX_PATH], szProfilesPrefix[MAX_PATH] = { 0 }; + HKEY key = NULL; + + TRACE("%s, %p\n", debugstr_w(szSrc), szDest); + + if (!szSrc || !szDest) return E_INVALIDARG; + + /* short-circuit if there's nothing to expand */ + if (szSrc[0] != '%') + { + strcpyW(szDest, szSrc); + hr = S_OK; + goto end; + } + /* Get the profile prefix, we'll probably be needing it */ + hr = _SHOpenProfilesKey(&key); + if (SUCCEEDED(hr)) + { + WCHAR def_val[MAX_PATH]; + + /* get the system drive */ + GetSystemDirectoryW(def_val, MAX_PATH); + if (def_val[1] == ':') strcpyW( def_val + 3, szDefaultProfileDirW ); + else FIXME("non-drive system paths unsupported\n"); + + hr = _SHGetProfilesValue(key, ProfilesDirectoryW, szProfilesPrefix, def_val ); + } + + *szDest = 0; + strcpyW(szTemp, szSrc); + while (SUCCEEDED(hr) && szTemp[0] == '%') + { + if (!strncmpiW(szTemp, AllUsersProfileW, strlenW(AllUsersProfileW))) + { + WCHAR szAllUsers[MAX_PATH]; + + strcpyW(szDest, szProfilesPrefix); + hr = _SHGetProfilesValue(key, AllUsersProfileValueW, + szAllUsers, AllUsersW); + PathAppendW(szDest, szAllUsers); + PathAppendW(szDest, szTemp + strlenW(AllUsersProfileW)); + } + else if (!strncmpiW(szTemp, UserProfileW, strlenW(UserProfileW))) + { + WCHAR userName[MAX_PATH]; + DWORD userLen = MAX_PATH; + + strcpyW(szDest, szProfilesPrefix); + GetUserNameW(userName, &userLen); + PathAppendW(szDest, userName); + PathAppendW(szDest, szTemp + strlenW(UserProfileW)); + } + else if (!strncmpiW(szTemp, SystemDriveW, strlenW(SystemDriveW))) + { + GetSystemDirectoryW(szDest, MAX_PATH); + if (szDest[1] != ':') + { + FIXME("non-drive system paths unsupported\n"); + hr = E_FAIL; + } + else + { + strcpyW(szDest + 3, szTemp + strlenW(SystemDriveW) + 1); + hr = S_OK; + } + } + else + { + DWORD ret = ExpandEnvironmentStringsW(szSrc, szDest, MAX_PATH); + + if (ret > MAX_PATH) + hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); + else if (ret == 0) + hr = HRESULT_FROM_WIN32(GetLastError()); + else + hr = S_OK; + } + if (SUCCEEDED(hr) && szDest[0] == '%') + strcpyW(szTemp, szDest); + else + { + /* terminate loop */ + szTemp[0] = '\0'; + } + } +end: + if (key) + RegCloseKey(key); + TRACE("returning 0x%08x (input was %s, output is %s)\n", hr, + debugstr_w(szSrc), debugstr_w(szDest)); + return hr; +} + /************************************************************************* - * SHGetFolderPathW [SHELL32.@] + * SHGetFolderPathW [SHELL32.@] * - * Convert nFolder to path. + * Convert nFolder to path. * * RETURNS * Success: S_OK @@ -1293,11 +1927,11 @@ static HRESULT _SHGetAllUsersProfilePath(DWORD dwFlags, BYTE folder, * Furthermore, the HKCU paths take precedence over the HKLM paths. */ HRESULT WINAPI SHGetFolderPathW( - HWND hwndOwner, /* [I] owner window */ - int nFolder, /* [I] CSIDL identifying the folder */ - HANDLE hToken, /* [I] access token */ - DWORD dwFlags, /* [I] which path to return */ - LPWSTR pszPath) /* [O] converted path */ + HWND hwndOwner, /* [I] owner window */ + int nFolder, /* [I] CSIDL identifying the folder */ + HANDLE hToken, /* [I] access token */ + DWORD dwFlags, /* [I] which path to return */ + LPWSTR pszPath) /* [O] converted path */ { HRESULT hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, NULL, pszPath); if(HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr) @@ -1306,12 +1940,12 @@ HRESULT WINAPI SHGetFolderPathW( } HRESULT WINAPI SHGetFolderPathAndSubDirA( - HWND hwndOwner, /* [I] owner window */ - int nFolder, /* [I] CSIDL identifying the folder */ - HANDLE hToken, /* [I] access token */ - DWORD dwFlags, /* [I] which path to return */ - LPCSTR pszSubPath, /* [I] sub directory of the specified folder */ - LPSTR pszPath) /* [O] converted path */ + HWND hwndOwner, /* [I] owner window */ + int nFolder, /* [I] CSIDL identifying the folder */ + HANDLE hToken, /* [I] access token */ + DWORD dwFlags, /* [I] which path to return */ + LPCSTR pszSubPath, /* [I] sub directory of the specified folder */ + LPSTR pszPath) /* [O] converted path */ { int length; HRESULT hr = S_OK; @@ -1320,7 +1954,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirA( TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW)); if(pszPath) { - pszPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); + pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); if(!pszPathW) { hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; @@ -1334,7 +1968,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirA( */ if (pszSubPath && pszSubPath[0]) { length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0); - pszSubPathW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR)); + pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR)); if(!pszSubPathW) { hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); goto cleanup; @@ -1353,20 +1987,23 @@ cleanup: return hr; } +/************************************************************************* + * SHGetFolderPathAndSubDirW [SHELL32.@] + */ HRESULT WINAPI SHGetFolderPathAndSubDirW( - HWND hwndOwner, /* [I] owner window */ - int nFolder, /* [I] CSIDL identifying the folder */ - HANDLE hToken, /* [I] access token */ - DWORD dwFlags, /* [I] which path to return */ - LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */ - LPWSTR pszPath) /* [O] converted path */ + HWND hwndOwner, /* [I] owner window */ + int nFolder, /* [I] CSIDL identifying the folder */ + HANDLE hToken, /* [I] access token */ + DWORD dwFlags, /* [I] which path to return */ + LPCWSTR pszSubPath,/* [I] sub directory of the specified folder */ + LPWSTR pszPath) /* [O] converted path */ { HRESULT hr; WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH]; - DWORD folder = nFolder & CSIDL_FOLDER_MASK; //FIXME + DWORD folder = nFolder & CSIDL_FOLDER_MASK; CSIDL_Type type; int ret; - + TRACE("%p,%p,nFolder=0x%04x,%s\n", hwndOwner,pszPath,nFolder,debugstr_w(pszSubPath)); /* Windows always NULL-terminates the resulting path regardless of success @@ -1396,7 +2033,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( *CSIDL_Data[folder].szDefaultPath) { PathAddBackslashW(szTemp); - wcscat(szTemp, CSIDL_Data[folder].szDefaultPath); + strcatW(szTemp, CSIDL_Data[folder].szDefaultPath); } hr = S_OK; break; @@ -1407,7 +2044,18 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( *CSIDL_Data[folder].szDefaultPath) { PathAddBackslashW(szTemp); - wcscat(szTemp, CSIDL_Data[folder].szDefaultPath); + strcatW(szTemp, CSIDL_Data[folder].szDefaultPath); + } + hr = S_OK; + break; + case CSIDL_Type_SystemX86Path: + if (!GetSystemWow64DirectoryW(szTemp, MAX_PATH)) GetSystemDirectoryW(szTemp, MAX_PATH); + if (CSIDL_Data[folder].szDefaultPath && + !IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) && + *CSIDL_Data[folder].szDefaultPath) + { + PathAddBackslashW(szTemp); + strcatW(szTemp, CSIDL_Data[folder].szDefaultPath); } hr = S_OK; break; @@ -1428,27 +2076,16 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( /* Expand environment strings if necessary */ if (*szTemp == '%') - { - DWORD ExpandRet = ExpandEnvironmentStringsW(szTemp, szBuildPath, MAX_PATH); - - if (ExpandRet > MAX_PATH) - hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); - else if (ExpandRet == 0) - hr = HRESULT_FROM_WIN32(GetLastError()); - else - hr = S_OK; - } + hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath); else - { - wcscpy(szBuildPath, szTemp); - } + strcpyW(szBuildPath, szTemp); if (FAILED(hr)) goto end; if(pszSubPath) { - /* make sure the new path does not exceed th bufferlength - * rememebr to backslash and the termination */ - if(MAX_PATH < (wcslen(szBuildPath) + wcslen(pszSubPath) + 2)) { + /* make sure the new path does not exceed the buffer length + * and remember to backslash and terminate it */ + if(MAX_PATH < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) { hr = HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE); goto end; } @@ -1457,7 +2094,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( } /* Copy the path if it's available before we might return */ if (SUCCEEDED(hr) && pszPath) - wcscpy(pszPath, szBuildPath); + strcpyW(pszPath, szBuildPath); /* if we don't care about existing directories we are ready */ if(nFolder & CSIDL_FLAG_DONT_VERIFY) goto end; @@ -1477,7 +2114,7 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL); if (ret && ret != ERROR_ALREADY_EXISTS) { - WARN("Failed to create directory %s.\n", debugstr_w(szBuildPath)); + ERR("Failed to create directory %s.\n", debugstr_w(szBuildPath)); hr = E_FAIL; goto end; } @@ -1489,16 +2126,16 @@ end: } /************************************************************************* - * SHGetFolderPathA [SHELL32.@] + * SHGetFolderPathA [SHELL32.@] * * See SHGetFolderPathW. */ HRESULT WINAPI SHGetFolderPathA( - HWND hwndOwner, - int nFolder, - HANDLE hToken, - DWORD dwFlags, - LPSTR pszPath) + HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwFlags, + LPSTR pszPath) { WCHAR szTemp[MAX_PATH]; HRESULT hr; @@ -1527,31 +2164,40 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, LPCWSTR szUserShellFolderPath, LPCWSTR szShellFolderPath, const UINT folders[], UINT foldersLen) { + const WCHAR *szValueName; + WCHAR buffer[40]; UINT i; WCHAR path[MAX_PATH]; HRESULT hr = S_OK; HKEY hUserKey = NULL, hKey = NULL; - DWORD dwDisp, dwType, dwPathLen; + DWORD dwType, dwPathLen; LONG ret; TRACE("%p,%p,%s,%p,%u\n", hRootKey, hToken, debugstr_w(szUserShellFolderPath), folders, foldersLen); - ret = RegCreateKeyExW(hRootKey, szUserShellFolderPath, 0, NULL, 0, - KEY_ALL_ACCESS, NULL, &hUserKey, &dwDisp); + ret = RegCreateKeyW(hRootKey, szUserShellFolderPath, &hUserKey); if (ret) hr = HRESULT_FROM_WIN32(ret); else { - ret = RegCreateKeyExW(hRootKey, szShellFolderPath, 0, NULL, 0, - KEY_ALL_ACCESS, NULL, &hKey, &dwDisp); + ret = RegCreateKeyW(hRootKey, szShellFolderPath, &hKey); if (ret) hr = HRESULT_FROM_WIN32(ret); } for (i = 0; SUCCEEDED(hr) && i < foldersLen; i++) { dwPathLen = MAX_PATH * sizeof(WCHAR); - if (RegQueryValueExW(hUserKey, CSIDL_Data[folders[i]].szValueName, NULL, + + /* For CSIDL_Type_User we also use the GUID if no szValueName is provided */ + szValueName = CSIDL_Data[folders[i]].szValueName; + if (!szValueName && CSIDL_Data[folders[i]].type == CSIDL_Type_User) + { + StringFromGUID2( CSIDL_Data[folders[i]].id, buffer, 39 ); + szValueName = &buffer[0]; + } + + if (RegQueryValueExW(hUserKey, szValueName, NULL, &dwType, (LPBYTE)path, &dwPathLen) || (dwType != REG_SZ && dwType != REG_EXPAND_SZ)) { @@ -1562,27 +2208,31 @@ static HRESULT _SHRegisterFolders(HKEY hRootKey, HANDLE hToken, else if (CSIDL_Data[folders[i]].type == CSIDL_Type_AllUsers) _SHGetAllUsersProfilePath(SHGFP_TYPE_DEFAULT, folders[i], path); else if (CSIDL_Data[folders[i]].type == CSIDL_Type_WindowsPath) + { GetWindowsDirectoryW(path, MAX_PATH); + if (CSIDL_Data[folders[i]].szDefaultPath && + !IS_INTRESOURCE(CSIDL_Data[folders[i]].szDefaultPath)) + { + PathAddBackslashW(path); + strcatW(path, CSIDL_Data[folders[i]].szDefaultPath); + } + } else hr = E_FAIL; if (*path) { - ret = RegSetValueExW(hUserKey, - CSIDL_Data[folders[i]].szValueName, 0, REG_EXPAND_SZ, - (LPBYTE)path, (wcslen(path) + 1) * sizeof(WCHAR)); + ret = RegSetValueExW(hUserKey, szValueName, 0, REG_EXPAND_SZ, + (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR)); if (ret) hr = HRESULT_FROM_WIN32(ret); else { - // Don't fail if folder can't be created - if (SUCCEEDED(SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE, - hToken, SHGFP_TYPE_DEFAULT, path))) - { - ret = RegSetValueExW(hKey, CSIDL_Data[folders[i]].szValueName, 0, REG_SZ, - (LPBYTE)path, (wcslen(path) + 1) * sizeof(WCHAR)); - if (ret) - hr = HRESULT_FROM_WIN32(ret); - } + hr = SHGetFolderPathW(NULL, folders[i] | CSIDL_FLAG_CREATE, + hToken, SHGFP_TYPE_DEFAULT, path); + ret = RegSetValueExW(hKey, szValueName, 0, REG_SZ, + (LPBYTE)path, (strlenW(path) + 1) * sizeof(WCHAR)); + if (ret) + hr = HRESULT_FROM_WIN32(ret); } } } @@ -1618,7 +2268,14 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault) CSIDL_COOKIES, CSIDL_HISTORY, CSIDL_MYPICTURES, - CSIDL_FONTS + CSIDL_FONTS, + CSIDL_ADMINTOOLS, + CSIDL_CONTACTS, + CSIDL_DOWNLOADS, + CSIDL_LINKS, + CSIDL_APPDATA_LOCALLOW, + CSIDL_SAVED_GAMES, + CSIDL_SEARCHES }; WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH]; LPCWSTR pUserShellFolderPath, pShellFolderPath; @@ -1631,13 +2288,13 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault) { hToken = (HANDLE)-1; hRootKey = HKEY_USERS; - wcscpy(userShellFolderPath, DefaultW); + strcpyW(userShellFolderPath, DefaultW); PathAddBackslashW(userShellFolderPath); - wcscat(userShellFolderPath, szSHUserFolders); + strcatW(userShellFolderPath, szSHUserFolders); pUserShellFolderPath = userShellFolderPath; - wcscpy(shellFolderPath, DefaultW); + strcpyW(shellFolderPath, DefaultW); PathAddBackslashW(shellFolderPath); - wcscat(shellFolderPath, szSHFolders); + strcatW(shellFolderPath, szSHFolders); pShellFolderPath = shellFolderPath; } else @@ -1665,6 +2322,10 @@ static HRESULT _SHRegisterCommonShellFolders(void) CSIDL_COMMON_APPDATA, CSIDL_COMMON_TEMPLATES, CSIDL_COMMON_DOCUMENTS, + CSIDL_COMMON_ADMINTOOLS, + CSIDL_COMMON_MUSIC, + CSIDL_COMMON_PICTURES, + CSIDL_COMMON_VIDEO, }; HRESULT hr; @@ -1678,7 +2339,7 @@ static HRESULT _SHRegisterCommonShellFolders(void) /* Register the default values in the registry, as some apps seem to depend * on their presence. The set registered was taken from Windows XP. */ -EXTERN_C HRESULT SHELL_RegisterShellFolders(void) +HRESULT SHELL_RegisterShellFolders(void) { HRESULT hr; @@ -1694,34 +2355,26 @@ EXTERN_C HRESULT SHELL_RegisterShellFolders(void) * SHGetSpecialFolderPathA [SHELL32.@] */ BOOL WINAPI SHGetSpecialFolderPathA ( - HWND hwndOwner, - LPSTR szPath, - int nFolder, - BOOL bCreate) + HWND hwndOwner, + LPSTR szPath, + int nFolder, + BOOL bCreate) { - return (SHGetFolderPathA( - hwndOwner, - nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), - NULL, - 0, - szPath)) == S_OK ? TRUE : FALSE; + return SHGetFolderPathA(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0, + szPath) == S_OK; } /************************************************************************* * SHGetSpecialFolderPathW */ BOOL WINAPI SHGetSpecialFolderPathW ( - HWND hwndOwner, - LPWSTR szPath, - int nFolder, - BOOL bCreate) + HWND hwndOwner, + LPWSTR szPath, + int nFolder, + BOOL bCreate) { - return (SHGetFolderPathW( - hwndOwner, - nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), - NULL, - 0, - szPath)) == S_OK ? TRUE : FALSE; + return SHGetFolderPathW(hwndOwner, nFolder + (bCreate ? CSIDL_FLAG_CREATE : 0), NULL, 0, + szPath) == S_OK; } /************************************************************************* @@ -1747,17 +2400,17 @@ BOOL WINAPI SHGetSpecialFolderPathW ( * virtual folders that are handled here. */ HRESULT WINAPI SHGetFolderLocation( - HWND hwndOwner, - int nFolder, - HANDLE hToken, - DWORD dwReserved, - LPITEMIDLIST *ppidl) + HWND hwndOwner, + int nFolder, + HANDLE hToken, + DWORD dwReserved, + LPITEMIDLIST *ppidl) { HRESULT hr = E_INVALIDARG; TRACE("%p 0x%08x %p 0x%08x %p\n", hwndOwner, nFolder, hToken, dwReserved, ppidl); - + if (!ppidl) return E_INVALIDARG; if (dwReserved) @@ -1765,7 +2418,7 @@ HRESULT WINAPI SHGetFolderLocation( /* The virtual folders' locations are not user-dependent */ *ppidl = NULL; - switch (nFolder) + switch (nFolder & CSIDL_FOLDER_MASK) { case CSIDL_DESKTOP: *ppidl = _ILCreateDesktop(); @@ -1829,16 +2482,16 @@ HRESULT WINAPI SHGetFolderLocation( } /************************************************************************* - * SHGetSpecialFolderLocation [SHELL32.@] + * SHGetSpecialFolderLocation [SHELL32.@] * * NOTES * In NT5, SHGetSpecialFolderLocation needs the /Recent * directory. */ HRESULT WINAPI SHGetSpecialFolderLocation( - HWND hwndOwner, - INT nFolder, - LPITEMIDLIST * ppidl) + HWND hwndOwner, + INT nFolder, + LPITEMIDLIST * ppidl) { HRESULT hr = E_INVALIDARG;