/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/* Main file for CD-ROM support
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1999, 2001, 2003 Eric Pouech
 * Copyright 2000 Andreas Mohr
 * Copyright 2005 Ivan Leo Puoti
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <errno.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#ifdef HAVE_IO_H
# include <io.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#include <sys/types.h>

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SCSI_SG_H
# include <scsi/sg.h>
#endif
#ifdef HAVE_SCSI_SCSI_H
# include <scsi/scsi.h>
# undef REASSIGN_BLOCKS  /* avoid conflict with winioctl.h */
# undef FAILED           /* avoid conflict with winerror.h */
#endif
#ifdef HAVE_SCSI_SCSI_IOCTL_H
# include <scsi/scsi_ioctl.h>
#endif
#ifdef HAVE_LINUX_MAJOR_H
# include <linux/major.h>
#endif
#ifdef HAVE_LINUX_HDREG_H
# include <linux/hdreg.h>
#endif
#ifdef HAVE_LINUX_PARAM_H
# include <linux/param.h>
#endif
#ifdef HAVE_LINUX_CDROM_H
# include <linux/cdrom.h>
#endif
#ifdef HAVE_LINUX_UCDROM_H
# include <linux/ucdrom.h>
#endif
#ifdef HAVE_SYS_CDIO_H
# include <sys/cdio.h>
#endif
#ifdef HAVE_SYS_SCSIIO_H
# include <sys/scsiio.h>
#endif

#ifdef HAVE_IOKIT_IOKITLIB_H
# include <libkern/OSByteOrder.h>
# include <sys/disk.h>
# include <IOKit/IOKitLib.h>
# include <IOKit/storage/IOMedia.h>
# include <IOKit/storage/IOCDMediaBSDClient.h>
# include <IOKit/storage/IODVDMediaBSDClient.h>
# include <IOKit/scsi/SCSITask.h>
# include <IOKit/scsi/SCSICmds_REQUEST_SENSE_Defs.h>
# define SENSEBUFLEN kSenseDefaultSize

typedef struct
{
    uint32_t attribute;
    uint32_t timeout;
    uint32_t response;
    uint32_t status;
    uint8_t direction;
    uint8_t cdbSize;
    uint8_t reserved0144[2];
    uint8_t cdb[16];
    void* buffer;
    uint64_t bufferSize;
    void* sense;
    uint64_t senseLen;
} dk_scsi_command_t;

typedef struct
{
    uint64_t bus;
    uint64_t port;
    uint64_t target;
    uint64_t lun;
} dk_scsi_identify_t;

#define DKIOCSCSICOMMAND _IOWR('d', 253, dk_scsi_command_t)
#define DKIOCSCSIIDENTIFY _IOR('d', 254, dk_scsi_identify_t)

#endif

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winternl.h"
#include "winioctl.h"
#include "ntddstor.h"
#include "ntddcdrm.h"
#include "ddk/ntddcdvd.h"
#include "ntddscsi.h"
#include "ntdll_misc.h"
#include "wine/server.h"
#include "wine/library.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(cdrom);

/* Non-Linux systems do not have linux/cdrom.h and the like, and thus
   lack the following constants. */

#ifndef CD_SECS
# define CD_SECS              60 /* seconds per minute */
#endif
#ifndef CD_FRAMES
# define CD_FRAMES            75 /* frames per second */
#endif

#ifdef WORDS_BIGENDIAN
#define GET_BE_DWORD(x) (x)
#else
#define GET_BE_DWORD(x) RtlUlongByteSwap(x)
#endif

static const struct iocodexs
{
  DWORD code;
  const char *codex;
} iocodextable[] = {
#define X(x) { x, #x },
X(IOCTL_CDROM_CHECK_VERIFY)
X(IOCTL_CDROM_CURRENT_POSITION)
X(IOCTL_CDROM_DISK_TYPE)
X(IOCTL_CDROM_GET_CONTROL)
X(IOCTL_CDROM_GET_DRIVE_GEOMETRY)
X(IOCTL_CDROM_GET_VOLUME)
X(IOCTL_CDROM_LOAD_MEDIA)
X(IOCTL_CDROM_MEDIA_CATALOG)
X(IOCTL_CDROM_MEDIA_REMOVAL)
X(IOCTL_CDROM_PAUSE_AUDIO)
X(IOCTL_CDROM_PLAY_AUDIO_MSF)
X(IOCTL_CDROM_RAW_READ)
X(IOCTL_CDROM_READ_Q_CHANNEL)
X(IOCTL_CDROM_READ_TOC)
X(IOCTL_CDROM_RESUME_AUDIO)
X(IOCTL_CDROM_SEEK_AUDIO_MSF)
X(IOCTL_CDROM_SET_VOLUME)
X(IOCTL_CDROM_STOP_AUDIO)
X(IOCTL_CDROM_TRACK_ISRC)
X(IOCTL_DISK_GET_MEDIA_TYPES)
X(IOCTL_DISK_MEDIA_REMOVAL)
X(IOCTL_DVD_END_SESSION)
X(IOCTL_DVD_GET_REGION)
X(IOCTL_DVD_READ_KEY)
X(IOCTL_DVD_READ_STRUCTURE)
X(IOCTL_DVD_SEND_KEY)
X(IOCTL_DVD_START_SESSION)
X(IOCTL_SCSI_GET_ADDRESS)
X(IOCTL_SCSI_GET_CAPABILITIES)
X(IOCTL_SCSI_GET_INQUIRY_DATA)
X(IOCTL_SCSI_PASS_THROUGH)
X(IOCTL_SCSI_PASS_THROUGH_DIRECT)
X(IOCTL_STORAGE_CHECK_VERIFY)
X(IOCTL_STORAGE_CHECK_VERIFY2)
X(IOCTL_STORAGE_EJECTION_CONTROL)
X(IOCTL_STORAGE_EJECT_MEDIA)
X(IOCTL_STORAGE_GET_DEVICE_NUMBER)
X(IOCTL_STORAGE_GET_MEDIA_TYPES)
X(IOCTL_STORAGE_GET_MEDIA_TYPES_EX)
X(IOCTL_STORAGE_LOAD_MEDIA)
X(IOCTL_STORAGE_MEDIA_REMOVAL)
X(IOCTL_STORAGE_RESET_DEVICE)
#undef X
};
static const char *iocodex(DWORD code)
{
   unsigned int i;
   static char buffer[25];
   for(i=0; i<sizeof(iocodextable)/sizeof(struct iocodexs); i++)
      if (code==iocodextable[i].code)
	 return iocodextable[i].codex;
   sprintf(buffer, "IOCTL_CODE_%x", (int)code);
   return buffer;
}

#define INQ_REPLY_LEN 36
#define INQ_CMD_LEN 6

#define FRAME_OF_ADDR(a) (((int)(a)[1] * CD_SECS + (a)[2]) * CD_FRAMES + (a)[3])
#define FRAME_OF_MSF(a) (((int)(a).M * CD_SECS + (a).S) * CD_FRAMES + (a).F)
#define FRAME_OF_TOC(toc, idx)  FRAME_OF_ADDR((toc).TrackData[idx - (toc).FirstTrack].Address)
#define MSF_OF_FRAME(m,fr) {int f=(fr); ((UCHAR *)&(m))[2]=f%CD_FRAMES;f/=CD_FRAMES;((UCHAR *)&(m))[1]=f%CD_SECS;((UCHAR *)&(m))[0]=f/CD_SECS;}

/* The documented format of DVD_LAYER_DESCRIPTOR is wrong. Even the format in the
 * DDK's header is wrong. There are four bytes at the start  defined by
 * MMC-5. The first two are the size of the structure in big-endian order as
 * defined by MMC-5. The other two are reserved.
 */
typedef struct
{
    DVD_DESCRIPTOR_HEADER Header;
    DVD_LAYER_DESCRIPTOR Descriptor;
    UCHAR Padding;
} internal_dvd_layer_descriptor;
C_ASSERT(sizeof(internal_dvd_layer_descriptor) == 22);

typedef struct
{
    DVD_DESCRIPTOR_HEADER Header;
    DVD_MANUFACTURER_DESCRIPTOR Descriptor;
    UCHAR Padding;
} internal_dvd_manufacturer_descriptor;
C_ASSERT(sizeof(internal_dvd_manufacturer_descriptor) == 2053);

static NTSTATUS CDROM_ReadTOC(int, int, CDROM_TOC*);
static NTSTATUS CDROM_GetStatusCode(int);


#ifdef linux

# ifndef IDE6_MAJOR
#  define IDE6_MAJOR 88
# endif
# ifndef IDE7_MAJOR
#  define IDE7_MAJOR 89
# endif

# ifdef CDROM_SEND_PACKET
/* structure for CDROM_PACKET_COMMAND ioctl */
/* not all Linux versions have all the fields, so we define the
 * structure ourselves to make sure */
struct linux_cdrom_generic_command
{
    unsigned char          cmd[CDROM_PACKET_SIZE];
    unsigned char         *buffer;
    unsigned int           buflen;
    int                    stat;
    struct request_sense  *sense;
    unsigned char          data_direction;
    int                    quiet;
    int                    timeout;
    void                  *reserved[1];
};
# endif  /* CDROM_SEND_PACKET */

#endif  /* linux */

/* FIXME: this is needed because we can't open simultaneously several times /dev/cdrom
 * this should be removed when a proper device interface is implemented
 * 
 * (WS) We need this to keep track of current position and to safely
 * detect media changes. Besides this should provide a great speed up
 * for toc inquiries.
 */
struct cdrom_cache {
    dev_t       device;
    ino_t       inode;
    char        toc_good; /* if false, will reread TOC from disk */
    CDROM_TOC   toc;
    SUB_Q_CURRENT_POSITION CurrentPosition;
};
/* who has more than 5 cdroms on his/her machine ?? */
/* FIXME: this should grow depending on the number of cdroms we install/configure 
 * at startup
 */
#define MAX_CACHE_ENTRIES       5
static struct cdrom_cache cdrom_cache[MAX_CACHE_ENTRIES];

static RTL_CRITICAL_SECTION cache_section;
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
{
    0, 0, &cache_section,
    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": cache_section") }
};
static RTL_CRITICAL_SECTION cache_section = { &critsect_debug, -1, 0, 0, 0, 0 };

/* Proposed media change function: not really needed at this time */
/* This is a 1 or 0 type of function */
#if 0
static int CDROM_MediaChanged(int dev)
{
   int i;

   struct cdrom_tochdr	hdr;
   struct cdrom_tocentry entry;

   if (dev < 0 || dev >= MAX_CACHE_ENTRIES)
      return 0;
   if ( ioctl(cdrom_cache[dev].fd, CDROMREADTOCHDR, &hdr) == -1 )
      return 0;

   if ( memcmp(&hdr, &cdrom_cache[dev].hdr, sizeof(struct cdrom_tochdr)) )
      return 1;

   for (i=hdr.cdth_trk0; i<=hdr.cdth_trk1+1; i++)
   {
      if (i == hdr.cdth_trk1 + 1)
      {
	 entry.cdte_track = CDROM_LEADOUT;
      } else {
         entry.cdte_track = i;
      }
      entry.cdte_format = CDROM_MSF;
      if ( ioctl(cdrom_cache[dev].fd, CDROMREADTOCENTRY, &entry) == -1)
	 return 0;
      if ( memcmp(&entry, cdrom_cache[dev].entry+i-hdr.cdth_trk0,
			      sizeof(struct cdrom_tocentry)) )
	 return 1;
   }
   return 0;
}
#endif


/******************************************************************
 *		get_parent_device
 *
 * 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
 * support the eject ioctl.
 */
#ifdef __APPLE__
static NTSTATUS get_parent_device( int fd, char *name, size_t len )
{
    NTSTATUS status = STATUS_NO_SUCH_FILE;
    struct stat st;
    int i;
    io_service_t service;
    CFMutableDictionaryRef dict;
    CFTypeRef val;

    if (fstat( fd, &st ) == -1) return FILE_GetNtStatus();
    if (!S_ISCHR( st.st_mode )) return STATUS_OBJECT_TYPE_MISMATCH;

    /* create a dictionary with the right major/minor numbers */

    if (!(dict = IOServiceMatching( kIOMediaClass ))) return STATUS_NO_MEMORY;

    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 )))
        {
            strcpy( name, "/dev/r" );
            CFStringGetCString( str, name + 6, len - 6, kCFStringEncodingUTF8 );
            CFRelease( str );
            status = STATUS_SUCCESS;
        }
        IOObjectRelease( service );
        break;

next:
        IORegistryEntryGetParentEntry( service, kIOServicePlane, &parent );
        IOObjectRelease( service );
        service = parent;
    }
    return status;
}
#endif


/******************************************************************
 *		CDROM_SyncCache                          [internal]
 *
 * Read the TOC in and store it in the cdrom_cache structure.
 * Further requests for the TOC will be copied from the cache
 * unless certain events like disk ejection is detected, in which
 * case the cache will be cleared, causing it to be resynced.
 * The cache section must be held by caller.
 */
static NTSTATUS CDROM_SyncCache(int dev, int fd)
{
#ifdef linux
   int i, tsz;
   struct cdrom_tochdr		hdr;
   struct cdrom_tocentry	entry;

   CDROM_TOC *toc = &cdrom_cache[dev].toc;
   cdrom_cache[dev].toc_good = 0;

   if (ioctl(fd, CDROMREADTOCHDR, &hdr) == -1)
   {
      WARN("(%d) -- Error occurred (%s)!\n", dev, strerror(errno));
      return FILE_GetNtStatus();
   }

   toc->FirstTrack = hdr.cdth_trk0;
   toc->LastTrack  = hdr.cdth_trk1;
   tsz = sizeof(toc->FirstTrack) + sizeof(toc->LastTrack)
       + sizeof(TRACK_DATA) * (toc->LastTrack-toc->FirstTrack+2);
   toc->Length[0] = tsz >> 8;
   toc->Length[1] = tsz;

   TRACE("caching toc from=%d to=%d\n", toc->FirstTrack, toc->LastTrack );

   for (i = toc->FirstTrack; i <= toc->LastTrack + 1; i++)
   {
     if (i == toc->LastTrack + 1)
       entry.cdte_track = CDROM_LEADOUT;
     else 
       entry.cdte_track = i;
     entry.cdte_format = CDROM_MSF;
     if (ioctl(fd, CDROMREADTOCENTRY, &entry) == -1)
     {
       WARN("error read entry (%s)\n", strerror(errno));
       return FILE_GetNtStatus();
     }
     toc->TrackData[i - toc->FirstTrack].Control = entry.cdte_ctrl;
     toc->TrackData[i - toc->FirstTrack].Adr = entry.cdte_adr;
     /* marking last track with leadout value as index */
     toc->TrackData[i - toc->FirstTrack].TrackNumber = entry.cdte_track;
     toc->TrackData[i - toc->FirstTrack].Address[0] = 0;
     toc->TrackData[i - toc->FirstTrack].Address[1] = entry.cdte_addr.msf.minute;
     toc->TrackData[i - toc->FirstTrack].Address[2] = entry.cdte_addr.msf.second;
     toc->TrackData[i - toc->FirstTrack].Address[3] = entry.cdte_addr.msf.frame;
   }
   cdrom_cache[dev].toc_good = 1;
   return STATUS_SUCCESS;

#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)

   int i, tsz;
   struct ioc_toc_header hdr;
   struct ioc_read_toc_entry entry;
   struct cd_toc_entry toc_buffer;

   CDROM_TOC *toc = &cdrom_cache[dev].toc;
   cdrom_cache[dev].toc_good = 0;

    if (ioctl(fd, CDIOREADTOCHEADER, &hdr) == -1)
    {
        WARN("(%d) -- Error occurred (%s)!\n", dev, strerror(errno));
        return FILE_GetNtStatus();
    }
    toc->FirstTrack = hdr.starting_track;
    toc->LastTrack  = hdr.ending_track;
    tsz = sizeof(toc->FirstTrack) + sizeof(toc->LastTrack)
        + sizeof(TRACK_DATA) * (toc->LastTrack-toc->FirstTrack+2);
    toc->Length[0] = tsz >> 8;
    toc->Length[1] = tsz;

    TRACE("caching toc from=%d to=%d\n", toc->FirstTrack, toc->LastTrack );

    for (i = toc->FirstTrack; i <= toc->LastTrack + 1; i++)
    {
	if (i == toc->LastTrack + 1)
        {
#define LEADOUT 0xaa
	    entry.starting_track = LEADOUT;
        } else {
            entry.starting_track = i;
        }
        memset(&toc_buffer, 0, sizeof(toc_buffer));
	entry.address_format = CD_MSF_FORMAT;
	entry.data_len = sizeof(toc_buffer);
	entry.data = &toc_buffer;
        if (ioctl(fd, CDIOREADTOCENTRYS, &entry) == -1)
        {
	    WARN("error read entry (%s)\n", strerror(errno));
            return FILE_GetNtStatus();
	}
        toc->TrackData[i - toc->FirstTrack].Control = toc_buffer.control;
        toc->TrackData[i - toc->FirstTrack].Adr = toc_buffer.addr_type;
        /* marking last track with leadout value as index */
        toc->TrackData[i - toc->FirstTrack].TrackNumber = entry.starting_track;
        toc->TrackData[i - toc->FirstTrack].Address[0] = 0;
        toc->TrackData[i - toc->FirstTrack].Address[1] = toc_buffer.addr.msf.minute;
        toc->TrackData[i - toc->FirstTrack].Address[2] = toc_buffer.addr.msf.second;
        toc->TrackData[i - toc->FirstTrack].Address[3] = toc_buffer.addr.msf.frame;
    }
    cdrom_cache[dev].toc_good = 1;
    return STATUS_SUCCESS;

#elif defined(__APPLE__)
    int i;
    dk_cd_read_toc_t hdr;
    CDROM_TOC *toc = &cdrom_cache[dev].toc;
    cdrom_cache[dev].toc_good = 0;

    memset( &hdr, 0, sizeof(hdr) );
    hdr.buffer = toc;
    hdr.bufferLength = sizeof(*toc);
    if (ioctl(fd, DKIOCCDREADTOC, &hdr) == -1)
    {
        WARN("(%d) -- Error occurred (%s)!\n", dev, strerror(errno));
        return FILE_GetNtStatus();
    }
    for (i = toc->FirstTrack; i <= toc->LastTrack + 1; i++)
    {
        /* convert address format */
        TRACK_DATA *data = &toc->TrackData[i - toc->FirstTrack];
        DWORD frame = (((DWORD)data->Address[0] << 24) | ((DWORD)data->Address[1] << 16) |
                       ((DWORD)data->Address[2] << 8) | data->Address[3]);
        MSF_OF_FRAME( data->Address[1], frame );
        data->Address[0] = 0;
    }

    cdrom_cache[dev].toc_good = 1;
    return STATUS_SUCCESS;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

static void CDROM_ClearCacheEntry(int dev)
{
    RtlEnterCriticalSection( &cache_section );
    cdrom_cache[dev].toc_good = 0;
    RtlLeaveCriticalSection( &cache_section );
}



/******************************************************************
 *		CDROM_GetInterfaceInfo
 *
 * Determines the ide interface (the number after the ide), and the
 * number of the device on that interface for ide cdroms (*iface <= 1).
 * Determines the scsi information for scsi cdroms (*iface >= 2).
 * Returns false if the info cannot not be obtained.
 */
static int CDROM_GetInterfaceInfo(int fd, UCHAR* iface, UCHAR* port, UCHAR* device, UCHAR* lun)
{
#if defined(linux)
    struct stat st;
    if ( fstat(fd, &st) == -1 || ! S_ISBLK(st.st_mode)) return 0;
    *port = 0;
    *iface = 0;
    *device = 0;
    *lun = 0;
    switch (major(st.st_rdev)) {
    case IDE0_MAJOR: *iface = 0; break;
    case IDE1_MAJOR: *iface = 1; break;
    case IDE2_MAJOR: *iface = 2; break;
    case IDE3_MAJOR: *iface = 3; break;
    case IDE4_MAJOR: *iface = 4; break;
    case IDE5_MAJOR: *iface = 5; break;
    case IDE6_MAJOR: *iface = 6; break;
    case IDE7_MAJOR: *iface = 7; break;
    default: *port = 1; break;
    }

    if (*port == 0)
        *device = (minor(st.st_rdev) >> 6);
    else
    {
#ifdef SCSI_IOCTL_GET_IDLUN
        UINT32 idlun[2];
        if (ioctl(fd, SCSI_IOCTL_GET_IDLUN, idlun) != -1)
        {
            *port = (idlun[0] >> 24) & 0xff;
            *iface = ((idlun[0] >> 16) & 0xff) + 2;
            *device = idlun[0] & 0xff;
            *lun = (idlun[0] >> 8) & 0xff;
        }
        else
#endif
        {
            WARN("CD-ROM device (%d, %d) not supported\n", major(st.st_rdev), minor(st.st_rdev));
            return 0;
        }
    }
    return 1;
#elif defined(__NetBSD__)
    struct scsi_addr addr;
    if (ioctl(fd, SCIOCIDENTIFY, &addr) != -1)
    {
        switch (addr.type)
        {
        case TYPE_SCSI:
            *port = 1;
            *iface = addr.addr.scsi.scbus;
            *device = addr.addr.scsi.target;
            *lun = addr.addr.scsi.lun;
            return 1;
        case TYPE_ATAPI:
            *port = 0;
            *iface = addr.addr.atapi.atbus;
            *device = addr.addr.atapi.drive;
            *lun = 0;
            return 1;
        }
    }
    return 0;
#elif defined(__APPLE__)
    dk_scsi_identify_t addr;
    if (ioctl(fd, DKIOCSCSIIDENTIFY, &addr) != -1)
    {
       *port = addr.bus;
       *iface = addr.port;
       *device = addr.target;
       *lun = addr.lun;
       return 1;
    }
    return 0;
#else
    FIXME("not implemented on this O/S\n");
    return 0;
#endif
}


/******************************************************************
 *		CDROM_Open
 *
 */
static NTSTATUS CDROM_Open(int fd, int* dev)
{
    struct stat st;
    NTSTATUS ret = STATUS_SUCCESS;
    int         empty = -1;

    fstat(fd, &st);

    RtlEnterCriticalSection( &cache_section );
    for (*dev = 0; *dev < MAX_CACHE_ENTRIES; (*dev)++)
    {
        if (empty == -1 &&
            cdrom_cache[*dev].device == 0 &&
            cdrom_cache[*dev].inode == 0)
            empty = *dev;
        else if (cdrom_cache[*dev].device == st.st_dev &&
                 cdrom_cache[*dev].inode == st.st_ino)
            break;
    }
    if (*dev == MAX_CACHE_ENTRIES)
    {
        if (empty == -1) ret = STATUS_NOT_IMPLEMENTED;
        else
        {
            *dev = empty;
            cdrom_cache[*dev].device  = st.st_dev;
            cdrom_cache[*dev].inode   = st.st_ino;
        }
    }
    RtlLeaveCriticalSection( &cache_section );

    TRACE("%d, %d\n", *dev, fd);
    return ret;
}

/******************************************************************
 *		CDROM_GetStatusCode
 *
 *
 */
static NTSTATUS CDROM_GetStatusCode(int io)
{
    if (io == 0) return STATUS_SUCCESS;
    return FILE_GetNtStatus();
}

/******************************************************************
 *		CDROM_GetControl
 *
 */
static NTSTATUS CDROM_GetControl(int dev, int fd, CDROM_AUDIO_CONTROL* cac)
{
#ifdef __APPLE__
    uint16_t speed;
    int io = ioctl( fd, DKIOCCDGETSPEED, &speed );
    if (io != 0) return CDROM_GetStatusCode( io );
    /* DKIOCCDGETSPEED returns the speed in kilobytes per second,
     * so convert to logical blocks (assumed to be ~2 KB).
     */
    cac->LogicalBlocksPerSecond = speed/2;
#else
    cac->LogicalBlocksPerSecond = 1; /* FIXME */
#endif
    cac->LbaFormat = 0; /* FIXME */
    return  STATUS_NOT_SUPPORTED;
}

/******************************************************************
 *		CDROM_GetDeviceNumber
 *
 */
static NTSTATUS CDROM_GetDeviceNumber(int dev, STORAGE_DEVICE_NUMBER* devnum)
{
    FIXME( "stub\n" );
    devnum->DeviceType = FILE_DEVICE_DISK;
    devnum->DeviceNumber = 1;
    devnum->PartitionNumber = 1;
    return STATUS_SUCCESS;
}

/******************************************************************
 *		CDROM_GetDriveGeometry
 *
 */
static NTSTATUS CDROM_GetDriveGeometry(int dev, int fd, DISK_GEOMETRY* dg)
{
  CDROM_TOC     toc;
  NTSTATUS      ret = 0;
  int           fsize = 0;

  if ((ret = CDROM_ReadTOC(dev, fd, &toc)) != 0) return ret;

  fsize = FRAME_OF_TOC(toc, toc.LastTrack+1)
        - FRAME_OF_TOC(toc, 1); /* Total size in frames */

  dg->Cylinders.QuadPart = fsize / (64 * 32);
  dg->MediaType = RemovableMedia;  
  dg->TracksPerCylinder = 64; 
  dg->SectorsPerTrack = 32;  
  dg->BytesPerSector= 2048; 
  return ret;
}

/******************************************************************
 *		CDROM_GetMediaType
 *
 */
static NTSTATUS CDROM_GetMediaType(int dev, GET_MEDIA_TYPES* medtype)
{
    FIXME(": faking success\n");
    medtype->DeviceType = FILE_DEVICE_CD_ROM;
    medtype->MediaInfoCount = 0;
    return STATUS_SUCCESS;
}

/**************************************************************************
 *                              CDROM_Reset                     [internal]
 */
static NTSTATUS CDROM_ResetAudio(int fd)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROMRESET));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCRESET, NULL));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_SetTray
 *
 *
 */
static NTSTATUS CDROM_SetTray(int fd, BOOL doEject)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, doEject ? CDROMEJECT : CDROMCLOSETRAY));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    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
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_ControlEjection
 *
 *
 */
static NTSTATUS CDROM_ControlEjection(int fd, const PREVENT_MEDIA_REMOVAL* rmv)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROM_LOCKDOOR, rmv->PreventMediaRemoval));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    return CDROM_GetStatusCode(ioctl(fd, (rmv->PreventMediaRemoval) ? CDIOCPREVENT : CDIOCALLOW, NULL));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_ReadTOC
 *
 *
 */
static NTSTATUS CDROM_ReadTOC(int dev, int fd, CDROM_TOC* toc)
{
    NTSTATUS       ret = STATUS_NOT_SUPPORTED;

    if (dev < 0 || dev >= MAX_CACHE_ENTRIES)
        return STATUS_INVALID_PARAMETER;

    RtlEnterCriticalSection( &cache_section );
    if (cdrom_cache[dev].toc_good || !(ret = CDROM_SyncCache(dev, fd)))
    {
        *toc = cdrom_cache[dev].toc;
        ret = STATUS_SUCCESS;
    }
    RtlLeaveCriticalSection( &cache_section );
    return ret;
}

/******************************************************************
 *		CDROM_GetDiskData
 *
 *
 */
static NTSTATUS CDROM_GetDiskData(int dev, int fd, CDROM_DISK_DATA* data)
{
    CDROM_TOC   toc;
    NTSTATUS    ret;
    int         i;

    if ((ret = CDROM_ReadTOC(dev, fd, &toc)) != 0) return ret;
    data->DiskData = 0;
    for (i = toc.FirstTrack; i <= toc.LastTrack; i++) {
        if (toc.TrackData[i-toc.FirstTrack].Control & 0x04)
            data->DiskData |= CDROM_DISK_DATA_TRACK;
        else
            data->DiskData |= CDROM_DISK_AUDIO_TRACK;
    }
    return STATUS_SUCCESS;
}

/******************************************************************
 *		CDROM_ReadQChannel
 *
 *
 */
static NTSTATUS CDROM_ReadQChannel(int dev, int fd, const CDROM_SUB_Q_DATA_FORMAT* fmt,
                                   SUB_Q_CHANNEL_DATA* data)
{
    NTSTATUS            ret = STATUS_NOT_SUPPORTED;
#ifdef linux
    SUB_Q_HEADER*       hdr = (SUB_Q_HEADER*)data;
    int                 io;
    struct cdrom_subchnl	sc;
    sc.cdsc_format = CDROM_MSF;

    io = ioctl(fd, CDROMSUBCHNL, &sc);
    if (io == -1)
    {
	TRACE("opened or no_media (%s)!\n", strerror(errno));
	hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
	CDROM_ClearCacheEntry(dev);
	goto end;
    }

    hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;

    switch (sc.cdsc_audiostatus) {
    case CDROM_AUDIO_INVALID:
	CDROM_ClearCacheEntry(dev);
	hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
	break;
    case CDROM_AUDIO_NO_STATUS:
	CDROM_ClearCacheEntry(dev);
	hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
	break;
    case CDROM_AUDIO_PLAY:
        hdr->AudioStatus = AUDIO_STATUS_IN_PROGRESS;
        break;
    case CDROM_AUDIO_PAUSED:
        hdr->AudioStatus = AUDIO_STATUS_PAUSED;
        break;
    case CDROM_AUDIO_COMPLETED:
        hdr->AudioStatus = AUDIO_STATUS_PLAY_COMPLETE;
        break;
    case CDROM_AUDIO_ERROR:
        hdr->AudioStatus = AUDIO_STATUS_PLAY_ERROR;
        break;
    default:
	TRACE("status=%02X !\n", sc.cdsc_audiostatus);
        hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
    }
    switch (fmt->Format)
    {
    case IOCTL_CDROM_CURRENT_POSITION:
        RtlEnterCriticalSection( &cache_section );
	if (hdr->AudioStatus==AUDIO_STATUS_IN_PROGRESS) {
          data->CurrentPosition.FormatCode = IOCTL_CDROM_CURRENT_POSITION;
          data->CurrentPosition.Control = sc.cdsc_ctrl; 
          data->CurrentPosition.ADR = sc.cdsc_adr; 
          data->CurrentPosition.TrackNumber = sc.cdsc_trk; 
          data->CurrentPosition.IndexNumber = sc.cdsc_ind; 

          data->CurrentPosition.AbsoluteAddress[0] = 0; 
          data->CurrentPosition.AbsoluteAddress[1] = sc.cdsc_absaddr.msf.minute; 
          data->CurrentPosition.AbsoluteAddress[2] = sc.cdsc_absaddr.msf.second;
          data->CurrentPosition.AbsoluteAddress[3] = sc.cdsc_absaddr.msf.frame;
 
          data->CurrentPosition.TrackRelativeAddress[0] = 0; 
          data->CurrentPosition.TrackRelativeAddress[1] = sc.cdsc_reladdr.msf.minute; 
          data->CurrentPosition.TrackRelativeAddress[2] = sc.cdsc_reladdr.msf.second;
          data->CurrentPosition.TrackRelativeAddress[3] = sc.cdsc_reladdr.msf.frame;

	  cdrom_cache[dev].CurrentPosition = data->CurrentPosition;
	}
	else /* not playing */
	{
	  cdrom_cache[dev].CurrentPosition.Header = *hdr; /* Preserve header info */
	  data->CurrentPosition = cdrom_cache[dev].CurrentPosition;
	}
        RtlLeaveCriticalSection( &cache_section );
        break;
    case IOCTL_CDROM_MEDIA_CATALOG:
        data->MediaCatalog.FormatCode = IOCTL_CDROM_MEDIA_CATALOG;
        {
            struct cdrom_mcn mcn;
            if ((io = ioctl(fd, CDROM_GET_MCN, &mcn)) == -1) goto end;

            data->MediaCatalog.FormatCode = IOCTL_CDROM_MEDIA_CATALOG;
            data->MediaCatalog.Mcval = 0; /* FIXME */
            memcpy(data->MediaCatalog.MediaCatalog, mcn.medium_catalog_number, 14);
            data->MediaCatalog.MediaCatalog[14] = 0;
        }
        break;
    case IOCTL_CDROM_TRACK_ISRC:
        FIXME("TrackIsrc: NIY on linux\n");
        data->TrackIsrc.FormatCode = IOCTL_CDROM_TRACK_ISRC;
        data->TrackIsrc.Tcval = 0;
        io = 0;
        break;
    }

 end:
    ret = CDROM_GetStatusCode(io);
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    SUB_Q_HEADER*       hdr = (SUB_Q_HEADER*)data;
    int                 io;
    struct ioc_read_subchannel	read_sc;
    struct cd_sub_channel_info	sc;

    read_sc.address_format = CD_MSF_FORMAT;
    read_sc.track          = 0;
    read_sc.data_len       = sizeof(sc);
    read_sc.data           = &sc;
    switch (fmt->Format)
    {
    case IOCTL_CDROM_CURRENT_POSITION:
        read_sc.data_format    = CD_CURRENT_POSITION;
        break;
    case IOCTL_CDROM_MEDIA_CATALOG:
        read_sc.data_format    = CD_MEDIA_CATALOG;
        break;
    case IOCTL_CDROM_TRACK_ISRC:
        read_sc.data_format    = CD_TRACK_INFO;
        sc.what.track_info.track_number = data->TrackIsrc.Track;
        break;
    }
    io = ioctl(fd, CDIOCREADSUBCHANNEL, &read_sc);
    if (io == -1)
    {
	TRACE("opened or no_media (%s)!\n", strerror(errno));
	CDROM_ClearCacheEntry(dev);
	hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
	goto end;
    }

    hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;

    switch (sc.header.audio_status) {
    case CD_AS_AUDIO_INVALID:
	CDROM_ClearCacheEntry(dev);
	hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
	break;
    case CD_AS_NO_STATUS:
	CDROM_ClearCacheEntry(dev);
	hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
        break;
    case CD_AS_PLAY_IN_PROGRESS:
        hdr->AudioStatus = AUDIO_STATUS_IN_PROGRESS;
        break;
    case CD_AS_PLAY_PAUSED:
        hdr->AudioStatus = AUDIO_STATUS_PAUSED;
        break;
    case CD_AS_PLAY_COMPLETED:
        hdr->AudioStatus = AUDIO_STATUS_PLAY_COMPLETE;
        break;
    case CD_AS_PLAY_ERROR:
        hdr->AudioStatus = AUDIO_STATUS_PLAY_ERROR;
        break;
    default:
	TRACE("status=%02X !\n", sc.header.audio_status);
        hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
    }
    switch (fmt->Format)
    {
    case IOCTL_CDROM_CURRENT_POSITION:
        RtlEnterCriticalSection( &cache_section );
	if (hdr->AudioStatus==AUDIO_STATUS_IN_PROGRESS) {
          data->CurrentPosition.FormatCode = IOCTL_CDROM_CURRENT_POSITION;
          data->CurrentPosition.Control = sc.what.position.control;
          data->CurrentPosition.ADR = sc.what.position.addr_type;
          data->CurrentPosition.TrackNumber = sc.what.position.track_number;
          data->CurrentPosition.IndexNumber = sc.what.position.index_number;

          data->CurrentPosition.AbsoluteAddress[0] = 0;
          data->CurrentPosition.AbsoluteAddress[1] = sc.what.position.absaddr.msf.minute;
          data->CurrentPosition.AbsoluteAddress[2] = sc.what.position.absaddr.msf.second;
          data->CurrentPosition.AbsoluteAddress[3] = sc.what.position.absaddr.msf.frame;
          data->CurrentPosition.TrackRelativeAddress[0] = 0;
          data->CurrentPosition.TrackRelativeAddress[1] = sc.what.position.reladdr.msf.minute;
          data->CurrentPosition.TrackRelativeAddress[2] = sc.what.position.reladdr.msf.second;
          data->CurrentPosition.TrackRelativeAddress[3] = sc.what.position.reladdr.msf.frame;
	  cdrom_cache[dev].CurrentPosition = data->CurrentPosition;
	}
	else { /* not playing */
	  cdrom_cache[dev].CurrentPosition.Header = *hdr; /* Preserve header info */
	  data->CurrentPosition = cdrom_cache[dev].CurrentPosition;
	}
        RtlLeaveCriticalSection( &cache_section );
        break;
    case IOCTL_CDROM_MEDIA_CATALOG:
        data->MediaCatalog.FormatCode = IOCTL_CDROM_MEDIA_CATALOG;
        data->MediaCatalog.Mcval = sc.what.media_catalog.mc_valid;
        memcpy(data->MediaCatalog.MediaCatalog, sc.what.media_catalog.mc_number, 15);
        break;
    case IOCTL_CDROM_TRACK_ISRC:
        data->TrackIsrc.FormatCode = IOCTL_CDROM_TRACK_ISRC;
        data->TrackIsrc.Tcval = sc.what.track_info.ti_valid;
        memcpy(data->TrackIsrc.TrackIsrc, sc.what.track_info.ti_number, 15);
        break;
    }

 end:
    ret = CDROM_GetStatusCode(io);
#elif defined(__APPLE__)
    SUB_Q_HEADER* hdr = (SUB_Q_HEADER*)data;
    int io = 0;
    union
    {
        dk_cd_read_mcn_t mcn;
        dk_cd_read_isrc_t isrc;
    } ioc;
    /* We need IOCDAudioControl for IOCTL_CDROM_CURRENT_POSITION */
    if (fmt->Format == IOCTL_CDROM_CURRENT_POSITION)
    {
        FIXME("NIY\n");
        return STATUS_NOT_SUPPORTED;
    }
    /* No IOCDAudioControl support; just set the audio status to none */
    hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
    switch(fmt->Format)
    {
    case IOCTL_CDROM_MEDIA_CATALOG:
        if ((io = ioctl(fd, DKIOCCDREADMCN, &ioc.mcn)) == -1) break;
        memcpy(data->MediaCatalog.MediaCatalog, ioc.mcn.mcn, kCDMCNMaxLength);
        data->MediaCatalog.Mcval = 1;
        break;
    case IOCTL_CDROM_TRACK_ISRC:
        ioc.isrc.track = fmt->Track;
        if ((io = ioctl(fd, DKIOCCDREADISRC, &ioc.isrc)) == -1) break;
        memcpy(data->TrackIsrc.TrackIsrc, ioc.isrc.isrc, kCDISRCMaxLength);
        data->TrackIsrc.Tcval = 1;
        data->TrackIsrc.Track = ioc.isrc.track;
    }
    ret = CDROM_GetStatusCode(io);
#endif
    return ret;
}

/******************************************************************
 *		CDROM_Verify
 *  Implements: IOCTL_STORAGE_CHECK_VERIFY
 *              IOCTL_CDROM_CHECK_VERIFY
 *              IOCTL_DISK_CHECK_VERIFY
 *
 */
static NTSTATUS CDROM_Verify(int dev, int fd)
{
#if defined(linux)
    int ret;

    ret = ioctl(fd,  CDROM_DRIVE_STATUS, NULL);
    if(ret == -1) {
        TRACE("ioctl CDROM_DRIVE_STATUS failed(%s)!\n", strerror(errno));
        return CDROM_GetStatusCode(ret);
    }

    if(ret == CDS_DISC_OK)
        return STATUS_SUCCESS;
    else
        return STATUS_NO_MEDIA_IN_DEVICE;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    int ret;
    ret = ioctl(fd, CDIOCSTART, NULL);
    if(ret == 0)
        return STATUS_SUCCESS;
    else
        return STATUS_NO_MEDIA_IN_DEVICE;
#elif defined(__APPLE__)
	/* At this point, we know that we have media, because in Mac OS X, the
	 * device file is only created when media is present. */
	return STATUS_SUCCESS;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_PlayAudioMSF
 *
 *
 */
static NTSTATUS CDROM_PlayAudioMSF(int fd, const CDROM_PLAY_AUDIO_MSF* audio_msf)
{
    NTSTATUS       ret = STATUS_NOT_SUPPORTED;
#ifdef linux
    struct 	cdrom_msf	msf;
    int         io;

    msf.cdmsf_min0   = audio_msf->StartingM;
    msf.cdmsf_sec0   = audio_msf->StartingS;
    msf.cdmsf_frame0 = audio_msf->StartingF;
    msf.cdmsf_min1   = audio_msf->EndingM;
    msf.cdmsf_sec1   = audio_msf->EndingS;
    msf.cdmsf_frame1 = audio_msf->EndingF;

    io = ioctl(fd, CDROMSTART);
    if (io == -1)
    {
	WARN("motor doesn't start !\n");
	goto end;
    }
    io = ioctl(fd, CDROMPLAYMSF, &msf);
    if (io == -1)
    {
	WARN("device doesn't play !\n");
	goto end;
    }
    TRACE("msf = %d:%d:%d %d:%d:%d\n",
	  msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0,
	  msf.cdmsf_min1, msf.cdmsf_sec1, msf.cdmsf_frame1);
 end:
    ret = CDROM_GetStatusCode(io);
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    struct	ioc_play_msf	msf;
    int         io;

    msf.start_m      = audio_msf->StartingM;
    msf.start_s      = audio_msf->StartingS;
    msf.start_f      = audio_msf->StartingF;
    msf.end_m        = audio_msf->EndingM;
    msf.end_s        = audio_msf->EndingS;
    msf.end_f        = audio_msf->EndingF;

    io = ioctl(fd, CDIOCSTART, NULL);
    if (io == -1)
    {
	WARN("motor doesn't start !\n");
	goto end;
    }
    io = ioctl(fd, CDIOCPLAYMSF, &msf);
    if (io == -1)
    {
	WARN("device doesn't play !\n");
	goto end;
    }
    TRACE("msf = %d:%d:%d %d:%d:%d\n",
	  msf.start_m, msf.start_s, msf.start_f,
	  msf.end_m,   msf.end_s,   msf.end_f);
end:
    ret = CDROM_GetStatusCode(io);
#endif
    return ret;
}

/******************************************************************
 *		CDROM_SeekAudioMSF
 *
 *
 */
static NTSTATUS CDROM_SeekAudioMSF(int dev, int fd, const CDROM_SEEK_AUDIO_MSF* audio_msf)
{
    CDROM_TOC toc;
    int i, io, frame;
    SUB_Q_CURRENT_POSITION *cp;
#if defined(linux)
    struct cdrom_msf0	msf;
    struct cdrom_subchnl sc;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    struct ioc_play_msf	msf;
    struct ioc_read_subchannel	read_sc;
    struct cd_sub_channel_info	sc;
    int final_frame;
#endif

    /* Use the information on the TOC to compute the new current
     * position, which is shadowed on the cache. [Portable]. */
    frame = FRAME_OF_MSF(*audio_msf);

    if ((io = CDROM_ReadTOC(dev, fd, &toc)) != 0) return io;

    for(i=toc.FirstTrack;i<=toc.LastTrack+1;i++)
      if (FRAME_OF_TOC(toc,i)>frame) break;
    if (i <= toc.FirstTrack || i > toc.LastTrack+1)
      return STATUS_INVALID_PARAMETER;
    i--;
    RtlEnterCriticalSection( &cache_section );
    cp = &cdrom_cache[dev].CurrentPosition;
    cp->FormatCode = IOCTL_CDROM_CURRENT_POSITION; 
    cp->Control = toc.TrackData[i-toc.FirstTrack].Control; 
    cp->ADR = toc.TrackData[i-toc.FirstTrack].Adr; 
    cp->TrackNumber = toc.TrackData[i-toc.FirstTrack].TrackNumber;
    cp->IndexNumber = 0; /* FIXME: where do they keep these? */
    cp->AbsoluteAddress[0] = 0; 
    cp->AbsoluteAddress[1] = toc.TrackData[i-toc.FirstTrack].Address[1];
    cp->AbsoluteAddress[2] = toc.TrackData[i-toc.FirstTrack].Address[2];
    cp->AbsoluteAddress[3] = toc.TrackData[i-toc.FirstTrack].Address[3];
    frame -= FRAME_OF_TOC(toc,i);
    cp->TrackRelativeAddress[0] = 0;
    MSF_OF_FRAME(cp->TrackRelativeAddress[1], frame); 
    RtlLeaveCriticalSection( &cache_section );

    /* If playing, then issue a seek command, otherwise do nothing */
#ifdef linux
    sc.cdsc_format = CDROM_MSF;

    io = ioctl(fd, CDROMSUBCHNL, &sc);
    if (io == -1)
    {
	TRACE("opened or no_media (%s)!\n", strerror(errno));
	CDROM_ClearCacheEntry(dev);
        return CDROM_GetStatusCode(io);
    }
    if (sc.cdsc_audiostatus==CDROM_AUDIO_PLAY)
    {
      msf.minute = audio_msf->M;
      msf.second = audio_msf->S;
      msf.frame  = audio_msf->F;
      return CDROM_GetStatusCode(ioctl(fd, CDROMSEEK, &msf));
    }
    return STATUS_SUCCESS;
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    read_sc.address_format = CD_MSF_FORMAT;
    read_sc.track          = 0;
    read_sc.data_len       = sizeof(sc);
    read_sc.data           = &sc;
    read_sc.data_format    = CD_CURRENT_POSITION;

    io = ioctl(fd, CDIOCREADSUBCHANNEL, &read_sc);
    if (io == -1)
    {
	TRACE("opened or no_media (%s)!\n", strerror(errno));
	CDROM_ClearCacheEntry(dev);
        return CDROM_GetStatusCode(io);
    }
    if (sc.header.audio_status==CD_AS_PLAY_IN_PROGRESS) 
    {

      msf.start_m      = audio_msf->M;
      msf.start_s      = audio_msf->S;
      msf.start_f      = audio_msf->F;
      final_frame = FRAME_OF_TOC(toc,toc.LastTrack+1)-1;
      MSF_OF_FRAME(msf.end_m, final_frame);

      return CDROM_GetStatusCode(ioctl(fd, CDIOCPLAYMSF, &msf));
    }
    return STATUS_SUCCESS;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_PauseAudio
 *
 *
 */
static NTSTATUS CDROM_PauseAudio(int fd)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROMPAUSE));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCPAUSE, NULL));
#else
    FIXME(": not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_ResumeAudio
 *
 *
 */
static NTSTATUS CDROM_ResumeAudio(int fd)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROMRESUME));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCRESUME, NULL));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_StopAudio
 *
 *
 */
static NTSTATUS CDROM_StopAudio(int fd)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROMSTOP));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCSTOP, NULL));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_GetVolume
 *
 *
 */
static NTSTATUS CDROM_GetVolume(int fd, VOLUME_CONTROL* vc)
{
#if defined(linux)
    struct cdrom_volctrl volc;
    int io;

    io = ioctl(fd, CDROMVOLREAD, &volc);
    if (io != -1)
    {
        vc->PortVolume[0] = volc.channel0;
        vc->PortVolume[1] = volc.channel1;
        vc->PortVolume[2] = volc.channel2;
        vc->PortVolume[3] = volc.channel3;
    }
    return CDROM_GetStatusCode(io);
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    struct  ioc_vol     volc;
    int io;

    io = ioctl(fd, CDIOCGETVOL, &volc);
    if (io != -1)
    {
        vc->PortVolume[0] = volc.vol[0];
        vc->PortVolume[1] = volc.vol[1];
        vc->PortVolume[2] = volc.vol[2];
        vc->PortVolume[3] = volc.vol[3];
    }
    return CDROM_GetStatusCode(io);
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_SetVolume
 *
 *
 */
static NTSTATUS CDROM_SetVolume(int fd, const VOLUME_CONTROL* vc)
{
#if defined(linux)
    struct cdrom_volctrl volc;

    volc.channel0 = vc->PortVolume[0];
    volc.channel1 = vc->PortVolume[1];
    volc.channel2 = vc->PortVolume[2];
    volc.channel3 = vc->PortVolume[3];

    return CDROM_GetStatusCode(ioctl(fd, CDROMVOLCTRL, &volc));
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__DragonFly__)
    struct  ioc_vol     volc;

    volc.vol[0] = vc->PortVolume[0];
    volc.vol[1] = vc->PortVolume[1];
    volc.vol[2] = vc->PortVolume[2];
    volc.vol[3] = vc->PortVolume[3];

    return CDROM_GetStatusCode(ioctl(fd, CDIOCSETVOL, &volc));
#else
    FIXME(": not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_RawRead
 *
 * Some features of this IOCTL are rather poorly documented and
 * not really intuitive either:
 *
 *   1. Although the DiskOffset parameter is meant to be a
 *      byte offset into the disk, it is in fact the sector
 *      number multiplied by 2048 regardless of the actual
 *      sector size.
 *
 *   2. The least significant 11 bits of DiskOffset are ignored.
 *
 *   3. The TrackMode parameter has no effect on the sector
 *      size. The entire raw sector (i.e. 2352 bytes of data)
 *      is always returned. IMO the TrackMode is only used
 *      to check the correct sector type.
 *
 */
static NTSTATUS CDROM_RawRead(int fd, const RAW_READ_INFO* raw, void* buffer, DWORD len, DWORD* sz)
{
    int         ret = STATUS_NOT_SUPPORTED;
    int         io = -1;
#ifdef __APPLE__
    dk_cd_read_t cdrd;
#endif

    TRACE("RAW_READ_INFO: DiskOffset=%i,%i SectorCount=%i TrackMode=%i\n buffer=%p len=%i sz=%p\n",
          raw->DiskOffset.u.HighPart, raw->DiskOffset.u.LowPart, raw->SectorCount, raw->TrackMode, buffer, len, sz);

    if (len < raw->SectorCount * 2352) return STATUS_BUFFER_TOO_SMALL;

#if defined(linux)
    if (raw->DiskOffset.u.HighPart & ~2047) {
        WARN("DiskOffset points to a sector >= 2**32\n");
        return ret;
    }

    switch (raw->TrackMode)
    {
    case YellowMode2:
    case XAForm2:
    {
        DWORD lba = raw->DiskOffset.QuadPart >> 11;
        struct cdrom_msf*       msf;
        PBYTE                   *bp; /* current buffer pointer */
        DWORD i;

        if ((lba + raw->SectorCount) >
            ((1 << 8*sizeof(msf->cdmsf_min0)) * CD_SECS * CD_FRAMES
             - CD_MSF_OFFSET)) {
            WARN("DiskOffset not accessible with MSF\n");
            return ret;
        }

        /* Linux reads only one sector at a time.
         * ioctl CDROMREADRAW takes struct cdrom_msf as an argument
         * on the contrary to what header comments state.
         */
        lba += CD_MSF_OFFSET;
        for (i = 0, bp = buffer; i < raw->SectorCount;
             i++, lba++, bp += 2352)
        {
            msf = (struct cdrom_msf*)bp;
            msf->cdmsf_min0   = lba / CD_FRAMES / CD_SECS;
            msf->cdmsf_sec0   = lba / CD_FRAMES % CD_SECS;
            msf->cdmsf_frame0 = lba % CD_FRAMES;
            io = ioctl(fd, CDROMREADRAW, msf);
            if (io != 0)
            {
                *sz = 2352 * i;
                return CDROM_GetStatusCode(io);
            }
        }
        break;
    }

    case CDDA:
    {
        struct cdrom_read_audio cdra;

        cdra.addr.lba = raw->DiskOffset.QuadPart >> 11;
        TRACE("reading at %u\n", cdra.addr.lba);
        cdra.addr_format = CDROM_LBA;
        cdra.nframes = raw->SectorCount;
        cdra.buf = buffer;
        io = ioctl(fd, CDROMREADAUDIO, &cdra);
        break;
    }

    default:
        FIXME("NIY: %d\n", raw->TrackMode);
        return STATUS_INVALID_PARAMETER;
    }
#elif defined(__APPLE__)
    /* Mac OS lets us read multiple parts of the sector at a time.
     * We can read all the sectors in at once, unlike Linux.
     */
    memset(&cdrd, 0, sizeof(cdrd));
    cdrd.offset = (raw->DiskOffset.QuadPart >> 11) * kCDSectorSizeWhole;
    cdrd.buffer = buffer;
    cdrd.bufferLength = raw->SectorCount * kCDSectorSizeWhole;
    switch (raw->TrackMode)
    {
    case YellowMode2:
        cdrd.sectorType = kCDSectorTypeMode2;
        cdrd.sectorArea = kCDSectorAreaSync | kCDSectorAreaHeader | kCDSectorAreaUser;
        break;

    case XAForm2:
        cdrd.sectorType = kCDSectorTypeMode2Form2;
        cdrd.sectorArea = kCDSectorAreaSync | kCDSectorAreaHeader | kCDSectorAreaSubHeader | kCDSectorAreaUser;
        break;

    case CDDA:
        cdrd.sectorType = kCDSectorTypeCDDA;
        cdrd.sectorArea = kCDSectorAreaUser;
        break;

    default:
        FIXME("NIY: %d\n", raw->TrackMode);
        return STATUS_INVALID_PARAMETER;
    }
    io = ioctl(fd, DKIOCCDREAD, &cdrd);
    if (io != 0)
    {
        *sz = cdrd.bufferLength;
        return CDROM_GetStatusCode(io);
    }
#else
    switch (raw->TrackMode)
    {
    case YellowMode2:
        FIXME("YellowMode2: NIY\n");
        return ret;
    case XAForm2:
        FIXME("XAForm2: NIY\n");
        return ret;
    case CDDA:
        FIXME("CDDA: NIY\n");
        return ret;
    default:
        FIXME("NIY: %d\n", raw->TrackMode);
        return STATUS_INVALID_PARAMETER;
    }
#endif

    *sz = 2352 * raw->SectorCount;
    ret = CDROM_GetStatusCode(io);
    return ret;
}

/******************************************************************
 *        CDROM_ScsiPassThroughDirect
 *        Implements IOCTL_SCSI_PASS_THROUGH_DIRECT
 *
 */
static NTSTATUS CDROM_ScsiPassThroughDirect(int fd, PSCSI_PASS_THROUGH_DIRECT pPacket)
{
    int ret = STATUS_NOT_SUPPORTED;
#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
    sg_io_hdr_t cmd;
    int io;
#elif defined HAVE_SCSIREQ_T_CMD
    scsireq_t cmd;
    int io;
#elif defined __APPLE__
    dk_scsi_command_t cmd;
    int io;
#endif

    if (pPacket->Length < sizeof(SCSI_PASS_THROUGH_DIRECT))
        return STATUS_BUFFER_TOO_SMALL;

    if (pPacket->CdbLength > 16)
        return STATUS_INVALID_PARAMETER;

#ifdef SENSEBUFLEN
    if (pPacket->SenseInfoLength > SENSEBUFLEN)
        return STATUS_INVALID_PARAMETER;
#elif defined HAVE_REQUEST_SENSE
    if (pPacket->SenseInfoLength > sizeof(struct request_sense))
        return STATUS_INVALID_PARAMETER;
#endif

    if (pPacket->DataTransferLength > 0 && !pPacket->DataBuffer)
        return STATUS_INVALID_PARAMETER;

#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
    RtlZeroMemory(&cmd, sizeof(cmd));

    cmd.interface_id   = 'S';
    cmd.cmd_len        = pPacket->CdbLength;
    cmd.mx_sb_len      = pPacket->SenseInfoLength;
    cmd.dxfer_len      = pPacket->DataTransferLength;
    cmd.dxferp         = pPacket->DataBuffer;
    cmd.cmdp           = pPacket->Cdb;
    cmd.sbp            = (unsigned char*)pPacket + pPacket->SenseInfoOffset;
    cmd.timeout        = pPacket->TimeOutValue*1000;

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_IN:
        cmd.dxfer_direction = SG_DXFER_FROM_DEV;
        break;
    case SCSI_IOCTL_DATA_OUT:
        cmd.dxfer_direction = SG_DXFER_TO_DEV;
        break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.dxfer_direction = SG_DXFER_NONE;
        break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, SG_IO, &cmd);

    pPacket->ScsiStatus         = cmd.status;
    pPacket->DataTransferLength = cmd.resid;
    pPacket->SenseInfoLength    = cmd.sb_len_wr;

    ret = CDROM_GetStatusCode(io);

#elif defined HAVE_SCSIREQ_T_CMD

    memset(&cmd, 0, sizeof(cmd));
    memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);

    cmd.cmdlen         = pPacket->CdbLength;
    cmd.databuf        = pPacket->DataBuffer;
    cmd.datalen        = pPacket->DataTransferLength;
    cmd.senselen       = pPacket->SenseInfoLength;
    cmd.timeout        = pPacket->TimeOutValue*1000; /* in milliseconds */

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_OUT:
        cmd.flags |= SCCMD_WRITE;
	break;
    case SCSI_IOCTL_DATA_IN:
        cmd.flags |= SCCMD_READ;
	break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.flags = 0;
	break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, SCIOCCOMMAND, &cmd);

    switch (cmd.retsts)
    {
    case SCCMD_OK:         break;
    case SCCMD_TIMEOUT:    return STATUS_TIMEOUT;
                           break;
    case SCCMD_BUSY:       return STATUS_DEVICE_BUSY;
                           break;
    case SCCMD_SENSE:      break;
    case SCCMD_UNKNOWN:    return STATUS_UNSUCCESSFUL;
                           break;
    }

    if (pPacket->SenseInfoLength != 0)
    {
        memcpy((char*)pPacket + pPacket->SenseInfoOffset,
	       cmd.sense, pPacket->SenseInfoLength);
    }

    pPacket->ScsiStatus = cmd.status;

    ret = CDROM_GetStatusCode(io);

#elif defined(__APPLE__)

    memset(&cmd, 0, sizeof(cmd));
    memcpy(cmd.cdb, pPacket->Cdb, pPacket->CdbLength);

    cmd.cdbSize        = pPacket->CdbLength;
    cmd.buffer         = pPacket->DataBuffer;
    cmd.bufferSize     = pPacket->DataTransferLength;
    cmd.sense          = (char*)pPacket + pPacket->SenseInfoOffset;
    cmd.senseLen       = pPacket->SenseInfoLength;
    cmd.timeout        = pPacket->TimeOutValue*1000; /* in milliseconds */

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_OUT:
        cmd.direction = kSCSIDataTransfer_FromInitiatorToTarget;
	break;
    case SCSI_IOCTL_DATA_IN:
        cmd.direction = kSCSIDataTransfer_FromTargetToInitiator;
	break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.direction = kSCSIDataTransfer_NoDataTransfer;
	break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, DKIOCSCSICOMMAND, &cmd);

    if (cmd.response == kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE)
    {
        /* Command failed */
        switch (cmd.status)
        {
        case kSCSITaskStatus_TaskTimeoutOccurred:     return STATUS_TIMEOUT;
                                                      break;
        case kSCSITaskStatus_ProtocolTimeoutOccurred: return STATUS_IO_TIMEOUT;
                                                      break;
        case kSCSITaskStatus_DeviceNotResponding:     return STATUS_DEVICE_BUSY;
                                                      break;
        case kSCSITaskStatus_DeviceNotPresent:
            return STATUS_NO_SUCH_DEVICE;
            break;
        case kSCSITaskStatus_DeliveryFailure:
            return STATUS_DEVICE_PROTOCOL_ERROR;
            break;
        case kSCSITaskStatus_No_Status:
        default:
            return STATUS_UNSUCCESSFUL;
            break;
        }
    }

    if (cmd.status != kSCSITaskStatus_No_Status)
        pPacket->ScsiStatus = cmd.status;

    ret = CDROM_GetStatusCode(io);
#endif
    return ret;
}

/******************************************************************
 *              CDROM_ScsiPassThrough
 *              Implements IOCTL_SCSI_PASS_THROUGH
 *
 */
static NTSTATUS CDROM_ScsiPassThrough(int fd, PSCSI_PASS_THROUGH pPacket)
{
    int ret = STATUS_NOT_SUPPORTED;
#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
    sg_io_hdr_t cmd;
    int io;
#elif defined HAVE_SCSIREQ_T_CMD
    scsireq_t cmd;
    int io;
#elif defined __APPLE__
    dk_scsi_command_t cmd;
    int io;
#endif

    if (pPacket->Length < sizeof(SCSI_PASS_THROUGH))
        return STATUS_BUFFER_TOO_SMALL;

    if (pPacket->CdbLength > 16)
        return STATUS_INVALID_PARAMETER;

#ifdef SENSEBUFLEN
    if (pPacket->SenseInfoLength > SENSEBUFLEN)
        return STATUS_INVALID_PARAMETER;
#elif defined HAVE_REQUEST_SENSE
    if (pPacket->SenseInfoLength > sizeof(struct request_sense))
        return STATUS_INVALID_PARAMETER;
#endif

    if (pPacket->DataTransferLength > 0 && pPacket->DataBufferOffset < sizeof(SCSI_PASS_THROUGH))
        return STATUS_INVALID_PARAMETER;

#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
    RtlZeroMemory(&cmd, sizeof(cmd));

    cmd.interface_id   = 'S';
    cmd.dxfer_len      = pPacket->DataTransferLength;
    cmd.dxferp         = (char*)pPacket + pPacket->DataBufferOffset;
    cmd.cmd_len        = pPacket->CdbLength;
    cmd.cmdp           = pPacket->Cdb;
    cmd.mx_sb_len      = pPacket->SenseInfoLength;
    cmd.timeout        = pPacket->TimeOutValue*1000;

    if(cmd.mx_sb_len > 0)
        cmd.sbp = (unsigned char*)pPacket + pPacket->SenseInfoOffset;

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_IN:
        cmd.dxfer_direction = SG_DXFER_FROM_DEV;
                             break;
    case SCSI_IOCTL_DATA_OUT:
        cmd.dxfer_direction = SG_DXFER_TO_DEV;
                             break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.dxfer_direction = SG_DXFER_NONE;
                             break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, SG_IO, &cmd);

    pPacket->ScsiStatus         = cmd.status;
    pPacket->DataTransferLength = cmd.resid;
    pPacket->SenseInfoLength    = cmd.sb_len_wr;

    ret = CDROM_GetStatusCode(io);

#elif defined HAVE_SCSIREQ_T_CMD

    memset(&cmd, 0, sizeof(cmd));
    memcpy(&(cmd.cmd), &(pPacket->Cdb), pPacket->CdbLength);

    if ( pPacket->DataBufferOffset > 0x1000 )
    {
        cmd.databuf     = (void*)pPacket->DataBufferOffset;
    }
    else
    {
        cmd.databuf     = (char*)pPacket + pPacket->DataBufferOffset;
    }

    cmd.cmdlen         = pPacket->CdbLength;
    cmd.datalen        = pPacket->DataTransferLength;
    cmd.senselen       = pPacket->SenseInfoLength;
    cmd.timeout        = pPacket->TimeOutValue*1000; /* in milliseconds */

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_OUT:
        cmd.flags |= SCCMD_WRITE;
	break;
    case SCSI_IOCTL_DATA_IN:
        cmd.flags |= SCCMD_READ;
	break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.flags = 0;
	break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, SCIOCCOMMAND, &cmd);

    switch (cmd.retsts)
    {
    case SCCMD_OK:         break;
    case SCCMD_TIMEOUT:    return STATUS_TIMEOUT;
                           break;
    case SCCMD_BUSY:       return STATUS_DEVICE_BUSY;
                           break;
    case SCCMD_SENSE:      break;
    case SCCMD_UNKNOWN:    return STATUS_UNSUCCESSFUL;
                           break;
    }

    if (pPacket->SenseInfoLength != 0)
    {
        memcpy((char*)pPacket + pPacket->SenseInfoOffset,
	       cmd.sense, pPacket->SenseInfoLength);
    }

    pPacket->ScsiStatus = cmd.status;

    ret = CDROM_GetStatusCode(io);

#elif defined(__APPLE__)

    memset(&cmd, 0, sizeof(cmd));
    memcpy(cmd.cdb, pPacket->Cdb, pPacket->CdbLength);

    cmd.cdbSize        = pPacket->CdbLength;
    cmd.buffer         = (char*)pPacket + pPacket->DataBufferOffset;
    cmd.bufferSize     = pPacket->DataTransferLength;
    cmd.sense          = (char*)pPacket + pPacket->SenseInfoOffset;
    cmd.senseLen       = pPacket->SenseInfoLength;
    cmd.timeout        = pPacket->TimeOutValue*1000; /* in milliseconds */

    switch (pPacket->DataIn)
    {
    case SCSI_IOCTL_DATA_OUT:
        cmd.direction = kSCSIDataTransfer_FromInitiatorToTarget;
	break;
    case SCSI_IOCTL_DATA_IN:
        cmd.direction = kSCSIDataTransfer_FromTargetToInitiator;
	break;
    case SCSI_IOCTL_DATA_UNSPECIFIED:
        cmd.direction = kSCSIDataTransfer_NoDataTransfer;
	break;
    default:
       return STATUS_INVALID_PARAMETER;
    }

    io = ioctl(fd, DKIOCSCSICOMMAND, &cmd);

    if (cmd.response == kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE)
    {
        /* Command failed */
        switch (cmd.status)
        {
        case kSCSITaskStatus_TaskTimeoutOccurred:
            return STATUS_TIMEOUT;
            break;
        case kSCSITaskStatus_ProtocolTimeoutOccurred:
            return STATUS_IO_TIMEOUT;
            break;
        case kSCSITaskStatus_DeviceNotResponding:
            return STATUS_DEVICE_BUSY;
            break;
        case kSCSITaskStatus_DeviceNotPresent:
            return STATUS_NO_SUCH_DEVICE;
            break;
        case kSCSITaskStatus_DeliveryFailure:
            return STATUS_DEVICE_PROTOCOL_ERROR;
            break;
        case kSCSITaskStatus_No_Status:
        default:
            return STATUS_UNSUCCESSFUL;
            break;
        }
    }

    if (cmd.status != kSCSITaskStatus_No_Status)
        pPacket->ScsiStatus = cmd.status;

    ret = CDROM_GetStatusCode(io);
#endif
    return ret;
}

/******************************************************************
 *		CDROM_ScsiGetCaps
 *
 *
 */
static NTSTATUS CDROM_ScsiGetCaps(int fd, PIO_SCSI_CAPABILITIES caps)
{
    NTSTATUS    ret = STATUS_NOT_IMPLEMENTED;

#ifdef SG_SCATTER_SZ
    caps->Length = sizeof(*caps);
    caps->MaximumTransferLength = SG_SCATTER_SZ; /* FIXME */
    caps->MaximumPhysicalPages = SG_SCATTER_SZ / page_size;
    caps->SupportedAsynchronousEvents = TRUE;
    caps->AlignmentMask = page_size;
    caps->TaggedQueuing = FALSE; /* we could check that it works and answer TRUE */
    caps->AdapterScansDown = FALSE; /* FIXME ? */
    caps->AdapterUsesPio = FALSE; /* FIXME ? */
    ret = STATUS_SUCCESS;
#elif defined __APPLE__
    uint64_t bytesr, bytesw, align;
    int io = ioctl(fd, DKIOCGETMAXBYTECOUNTREAD, &bytesr);
    if (io != 0) return CDROM_GetStatusCode(io);
    io = ioctl(fd, DKIOCGETMAXBYTECOUNTWRITE, &bytesw);
    if (io != 0) return CDROM_GetStatusCode(io);
    io = ioctl(fd, DKIOCGETMINSEGMENTALIGNMENTBYTECOUNT, &align);
    if (io != 0) return CDROM_GetStatusCode(io);
    caps->Length = sizeof(*caps);
    caps->MaximumTransferLength = bytesr < bytesw ? bytesr : bytesw;
    caps->MaximumPhysicalPages = caps->MaximumTransferLength / page_size;
    caps->SupportedAsynchronousEvents = TRUE;
    caps->AlignmentMask = align-1;
    caps->TaggedQueuing = FALSE; /* we could check that it works and answer TRUE */
    caps->AdapterScansDown = FALSE; /* FIXME ? */
    caps->AdapterUsesPio = FALSE; /* FIXME ? */
    ret = STATUS_SUCCESS;
#else
    FIXME("Unimplemented\n");
#endif
    return ret;
}

/******************************************************************
 *		CDROM_GetAddress
 *
 * implements IOCTL_SCSI_GET_ADDRESS
 */
static NTSTATUS CDROM_GetAddress(int fd, SCSI_ADDRESS* address)
{
    UCHAR portnum, busid, targetid, lun;

    address->Length = sizeof(SCSI_ADDRESS);
    if ( ! CDROM_GetInterfaceInfo(fd, &portnum, &busid, &targetid, &lun))
        return STATUS_NOT_SUPPORTED;

    address->PortNumber = portnum; /* primary=0 secondary=1 for ide */
    address->PathId = busid;       /* always 0 for ide */
    address->TargetId = targetid;  /* master=0 slave=1 for ide */
    address->Lun = lun;
    return STATUS_SUCCESS;
}

/******************************************************************
 *		DVD_StartSession
 *
 *
 */
static NTSTATUS DVD_StartSession(int fd, const DVD_SESSION_ID *sid_in, PDVD_SESSION_ID sid_out)
{
#if defined(linux)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dvd_authinfo auth_info;

    memset( &auth_info, 0, sizeof( auth_info ) );
    auth_info.type = DVD_LU_SEND_AGID;
    if (sid_in) auth_info.lsa.agid = *(const int*)sid_in; /* ?*/

    TRACE("fd 0x%08x\n",fd);
    ret =CDROM_GetStatusCode(ioctl(fd, DVD_AUTH, &auth_info));
    *sid_out = auth_info.lsa.agid;
    return ret;
#elif defined(__APPLE__)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dk_dvd_report_key_t dvdrk;
    DVDAuthenticationGrantIDInfo agid_info;

    dvdrk.format = kDVDKeyFormatAGID_CSS;
    dvdrk.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
    if(sid_in) dvdrk.grantID = *(uint8_t*)sid_in; /* ? */
    dvdrk.bufferLength = sizeof(DVDAuthenticationGrantIDInfo);
    dvdrk.buffer = &agid_info;

    ret = CDROM_GetStatusCode(ioctl(fd, DKIOCDVDREPORTKEY, &dvdrk));
    *sid_out = agid_info.grantID;
    return ret;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		DVD_EndSession
 *
 *
 */
static NTSTATUS DVD_EndSession(int fd, const DVD_SESSION_ID *sid)
{
#if defined(linux)
    dvd_authinfo auth_info;

    memset( &auth_info, 0, sizeof( auth_info ) );
    auth_info.type = DVD_INVALIDATE_AGID;
    auth_info.lsa.agid = *(const int*)sid;

    TRACE("\n");
    return CDROM_GetStatusCode(ioctl(fd, DVD_AUTH, &auth_info));
#elif defined(__APPLE__)
    dk_dvd_send_key_t dvdsk;

    dvdsk.format = kDVDKeyFormatAGID_Invalidate;
    dvdsk.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
    dvdsk.grantID = (uint8_t)*sid;

    return CDROM_GetStatusCode(ioctl(fd, DKIOCDVDSENDKEY, &dvdsk));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		DVD_SendKey
 *
 *
 */
static NTSTATUS DVD_SendKey(int fd, const DVD_COPY_PROTECT_KEY *key)
{
#if defined(linux)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dvd_authinfo auth_info;

    memset( &auth_info, 0, sizeof( auth_info ) );
    switch (key->KeyType)
    {
    case DvdChallengeKey:
	auth_info.type = DVD_HOST_SEND_CHALLENGE;
	auth_info.hsc.agid = (int)key->SessionId;
	TRACE("DvdChallengeKey ioc 0x%x\n", DVD_AUTH );
	memcpy( auth_info.hsc.chal, key->KeyData, DVD_CHALLENGE_SIZE );
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));
	break;
    case DvdBusKey2:
	auth_info.type = DVD_HOST_SEND_KEY2;
	auth_info.hsk.agid = (int)key->SessionId;

	memcpy( auth_info.hsk.key, key->KeyData, DVD_KEY_SIZE );
	
	TRACE("DvdBusKey2\n");
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));
	break;

    default:
	FIXME("Unknown Keytype 0x%x\n",key->KeyType);
    }
    return ret;
#elif defined(__APPLE__)
    dk_dvd_send_key_t dvdsk;
    union
    {
        DVDChallengeKeyInfo chal;
        DVDKey2Info key2;
    } key_desc;

    switch(key->KeyType)
    {
    case DvdChallengeKey:
        dvdsk.format = kDVDKeyFormatChallengeKey;
        dvdsk.bufferLength = sizeof(key_desc.chal);
        dvdsk.buffer = &key_desc.chal;
        OSWriteBigInt16(key_desc.chal.dataLength, 0, key->KeyLength);
        memcpy(key_desc.chal.challengeKeyValue, key->KeyData, key->KeyLength);
        break;
    case DvdBusKey2:
        dvdsk.format = kDVDKeyFormatKey2;
        dvdsk.bufferLength = sizeof(key_desc.key2);
        dvdsk.buffer = &key_desc.key2;
        OSWriteBigInt16(key_desc.key2.dataLength, 0, key->KeyLength);
        memcpy(key_desc.key2.key2Value, key->KeyData, key->KeyLength);
        break;
    case DvdInvalidateAGID:
        dvdsk.format = kDVDKeyFormatAGID_Invalidate;
        break;
    case DvdBusKey1:
    case DvdTitleKey:
    case DvdAsf:
    case DvdGetRpcKey:
    case DvdDiskKey:
        ERR("attempted to write read-only key type 0x%x\n", key->KeyType);
        return STATUS_NOT_SUPPORTED;
    case DvdSetRpcKey:
        FIXME("DvdSetRpcKey NIY\n");
        return STATUS_NOT_SUPPORTED;
    default:
        FIXME("got unknown key type 0x%x\n", key->KeyType);
        return STATUS_NOT_SUPPORTED;
    }
    dvdsk.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
    dvdsk.grantID = (uint8_t)key->SessionId;

    return CDROM_GetStatusCode(ioctl(fd, DKIOCDVDSENDKEY, &dvdsk));
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif    
}

/******************************************************************
 *		DVD_ReadKey
 *
 *
 */
static NTSTATUS DVD_ReadKey(int fd, PDVD_COPY_PROTECT_KEY key)
{
#if defined(linux)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dvd_struct dvd;
    dvd_authinfo auth_info;

    memset( &dvd, 0, sizeof( dvd_struct ) );
    memset( &auth_info, 0, sizeof( auth_info ) );
    switch (key->KeyType)
    {
    case DvdDiskKey:
	
	dvd.type = DVD_STRUCT_DISCKEY;
	dvd.disckey.agid = (int)key->SessionId;
	memset( dvd.disckey.value, 0, DVD_DISCKEY_SIZE );
	
	TRACE("DvdDiskKey\n");
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_READ_STRUCT, &dvd ));
	if (ret == STATUS_SUCCESS)
	    memcpy(key->KeyData,dvd.disckey.value,DVD_DISCKEY_SIZE);
	break;
    case DvdTitleKey:
	auth_info.type = DVD_LU_SEND_TITLE_KEY;
	auth_info.lstk.agid = (int)key->SessionId;
	auth_info.lstk.lba = (int)(key->Parameters.TitleOffset.QuadPart>>11);
	TRACE("DvdTitleKey session %d Quadpart 0x%08lx offset 0x%08x\n",
	      (int)key->SessionId, (long)key->Parameters.TitleOffset.QuadPart, 
	      auth_info.lstk.lba);
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));
	if (ret == STATUS_SUCCESS)
	    memcpy(key->KeyData, auth_info.lstk.title_key, DVD_KEY_SIZE );
	break;
    case DvdChallengeKey:

	auth_info.type = DVD_LU_SEND_CHALLENGE;
	auth_info.lsc.agid = (int)key->SessionId;

	TRACE("DvdChallengeKey\n");
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));
	if (ret == STATUS_SUCCESS)
	    memcpy( key->KeyData, auth_info.lsc.chal, DVD_CHALLENGE_SIZE );
	break;
    case DvdAsf:
	auth_info.type = DVD_LU_SEND_ASF;
	TRACE("DvdAsf\n");
	auth_info.lsasf.asf=((PDVD_ASF)key->KeyData)->SuccessFlag;
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));
	((PDVD_ASF)key->KeyData)->SuccessFlag = auth_info.lsasf.asf;
	break;
    case DvdBusKey1:
	auth_info.type = DVD_LU_SEND_KEY1;
	auth_info.lsk.agid = (int)key->SessionId;

	TRACE("DvdBusKey1\n");
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));

	if (ret == STATUS_SUCCESS)
	    memcpy( key->KeyData, auth_info.lsk.key, DVD_KEY_SIZE );
	break;
    case DvdGetRpcKey:
	auth_info.type = DVD_LU_SEND_RPC_STATE;

	TRACE("DvdGetRpcKey\n");
	ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));

	if (ret == STATUS_SUCCESS)
	{
	    ((PDVD_RPC_KEY)key->KeyData)->TypeCode = auth_info.lrpcs.type;
	    ((PDVD_RPC_KEY)key->KeyData)->RegionMask = auth_info.lrpcs.region_mask;
	    ((PDVD_RPC_KEY)key->KeyData)->RpcScheme = auth_info.lrpcs.rpc_scheme;
	    ((PDVD_RPC_KEY)key->KeyData)->UserResetsAvailable = auth_info.lrpcs.ucca;
	    ((PDVD_RPC_KEY)key->KeyData)->ManufacturerResetsAvailable = auth_info.lrpcs.vra;
	}
	break;
    default:
	FIXME("Unknown keytype 0x%x\n",key->KeyType);
    }
    return ret;
#elif defined(__APPLE__)
    union
    {
        dk_dvd_report_key_t key;
        dk_dvd_read_structure_t disk_key;
    } ioc;
    union
    {
        DVDDiscKeyInfo disk_key;
        DVDChallengeKeyInfo chal;
        DVDKey1Info key1;
        DVDTitleKeyInfo title;
        DVDAuthenticationSuccessFlagInfo asf;
        DVDRegionPlaybackControlInfo rpc;
    } desc;
    NTSTATUS ret = STATUS_NOT_SUPPORTED;

    switch(key->KeyType)
    {
    case DvdChallengeKey:
        ioc.key.format = kDVDKeyFormatChallengeKey;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        ioc.key.bufferLength = sizeof(desc.chal);
        ioc.key.buffer = &desc.chal;
        OSWriteBigInt16(desc.chal.dataLength, 0, key->KeyLength);
        break;
    case DvdBusKey1:
        ioc.key.format = kDVDKeyFormatKey1;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        ioc.key.bufferLength = sizeof(desc.key1);
        ioc.key.buffer = &desc.key1;
        OSWriteBigInt16(desc.key1.dataLength, 0, key->KeyLength);
        break;
    case DvdTitleKey:
        ioc.key.format = kDVDKeyFormatTitleKey;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        ioc.key.bufferLength = sizeof(desc.title);
        ioc.key.buffer = &desc.title;
        ioc.key.address = (uint32_t)(key->Parameters.TitleOffset.QuadPart>>11);
        OSWriteBigInt16(desc.title.dataLength, 0, key->KeyLength);
        break;
    case DvdAsf:
        ioc.key.format = kDVDKeyFormatASF;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        ioc.key.bufferLength = sizeof(desc.asf);
        ioc.key.buffer = &desc.asf;
        OSWriteBigInt16(desc.asf.dataLength, 0, key->KeyLength);
        break;
    case DvdGetRpcKey:
        ioc.key.format = kDVDKeyFormatRegionState;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        ioc.key.bufferLength = sizeof(desc.rpc);
        ioc.key.buffer = &desc.rpc;
        OSWriteBigInt16(desc.rpc.dataLength, 0, key->KeyLength);
        break;
    case DvdDiskKey:
        ioc.disk_key.format = kDVDStructureFormatDiscKeyInfo;
        ioc.disk_key.grantID = (uint8_t)key->SessionId;
        ioc.disk_key.bufferLength = sizeof(desc.disk_key);
        ioc.disk_key.buffer = &desc.disk_key;
        break;
    case DvdInvalidateAGID:
        ioc.key.format = kDVDKeyFormatAGID_Invalidate;
        ioc.key.grantID = (uint8_t)key->SessionId;
        ioc.key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
        break;
    case DvdBusKey2:
    case DvdSetRpcKey:
        ERR("attempted to read write-only key type 0x%x\n", key->KeyType);
        return STATUS_NOT_SUPPORTED;
    default:
        FIXME("got unknown key type 0x%x\n", key->KeyType);
        return STATUS_NOT_SUPPORTED;
    }

    ret = CDROM_GetStatusCode(ioctl(fd, (key->KeyType == DvdDiskKey ? DKIOCDVDREADSTRUCTURE : DKIOCDVDREPORTKEY), &ioc));

    if (ret == STATUS_SUCCESS)
    {
        switch(key->KeyType)
        {
        case DvdChallengeKey:
            key->KeyLength = OSReadBigInt16(desc.chal.dataLength, 0);
            memcpy(key->KeyData, desc.chal.challengeKeyValue, key->KeyLength);
            break;
        case DvdBusKey1:
            key->KeyLength = OSReadBigInt16(desc.key1.dataLength, 0);
            memcpy(key->KeyData, desc.key1.key1Value, key->KeyLength);
            break;
        case DvdTitleKey:
            key->KeyLength = OSReadBigInt16(desc.title.dataLength, 0);
            memcpy(key->KeyData, desc.title.titleKeyValue, key->KeyLength);
            key->KeyFlags = 0;
            if (desc.title.CPM)
            {
                /*key->KeyFlags |= DVD_COPYRIGHTED;*/
                if (desc.title.CP_SEC) key->KeyFlags |= DVD_SECTOR_PROTECTED;
                /*else key->KeyFlags |= DVD_SECTOR_NOT_PROTECTED;*/
#if 0
                switch (desc.title.CGMS)
                {
                case 0:
                    key->KeyFlags |= DVD_CGMS_COPY_PERMITTED;
                    break;
                case 2:
                    key->KeyFlags |= DVD_CGMS_COPY_ONCE;
                    break;
                case 3:
                    key->KeyFlags |= DVD_CGMS_NO_COPY;
                    break;
                }
#endif
            } /*else key->KeyFlags |= DVD_NOT_COPYRIGHTED;*/
            break;
        case DvdAsf:
            key->KeyLength = OSReadBigInt16(desc.title.dataLength, 0);
            ((PDVD_ASF)key->KeyData)->SuccessFlag = desc.asf.successFlag;
            break;
        case DvdGetRpcKey:
            key->KeyLength = OSReadBigInt16(desc.rpc.dataLength, 0);
            ((PDVD_RPC_KEY)key->KeyData)->UserResetsAvailable =
                desc.rpc.numberUserResets;
            ((PDVD_RPC_KEY)key->KeyData)->ManufacturerResetsAvailable =
                desc.rpc.numberVendorResets;
            ((PDVD_RPC_KEY)key->KeyData)->TypeCode =
                desc.rpc.typeCode;
            ((PDVD_RPC_KEY)key->KeyData)->RegionMask =
                desc.rpc.driveRegion;
            ((PDVD_RPC_KEY)key->KeyData)->RpcScheme =
                desc.rpc.rpcScheme;
        case DvdDiskKey:
            key->KeyLength = OSReadBigInt16(desc.disk_key.dataLength, 0);
            memcpy(key->KeyData, desc.disk_key.discKeyStructures, key->KeyLength);
            break;
        case DvdBusKey2:
        case DvdSetRpcKey:
        case DvdInvalidateAGID:
        default:
            /* Silence warning */
            ;
        }
    }
    return ret;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		DVD_GetRegion
 *
 * This IOCTL combines information from both IOCTL_DVD_READ_KEY
 * with key type DvdGetRpcKey and IOCTL_DVD_READ_STRUCTURE with
 * structure type DvdCopyrightInformation into one structure.
 */
static NTSTATUS DVD_GetRegion(int fd, PDVD_REGION region)
{
#if defined(linux)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dvd_struct dvd;
    dvd_authinfo auth_info;

    dvd.type = DVD_STRUCT_COPYRIGHT;
    dvd.copyright.layer_num = 0;
    auth_info.type = DVD_LU_SEND_RPC_STATE;

    ret = CDROM_GetStatusCode(ioctl( fd, DVD_AUTH, &auth_info ));

    if (ret == STATUS_SUCCESS)
    {
        ret = CDROM_GetStatusCode(ioctl( fd, DVD_READ_STRUCT, &dvd ));

        if (ret == STATUS_SUCCESS)
        {
            region->CopySystem = dvd.copyright.cpst;
            region->RegionData = dvd.copyright.rmi;
            region->SystemRegion = auth_info.lrpcs.region_mask;
            region->ResetCount = auth_info.lrpcs.ucca;
        }
    }
    return ret;
#elif defined(__APPLE__)
    dk_dvd_report_key_t key;
    dk_dvd_read_structure_t dvd;
    DVDRegionPlaybackControlInfo rpc;
    DVDCopyrightInfo copy;
    NTSTATUS ret = STATUS_NOT_SUPPORTED;

    key.format = kDVDKeyFormatRegionState;
    key.keyClass = kDVDKeyClassCSS_CPPM_CPRM;
    key.bufferLength = sizeof(rpc);
    key.buffer = &rpc;
    dvd.format = kDVDStructureFormatCopyrightInfo;
    dvd.bufferLength = sizeof(copy);
    dvd.buffer = &copy;

    ret = CDROM_GetStatusCode(ioctl( fd, DKIOCDVDREPORTKEY, &key ));

    if (ret == STATUS_SUCCESS)
    {
        ret = CDROM_GetStatusCode(ioctl( fd, DKIOCDVDREADSTRUCTURE, &dvd ));

        if (ret == STATUS_SUCCESS)
        {
            region->CopySystem = copy.copyrightProtectionSystemType;
            region->RegionData = copy.regionMask;
            region->SystemRegion = rpc.driveRegion;
            region->ResetCount = rpc.numberUserResets;
        }
    }
    return ret;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		DVD_ReadStructure
 *
 *
 */
static NTSTATUS DVD_ReadStructure(int dev, const DVD_READ_STRUCTURE *structure, PDVD_LAYER_DESCRIPTOR layer)
{
#ifdef DVD_READ_STRUCT
    /* dvd_struct is not defined consistently across platforms */
    union
    {
	struct dvd_physical	physical;
	struct dvd_copyright	copyright;
	struct dvd_disckey	disckey;
	struct dvd_bca		bca;
	struct dvd_manufact	manufact;
    } s;

    if (structure->BlockByteOffset.QuadPart) FIXME(": BlockByteOffset is not handled\n");

    switch (structure->Format)
    {
    case DvdPhysicalDescriptor:
        s.physical.type = DVD_STRUCT_PHYSICAL;
        s.physical.layer_num = structure->LayerNumber;
        break;

    case DvdCopyrightDescriptor:
        s.copyright.type = DVD_STRUCT_COPYRIGHT;
        s.copyright.layer_num = structure->LayerNumber;
        break;

    case DvdDiskKeyDescriptor:
        s.disckey.type = DVD_STRUCT_DISCKEY;
        s.disckey.agid = structure->SessionId;
        break;

    case DvdBCADescriptor:
        s.bca.type = DVD_STRUCT_BCA;
        break;

    case DvdManufacturerDescriptor:
        s.manufact.type = DVD_STRUCT_MANUFACT;
        s.manufact.layer_num = structure->LayerNumber;
        break;

    case DvdMaxDescriptor: /* This is not a real request, no matter what MSDN says! */
    default:
        return STATUS_INVALID_PARAMETER;
    }

    if (ioctl(dev, DVD_READ_STRUCT, &s) < 0)
       return STATUS_INVALID_PARAMETER;

    switch (structure->Format)
    {
    case DvdPhysicalDescriptor:
        {
            internal_dvd_layer_descriptor *p = (internal_dvd_layer_descriptor *) layer;
            struct dvd_layer *l = &s.physical.layer[s.physical.layer_num];

            p->Header.Length = 0x0802;
            p->Header.Reserved[0] = 0;
            p->Header.Reserved[1] = 0;
            p->Descriptor.BookVersion = l->book_version;
            p->Descriptor.BookType = l->book_type;
            p->Descriptor.MinimumRate = l->min_rate;
            p->Descriptor.DiskSize = l->disc_size;
            p->Descriptor.LayerType = l->layer_type;
            p->Descriptor.TrackPath = l->track_path;
            p->Descriptor.NumberOfLayers = l->nlayers;
            p->Descriptor.Reserved1 = 0;
            p->Descriptor.TrackDensity = l->track_density;
            p->Descriptor.LinearDensity = l->linear_density;
            p->Descriptor.StartingDataSector = GET_BE_DWORD(l->start_sector);
            p->Descriptor.EndDataSector = GET_BE_DWORD(l->end_sector);
            p->Descriptor.EndLayerZeroSector = GET_BE_DWORD(l->end_sector_l0);
            p->Descriptor.Reserved5 = 0;
            p->Descriptor.BCAFlag = l->bca;
        }
        break;

    case DvdCopyrightDescriptor:
        {
            PDVD_COPYRIGHT_DESCRIPTOR p = (PDVD_COPYRIGHT_DESCRIPTOR) layer;

            p->CopyrightProtectionType = s.copyright.cpst;
            p->RegionManagementInformation = s.copyright.rmi;
            p->Reserved = 0;
        }
        break;

    case DvdDiskKeyDescriptor:
        {
            PDVD_DISK_KEY_DESCRIPTOR p = (PDVD_DISK_KEY_DESCRIPTOR) layer;

            memcpy(p->DiskKeyData, s.disckey.value, 2048);
        }
        break;

    case DvdBCADescriptor:
        {
            PDVD_BCA_DESCRIPTOR p = (PDVD_BCA_DESCRIPTOR) layer;

            memcpy(p->BCAInformation, s.bca.value, s.bca.len);
        }
        break;

    case DvdManufacturerDescriptor:
        {
            internal_dvd_manufacturer_descriptor *p = (internal_dvd_manufacturer_descriptor*) layer;

            p->Header.Length = 0x0802;
            p->Header.Reserved[0] = 0;
            p->Header.Reserved[1] = 0;
            memcpy(p->Descriptor.ManufacturingInformation, s.manufact.value, 2048);
        }
        break;

    case DvdMaxDescriptor: /* Suppress warning */
	break;
    }
#elif defined(__APPLE__)
    NTSTATUS ret = STATUS_NOT_SUPPORTED;
    dk_dvd_read_structure_t dvdrs;
    union
    {
        DVDPhysicalFormatInfo phys;
        DVDCopyrightInfo copy;
        DVDDiscKeyInfo disk_key;
        DVDManufacturingInfo manf;
    } desc;
    union
    {
        PDVD_LAYER_DESCRIPTOR layer;
        internal_dvd_layer_descriptor *xlayer;
        PDVD_COPYRIGHT_DESCRIPTOR copy;
        PDVD_DISK_KEY_DESCRIPTOR disk_key;
        internal_dvd_manufacturer_descriptor *manf;
    } nt_desc;

    nt_desc.layer = layer;
    RtlZeroMemory(&dvdrs, sizeof(dvdrs));
    dvdrs.address = (uint32_t)(structure->BlockByteOffset.QuadPart>>11);
    dvdrs.grantID = (uint8_t)structure->SessionId;
    dvdrs.layer = structure->LayerNumber;
    switch(structure->Format)
    {
    case DvdPhysicalDescriptor:
        dvdrs.format = kDVDStructureFormatPhysicalFormatInfo;
        dvdrs.bufferLength = sizeof(desc.phys);
        dvdrs.buffer = &desc.phys;
        break;

    case DvdCopyrightDescriptor:
        dvdrs.format = kDVDStructureFormatCopyrightInfo;
        dvdrs.bufferLength = sizeof(desc.copy);
        dvdrs.buffer = &desc.copy;
        break;

    case DvdDiskKeyDescriptor:
        dvdrs.format = kDVDStructureFormatDiscKeyInfo;
        dvdrs.bufferLength = sizeof(desc.disk_key);
        dvdrs.buffer = &desc.disk_key;
        break;

    case DvdBCADescriptor:
        FIXME("DvdBCADescriptor NIY\n");
        return STATUS_NOT_SUPPORTED;

    case DvdManufacturerDescriptor:
        dvdrs.format = kDVDStructureFormatManufacturingInfo;
        dvdrs.bufferLength = sizeof(desc.manf);
        dvdrs.buffer = &desc.manf;
        break;

    case DvdMaxDescriptor:
    default:
        FIXME("got unknown structure type 0x%x\n", structure->Format);
        return STATUS_NOT_SUPPORTED;
    }
    ret = CDROM_GetStatusCode(ioctl(dev, DKIOCDVDREADSTRUCTURE, &dvdrs));
    if(ret == STATUS_SUCCESS)
    {
        switch(structure->Format)
        {
        case DvdPhysicalDescriptor:
            nt_desc.xlayer->Header.Length = 0x0802;
            nt_desc.xlayer->Header.Reserved[0] = 0;
            nt_desc.xlayer->Header.Reserved[1] = 0;
            nt_desc.xlayer->Descriptor.BookVersion = desc.phys.partVersion;
            nt_desc.xlayer->Descriptor.BookType = desc.phys.bookType;
            nt_desc.xlayer->Descriptor.MinimumRate = desc.phys.minimumRate;
            nt_desc.xlayer->Descriptor.DiskSize = desc.phys.discSize;
            nt_desc.xlayer->Descriptor.LayerType = desc.phys.layerType;
            nt_desc.xlayer->Descriptor.TrackPath = desc.phys.trackPath;
            nt_desc.xlayer->Descriptor.NumberOfLayers = desc.phys.numberOfLayers;
            nt_desc.xlayer->Descriptor.Reserved1 = 0;
            nt_desc.xlayer->Descriptor.TrackDensity = desc.phys.trackDensity;
            nt_desc.xlayer->Descriptor.LinearDensity = desc.phys.linearDensity;
            nt_desc.xlayer->Descriptor.StartingDataSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero1);
            nt_desc.xlayer->Descriptor.EndDataSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero2);
            nt_desc.xlayer->Descriptor.EndLayerZeroSector = GET_BE_DWORD(*(DWORD *)&desc.phys.zero3);
            nt_desc.xlayer->Descriptor.Reserved5 = 0;
            nt_desc.xlayer->Descriptor.BCAFlag = desc.phys.bcaFlag;
            break;

        case DvdCopyrightDescriptor:
            nt_desc.copy->CopyrightProtectionType =
                desc.copy.copyrightProtectionSystemType;
            nt_desc.copy->RegionManagementInformation =
                desc.copy.regionMask;
            nt_desc.copy->Reserved = 0;
            break;

        case DvdDiskKeyDescriptor:
            memcpy(
                nt_desc.disk_key->DiskKeyData,
                desc.disk_key.discKeyStructures,
                2048);
            break;

        case DvdManufacturerDescriptor:
            nt_desc.manf->Header.Length = 0x0802;
            nt_desc.manf->Header.Reserved[0] = 0;
            nt_desc.manf->Header.Reserved[1] = 0;
            memcpy(
                nt_desc.manf->Descriptor.ManufacturingInformation,
                desc.manf.discManufacturingInfo,
                2048);
            break;

        case DvdBCADescriptor:
        case DvdMaxDescriptor:
        default:
            /* Silence warning */
            break;
        }
    }
    return ret;
#else
    FIXME("\n");
#endif
    return STATUS_SUCCESS;

}

/******************************************************************
 *        GetInquiryData
 *        Implements the IOCTL_GET_INQUIRY_DATA ioctl.
 *        Returns Inquiry data for all devices on the specified scsi bus
 *        Returns STATUS_BUFFER_TOO_SMALL if the output buffer is too small, 
 *        STATUS_INVALID_DEVICE_REQUEST if the given handle isn't to a SCSI device,
 *        or STATUS_NOT_SUPPORTED if the OS driver is too old
 */
static NTSTATUS GetInquiryData(int fd, PSCSI_ADAPTER_BUS_INFO BufferOut, DWORD OutBufferSize)
{
#ifdef HAVE_SG_IO_HDR_T_INTERFACE_ID
    PSCSI_INQUIRY_DATA pInquiryData = NULL;
    UCHAR sense_buffer[32];
    int iochk, version;
    sg_io_hdr_t iocmd;
    UCHAR inquiry[INQ_CMD_LEN] = {INQUIRY, 0, 0, 0, INQ_REPLY_LEN, 0};

    /* Check we have a SCSI device and a supported driver */
    if(ioctl(fd, SG_GET_VERSION_NUM, &version) != 0)
    {
        WARN("IOCTL_SCSI_GET_INQUIRY_DATA sg driver is not loaded\n");
        return STATUS_INVALID_DEVICE_REQUEST;
    }
    if(version < 30000 )
        return STATUS_NOT_SUPPORTED;

    /* FIXME: Enumerate devices on the bus */
    BufferOut->NumberOfBuses = 1;
    BufferOut->BusData[0].NumberOfLogicalUnits = 1;
    BufferOut->BusData[0].InquiryDataOffset = sizeof(SCSI_ADAPTER_BUS_INFO);

    pInquiryData = (PSCSI_INQUIRY_DATA)(BufferOut + 1);

    RtlZeroMemory(&iocmd, sizeof(iocmd));
    iocmd.interface_id = 'S';
    iocmd.cmd_len = sizeof(inquiry);
    iocmd.mx_sb_len = sizeof(sense_buffer);
    iocmd.dxfer_direction = SG_DXFER_FROM_DEV;
    iocmd.dxfer_len = INQ_REPLY_LEN;
    iocmd.dxferp = pInquiryData->InquiryData;
    iocmd.cmdp = inquiry;
    iocmd.sbp = sense_buffer;
    iocmd.timeout = 1000;

    iochk = ioctl(fd, SG_IO, &iocmd);
    if(iochk != 0)
        WARN("ioctl SG_IO returned %d, error (%s)\n", iochk, strerror(errno));

    CDROM_GetInterfaceInfo(fd, &BufferOut->BusData[0].InitiatorBusId, &pInquiryData->PathId, &pInquiryData->TargetId, &pInquiryData->Lun);
    pInquiryData->DeviceClaimed = TRUE;
    pInquiryData->InquiryDataLength = INQ_REPLY_LEN;
    pInquiryData->NextInquiryDataOffset = 0;
    return STATUS_SUCCESS;
#else
    FIXME("not supported on this O/S\n");
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		CDROM_DeviceIoControl
 *
 *
 */
NTSTATUS CDROM_DeviceIoControl(HANDLE hDevice, 
                               HANDLE hEvent, PIO_APC_ROUTINE UserApcRoutine,
                               PVOID UserApcContext, 
                               PIO_STATUS_BLOCK piosb, 
                               ULONG dwIoControlCode,
                               LPVOID lpInBuffer, DWORD nInBufferSize,
                               LPVOID lpOutBuffer, DWORD nOutBufferSize)
{
    DWORD       sz = 0;
    NTSTATUS    status = STATUS_SUCCESS;
    int fd, needs_close, dev;

    TRACE("%p %s %p %d %p %d %p\n",
          hDevice, iocodex(dwIoControlCode), lpInBuffer, nInBufferSize,
          lpOutBuffer, nOutBufferSize, piosb);

    piosb->Information = 0;

    if ((status = server_get_unix_fd( hDevice, 0, &fd, &needs_close, NULL, NULL )))
    {
        if (status == STATUS_BAD_DEVICE_TYPE) return status;  /* no associated fd */
        goto error;
    }

    if ((status = CDROM_Open(fd, &dev)))
    {
        if (needs_close) close( fd );
        goto error;
    }

#ifdef __APPLE__
    {
        char name[100];

        /* This is ugly as hell, but Mac OS is unable to do anything from the
         * partition fd, it wants an fd for the whole device, and it sometimes
         * also requires the device fd 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 we're trying to eject the disk.
         */
        if ((status = get_parent_device( fd, name, sizeof(name) ))) goto error;
        if (dwIoControlCode == IOCTL_STORAGE_EJECT_MEDIA)
            NtClose( hDevice );
        if (needs_close) close( fd );
        TRACE("opening parent %s\n", name );
        if ((fd = open( name, O_RDONLY )) == -1)
        {
            status = FILE_GetNtStatus();
            goto error;
        }
        needs_close = 1;
    }
#endif

    switch (dwIoControlCode)
    {
    case IOCTL_CDROM_CHECK_VERIFY:
    case IOCTL_DISK_CHECK_VERIFY:
    case IOCTL_STORAGE_CHECK_VERIFY:
    case IOCTL_STORAGE_CHECK_VERIFY2:
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_Verify(dev, fd);
        break;

/* EPP     case IOCTL_STORAGE_CHECK_VERIFY2: */

/* EPP     case IOCTL_STORAGE_FIND_NEW_DEVICES: */
/* EPP     case IOCTL_CDROM_FIND_NEW_DEVICES: */

    case IOCTL_STORAGE_LOAD_MEDIA:
    case IOCTL_CDROM_LOAD_MEDIA:
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_SetTray(fd, FALSE);
        break;
     case IOCTL_STORAGE_EJECT_MEDIA:
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else
            status = CDROM_SetTray(fd, TRUE);
        break;

    case IOCTL_CDROM_MEDIA_REMOVAL:
    case IOCTL_DISK_MEDIA_REMOVAL:
    case IOCTL_STORAGE_MEDIA_REMOVAL:
    case IOCTL_STORAGE_EJECTION_CONTROL:
        /* FIXME the last ioctl:s is not the same as the two others...
         * lockcount/owner should be handled */
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpOutBuffer != NULL || nOutBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nInBufferSize < sizeof(PREVENT_MEDIA_REMOVAL)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ControlEjection(fd, lpInBuffer);
        break;

    case IOCTL_DISK_GET_MEDIA_TYPES:
    case IOCTL_STORAGE_GET_MEDIA_TYPES:
    case IOCTL_STORAGE_GET_MEDIA_TYPES_EX:
        sz = sizeof(GET_MEDIA_TYPES);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetMediaType(dev, lpOutBuffer);
        break;

    case IOCTL_STORAGE_GET_DEVICE_NUMBER:
        sz = sizeof(STORAGE_DEVICE_NUMBER);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetDeviceNumber(dev, lpOutBuffer);
        break;

    case IOCTL_STORAGE_RESET_DEVICE:
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_ResetAudio(fd);
        break;

    case IOCTL_CDROM_GET_CONTROL:
        sz = sizeof(CDROM_AUDIO_CONTROL);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetControl(dev, fd, lpOutBuffer);
        break;

    case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
        sz = sizeof(DISK_GEOMETRY);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetDriveGeometry(dev, fd, lpOutBuffer);
        break;

    case IOCTL_CDROM_DISK_TYPE:
        sz = sizeof(CDROM_DISK_DATA);
	/* CDROM_ClearCacheEntry(dev); */
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetDiskData(dev, fd, lpOutBuffer);
        break;

/* EPP     case IOCTL_CDROM_GET_LAST_SESSION: */

    case IOCTL_CDROM_READ_Q_CHANNEL:
        sz = sizeof(SUB_Q_CHANNEL_DATA);
        if (lpInBuffer == NULL || nInBufferSize < sizeof(CDROM_SUB_Q_DATA_FORMAT))
            status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ReadQChannel(dev, fd, lpInBuffer, lpOutBuffer);
        break;

    case IOCTL_CDROM_READ_TOC:
        sz = sizeof(CDROM_TOC);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ReadTOC(dev, fd, lpOutBuffer);
        break;

/* EPP     case IOCTL_CDROM_READ_TOC_EX: */

    case IOCTL_CDROM_PAUSE_AUDIO:
        sz = 0;
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_PauseAudio(fd);
        break;
    case IOCTL_CDROM_PLAY_AUDIO_MSF:
        sz = 0;
        if (lpOutBuffer != NULL || nOutBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nInBufferSize < sizeof(CDROM_PLAY_AUDIO_MSF)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_PlayAudioMSF(fd, lpInBuffer);
        break;
    case IOCTL_CDROM_RESUME_AUDIO:
        sz = 0;
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_ResumeAudio(fd);
        break;
    case IOCTL_CDROM_SEEK_AUDIO_MSF:
        sz = 0;
        if (lpOutBuffer != NULL || nOutBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nInBufferSize < sizeof(CDROM_SEEK_AUDIO_MSF)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_SeekAudioMSF(dev, fd, lpInBuffer);
        break;
    case IOCTL_CDROM_STOP_AUDIO:
        sz = 0;
	CDROM_ClearCacheEntry(dev); /* Maybe intention is to change media */
        if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_StopAudio(fd);
        break;
    case IOCTL_CDROM_GET_VOLUME:
        sz = sizeof(VOLUME_CONTROL);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetVolume(fd, lpOutBuffer);
        break;
    case IOCTL_CDROM_SET_VOLUME:
        sz = 0;
	CDROM_ClearCacheEntry(dev);
        if (lpInBuffer == NULL || nInBufferSize < sizeof(VOLUME_CONTROL) || lpOutBuffer != NULL)
            status = STATUS_INVALID_PARAMETER;
        else status = CDROM_SetVolume(fd, lpInBuffer);
        break;
    case IOCTL_CDROM_RAW_READ:
        sz = 0;
        if (nInBufferSize < sizeof(RAW_READ_INFO)) status = STATUS_INVALID_PARAMETER;
        else if (lpOutBuffer == NULL) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_RawRead(fd, lpInBuffer, lpOutBuffer,
                                    nOutBufferSize, &sz);
        break;
    case IOCTL_SCSI_GET_ADDRESS:
        sz = sizeof(SCSI_ADDRESS);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_GetAddress(fd, lpOutBuffer);
        break;
    case IOCTL_SCSI_PASS_THROUGH_DIRECT:
        sz = sizeof(SCSI_PASS_THROUGH_DIRECT);
        if (lpOutBuffer == NULL) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sizeof(SCSI_PASS_THROUGH_DIRECT)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ScsiPassThroughDirect(fd, lpOutBuffer);
        break;
    case IOCTL_SCSI_PASS_THROUGH:
        sz = sizeof(SCSI_PASS_THROUGH);
        if (lpOutBuffer == NULL) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sizeof(SCSI_PASS_THROUGH)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ScsiPassThrough(fd, lpOutBuffer);
        break;
    case IOCTL_SCSI_GET_CAPABILITIES:
        sz = sizeof(IO_SCSI_CAPABILITIES);
        if (lpOutBuffer == NULL) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sizeof(IO_SCSI_CAPABILITIES)) status = STATUS_BUFFER_TOO_SMALL;
        else status = CDROM_ScsiGetCaps(fd, lpOutBuffer);
        break;
    case IOCTL_DVD_START_SESSION:
        sz = sizeof(DVD_SESSION_ID);
        if (lpOutBuffer == NULL) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        else
        {
            TRACE("before in 0x%08x out 0x%08x\n",(lpInBuffer)?*(PDVD_SESSION_ID)lpInBuffer:0,
                  *(PDVD_SESSION_ID)lpOutBuffer);
            status = DVD_StartSession(fd, lpInBuffer, lpOutBuffer);
            TRACE("before in 0x%08x out 0x%08x\n",(lpInBuffer)?*(PDVD_SESSION_ID)lpInBuffer:0,
                  *(PDVD_SESSION_ID)lpOutBuffer);
        }
        break;
    case IOCTL_DVD_END_SESSION:
        sz = sizeof(DVD_SESSION_ID);
        if ((lpInBuffer == NULL) ||  (nInBufferSize < sz))status = STATUS_INVALID_PARAMETER;
        else status = DVD_EndSession(fd, lpInBuffer);
        break;
    case IOCTL_DVD_SEND_KEY:
        sz = 0;
        if (!lpInBuffer ||
            (((PDVD_COPY_PROTECT_KEY)lpInBuffer)->KeyLength != nInBufferSize))
            status = STATUS_INVALID_PARAMETER;
        else
        {
            TRACE("doing DVD_SendKey\n");
            status = DVD_SendKey(fd, lpInBuffer);
        }
        break;
    case IOCTL_DVD_READ_KEY:
        if (!lpInBuffer ||
            (((PDVD_COPY_PROTECT_KEY)lpInBuffer)->KeyLength != nInBufferSize))
            status = STATUS_INVALID_PARAMETER;
        else if (lpInBuffer !=lpOutBuffer) status = STATUS_BUFFER_TOO_SMALL;
        else
        {
            TRACE("doing DVD_READ_KEY\n");
            sz = ((PDVD_COPY_PROTECT_KEY)lpInBuffer)->KeyLength;
            status = DVD_ReadKey(fd, lpInBuffer);
        }
        break;
    case IOCTL_DVD_GET_REGION:
        sz = sizeof(DVD_REGION);
        if (lpInBuffer != NULL || nInBufferSize != 0) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz) status = STATUS_BUFFER_TOO_SMALL;
        TRACE("doing DVD_Get_REGION\n");
        status = DVD_GetRegion(fd, lpOutBuffer);
        break;
    case IOCTL_DVD_READ_STRUCTURE:
        sz = sizeof(DVD_LAYER_DESCRIPTOR);
        if (lpInBuffer == NULL || nInBufferSize != sizeof(DVD_READ_STRUCTURE)) status = STATUS_INVALID_PARAMETER;
        else if (nOutBufferSize < sz || !lpOutBuffer) status = STATUS_BUFFER_TOO_SMALL;
        else
        {
            TRACE("doing DVD_READ_STRUCTURE\n");
            status = DVD_ReadStructure(fd, lpInBuffer, lpOutBuffer);
        }
        break;

    case IOCTL_SCSI_GET_INQUIRY_DATA:
        sz = INQ_REPLY_LEN;
        status = GetInquiryData(fd, lpOutBuffer, nOutBufferSize);
        break;

    default:
        if (needs_close) close( fd );
        return STATUS_NOT_SUPPORTED;
    }
    if (needs_close) close( fd );
 error:
    piosb->u.Status = status;
    piosb->Information = sz;
    if (hEvent) NtSetEvent(hEvent, NULL);
    return status;
}
