mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 17:14:06 +00:00
Changed the Wine internal cdrom interface to the NT model.
This commit is contained in:
parent
220c1c2c39
commit
5cc6105b39
|
@ -6,6 +6,7 @@ MODULE = ntdll
|
|||
EXTRALIBS = $(LIBUNICODE)
|
||||
|
||||
C_SRCS = \
|
||||
cdrom.c \
|
||||
critsection.c \
|
||||
debugtools.c \
|
||||
exception.c \
|
||||
|
|
996
dlls/ntdll/cdrom.c
Normal file
996
dlls/ntdll/cdrom.c
Normal file
|
@ -0,0 +1,996 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
/* Main file for CD-ROM support
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1999, 2001 Eric Pouech
|
||||
* Copyright 2000 Andreas Mohr
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "ntddk.h"
|
||||
#include "winioctl.h"
|
||||
#include "ntddstor.h"
|
||||
#include "ntddcdrm.h"
|
||||
#include "drive.h"
|
||||
#include "file.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
#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
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(cdrom);
|
||||
|
||||
/* 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
|
||||
*/
|
||||
struct cdrom_cache {
|
||||
int fd;
|
||||
int count;
|
||||
};
|
||||
static struct cdrom_cache cdrom_cache[26];
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_Open
|
||||
*
|
||||
*
|
||||
*/
|
||||
static int CDROM_Open(HANDLE hDevice, DWORD clientID)
|
||||
{
|
||||
int dev = LOWORD(clientID);
|
||||
|
||||
if (dev >= 26) return -1;
|
||||
|
||||
if (!cdrom_cache[dev].count)
|
||||
{
|
||||
char root[4];
|
||||
|
||||
strcpy(root, "A:\\");
|
||||
root[0] += dev;
|
||||
if (GetDriveTypeA(root) != DRIVE_CDROM) return -1;
|
||||
cdrom_cache[dev].fd = open(DRIVE_GetDevice(dev), O_RDONLY|O_NONBLOCK);
|
||||
if (cdrom_cache[dev].fd == -1)
|
||||
{
|
||||
FIXME("Can't open %s: %s\n", root, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
cdrom_cache[dev].count++;
|
||||
return cdrom_cache[dev].fd;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_Close
|
||||
*
|
||||
*
|
||||
*/
|
||||
static void CDROM_Close(DWORD clientID, int fd)
|
||||
{
|
||||
int dev = LOWORD(clientID);
|
||||
|
||||
if (dev >= 26 || fd != cdrom_cache[dev].fd) FIXME("how come\n");
|
||||
if (--cdrom_cache[dev].count == 0)
|
||||
close(cdrom_cache[dev].fd);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_GetStatusCode
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_GetStatusCode(int io)
|
||||
{
|
||||
if (io == 0) return 0;
|
||||
switch (errno)
|
||||
{
|
||||
case EIO: return STATUS_NO_MEDIA_IN_DEVICE;
|
||||
}
|
||||
FIXME("Unmapped error code %d: %s\n", errno, strerror(errno));
|
||||
return STATUS_IO_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
static DWORD CDROM_GetControl(int dev, CDROM_AUDIO_CONTROL* cac)
|
||||
{
|
||||
cac->LbaFormat = 0; /* FIXME */
|
||||
cac->LogicalBlocksPerSecond = 1; /* FIXME */
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static DWORD CDROM_GetDeviceNumber(int dev, STORAGE_DEVICE_NUMBER* devnum)
|
||||
{
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static DWORD CDROM_GetDriveGeometry(int dev, DISK_GEOMETRY* dg)
|
||||
{
|
||||
#if 0
|
||||
dg->Cylinders.s.LowPart = 1; /* FIXME */
|
||||
dg->Cylinders.s.HighPart = 0; /* FIXME */
|
||||
dg->MediaType = 1; /* FIXME */
|
||||
dg->TracksPerCylinder = 1; /* FIXME */
|
||||
dg->SectorsPerTrack = 1; /* FIXME */
|
||||
dg->BytesPerSector= 1; /* FIXME */
|
||||
#endif
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Reset [internal]
|
||||
*/
|
||||
static DWORD CDROM_ResetAudio(int dev)
|
||||
{
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROMRESET));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDIOCRESET, NULL));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_SetTray
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_SetTray(int dev, BOOL doEject)
|
||||
{
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, doEject ? CDROMEJECT : CDROMCLOSETRAY));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode((ioctl(dev, CDIOCALLOW, NULL)) ||
|
||||
(ioctl(dev, doEject ? CDIOCEJECT : CDIOCCLOSE, NULL)) ||
|
||||
(ioctl(dev, CDIOCPREVENT, NULL)));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_ControlEjection
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_ControlEjection(int dev, const PREVENT_MEDIA_REMOVAL* rmv)
|
||||
{
|
||||
int val = rmv->PreventMediaRemoval;
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROM_LOCKDOOR, val));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode(ioctl(dev, (val) ? CDIOPREVENT : CDIOCALLOW, NULL));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_ReadTOC
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_ReadTOC(int dev, CDROM_TOC* toc)
|
||||
{
|
||||
DWORD ret = STATUS_NOT_SUPPORTED;
|
||||
|
||||
#if defined(linux)
|
||||
int i, io = -1;
|
||||
struct cdrom_tochdr hdr;
|
||||
struct cdrom_tocentry entry;
|
||||
|
||||
io = ioctl(dev, CDROMREADTOCHDR, &hdr);
|
||||
if (io == -1)
|
||||
{
|
||||
WARN("(%d) -- Error occurred (%s)!\n", dev, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
toc->FirstTrack = hdr.cdth_trk0;
|
||||
toc->LastTrack = hdr.cdth_trk1;
|
||||
|
||||
TRACE("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;
|
||||
io = ioctl(dev, CDROMREADTOCENTRY, &entry);
|
||||
if (io == -1) {
|
||||
WARN("error read entry (%s)\n", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
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;
|
||||
}
|
||||
end:
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int i, io = -1;
|
||||
struct ioc_toc_header hdr;
|
||||
struct ioc_read_toc_entry entry;
|
||||
struct cd_toc_entry toc_buffer;
|
||||
|
||||
io = ioctl(dev, CDIOREADTOCHEADER, &hdr);
|
||||
if (io == -1)
|
||||
{
|
||||
WARN("(%d) -- Error occurred (%s)!\n", dev, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
toc->FirstTrack = hdr.starting_track;
|
||||
toc->LastTrack = hdr.ending_track;
|
||||
|
||||
TRACE("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((char *)&toc_buffer, 0, sizeof(toc_buffer));
|
||||
entry.address_format = CD_MSF_FORMAT;
|
||||
entry.data_len = sizeof(toc_buffer);
|
||||
entry.data = &toc_buffer;
|
||||
io = ioctl(dev, CDIOREADTOCENTRYS, &entry);
|
||||
if (io == -1) {
|
||||
WARN("error read entry (%s)\n", strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
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;
|
||||
}
|
||||
end:
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#else
|
||||
ret = STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_GetDiskData
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_GetDiskData(int dev, CDROM_DISK_DATA* data)
|
||||
{
|
||||
CDROM_TOC toc;
|
||||
DWORD ret;
|
||||
int i;
|
||||
|
||||
if ((ret = CDROM_ReadTOC(dev, &toc)) != 0) return ret;
|
||||
data->DiskData = 0;
|
||||
for (i = toc.FirstTrack; i <= toc.LastTrack; i++) {
|
||||
if (toc.TrackData[i].Control & 0x04)
|
||||
data->DiskData |= CDROM_DISK_DATA_TRACK;
|
||||
else
|
||||
data->DiskData |= CDROM_DISK_AUDIO_TRACK;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_ReadQChannel
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_ReadQChannel(int dev, const CDROM_SUB_Q_DATA_FORMAT* fmt,
|
||||
SUB_Q_CHANNEL_DATA* data)
|
||||
{
|
||||
DWORD ret = STATUS_NOT_SUPPORTED;
|
||||
unsigned size;
|
||||
SUB_Q_HEADER* hdr = (SUB_Q_HEADER*)data;
|
||||
int io;
|
||||
|
||||
#ifdef linux
|
||||
struct cdrom_subchnl sc;
|
||||
sc.cdsc_format = CDROM_MSF;
|
||||
|
||||
io = ioctl(dev, CDROMSUBCHNL, &sc);
|
||||
if (io == -1)
|
||||
{
|
||||
TRACE("opened or no_media (%s)!\n", strerror(errno));
|
||||
hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
|
||||
|
||||
switch (sc.cdsc_audiostatus) {
|
||||
case CDROM_AUDIO_INVALID:
|
||||
hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
case CDROM_AUDIO_NO_STATUS:
|
||||
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:
|
||||
size = sizeof(SUB_Q_CURRENT_POSITION);
|
||||
data->CurrentPosition.FormatCode = sc.cdsc_format;
|
||||
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;
|
||||
break;
|
||||
case IOCTL_CDROM_MEDIA_CATALOG:
|
||||
size = sizeof(SUB_Q_MEDIA_CATALOG_NUMBER);
|
||||
data->MediaCatalog.FormatCode = IOCTL_CDROM_MEDIA_CATALOG;
|
||||
{
|
||||
struct cdrom_mcn mcn;
|
||||
if ((io = ioctl(dev, 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:
|
||||
size = sizeof(SUB_Q_CURRENT_POSITION);
|
||||
FIXME("TrackIsrc: NIY on linux");
|
||||
data->TrackIsrc.FormatCode = IOCTL_CDROM_TRACK_ISRC;
|
||||
data->TrackIsrc.Tcval = 0;
|
||||
io = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
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 = ≻
|
||||
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.track_info.track_number = data->TrackIsrc.Track;
|
||||
break;
|
||||
}
|
||||
io = ioctl(dev, CDIOCREADSUBCHANNEL, &read_sc);
|
||||
if (io == -1)
|
||||
{
|
||||
TRACE("opened or no_media (%s)!\n", strerror(errno));
|
||||
hdr->AudioStatus = AUDIO_STATUS_NO_STATUS;
|
||||
goto end;
|
||||
}
|
||||
|
||||
hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
|
||||
|
||||
switch (sc.header.audio_status) {
|
||||
case CD_AS_AUDIO_INVALID:
|
||||
hdr->AudioStatus = AUDIO_STATUS_NOT_SUPPORTED;
|
||||
break;
|
||||
case CD_AS_NO_STATUS:
|
||||
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_IN_PAUSED;
|
||||
break;
|
||||
case CD_AS_PLAY_AUDIO_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:
|
||||
size = sizeof(SUB_Q_CURRENT_POSITION);
|
||||
data->CurrentPosition.FormatCode = sc.position.data_format;
|
||||
data->CurrentPosition.Control = sc.position.control;
|
||||
data->CurrentPosition.ADR = sc.position.addr_type;
|
||||
data->CurrentPosition.TrackNumber = sc.position.track_number;
|
||||
data->CurrentPosition.IndexNumber = sc.position.index_number;
|
||||
|
||||
data->CurrentPosition.AbsoluteAddress[0] = 0;
|
||||
data->CurrentPosition.AbsoluteAddress[1] = sc.position.absaddr.msf.minute;
|
||||
data->CurrentPosition.AbsoluteAddress[2] = sc.position.absaddr.msf.second;
|
||||
data->CurrentPosition.AbsoluteAddress[3] = sc.position.absaddr.msf.frame;
|
||||
data->CurrentPosition.TrackRelativeAddress[0] = 0;
|
||||
data->CurrentPosition.TrackRelativeAddress[1] = sc.position.reladdr.msf.minute;
|
||||
data->CurrentPosition.TrackRelativeAddress[2] = sc.position.reladdr.msf.second;
|
||||
data->CurrentPosition.TrackRelativeAddress[3] = sc.position.reladdr.msf.frame;
|
||||
break;
|
||||
case IOCTL_CDROM_MEDIA_CATALOG:
|
||||
size = sizeof(SUB_Q_MEDIA_CATALOG_NUMBER);
|
||||
data->MediaCatalog.FormatCode = IOCTL_CDROM_MEDIA_CATALOG;
|
||||
data->MediaCatalog.FormatCode = sc.media_catalog.data_format;
|
||||
data->MediaCatalog.Mcval = sc.media_catalog.mc_valid;
|
||||
memcpy(data->MediaCatalog.MediaCatalog, sc.media_catalog.mc_number, 15);
|
||||
break;
|
||||
case IOCTL_CDROM_TRACK_ISRC:
|
||||
size = sizeof(SUB_Q_CURRENT_POSITION);
|
||||
data->TrackIsrc.Tcval = sc.track_info.ti_valid;
|
||||
memcpy(data->TrackIsrc.TrackIsrc, sc.track_info.ti_number, 15);
|
||||
break;
|
||||
}
|
||||
|
||||
end:
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_Verify
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_Verify(int dev)
|
||||
{
|
||||
/* quick implementation */
|
||||
CDROM_SUB_Q_DATA_FORMAT fmt;
|
||||
SUB_Q_CHANNEL_DATA data;
|
||||
|
||||
fmt.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
return CDROM_ReadQChannel(dev, &fmt, &data) ? 0 : 1;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_PlayAudioMSF
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_PlayAudioMSF(int dev, const CDROM_PLAY_AUDIO_MSF* audio_msf)
|
||||
{
|
||||
DWORD 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(dev, CDROMSTART);
|
||||
if (io == -1)
|
||||
{
|
||||
WARN("motor doesn't start !\n");
|
||||
goto end;
|
||||
}
|
||||
io = ioctl(dev, 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(dev, CDIOCSTART, NULL);
|
||||
if (io == -1)
|
||||
{
|
||||
WARN("motor doesn't start !\n");
|
||||
goto end;
|
||||
}
|
||||
io = ioctl(dev, 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 DWORD CDROM_SeekAudioMSF(int dev, const CDROM_SEEK_AUDIO_MSF* audio_msf)
|
||||
{
|
||||
#if defined(linux)
|
||||
struct cdrom_msf0 msf;
|
||||
msf.minute = audio_msf->M;
|
||||
msf.second = audio_msf->S;
|
||||
msf.frame = audio_msf->F;
|
||||
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROMSEEK, &msf));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
FIXME("Could a BSD expert implement the seek function ?\n");
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_PauseAudio
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_PauseAudio(int dev)
|
||||
{
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROMPAUSE));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDIOCPAUSE, NULL));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_ResumeAudio
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_ResumeAudio(int dev)
|
||||
{
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROMRESUME));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDIOCRESUME, NULL));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_StopAudio
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_StopAudio(int dev)
|
||||
{
|
||||
#if defined(linux)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDROMSTOP));
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
return CDROM_GetStatusCode(ioctl(dev, CDIOCSTOP, NULL));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_GetVolume
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_GetVolume(int dev, VOLUME_CONTROL* vc)
|
||||
{
|
||||
#if defined(linux)
|
||||
struct cdrom_volctrl volc;
|
||||
int io;
|
||||
|
||||
io = ioctl(dev, 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(dev, 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 DWORD CDROM_SetVolume(int dev, 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(dev, 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(dev, CDIOCSETVOL, &volc));
|
||||
#else
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_RawRead
|
||||
*
|
||||
*
|
||||
*/
|
||||
static DWORD CDROM_RawRead(int dev, const RAW_READ_INFO* raw, void* buffer, DWORD len, DWORD* sz)
|
||||
{
|
||||
int ret = STATUS_NOT_SUPPORTED;
|
||||
int io = -1;
|
||||
DWORD sectSize;
|
||||
|
||||
switch (raw->TrackMode)
|
||||
{
|
||||
case YellowMode2: sectSize = 2336; break;
|
||||
case XAForm2: sectSize = 2328; break;
|
||||
case CDDA: sectSize = 2352; break;
|
||||
default: return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
if (len < raw->SectorCount * sectSize) return STATUS_BUFFER_TOO_SMALL;
|
||||
/* strangely enough, it seems that sector offsets are always indicated with a size of 2048,
|
||||
* even if a larger size if read...
|
||||
*/
|
||||
#if defined(linux)
|
||||
{
|
||||
struct cdrom_read cdr;
|
||||
struct cdrom_read_audio cdra;
|
||||
|
||||
switch (raw->TrackMode)
|
||||
{
|
||||
case YellowMode2:
|
||||
if (raw->DiskOffset.s.HighPart) FIXME("Unsupported value\n");
|
||||
cdr.cdread_lba = raw->DiskOffset.s.LowPart; /* FIXME ? */
|
||||
cdr.cdread_bufaddr = buffer;
|
||||
cdr.cdread_buflen = raw->SectorCount * sectSize;
|
||||
io = ioctl(dev, CDROMREADMODE2, &cdr);
|
||||
break;
|
||||
case XAForm2:
|
||||
FIXME("XAForm2: NIY\n");
|
||||
return ret;
|
||||
case CDDA:
|
||||
/* FIXME: the output doesn't seem 100% correct... in fact output is shifted
|
||||
* between by NT2K box and this... should check on the same drive...
|
||||
* otherwise, I fear a 2352/2368 mismatch somewhere in one of the drivers
|
||||
* (linux/NT).
|
||||
* Anyway, that's not critical at all. We're talking of 16/32 bytes, we're
|
||||
* talking of 0.2 ms of sound
|
||||
*/
|
||||
/* 2048 = 2 ** 11 */
|
||||
if (raw->DiskOffset.s.HighPart & ~2047) FIXME("Unsupported value\n");
|
||||
cdra.addr.lba = ((raw->DiskOffset.s.LowPart >> 11) |
|
||||
(raw->DiskOffset.s.HighPart << (32 - 11))) - 1;
|
||||
FIXME("reading at %u\n", cdra.addr.lba);
|
||||
cdra.addr_format = CDROM_LBA;
|
||||
cdra.nframes = raw->SectorCount;
|
||||
cdra.buf = buffer;
|
||||
io = ioctl(dev, CDROMREADAUDIO, &cdra);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*sz = sectSize * raw->SectorCount;
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
{
|
||||
struct ioc_read_audio ira;
|
||||
|
||||
switch (raw->TrackMode)
|
||||
{
|
||||
case YellowMode2:
|
||||
FIXME("YellowMode2: NIY\n");
|
||||
return ret;
|
||||
case XAForm2:
|
||||
FIXME("XAForm2: NIY\n");
|
||||
return ret;
|
||||
case CDDA:
|
||||
/* 2048 = 2 ** 11 */
|
||||
if (raw->DiskOffset.s.HighPart & ~2047) FIXME("Unsupported value\n");
|
||||
ira.address.lba = ((raw->DiskOffset.s.LowPart >> 11) |
|
||||
raw->DiskOffset.s.HighPart << (32 - 11)) - 1;
|
||||
ira.address_format = CD_LBA_FORMAT;
|
||||
ira.nframes = raw->SectorCount;
|
||||
ira.buffer = buffer;
|
||||
io = ioctl(dev, CDIOCREADAUDIO, &ira);
|
||||
break;
|
||||
}
|
||||
}
|
||||
*sz = sectSize * raw->SectorCount;
|
||||
ret = CDROM_GetStatusCode(io);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* CDROM_DeviceIoControl
|
||||
*
|
||||
*
|
||||
*/
|
||||
BOOL CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, DWORD dwIoControlCode,
|
||||
LPVOID lpInBuffer, DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
DWORD sz;
|
||||
DWORD error = 0;
|
||||
int dev;
|
||||
|
||||
TRACE("%lx[%c] %lx %lx %ld %lx %ld %lx %lx\n",
|
||||
(DWORD)hDevice, 'A' + LOWORD(clientID), dwIoControlCode, (DWORD)lpInBuffer, nInBufferSize,
|
||||
(DWORD)lpOutBuffer, nOutBufferSize, (DWORD)lpBytesReturned, (DWORD)lpOverlapped);
|
||||
|
||||
if (lpBytesReturned) *lpBytesReturned = 0;
|
||||
if (lpOverlapped)
|
||||
{
|
||||
FIXME("Overlapped isn't implemented yet\n");
|
||||
SetLastError(STATUS_NOT_SUPPORTED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SetLastError(0);
|
||||
dev = CDROM_Open(hDevice, clientID);
|
||||
if (dev == -1)
|
||||
{
|
||||
CDROM_GetStatusCode(-1);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (dwIoControlCode)
|
||||
{
|
||||
case IOCTL_STORAGE_CHECK_VERIFY:
|
||||
case IOCTL_CDROM_CHECK_VERIFY:
|
||||
sz = 0;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_Verify(dev);
|
||||
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;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_SetTray(dev, FALSE);
|
||||
break;
|
||||
case IOCTL_STORAGE_EJECT_MEDIA:
|
||||
sz = 0;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_SetTray(dev, TRUE);
|
||||
break;
|
||||
|
||||
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;
|
||||
if (lpOutBuffer != NULL || nOutBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nInBufferSize < sizeof(PREVENT_MEDIA_REMOVAL)) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_ControlEjection(dev, (const PREVENT_MEDIA_REMOVAL*)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) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_GetDeviceNumber(dev, (STORAGE_DEVICE_NUMBER*)lpOutBuffer);
|
||||
break;
|
||||
|
||||
case IOCTL_STORAGE_RESET_DEVICE:
|
||||
sz = 0;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_ResetAudio(dev);
|
||||
break;
|
||||
|
||||
case IOCTL_CDROM_GET_CONTROL:
|
||||
sz = sizeof(CDROM_AUDIO_CONTROL);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_GetControl(dev, (CDROM_AUDIO_CONTROL*)lpOutBuffer);
|
||||
break;
|
||||
|
||||
case IOCTL_CDROM_GET_DRIVE_GEOMETRY:
|
||||
sz = sizeof(DISK_GEOMETRY);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_GetDriveGeometry(dev, (DISK_GEOMETRY*)lpOutBuffer);
|
||||
break;
|
||||
|
||||
case IOCTL_CDROM_DISK_TYPE:
|
||||
sz = sizeof(CDROM_DISK_DATA);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_GetDiskData(dev, (CDROM_DISK_DATA*)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))
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_ReadQChannel(dev, (const CDROM_SUB_Q_DATA_FORMAT*)lpInBuffer,
|
||||
(SUB_Q_CHANNEL_DATA*)lpOutBuffer);
|
||||
break;
|
||||
|
||||
case IOCTL_CDROM_READ_TOC:
|
||||
sz = sizeof(CDROM_TOC);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_ReadTOC(dev, (CDROM_TOC*)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)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_PauseAudio(dev);
|
||||
break;
|
||||
case IOCTL_CDROM_PLAY_AUDIO_MSF:
|
||||
sz = 0;
|
||||
if (lpOutBuffer != NULL || nOutBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nInBufferSize < sizeof(CDROM_PLAY_AUDIO_MSF)) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_PlayAudioMSF(dev, (const CDROM_PLAY_AUDIO_MSF*)lpInBuffer);
|
||||
break;
|
||||
case IOCTL_CDROM_RESUME_AUDIO:
|
||||
sz = 0;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_ResumeAudio(dev);
|
||||
break;
|
||||
case IOCTL_CDROM_SEEK_AUDIO_MSF:
|
||||
sz = 0;
|
||||
if (lpOutBuffer != NULL || nOutBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nInBufferSize < sizeof(CDROM_SEEK_AUDIO_MSF)) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_SeekAudioMSF(dev, (const CDROM_SEEK_AUDIO_MSF*)lpInBuffer);
|
||||
break;
|
||||
case IOCTL_CDROM_STOP_AUDIO:
|
||||
sz = 0;
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0 || lpOutBuffer != NULL || nOutBufferSize != 0)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_StopAudio(dev);
|
||||
break;
|
||||
case IOCTL_CDROM_GET_VOLUME:
|
||||
sz = sizeof(VOLUME_CONTROL);
|
||||
if (lpInBuffer != NULL || nInBufferSize != 0) error = STATUS_INVALID_PARAMETER;
|
||||
else if (nOutBufferSize < sz) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_GetVolume(dev, (VOLUME_CONTROL*)lpOutBuffer);
|
||||
break;
|
||||
case IOCTL_CDROM_SET_VOLUME:
|
||||
sz = 0;
|
||||
if (lpInBuffer == NULL || nInBufferSize < sizeof(VOLUME_CONTROL) || lpOutBuffer != NULL)
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
else error = CDROM_SetVolume(dev, (const VOLUME_CONTROL*)lpInBuffer);
|
||||
break;
|
||||
case IOCTL_CDROM_RAW_READ:
|
||||
sz = 0;
|
||||
if (nInBufferSize < sizeof(RAW_READ_INFO)) error = STATUS_INVALID_PARAMETER;
|
||||
else if (lpOutBuffer == NULL) error = STATUS_BUFFER_TOO_SMALL;
|
||||
else error = CDROM_RawRead(dev, (const RAW_READ_INFO*)lpInBuffer,
|
||||
lpOutBuffer, nOutBufferSize, &sz);
|
||||
break;
|
||||
default:
|
||||
FIXME("Unsupported IOCTL %lx\n", dwIoControlCode);
|
||||
sz = 0;
|
||||
error = STATUS_INVALID_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lpBytesReturned) *lpBytesReturned = sz;
|
||||
if (error)
|
||||
{
|
||||
SetLastError(error);
|
||||
return FALSE;
|
||||
}
|
||||
CDROM_Close(clientID, dev);
|
||||
return TRUE;
|
||||
}
|
||||
|
263
files/drive.c
263
files/drive.c
|
@ -44,7 +44,6 @@
|
|||
#include "wine/winbase16.h" /* for GetCurrentTask */
|
||||
#include "winerror.h"
|
||||
#include "drive.h"
|
||||
#include "cdrom.h"
|
||||
#include "file.h"
|
||||
#include "heap.h"
|
||||
#include "msdos.h"
|
||||
|
@ -52,6 +51,9 @@
|
|||
#include "task.h"
|
||||
#include "debugtools.h"
|
||||
#include "wine/server.h"
|
||||
#include "winioctl.h"
|
||||
#include "ntddstor.h"
|
||||
#include "ntddcdrm.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(dosfs);
|
||||
DECLARE_DEBUG_CHANNEL(file);
|
||||
|
@ -459,6 +461,40 @@ const char * DRIVE_GetDevice( int drive )
|
|||
return (DRIVE_IsValid( drive )) ? DOSDrives[drive].device : NULL;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* static WORD CDROM_Data_FindBestVoldesc
|
||||
*
|
||||
*
|
||||
*/
|
||||
static WORD CDROM_Data_FindBestVoldesc(int fd)
|
||||
{
|
||||
BYTE cur_vd_type, max_vd_type = 0;
|
||||
unsigned int offs, best_offs = 0, extra_offs = 0;
|
||||
char sig[3];
|
||||
|
||||
for (offs = 0x8000; offs <= 0x9800; offs += 0x800)
|
||||
{
|
||||
/* if 'CDROM' occurs at position 8, this is a pre-iso9660 cd, and
|
||||
* the volume label is displaced forward by 8
|
||||
*/
|
||||
lseek(fd, offs + 11, SEEK_SET); /* check for non-ISO9660 signature */
|
||||
read(fd, &sig, 3);
|
||||
if ((sig[0] == 'R') && (sig[1] == 'O') && (sig[2]=='M'))
|
||||
{
|
||||
extra_offs = 8;
|
||||
}
|
||||
lseek(fd, offs + extra_offs, SEEK_SET);
|
||||
read(fd, &cur_vd_type, 1);
|
||||
if (cur_vd_type == 0xff) /* voldesc set terminator */
|
||||
break;
|
||||
if (cur_vd_type > max_vd_type)
|
||||
{
|
||||
max_vd_type = cur_vd_type;
|
||||
best_offs = offs + extra_offs;
|
||||
}
|
||||
}
|
||||
return best_offs;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DRIVE_ReadSuperblock
|
||||
|
@ -567,8 +603,103 @@ int DRIVE_WriteSuperblockEntry (int drive, off_t ofs, size_t len, char * buff)
|
|||
return close (fd);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
* static HANDLE CDROM_Open
|
||||
*
|
||||
*
|
||||
*/
|
||||
static HANDLE CDROM_Open(int drive)
|
||||
{
|
||||
char root[6];
|
||||
|
||||
strcpy(root, "\\\\.\\A:");
|
||||
root[4] += drive;
|
||||
|
||||
return CreateFileA(root, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_GetLabel [internal]
|
||||
*/
|
||||
DWORD CDROM_Data_GetLabel(int drive, char *label)
|
||||
{
|
||||
#define LABEL_LEN 32+1
|
||||
int dev = open(DOSDrives[drive].device, O_RDONLY|O_NONBLOCK);
|
||||
WORD offs = CDROM_Data_FindBestVoldesc(dev);
|
||||
WCHAR label_read[LABEL_LEN]; /* Unicode possible, too */
|
||||
DWORD unicode_id = 0;
|
||||
|
||||
if (offs)
|
||||
{
|
||||
if ((lseek(dev, offs+0x58, SEEK_SET) == offs+0x58)
|
||||
&& (read(dev, &unicode_id, 3) == 3))
|
||||
{
|
||||
int ver = (unicode_id & 0xff0000) >> 16;
|
||||
|
||||
if ((lseek(dev, offs+0x28, SEEK_SET) != offs+0x28)
|
||||
|| (read(dev, &label_read, LABEL_LEN) != LABEL_LEN))
|
||||
goto failure;
|
||||
|
||||
close(dev);
|
||||
if ((LOWORD(unicode_id) == 0x2f25) /* Unicode ID */
|
||||
&& ((ver == 0x40) || (ver == 0x43) || (ver == 0x45)))
|
||||
{ /* yippee, unicode */
|
||||
int i;
|
||||
WORD ch;
|
||||
for (i=0; i<LABEL_LEN;i++)
|
||||
{ /* Motorola -> Intel Unicode conversion :-\ */
|
||||
ch = label_read[i];
|
||||
label_read[i] = (ch << 8) | (ch >> 8);
|
||||
}
|
||||
WideCharToMultiByte( CP_ACP, 0, label_read, -1, label, 12, NULL, NULL );
|
||||
label[11] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(label, (LPSTR)label_read, 11);
|
||||
label[11] = '\0';
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
failure:
|
||||
close(dev);
|
||||
ERR("error reading label !\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetLabel [internal]
|
||||
*/
|
||||
static DWORD CDROM_GetLabel(int drive, char *label)
|
||||
{
|
||||
HANDLE h = CDROM_Open(drive);
|
||||
CDROM_DISK_DATA cdd;
|
||||
DWORD br;
|
||||
DWORD ret = 1;
|
||||
|
||||
if (!h || !DeviceIoControl(h, IOCTL_CDROM_DISK_TYPE, NULL, 0, &cdd, sizeof(cdd), &br, 0))
|
||||
return 0;
|
||||
|
||||
switch (cdd.DiskData & 0x03)
|
||||
{
|
||||
case CDROM_DISK_DATA_TRACK:
|
||||
if (!CDROM_Data_GetLabel(drive, label))
|
||||
ret = 0;
|
||||
case CDROM_DISK_AUDIO_TRACK:
|
||||
strcpy(label, "Audio CD ");
|
||||
break;
|
||||
case CDROM_DISK_DATA_TRACK|CDROM_DISK_AUDIO_TRACK:
|
||||
FIXME("Need to get the label of a mixed mode CD: not implemented yet !\n");
|
||||
/* fall through */
|
||||
case 0:
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
TRACE("CD: label is '%s'.\n", label);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/***********************************************************************
|
||||
* DRIVE_GetLabel
|
||||
*/
|
||||
|
@ -605,6 +736,132 @@ const char * DRIVE_GetLabel( int drive )
|
|||
DOSDrives[drive].label_read : DOSDrives[drive].label_conf;
|
||||
}
|
||||
|
||||
#define CDFRAMES_PERSEC 75
|
||||
#define CDFRAMES_PERMIN (CDFRAMES_PERSEC * 60)
|
||||
#define FRAME_OF_ADDR(a) ((a)[0] * CDFRAMES_PERMIN + (a)[1] * CDFRAMES_PERSEC + (a)[2])
|
||||
#define FRAME_OF_TOC(toc, idx) FRAME_OF_ADDR((toc).TrackData[idx - (toc).FirstTrack].Address)
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_GetSerial [internal]
|
||||
*/
|
||||
static DWORD CDROM_Audio_GetSerial(HANDLE h)
|
||||
{
|
||||
unsigned long serial = 0;
|
||||
int i;
|
||||
WORD wMagic;
|
||||
DWORD dwStart, dwEnd, br;
|
||||
CDROM_TOC toc;
|
||||
|
||||
if (!DeviceIoControl(h, IOCTL_CDROM_READ_TOC, NULL, 0, &toc, sizeof(toc), &br, 0))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* wMagic collects the wFrames from track 1
|
||||
* dwStart, dwEnd collect the beginning and end of the disc respectively, in
|
||||
* frames.
|
||||
* There it is collected for correcting the serial when there are less than
|
||||
* 3 tracks.
|
||||
*/
|
||||
wMagic = toc.TrackData[0].Address[2];
|
||||
dwStart = FRAME_OF_TOC(toc, toc.FirstTrack);
|
||||
|
||||
for (i = 0; i <= toc.LastTrack - toc.FirstTrack; i++) {
|
||||
serial += (toc.TrackData[i].Address[0] << 16) |
|
||||
(toc.TrackData[i].Address[1] << 8) | toc.TrackData[i].Address[2];
|
||||
}
|
||||
dwEnd = FRAME_OF_TOC(toc, toc.LastTrack + 1);
|
||||
|
||||
if (toc.LastTrack - toc.FirstTrack + 1 < 3)
|
||||
serial += wMagic + (dwEnd - dwStart);
|
||||
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_GetSerial [internal]
|
||||
*/
|
||||
static DWORD CDROM_Data_GetSerial(int drive)
|
||||
{
|
||||
int dev = open(DOSDrives[drive].device, O_RDONLY|O_NONBLOCK);
|
||||
WORD offs;
|
||||
union {
|
||||
unsigned long val;
|
||||
unsigned char p[4];
|
||||
} serial;
|
||||
BYTE b0 = 0, b1 = 1, b2 = 2, b3 = 3;
|
||||
|
||||
|
||||
if (dev == -1) return 0;
|
||||
offs = CDROM_Data_FindBestVoldesc(dev);
|
||||
|
||||
serial.val = 0;
|
||||
if (offs)
|
||||
{
|
||||
BYTE buf[2048];
|
||||
OSVERSIONINFOA ovi;
|
||||
int i;
|
||||
|
||||
lseek(dev, offs, SEEK_SET);
|
||||
read(dev, buf, 2048);
|
||||
/*
|
||||
* OK, another braindead one... argh. Just believe it.
|
||||
* Me$$ysoft chose to reverse the serial number in NT4/W2K.
|
||||
* It's true and nobody will ever be able to change it.
|
||||
*/
|
||||
ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
GetVersionExA(&ovi);
|
||||
if ((ovi.dwPlatformId == VER_PLATFORM_WIN32_NT) && (ovi.dwMajorVersion >= 4))
|
||||
{
|
||||
b0 = 3; b1 = 2; b2 = 1; b3 = 0;
|
||||
}
|
||||
for (i = 0; i < 2048; i += 4)
|
||||
{
|
||||
/* DON'T optimize this into DWORD !! (breaks overflow) */
|
||||
serial.p[b0] += buf[i+b0];
|
||||
serial.p[b1] += buf[i+b1];
|
||||
serial.p[b2] += buf[i+b2];
|
||||
serial.p[b3] += buf[i+b3];
|
||||
}
|
||||
}
|
||||
close(dev);
|
||||
return serial.val;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetSerial [internal]
|
||||
*/
|
||||
static DWORD CDROM_GetSerial(int drive)
|
||||
{
|
||||
DWORD serial = 0;
|
||||
HANDLE h = CDROM_Open(drive);
|
||||
CDROM_DISK_DATA cdd;
|
||||
DWORD br;
|
||||
|
||||
if (!h || ! !DeviceIoControl(h, IOCTL_CDROM_DISK_TYPE, NULL, 0, &cdd, sizeof(cdd), &br, 0))
|
||||
return 0;
|
||||
|
||||
switch (cdd.DiskData & 0x03)
|
||||
{
|
||||
case CDROM_DISK_DATA_TRACK:
|
||||
/* hopefully a data CD */
|
||||
serial = CDROM_Data_GetSerial(drive);
|
||||
break;
|
||||
case CDROM_DISK_AUDIO_TRACK:
|
||||
/* fall thru */
|
||||
case CDROM_DISK_DATA_TRACK|CDROM_DISK_AUDIO_TRACK:
|
||||
serial = CDROM_Audio_GetSerial(h);
|
||||
break;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
|
||||
if (serial)
|
||||
TRACE("CD serial number is %04x-%04x.\n", HIWORD(serial), LOWORD(serial));
|
||||
|
||||
CloseHandle(h);
|
||||
|
||||
return serial;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DRIVE_GetSerialNumber
|
||||
|
@ -612,7 +869,7 @@ const char * DRIVE_GetLabel( int drive )
|
|||
DWORD DRIVE_GetSerialNumber( int drive )
|
||||
{
|
||||
DWORD serial = 0;
|
||||
char buff[DRIVE_SUPER];
|
||||
char buff[DRIVE_SUPER];
|
||||
|
||||
if (!DRIVE_IsValid( drive )) return 0;
|
||||
|
||||
|
@ -938,7 +1195,7 @@ static UINT DRIVE_GetCurrentDirectory( UINT buflen, LPSTR buf )
|
|||
assert(s);
|
||||
ret = strlen(s) + 3; /* length of WHOLE current directory */
|
||||
if (ret >= buflen) return ret + 1;
|
||||
lstrcpynA( buf, "A:\\", min( 4, buflen ) );
|
||||
lstrcpynA( buf, "A:\\", min( 4u, buflen ) );
|
||||
if (buflen) buf[0] += DRIVE_GetCurrentDrive();
|
||||
if (buflen > 3) lstrcpynA( buf + 3, s, buflen - 3 );
|
||||
return ret;
|
||||
|
|
|
@ -449,6 +449,11 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
|||
ret = FILE_OpenPipe(filename,access);
|
||||
goto done;
|
||||
}
|
||||
else if (isalpha(filename[4]) && filename[5] == ':' && filename[6] == '\0')
|
||||
{
|
||||
ret = FILE_CreateDevice( (toupper(filename[4]) - 'A') | 0x20000, access, sa );
|
||||
goto done;
|
||||
}
|
||||
else if (!DOSFS_GetDevice( filename ))
|
||||
{
|
||||
ret = DEVICE_Open( filename+4, access, sa );
|
||||
|
|
109
include/cdrom.h
109
include/cdrom.h
|
@ -1,109 +0,0 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Header file for CD-ROM support
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1999 Eric Pouech
|
||||
* Copyright 2000 Andreas Mohr
|
||||
*/
|
||||
|
||||
#ifndef __WINE_CDROM_H__
|
||||
#define __WINE_CDROM_H__
|
||||
|
||||
#ifndef __WINE_CONFIG_H
|
||||
# error You must include config.h to use this header
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "windef.h"
|
||||
#include "wine/windef16.h"
|
||||
|
||||
#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
|
||||
|
||||
typedef struct {
|
||||
const char *devname;
|
||||
#if defined(linux)
|
||||
struct cdrom_subchnl sc;
|
||||
#elif defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
struct cd_sub_channel_info sc;
|
||||
#endif
|
||||
/* those data reflect the cdaudio structure and
|
||||
* don't change while playing
|
||||
*/
|
||||
UINT16 nTracks;
|
||||
UINT16 nFirstTrack;
|
||||
UINT16 nLastTrack;
|
||||
LPDWORD lpdwTrackLen;
|
||||
LPDWORD lpdwTrackPos;
|
||||
LPBYTE lpbTrackFlags;
|
||||
DWORD dwFirstFrame;
|
||||
DWORD dwLastFrame;
|
||||
/* those data change while playing */
|
||||
int cdaMode;
|
||||
UINT16 nCurTrack;
|
||||
DWORD dwCurFrame;
|
||||
} WINE_CDAUDIO;
|
||||
|
||||
#define WINE_CDA_DONTKNOW 0x00
|
||||
#define WINE_CDA_NOTREADY 0x01
|
||||
#define WINE_CDA_OPEN 0x02
|
||||
#define WINE_CDA_PLAY 0x03
|
||||
#define WINE_CDA_STOP 0x04
|
||||
#define WINE_CDA_PAUSE 0x05
|
||||
|
||||
int CDROM_Open(WINE_CDAUDIO* wcda, int drive);
|
||||
int CDROM_OpenDev(WINE_CDAUDIO* wcda);
|
||||
int CDROM_GetMediaType(WINE_CDAUDIO* wcda, int parentdev);
|
||||
int CDROM_CloseDev(int dev);
|
||||
int CDROM_Close(WINE_CDAUDIO* wcda);
|
||||
int CDROM_Reset(WINE_CDAUDIO* wcda, int parentdev);
|
||||
int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop, int parentdev);
|
||||
int CDROM_Audio_Stop(WINE_CDAUDIO* wcda, int parentdev);
|
||||
int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn, int parentdev);
|
||||
int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at, int parentdev);
|
||||
int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open, int parentdev);
|
||||
UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda, int parentdev);
|
||||
BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda, int parentdev);
|
||||
BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda, int parentdev);
|
||||
WORD CDROM_Data_FindBestVoldesc(int fd);
|
||||
DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda);
|
||||
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda, int parentdev);
|
||||
DWORD CDROM_GetSerial(int drive);
|
||||
DWORD CDROM_GetLabel(int drive, char *label);
|
||||
|
||||
#define CDFRAMES_PERSEC 75
|
||||
#define SECONDS_PERMIN 60
|
||||
#define CDFRAMES_PERMIN ((CDFRAMES_PERSEC) * (SECONDS_PERMIN))
|
||||
|
||||
#ifndef CDROM_DATA_TRACK
|
||||
#define CDROM_DATA_TRACK 0x04
|
||||
#endif
|
||||
|
||||
#define CDROM_MSF_MINUTE(msf) ((BYTE)(msf))
|
||||
#define CDROM_MSF_SECOND(msf) ((BYTE)(((WORD)(msf)) >> 8))
|
||||
#define CDROM_MSF_FRAME(msf) ((BYTE)((msf)>>16))
|
||||
|
||||
#define CDROM_MAKE_MSF(m, s, f) ((DWORD)(((BYTE)(m) | \
|
||||
((WORD)(s)<<8)) | \
|
||||
(((DWORD)(BYTE)(f))<<16)))
|
||||
|
||||
/* values borrowed from Linux 2.2.x cdrom.h */
|
||||
#define CDS_NO_INFO 0
|
||||
#define CDS_AUDIO 100
|
||||
#define CDS_DATA_1 101
|
||||
#define CDS_DATA_2 102
|
||||
#define CDS_XA_2_1 103
|
||||
#define CDS_XA_2_2 104
|
||||
#define CDS_MIXED 105
|
||||
|
||||
#endif
|
||||
|
|
@ -115,4 +115,10 @@ extern int DOSFS_FindNext( const char *path, const char *short_mask,
|
|||
/* win32/device.c */
|
||||
extern HANDLE DEVICE_Open( LPCSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
|
||||
|
||||
/* ntdll/cdrom.c.c */
|
||||
extern BOOL CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, DWORD dwIoControlCode,
|
||||
LPVOID lpInBuffer, DWORD nInBufferSize,
|
||||
LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
|
||||
|
||||
#endif /* __WINE_FILE_H */
|
||||
|
|
167
include/ntddcdrm.h
Normal file
167
include/ntddcdrm.h
Normal file
|
@ -0,0 +1,167 @@
|
|||
/* DDK information for CD ROM */
|
||||
|
||||
#ifndef __NTDDCDRM_H
|
||||
#define __NTDDCDRM_H
|
||||
|
||||
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
|
||||
#define IOCTL_CDROM_UNLOAD_DRIVER CTL_CODE(IOCTL_CDROM_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_CONTROL CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_PLAY_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_STOP_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_PAUSE_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RESUME_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_SET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_DISK_TYPE CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define IOCTL_CDROM_CHECK_VERIFY CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_EJECT_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_LOAD_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RESERVE CTL_CODE(IOCTL_CDROM_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RELEASE CTL_CODE(IOCTL_CDROM_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_FIND_NEW_DEVICES CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#include "ntddstor.h"
|
||||
|
||||
#define MAXIMUM_NUMBER_TRACKS 100
|
||||
#define MAXIMUM_CDROM_SIZE 804
|
||||
|
||||
typedef struct _TRACK_DATA {
|
||||
UCHAR Reserved;
|
||||
UCHAR Control : 4;
|
||||
UCHAR Adr : 4;
|
||||
UCHAR TrackNumber;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Address[4];
|
||||
} TRACK_DATA, *PTRACK_DATA;
|
||||
|
||||
typedef struct _CDROM_TOC {
|
||||
UCHAR Length[2];
|
||||
UCHAR FirstTrack;
|
||||
UCHAR LastTrack;
|
||||
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
|
||||
} CDROM_TOC, *PCDROM_TOC;
|
||||
|
||||
#define CDROM_TOC_SIZE sizeof(CDROM_TOC)
|
||||
|
||||
typedef struct _CDROM_PLAY_AUDIO_MSF {
|
||||
UCHAR StartingM;
|
||||
UCHAR StartingS;
|
||||
UCHAR StartingF;
|
||||
UCHAR EndingM;
|
||||
UCHAR EndingS;
|
||||
UCHAR EndingF;
|
||||
} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF;
|
||||
|
||||
typedef struct _CDROM_SEEK_AUDIO_MSF {
|
||||
UCHAR M;
|
||||
UCHAR S;
|
||||
UCHAR F;
|
||||
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
|
||||
|
||||
typedef struct _CDROM_DISK_DATA {
|
||||
ULONG DiskData;
|
||||
} CDROM_DISK_DATA, *PCDROM_DISK_DATA;
|
||||
|
||||
#define CDROM_DISK_AUDIO_TRACK (0x00000001)
|
||||
#define CDROM_DISK_DATA_TRACK (0x00000002)
|
||||
|
||||
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
|
||||
#define IOCTL_CDROM_CURRENT_POSITION 0x01
|
||||
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
|
||||
#define IOCTL_CDROM_TRACK_ISRC 0x03
|
||||
|
||||
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
|
||||
UCHAR Format;
|
||||
UCHAR Track;
|
||||
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
|
||||
|
||||
typedef struct _SUB_Q_HEADER {
|
||||
UCHAR Reserved;
|
||||
UCHAR AudioStatus;
|
||||
UCHAR DataLength[2];
|
||||
} SUB_Q_HEADER, *PSUB_Q_HEADER;
|
||||
|
||||
typedef struct _SUB_Q_CURRENT_POSITION {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Control : 4;
|
||||
UCHAR ADR : 4;
|
||||
UCHAR TrackNumber;
|
||||
UCHAR IndexNumber;
|
||||
UCHAR AbsoluteAddress[4];
|
||||
UCHAR TrackRelativeAddress[4];
|
||||
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
|
||||
|
||||
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved[3];
|
||||
UCHAR Reserved1 : 7;
|
||||
UCHAR Mcval : 1;
|
||||
UCHAR MediaCatalog[15];
|
||||
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
|
||||
|
||||
typedef struct _SUB_Q_TRACK_ISRC {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved0;
|
||||
UCHAR Track;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2 : 7;
|
||||
UCHAR Tcval : 1;
|
||||
UCHAR TrackIsrc[15];
|
||||
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
|
||||
|
||||
typedef union _SUB_Q_CHANNEL_DATA {
|
||||
SUB_Q_CURRENT_POSITION CurrentPosition;
|
||||
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
|
||||
SUB_Q_TRACK_ISRC TrackIsrc;
|
||||
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
|
||||
|
||||
#define AUDIO_STATUS_NOT_SUPPORTED 0x00
|
||||
#define AUDIO_STATUS_IN_PROGRESS 0x11
|
||||
#define AUDIO_STATUS_PAUSED 0x12
|
||||
#define AUDIO_STATUS_PLAY_COMPLETE 0x13
|
||||
#define AUDIO_STATUS_PLAY_ERROR 0x14
|
||||
#define AUDIO_STATUS_NO_STATUS 0x15
|
||||
|
||||
#define ADR_NO_MODE_INFORMATION 0x0
|
||||
#define ADR_ENCODES_CURRENT_POSITION 0x1
|
||||
#define ADR_ENCODES_MEDIA_CATALOG 0x2
|
||||
#define ADR_ENCODES_ISRC 0x3
|
||||
|
||||
#define AUDIO_WITH_PREEMPHASIS 0x0
|
||||
#define DIGITAL_COPY_PERMITTED 0x2
|
||||
#define AUDIO_DATA_TRACK 0x4
|
||||
#define TWO_FOUR_CHANNEL_AUDIO 0x8
|
||||
|
||||
typedef struct _CDROM_AUDIO_CONTROL {
|
||||
UCHAR LbaFormat;
|
||||
USHORT LogicalBlocksPerSecond;
|
||||
} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL;
|
||||
|
||||
typedef struct _VOLUME_CONTROL {
|
||||
UCHAR PortVolume[4];
|
||||
} VOLUME_CONTROL, *PVOLUME_CONTROL;
|
||||
|
||||
typedef enum _TRACK_MODE_TYPE {
|
||||
YellowMode2,
|
||||
XAForm2,
|
||||
CDDA
|
||||
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
|
||||
|
||||
typedef struct __RAW_READ_INFO {
|
||||
LARGE_INTEGER DiskOffset;
|
||||
ULONG SectorCount;
|
||||
TRACK_MODE_TYPE TrackMode;
|
||||
} RAW_READ_INFO, *PRAW_READ_INFO;
|
||||
|
||||
#endif /* __NTDDCDRM_H */
|
229
include/ntddstor.h
Normal file
229
include/ntddstor.h
Normal file
|
@ -0,0 +1,229 @@
|
|||
/* DDK definitions for storage media access */
|
||||
|
||||
#ifndef _NTDDSTOR_H_
|
||||
#define _NTDDSTOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
|
||||
|
||||
#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
typedef struct _STORAGE_DEVICE_NUMBER {
|
||||
DEVICE_TYPE DeviceType;
|
||||
ULONG DeviceNumber;
|
||||
ULONG PartitionNumber;
|
||||
} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
|
||||
|
||||
typedef struct _STORAGE_BUS_RESET_REQUEST {
|
||||
UCHAR PathId;
|
||||
} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST;
|
||||
|
||||
typedef struct _PREVENT_MEDIA_REMOVAL {
|
||||
BOOLEAN PreventMediaRemoval;
|
||||
} PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL;
|
||||
|
||||
typedef struct _TAPE_STATISTICS {
|
||||
ULONG Version;
|
||||
ULONG Flags;
|
||||
LARGE_INTEGER RecoveredWrites;
|
||||
LARGE_INTEGER UnrecoveredWrites;
|
||||
LARGE_INTEGER RecoveredReads;
|
||||
LARGE_INTEGER UnrecoveredReads;
|
||||
UCHAR CompressionRatioReads;
|
||||
UCHAR CompressionRatioWrites;
|
||||
} TAPE_STATISTICS, *PTAPE_STATISTICS;
|
||||
|
||||
#define RECOVERED_WRITES_VALID 0x00000001
|
||||
#define UNRECOVERED_WRITES_VALID 0x00000002
|
||||
#define RECOVERED_READS_VALID 0x00000004
|
||||
#define UNRECOVERED_READS_VALID 0x00000008
|
||||
#define WRITE_COMPRESSION_INFO_VALID 0x00000010
|
||||
#define READ_COMPRESSION_INFO_VALID 0x00000020
|
||||
|
||||
typedef struct _TAPE_GET_STATISTICS {
|
||||
ULONG Operation;
|
||||
} TAPE_GET_STATISTICS, *PTAPE_GET_STATISTICS;
|
||||
|
||||
#define TAPE_RETURN_STATISTICS 0L
|
||||
#define TAPE_RETURN_ENV_INFO 1L
|
||||
#define TAPE_RESET_STATISTICS 2L
|
||||
|
||||
typedef enum _STORAGE_MEDIA_TYPE {
|
||||
/* see also defines in ntdddisk.h */
|
||||
|
||||
DDS_4mm = 0x20,
|
||||
MiniQic,
|
||||
Travan,
|
||||
QIC,
|
||||
MP_8mm,
|
||||
AME_8mm,
|
||||
AIT1_8mm,
|
||||
DLT,
|
||||
NCTP,
|
||||
IBM_3480,
|
||||
IBM_3490E,
|
||||
IBM_Magstar_3590,
|
||||
IBM_Magstar_MP,
|
||||
STK_DATA_D3,
|
||||
SONY_DTF,
|
||||
DV_6mm,
|
||||
DMI,
|
||||
SONY_D2,
|
||||
CLEANER_CARTRIDGE,
|
||||
CD_ROM,
|
||||
CD_R,
|
||||
CD_RW,
|
||||
DVD_ROM,
|
||||
DVD_R,
|
||||
DVD_RW,
|
||||
MO_3_RW,
|
||||
MO_5_WO,
|
||||
MO_5_RW,
|
||||
MO_5_LIMDOW,
|
||||
PC_5_WO,
|
||||
PC_5_RW,
|
||||
PD_5_RW,
|
||||
ABL_5_WO,
|
||||
PINNACLE_APEX_5_RW,
|
||||
SONY_12_WO,
|
||||
PHILIPS_12_WO,
|
||||
HITACHI_12_WO,
|
||||
CYGNET_12_WO,
|
||||
KODAK_14_WO,
|
||||
MO_NFR_525,
|
||||
NIKON_12_RW,
|
||||
IOMEGA_ZIP,
|
||||
IOMEGA_JAZ,
|
||||
SYQUEST_EZ135,
|
||||
SYQUEST_EZFLYER,
|
||||
SYQUEST_SYJET,
|
||||
AVATAR_F2,
|
||||
MP2_8mm
|
||||
} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE;
|
||||
|
||||
#define MEDIA_ERASEABLE 0x00000001
|
||||
#define MEDIA_WRITE_ONCE 0x00000002
|
||||
#define MEDIA_READ_ONLY 0x00000004
|
||||
#define MEDIA_READ_WRITE 0x00000008
|
||||
#define MEDIA_WRITE_PROTECTED 0x00000100
|
||||
#define MEDIA_CURRENTLY_MOUNTED 0x80000000
|
||||
|
||||
typedef struct _DEVICE_MEDIA_INFO {
|
||||
union {
|
||||
struct {
|
||||
LARGE_INTEGER Cylinders;
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG TracksPerCylinder;
|
||||
ULONG SectorsPerTrack;
|
||||
ULONG BytesPerSector;
|
||||
ULONG NumberMediaSides;
|
||||
ULONG MediaCharacteristics;
|
||||
} DiskInfo;
|
||||
struct {
|
||||
LARGE_INTEGER Cylinders;
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG TracksPerCylinder;
|
||||
ULONG SectorsPerTrack;
|
||||
ULONG BytesPerSector;
|
||||
ULONG NumberMediaSides;
|
||||
ULONG MediaCharacteristics;
|
||||
} RemovableDiskInfo;
|
||||
struct {
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG MediaCharacteristics;
|
||||
ULONG CurrentBlockSize;
|
||||
} TapeInfo;
|
||||
} DeviceSpecific;
|
||||
} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO;
|
||||
|
||||
typedef struct _GET_MEDIA_TYPES {
|
||||
ULONG DeviceType;
|
||||
ULONG MediaInfoCount;
|
||||
DEVICE_MEDIA_INFO MediaInfo[1];
|
||||
} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES;
|
||||
|
||||
typedef enum _STORAGE_QUERY_TYPE {
|
||||
PropertyStandardQuery = 0,
|
||||
PropertyExistsQuery,
|
||||
PropertyMaskQuery,
|
||||
PropertyQueryMaxDefined
|
||||
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
|
||||
|
||||
typedef enum _STORAGE_PROPERTY_ID {
|
||||
StorageDeviceProperty = 0,
|
||||
StorageAdapterProperty
|
||||
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
|
||||
|
||||
typedef struct _STORAGE_PROPERTY_QUERY {
|
||||
STORAGE_PROPERTY_ID PropertyId;
|
||||
STORAGE_QUERY_TYPE QueryType;
|
||||
UCHAR AdditionalParameters[1];
|
||||
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
|
||||
|
||||
typedef struct _STORAGE_DESCRIPTOR_HEADER {
|
||||
ULONG Version;
|
||||
ULONG Size;
|
||||
} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER;
|
||||
|
||||
typedef enum _STORAGE_BUS_TYPE {
|
||||
BusTypeUnknown = 0x00,
|
||||
BusTypeScsi,
|
||||
BusTypeAtapi,
|
||||
BusTypeAta,
|
||||
BusType1394,
|
||||
BusTypeSsa,
|
||||
BusTypeFibre,
|
||||
BusTypeMaxReserved = 0x7F
|
||||
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
|
||||
|
||||
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
|
||||
ULONG Version;
|
||||
ULONG Size;
|
||||
UCHAR DeviceType;
|
||||
UCHAR DeviceTypeModifier;
|
||||
BOOLEAN RemovableMedia;
|
||||
BOOLEAN CommandQueueing;
|
||||
ULONG VendorIdOffset;
|
||||
ULONG ProductIdOffset;
|
||||
ULONG ProductRevisionOffset;
|
||||
ULONG SerialNumberOffset;
|
||||
STORAGE_BUS_TYPE BusType;
|
||||
ULONG RawPropertiesLength;
|
||||
UCHAR RawDeviceProperties[1];
|
||||
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
|
||||
|
||||
typedef struct _STORAGE_ADAPTER_DESCRIPTOR {
|
||||
ULONG Version;
|
||||
ULONG Size;
|
||||
ULONG MaximumTransferLength;
|
||||
ULONG MaximumPhysicalPages;
|
||||
ULONG AlignmentMask;
|
||||
BOOLEAN AdapterUsesPio;
|
||||
BOOLEAN AdapterScansDown;
|
||||
BOOLEAN CommandQueueing;
|
||||
BOOLEAN AcceleratedTransfer;
|
||||
BOOLEAN BusType;
|
||||
USHORT BusMajorVersion;
|
||||
USHORT BusMinorVersion;
|
||||
} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NTDDSTOR_H_ */
|
|
@ -150,7 +150,9 @@
|
|||
#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_EJECTION_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_MCN_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
@ -213,6 +215,81 @@
|
|||
#define PARTITION_LDM 0x42 /* Logical Disk Manager partition */
|
||||
#define PARTITION_UNIX 0x63 /* Unix */
|
||||
|
||||
typedef enum _MEDIA_TYPE {
|
||||
Unknown, F5_1Pt2_512, F3_1Pt44_512, F3_2Pt88_512, F3_20Pt8_512, F3_720_512, F5_360_512,
|
||||
F5_320_512, F5_320_1024, F5_180_512, F5_160_512, RemovableMedia, FixedMedia, F3_120M_512,
|
||||
F3_640_512, F5_640_512, F5_720_512, F3_1Pt2_512, F3_1Pt23_1024, F5_1Pt23_1024, F3_128Mb_512,
|
||||
F3_230Mb_512, F8_256_128
|
||||
} MEDIA_TYPE, *PMEDIA_TYPE;
|
||||
|
||||
typedef struct _FORMAT_PARAMETERS {
|
||||
MEDIA_TYPE MediaType;
|
||||
DWORD StartCylinderNumber;
|
||||
DWORD EndCylinderNumber;
|
||||
DWORD StartHeadNumber;
|
||||
DWORD EndHeadNumber;
|
||||
} FORMAT_PARAMETERS, *PFORMAT_PARAMETERS;
|
||||
|
||||
typedef WORD BAD_TRACK_NUMBER;
|
||||
typedef WORD *PBAD_TRACK_NUMBER;
|
||||
|
||||
typedef struct _FORMAT_EX_PARAMETERS {
|
||||
MEDIA_TYPE MediaType;
|
||||
DWORD StartCylinderNumber;
|
||||
DWORD EndCylinderNumber;
|
||||
DWORD StartHeadNumber;
|
||||
DWORD EndHeadNumber;
|
||||
WORD FormatGapLength;
|
||||
WORD SectorsPerTrack;
|
||||
WORD SectorNumber[1];
|
||||
} FORMAT_EX_PARAMETERS, *PFORMAT_EX_PARAMETERS;
|
||||
|
||||
typedef struct _DISK_GEOMETRY {
|
||||
LARGE_INTEGER Cylinders;
|
||||
MEDIA_TYPE MediaType;
|
||||
DWORD TracksPerCylinder;
|
||||
DWORD SectorsPerTrack;
|
||||
DWORD BytesPerSector;
|
||||
} DISK_GEOMETRY, *PDISK_GEOMETRY;
|
||||
|
||||
typedef struct _PARTITION_INFORMATION {
|
||||
LARGE_INTEGER StartingOffset;
|
||||
LARGE_INTEGER PartitionLength;
|
||||
DWORD HiddenSectors;
|
||||
DWORD PartitionNumber;
|
||||
BYTE PartitionType;
|
||||
BOOLEAN BootIndicator;
|
||||
BOOLEAN RecognizedPartition;
|
||||
BOOLEAN RewritePartition;
|
||||
} PARTITION_INFORMATION, *PPARTITION_INFORMATION;
|
||||
|
||||
typedef struct _SET_PARTITION_INFORMATION {
|
||||
BYTE PartitionType;
|
||||
} SET_PARTITION_INFORMATION, *PSET_PARTITION_INFORMATION;
|
||||
|
||||
typedef struct _DRIVE_LAYOUT_INFORMATION {
|
||||
DWORD PartitionCount;
|
||||
DWORD Signature;
|
||||
PARTITION_INFORMATION PartitionEntry[1];
|
||||
} DRIVE_LAYOUT_INFORMATION, *PDRIVE_LAYOUT_INFORMATION;
|
||||
|
||||
typedef struct _VERIFY_INFORMATION {
|
||||
LARGE_INTEGER StartingOffset;
|
||||
DWORD Length;
|
||||
} VERIFY_INFORMATION, *PVERIFY_INFORMATION;
|
||||
|
||||
typedef struct _REASSIGN_BLOCKS {
|
||||
WORD Reserved;
|
||||
WORD Count;
|
||||
DWORD BlockNumber[1];
|
||||
} REASSIGN_BLOCKS, *PREASSIGN_BLOCKS;
|
||||
|
||||
#if(_WIN32_WINNT >= 0x0400)
|
||||
typedef struct _DISK_CONTROLLER_NUMBER {
|
||||
DWORD ControllerNumber;
|
||||
DWORD DiskNumber;
|
||||
} DISK_CONTROLLER_NUMBER, *PDISK_CONTROLLER_NUMBER;
|
||||
#endif /* _WIN32_WINNT >= 0x0400 */
|
||||
|
||||
/* Device Io Stuff - Most VxD support.
|
||||
* NOTE: All VxD messages seem to start with a hiword or 0
|
||||
|
|
|
@ -7,7 +7,6 @@ VPATH = @srcdir@
|
|||
MODULE = misc
|
||||
|
||||
C_SRCS = \
|
||||
cdrom.c \
|
||||
cpu.c \
|
||||
error.c \
|
||||
main.c \
|
||||
|
|
908
misc/cdrom.c
908
misc/cdrom.c
|
@ -1,908 +0,0 @@
|
|||
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* Main file for CD-ROM support
|
||||
*
|
||||
* Copyright 1994 Martin Ayotte
|
||||
* Copyright 1999 Eric Pouech
|
||||
* Copyright 2000 Andreas Mohr
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "winnls.h"
|
||||
#include "cdrom.h"
|
||||
#include "drive.h"
|
||||
#include "debugtools.h"
|
||||
#include "winbase.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(cdrom);
|
||||
|
||||
#define MAX_CDAUDIO_TRACKS 256
|
||||
|
||||
#define CDROM_OPEN(wcda,parentdev) \
|
||||
(((parentdev) == -1) ? CDROM_OpenDev(wcda) : (parentdev))
|
||||
|
||||
#define CDROM_CLOSE(dev,parentdev) \
|
||||
(((parentdev) == -1) ? CDROM_CloseDev(dev) : 0)
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Open [internal]
|
||||
*
|
||||
* drive = 0, 1, ...
|
||||
* or -1 (figure it out)
|
||||
*/
|
||||
int CDROM_Open(WINE_CDAUDIO* wcda, int drive)
|
||||
{
|
||||
int i, dev;
|
||||
BOOL avail = FALSE;
|
||||
|
||||
if (drive == -1)
|
||||
{
|
||||
char root[] = "A:\\";
|
||||
for (i=0; i < MAX_DOS_DRIVES; i++, root[0]++)
|
||||
if (GetDriveTypeA(root) == DRIVE_CDROM)
|
||||
{
|
||||
drive = i;
|
||||
avail = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
avail = TRUE;
|
||||
|
||||
if (avail == FALSE)
|
||||
{
|
||||
WARN("No CD-ROM #%d found !\n", drive);
|
||||
return -1;
|
||||
}
|
||||
if ((wcda->devname = DRIVE_GetDevice(drive)) == NULL)
|
||||
{
|
||||
WARN("No device entry for CD-ROM #%d (drive %c:) found !\n",
|
||||
drive, 'A' + drive);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Test whether device can be opened */
|
||||
dev = CDROM_OpenDev(wcda);
|
||||
if (dev == -1)
|
||||
return -1;
|
||||
else
|
||||
CDROM_CloseDev(dev);
|
||||
|
||||
wcda->cdaMode = WINE_CDA_OPEN; /* to force reading tracks info */
|
||||
wcda->nCurTrack = 0;
|
||||
wcda->nTracks = 0;
|
||||
wcda->dwFirstFrame = 0;
|
||||
wcda->dwLastFrame = 0;
|
||||
wcda->lpdwTrackLen = NULL;
|
||||
wcda->lpdwTrackPos = NULL;
|
||||
wcda->lpbTrackFlags = NULL;
|
||||
TRACE("opened drive %c: (device %s)\n", 'A' + drive, wcda->devname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_OpenDev [internal]
|
||||
*
|
||||
*/
|
||||
int CDROM_OpenDev(WINE_CDAUDIO* wcda)
|
||||
{
|
||||
int dev = open(wcda->devname, O_RDONLY | O_NONBLOCK, 0);
|
||||
if (dev == -1)
|
||||
WARN("can't open device '%s'! (%s)\n", wcda->devname, strerror(errno));
|
||||
|
||||
TRACE("-> %d\n", dev);
|
||||
return dev;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetMediaType [internal]
|
||||
*/
|
||||
int CDROM_GetMediaType(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
int type = -1;
|
||||
#ifdef linux
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
type = ioctl(dev, CDROM_DISC_STATUS);
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
TRACE("-> %d\n", type);
|
||||
return type;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Close [internal]
|
||||
*/
|
||||
int CDROM_CloseDev(int dev)
|
||||
{
|
||||
TRACE("%d\n", dev);
|
||||
return close(dev);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Close [internal]
|
||||
*/
|
||||
int CDROM_Close(WINE_CDAUDIO* wcda)
|
||||
{
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
if (wcda->lpdwTrackLen != NULL) free(wcda->lpdwTrackLen);
|
||||
if (wcda->lpdwTrackPos != NULL) free(wcda->lpdwTrackPos);
|
||||
if (wcda->lpbTrackFlags != NULL) free(wcda->lpbTrackFlags);
|
||||
TRACE("%s\n", wcda->devname);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Get_UPC [internal]
|
||||
*
|
||||
* upc has to be 14 bytes long
|
||||
*/
|
||||
int CDROM_Get_UPC(WINE_CDAUDIO* wcda, LPSTR upc, int parentdev)
|
||||
{
|
||||
#ifdef linux
|
||||
struct cdrom_mcn mcn;
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
int status = ioctl(dev, CDROM_GET_MCN, &mcn);
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
if (status)
|
||||
{
|
||||
ERR("ioctl() failed with code %d\n",status);
|
||||
return -1;
|
||||
}
|
||||
strcpy(upc, mcn.medium_catalog_number);
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_GetNumberOfTracks [internal]
|
||||
*/
|
||||
UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
UINT16 ret = (UINT16)-1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#ifdef linux
|
||||
struct cdrom_tochdr hdr;
|
||||
#else
|
||||
struct ioc_toc_header hdr;
|
||||
#endif
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
|
||||
if (wcda->nTracks == 0) {
|
||||
#ifdef linux
|
||||
if (ioctl(dev, CDROMREADTOCHDR, &hdr))
|
||||
#else
|
||||
if (ioctl(dev, CDIOREADTOCHEADER, &hdr))
|
||||
#endif
|
||||
{
|
||||
WARN("(%p) -- Error occurred (%s)!\n", wcda, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
#ifdef linux
|
||||
wcda->nFirstTrack = hdr.cdth_trk0;
|
||||
wcda->nLastTrack = hdr.cdth_trk1;
|
||||
#else
|
||||
wcda->nFirstTrack = hdr.starting_track;
|
||||
wcda->nLastTrack = hdr.ending_track;
|
||||
#endif
|
||||
wcda->nTracks = wcda->nLastTrack - wcda->nFirstTrack + 1;
|
||||
}
|
||||
ret = wcda->nTracks;
|
||||
end:
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_GetTracksInfo [internal]
|
||||
*/
|
||||
BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int i, length;
|
||||
int start, last_start = 0;
|
||||
int total_length = 0;
|
||||
#ifdef linux
|
||||
struct cdrom_tocentry entry;
|
||||
#else
|
||||
struct ioc_read_toc_entry entry;
|
||||
struct cd_toc_entry toc_buffer;
|
||||
#endif
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
|
||||
if (wcda->nTracks == 0) {
|
||||
if (CDROM_Audio_GetNumberOfTracks(wcda, dev) == (WORD)-1)
|
||||
goto end;
|
||||
}
|
||||
TRACE("nTracks=%u\n", wcda->nTracks);
|
||||
|
||||
if (wcda->lpdwTrackLen != NULL)
|
||||
free(wcda->lpdwTrackLen);
|
||||
wcda->lpdwTrackLen = (LPDWORD)malloc((wcda->nTracks + 1) * sizeof(DWORD));
|
||||
if (wcda->lpdwTrackPos != NULL)
|
||||
free(wcda->lpdwTrackPos);
|
||||
wcda->lpdwTrackPos = (LPDWORD)malloc((wcda->nTracks + 1) * sizeof(DWORD));
|
||||
if (wcda->lpbTrackFlags != NULL)
|
||||
free(wcda->lpbTrackFlags);
|
||||
wcda->lpbTrackFlags = (LPBYTE)malloc((wcda->nTracks + 1) * sizeof(BYTE));
|
||||
if (wcda->lpdwTrackLen == NULL || wcda->lpdwTrackPos == NULL ||
|
||||
wcda->lpbTrackFlags == NULL) {
|
||||
WARN("error allocating track table !\n");
|
||||
goto end;
|
||||
}
|
||||
memset(wcda->lpdwTrackLen, 0, (wcda->nTracks + 1) * sizeof(DWORD));
|
||||
memset(wcda->lpdwTrackPos, 0, (wcda->nTracks + 1) * sizeof(DWORD));
|
||||
memset(wcda->lpbTrackFlags, 0, (wcda->nTracks + 1) * sizeof(BYTE));
|
||||
for (i = 0; i <= wcda->nTracks; i++) {
|
||||
if (i == wcda->nTracks)
|
||||
#ifdef linux
|
||||
entry.cdte_track = CDROM_LEADOUT;
|
||||
#else
|
||||
#define LEADOUT 0xaa
|
||||
entry.starting_track = LEADOUT; /* FIXME */
|
||||
#endif
|
||||
else
|
||||
#ifdef linux
|
||||
entry.cdte_track = i + 1;
|
||||
#else
|
||||
entry.starting_track = i + 1;
|
||||
#endif
|
||||
#ifdef linux
|
||||
entry.cdte_format = CDROM_MSF;
|
||||
#else
|
||||
memset((char *)&toc_buffer, 0, sizeof(toc_buffer));
|
||||
entry.address_format = CD_MSF_FORMAT;
|
||||
entry.data_len = sizeof(toc_buffer);
|
||||
entry.data = &toc_buffer;
|
||||
#endif
|
||||
#ifdef linux
|
||||
if (ioctl(dev, CDROMREADTOCENTRY, &entry))
|
||||
#else
|
||||
if (ioctl(dev, CDIOREADTOCENTRYS, &entry))
|
||||
#endif
|
||||
{
|
||||
WARN("error read entry (%s)\n", strerror(errno));
|
||||
/* update status according to new status */
|
||||
CDROM_Audio_GetCDStatus(wcda, dev);
|
||||
|
||||
goto end;
|
||||
}
|
||||
#ifdef linux
|
||||
start = CDFRAMES_PERSEC * (SECONDS_PERMIN *
|
||||
entry.cdte_addr.msf.minute + entry.cdte_addr.msf.second) +
|
||||
entry.cdte_addr.msf.frame;
|
||||
#else
|
||||
start = CDFRAMES_PERSEC * (SECONDS_PERMIN *
|
||||
toc_buffer.addr.msf.minute + toc_buffer.addr.msf.second) +
|
||||
toc_buffer.addr.msf.frame;
|
||||
#endif
|
||||
if (i == 0) {
|
||||
last_start = start;
|
||||
wcda->dwFirstFrame = start;
|
||||
TRACE("dwFirstOffset=%u\n", start);
|
||||
} else {
|
||||
length = start - last_start;
|
||||
last_start = start;
|
||||
start = last_start - length;
|
||||
total_length += length;
|
||||
wcda->lpdwTrackLen[i - 1] = length;
|
||||
wcda->lpdwTrackPos[i - 1] = start;
|
||||
TRACE("track #%u start=%u len=%u\n", i, start, length);
|
||||
}
|
||||
#ifdef linux
|
||||
wcda->lpbTrackFlags[i] =
|
||||
(entry.cdte_adr << 4) | (entry.cdte_ctrl & 0x0f);
|
||||
#else
|
||||
wcda->lpbTrackFlags[i] =
|
||||
(toc_buffer.addr_type << 4) | (toc_buffer.control & 0x0f);
|
||||
#endif
|
||||
TRACE("track #%u flags=%02x\n", i + 1, wcda->lpbTrackFlags[i]);
|
||||
}
|
||||
wcda->dwLastFrame = last_start;
|
||||
TRACE("total_len=%u\n", total_length);
|
||||
ret = TRUE;
|
||||
end:
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_GetCDStatus [internal]
|
||||
*/
|
||||
BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int oldmode = wcda->cdaMode;
|
||||
int ret = FALSE;
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
#ifdef linux
|
||||
wcda->sc.cdsc_format = CDROM_MSF;
|
||||
#else
|
||||
struct ioc_read_subchannel read_sc;
|
||||
|
||||
read_sc.address_format = CD_MSF_FORMAT;
|
||||
read_sc.data_format = CD_CURRENT_POSITION;
|
||||
read_sc.track = 0;
|
||||
read_sc.data_len = sizeof(wcda->sc);
|
||||
read_sc.data = (struct cd_sub_channel_info *)&wcda->sc;
|
||||
#endif
|
||||
#ifdef linux
|
||||
if (ioctl(dev, CDROMSUBCHNL, &wcda->sc))
|
||||
#else
|
||||
if (ioctl(dev, CDIOCREADSUBCHANNEL, &read_sc))
|
||||
#endif
|
||||
{
|
||||
TRACE("opened or no_media (%s)!\n", strerror(errno));
|
||||
wcda->cdaMode = WINE_CDA_OPEN; /* was NOT_READY */
|
||||
goto end;
|
||||
}
|
||||
switch (
|
||||
#ifdef linux
|
||||
wcda->sc.cdsc_audiostatus
|
||||
#else
|
||||
wcda->sc.header.audio_status
|
||||
#endif
|
||||
) {
|
||||
#ifdef linux
|
||||
case CDROM_AUDIO_INVALID:
|
||||
#else
|
||||
case CD_AS_AUDIO_INVALID:
|
||||
#endif
|
||||
/* seems that this means stop for ide drives */
|
||||
wcda->cdaMode = WINE_CDA_STOP;
|
||||
TRACE("AUDIO_INVALID -> WINE_CDA_STOP\n");
|
||||
break;
|
||||
#ifdef linux
|
||||
case CDROM_AUDIO_NO_STATUS:
|
||||
#else
|
||||
case CD_AS_NO_STATUS:
|
||||
#endif
|
||||
wcda->cdaMode = WINE_CDA_STOP;
|
||||
TRACE("WINE_CDA_STOP !\n");
|
||||
break;
|
||||
#ifdef linux
|
||||
case CDROM_AUDIO_PLAY:
|
||||
#else
|
||||
case CD_AS_PLAY_IN_PROGRESS:
|
||||
#endif
|
||||
wcda->cdaMode = WINE_CDA_PLAY;
|
||||
break;
|
||||
#ifdef linux
|
||||
case CDROM_AUDIO_PAUSED:
|
||||
#else
|
||||
case CD_AS_PLAY_PAUSED:
|
||||
#endif
|
||||
wcda->cdaMode = WINE_CDA_PAUSE;
|
||||
TRACE("WINE_CDA_PAUSE !\n");
|
||||
break;
|
||||
default:
|
||||
#ifdef linux
|
||||
TRACE("status=%02X !\n",
|
||||
wcda->sc.cdsc_audiostatus);
|
||||
#else
|
||||
TRACE("status=%02X !\n",
|
||||
wcda->sc.header.audio_status);
|
||||
#endif
|
||||
}
|
||||
#ifdef linux
|
||||
wcda->nCurTrack = wcda->sc.cdsc_trk;
|
||||
wcda->dwCurFrame =
|
||||
CDFRAMES_PERMIN * wcda->sc.cdsc_absaddr.msf.minute +
|
||||
CDFRAMES_PERSEC * wcda->sc.cdsc_absaddr.msf.second +
|
||||
wcda->sc.cdsc_absaddr.msf.frame;
|
||||
#else
|
||||
wcda->nCurTrack = wcda->sc.what.position.track_number;
|
||||
wcda->dwCurFrame =
|
||||
CDFRAMES_PERMIN * wcda->sc.what.position.absaddr.msf.minute +
|
||||
CDFRAMES_PERSEC * wcda->sc.what.position.absaddr.msf.second +
|
||||
wcda->sc.what.position.absaddr.msf.frame;
|
||||
#endif
|
||||
#ifdef linux
|
||||
TRACE("%02u-%02u:%02u:%02u\n",
|
||||
wcda->sc.cdsc_trk,
|
||||
wcda->sc.cdsc_absaddr.msf.minute,
|
||||
wcda->sc.cdsc_absaddr.msf.second,
|
||||
wcda->sc.cdsc_absaddr.msf.frame);
|
||||
#else
|
||||
TRACE("%02u-%02u:%02u:%02u\n",
|
||||
wcda->sc.what.position.track_number,
|
||||
wcda->sc.what.position.absaddr.msf.minute,
|
||||
wcda->sc.what.position.absaddr.msf.second,
|
||||
wcda->sc.what.position.absaddr.msf.frame);
|
||||
#endif
|
||||
|
||||
if (oldmode != wcda->cdaMode && oldmode == WINE_CDA_OPEN) {
|
||||
if (!CDROM_Audio_GetTracksInfo(wcda, dev)) {
|
||||
WARN("error updating TracksInfo !\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (wcda->cdaMode != WINE_CDA_OPEN)
|
||||
ret = TRUE;
|
||||
end:
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
return ret;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_Play [internal]
|
||||
*/
|
||||
int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD end, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
#ifdef linux
|
||||
struct cdrom_msf msf;
|
||||
#else
|
||||
struct ioc_play_msf msf;
|
||||
#endif
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
|
||||
#ifdef linux
|
||||
msf.cdmsf_min0 = start / CDFRAMES_PERMIN;
|
||||
msf.cdmsf_sec0 = (start % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
|
||||
msf.cdmsf_frame0 = start % CDFRAMES_PERSEC;
|
||||
msf.cdmsf_min1 = end / CDFRAMES_PERMIN;
|
||||
msf.cdmsf_sec1 = (end % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
|
||||
msf.cdmsf_frame1 = end % CDFRAMES_PERSEC;
|
||||
#else
|
||||
msf.start_m = start / CDFRAMES_PERMIN;
|
||||
msf.start_s = (start % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
|
||||
msf.start_f = start % CDFRAMES_PERSEC;
|
||||
msf.end_m = end / CDFRAMES_PERMIN;
|
||||
msf.end_s = (end % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
|
||||
msf.end_f = end % CDFRAMES_PERSEC;
|
||||
#endif
|
||||
#ifdef linux
|
||||
if (ioctl(dev, CDROMSTART))
|
||||
#else
|
||||
if (ioctl(dev, CDIOCSTART, NULL))
|
||||
#endif
|
||||
{
|
||||
WARN("motor doesn't start !\n");
|
||||
goto end;
|
||||
}
|
||||
#ifdef linux
|
||||
if (ioctl(dev, CDROMPLAYMSF, &msf))
|
||||
#else
|
||||
if (ioctl(dev, CDIOCPLAYMSF, &msf))
|
||||
#endif
|
||||
{
|
||||
WARN("device doesn't play !\n");
|
||||
goto end;
|
||||
}
|
||||
#ifdef linux
|
||||
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);
|
||||
#else
|
||||
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);
|
||||
#endif
|
||||
ret = 0;
|
||||
end:
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_Stop [internal]
|
||||
*/
|
||||
int CDROM_Audio_Stop(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
#ifdef linux
|
||||
ret = ioctl(dev, CDROMSTOP);
|
||||
#else
|
||||
ret = ioctl(dev, CDIOCSTOP, NULL);
|
||||
#endif
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_Pause [internal]
|
||||
*/
|
||||
int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
#ifdef linux
|
||||
ret = ioctl(dev, pauseOn ? CDROMPAUSE : CDROMRESUME);
|
||||
#else
|
||||
ret = ioctl(dev, pauseOn ? CDIOCPAUSE : CDIOCRESUME, NULL);
|
||||
#endif
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_Seek [internal]
|
||||
*/
|
||||
int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
#ifdef linux
|
||||
struct cdrom_msf0 msf;
|
||||
msf.minute = at / CDFRAMES_PERMIN;
|
||||
msf.second = (at % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
|
||||
msf.frame = at % CDFRAMES_PERSEC;
|
||||
|
||||
ret = ioctl(dev, CDROMSEEK, &msf);
|
||||
#else
|
||||
/* FIXME: the current end for play is lost
|
||||
* use end of CD ROM instead
|
||||
*/
|
||||
FIXME("Could a BSD expert implement the seek function ?\n");
|
||||
CDROM_Audio_Play(wcda, at, wcda->lpdwTrackPos[wcda->nTracks] + wcda->lpdwTrackLen[wcda->nTracks], dev);
|
||||
#endif
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_SetDoor [internal]
|
||||
*/
|
||||
int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
|
||||
TRACE("%d\n", open);
|
||||
#ifdef linux
|
||||
if (open) {
|
||||
ret = ioctl(dev, CDROMEJECT);
|
||||
} else {
|
||||
ret = ioctl(dev, CDROMCLOSETRAY);
|
||||
}
|
||||
#else
|
||||
ret = (ioctl(dev, CDIOCALLOW, NULL)) ||
|
||||
(ioctl(dev, open ? CDIOCEJECT : CDIOCCLOSE, NULL)) ||
|
||||
(ioctl(dev, CDIOCPREVENT, NULL));
|
||||
#endif
|
||||
wcda->nTracks = 0;
|
||||
if (ret == -1)
|
||||
WARN("failed (%s)\n", strerror(errno));
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Reset [internal]
|
||||
*/
|
||||
int CDROM_Reset(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
int ret = -1;
|
||||
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
#ifdef linux
|
||||
ret = ioctl(dev, CDROMRESET);
|
||||
#else
|
||||
ret = ioctl(dev, CDIOCRESET, NULL);
|
||||
#endif
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_FindBestVoldesc [internal]
|
||||
*/
|
||||
WORD CDROM_Data_FindBestVoldesc(int fd)
|
||||
{
|
||||
BYTE cur_vd_type, max_vd_type = 0;
|
||||
unsigned int offs, best_offs=0, extra_offs = 0;
|
||||
char sig[3];
|
||||
|
||||
|
||||
for (offs=0x8000; offs <= 0x9800; offs += 0x800)
|
||||
{
|
||||
/* if 'CDROM' occurs at position 8, this is a pre-iso9660 cd, and
|
||||
* the volume label is displaced forward by 8
|
||||
*/
|
||||
lseek(fd, offs+11, SEEK_SET); /* check for non-ISO9660 signature */
|
||||
read(fd, &sig, 3);
|
||||
if ((sig[0]=='R')&&(sig[1]=='O')&&(sig[2]=='M'))
|
||||
{
|
||||
extra_offs=8;
|
||||
}
|
||||
lseek(fd, offs+extra_offs, SEEK_SET);
|
||||
read(fd, &cur_vd_type, 1);
|
||||
if (cur_vd_type == 0xff) /* voldesc set terminator */
|
||||
break;
|
||||
if (cur_vd_type > max_vd_type)
|
||||
{
|
||||
max_vd_type = cur_vd_type;
|
||||
best_offs = offs + extra_offs;
|
||||
}
|
||||
}
|
||||
return best_offs;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Audio_GetSerial [internal]
|
||||
*/
|
||||
DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda)
|
||||
{
|
||||
unsigned long serial = 0;
|
||||
int i;
|
||||
DWORD dwFrame, msf;
|
||||
WORD wMinutes, wSeconds, wFrames;
|
||||
WORD wMagic;
|
||||
DWORD dwStart, dwEnd;
|
||||
|
||||
/*
|
||||
* wMagic collects the wFrames from track 1
|
||||
* dwStart, dwEnd collect the beginning and end of the disc respectively, in
|
||||
* frames.
|
||||
* There it is collected for correcting the serial when there are less than
|
||||
* 3 tracks.
|
||||
*/
|
||||
wMagic = 0;
|
||||
dwStart = dwEnd = 0;
|
||||
|
||||
for (i = 0; i < wcda->nTracks; i++) {
|
||||
dwFrame = wcda->lpdwTrackPos[i];
|
||||
wMinutes = dwFrame / CDFRAMES_PERMIN;
|
||||
wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
|
||||
wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
|
||||
msf = CDROM_MAKE_MSF(wMinutes, wSeconds, wFrames);
|
||||
|
||||
serial += (CDROM_MSF_MINUTE(msf) << 16) +
|
||||
(CDROM_MSF_SECOND(msf) << 8) +
|
||||
(CDROM_MSF_FRAME(msf));
|
||||
|
||||
if (i==0)
|
||||
{
|
||||
wMagic = wFrames;
|
||||
dwStart = dwFrame;
|
||||
}
|
||||
dwEnd = dwFrame + wcda->lpdwTrackLen[i];
|
||||
|
||||
}
|
||||
|
||||
if (wcda->nTracks < 3)
|
||||
{
|
||||
serial += wMagic + (dwEnd - dwStart);
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_GetSerial [internal]
|
||||
*/
|
||||
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda, int parentdev)
|
||||
{
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
WORD offs = CDROM_Data_FindBestVoldesc(dev);
|
||||
union {
|
||||
unsigned long val;
|
||||
unsigned char p[4];
|
||||
} serial;
|
||||
BYTE b0 = 0, b1 = 1, b2 = 2, b3 = 3;
|
||||
|
||||
serial.val = 0;
|
||||
if (offs)
|
||||
{
|
||||
BYTE buf[2048];
|
||||
OSVERSIONINFOA ovi;
|
||||
int i;
|
||||
|
||||
lseek(dev,offs,SEEK_SET);
|
||||
read(dev,buf,2048);
|
||||
/*
|
||||
* OK, another braindead one... argh. Just believe it.
|
||||
* Me$$ysoft chose to reverse the serial number in NT4/W2K.
|
||||
* It's true and nobody will ever be able to change it.
|
||||
*/
|
||||
ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
GetVersionExA(&ovi);
|
||||
if ((ovi.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
||||
&& (ovi.dwMajorVersion >= 4))
|
||||
{
|
||||
b0 = 3; b1 = 2; b2 = 1; b3 = 0;
|
||||
}
|
||||
for(i=0; i<2048; i+=4)
|
||||
{
|
||||
/* DON'T optimize this into DWORD !! (breaks overflow) */
|
||||
serial.p[b0] += buf[i+b0];
|
||||
serial.p[b1] += buf[i+b1];
|
||||
serial.p[b2] += buf[i+b2];
|
||||
serial.p[b3] += buf[i+b3];
|
||||
}
|
||||
}
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
return serial.val;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetSerial [internal]
|
||||
*/
|
||||
DWORD CDROM_GetSerial(int drive)
|
||||
{
|
||||
WINE_CDAUDIO wcda;
|
||||
DWORD serial = 0;
|
||||
|
||||
/* EXPIRES 01.01.2002 */
|
||||
WARN("CD-ROM serial number calculation might fail.\n");
|
||||
WARN("Please test with as many exotic CDs as possible !\n");
|
||||
|
||||
if (!(CDROM_Open(&wcda, drive)))
|
||||
{
|
||||
int dev = CDROM_OpenDev(&wcda);
|
||||
int media = CDROM_GetMediaType(&wcda, dev);
|
||||
|
||||
switch (media)
|
||||
{
|
||||
case CDS_AUDIO:
|
||||
case CDS_MIXED: /* mixed is basically a mountable audio CD */
|
||||
if (!(CDROM_Audio_GetCDStatus(&wcda, dev))) {
|
||||
ERR("couldn't get CD status !\n");
|
||||
goto end;
|
||||
}
|
||||
serial = CDROM_Audio_GetSerial(&wcda);
|
||||
break;
|
||||
case CDS_DATA_1:
|
||||
case CDS_DATA_2:
|
||||
case CDS_XA_2_1:
|
||||
case CDS_XA_2_2:
|
||||
case -1: /* ioctl() error: ISO9660 image file given ? */
|
||||
/* hopefully a data CD */
|
||||
serial = CDROM_Data_GetSerial(&wcda, dev);
|
||||
break;
|
||||
default:
|
||||
WARN("Strange CD type (%d) or empty ?\n", media);
|
||||
}
|
||||
if (serial)
|
||||
TRACE("CD serial number is %04x-%04x.\n",
|
||||
HIWORD(serial), LOWORD(serial));
|
||||
else
|
||||
if (media >= CDS_AUDIO)
|
||||
ERR("couldn't get CD serial !\n");
|
||||
end:
|
||||
CDROM_CloseDev(dev);
|
||||
CDROM_Close(&wcda);
|
||||
}
|
||||
return serial;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_GetLabel [internal]
|
||||
*/
|
||||
DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label, int parentdev)
|
||||
{
|
||||
#define LABEL_LEN 32+1
|
||||
int dev = CDROM_OPEN( wcda, parentdev );
|
||||
WORD offs = CDROM_Data_FindBestVoldesc(dev);
|
||||
WCHAR label_read[LABEL_LEN]; /* Unicode possible, too */
|
||||
DWORD unicode_id = 0;
|
||||
|
||||
if (offs)
|
||||
{
|
||||
if ((lseek(dev, offs+0x58, SEEK_SET) == offs+0x58)
|
||||
&& (read(dev, &unicode_id, 3) == 3))
|
||||
{
|
||||
int ver = (unicode_id & 0xff0000) >> 16;
|
||||
|
||||
if ((lseek(dev, offs+0x28, SEEK_SET) != offs+0x28)
|
||||
|| (read(dev, &label_read, LABEL_LEN) != LABEL_LEN))
|
||||
goto failure;
|
||||
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
if ((LOWORD(unicode_id) == 0x2f25) /* Unicode ID */
|
||||
&& ((ver == 0x40) || (ver == 0x43) || (ver == 0x45)))
|
||||
{ /* yippee, unicode */
|
||||
int i;
|
||||
WORD ch;
|
||||
for (i=0; i<LABEL_LEN;i++)
|
||||
{ /* Motorola -> Intel Unicode conversion :-\ */
|
||||
ch = label_read[i];
|
||||
label_read[i] = (ch << 8) | (ch >> 8);
|
||||
}
|
||||
WideCharToMultiByte( CP_ACP, 0, label_read, -1, label, 12, NULL, NULL );
|
||||
label[11] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(label, (LPSTR)label_read, 11);
|
||||
label[11] = '\0';
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
failure:
|
||||
CDROM_CLOSE( dev, parentdev );
|
||||
ERR("error reading label !\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetLabel [internal]
|
||||
*/
|
||||
DWORD CDROM_GetLabel(int drive, char *label)
|
||||
{
|
||||
WINE_CDAUDIO wcda;
|
||||
DWORD ret = 1;
|
||||
|
||||
if (!(CDROM_Open(&wcda, drive)))
|
||||
{
|
||||
int dev = CDROM_OpenDev(&wcda);
|
||||
int media = CDROM_GetMediaType(&wcda, dev);
|
||||
LPSTR cdname = NULL;
|
||||
|
||||
switch (media)
|
||||
{
|
||||
case CDS_AUDIO:
|
||||
cdname = "Audio";
|
||||
strcpy(label, "Audio CD ");
|
||||
break;
|
||||
|
||||
case CDS_DATA_1: /* fall through for all data CD types !! */
|
||||
if (!cdname) cdname = "Data_1";
|
||||
case CDS_DATA_2:
|
||||
if (!cdname) cdname = "Data_2";
|
||||
case CDS_XA_2_1:
|
||||
if (!cdname) cdname = "XA 2.1";
|
||||
case CDS_XA_2_2:
|
||||
if (!cdname) cdname = "XA 2.2";
|
||||
case CDS_MIXED:
|
||||
if (!cdname) cdname = "Mixed mode";
|
||||
case -1:
|
||||
if (!cdname) cdname = "Unknown/ISO file";
|
||||
|
||||
/* common code *here* !! */
|
||||
/* hopefully a data CD */
|
||||
if (!CDROM_Data_GetLabel(&wcda, label, dev))
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
case CDS_NO_INFO:
|
||||
if (!cdname) cdname = "No_info";
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
WARN("Strange CD type (%d) or empty ?\n", media);
|
||||
cdname = "Strange/empty";
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
CDROM_CloseDev(dev);
|
||||
CDROM_Close(&wcda);
|
||||
TRACE("%s CD: label is '%s'.\n",
|
||||
cdname, label);
|
||||
}
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -319,8 +319,7 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
|
|||
|
||||
|
||||
|
||||
HANDLE DEVICE_Open( LPCSTR filename, DWORD access,
|
||||
LPSECURITY_ATTRIBUTES sa )
|
||||
HANDLE DEVICE_Open( LPCSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa )
|
||||
{
|
||||
const struct VxDInfo *info;
|
||||
|
||||
|
@ -333,21 +332,28 @@ HANDLE DEVICE_Open( LPCSTR filename, DWORD access,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct VxDInfo *DEVICE_GetInfo( HANDLE handle )
|
||||
static DWORD DEVICE_GetClientID( HANDLE handle )
|
||||
{
|
||||
const struct VxDInfo *info = NULL;
|
||||
DWORD ret = 0;
|
||||
SERVER_START_REQ( get_file_info )
|
||||
{
|
||||
req->handle = handle;
|
||||
if (!wine_server_call( req ) &&
|
||||
(reply->type == FILE_TYPE_UNKNOWN) &&
|
||||
(reply->attr & 0x10000))
|
||||
{
|
||||
for (info = VxDList; info->name; info++)
|
||||
if (info->id == LOWORD(reply->attr)) break;
|
||||
}
|
||||
if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN))
|
||||
ret = reply->attr;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct VxDInfo *DEVICE_GetInfo( DWORD clientID )
|
||||
{
|
||||
const struct VxDInfo *info = NULL;
|
||||
|
||||
if (clientID & 0x10000)
|
||||
{
|
||||
for (info = VxDList; info->name; info++)
|
||||
if (info->id == LOWORD(clientID)) break;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
|
@ -366,13 +372,13 @@ BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
|
|||
LPDWORD lpcbBytesReturned,
|
||||
LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
const struct VxDInfo *info;
|
||||
DWORD clientID;
|
||||
|
||||
TRACE( "(%d,%ld,%p,%ld,%p,%ld,%p,%p)\n",
|
||||
hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer,
|
||||
lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped );
|
||||
|
||||
if (!(info = DEVICE_GetInfo( hDevice )))
|
||||
if (!(clientID = DEVICE_GetClientID( hDevice )))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
|
@ -381,7 +387,12 @@ BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
|
|||
/* Check if this is a user defined control code for a VxD */
|
||||
if( HIWORD( dwIoControlCode ) == 0 )
|
||||
{
|
||||
if ( info->deviceio )
|
||||
const struct VxDInfo *info;
|
||||
if (!(info = DEVICE_GetInfo( clientID )))
|
||||
{
|
||||
FIXME( "No device found for id %lx\n", clientID);
|
||||
}
|
||||
else if ( info->deviceio )
|
||||
{
|
||||
return info->deviceio( dwIoControlCode,
|
||||
lpvInBuffer, cbInBuffer,
|
||||
|
@ -400,7 +411,15 @@ BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode,
|
|||
}
|
||||
else
|
||||
{
|
||||
switch( dwIoControlCode )
|
||||
char str[3];
|
||||
|
||||
strcpy(str, "A:");
|
||||
str[0] += LOBYTE(clientID);
|
||||
if (GetDriveTypeA(str) == DRIVE_CDROM)
|
||||
return CDROM_DeviceIoControl(clientID, hDevice, dwIoControlCode, lpvInBuffer, cbInBuffer,
|
||||
lpvOutBuffer, cbOutBuffer, lpcbBytesReturned,
|
||||
lpOverlapped);
|
||||
else switch( dwIoControlCode )
|
||||
{
|
||||
case FSCTL_DELETE_REPARSE_POINT:
|
||||
case FSCTL_DISMOUNT_VOLUME:
|
||||
|
@ -1135,7 +1154,7 @@ static BOOL DeviceIo_VWin32(DWORD dwIoControlCode,
|
|||
case VWIN32_DIOC_DOS_INT13:
|
||||
case VWIN32_DIOC_DOS_INT25:
|
||||
case VWIN32_DIOC_DOS_INT26:
|
||||
case VWIN32_DIOC_DOS_DRIVEINFO:
|
||||
case VWIN32_DIOC_DOS_DRIVEINFO:
|
||||
{
|
||||
CONTEXT86 cxt;
|
||||
DIOC_REGISTERS *pIn = (DIOC_REGISTERS *)lpvInBuffer;
|
||||
|
@ -1160,7 +1179,7 @@ static BOOL DeviceIo_VWin32(DWORD dwIoControlCode,
|
|||
case VWIN32_DIOC_DOS_INT13: INT_Int13Handler( &cxt ); break;
|
||||
case VWIN32_DIOC_DOS_INT25: INT_Int25Handler( &cxt ); break;
|
||||
case VWIN32_DIOC_DOS_INT26: INT_Int26Handler( &cxt ); break;
|
||||
case VWIN32_DIOC_DOS_DRIVEINFO: DOS3Call( &cxt ); break; /* Call int 21h 730x */
|
||||
case VWIN32_DIOC_DOS_DRIVEINFO: DOS3Call( &cxt ); break; /* Call int 21h 730x */
|
||||
}
|
||||
|
||||
CONTEXT_2_DIOCRegs( &cxt, pOut );
|
||||
|
|
Loading…
Reference in a new issue