Commit c4dd56bc authored by Filip Navara's avatar Filip Navara Committed by Alexandre Julliard

- Moved actual code from SHGetSpecialFolderPathA to SHGetFolderPathW,

adjusted and unicodified it. - Rewrote SHGetFolderPathA to call SHGetFolderPathW. - Rewrote SHGetSpecialFolderPath[AW] to call SHGetFolderPath[AW].
parent 23f26c8a
...@@ -676,21 +676,16 @@ VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath) ...@@ -676,21 +676,16 @@ VOID WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
PathSetDlgItemPathA(hDlg, id, pszPath); PathSetDlgItemPathA(hDlg, id, pszPath);
} }
/************************************************************************* /*************************************************************************
* SHGetSpecialFolderPathA [SHELL32.@] * SHGetFolderPathW [SHELL32.@]
* *
* converts csidl to path * converts csidl to path
*/ */
static const char * const szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; 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 char * const szSHUserFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders"; 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 char * const szSetup = "Software\\Microsoft\\Windows\\CurrentVersion\\Setup"; static const WCHAR szSetup[] = {'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','e','t','u','p','\0'};
static const char * const szCurrentVersion = "Software\\Microsoft\\Windows\\CurrentVersion"; 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'};
#if 0
static const char * const szEnvUserProfile = "%USERPROFILE%";
static const char * const szEnvSystemRoot = "%SYSTEMROOT%";
#endif
typedef struct typedef struct
{ {
...@@ -1028,106 +1023,104 @@ static const CSIDL_DATA CSIDL_Data[] = ...@@ -1028,106 +1023,104 @@ static const CSIDL_DATA CSIDL_Data[] =
#undef HKCU #undef HKCU
#undef HKLM #undef HKLM
/**********************************************************************/ HRESULT WINAPI SHGetFolderPathW(
BOOL WINAPI SHGetSpecialFolderPathA (
HWND hwndOwner, HWND hwndOwner,
LPSTR szPath,
int csidl, int csidl,
BOOL bCreate) HANDLE hToken, /* [in] FIXME: get paths for specific user */
DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */
LPWSTR pszPath)
{ {
CHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH]; WCHAR szValueName[MAX_PATH], szDefaultPath[MAX_PATH], szBuildPath[MAX_PATH];
HKEY hRootKey, hKey; HKEY hRootKey, hKey;
DWORD dwFlags; DWORD dwCsidlFlags;
DWORD dwType, dwDisp, dwPathLen = MAX_PATH; DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
DWORD folder = csidl & CSIDL_FOLDER_MASK; DWORD folder = csidl & CSIDL_FOLDER_MASK;
CHAR *p; WCHAR *p;
TRACE("%p,%p,csidl=%d,0x%04x\n", hwndOwner,szPath,csidl,bCreate); TRACE("%p,%p,csidl=0x%04x\n", hwndOwner,pszPath,csidl);
if ((folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) || if ((folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0])) ||
(CSIDL_Data[folder].hRootKey == 0)) (CSIDL_Data[folder].hRootKey == 0))
{ {
ERR("folder 0x%04lx unknown or not allowed\n", folder); ERR("folder 0x%04lx unknown or not allowed\n", folder);
return FALSE; return E_FAIL;
} }
if (CSIDL_Data[folder].hRootKey == (HKEY)1) if (CSIDL_Data[folder].hRootKey == (HKEY)1)
{ {
FIXME("folder 0x%04lx unknown, please add.\n", folder); FIXME("folder 0x%04lx unknown, please add.\n", folder);
return FALSE; return E_FAIL;
} }
dwFlags = CSIDL_Data[folder].dwFlags; dwCsidlFlags = CSIDL_Data[folder].dwFlags;
hRootKey = CSIDL_Data[folder].hRootKey; hRootKey = CSIDL_Data[folder].hRootKey;
strcpy(szValueName, CSIDL_Data[folder].szValueName); MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szValueName, -1, szValueName, MAX_PATH);
strcpy(szDefaultPath, CSIDL_Data[folder].szDefaultPath); MultiByteToWideChar(CP_ACP, 0, CSIDL_Data[folder].szDefaultPath, -1, szDefaultPath, MAX_PATH);
if (dwFlags & CSIDL_MYFLAG_SHFOLDER) if (dwCsidlFlags & CSIDL_MYFLAG_SHFOLDER)
{ {
/* user shell folders */ /* user shell folders */
if (RegCreateKeyExA(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE; if (RegCreateKeyExW(hRootKey,szSHUserFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return E_FAIL;
if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen)) if (RegQueryValueExW(hKey,szValueName,NULL,&dwType,(LPBYTE)pszPath,&dwPathLen))
{ {
RegCloseKey(hKey); RegCloseKey(hKey);
/* shell folders */ /* shell folders */
if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE; if (RegCreateKeyExW(hRootKey,szSHFolders,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return E_FAIL;
if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen)) if (RegQueryValueExW(hKey,szValueName,NULL,&dwType,(LPBYTE)pszPath,&dwPathLen))
{ {
/* value not existing */ /* value not existing */
if (dwFlags & CSIDL_MYFLAG_RELATIVE) if (dwCsidlFlags & CSIDL_MYFLAG_RELATIVE)
{ {
GetWindowsDirectoryA(szPath, MAX_PATH); GetWindowsDirectoryW(pszPath, MAX_PATH);
PathAddBackslashA(szPath); PathAddBackslashW(pszPath);
strcat(szPath, szDefaultPath); strcatW(pszPath, szDefaultPath);
} }
else else
{ {
strcpy(szPath, "C:\\"); /* FIXME ??? */ GetSystemDirectoryW(pszPath, MAX_PATH);
strcat(szPath, szDefaultPath); strcpyW(pszPath + 3, szDefaultPath);
} }
dwType=REG_SZ; dwType=REG_SZ;
RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1); RegSetValueExW(hKey,szValueName,0,REG_SZ,(LPBYTE)pszPath,strlenW(pszPath)+1);
} }
} }
RegCloseKey(hKey); RegCloseKey(hKey);
} }
else else
{ {
LPCSTR pRegPath; LPCWSTR pRegPath;
if (dwFlags & CSIDL_MYFLAG_SETUP) if (dwCsidlFlags & CSIDL_MYFLAG_SETUP)
pRegPath = szSetup; pRegPath = szSetup;
else else if (dwCsidlFlags & CSIDL_MYFLAG_CURRVER)
if (dwFlags & CSIDL_MYFLAG_CURRVER)
pRegPath = szCurrentVersion; pRegPath = szCurrentVersion;
else else
{ {
ERR("folder settings broken, please correct !\n"); ERR("folder settings broken, please correct !\n");
return FALSE; return E_FAIL;
} }
if (RegCreateKeyExA(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return FALSE; if (RegCreateKeyExW(hRootKey,pRegPath,0,NULL,0,KEY_ALL_ACCESS,NULL,&hKey,&dwDisp)) return E_FAIL;
if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen)) if (RegQueryValueExW(hKey,szValueName,NULL,&dwType,(LPBYTE)pszPath,&dwPathLen))
{ {
/* value not existing */ /* value not existing */
if (dwFlags & CSIDL_MYFLAG_RELATIVE) if (dwCsidlFlags & CSIDL_MYFLAG_RELATIVE)
{ {
GetWindowsDirectoryA(szPath, MAX_PATH); GetWindowsDirectoryW(pszPath, MAX_PATH);
PathAddBackslashA(szPath); PathAddBackslashW(pszPath);
strcat(szPath, szDefaultPath); strcatW(pszPath, szDefaultPath);
} }
else else
{ {
strcpy(szPath, "C:\\"); /* FIXME ??? */ GetSystemDirectoryW(pszPath, MAX_PATH);
strcat(szPath, szDefaultPath); strcpyW(pszPath + 3, szDefaultPath);
} }
dwType=REG_SZ; dwType=REG_SZ;
RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1); RegSetValueExW(hKey,szValueName,0,REG_SZ,(LPBYTE)pszPath,strlenW(pszPath)+1);
} }
RegCloseKey(hKey); RegCloseKey(hKey);
} }
...@@ -1135,116 +1128,119 @@ BOOL WINAPI SHGetSpecialFolderPathA ( ...@@ -1135,116 +1128,119 @@ BOOL WINAPI SHGetSpecialFolderPathA (
/* expand paths like %USERPROFILE% */ /* expand paths like %USERPROFILE% */
if (dwType == REG_EXPAND_SZ) if (dwType == REG_EXPAND_SZ)
{ {
ExpandEnvironmentStringsA(szPath, szDefaultPath, MAX_PATH); ExpandEnvironmentStringsW(pszPath, szDefaultPath, MAX_PATH);
strcpy(szPath, szDefaultPath); strcpyW(pszPath, szDefaultPath);
} }
/* if we don't care about existing directories we are ready */ /* if we don't care about existing directories we are ready */
if(csidl & CSIDL_FLAG_DONT_VERIFY) return TRUE; if(csidl & CSIDL_FLAG_DONT_VERIFY) return S_OK;
if (PathFileExistsA(szPath)) return TRUE; if (PathFileExistsW(pszPath)) return S_OK;
/* not existing but we are not allowed to create it */ /* not existing but we are not allowed to create it */
if (!bCreate) return FALSE; if (!(csidl & CSIDL_FLAG_CREATE)) return E_FAIL;
/* create directory/directories */ /* create directory/directories */
strcpy(szBuildPath, szPath); strcpyW(szBuildPath, pszPath);
p = strchr(szBuildPath, '\\'); p = strchrW(szBuildPath, '\\');
while (p) while (p)
{ {
*p = 0; *p = 0;
if (!PathFileExistsA(szBuildPath)) if (!PathFileExistsW(szBuildPath))
{ {
if (!CreateDirectoryA(szBuildPath,NULL)) if (!CreateDirectoryW(szBuildPath,NULL))
{ {
ERR("Failed to create directory '%s'.\n", szPath); ERR("Failed to create directory '%s'.\n", debugstr_w(pszPath));
return FALSE; return E_FAIL;
} }
} }
*p = '\\'; *p = '\\';
p = strchr(p+1, '\\'); p = strchrW(p+1, '\\');
} }
/* last component must be created too. */ /* last component must be created too. */
if (!PathFileExistsA(szBuildPath)) if (!PathFileExistsW(szBuildPath))
{ {
if (!CreateDirectoryA(szBuildPath,NULL)) if (!CreateDirectoryW(szBuildPath,NULL))
{ {
ERR("Failed to create directory '%s'.\n", szPath); ERR("Failed to create directory '%s'.\n", debugstr_w(pszPath));
return FALSE; return E_FAIL;
} }
} }
TRACE("Created missing system directory '%s'\n", szPath); TRACE("Created missing system directory '%s'\n", debugstr_w(pszPath));
return TRUE; return S_OK;
} }
/************************************************************************* /*************************************************************************
* SHGetSpecialFolderPathW * SHGetFolderPathA [SHELL32.@]
*/ */
BOOL WINAPI SHGetSpecialFolderPathW ( HRESULT WINAPI SHGetFolderPathA(
HWND hwndOwner, HWND hwndOwner,
LPWSTR szPath,
int csidl, int csidl,
BOOL bCreate) HANDLE hToken,
DWORD dwFlags,
LPSTR pszPath)
{ {
char szTemp[MAX_PATH]; WCHAR szTemp[MAX_PATH];
HRESULT hr;
if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate)) hr = SHGetFolderPathW(hwndOwner, csidl, hToken, dwFlags, szTemp);
if (hr == S_OK)
{ {
if (!MultiByteToWideChar( CP_ACP, 0, szTemp, -1, szPath, MAX_PATH )) if (!WideCharToMultiByte( CP_ACP, 0, szTemp, -1, pszPath, MAX_PATH, NULL, NULL ))
szPath[MAX_PATH-1] = 0; pszPath[MAX_PATH - 1] = 0;
} }
TRACE("%p,%p,csidl=%d,0x%04x\n", hwndOwner,szPath,csidl,bCreate); TRACE("%p,%p,csidl=0x%04x\n",hwndOwner,pszPath,csidl);
return TRUE; return hr;
} }
/************************************************************************* /*************************************************************************
* SHGetSpecialFolderPath (SHELL32.175) * SHGetSpecialFolderPathA [SHELL32.@]
*/ */
BOOL WINAPI SHGetSpecialFolderPathAW ( BOOL WINAPI SHGetSpecialFolderPathA (
HWND hwndOwner, HWND hwndOwner,
LPVOID szPath, LPSTR szPath,
int csidl, int csidl,
BOOL bCreate) BOOL bCreate)
{ {
if (SHELL_OsIsUnicode()) return (SHGetFolderPathA(
return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate); hwndOwner,
return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate); csidl + (bCreate ? CSIDL_FLAG_CREATE : 0),
NULL,
0,
szPath)) == S_OK ? TRUE : FALSE;
} }
/************************************************************************* /*************************************************************************
* SHGetFolderPathA [SHELL32.@] * SHGetSpecialFolderPathW
*/ */
HRESULT WINAPI SHGetFolderPathA( BOOL WINAPI SHGetSpecialFolderPathW (
HWND hwndOwner, HWND hwndOwner,
int nFolder, LPWSTR szPath,
HANDLE hToken, /* [in] FIXME: get paths for specific user */ int csidl,
DWORD dwFlags, /* [in] FIXME: SHGFP_TYPE_CURRENT|SHGFP_TYPE_DEFAULT */ BOOL bCreate)
LPSTR pszPath)
{ {
return (SHGetSpecialFolderPathA( return (SHGetFolderPathW(
hwndOwner, hwndOwner,
pszPath, csidl + (bCreate ? CSIDL_FLAG_CREATE : 0),
CSIDL_FOLDER_MASK & nFolder, NULL,
CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL; 0,
szPath)) == S_OK ? TRUE : FALSE;
} }
/************************************************************************* /*************************************************************************
* SHGetFolderPathW [SHELL32.@] * SHGetSpecialFolderPath (SHELL32.175)
*/ */
HRESULT WINAPI SHGetFolderPathW( BOOL WINAPI SHGetSpecialFolderPathAW (
HWND hwndOwner, HWND hwndOwner,
int nFolder, LPVOID szPath,
HANDLE hToken, int csidl,
DWORD dwFlags, BOOL bCreate)
LPWSTR pszPath)
{ {
return (SHGetSpecialFolderPathW( if (SHELL_OsIsUnicode())
hwndOwner, return SHGetSpecialFolderPathW (hwndOwner, szPath, csidl, bCreate);
pszPath, return SHGetSpecialFolderPathA (hwndOwner, szPath, csidl, bCreate);
CSIDL_FOLDER_MASK & nFolder,
CSIDL_FLAG_CREATE & nFolder )) ? S_OK : E_FAIL;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment