Alexandre Julliard : mountmgr: Add some helpers to abstract the Unix calls from mountmgr.c.
Alexandre Julliard
julliard at winehq.org
Thu Nov 25 16:00:26 CST 2021
Module: wine
Branch: master
Commit: 086e9e0eda074bba36d1cb35cd0e2fc8c2e8e285
URL: https://source.winehq.org/git/wine.git/?a=commit;h=086e9e0eda074bba36d1cb35cd0e2fc8c2e8e285
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Nov 25 17:20:07 2021 +0100
mountmgr: Add some helpers to abstract the Unix calls from mountmgr.c.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mountmgr.sys/mountmgr.c | 63 +++++--------------------------------------
dlls/mountmgr.sys/unixlib.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
dlls/mountmgr.sys/unixlib.h | 2 ++
3 files changed, 72 insertions(+), 57 deletions(-)
diff --git a/dlls/mountmgr.sys/mountmgr.c b/dlls/mountmgr.sys/mountmgr.c
index 6c7f21172fa..33be9293713 100644
--- a/dlls/mountmgr.sys/mountmgr.c
+++ b/dlls/mountmgr.sys/mountmgr.c
@@ -33,14 +33,12 @@
#include <stdarg.h>
#include <stdlib.h>
#include <unistd.h>
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
#define NONAMELESSUNION
#include "mountmgr.h"
#include "winreg.h"
+#include "unixlib.h"
#include "wine/list.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@@ -297,9 +295,7 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
UNICODE_STRING name;
NTSTATUS status;
ULONG size = 256;
- const char *home;
- char *buffer = NULL, *backup = NULL, *homelink = NULL;
- struct stat st;
+ char *buffer = NULL, *backup = NULL;
if (input->folder_offset >= insize || input->folder_size > insize - input->folder_offset ||
input->symlink_offset >= insize)
@@ -313,22 +309,6 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
if (!link[0]) link = NULL;
}
- if (link && (!strcmp( link, "$HOME" ) || !strncmp( link, "$HOME/", 6 )) && (home = getenv( "HOME" )))
- {
- link += 5;
- homelink = HeapAlloc( GetProcessHeap(), 0, strlen(home) + strlen(link) + 1 );
- strcpy( homelink, home );
- strcat( homelink, link );
- link = homelink;
- }
-
- /* ignore nonexistent link targets */
- if (link && (stat( link, &st ) || !S_ISDIR( st.st_mode )))
- {
- status = STATUS_OBJECT_NAME_NOT_FOUND;
- goto done;
- }
-
name.Buffer = (WCHAR *)((char *)in_buff + input->folder_offset);
name.Length = input->folder_size;
InitializeObjectAttributes( &attr, &name, 0, 0, NULL );
@@ -358,37 +338,11 @@ static NTSTATUS define_shell_folder( const void *in_buff, SIZE_T insize )
strcat( backup, ".backup" );
}
- if (!lstat( buffer, &st )) /* move old folder/link out of the way */
- {
- if (S_ISLNK( st.st_mode ))
- {
- unlink( buffer );
- }
- else if (link && S_ISDIR( st.st_mode ))
- {
- if (rmdir( buffer )) /* non-empty dir, try to make a backup */
- {
- if (!backup || rename( buffer, backup ))
- {
- status = STATUS_OBJECT_NAME_COLLISION;
- goto done;
- }
- }
- }
- else goto done; /* nothing to do, folder already exists */
- }
-
- if (link) symlink( link, buffer );
- else
- {
- if (backup && !lstat( backup, &st ) && S_ISDIR( st.st_mode )) rename( backup, buffer );
- else mkdir( buffer, 0777 );
- }
+ status = set_shell_folder( buffer, backup, link );
done:
HeapFree( GetProcessHeap(), 0, buffer );
HeapFree( GetProcessHeap(), 0, backup );
- HeapFree( GetProcessHeap(), 0, homelink );
return status;
}
@@ -401,7 +355,6 @@ static NTSTATUS query_shell_folder( void *buff, SIZE_T insize, SIZE_T outsize, I
NTSTATUS status;
ULONG size = 256;
char *buffer;
- int ret;
name.Buffer = buff;
name.Length = insize;
@@ -415,13 +368,9 @@ static NTSTATUS query_shell_folder( void *buff, SIZE_T insize, SIZE_T outsize, I
HeapFree( GetProcessHeap(), 0, buffer );
if (status != STATUS_BUFFER_TOO_SMALL) return status;
}
- ret = readlink( buffer, output, outsize - 1 );
- if (ret >= 0)
- {
- output[ret] = 0;
- iosb->Information = ret + 1;
- }
- else status = STATUS_OBJECT_NAME_NOT_FOUND;
+
+ status = get_shell_folder( buffer, output, outsize );
+ if (!status) iosb->Information = strlen(output) + 1;
HeapFree( GetProcessHeap(), 0, buffer );
return status;
diff --git a/dlls/mountmgr.sys/unixlib.c b/dlls/mountmgr.sys/unixlib.c
index b2c475c90cc..8e6378e5637 100644
--- a/dlls/mountmgr.sys/unixlib.c
+++ b/dlls/mountmgr.sys/unixlib.c
@@ -277,3 +277,67 @@ NTSTATUS detect_parallel_ports( char *names, ULONG size )
detect_devices( paths, names, size );
return STATUS_SUCCESS;
}
+
+NTSTATUS set_shell_folder( const char *folder, const char *backup, const char *link )
+{
+ struct stat st;
+ const char *home;
+ char *homelink = NULL;
+ NTSTATUS status = STATUS_SUCCESS;
+
+ if (link && (!strcmp( link, "$HOME" ) || !strncmp( link, "$HOME/", 6 )) && (home = getenv( "HOME" )))
+ {
+ link += 5;
+ homelink = malloc( strlen(home) + strlen(link) + 1 );
+ strcpy( homelink, home );
+ strcat( homelink, link );
+ link = homelink;
+ }
+
+ /* ignore nonexistent link targets */
+ if (link && (stat( link, &st ) || !S_ISDIR( st.st_mode )))
+ {
+ status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto done;
+ }
+
+ if (!lstat( folder, &st )) /* move old folder/link out of the way */
+ {
+ if (S_ISLNK( st.st_mode ))
+ {
+ unlink( folder );
+ }
+ else if (link && S_ISDIR( st.st_mode ))
+ {
+ if (rmdir( folder )) /* non-empty dir, try to make a backup */
+ {
+ if (!backup || rename( folder, backup ))
+ {
+ status = STATUS_OBJECT_NAME_COLLISION;
+ goto done;
+ }
+ }
+ }
+ else goto done; /* nothing to do, folder already exists */
+ }
+
+ if (link) symlink( link, folder );
+ else
+ {
+ if (backup && !lstat( backup, &st ) && S_ISDIR( st.st_mode )) rename( backup, folder );
+ else mkdir( folder, 0777 );
+ }
+
+done:
+ free( homelink );
+ return status;
+}
+
+NTSTATUS get_shell_folder( const char *folder, char *buffer, ULONG size )
+{
+ int ret = readlink( folder, buffer, size - 1 );
+
+ if (ret < 0) return STATUS_OBJECT_NAME_NOT_FOUND;
+ buffer[ret] = 0;
+ return STATUS_SUCCESS;
+}
diff --git a/dlls/mountmgr.sys/unixlib.h b/dlls/mountmgr.sys/unixlib.h
index b99ea7adca8..ab51481cabb 100644
--- a/dlls/mountmgr.sys/unixlib.h
+++ b/dlls/mountmgr.sys/unixlib.h
@@ -28,3 +28,5 @@ extern NTSTATUS read_volume_file( const char *volume, const char *file, void *bu
extern BOOL match_unixdev( const char *device, ULONGLONG unix_dev ) DECLSPEC_HIDDEN;
extern NTSTATUS detect_serial_ports( char *names, ULONG size ) DECLSPEC_HIDDEN;
extern NTSTATUS detect_parallel_ports( char *names, ULONG size ) DECLSPEC_HIDDEN;
+extern NTSTATUS set_shell_folder( const char *folder, const char *backup, const char *link ) DECLSPEC_HIDDEN;
+extern NTSTATUS get_shell_folder( const char *folder, char *buffer, ULONG size ) DECLSPEC_HIDDEN;
More information about the wine-cvs
mailing list