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