ntdll: Implement FSCTL_DISMOUNT_VOLUME for MacOSX.

This commit is contained in:
Alexandre Julliard 2006-10-03 14:54:21 +02:00
parent 6735eb2e0a
commit 01dd1ffdc2
2 changed files with 46 additions and 2 deletions

View File

@ -158,6 +158,17 @@ static inline BOOL is_invalid_dos_char( WCHAR ch )
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 @@ static char *get_device_mount_point( dev_t dev )
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 handle )
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)
{

View File

@ -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 *device_fd )
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;