shell32: Move retrieving folder path logic to SHGetKnownFolderPath().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
064508c0dd
commit
a0c259cf56
|
@ -4704,45 +4704,134 @@ static int csidl_from_id( const KNOWNFOLDERID *id )
|
|||
/*************************************************************************
|
||||
* SHGetKnownFolderPath [SHELL32.@]
|
||||
*/
|
||||
HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE token, PWSTR *path)
|
||||
HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE token, WCHAR **ret_path)
|
||||
{
|
||||
WCHAR pathW[MAX_PATH], tempW[MAX_PATH];
|
||||
HRESULT hr;
|
||||
WCHAR folder[MAX_PATH];
|
||||
int index = csidl_from_id( rfid );
|
||||
CSIDL_Type type;
|
||||
int ret;
|
||||
int folder = csidl_from_id(rfid), shgfp_flags;
|
||||
|
||||
TRACE("%s, 0x%08x, %p, %p\n", debugstr_guid(rfid), flags, token, path);
|
||||
TRACE("%s, 0x%08x, %p, %p\n", debugstr_guid(rfid), flags, token, ret_path);
|
||||
|
||||
*path = NULL;
|
||||
*ret_path = NULL;
|
||||
|
||||
if (index < 0)
|
||||
if (folder < 0)
|
||||
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
|
||||
|
||||
if (flags & KF_FLAG_CREATE)
|
||||
index |= CSIDL_FLAG_CREATE;
|
||||
|
||||
if (flags & KF_FLAG_DONT_VERIFY)
|
||||
index |= CSIDL_FLAG_DONT_VERIFY;
|
||||
|
||||
if (flags & KF_FLAG_NO_ALIAS)
|
||||
index |= CSIDL_FLAG_NO_ALIAS;
|
||||
|
||||
if (flags & KF_FLAG_INIT)
|
||||
index |= CSIDL_FLAG_PER_USER_INIT;
|
||||
|
||||
if (flags & ~(KF_FLAG_CREATE|KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS|KF_FLAG_INIT))
|
||||
if (flags & ~(KF_FLAG_CREATE|KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS|
|
||||
KF_FLAG_INIT|KF_FLAG_DEFAULT_PATH))
|
||||
{
|
||||
FIXME("flags 0x%08x not supported\n", flags);
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
hr = SHGetFolderPathW( NULL, index, token, 0, folder );
|
||||
if (SUCCEEDED(hr))
|
||||
shgfp_flags = flags & KF_FLAG_DEFAULT_PATH ? SHGFP_TYPE_DEFAULT : SHGFP_TYPE_CURRENT;
|
||||
|
||||
type = CSIDL_Data[folder].type;
|
||||
switch (type)
|
||||
{
|
||||
*path = CoTaskMemAlloc( (strlenW( folder ) + 1) * sizeof(WCHAR) );
|
||||
if (!*path)
|
||||
return E_OUTOFMEMORY;
|
||||
strcpyW( *path, folder );
|
||||
case CSIDL_Type_Disallowed:
|
||||
hr = E_INVALIDARG;
|
||||
break;
|
||||
case CSIDL_Type_NonExistent:
|
||||
hr = S_FALSE;
|
||||
break;
|
||||
case CSIDL_Type_WindowsPath:
|
||||
GetWindowsDirectoryW(tempW, MAX_PATH);
|
||||
if (CSIDL_Data[folder].szDefaultPath &&
|
||||
!IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
|
||||
*CSIDL_Data[folder].szDefaultPath)
|
||||
{
|
||||
PathAddBackslashW(tempW);
|
||||
strcatW(tempW, CSIDL_Data[folder].szDefaultPath);
|
||||
}
|
||||
hr = S_OK;
|
||||
break;
|
||||
case CSIDL_Type_SystemPath:
|
||||
GetSystemDirectoryW(tempW, MAX_PATH);
|
||||
if (CSIDL_Data[folder].szDefaultPath &&
|
||||
!IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
|
||||
*CSIDL_Data[folder].szDefaultPath)
|
||||
{
|
||||
PathAddBackslashW(tempW);
|
||||
strcatW(tempW, CSIDL_Data[folder].szDefaultPath);
|
||||
}
|
||||
hr = S_OK;
|
||||
break;
|
||||
case CSIDL_Type_SystemX86Path:
|
||||
if (!GetSystemWow64DirectoryW(tempW, MAX_PATH)) GetSystemDirectoryW(tempW, MAX_PATH);
|
||||
if (CSIDL_Data[folder].szDefaultPath &&
|
||||
!IS_INTRESOURCE(CSIDL_Data[folder].szDefaultPath) &&
|
||||
*CSIDL_Data[folder].szDefaultPath)
|
||||
{
|
||||
PathAddBackslashW(tempW);
|
||||
strcatW(tempW, CSIDL_Data[folder].szDefaultPath);
|
||||
}
|
||||
hr = S_OK;
|
||||
break;
|
||||
case CSIDL_Type_CurrVer:
|
||||
hr = _SHGetCurrentVersionPath(shgfp_flags, folder, tempW);
|
||||
break;
|
||||
case CSIDL_Type_User:
|
||||
hr = _SHGetUserProfilePath(token, shgfp_flags, folder, tempW);
|
||||
break;
|
||||
case CSIDL_Type_AllUsers:
|
||||
hr = _SHGetAllUsersProfilePath(shgfp_flags, folder, tempW);
|
||||
break;
|
||||
default:
|
||||
FIXME("bogus type %d, please fix\n", type);
|
||||
hr = E_INVALIDARG;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Expand environment strings if necessary */
|
||||
if (*tempW == '%')
|
||||
hr = _SHExpandEnvironmentStrings(tempW, pathW);
|
||||
else
|
||||
strcpyW(pathW, tempW);
|
||||
|
||||
if (FAILED(hr))
|
||||
goto failed;
|
||||
|
||||
/* if we don't care about existing directories we are ready */
|
||||
if (flags & KF_FLAG_DONT_VERIFY) goto done;
|
||||
|
||||
if (PathFileExistsW(pathW)) goto done;
|
||||
|
||||
/* Does not exist but we are not allowed to create it. The return value
|
||||
* is verified against shell32 version 6.0.
|
||||
*/
|
||||
if (!(flags & KF_FLAG_CREATE))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* create directory/directories */
|
||||
ret = SHCreateDirectoryExW(NULL, pathW, NULL);
|
||||
if (ret && ret != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
ERR("Failed to create directory %s.\n", debugstr_w(pathW));
|
||||
hr = E_FAIL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
TRACE("Created missing system directory %s\n", debugstr_w(pathW));
|
||||
|
||||
done:
|
||||
TRACE("Final path is %s, %#x\n", debugstr_w(pathW), hr);
|
||||
|
||||
*ret_path = CoTaskMemAlloc((strlenW(pathW) + 1) * sizeof(WCHAR));
|
||||
if (!*ret_path)
|
||||
return E_OUTOFMEMORY;
|
||||
strcpyW(*ret_path, pathW);
|
||||
|
||||
return hr;
|
||||
|
||||
failed:
|
||||
TRACE("Failed to get folder path, %#x.\n", hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue