Commit 5cc6105b authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

Changed the Wine internal cdrom interface to the NT model.

parent 220c1c2c
......@@ -6,6 +6,7 @@ MODULE = ntdll
EXTRALIBS = $(LIBUNICODE)
C_SRCS = \
cdrom.c \
critsection.c \
debugtools.c \
exception.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 );
......
/* -*- 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 */
/* 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 */
/* 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 \
......
......@@ -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 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment