Alexandre Julliard : winecfg: Use mountmgr to manage shell folders.
Alexandre Julliard
julliard at winehq.org
Tue Sep 7 16:25:19 CDT 2021
Module: wine
Branch: master
Commit: 01a2b9c6282f9ff5480563cc5e4be12ce2f907a6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=01a2b9c6282f9ff5480563cc5e4be12ce2f907a6
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Sep 7 13:18:37 2021 +0200
winecfg: Use mountmgr to manage shell folders.
Signed-off-by: Alexandre Julliard <julliard at 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 */
More information about the wine-cvs
mailing list