Alexandre Julliard : ntdll: Implement FSCTL_DISMOUNT_VOLUME for MacOSX.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Oct 3 10:04:38 CDT 2006


Module: wine
Branch: master
Commit: 01dd1ffdc2a8af27e4df1a24f9aec04a65204f42
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=01dd1ffdc2a8af27e4df1a24f9aec04a65204f42

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Oct  3 14:54:21 2006 +0200

ntdll: Implement FSCTL_DISMOUNT_VOLUME for MacOSX.

---

 dlls/ntdll/directory.c |   36 +++++++++++++++++++++++++++++++++++-
 server/fd.c            |   12 +++++++++++-
 2 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 60aa5b5..145fc00 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -158,6 +158,17 @@ static inline BOOL is_invalid_dos_char( 
     return strchrW( invalid_chars, ch ) != NULL;
 }
 
+/* check if the device can be a mounted volume */
+static inline int is_valid_mounted_device( struct stat *st )
+{
+#if defined(linux) || defined(__sun__)
+    return S_ISBLK( st->st_mode );
+#else
+    /* disks are char devices on *BSD */
+    return S_ISCHR( st->st_mode );
+#endif
+}
+
 /***********************************************************************
  *           get_default_com_device
  *
@@ -565,6 +576,25 @@ #ifdef linux
         endmntent( f );
     }
     RtlLeaveCriticalSection( &dir_section );
+#elif defined(__APPLE__)
+    struct statfs *entry;
+    struct stat st;
+    int i, size;
+
+    RtlEnterCriticalSection( &dir_section );
+
+    size = getmntinfo( &entry, MNT_NOWAIT );
+    for (i = 0; i < size; i++)
+    {
+        if (stat( entry[i].f_mntfromname, &st ) == -1) continue;
+        if (S_ISBLK(st.st_mode) && st.st_rdev == dev)
+        {
+            ret = RtlAllocateHeap( GetProcessHeap(), 0, strlen(entry[i].f_mntfromname) + 1 );
+            if (ret) strcpy( ret, entry[i].f_mntfromname );
+            break;
+        }
+    }
+    RtlLeaveCriticalSection( &dir_section );
 #else
     static int warned;
     if (!warned++) FIXME( "unmounting devices not supported on this platform\n" );
@@ -1760,13 +1790,17 @@ NTSTATUS DIR_unmount_device( HANDLE hand
         struct stat st;
         char *mount_point = NULL;
 
-        if (fstat( unix_fd, &st ) == -1 || !S_ISBLK(st.st_mode))
+        if (fstat( unix_fd, &st ) == -1 || !is_valid_mounted_device( &st ))
             status = STATUS_INVALID_PARAMETER;
         else
         {
             if ((mount_point = get_device_mount_point( st.st_rdev )))
             {
+#ifdef __APPLE__
+                static const char umount[] = "diskutil unmount >/dev/null 2>&1 ";
+#else
                 static const char umount[] = "umount >/dev/null 2>&1 ";
+#endif
                 char *cmd = RtlAllocateHeap( GetProcessHeap(), 0, strlen(mount_point)+sizeof(umount));
                 if (cmd)
                 {
diff --git a/server/fd.c b/server/fd.c
index 5f172a9..e422eea 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1780,6 +1780,16 @@ void no_cancel_async( struct fd *fd )
     set_error( STATUS_OBJECT_TYPE_MISMATCH );
 }
 
+static inline int is_valid_mounted_device( struct stat *st )
+{
+#if defined(linux) || defined(__sun__)
+    return S_ISBLK( st->st_mode );
+#else
+    /* disks are char devices on *BSD */
+    return S_ISCHR( st->st_mode );
+#endif
+}
+
 /* close all Unix file descriptors on a device to allow unmounting it */
 static void unmount_device( struct fd *device_fd )
 {
@@ -1792,7 +1802,7 @@ static void unmount_device( struct fd *d
 
     if (unix_fd == -1) return;
 
-    if (fstat( unix_fd, &st ) == -1 || !S_ISBLK( st.st_mode ))
+    if (fstat( unix_fd, &st ) == -1 || !is_valid_mounted_device( &st ))
     {
         set_error( STATUS_INVALID_PARAMETER );
         return;




More information about the wine-cvs mailing list