/* -*- 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_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
{
    UCHAR DataLength[2];
    UCHAR Reserved0[2];
    UCHAR BookVersion : 4;
    UCHAR BookType : 4;
    UCHAR MinimumRate : 4;
    UCHAR DiskSize : 4;
    UCHAR LayerType : 4;
    UCHAR TrackPath : 1;
    UCHAR NumberOfLayers : 2;
    UCHAR Reserved1 : 1;
    UCHAR TrackDensity : 4;
    UCHAR LinearDensity : 4;
    ULONG StartingDataSector;
    ULONG EndDataSector;
    ULONG EndLayerZeroSector;
    UCHAR Reserved5 : 7;
    UCHAR BCAFlag : 1;
    UCHAR Reserved6;
} internal_dvd_layer_descriptor;


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.u.LowPart = fsize / (64 * 32); 
  dg->Cylinders.u.HighPart = 0; 
  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);
        break;
    }
    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);
    }
    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 / getpagesize();
    caps->SupportedAsynchronousEvents = TRUE;
    caps->AlignmentMask = getpagesize();
    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 / getpagesize();
    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.u.HighPart || structure->BlockByteOffset.u.LowPart)
        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->DataLength[0] = 2;
            p->DataLength[1] = 8;
            p->Reserved0[0] = 0;
            p->Reserved0[1] = 0;
            p->BookVersion = l->book_version;
            p->BookType = l->book_type;
            p->MinimumRate = l->min_rate;
            p->DiskSize = l->disc_size;
            p->LayerType = l->layer_type;
            p->TrackPath = l->track_path;
            p->NumberOfLayers = l->nlayers;
            p->Reserved1 = 0;
            p->TrackDensity = l->track_density;
            p->LinearDensity = l->linear_density;
            p->StartingDataSector = GET_BE_DWORD(l->start_sector);
            p->EndDataSector = GET_BE_DWORD(l->end_sector);
            p->EndLayerZeroSector = GET_BE_DWORD(l->end_sector_l0);
            p->Reserved5 = 0;
            p->BCAFlag = l->bca;
            p->Reserved6 = 0;
        }
        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:
        {
            PDVD_MANUFACTURER_DESCRIPTOR p = (PDVD_MANUFACTURER_DESCRIPTOR) layer;

            memcpy(p->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;
        PDVD_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->DataLength[0] = 2;
            nt_desc.xlayer->DataLength[1] = 8;
            nt_desc.xlayer->Reserved0[0] = 0;
            nt_desc.xlayer->Reserved0[1] = 0;
            nt_desc.xlayer->BookVersion = desc.phys.partVersion;
            nt_desc.xlayer->BookType = desc.phys.bookType;
            nt_desc.xlayer->MinimumRate = desc.phys.minimumRate;
            nt_desc.xlayer->DiskSize = desc.phys.discSize;
            nt_desc.xlayer->LayerType = desc.phys.layerType;
            nt_desc.xlayer->TrackPath = desc.phys.trackPath;
            nt_desc.xlayer->NumberOfLayers = desc.phys.numberOfLayers;
            nt_desc.xlayer->Reserved1 = 0;
            nt_desc.xlayer->TrackDensity = desc.phys.trackDensity;
            nt_desc.xlayer->LinearDensity = desc.phys.linearDensity;
            nt_desc.xlayer->BCAFlag = desc.phys.bcaFlag;
            nt_desc.xlayer->StartingDataSector = *(DWORD *)&desc.phys.zero1;
            nt_desc.xlayer->EndDataSector = *(DWORD *)&desc.phys.zero2;
            nt_desc.xlayer->EndLayerZeroSector = *(DWORD *)&desc.phys.zero3;
            nt_desc.xlayer->Reserved5 = 0;
            nt_desc.xlayer->Reserved6 = 0;
            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:
            memcpy(
                nt_desc.manf->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_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) 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;
}
