mirror of
https://github.com/reactos/wine.git
synced 2025-02-17 19:39:00 +00:00
ntdll: Added support for physically ejecting devices on Mac OS.
This commit is contained in:
parent
9fed1205ca
commit
9ff161860c
@ -77,7 +77,9 @@
|
||||
|
||||
#ifdef HAVE_IOKIT_IOKITLIB_H
|
||||
# ifndef SENSEBUFLEN
|
||||
# include <sys/disk.h>
|
||||
# include <IOKit/IOKitLib.h>
|
||||
# include <IOKit/storage/IOMedia.h>
|
||||
# include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h>
|
||||
# define SENSEBUFLEN kSenseDefaultSize
|
||||
# endif
|
||||
@ -302,6 +304,82 @@ static int CDROM_MediaChanged(int dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* open_parent_device
|
||||
*
|
||||
* On Mac OS, open the device for the whole disk from a fd that points to a partition.
|
||||
* This is ugly and inefficient, but we have no choice since the partition fd doesn't
|
||||
* support the eject ioctl.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
static int open_parent_device( int fd )
|
||||
{
|
||||
struct stat st;
|
||||
int i, parent_fd = -1;
|
||||
io_service_t service;
|
||||
CFMutableDictionaryRef dict;
|
||||
CFTypeRef val;
|
||||
|
||||
if (fstat( fd, &st ) == -1) return -1;
|
||||
if (!S_ISCHR( st.st_mode )) return -1;
|
||||
|
||||
/* create a dictionary with the right major/minor numbers */
|
||||
|
||||
if (!(dict = IOServiceMatching( kIOMediaClass ))) return -1;
|
||||
|
||||
i = major( st.st_rdev );
|
||||
val = CFNumberCreate( NULL, kCFNumberIntType, &i );
|
||||
CFDictionaryAddValue( dict, CFSTR( "BSD Major" ), val );
|
||||
CFRelease( val );
|
||||
|
||||
i = minor( st.st_rdev );
|
||||
val = CFNumberCreate( NULL, kCFNumberIntType, &i );
|
||||
CFDictionaryAddValue( dict, CFSTR( "BSD Minor" ), val );
|
||||
CFRelease( val );
|
||||
|
||||
CFDictionaryAddValue( dict, CFSTR("Removable"), kCFBooleanTrue );
|
||||
|
||||
service = IOServiceGetMatchingService( kIOMasterPortDefault, dict );
|
||||
|
||||
/* now look for the parent that has the "Whole" attribute set to TRUE */
|
||||
|
||||
while (service)
|
||||
{
|
||||
io_service_t parent = 0;
|
||||
CFBooleanRef whole;
|
||||
CFStringRef str;
|
||||
int ok;
|
||||
|
||||
if (!IOObjectConformsTo( service, kIOMediaClass ))
|
||||
goto next;
|
||||
if (!(whole = IORegistryEntryCreateCFProperty( service, CFSTR("Whole"), NULL, 0 )))
|
||||
goto next;
|
||||
ok = (whole == kCFBooleanTrue);
|
||||
CFRelease( whole );
|
||||
if (!ok) goto next;
|
||||
|
||||
if ((str = IORegistryEntryCreateCFProperty( service, CFSTR("BSD Name"), NULL, 0 )))
|
||||
{
|
||||
char name[100];
|
||||
strcpy( name, "/dev/r" );
|
||||
CFStringGetCString( str, name + 6, sizeof(name) - 6, kCFStringEncodingUTF8 );
|
||||
CFRelease( str );
|
||||
parent_fd = open( name, O_RDONLY );
|
||||
}
|
||||
IOObjectRelease( service );
|
||||
break;
|
||||
|
||||
next:
|
||||
IORegistryEntryGetParentEntry( service, kIOServicePlane, &parent );
|
||||
IOObjectRelease( service );
|
||||
service = parent;
|
||||
}
|
||||
return parent_fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_SyncCache [internal]
|
||||
*
|
||||
@ -628,6 +706,9 @@ static NTSTATUS CDROM_SetTray(int fd, BOOL doEject)
|
||||
return CDROM_GetStatusCode((ioctl(fd, CDIOCALLOW, NULL)) ||
|
||||
(ioctl(fd, doEject ? CDIOCEJECT : CDIOCCLOSE, NULL)) ||
|
||||
(ioctl(fd, CDIOCPREVENT, NULL)));
|
||||
#elif defined(__APPLE__)
|
||||
if (doEject) return CDROM_GetStatusCode( ioctl( fd, DKIOCEJECT, NULL ) );
|
||||
else return STATUS_NOT_SUPPORTED;
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
@ -2059,7 +2140,23 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
|
||||
CDROM_ClearCacheEntry(dev);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
status = STATUS_INVALID_PARAMETER;
|
||||
else status = CDROM_SetTray(fd, TRUE);
|
||||
else
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
int parent_fd = open_parent_device( fd );
|
||||
if (parent_fd != -1)
|
||||
{
|
||||
/* This is ugly as hell, but Mac OS is unable to eject from the device fd,
|
||||
* it wants an fd for the whole device, and it also requires the device fd
|
||||
* to be closed first, so we have to close the handle that the caller gave us */
|
||||
NtClose( hDevice );
|
||||
if (needs_close) close( fd );
|
||||
fd = parent_fd;
|
||||
needs_close = 1;
|
||||
}
|
||||
#endif
|
||||
status = CDROM_SetTray(fd, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_CDROM_MEDIA_REMOVAL:
|
||||
|
Loading…
x
Reference in New Issue
Block a user