forked from Mirrors/wine-wine
ntdll: On Mac OS, close the CDROM device before opening the parent.
This is needed to allow ejecting DVD disks.oldstable
parent
a76ef05c90
commit
572771ebfa
|
@ -305,27 +305,28 @@ static int CDROM_MediaChanged(int dev)
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* open_parent_device
|
* get_parent_device
|
||||||
*
|
*
|
||||||
* On Mac OS, open the device for the whole disk from a fd that points to a partition.
|
* On Mac OS, get 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
|
* This is ugly and inefficient, but we have no choice since the partition fd doesn't
|
||||||
* support the eject ioctl.
|
* support the eject ioctl.
|
||||||
*/
|
*/
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
static int open_parent_device( int fd )
|
static NTSTATUS get_parent_device( int fd, char *name, size_t len )
|
||||||
{
|
{
|
||||||
|
NTSTATUS status = STATUS_NO_SUCH_FILE;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int i, parent_fd = -1;
|
int i;
|
||||||
io_service_t service;
|
io_service_t service;
|
||||||
CFMutableDictionaryRef dict;
|
CFMutableDictionaryRef dict;
|
||||||
CFTypeRef val;
|
CFTypeRef val;
|
||||||
|
|
||||||
if (fstat( fd, &st ) == -1) return -1;
|
if (fstat( fd, &st ) == -1) return FILE_GetNtStatus();
|
||||||
if (!S_ISCHR( st.st_mode )) return -1;
|
if (!S_ISCHR( st.st_mode )) return STATUS_OBJECT_TYPE_MISMATCH;
|
||||||
|
|
||||||
/* create a dictionary with the right major/minor numbers */
|
/* create a dictionary with the right major/minor numbers */
|
||||||
|
|
||||||
if (!(dict = IOServiceMatching( kIOMediaClass ))) return -1;
|
if (!(dict = IOServiceMatching( kIOMediaClass ))) return STATUS_NO_MEMORY;
|
||||||
|
|
||||||
i = major( st.st_rdev );
|
i = major( st.st_rdev );
|
||||||
val = CFNumberCreate( NULL, kCFNumberIntType, &i );
|
val = CFNumberCreate( NULL, kCFNumberIntType, &i );
|
||||||
|
@ -360,11 +361,10 @@ static int open_parent_device( int fd )
|
||||||
|
|
||||||
if ((str = IORegistryEntryCreateCFProperty( service, CFSTR("BSD Name"), NULL, 0 )))
|
if ((str = IORegistryEntryCreateCFProperty( service, CFSTR("BSD Name"), NULL, 0 )))
|
||||||
{
|
{
|
||||||
char name[100];
|
|
||||||
strcpy( name, "/dev/r" );
|
strcpy( name, "/dev/r" );
|
||||||
CFStringGetCString( str, name + 6, sizeof(name) - 6, kCFStringEncodingUTF8 );
|
CFStringGetCString( str, name + 6, len - 6, kCFStringEncodingUTF8 );
|
||||||
CFRelease( str );
|
CFRelease( str );
|
||||||
parent_fd = open( name, O_RDONLY );
|
status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
IOObjectRelease( service );
|
IOObjectRelease( service );
|
||||||
break;
|
break;
|
||||||
|
@ -374,7 +374,7 @@ next:
|
||||||
IOObjectRelease( service );
|
IOObjectRelease( service );
|
||||||
service = parent;
|
service = parent;
|
||||||
}
|
}
|
||||||
return parent_fd;
|
return status;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -2181,17 +2181,23 @@ NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
int parent_fd = open_parent_device( fd );
|
char name[100];
|
||||||
if (parent_fd != -1)
|
|
||||||
{
|
|
||||||
/* This is ugly as hell, but Mac OS is unable to eject from the device fd,
|
/* 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
|
* 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 */
|
* to be closed first, so we have to close the handle that the caller gave us.
|
||||||
|
* Also for some reason it wants the fd to be closed before we even open the parent.
|
||||||
|
*/
|
||||||
|
if ((status = get_parent_device( fd, name, sizeof(name) ))) break;
|
||||||
NtClose( hDevice );
|
NtClose( hDevice );
|
||||||
if (needs_close) close( fd );
|
if (needs_close) close( fd );
|
||||||
fd = parent_fd;
|
TRACE("opening parent %s\n", name );
|
||||||
needs_close = 1;
|
if ((fd = open( name, O_RDONLY )) == -1)
|
||||||
|
{
|
||||||
|
status = FILE_GetNtStatus();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
needs_close = 1;
|
||||||
#endif
|
#endif
|
||||||
status = CDROM_SetTray(fd, TRUE);
|
status = CDROM_SetTray(fd, TRUE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue