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