/* -*- 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/SCSICmds_REQUEST_SENSE_Defs.h>
# define SENSEBUFLEN kSenseDefaultSize
#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

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_EJECTION_CONTROL)
X(IOCTL_STORAGE_EJECT_MEDIA)
X(IOCTL_STORAGE_GET_DEVICE_NUMBER)
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(__NetBSD__)

   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
    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;
            break;
        case TYPE_ATAPI: *port = 0;
            *iface = addr.addr.atapi.atbus;
            *device = addr.addr.atapi.drive;
            *lun = 0;
            break;
        }
        return 1;
    }
    return 0;
#elif defined(__FreeBSD__)
    FIXME("not implemented for BSD\n");
    return 0;
#else
    FIXME("not implemented for nonlinux\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_Reset                     [internal]
 */
static NTSTATUS CDROM_ResetAudio(int fd)
{
#if defined(linux)
    return CDROM_GetStatusCode(ioctl(fd, CDROMRESET));
#elif defined(__FreeBSD__) || defined(__NetBSD__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCRESET, NULL));
#else
    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(__NetBSD__)
    return CDROM_GetStatusCode((ioctl(fd, CDIOCALLOW, NULL)) ||
                               (ioctl(fd, doEject ? CDIOCEJECT : CDIOCCLOSE, NULL)) ||
                               (ioctl(fd, CDIOCPREVENT, NULL)));
#elif defined(__APPLE__)
    if (doEject) return CDROM_GetStatusCode( ioctl( fd, DKIOCEJECT, NULL ) );
    else return STATUS_NOT_SUPPORTED;
#else
    return STATUS_NOT_SUPPORTED;
#endif
}

/******************************************************************
 *		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(__NetBSD__)
    return CDROM_GetStatusCode(ioctl(fd, (rmv->PreventMediaRemoval) ? CDIOCPREVENT : CDIOCALLOW, NULL));
#else
    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(__NetBSD__)
    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__)
    int ret;
    ret = ioctl(fd, CDIOCSTART, NULL);
    if(ret == 0)
        return STATUS_SUCCESS;
    else
        return STATUS_NO_MEDIA_IN_DEVICE;
#else
    FIXME("not implemented for non-linux\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(__NetBSD__)
    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(__NetBSD__)
    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(__NetBSD__)
    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
    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(__NetBSD__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCPAUSE, NULL));
#else
    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(__NetBSD__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCRESUME, NULL));
#else
    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(__NetBSD__)
    return CDROM_GetStatusCode(ioctl(fd, CDIOCSTOP, NULL));
#else
    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(__NetBSD__)
    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
    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(__NetBSD__)
    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
    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;

    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__)
    switch (raw->TrackMode)
    {
    case YellowMode2:
    {
        /* Mac OS, on the other hand, DOES read only one part of the sector
         * at a time. Therefore, we have to read each part of the sector, in
         * order, to get the whole raw sector in.
         * This means that we have to read each sector one at a time, as on
         * Linux.
         */
        dk_cd_read_t cdrd;
        UInt64 lba = raw->DiskOffset.QuadPart >> 11;
        PBYTE bp;
        int i;

        for (i = 0, bp = buffer; i < raw->SectorCount;
             i++, lba++, bp += kCDSectorSizeWhole)
        {
            cdrd.offset = lba * kCDSectorSizeWhole;
            cdrd.sectorType = kCDSectorTypeMode2;

            /* First, the sync area */
            cdrd.sectorArea = kCDSectorAreaSync;
            cdrd.buffer = bp;
            cdrd.bufferLength = 12;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i;
                return CDROM_GetStatusCode(io);
            }

            /* Then the header */
            cdrd.offset += 12;
            cdrd.sectorArea = kCDSectorAreaHeader;
            cdrd.buffer = (PBYTE)cdrd.buffer + 12;
            cdrd.bufferLength = 4;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i + 12;
                return CDROM_GetStatusCode(io);
            }

            /* And finally the sector proper */
            cdrd.offset += 4;
            cdrd.sectorArea = kCDSectorAreaUser;
            cdrd.buffer = (PBYTE)cdrd.buffer + 4;
            cdrd.bufferLength = kCDSectorSizeMode2;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i + 16;
                return CDROM_GetStatusCode(io);
            }
        }

        break;
    }

    case XAForm2:
    {
        /* Same here */
        dk_cd_read_t cdrd;
        UInt64 lba = raw->DiskOffset.QuadPart >> 11;
        PBYTE bp;
        int i;

        for (i = 0, bp = buffer; i < raw->SectorCount;
             i++, lba++, bp += kCDSectorSizeWhole)
        {
            cdrd.offset = lba * kCDSectorSizeWhole;
            cdrd.sectorType = kCDSectorTypeMode2Form2;

            /* First, the sync area */
            cdrd.sectorArea = kCDSectorAreaSync;
            cdrd.buffer = bp;
            cdrd.bufferLength = 12;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i;
                return CDROM_GetStatusCode(io);
            }

            /* Then the header */
            cdrd.offset += 12;
            cdrd.sectorArea = kCDSectorAreaHeader;
            cdrd.buffer = (PBYTE)cdrd.buffer + 12;
            cdrd.bufferLength = 4;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i + 12;
                return CDROM_GetStatusCode(io);
            }

            /* And the sub-header */
            cdrd.offset += 4;
            cdrd.sectorArea = kCDSectorAreaSubHeader;
            cdrd.buffer = (PBYTE)cdrd.buffer + 4;
            cdrd.bufferLength = 8;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i + 16;
                return CDROM_GetStatusCode(io);
            }

            /* And finally the sector proper */
            cdrd.offset += 8;
            cdrd.sectorArea = kCDSectorAreaUser;
            cdrd.buffer = (PBYTE)cdrd.buffer + 8;
            cdrd.bufferLength = kCDSectorSizeMode2;
            io = ioctl(fd, DKIOCCDREAD, &cdrd);
            if (io != 0)
            {
                *sz = kCDSectorSizeWhole * i + 24;
                return CDROM_GetStatusCode(io);
            }
        }

        break;
    }

    case CDDA:
    {
        /* With CDDA, the whole raw sector is considered user data, so there's
         * no need to read one at a time.
         */
        dk_cd_read_t cdrd;

        cdrd.offset = (raw->DiskOffset.QuadPart >> 11) * kCDSectorSizeCDDA;
        cdrd.sectorArea = kCDSectorAreaUser;
        cdrd.sectorType = kCDSectorTypeCDDA;
        cdrd.buffer = buffer;
        cdrd.bufferLength = len < raw->SectorCount*kCDSectorSizeCDDA ? len :
                            raw->SectorCount*kCDSectorSizeCDDA;

        io = ioctl(fd, DKIOCCDREAD, &cdrd);
        if (io != 0) return CDROM_GetStatusCode(io);
        break;
    }

    default:
        FIXME("NIY: %d\n", raw->TrackMode);
        return STATUS_INVALID_PARAMETER;
    }
#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;
#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);
#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;
#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);
#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(__FreeBSD__) || defined(__NetBSD__)
    return STATUS_NOT_SUPPORTED;
#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
    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(__FreeBSD__) || defined(__NetBSD__)
    return STATUS_NOT_SUPPORTED;
#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
    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("unsupported on this platform\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(__FreeBSD__) || defined(__NetBSD__)
    TRACE("bsd\n");
    return STATUS_NOT_SUPPORTED;
#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
    TRACE("outside\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(__FreeBSD__) || defined(__NetBSD__)
    TRACE("bsd\n");
    return STATUS_NOT_SUPPORTED;
#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("\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 = l->start_sector;
            p->EndDataSector = l->end_sector;
            p->EndLayerZeroSector = 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;
    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 = OSReadBigInt32(&desc.phys.zero1, 0);
            nt_desc.xlayer->EndDataSector = OSReadBigInt32(&desc.phys.zero2, 0);
            nt_desc.xlayer->EndLayerZeroSector = OSReadBigInt32(&desc.phys.zero3, 0);
            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 implemented for nonlinux\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_STORAGE_CHECK_VERIFY:
    case IOCTL_CDROM_CHECK_VERIFY:
    case IOCTL_DISK_CHECK_VERIFY:
        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;

/* EPP     case IOCTL_STORAGE_GET_MEDIA_TYPES: */

    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;
}
