Module: wine Branch: master Commit: 01a2b9c6282f9ff5480563cc5e4be12ce2f907a6 URL: https://source.winehq.org/git/wine.git/?a=commit;h=01a2b9c6282f9ff5480563cc5...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Sep 7 13:18:37 2021 +0200
winecfg: Use mountmgr to manage shell folders.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
programs/winecfg/drive.c | 52 ++++++++++++++++++++++++++++++++ programs/winecfg/theme.c | 75 +++++----------------------------------------- programs/winecfg/winecfg.h | 2 ++ 3 files changed, 61 insertions(+), 68 deletions(-)
diff --git a/programs/winecfg/drive.c b/programs/winecfg/drive.c index a5fc3bfd73a..bfe9a48e94d 100644 --- a/programs/winecfg/drive.c +++ b/programs/winecfg/drive.c @@ -370,3 +370,55 @@ void apply_drive_changes(void) } CloseHandle( mgr ); } + + +void query_shell_folder( const WCHAR *path, char *dest, unsigned int len ) +{ + UNICODE_STRING nt_name; + HANDLE mgr; + + if ((mgr = open_mountmgr()) == INVALID_HANDLE_VALUE) return; + + if (!RtlDosPathNameToNtPathName_U( path, &nt_name, NULL, NULL )) + { + CloseHandle( mgr ); + return; + } + DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_SHELL_FOLDER, nt_name.Buffer, nt_name.Length, + dest, len, NULL, NULL ); + RtlFreeUnicodeString( &nt_name ); +} + +void set_shell_folder( const WCHAR *path, const char *dest ) +{ + struct mountmgr_shell_folder *ioctl; + UNICODE_STRING nt_name; + HANDLE mgr; + DWORD len; + + if ((mgr = open_mountmgr()) == INVALID_HANDLE_VALUE) return; + + if (!RtlDosPathNameToNtPathName_U( path, &nt_name, NULL, NULL )) + { + CloseHandle( mgr ); + return; + } + + len = sizeof(*ioctl) + nt_name.Length; + if (dest) len += strlen(dest) + 1; + + if (!(ioctl = HeapAlloc( GetProcessHeap(), 0, len ))) return; + ioctl->folder_offset = sizeof(*ioctl); + ioctl->folder_size = nt_name.Length; + memcpy( (char *)ioctl + ioctl->folder_offset, nt_name.Buffer, nt_name.Length ); + if (dest) + { + ioctl->symlink_offset = ioctl->folder_offset + ioctl->folder_size; + strcpy( (char *)ioctl + ioctl->symlink_offset, dest ); + } + else ioctl->symlink_offset = 0; + + DeviceIoControl( mgr, IOCTL_MOUNTMGR_DEFINE_SHELL_FOLDER, ioctl, len, NULL, 0, NULL, NULL ); + HeapFree( GetProcessHeap(), 0, ioctl ); + RtlFreeUnicodeString( &nt_name ); +} diff --git a/programs/winecfg/theme.c b/programs/winecfg/theme.c index b3a3eeed3ba..151dc486659 100644 --- a/programs/winecfg/theme.c +++ b/programs/winecfg/theme.c @@ -28,12 +28,6 @@ #include <stdarg.h> #include <stdlib.h> #include <stdio.h> -#ifdef HAVE_SYS_STAT_H -#include <sys/stat.h> -#endif -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif
#define COBJMACROS
@@ -765,25 +759,14 @@ static void init_shell_folder_listview_headers(HWND dialog) { /* Reads the currently set shell folder symbol link targets into asfiInfo. */ static void read_shell_folder_link_targets(void) { WCHAR wszPath[MAX_PATH]; - HRESULT hr; int i;
for (i=0; i<ARRAY_SIZE(asfiInfo); i++) { asfiInfo[i].szLinkTarget[0] = '\0'; - hr = SHGetFolderPathW(NULL, asfiInfo[i].nFolder|CSIDL_FLAG_DONT_VERIFY, NULL, - SHGFP_TYPE_CURRENT, wszPath); - if (SUCCEEDED(hr)) { - char *pszUnixPath = wine_get_unix_file_name(wszPath); - if (pszUnixPath) { - struct stat statPath; - if (!lstat(pszUnixPath, &statPath) && S_ISLNK(statPath.st_mode)) { - int cLen = readlink(pszUnixPath, asfiInfo[i].szLinkTarget, FILENAME_MAX-1); - if (cLen >= 0) asfiInfo[i].szLinkTarget[cLen] = '\0'; - } - HeapFree(GetProcessHeap(), 0, pszUnixPath); - } - } - } + if (SUCCEEDED( SHGetFolderPathW( NULL, asfiInfo[i].nFolder | CSIDL_FLAG_DONT_VERIFY, NULL, + SHGFP_TYPE_CURRENT, wszPath ))) + query_shell_folder( wszPath, asfiInfo[i].szLinkTarget, FILENAME_MAX ); + } }
static void update_shell_folder_listview(HWND dialog) { @@ -904,56 +887,12 @@ static void on_shell_folder_edit_changed(HWND hDlg) {
static void apply_shell_folder_changes(void) { WCHAR wszPath[MAX_PATH]; - char szBackupPath[FILENAME_MAX], szUnixPath[FILENAME_MAX], *pszUnixPath = NULL; int i; - struct stat statPath; - HRESULT hr;
for (i=0; i<ARRAY_SIZE(asfiInfo); i++) { - /* Ignore nonexistent link targets */ - if (asfiInfo[i].szLinkTarget[0] && stat(asfiInfo[i].szLinkTarget, &statPath)) - continue; - - hr = SHGetFolderPathW(NULL, asfiInfo[i].nFolder|CSIDL_FLAG_CREATE, NULL, - SHGFP_TYPE_CURRENT, wszPath); - if (FAILED(hr)) continue; - - /* Retrieve the corresponding unix path. */ - pszUnixPath = wine_get_unix_file_name(wszPath); - if (!pszUnixPath) continue; - lstrcpyA(szUnixPath, pszUnixPath); - HeapFree(GetProcessHeap(), 0, pszUnixPath); - - /* Derive name for folder backup. */ - lstrcpyA(szBackupPath, szUnixPath); - lstrcatA(szBackupPath, ".winecfg"); - - if (lstat(szUnixPath, &statPath)) continue; - - /* Move old folder/link out of the way. */ - if (S_ISLNK(statPath.st_mode)) { - if (unlink(szUnixPath)) continue; /* Unable to remove link. */ - } else { - if (!*asfiInfo[i].szLinkTarget) { - continue; /* We are done. Old was real folder, as new shall be. */ - } else { - if (rename(szUnixPath, szBackupPath)) { /* Move folder out of the way. */ - continue; /* Unable to move old folder. */ - } - } - } - - /* Create new link/folder. */ - if (*asfiInfo[i].szLinkTarget) { - symlink(asfiInfo[i].szLinkTarget, szUnixPath); - } else { - /* If there's a backup folder, restore it. Else create new folder. */ - if (!lstat(szBackupPath, &statPath) && S_ISDIR(statPath.st_mode)) { - rename(szBackupPath, szUnixPath); - } else { - mkdir(szUnixPath, 0777); - } - } + if (SUCCEEDED( SHGetFolderPathW( NULL, asfiInfo[i].nFolder | CSIDL_FLAG_CREATE, NULL, + SHGFP_TYPE_CURRENT, wszPath ))) + set_shell_folder( wszPath, asfiInfo[i].szLinkTarget ); } }
diff --git a/programs/winecfg/winecfg.h b/programs/winecfg/winecfg.h index d022cd3d688..17516aa4a14 100644 --- a/programs/winecfg/winecfg.h +++ b/programs/winecfg/winecfg.h @@ -117,6 +117,8 @@ BOOL add_drive(char letter, const char *targetpath, const char *device, const WCHAR *label, DWORD serial, DWORD type); void delete_drive(struct drive *pDrive); void apply_drive_changes(void); +void query_shell_folder( const WCHAR *path, char *dest, unsigned int len ); +void set_shell_folder( const WCHAR *path, const char *dest ); BOOL browse_for_unix_folder(HWND dialog, WCHAR *pszPath); extern struct drive drives[26]; /* one for each drive letter */