shell32: Implement SHGetFolderPathAndSubDirA/W.

oldstable
Stefan Leichter 2008-04-17 23:31:05 +02:00 committed by Alexandre Julliard
parent f9c2d8e2f4
commit a629a4199e
3 changed files with 87 additions and 4 deletions

View File

@ -344,6 +344,8 @@
@ stdcall SHGetFileInfoW(ptr long ptr long long)
@ stdcall SHGetFolderLocation(long long long long ptr)
@ stdcall SHGetFolderPathA(long long long long ptr)
@ stdcall SHGetFolderPathAndSubDirA(long long long long str ptr)
@ stdcall SHGetFolderPathAndSubDirW(long long long long wstr ptr)
@ stdcall SHGetFolderPathW(long long long long ptr)
@ stub SHGetFreeDiskSpace
@ stub SHGetIconOverlayIndexA

View File

@ -1674,6 +1674,70 @@ HRESULT WINAPI SHGetFolderPathW(
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)
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
return hr;
}
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 */
{
int length;
HRESULT hr = S_OK;
LPWSTR pszSubPathW = NULL;
LPWSTR pszPathW = NULL;
TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
if(pszPath) {
pszPathW = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
if(!pszPathW) {
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
WARN("Failed to allocate %u bytes of memory\n", MAX_PATH * sizeof(WCHAR));
goto cleanup;
}
}
TRACE("%08x,%08x,%s\n",nFolder, dwFlags, debugstr_w(pszSubPathW));
/* SHGetFolderPathAndSubDirW does not distinguish if pszSubPath isn't
* set (null), or an empty string.therefore call it without the parameter set
* if pszSubPath is an empty string
*/
if (pszSubPath && pszSubPath[0]) {
length = MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, NULL, 0);
pszSubPathW = HeapAlloc(GetProcessHeap(), 0, length * sizeof(WCHAR));
if(!pszSubPathW) {
hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
WARN("Failed to allocate %u bytes of memory\n", length * sizeof(WCHAR));
goto cleanup;
}
MultiByteToWideChar(CP_ACP, 0, pszSubPath, -1, pszSubPathW, length);
}
hr = SHGetFolderPathAndSubDirW(hwndOwner, nFolder, hToken, dwFlags, pszSubPathW, pszPathW);
if (SUCCEEDED(hr) && pszPath)
WideCharToMultiByte(CP_ACP, 0, pszPathW, -1, pszPath, MAX_PATH, NULL, NULL);
cleanup:
HeapFree(GetProcessHeap(), 0, pszPathW);
HeapFree(GetProcessHeap(), 0, pszSubPathW);
return hr;
}
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 */
{
HRESULT hr;
WCHAR szBuildPath[MAX_PATH], szTemp[MAX_PATH];
@ -1681,15 +1745,18 @@ HRESULT WINAPI SHGetFolderPathW(
CSIDL_Type type;
int ret;
TRACE("%p,%p,nFolder=0x%04x\n", hwndOwner,pszPath,nFolder);
TRACE("%p,%p,nFolder=0x%04x,%s\n", hwndOwner,pszPath,nFolder,debugstr_w(pszSubPath));
/* Windows always NULL-terminates the resulting path regardless of success
* or failure, so do so first
*/
if (pszPath)
*pszPath = '\0';
if (folder >= sizeof(CSIDL_Data) / sizeof(CSIDL_Data[0]))
return E_INVALIDARG;
if ((SHGFP_TYPE_CURRENT != dwFlags) && (SHGFP_TYPE_DEFAULT != dwFlags))
return E_INVALIDARG;
szTemp[0] = 0;
type = CSIDL_Data[folder].type;
switch (type)
@ -1742,12 +1809,23 @@ HRESULT WINAPI SHGetFolderPathW(
hr = _SHExpandEnvironmentStrings(szTemp, szBuildPath);
else
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 < (lstrlenW(szBuildPath) + lstrlenW(pszSubPath) + 2)) {
hr = HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
goto end;
}
PathAppendW(szBuildPath, pszSubPath);
PathRemoveBackslashW(szBuildPath);
}
/* Copy the path if it's available before we might return */
if (SUCCEEDED(hr) && pszPath)
strcpyW(pszPath, szBuildPath);
if (FAILED(hr)) goto end;
/* if we don't care about existing directories we are ready */
if(nFolder & CSIDL_FLAG_DONT_VERIFY) goto end;
@ -1758,7 +1836,7 @@ HRESULT WINAPI SHGetFolderPathW(
*/
if (!(nFolder & CSIDL_FLAG_CREATE))
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
hr = HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
goto end;
}

View File

@ -54,6 +54,9 @@ DWORD WINAPI SHFormatDrive(HWND,UINT,UINT,UINT);
void WINAPI SHFree(LPVOID);
BOOL WINAPI GetFileNameFromBrowse(HWND,LPSTR,DWORD,LPCSTR,LPCSTR,LPCSTR,LPCSTR);
HRESULT WINAPI SHGetInstanceExplorer(IUnknown**);
HRESULT WINAPI SHGetFolderPathAndSubDirA(HWND,int,HANDLE,DWORD,LPCSTR,LPSTR);
HRESULT WINAPI SHGetFolderPathAndSubDirW(HWND,int,HANDLE,DWORD,LPCWSTR,LPWSTR);
#define SHGetFolderPathAndSubDir WINELIB_NAME_AW(SHGetFolderPathAndSubDir);
BOOL WINAPI SHGetPathFromIDListA(LPCITEMIDLIST,LPSTR);
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST,LPWSTR);
#define SHGetPathFromIDList WINELIB_NAME_AW(SHGetPathFromIDList)