mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-02 17:53:37 +00:00
winecfg: Use mountmgr to manage shell folders.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0a8776d455
commit
01a2b9c628
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue