Module: wine
Branch: master
Commit: 2aad95254c19df21fc0f7c4413ca3874c8d87997
URL: https://source.winehq.org/git/wine.git/?a=commit;h=2aad95254c19df21fc0f7c44…
Author: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Date: Wed Feb 19 00:16:44 2020 +0100
shell32: Create user folder symlinks on lookup and only if it's missing.
Change the logic so that when a user folder already exists in the
prefix, as a real directory or symbolic link, it's left as-is. Also
create a symbolic link, instead of a real directory, when looking up a
user folder that is currently missing.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22974
Signed-off-by: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/shell32/shellpath.c | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index d32529bae3..71267ecf58 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -4116,8 +4116,8 @@ static void _SHCreateMyDocumentsSymbolicLink(const UINT * aidsMyStuff, const UIN
const char *pszHome;
char ** xdg_results;
- /* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */
- pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_CREATE);
+ /* Get the unix path of 'My Documents'. */
+ pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_DONT_VERIFY);
if (!pszPersonal) return;
_SHGetXDGUserDirs(xdg_dirs, num, &xdg_results);
@@ -4161,8 +4161,8 @@ static void _SHCreateMyDocumentsSymbolicLink(const UINT * aidsMyStuff, const UIN
break;
}
- /* Replace 'My Documents' directory with a symlink or fail silently if not empty. */
- remove(pszPersonal);
+ /* Create symbolic link to 'My Documents' or fail silently if a directory
+ * or symlink exists. */
symlink(szPersonalTarget, pszPersonal);
}
else
@@ -4233,8 +4233,8 @@ static void _SHCreateMyStuffSymbolicLink(int nFolder)
while (1)
{
- /* Create the current 'My Whatever' folder and get its unix path. */
- pszMyStuff = _SHGetFolderUnixPath(acsidlMyStuff[i]|CSIDL_FLAG_CREATE);
+ /* Get the current 'My Whatever' folder unix path. */
+ pszMyStuff = _SHGetFolderUnixPath(acsidlMyStuff[i]|CSIDL_FLAG_DONT_VERIFY);
if (!pszMyStuff) break;
while (1)
@@ -4266,7 +4266,6 @@ static void _SHCreateMyStuffSymbolicLink(int nFolder)
strcpy(szMyStuffTarget, szPersonalTarget);
break;
}
- remove(pszMyStuff);
symlink(szMyStuffTarget, pszMyStuff);
heap_free(pszMyStuff);
break;
@@ -4311,10 +4310,9 @@ static void _SHCreateDesktopSymbolicLink(void)
(_SHAppendToUnixPath(szDesktopTarget, DesktopW) &&
!stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode)))
{
- pszDesktop = _SHGetFolderUnixPath(CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE);
+ pszDesktop = _SHGetFolderUnixPath(CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_DONT_VERIFY);
if (pszDesktop)
{
- remove(pszDesktop);
if (xdg_desktop_dir)
symlink(xdg_desktop_dir, pszDesktop);
else
@@ -4599,6 +4597,10 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW(
goto end;
}
+ /* create symbolic links rather than directories for specific
+ * user shell folders */
+ _SHCreateSymbolicLink(folder);
+
/* create directory/directories */
ret = SHCreateDirectoryExW(hwndOwner, szBuildPath, NULL);
if (ret && ret != ERROR_ALREADY_EXISTS)
@@ -5232,6 +5234,10 @@ HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE t
goto failed;
}
+ /* create symbolic links rather than directories for specific
+ * user shell folders */
+ _SHCreateSymbolicLink(folder);
+
/* create directory/directories */
ret = SHCreateDirectoryExW(NULL, pathW, NULL);
if (ret && ret != ERROR_ALREADY_EXISTS)
Module: wine
Branch: master
Commit: 60915a5544def2dd224bdd3e1d34fbfb0161a8e6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=60915a5544def2dd224bdd3e…
Author: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Date: Wed Feb 19 00:16:42 2020 +0100
shell32: Move 'Desktop' symbolic link creation to a separate function.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22974
Signed-off-by: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/shell32/shellpath.c | 84 +++++++++++++++++++++++++++---------------------
1 file changed, 48 insertions(+), 36 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index e9835dbe03..2012ecbe35 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -4276,36 +4276,13 @@ static void _SHCreateMyStuffSymbolicLink(int nFolder)
}
/******************************************************************************
- * _SHCreateSymbolicLinks [Internal]
+ * _SHCreateDesktopSymbolicLink [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 'Desktop' shell folder to point into the
+ * users home directory.
*/
-static void _SHCreateSymbolicLinks(void)
+static void _SHCreateDesktopSymbolicLink(void)
{
- static const UINT aidsMyStuff[] = {
- IDS_MYPICTURES, IDS_MYVIDEOS, IDS_MYMUSIC, IDS_DOWNLOADS, IDS_TEMPLATES
- };
- static const int acsidlMyStuff[] = {
- CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES
- };
static const char * const xdg_dirs[] = { "DESKTOP" };
static const unsigned int num = ARRAY_SIZE(xdg_dirs);
char *pszPersonal;
@@ -4314,13 +4291,6 @@ static void _SHCreateSymbolicLinks(void)
const char *pszHome;
char ** xdg_results;
char * xdg_desktop_dir;
- UINT i;
-
- _SHCreateMyDocumentsSymbolicLink(aidsMyStuff, ARRAY_SIZE(aidsMyStuff));
-
- /* Create symbolic links for 'My Pictures', 'My Videos', 'My Music' etc. */
- for (i=0; i < ARRAY_SIZE(acsidlMyStuff); i++)
- _SHCreateMyStuffSymbolicLink(acsidlMyStuff[i]);
/* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */
pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_CREATE);
@@ -4330,14 +4300,13 @@ static void _SHCreateSymbolicLinks(void)
pszHome = getenv("HOME");
- /* Last but not least, the Desktop folder */
if (pszHome)
strcpy(szDesktopTarget, pszHome);
else
strcpy(szDesktopTarget, pszPersonal);
heap_free(pszPersonal);
- xdg_desktop_dir = xdg_results ? xdg_results[num - 1] : NULL;
+ xdg_desktop_dir = xdg_results ? xdg_results[0] : NULL;
if (xdg_desktop_dir ||
(_SHAppendToUnixPath(szDesktopTarget, DesktopW) &&
!stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode)))
@@ -4357,6 +4326,49 @@ static void _SHCreateSymbolicLinks(void)
_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 int acsidlMyStuff[] = {
+ CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES
+ };
+ UINT i;
+
+ _SHCreateMyDocumentsSymbolicLink(aidsMyStuff, ARRAY_SIZE(aidsMyStuff));
+
+ /* Create symbolic links for 'My Pictures', 'My Videos', 'My Music' etc. */
+ for (i=0; i < ARRAY_SIZE(acsidlMyStuff); i++)
+ _SHCreateMyStuffSymbolicLink(acsidlMyStuff[i]);
+
+ /* Last but not least, the Desktop folder */
+ _SHCreateDesktopSymbolicLink();
+}
+
/******************************************************************************
* SHGetFolderPathW [SHELL32.@]
*
Module: wine
Branch: master
Commit: c6d8f1ac28e2cf3d703acd6d0a8f76289cf20adb
URL: https://source.winehq.org/git/wine.git/?a=commit;h=c6d8f1ac28e2cf3d703acd6d…
Author: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Date: Wed Feb 19 00:16:41 2020 +0100
shell32: Move 'My Stuff' symbolic link creation in a separate generic function.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22974
Signed-off-by: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
dlls/shell32/shellpath.c | 101 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 73 insertions(+), 28 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index f790afa2df..e9835dbe03 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -4181,29 +4181,15 @@ static void _SHCreateMyDocumentsSymbolicLink(const UINT * aidsMyStuff, const UIN
}
/******************************************************************************
- * _SHCreateSymbolicLinks [Internal]
+ * _SHCreateMyStuffSymbolicLink [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 one of the 'My Whatever' shell folders to point
+ * into the users home directory.
+ *
+ * PARAMS
+ * nFolder [I] CSIDL identifying the folder.
*/
-static void _SHCreateSymbolicLinks(void)
+static void _SHCreateMyStuffSymbolicLink(int nFolder)
{
static const UINT aidsMyStuff[] = {
IDS_MYPICTURES, IDS_MYVIDEOS, IDS_MYMUSIC, IDS_DOWNLOADS, IDS_TEMPLATES
@@ -4215,19 +4201,19 @@ static void _SHCreateSymbolicLinks(void)
CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES
};
static const char * const xdg_dirs[] = {
- "PICTURES", "VIDEOS", "MUSIC", "DOWNLOAD", "TEMPLATES", "DESKTOP"
+ "PICTURES", "VIDEOS", "MUSIC", "DOWNLOAD", "TEMPLATES"
};
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;
+ DWORD folder = nFolder & CSIDL_FOLDER_MASK;
UINT i;
- _SHCreateMyDocumentsSymbolicLink(aidsMyStuff, ARRAY_SIZE(aidsMyStuff));
+ for (i = 0; i < ARRAY_SIZE(acsidlMyStuff) && acsidlMyStuff[i] != folder; i++);
+ if (i >= ARRAY_SIZE(acsidlMyStuff)) return;
/* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */
pszPersonal = _SHGetFolderUnixPath(CSIDL_PERSONAL|CSIDL_FLAG_CREATE);
@@ -4239,17 +4225,17 @@ static void _SHCreateSymbolicLinks(void)
int cLen = readlink(pszPersonal, szPersonalTarget, FILENAME_MAX-1);
if (cLen >= 0) szPersonalTarget[cLen] = '\0';
}
+ heap_free(pszPersonal);
_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++)
+ while (1)
{
/* Create the current 'My Whatever' folder and get its unix path. */
pszMyStuff = _SHGetFolderUnixPath(acsidlMyStuff[i]|CSIDL_FLAG_CREATE);
- if (!pszMyStuff) continue;
+ if (!pszMyStuff) break;
while (1)
{
@@ -4283,8 +4269,67 @@ static void _SHCreateSymbolicLinks(void)
remove(pszMyStuff);
symlink(szMyStuffTarget, pszMyStuff);
heap_free(pszMyStuff);
+ break;
}
+ _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 int acsidlMyStuff[] = {
+ CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC, CSIDL_DOWNLOADS, CSIDL_TEMPLATES
+ };
+ static const char * const xdg_dirs[] = { "DESKTOP" };
+ static const unsigned int num = ARRAY_SIZE(xdg_dirs);
+ char *pszPersonal;
+ 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 symbolic links for 'My Pictures', 'My Videos', 'My Music' etc. */
+ for (i=0; i < ARRAY_SIZE(acsidlMyStuff); i++)
+ _SHCreateMyStuffSymbolicLink(acsidlMyStuff[i]);
+
+ /* 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;
+
+ _SHGetXDGUserDirs(xdg_dirs, num, &xdg_results);
+
+ pszHome = getenv("HOME");
+
/* Last but not least, the Desktop folder */
if (pszHome)
strcpy(szDesktopTarget, pszHome);
Module: wine
Branch: master
Commit: fe89ae49659292a39c38363a64e44e0dd4aadb43
URL: https://source.winehq.org/git/wine.git/?a=commit;h=fe89ae49659292a39c38363a…
Author: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Date: Wed Feb 19 00:16:40 2020 +0100
shell32: Move 'My Documents' symbolic link creation in a separate function.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=22974
Signed-off-by: Olivier F. R. Dierick <o.dierick(a)piezo-forte.be>
Signed-off-by: Alexandre Julliard <julliard(a)winehq.org>
---
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 428b3be24f..f790afa2df 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++)
{