diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index e14f533bb9..045f1f00a8 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -59,6 +59,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell); static const BOOL is_win64 = sizeof(void *) > sizeof(int); +static void _SHCreateSymbolicLinks(void); + /* ########## Combining and Constructing paths ########## */ @@ -4097,6 +4099,9 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW( goto end; } + /* If creation of one of directory is requested, and it doesn't exist yet, make sure to setup symlinks to some of default directories first */ + _SHCreateSymbolicLinks(); + /* create directory/directories */ ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL); if (ret && ret != ERROR_ALREADY_EXISTS) @@ -4424,9 +4429,9 @@ static void _SHCreateSymbolicLinks(void) char * xdg_desktop_dir; /* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */ - hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, + hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (FAILED(hr)) return; + if (FAILED(hr) && (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))) return; pszPersonal = wine_get_unix_file_name(wszTempPath); if (!pszPersonal) return; @@ -4451,7 +4456,7 @@ static void _SHCreateSymbolicLinks(void) { strcpy(szMyStuffTarget, szPersonalTarget); if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i]))) - mkdir(szMyStuffTarget, 0777); + mkdir(szMyStuffTarget, 0755); } break; } @@ -4478,7 +4483,6 @@ static void _SHCreateSymbolicLinks(void) } /* Replace 'My Documents' directory with a symlink or fail silently if not empty. */ - remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } else @@ -4486,11 +4490,12 @@ static void _SHCreateSymbolicLinks(void) /* '$HOME' doesn't exist. Create 'My Pictures', 'My Videos' and 'My Music' subdirs * in '%USERPROFILE%\\My Documents' or fail silently if they already exist. */ pszHome = NULL; + mkdir(pszPersonal, 0755); strcpy(szPersonalTarget, pszPersonal); for (i = 0; i < ARRAY_SIZE(aidsMyStuff); i++) { strcpy(szMyStuffTarget, szPersonalTarget); if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i]))) - mkdir(szMyStuffTarget, 0777); + mkdir(szMyStuffTarget, 0755); } } @@ -4498,9 +4503,9 @@ static void _SHCreateSymbolicLinks(void) for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) { /* Create the current 'My Whatever' folder and get its unix path. */ - hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE, NULL, + hr = SHGetFolderPathW(NULL, acsidlMyStuff[i], NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (FAILED(hr)) continue; + if (hr != HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) continue; pszMyStuff = wine_get_unix_file_name(wszTempPath); if (!pszMyStuff) continue; @@ -4534,7 +4539,6 @@ static void _SHCreateSymbolicLinks(void) strcpy(szMyStuffTarget, szPersonalTarget); break; } - remove(pszMyStuff); symlink(szMyStuffTarget, pszMyStuff); heap_free(pszMyStuff); } @@ -4551,11 +4555,10 @@ static void _SHCreateSymbolicLinks(void) (_SHAppendToUnixPath(szDesktopTarget, DesktopW) && !stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode))) { - hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, + hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (SUCCEEDED(hr) && (pszDesktop = wine_get_unix_file_name(wszTempPath))) + if ((hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) && (pszDesktop = wine_get_unix_file_name(wszTempPath))) { - remove(pszDesktop); if (xdg_desktop_dir) symlink(xdg_desktop_dir, pszDesktop); else