XDG_UserDirLookup() will return a NULL result for any XDG directory path that is not a valid directory or is a broken symlinked directory path. So we can remove a redundant test, that ensures the returned XDG_DOCUMENTS_DIR path is a valid directory. Tidy up the inline code comments, removing some that are unnecessary.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index de4bf7d566..0d8a5987d7 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4424,7 +4424,7 @@ static void _SHCreateSymbolicLinks(void) char ** xdg_results; char * xdg_desktop_dir;
- /* Create all necessary profile sub-dirs up to 'My Documents' and get the unix path. */ + /* Create the '%USERPROFILE%\My Documents' directory path. */ hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (FAILED(hr)) return; @@ -4439,7 +4439,7 @@ static void _SHCreateSymbolicLinks(void) { while (1) { - /* Check if there's already a Wine-specific 'My Documents' folder */ + /* Try to target a pre-existing '$HOME/My Documents' folder. */ strcpy(szPersonalTarget, pszHome); if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) @@ -4457,28 +4457,23 @@ static void _SHCreateSymbolicLinks(void) break; }
- /* Try to point to the XDG Documents folder */ - if (xdg_results && xdg_results[num-2] && - !stat(xdg_results[num-2], &statFolder) && - S_ISDIR(statFolder.st_mode)) + /* Try to target the XDG_DOCUMENTS_DIR folder. */ + if (xdg_results && xdg_results[num-2]) { strcpy(szPersonalTarget, xdg_results[num-2]); break; }
- /* Or the hardcoded / OS X Documents folder */ + /* Try to target the hardcoded / OS X 'Documents' folder. */ strcpy(szPersonalTarget, pszHome); if (_SHAppendToUnixPath(szPersonalTarget, DocumentsW) && - !stat(szPersonalTarget, &statFolder) && - S_ISDIR(statFolder.st_mode)) + !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) break;
- /* As a last resort point to $HOME. */ + /* Target the '$HOME' folder directly (fallback). */ strcpy(szPersonalTarget, pszHome); break; } - - /* Replace 'My Documents' directory with a symlink or fail silently if not empty. */ remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } @@ -4498,30 +4493,30 @@ static void _SHCreateSymbolicLinks(void) /* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */ for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) { - /* Create the current 'My Whatever' folder and get its unix path. */ + /* Create the '%USERPROFILE%\My XXX' directory path. */ hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (FAILED(hr)) continue;
pszMyStuff = wine_get_unix_file_name(wszTempPath); if (!pszMyStuff) continue; - + while (1) { - /* Check for the Wine-specific '$HOME/My Documents' subfolder */ + /* Try to target a pre-existing '$HOME/My Documents/My XXX' folder. */ strcpy(szMyStuffTarget, szPersonalTarget); if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) break;
- /* Try the XDG_XXX_DIR folder */ + /* Try to target the XDG_XXX_DIR folder. */ if (xdg_results && xdg_results[i]) { strcpy(szMyStuffTarget, xdg_results[i]); break; }
- /* Or the OS X folder (these are never localized) */ + /* Try to target the hardcoded / OS X 'XXX' folder. */ if (pszHome) { strcpy(szMyStuffTarget, pszHome); @@ -4531,7 +4526,7 @@ static void _SHCreateSymbolicLinks(void) break; }
- /* As a last resort point to the same location as 'My Documents' */ + /* Use the same target as '%USERPROFILE%\My Documents' (fallback). */ strcpy(szMyStuffTarget, szPersonalTarget); break; } @@ -4540,7 +4535,7 @@ static void _SHCreateSymbolicLinks(void) heap_free(pszMyStuff); }
- /* Last but not least, the Desktop folder */ + /* Create a symbolic link for the 'Desktop' folder. */ if (pszHome) strcpy(szDesktopTarget, pszHome); else @@ -4552,6 +4547,7 @@ static void _SHCreateSymbolicLinks(void) (_SHAppendToUnixPath(szDesktopTarget, DesktopW) && !stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode))) { + /* Get the '%USERPROFILE%\Desktop' directory path. */ hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (SUCCEEDED(hr) && (pszDesktop = wine_get_unix_file_name(wszTempPath))) @@ -4565,7 +4561,6 @@ static void _SHCreateSymbolicLinks(void) } }
- /* Free resources allocated by XDG_UserDirLookup() */ if (xdg_results) { for (i = 0; i < num; i++)
Remove loops to create 'My Pictures', 'My Videos' and 'My Music' subdirectories in the '%USERPROFILE%\My Documents' directory. Flatten User Profile media profile directory symlink targets, so they are direct subdirectories of $HOME. If $HOME is not set, do not create any external symlinks for the User Profile media directories (it's not clear what the use case is for supporting an XDG_XXX_DIR, without $HOME set).
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 45 +++++++++------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 0d8a5987d7..ee5274b5fc 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4435,7 +4435,10 @@ static void _SHCreateSymbolicLinks(void) if (FAILED(hr)) xdg_results = NULL;
pszHome = getenv("HOME"); - if (pszHome && !stat(pszHome, &statFolder) && S_ISDIR(statFolder.st_mode)) + if (!(pszHome && !stat(pszHome, &statFolder) && S_ISDIR(statFolder.st_mode))) + pszHome = NULL; + + if (pszHome) { while (1) { @@ -4443,19 +4446,7 @@ static void _SHCreateSymbolicLinks(void) strcpy(szPersonalTarget, pszHome); if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - { - /* '$HOME/My Documents' exists. Create 'My Pictures', - * 'My Videos' and 'My Music' subfolders or fail silently if - * they already exist. - */ - for (i = 0; i < ARRAY_SIZE(aidsMyStuff); i++) - { - strcpy(szMyStuffTarget, szPersonalTarget); - if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i]))) - mkdir(szMyStuffTarget, 0777); - } break; - }
/* Try to target the XDG_DOCUMENTS_DIR folder. */ if (xdg_results && xdg_results[num-2]) @@ -4477,18 +4468,6 @@ static void _SHCreateSymbolicLinks(void) remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } - else - { - /* '$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; - strcpy(szPersonalTarget, pszPersonal); - for (i = 0; i < ARRAY_SIZE(aidsMyStuff); i++) { - strcpy(szMyStuffTarget, szPersonalTarget); - if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i]))) - mkdir(szMyStuffTarget, 0777); - } - }
/* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */ for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) @@ -4496,7 +4475,7 @@ static void _SHCreateSymbolicLinks(void) /* Create the '%USERPROFILE%\My XXX' directory path. */ hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (FAILED(hr)) continue; + if (FAILED(hr) || !pszHome) continue;
pszMyStuff = wine_get_unix_file_name(wszTempPath); if (!pszMyStuff) continue; @@ -4504,7 +4483,7 @@ static void _SHCreateSymbolicLinks(void) while (1) { /* Try to target a pre-existing '$HOME/My Documents/My XXX' folder. */ - strcpy(szMyStuffTarget, szPersonalTarget); + strcpy(szMyStuffTarget, pszHome); if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) break; @@ -4517,14 +4496,10 @@ static void _SHCreateSymbolicLinks(void) }
/* Try to target the hardcoded / OS X 'XXX' folder. */ - if (pszHome) - { - strcpy(szMyStuffTarget, pszHome); - if (_SHAppendToUnixPath(szMyStuffTarget, MyOSXStuffW[i]) && - !stat(szMyStuffTarget, &statFolder) && - S_ISDIR(statFolder.st_mode)) - break; - } + strcpy(szMyStuffTarget, pszHome); + if (_SHAppendToUnixPath(szMyStuffTarget, MyOSXStuffW[i]) && + !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) + break;
/* Use the same target as '%USERPROFILE%\My Documents' (fallback). */ strcpy(szMyStuffTarget, szPersonalTarget);
Cleanup code to avoid the use of an infinite while loop, as a pseudo code subblock demarker (which is not very readable).
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 91 +++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 42 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index ee5274b5fc..b223bf5212 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4421,6 +4421,7 @@ static void _SHCreateSymbolicLinks(void) struct stat statFolder; const char *pszHome; HRESULT hr; + BOOL target_ok; char ** xdg_results; char * xdg_desktop_dir;
@@ -4440,31 +4441,34 @@ static void _SHCreateSymbolicLinks(void)
if (pszHome) { - while (1) + target_ok = FALSE; + + /* Try to target a pre-existing '$HOME/My Documents' folder. */ + strcpy(szPersonalTarget, pszHome); + if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && + !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) + { + target_ok = TRUE; + } + /* Try to target the XDG_DOCUMENTS_DIR folder. */ + else if (xdg_results && xdg_results[num-2]) + { + strcpy(szPersonalTarget, xdg_results[num-2]); + target_ok = TRUE; + } + /* Try to target the hardcoded / OS X 'Documents' folder. */ + else { - /* Try to target a pre-existing '$HOME/My Documents' folder. */ strcpy(szPersonalTarget, pszHome); - if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && - !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - break; - - /* Try to target the XDG_DOCUMENTS_DIR folder. */ - if (xdg_results && xdg_results[num-2]) - { - strcpy(szPersonalTarget, xdg_results[num-2]); - break; - } + target_ok = _SHAppendToUnixPath(szPersonalTarget, DocumentsW) + && !stat(szPersonalTarget, &statFolder) + && S_ISDIR(statFolder.st_mode); + }
- /* Try to target the hardcoded / OS X 'Documents' folder. */ + /* Target the '$HOME' folder directly (fallback). */ + if (!target_ok) strcpy(szPersonalTarget, pszHome); - if (_SHAppendToUnixPath(szPersonalTarget, DocumentsW) && - !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - break;
- /* Target the '$HOME' folder directly (fallback). */ - strcpy(szPersonalTarget, pszHome); - break; - } remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } @@ -4478,33 +4482,36 @@ static void _SHCreateSymbolicLinks(void) if (FAILED(hr) || !pszHome) continue;
pszMyStuff = wine_get_unix_file_name(wszTempPath); - if (!pszMyStuff) continue; - - while (1) - { - /* Try to target a pre-existing '$HOME/My Documents/My XXX' folder. */ - strcpy(szMyStuffTarget, pszHome); - if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && - !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - break; + if (!pszMyStuff) continue;
- /* Try to target the XDG_XXX_DIR folder. */ - if (xdg_results && xdg_results[i]) - { - strcpy(szMyStuffTarget, xdg_results[i]); - break; - } + target_ok = FALSE;
- /* Try to target the hardcoded / OS X 'XXX' folder. */ + /* Try to target a pre-existing '$HOME/My Documents/My XXX' folder. */ + strcpy(szMyStuffTarget, pszHome); + if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && + !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) + { + target_ok = TRUE; + } + /* Try to target the XDG_XXX_DIR folder. */ + else if (xdg_results && xdg_results[i]) + { + strcpy(szMyStuffTarget, xdg_results[i]); + target_ok = TRUE; + } + /* Try to target the hardcoded / OS X 'XXX' folder. */ + else + { strcpy(szMyStuffTarget, pszHome); - if (_SHAppendToUnixPath(szMyStuffTarget, MyOSXStuffW[i]) && - !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - break; + target_ok = _SHAppendToUnixPath(szMyStuffTarget, MyOSXStuffW[i]) + && !stat(szMyStuffTarget, &statFolder) + && S_ISDIR(statFolder.st_mode); + }
- /* Use the same target as '%USERPROFILE%\My Documents' (fallback). */ + /* Use the same target as '%USERPROFILE%\My Documents' (fallback). */ + if (!target_ok) strcpy(szMyStuffTarget, szPersonalTarget); - break; - } + remove(pszMyStuff); symlink(szMyStuffTarget, pszMyStuff); heap_free(pszMyStuff);
Wineprefix User Profile media directories:
'%USERPROFILE%\My Music' '%USERPROFILE%\My Pictures' '%USERPROFILE%\My Videos'
use '$HOME/My Documents' as a fallback symlink target path. Remove this code path, as it serves no logical purpose.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index b223bf5212..0e2ee2e263 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4508,12 +4508,11 @@ static void _SHCreateSymbolicLinks(void) && S_ISDIR(statFolder.st_mode); }
- /* Use the same target as '%USERPROFILE%\My Documents' (fallback). */ - if (!target_ok) - strcpy(szMyStuffTarget, szPersonalTarget); - - remove(pszMyStuff); - symlink(szMyStuffTarget, pszMyStuff); + if (target_ok) + { + remove(pszMyStuff); + symlink(szMyStuffTarget, pszMyStuff); + } heap_free(pszMyStuff); }
Remove the code path which falls back to symlinking User Profile media directories to the user's $HOME directory. End users will not appreciate having their $HOME directory (potentially) filled up with Windows-related files / directories. Remove unnecessary code comment, about directory removal.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 0e2ee2e263..cf4d9ffbd0 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4465,12 +4465,11 @@ static void _SHCreateSymbolicLinks(void) && S_ISDIR(statFolder.st_mode); }
- /* Target the '$HOME' folder directly (fallback). */ - if (!target_ok) - strcpy(szPersonalTarget, pszHome); - - remove(pszPersonal); - symlink(szPersonalTarget, pszPersonal); + if (target_ok) + { + remove(pszPersonal); + symlink(szPersonalTarget, pszPersonal); + } }
/* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */
The fall-back target path, 'pszPersonal' (base)+'DesktopW' (offset), will point to:
'%USERPROFILE%\Documents\Desktop'
Wine does not create this directory. So this code path is clearly invalid, as this symlink will never be created. Refactor this block to make it consistent with the other 2 (preceding) blocks.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 48 ++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 19 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index cf4d9ffbd0..faa8c892e9 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4423,7 +4423,6 @@ static void _SHCreateSymbolicLinks(void) HRESULT hr; BOOL target_ok; char ** xdg_results; - char * xdg_desktop_dir;
/* Create the '%USERPROFILE%\My Documents' directory path. */ hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, @@ -4470,6 +4469,8 @@ static void _SHCreateSymbolicLinks(void) remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } + + heap_free(pszPersonal); }
/* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */ @@ -4515,28 +4516,37 @@ static void _SHCreateSymbolicLinks(void) heap_free(pszMyStuff); }
- /* Create a symbolic link for 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; - if (xdg_desktop_dir || - (_SHAppendToUnixPath(szDesktopTarget, DesktopW) && - !stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode))) - { - /* Get the '%USERPROFILE%\Desktop' directory path. */ - hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, + /* Get the '%USERPROFILE%\Desktop' directory path. */ + hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (SUCCEEDED(hr) && (pszDesktop = wine_get_unix_file_name(wszTempPath))) + if (SUCCEEDED(hr) && pszHome) + { + /* Create a symbolic link for the 'Desktop' folder. */ + pszDesktop = wine_get_unix_file_name(wszTempPath); + if (pszDesktop) { - remove(pszDesktop); - if (xdg_desktop_dir) - symlink(xdg_desktop_dir, pszDesktop); + strcpy(szDesktopTarget, pszHome); + i = num - 1; + /* Try to target the XDG_DESKTOP_DIR folder. */ + if (xdg_results && xdg_results[i]) + { + strcpy(szDesktopTarget, xdg_results[i]); + target_ok = TRUE; + } + /* Try to target the hardcoded / OS X 'Desktop' folder. */ else + { + strcpy(szDesktopTarget, pszHome); + target_ok = _SHAppendToUnixPath(szDesktopTarget, DesktopW) + && !stat(szDesktopTarget, &statFolder) + && S_ISDIR(statFolder.st_mode); + } + + if (target_ok) + { + remove(pszDesktop); symlink(szDesktopTarget, pszDesktop); + } heap_free(pszDesktop); } }
Move creation of the 5 User Profile directories:
'%USERPROFILE%\My Documents' '%USERPROFILE%\My Music' '%USERPROFILE%\My Pictures' '%USERPROFILE%\My Videos' '%USERPROFILE%\Desktop'
into a single unified loop. This improves code readability and reduces code length / complexity. Make the arrays, of encoded directory designators, use a consistent ordering. Reword inline code comments as necessary to be consistent with new code structure.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 109 +++++++-------------------------------- 1 file changed, 18 insertions(+), 91 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index faa8c892e9..ce8af7760c 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4409,27 +4409,20 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) { */ static void _SHCreateSymbolicLinks(void) { - UINT aidsMyStuff[] = { IDS_MYPICTURES, IDS_MYVIDEOS, IDS_MYMUSIC }, i; - const WCHAR* MyOSXStuffW[] = { PicturesW, MoviesW, MusicW }; - int acsidlMyStuff[] = { CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_MYMUSIC }; - static const char * const xdg_dirs[] = { "PICTURES", "VIDEOS", "MUSIC", "DOCUMENTS", "DESKTOP" }; + UINT aidsMyStuff[] = { IDS_PERSONAL, IDS_MYMUSIC, IDS_MYPICTURES, IDS_MYVIDEOS, IDS_DESKTOPDIRECTORY }; + const WCHAR* MyOSXStuffW[] = { DocumentsW, MusicW, PicturesW, MoviesW, DesktopW }; + int acsidlMyStuff[] = { CSIDL_PERSONAL, CSIDL_MYMUSIC, CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_DESKTOPDIRECTORY }; + static const char * const xdg_dirs[] = { "DOCUMENTS", "MUSIC", "PICTURES", "VIDEOS", "DESKTOP" }; static const unsigned int num = ARRAY_SIZE(xdg_dirs); WCHAR wszTempPath[MAX_PATH]; - char szPersonalTarget[FILENAME_MAX], *pszPersonal; char szMyStuffTarget[FILENAME_MAX], *pszMyStuff; - char szDesktopTarget[FILENAME_MAX], *pszDesktop; struct stat statFolder; const char *pszHome; HRESULT hr; BOOL target_ok; char ** xdg_results; - - /* Create the '%USERPROFILE%\My Documents' directory path. */ - hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, - SHGFP_TYPE_DEFAULT, wszTempPath); - if (FAILED(hr)) return; - pszPersonal = wine_get_unix_file_name(wszTempPath); - if (!pszPersonal) return; + int ret; + UINT i;
hr = XDG_UserDirLookup(xdg_dirs, num, &xdg_results); if (FAILED(hr)) xdg_results = NULL; @@ -4438,45 +4431,9 @@ static void _SHCreateSymbolicLinks(void) if (!(pszHome && !stat(pszHome, &statFolder) && S_ISDIR(statFolder.st_mode))) pszHome = NULL;
- if (pszHome) + for (i = 0; i < num; ++i) { - target_ok = FALSE; - - /* Try to target a pre-existing '$HOME/My Documents' folder. */ - strcpy(szPersonalTarget, pszHome); - if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && - !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) - { - target_ok = TRUE; - } - /* Try to target the XDG_DOCUMENTS_DIR folder. */ - else if (xdg_results && xdg_results[num-2]) - { - strcpy(szPersonalTarget, xdg_results[num-2]); - target_ok = TRUE; - } - /* Try to target the hardcoded / OS X 'Documents' folder. */ - else - { - strcpy(szPersonalTarget, pszHome); - target_ok = _SHAppendToUnixPath(szPersonalTarget, DocumentsW) - && !stat(szPersonalTarget, &statFolder) - && S_ISDIR(statFolder.st_mode); - } - - if (target_ok) - { - remove(pszPersonal); - symlink(szPersonalTarget, pszPersonal); - } - - heap_free(pszPersonal); - } - - /* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */ - for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) - { - /* Create the '%USERPROFILE%\My XXX' directory path. */ + /* Create the '%USERPROFILE%\XXX' directory path. */ hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (FAILED(hr) || !pszHome) continue; @@ -4485,10 +4442,10 @@ static void _SHCreateSymbolicLinks(void) if (!pszMyStuff) continue;
target_ok = FALSE; - - /* Try to target a pre-existing '$HOME/My Documents/My XXX' folder. */ + /* Try to target a pre-existing '$HOME/My XXX' folder. */ strcpy(szMyStuffTarget, pszHome); - if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && + if ((aidsMyStuff[i] != IDS_DESKTOPDIRECTORY) && + _SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) { target_ok = TRUE; @@ -4510,47 +4467,17 @@ static void _SHCreateSymbolicLinks(void)
if (target_ok) { - remove(pszMyStuff); - symlink(szMyStuffTarget, pszMyStuff); + ret = remove(pszMyStuff); + TRACE("remove directory (%s): %s\n", + (ret ? "soft failed" : "OK"), debugstr_a(pszMyStuff)); + ret = symlink(szMyStuffTarget, pszMyStuff); + TRACE("symlink directory (%s): %s -> %s\n", + (ret ? "soft failed" : "OK"), + debugstr_a(pszMyStuff), debugstr_a(szMyStuffTarget)); } heap_free(pszMyStuff); }
- /* Get the '%USERPROFILE%\Desktop' directory path. */ - hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, - SHGFP_TYPE_DEFAULT, wszTempPath); - if (SUCCEEDED(hr) && pszHome) - { - /* Create a symbolic link for the 'Desktop' folder. */ - pszDesktop = wine_get_unix_file_name(wszTempPath); - if (pszDesktop) - { - strcpy(szDesktopTarget, pszHome); - i = num - 1; - /* Try to target the XDG_DESKTOP_DIR folder. */ - if (xdg_results && xdg_results[i]) - { - strcpy(szDesktopTarget, xdg_results[i]); - target_ok = TRUE; - } - /* Try to target the hardcoded / OS X 'Desktop' folder. */ - else - { - strcpy(szDesktopTarget, pszHome); - target_ok = _SHAppendToUnixPath(szDesktopTarget, DesktopW) - && !stat(szDesktopTarget, &statFolder) - && S_ISDIR(statFolder.st_mode); - } - - if (target_ok) - { - remove(pszDesktop); - symlink(szDesktopTarget, pszDesktop); - } - heap_free(pszDesktop); - } - } - if (xdg_results) { for (i = 0; i < num; i++)
Migrate all remaining _SHCreateSymbolicLinks() Camel Case variables to snake case. Also rename variables that are currently named in a rather "obtuse" fashion. Remove array size variable, which has no readability or performance advantage over using the ARRAY_SIZE macro. Make all loops pre-increment.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 75 ++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 38 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index ce8af7760c..d7ddfaf26d 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4409,80 +4409,79 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) { */ static void _SHCreateSymbolicLinks(void) { - UINT aidsMyStuff[] = { IDS_PERSONAL, IDS_MYMUSIC, IDS_MYPICTURES, IDS_MYVIDEOS, IDS_DESKTOPDIRECTORY }; - const WCHAR* MyOSXStuffW[] = { DocumentsW, MusicW, PicturesW, MoviesW, DesktopW }; - int acsidlMyStuff[] = { CSIDL_PERSONAL, CSIDL_MYMUSIC, CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_DESKTOPDIRECTORY }; - static const char * const xdg_dirs[] = { "DOCUMENTS", "MUSIC", "PICTURES", "VIDEOS", "DESKTOP" }; - static const unsigned int num = ARRAY_SIZE(xdg_dirs); + UINT ids_dirs[] = { IDS_PERSONAL, IDS_MYMUSIC, IDS_MYPICTURES, IDS_MYVIDEOS, IDS_DESKTOPDIRECTORY }; + const WCHAR* ws_osx_dirs[] = { DocumentsW, MusicW, PicturesW, MoviesW, DesktopW }; + int csidl_dirs[] = { CSIDL_PERSONAL, CSIDL_MYMUSIC, CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_DESKTOPDIRECTORY }; + static const char * const xdg_dirnames[] = { "DOCUMENTS", "MUSIC", "PICTURES", "VIDEOS", "DESKTOP" }; WCHAR wszTempPath[MAX_PATH]; - char szMyStuffTarget[FILENAME_MAX], *pszMyStuff; - struct stat statFolder; - const char *pszHome; + char home_target_dir[FILENAME_MAX], *prefix_profile_dir; + struct stat stat_folder; + const char *env_homedir; HRESULT hr; BOOL target_ok; - char ** xdg_results; + char ** xdg_dirs; int ret; UINT i;
- hr = XDG_UserDirLookup(xdg_dirs, num, &xdg_results); - if (FAILED(hr)) xdg_results = NULL; + hr = XDG_UserDirLookup(xdg_dirnames, ARRAY_SIZE(xdg_dirnames), &xdg_dirs); + if (FAILED(hr)) xdg_dirs = NULL;
- pszHome = getenv("HOME"); - if (!(pszHome && !stat(pszHome, &statFolder) && S_ISDIR(statFolder.st_mode))) - pszHome = NULL; + env_homedir = getenv("HOME"); + if (!(env_homedir && !stat(env_homedir, &stat_folder) && S_ISDIR(stat_folder.st_mode))) + env_homedir = NULL;
- for (i = 0; i < num; ++i) + for (i = 0; i < ARRAY_SIZE(xdg_dirnames); ++i) { /* Create the '%USERPROFILE%\XXX' directory path. */ - hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE, NULL, + hr = SHGetFolderPathW(NULL, csidl_dirs[i]|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); - if (FAILED(hr) || !pszHome) continue; + if (FAILED(hr) || !env_homedir) continue;
- pszMyStuff = wine_get_unix_file_name(wszTempPath); - if (!pszMyStuff) continue; + prefix_profile_dir = wine_get_unix_file_name(wszTempPath); + if (!prefix_profile_dir) continue;
target_ok = FALSE; /* Try to target a pre-existing '$HOME/My XXX' folder. */ - strcpy(szMyStuffTarget, pszHome); - if ((aidsMyStuff[i] != IDS_DESKTOPDIRECTORY) && - _SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && - !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) + strcpy(home_target_dir, env_homedir); + if ((ids_dirs[i] != IDS_DESKTOPDIRECTORY) && + _SHAppendToUnixPath(home_target_dir, MAKEINTRESOURCEW(ids_dirs[i])) && + !stat(home_target_dir, &stat_folder) && S_ISDIR(stat_folder.st_mode)) { target_ok = TRUE; } /* Try to target the XDG_XXX_DIR folder. */ - else if (xdg_results && xdg_results[i]) + else if (xdg_dirs && xdg_dirs[i]) { - strcpy(szMyStuffTarget, xdg_results[i]); + strcpy(home_target_dir, xdg_dirs[i]); target_ok = TRUE; } /* Try to target the hardcoded / OS X 'XXX' folder. */ else { - strcpy(szMyStuffTarget, pszHome); - target_ok = _SHAppendToUnixPath(szMyStuffTarget, MyOSXStuffW[i]) - && !stat(szMyStuffTarget, &statFolder) - && S_ISDIR(statFolder.st_mode); + strcpy(home_target_dir, env_homedir); + target_ok = _SHAppendToUnixPath(home_target_dir, ws_osx_dirs[i]) + && !stat(home_target_dir, &stat_folder) + && S_ISDIR(stat_folder.st_mode); }
if (target_ok) { - ret = remove(pszMyStuff); + ret = remove(prefix_profile_dir); TRACE("remove directory (%s): %s\n", - (ret ? "soft failed" : "OK"), debugstr_a(pszMyStuff)); - ret = symlink(szMyStuffTarget, pszMyStuff); + (ret ? "soft failed" : "OK"), debugstr_a(prefix_profile_dir)); + ret = symlink(home_target_dir, prefix_profile_dir); TRACE("symlink directory (%s): %s -> %s\n", (ret ? "soft failed" : "OK"), - debugstr_a(pszMyStuff), debugstr_a(szMyStuffTarget)); + debugstr_a(prefix_profile_dir), debugstr_a(home_target_dir)); } - heap_free(pszMyStuff); + heap_free(prefix_profile_dir); }
- if (xdg_results) + if (xdg_dirs) { - for (i = 0; i < num; i++) - heap_free(xdg_results[i]); - heap_free(xdg_results); + for (i = 0; i < ARRAY_SIZE(xdg_dirnames); ++i) + heap_free(xdg_dirs[i]); + heap_free(xdg_dirs); } }
Windows Vista (and newer releases), default to a flat USER PROFILE model of the form:
Personal='%USERPROFILE%\Documents' My Music='%USERPROFILE%\Music' My Pictures='%USERPROFILE%\Pictures' My Videos='%USERPROFILE%\Videos'
Update _SHCreateSymbolicLinks() description (comment). Update SHELL_RegisterShellFolders() comment.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shell32.rc | 8 +++--- dlls/shell32/shellpath.c | 58 +++++++++++++++++++++------------------- 2 files changed, 35 insertions(+), 31 deletions(-)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc index 084b052978..b2f91df5ed 100644 --- a/dlls/shell32/shell32.rc +++ b/dlls/shell32/shell32.rc @@ -200,12 +200,12 @@ the folder?" /* shell folder path default values */ /* FIXME: Some will be unused until desktop.ini support is implemented */ IDS_PROGRAMS "Programs" - IDS_PERSONAL "My Documents" + IDS_PERSONAL "Documents" IDS_FAVORITES "Favorites" IDS_STARTUP "StartUp" IDS_STARTMENU "Start Menu" - IDS_MYMUSIC "My Music" - IDS_MYVIDEOS "My Videos" + IDS_MYMUSIC "Music" + IDS_MYVIDEOS "Videos" IDS_DESKTOPDIRECTORY "#msgctxt#directory#Desktop" IDS_NETHOOD "NetHood" IDS_TEMPLATES "Templates" @@ -213,7 +213,7 @@ the folder?" IDS_HISTORY "History" IDS_PROGRAM_FILES "Program Files" IDS_PROGRAM_FILESX86 "Program Files (x86)" - IDS_MYPICTURES "My Pictures" + IDS_MYPICTURES "Pictures" IDS_COMMON_FILES "Common Files" IDS_COMMON_DOCUMENTS "Documents" IDS_ADMINTOOLS "Administrative Tools" diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index d7ddfaf26d..5bf027f6f2 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4353,13 +4353,13 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) { lstrcpyW(wszSubPath, DocumentsW); break; case IDS_MYMUSIC: - lstrcpyW(wszSubPath, My_MusicW); + lstrcpyW(wszSubPath, MusicW); break; case IDS_MYPICTURES: - lstrcpyW(wszSubPath, My_PicturesW); + lstrcpyW(wszSubPath, PicturesW); break; case IDS_MYVIDEOS: - lstrcpyW(wszSubPath, My_VideosW); + lstrcpyW(wszSubPath, VideosW); break; default: ERR("LoadString(%d) failed!\n", LOWORD(pwszSubPath)); @@ -4386,26 +4386,21 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) {
/****************************************************************************** * _SHCreateSymbolicLinks [Internal] - * - * Sets up symbol links for various shell folders to point into the users 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 imply that the user - * is a Windows lover and has no problem with wine creating 'My Pictures', - * 'My Music' and 'My Videos' subfolders under '$HOME/My Documents', if those - * do not already exits. 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 fo 'My Pictures' and 'My Videos'. - * - 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)) + * + * Creates a set of symbolic links from the current Wineprefix to the current + * user $HOME subdirectory (if this is set in the shell env). + * + * For each User Profile directory XXX in + * 'Documents', 'Music', 'Pictures', 'Movies', 'Desktop': + * + * 1) Create the '%USERPROFILE%\XXX' User Profile directory + * (in the current Wineprefix). + * 2) Create a symbolic link from the '%USERPROFILE%\XXX' User Profile directory + * to: + * Resource ID 'XXX' - if '$HOME/XXX' exists then target this. + * XDG_XXX_DIR - if '$XDG_XXX_DIR' exists then target this. + * MacOS 'XXX' directory - if '$HOME/XXX' exists then target this. + * */ static void _SHCreateSymbolicLinks(void) { @@ -6041,10 +6036,19 @@ HRESULT SHELL_RegisterShellFolders(void) { HRESULT hr;
- /* Set up '$HOME' targeted symlinks for 'My Documents', 'My Pictures', - * 'My Videos', 'My Music' and 'Desktop' in advance, so that the - * _SHRegister*ShellFolders() functions will find everything nice and clean - * and thus will not attempt to create them in the profile directory. */ + /* Pre-create and setup '$HOME' subdirectory targeted symlinks for: + * + * '%USERPROFILE\Documents' + * '%USERPROFILE\Music' + * '%USERPROFILE\Pictures', + * '%USERPROFILE\Videos' + * '%USERPROFILE\Desktop' + * + * User Profile directories. + * + * These User Profile directories must pre-exist when calling the: + * _SHRegister*ShellFolders() functions. + */ _SHCreateSymbolicLinks();
hr = _SHRegisterUserShellFolders(TRUE);
With the change to the newer User Profile directory names, the code to match agains the legacy directory targets, of the form '$HOME/My XXX', can be removed. The newer Windows USERPROFILE directory names now mirror standard XDG directory names.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 5bf027f6f2..6c6d879cb6 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4397,14 +4397,12 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) { * (in the current Wineprefix). * 2) Create a symbolic link from the '%USERPROFILE%\XXX' User Profile directory * to: - * Resource ID 'XXX' - if '$HOME/XXX' exists then target this. * XDG_XXX_DIR - if '$XDG_XXX_DIR' exists then target this. * MacOS 'XXX' directory - if '$HOME/XXX' exists then target this. * */ static void _SHCreateSymbolicLinks(void) { - UINT ids_dirs[] = { IDS_PERSONAL, IDS_MYMUSIC, IDS_MYPICTURES, IDS_MYVIDEOS, IDS_DESKTOPDIRECTORY }; const WCHAR* ws_osx_dirs[] = { DocumentsW, MusicW, PicturesW, MoviesW, DesktopW }; int csidl_dirs[] = { CSIDL_PERSONAL, CSIDL_MYMUSIC, CSIDL_MYPICTURES, CSIDL_MYVIDEO, CSIDL_DESKTOPDIRECTORY }; static const char * const xdg_dirnames[] = { "DOCUMENTS", "MUSIC", "PICTURES", "VIDEOS", "DESKTOP" }; @@ -4436,16 +4434,8 @@ static void _SHCreateSymbolicLinks(void) if (!prefix_profile_dir) continue;
target_ok = FALSE; - /* Try to target a pre-existing '$HOME/My XXX' folder. */ - strcpy(home_target_dir, env_homedir); - if ((ids_dirs[i] != IDS_DESKTOPDIRECTORY) && - _SHAppendToUnixPath(home_target_dir, MAKEINTRESOURCEW(ids_dirs[i])) && - !stat(home_target_dir, &stat_folder) && S_ISDIR(stat_folder.st_mode)) - { - target_ok = TRUE; - } /* Try to target the XDG_XXX_DIR folder. */ - else if (xdg_dirs && xdg_dirs[i]) + if (xdg_dirs && xdg_dirs[i]) { strcpy(home_target_dir, xdg_dirs[i]); target_ok = TRUE;
The only call(s) to this function, with a Resource ID string, have been removed from _SHCreateSymbolicLinks(). So we can remove support for this. Correctly handle a zero length base path string (which would segfault the pre-existing implementation).
Signed-off-by: Rob Walker bob.mt.wya@gmail.com --- dlls/shell32/shellpath.c | 42 +++++++++------------------------------- 1 file changed, 9 insertions(+), 33 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index 6c6d879cb6..5b12080b4a 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4328,13 +4328,12 @@ static HRESULT _SHRegisterCommonShellFolders(void) /****************************************************************************** * _SHAppendToUnixPath [Internal] * - * Helper function for _SHCreateSymbolicLinks. Appends pwszSubPath (or the - * corresponding resource, if IS_INTRESOURCE) to the unix base path 'szBasePath' - * and replaces backslashes with slashes. + * Helper function for _SHCreateSymbolicLinks. Appends pwszSubPath to the Unix + * base path 'szBasePath' and replaces backslashes with slashes. * * PARAMS * szBasePath [IO] The unix base path, which will be appended to (CP_UNXICP). - * pwszSubPath [I] Sub-path or resource id (use MAKEINTRESOURCEW). + * pwszSubPath [I] Sub-path. * * RETURNS * Success: TRUE, @@ -4345,42 +4344,19 @@ static inline BOOL _SHAppendToUnixPath(char *szBasePath, LPCWSTR pwszSubPath) { int cLen = strlen(szBasePath); char *pBackslash;
- if (IS_INTRESOURCE(pwszSubPath)) { - if (!LoadStringW(shell32_hInstance, LOWORD(pwszSubPath), wszSubPath, MAX_PATH)) { - /* Fall back to hard coded defaults. */ - switch (LOWORD(pwszSubPath)) { - case IDS_PERSONAL: - lstrcpyW(wszSubPath, DocumentsW); - break; - case IDS_MYMUSIC: - lstrcpyW(wszSubPath, MusicW); - break; - case IDS_MYPICTURES: - lstrcpyW(wszSubPath, PicturesW); - break; - case IDS_MYVIDEOS: - lstrcpyW(wszSubPath, VideosW); - break; - default: - ERR("LoadString(%d) failed!\n", LOWORD(pwszSubPath)); - return FALSE; - } - } - } else { - lstrcpyW(wszSubPath, pwszSubPath); - } - - if (szBasePath[cLen-1] != '/') szBasePath[cLen++] = '/'; - + lstrcpyW(wszSubPath, pwszSubPath); + + if (!cLen || (szBasePath[cLen-1] != '/')) szBasePath[cLen++] = '/'; + if (!WideCharToMultiByte(CP_UNIXCP, 0, wszSubPath, -1, szBasePath + cLen, FILENAME_MAX - cLen, NULL, NULL)) { return FALSE; } - + pBackslash = szBasePath + cLen; while ((pBackslash = strchr(pBackslash, '\'))) *pBackslash = '/'; - + return TRUE; }
On 16 July 2018 at 23:46, Rob Walker bob.mt.wya@gmail.com wrote:
XDG_UserDirLookup() will return a NULL result for any XDG directory path that is not a valid directory or is a broken symlinked directory path. So we can remove a redundant test, that ensures the returned XDG_DOCUMENTS_DIR path is a valid directory. Tidy up the inline code comments, removing some that are unnecessary.
Signed-off-by: Rob Walker bob.mt.wya@gmail.com
dlls/shell32/shellpath.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c index de4bf7d566..0d8a5987d7 100644 --- a/dlls/shell32/shellpath.c +++ b/dlls/shell32/shellpath.c @@ -4424,7 +4424,7 @@ static void _SHCreateSymbolicLinks(void) char ** xdg_results; char * xdg_desktop_dir;
- /* Create all necessary profile sub-dirs up to 'My Documents' and get
the unix path. */
- /* Create the '%USERPROFILE%\My Documents' directory path. */ hr = SHGetFolderPathW(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (FAILED(hr)) return;
@@ -4439,7 +4439,7 @@ static void _SHCreateSymbolicLinks(void) { while (1) {
/* Check if there's already a Wine-specific 'My Documents'
folder */
/* Try to target a pre-existing '$HOME/My Documents' folder.
*/ strcpy(szPersonalTarget, pszHome); if (_SHAppendToUnixPath(szPersonalTarget, MAKEINTRESOURCEW(IDS_PERSONAL)) && !stat(szPersonalTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) @@ -4457,28 +4457,23 @@ static void _SHCreateSymbolicLinks(void) break; }
/* Try to point to the XDG Documents folder */
if (xdg_results && xdg_results[num-2] &&
!stat(xdg_results[num-2], &statFolder) &&
S_ISDIR(statFolder.st_mode))
/* Try to target the XDG_DOCUMENTS_DIR folder. */
if (xdg_results && xdg_results[num-2]) { strcpy(szPersonalTarget, xdg_results[num-2]); break; }
/* Or the hardcoded / OS X Documents folder */
/* Try to target the hardcoded / OS X 'Documents' folder. */ strcpy(szPersonalTarget, pszHome); if (_SHAppendToUnixPath(szPersonalTarget, DocumentsW) &&
!stat(szPersonalTarget, &statFolder) &&
S_ISDIR(statFolder.st_mode))
!stat(szPersonalTarget, &statFolder) &&
S_ISDIR(statFolder.st_mode)) break;
/* As a last resort point to $HOME. */
/* Target the '$HOME' folder directly (fallback). */ strcpy(szPersonalTarget, pszHome); break; }
/* Replace 'My Documents' directory with a symlink or fail
silently if not empty. */ remove(pszPersonal); symlink(szPersonalTarget, pszPersonal); } @@ -4498,30 +4493,30 @@ static void _SHCreateSymbolicLinks(void) /* Create symbolic links for 'My Pictures', 'My Videos' and 'My Music'. */ for (i=0; i < ARRAY_SIZE(aidsMyStuff); i++) {
/* Create the current 'My Whatever' folder and get its unix path.
*/
/* Create the '%USERPROFILE%\\My XXX' directory path. */ hr = SHGetFolderPathW(NULL, acsidlMyStuff[i]|CSIDL_FLAG_CREATE,
NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (FAILED(hr)) continue;
pszMyStuff = wine_get_unix_file_name(wszTempPath); if (!pszMyStuff) continue;
while (1) {
/* Check for the Wine-specific '$HOME/My Documents' subfolder
*/
/* Try to target a pre-existing '$HOME/My Documents/My XXX'
folder. */ strcpy(szMyStuffTarget, szPersonalTarget); if (_SHAppendToUnixPath(szMyStuffTarget, MAKEINTRESOURCEW(aidsMyStuff[i])) && !stat(szMyStuffTarget, &statFolder) && S_ISDIR(statFolder.st_mode)) break;
/* Try the XDG_XXX_DIR folder */
/* Try to target the XDG_XXX_DIR folder. */ if (xdg_results && xdg_results[i]) { strcpy(szMyStuffTarget, xdg_results[i]); break; }
/* Or the OS X folder (these are never localized) */
/* Try to target the hardcoded / OS X 'XXX' folder. */ if (pszHome) { strcpy(szMyStuffTarget, pszHome);
@@ -4531,7 +4526,7 @@ static void _SHCreateSymbolicLinks(void) break; }
/* As a last resort point to the same location as 'My
Documents' */
/* Use the same target as '%USERPROFILE%\\My Documents'
(fallback). */ strcpy(szMyStuffTarget, szPersonalTarget); break; } @@ -4540,7 +4535,7 @@ static void _SHCreateSymbolicLinks(void) heap_free(pszMyStuff); }
- /* Last but not least, the Desktop folder */
- /* Create a symbolic link for the 'Desktop' folder. */ if (pszHome) strcpy(szDesktopTarget, pszHome); else
@@ -4552,6 +4547,7 @@ static void _SHCreateSymbolicLinks(void) (_SHAppendToUnixPath(szDesktopTarget, DesktopW) && !stat(szDesktopTarget, &statFolder) && S_ISDIR(statFolder.st_mode))) {
/* Get the '%USERPROFILE%\\Desktop' directory path. */ hr = SHGetFolderPathW(NULL, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE,
NULL, SHGFP_TYPE_DEFAULT, wszTempPath); if (SUCCEEDED(hr) && (pszDesktop = wine_get_unix_file_name(wszTempPath)))
@@ -4565,7 +4561,6 @@ static void _SHCreateSymbolicLinks(void) } }
- /* Free resources allocated by XDG_UserDirLookup() */ if (xdg_results) { for (i = 0; i < num; i++)
-- 2.18.0
This patchset is to primarily refactor: _SHCreateSymbolicLinks() It is intended to make the existing code less opaque, more streamlined and easier to work with. Although the _SHCreateSymbolicLinks() functionality is quite simple, the existing implementation is hard to parse/ spaghetti code.
FYI I obviously still have patches ready to submit, which will fix:
* https://bugs.winehq.org/show_bug.cgi?id=41668 * https://bugs.winehq.org/show_bug.cgi?id=28216
that depend heavily on this code clean-up. Plus an implementation of the Windows Vista(+) compatiblility junction links (again which depends on this patchset).
All the best, Robert
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=40054
Your paranoid android.
=== debian9 (build) === error: corrupt patch at line 201 Task: Patch failed to apply