Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22974 Signed-off-by: Olivier F. R. Dierick o.dierick@piezo-forte.be --- dlls/shell32/shellpath.c | 125 +++++++++++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 42 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 428b3be..f790afa 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4098,51 +4098,23 @@ static void _SHCreateMyDocumentsSubDirs(const UINT * aidsMyStuff, const UINT num }
/****************************************************************************** - * _SHCreateSymbolicLinks [Internal] + * _SHCreateMyDocumentsSymbolicLink [Internal] * - * Sets up symbol links for various shell folders to point into the user's home - * directory. We do an educated guess about what the user would probably want: - * - If there is a 'My Documents' directory in $HOME, the user probably wants - * wine's 'My Documents' to point there. Furthermore, we infer that the user - * is a Windows lover and has no problem with wine creating subfolders for - * 'My Pictures', 'My Music', 'My Videos' etc. under '$HOME/My Documents', if - * those do not already exist. We put appropriate symbolic links in place for - * those, too. - * - If there is no 'My Documents' directory in $HOME, we let 'My Documents' - * point directly to $HOME. We assume the user to be a unix hacker who does not - * want wine to create anything anywhere besides the .wine directory. So, if - * there already is a 'My Music' directory in $HOME, we symlink the 'My Music' - * shell folder to it. But if not, then we check XDG_MUSIC_DIR - "well known" - * directory, and try to link to that. If that fails, then we symlink to - * $HOME directly. The same holds for 'My Pictures', 'My Videos' etc. - * - The Desktop shell folder is symlinked to XDG_DESKTOP_DIR. If that does not - * exist, then we try '$HOME/Desktop'. If that does not exist, then we leave - * it alone. - * ('My Music',... above in fact means LoadString(IDS_MYMUSIC)) + * Sets up a symbolic link for the 'My Documents' shell folder to point into + * the users home directory. + * + * PARAMS + * aidsMyStuff [I] Array of IDS_* resources to create sub dirs for. + * aids_num [I] Number of elements in aidsMyStuff. */ -static void _SHCreateSymbolicLinks(void) +static void _SHCreateMyDocumentsSymbolicLink(const UINT * aidsMyStuff, const UINT aids_num) { - static const UINT aidsMyStuff[] = { - IDS_MYPICTURES, IDS_MYVIDEOS, IDS_MYMUSIC, IDS_DOWNLOADS, IDS_TEMPLATES - }; - static const WCHAR * const MyOSXStuffW[] = { - PicturesW, MoviesW, MusicW, DownloadsW, TemplatesW - }; - static const int acsidlMyStuff[] = { - CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES - }; - static const char * const xdg_dirs[] = { - "PICTURES", "VIDEOS", "MUSIC", "DOWNLOAD", "TEMPLATES", "DOCUMENTS", "DESKTOP" - }; + static const char * const xdg_dirs[] = { "DOCUMENTS" }; static const unsigned int num = ARRAY_SIZE(xdg_dirs); char szPersonalTarget[FILENAME_MAX], *pszPersonal; - char szMyStuffTarget[FILENAME_MAX], *pszMyStuff; - char szDesktopTarget[FILENAME_MAX], *pszDesktop; struct stat statFolder; const char *pszHome; char ** xdg_results; - char * xdg_desktop_dir; - UINT i;
/* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */ pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_CREATE); @@ -4164,16 +4136,16 @@ static void _SHCreateSymbolicLinks(void) * 'My Pictures', 'My Videos', 'My Music' etc. or fail silently * if they already exist. */ - _SHCreateMyDocumentsSubDirs(aidsMyStuff, ARRAY_SIZE(aidsMyStuff), szPersonalTarget); + _SHCreateMyDocumentsSubDirs(aidsMyStuff, aids_num, szPersonalTarget); break; }
/* Try to point to the XDG Documents folder */ - if (xdg_results && xdg_results[num-2] && - !stat(xdg_results[num-2], &statFolder) && + if (xdg_results && xdg_results[0] && + !stat(xdg_results[0], &statFolder) && S_ISDIR(statFolder.st_mode)) { - strcpy(szPersonalTarget, xdg_results[num-2]); + strcpy(szPersonalTarget, xdg_results[0]); break; }
@@ -4200,9 +4172,78 @@ static void _SHCreateSymbolicLinks(void) * they already exist. */ pszHome = NULL; strcpy(szPersonalTarget, pszPersonal); - _SHCreateMyDocumentsSubDirs(aidsMyStuff, ARRAY_SIZE(aidsMyStuff), szPersonalTarget); + _SHCreateMyDocumentsSubDirs(aidsMyStuff, aids_num, szPersonalTarget); }
+ heap_free(pszPersonal); + + _SHFreeXDGUserDirs(num, xdg_results); +} + +/****************************************************************************** + * _SHCreateSymbolicLinks [Internal] + * + * Sets up symbol links for various shell folders to point into the user's home + * directory. We do an educated guess about what the user would probably want: + * - If there is a 'My Documents' directory in $HOME, the user probably wants + * wine's 'My Documents' to point there. Furthermore, we infer that the user + * is a Windows lover and has no problem with wine creating subfolders for + * 'My Pictures', 'My Music', 'My Videos' etc. under '$HOME/My Documents', if + * those do not already exist. We put appropriate symbolic links in place for + * those, too. + * - If there is no 'My Documents' directory in $HOME, we let 'My Documents' + * point directly to $HOME. We assume the user to be a unix hacker who does not + * want wine to create anything anywhere besides the .wine directory. So, if + * there already is a 'My Music' directory in $HOME, we symlink the 'My Music' + * shell folder to it. But if not, then we check XDG_MUSIC_DIR - "well known" + * directory, and try to link to that. If that fails, then we symlink to + * $HOME directly. The same holds for 'My Pictures', 'My Videos' etc. + * - The Desktop shell folder is symlinked to XDG_DESKTOP_DIR. If that does not + * exist, then we try '$HOME/Desktop'. If that does not exist, then we leave + * it alone. + * ('My Music',... above in fact means LoadString(IDS_MYMUSIC)) + */ +static void _SHCreateSymbolicLinks(void) +{ + static const UINT aidsMyStuff[] = { + IDS_MYPICTURES, IDS_MYVIDEOS, IDS_MYMUSIC, IDS_DOWNLOADS, IDS_TEMPLATES + }; + static const WCHAR * const MyOSXStuffW[] = { + PicturesW, MoviesW, MusicW, DownloadsW, TemplatesW + }; + static const int acsidlMyStuff[] = { + CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES + }; + static const char * const xdg_dirs[] = { + "PICTURES", "VIDEOS", "MUSIC", "DOWNLOAD", "TEMPLATES", "DESKTOP" + }; + static const unsigned int num = ARRAY_SIZE(xdg_dirs); + char szPersonalTarget[FILENAME_MAX], *pszPersonal; + char szMyStuffTarget[FILENAME_MAX], *pszMyStuff; + char szDesktopTarget[FILENAME_MAX], *pszDesktop; + struct stat statFolder; + const char *pszHome; + char ** xdg_results; + char * xdg_desktop_dir; + UINT i; + + _SHCreateMyDocumentsSymbolicLink(aidsMyStuff, ARRAY_SIZE(aidsMyStuff)); + + /* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */ + pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_CREATE); + if (!pszPersonal) return; + + strcpy(szPersonalTarget, pszPersonal); + if (!stat(pszPersonal, &statFolder) && S_ISLNK(statFolder.st_mode)) + { + int cLen = readlink(pszPersonal, szPersonalTarget, FILENAME_MAX-1); + if (cLen >= 0) szPersonalTarget[cLen] = '\0'; + } + + _SHGetXDGUserDirs(xdg_dirs, num, &xdg_results); + + pszHome = getenv("HOME"); + /* Create symbolic links for 'My Pictures', 'My Videos', 'My Music' etc. */ for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) {