- support for reading labels and serial nums from device
- "reasonable" misc/cdrom.c device handling
- much improved audio CD support
- serial number overwrite bug fix
- spelling fixes
diff --git a/dlls/winmm/mcicda/mcicda.c b/dlls/winmm/mcicda/mcicda.c
index 9a87d18..77451c3 100644
--- a/dlls/winmm/mcicda/mcicda.c
+++ b/dlls/winmm/mcicda/mcicda.c
@@ -242,7 +242,7 @@
}
wmcda->wNotifyDeviceID = dwDeviceID;
- if (CDAUDIO_Open(&wmcda->wcda) == -1) {
+ if (CDAUDIO_Open(&wmcda->wcda, -1) == -1) {
--wmcda->nUseCount;
return MCIERR_HARDWARE;
}
diff --git a/documentation/cdrom-labels b/documentation/cdrom-labels
index a2f2bca..ce3bc7c 100644
--- a/documentation/cdrom-labels
+++ b/documentation/cdrom-labels
@@ -1,60 +1,70 @@
-*** VOLUME LABEL
+ Drive labels and serial numbers with wine
+ -----------------------------------------
-If a program depends on the correct label and/or serial number for the
-CD-Rom, you can use the following command to extract that information:
+ Until now, your only possibility of specifying drive volume labels
+and serial numbers was to set them manually in the wine config file.
+By now, wine can read them directly from the device as well. This may be
+useful for many Win 9x games or for setup programs distributed on CD-ROMs
+that check for volume label.
- dd if=<your cdrom device> bs=1 skip=32808 count=32
+WHAT'S SUPPORTED ?
-You need read access to the device, so perhaps you have to do it as root.
-Put the resulting string (without trailing blanks) into your
-wine.ini/.winerc file like:
-Label=<the label>
+ * FAT systems (types 'hd' and 'floppy'): reads labels and serial num's.
+ * Iso9660 ('cdrom'): reads labels only.
-*** SERIAL NUMBER
+HOW TO SET UP ?
-[FIXME: if someone knows how to get the serial number in Linux, please
- put this information here].
+ Reading labels and serial numbers just works automagically if
+you specify a 'Device=' line in the [Drive X] section in your wine.conf.
+Note that the device has to exist and must be accessible if you do this,
+though.
+If you don't do that, then you should give fixed 'Label=' or 'Serial=' entries
+in wine.conf, as Wine returns these entries instead if no device is given.
+If they don't exist, then Wine will return default values (label "Drive X"
+and serial 12345678).
-If you have access to a Win32 system and C-compiler, you can compile the
-following program to extract this information:
+Now a seldom needed one:
+If you want to give a 'Device=' entry *only* for drive raw sector accesses, but
+not for reading the volume info from the device (i.e. you want a *fixed*,
+preconfigured label), you need to specify 'ReadVolInfo=0' to tell Wine to skip
+the volume reading.
-------------------------- begin volinfo.c ---------------------------
-#include <windows.h>
-#include <stdio.h>
+EXAMPLES
-int main(int argc,char **argv[])
-{
- char drive, root[]="C:\\", label[1002], fsname[1002];
- DWORD serial, flags, filenamelen, labellen = 1000, fsnamelen = 1000;
+*** Simple example of cdrom and floppy; labels will be read from the device on
+both cdrom and floppy; serial numbers on floppy only:
- printf("Drive Serial Flags Filename-Length "
- "Label Fsname\n");
- for (drive = 'C'; drive <= 'Z'; drive++)
- {
- root[0] = drive;
- if (GetVolumeInformationA(root,label,labellen,&serial,
- &filenamelen,&flags,fsname,fsnamelen))
- {
- strcat(label,"\""); strcat (fsname,"\"");
- printf("%c:\\ 0x%08lx 0x%08lx %15ld \"%-20s \"%-20s\n",
- drive, (long) serial, (long) flags, (long) filenamelen,
- label, fsname);
- }
- }
- return 0;
-}
+[Drive A]
+Path=/mnt/floppy
+Type=floppy
+Device=/dev/fd0
+Filesystem=msdos
-Probably you can get that information also from the File Manager in
-Windows.
+[Drive R]
+Path=/mnt/cdrom
+Type=cdrom
+Device=/dev/hda1
+Filesystem=win95
-------------------------- end volinfo.c -----------------------------
+*** CD-ROM. We want to override the label:
+[Drive J]
+Path=/mnt/cdrom
+Type=cdrom
+Label=X234GCDSE
+; note that the device isn't really needed here as we have a fixed label
+Device=/dev/cdrom
+Filesystem=msdos
-*** DRIVE LETTER
+TODO / OPEN ISSUES
-Some installed programs only look for the CD-Rom in the drive letter
-that the CD-Rom had when the program was installed. In this case, make
-sure you use the correct letter, especially if you installed the
-program under Windows and are now trying to run it in Wine.
-Some programs reportedly store the drive letter in their .INI file,
-so you might look there and try to change it.
+ - The cdrom label can be read only if the data track of the disk resides in
+the first track and the cdrom is iso9660.
+ - Better checking for FAT superblock (it now check's only one byte).
+ - Support for labels/serial num's WRITING.
+ - Can the label be longer than 11 chars? (iso9660 has 32 chars).
+ - What about reading ext2 volume label? ....
+
+Petr Tomasek changes by: Andreas Mohr
+<tomasek@etf.cuni.cz> <a.mohr@mailto.de>
+Nov 14 1999 Jan 25 2000
diff --git a/files/drive.c b/files/drive.c
index 7363c2f..865439f 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -3,6 +3,11 @@
*
* Copyright 1993 Erik Bos
* Copyright 1996 Alexandre Julliard
+ *
+ * Label & serial number read support.
+ * (c) 1999 Petr Tomasek <tomasek@etf.cuni.cz>
+ * (c) 2000 Andreas Mohr (changes)
+ *
*/
#include "config.h"
@@ -37,6 +42,7 @@
#include "wine/winestring.h" /* for lstrcpyAtoW */
#include "winerror.h"
#include "drive.h"
+#include "cdrom.h"
#include "file.h"
#include "heap.h"
#include "msdos.h"
@@ -54,8 +60,10 @@
char *dos_cwd; /* cwd in DOS format without leading or trailing \ */
char *unix_cwd; /* cwd in Unix format without leading or trailing / */
char *device; /* raw device path */
- char label[12]; /* drive label */
- DWORD serial; /* drive serial number */
+ BOOL read_volinfo; /* read the volume info from the device ? */
+ char label_conf[12]; /* drive label as cfg'd in wine.conf */
+ char label_read[12]; /* drive label as read from device */
+ DWORD serial_conf; /* drive serial number as cfg'd in wine.conf */
DRIVETYPE type; /* drive type */
UINT flags; /* drive flags */
dev_t dev; /* unix device number */
@@ -111,7 +119,8 @@
{
if (!strcasecmp( buffer, DRIVE_Types[i] )) return (DRIVETYPE)i;
}
- MESSAGE("%s: unknown type '%s', defaulting to 'hd'.\n", name, buffer );
+ MESSAGE("%s: unknown drive type '%s', defaulting to 'hd'.\n",
+ name, buffer );
return TYPE_HD;
}
@@ -175,18 +184,18 @@
drive->ino = drive_stat_buffer.st_ino;
/* Get the drive label */
- PROFILE_GetWineIniString( name, "Label", name, drive->label, 12 );
- if ((len = strlen(drive->label)) < 11)
+ PROFILE_GetWineIniString( name, "Label", name, drive->label_conf, 12 );
+ if ((len = strlen(drive->label_conf)) < 11)
{
/* Pad label with spaces */
- memset( drive->label + len, ' ', 11 - len );
- drive->label[12] = '\0';
+ memset( drive->label_conf + len, ' ', 11 - len );
+ drive->label_conf[11] = '\0';
}
/* Get the serial number */
PROFILE_GetWineIniString( name, "Serial", "12345678",
buffer, sizeof(buffer) );
- drive->serial = strtoul( buffer, NULL, 16 );
+ drive->serial_conf = strtoul( buffer, NULL, 16 );
/* Get the filesystem type */
PROFILE_GetWineIniString( name, "Filesystem", "win95",
@@ -197,7 +206,13 @@
PROFILE_GetWineIniString( name, "Device", "",
buffer, sizeof(buffer) );
if (buffer[0])
+ {
drive->device = HEAP_strdupA( SystemHeap, 0, buffer );
+ drive->read_volinfo =
+ (BOOL)PROFILE_GetWineIniInt( name, "ReadVolInfo", 1);
+ }
+ else
+ drive->read_volinfo = FALSE;
/* Make the first hard disk the current drive */
if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD))
@@ -207,7 +222,7 @@
TRACE("%s: path=%s type=%s label='%s' serial=%08lx "
"flags=%08x dev=%x ino=%x\n",
name, path, DRIVE_Types[drive->type],
- drive->label, drive->serial, drive->flags,
+ drive->label_conf, drive->serial_conf, drive->flags,
(int)drive->dev, (int)drive->ino );
}
else WARN("%s: not defined\n", name );
@@ -220,8 +235,8 @@
DOSDrives[2].root = HEAP_strdupA( SystemHeap, 0, "/" );
DOSDrives[2].dos_cwd = HEAP_strdupA( SystemHeap, 0, "" );
DOSDrives[2].unix_cwd = HEAP_strdupA( SystemHeap, 0, "" );
- strcpy( DOSDrives[2].label, "Drive C " );
- DOSDrives[2].serial = 0x12345678;
+ strcpy( DOSDrives[2].label_conf, "Drive C " );
+ DOSDrives[2].serial_conf = 12345678;
DOSDrives[2].type = TYPE_HD;
DOSDrives[2].flags = 0;
DRIVE_CurDrive = 2;
@@ -396,22 +411,161 @@
/***********************************************************************
+ * DRIVE_GetDevice
+ */
+const char * DRIVE_GetDevice( int drive )
+{
+ return (DRIVE_IsValid( drive )) ? DOSDrives[drive].device : NULL;
+}
+
+
+/***********************************************************************
+ * DRIVE_ReadSuperblock
+ *
+ * Used in DRIVE_GetLabel
+ */
+int DRIVE_ReadSuperblock (int drive, char * buff)
+{
+#define DRIVE_SUPER 96
+ int fd;
+ off_t offs;
+
+ if (memset(buff,0,DRIVE_SUPER)!=buff) return -1;
+ if ((fd=open(DOSDrives[drive].device,O_RDONLY)) == -1)
+ {
+ struct stat st;
+ if (!DOSDrives[drive].device)
+ ERR("No device configured for drive %c: !\n", 'A'+drive);
+ else
+ ERR("Couldn't open device '%s' for drive %c: ! (%s)\n", DOSDrives[drive].device, 'A'+drive,
+ (stat(DOSDrives[drive].device, &st)) ?
+ "not available or symlink not valid ?" : "no permission");
+ ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n");
+ PROFILE_UsageWineIni();
+ return -1;
+ }
+
+ switch(DOSDrives[drive].type)
+ {
+ case TYPE_FLOPPY:
+ case TYPE_HD:
+ offs = 0;
+ break;
+ case TYPE_CDROM:
+ /* FIXME: Maybe we should search for the first data track on the CD,
+ not just assume that it is the first track */
+ offs = (off_t)2048*(16+0);
+ break;
+ default:
+ offs = 0;
+ break;
+ }
+
+ if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs)) return -4;
+ if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER) return -2;
+
+ switch(DOSDrives[drive].type)
+ {
+ case TYPE_FLOPPY:
+ case TYPE_HD:
+ if (buff[0x26]!=0x29) /* Check for FAT present */
+ return -3;
+ break;
+ case TYPE_CDROM:
+ if (strncmp(&buff[1],"CD001",5)) /* Check for iso9660 present */
+ return -3;
+ /* FIXME: do we need to check for "CDROM", too ? (high sierra) */
+ break;
+ default:
+ return -3;
+ break;
+ }
+
+ return close(fd);
+}
+
+
+/***********************************************************************
* DRIVE_GetLabel
*/
const char * DRIVE_GetLabel( int drive )
{
+ int read = 0;
+ char buff[DRIVE_SUPER];
+ int offs = -1;
+
if (!DRIVE_IsValid( drive )) return NULL;
- return DOSDrives[drive].label;
+ if (DRIVE_GetType(drive) == TYPE_CDROM)
+ {
+ WINE_CDAUDIO wcda;
+
+ if (!(CDAUDIO_Open(&wcda, drive)))
+ {
+ int media = CDAUDIO_GetMediaType(&wcda);
+
+ if (media == CDS_AUDIO)
+ {
+ strcpy(DOSDrives[drive].label_read, "Audio CD ");
+ read = 1;
+ }
+ else
+ if (media == CDS_NO_INFO)
+ {
+ strcpy(DOSDrives[drive].label_read, " ");
+ read = 1;
+ }
+
+ CDAUDIO_Close(&wcda);
+}
+ }
+ if ((!read) && (DOSDrives[drive].read_volinfo))
+ {
+ if (DRIVE_ReadSuperblock(drive,(char *) buff))
+ ERR("Invalid or unreadable superblock on %s (%c:).\n",
+ DOSDrives[drive].device, (char)(drive+'A'));
+ else {
+ if (DOSDrives[drive].type == TYPE_CDROM)
+ offs = 40;
+ else
+ if (DOSDrives[drive].type == TYPE_FLOPPY ||
+ DOSDrives[drive].type == TYPE_HD)
+ offs = 0x2b;
+
+ /* FIXME: ISO9660 uses 32-bytes long label. Should we do also? */
+ if (offs != -1) memcpy(DOSDrives[drive].label_read,buff+offs,11);
+ DOSDrives[drive].label_read[11]='\0';
+ read = 1;
+ }
+ }
+
+ return (read) ?
+ DOSDrives[drive].label_read : DOSDrives[drive].label_conf;
}
/***********************************************************************
* DRIVE_GetSerialNumber
+ *
+ * FIXME: apparently Win 9x (not DOS !) gives serial numbers to CD-ROMs, too.
+ * How to calculate them ?
*/
DWORD DRIVE_GetSerialNumber( int drive )
{
+char buff[DRIVE_SUPER];
+
if (!DRIVE_IsValid( drive )) return 0;
- return DOSDrives[drive].serial;
+ if ( (DOSDrives[drive].read_volinfo) &&
+ ((DOSDrives[drive].type == TYPE_FLOPPY) ||
+ (DOSDrives[drive].type == TYPE_HD)))
+ {
+ if (DRIVE_ReadSuperblock(drive,(char *) buff))
+
+ MESSAGE("Invalid or unreadable superblock on %s (%c:)."
+ " Maybe not FAT?\n" ,DOSDrives[drive].device,(char)(drive+'A'));
+ else
+ return *((DWORD*)(buff+0x27));
+ }
+ return DOSDrives[drive].serial_conf;
}
@@ -421,7 +575,10 @@
int DRIVE_SetSerialNumber( int drive, DWORD serial )
{
if (!DRIVE_IsValid( drive )) return 0;
- DOSDrives[drive].serial = serial;
+ if ((DOSDrives[drive].read_volinfo) &&
+ (DOSDrives[drive].type != TYPE_CDROM))
+ FIXME("Setting the serial number is useless for drive %c: until writing it is properly implemented, as this drive reads it from the device.\n", 'A'+drive);
+ DOSDrives[drive].serial_conf = serial;
return 1;
}
@@ -556,8 +713,8 @@
new->root = HEAP_strdupA( SystemHeap, 0, old->root );
new->dos_cwd = HEAP_strdupA( SystemHeap, 0, old->dos_cwd );
new->unix_cwd = HEAP_strdupA( SystemHeap, 0, old->unix_cwd );
- memcpy ( new->label, old->label, 12 );
- new->serial = old->serial;
+ memcpy ( new->label_conf, old->label_conf, 12 );
+ new->serial_conf = old->serial_conf;
new->type = old->type;
new->flags = old->flags;
new->dev = old->dev;
@@ -922,7 +1079,7 @@
/***********************************************************************
* GetDriveType16 (KERNEL.136)
- * This functions returns the drivetype of a drive in Win16.
+ * This function returns the type of a drive in Win16.
* Note that it returns DRIVE_REMOTE for CD-ROMs, since MSCDEX uses the
* remote drive API. The returnvalue DRIVE_REMOTE for CD-ROMs has been
* verified on Win3.11 and Windows 95. Some programs rely on it, so don't
@@ -972,7 +1129,7 @@
*
* Currently returns DRIVE_DOESNOTEXIST and DRIVE_CANNOTDETERMINE
* when it really should return DRIVE_NO_ROOT_DIR and DRIVE_UNKNOWN.
- * Why where the former defines used?
+ * Why were the former defines used?
*
* DRIVE_RAMDISK is unsupported.
*/
@@ -1173,7 +1330,11 @@
int drive;
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
- if (DRIVE_IsValid(drive)) ret |= (1 << drive);
+ {
+ if ( (DRIVE_IsValid(drive)) ||
+ (DOSDrives[drive].type == TYPE_CDROM)) /* audio CD is also valid */
+ ret |= (1 << drive);
+ }
return ret;
}
@@ -1189,7 +1350,7 @@
int drive;
char *cp;
- /* FIXME, SetLastErrors missing */
+ /* FIXME, SetLastError()s missing */
if (!root) drive = DRIVE_GetCurrentDrive();
else
@@ -1212,7 +1373,7 @@
if (serial) *serial = DRIVE_GetSerialNumber(drive);
/* Set the filesystem information */
- /* Note: we only emulate a FAT fs at the present */
+ /* Note: we only emulate a FAT fs at present */
if (filename_len) {
if (DOSDrives[drive].flags & DRIVE_SHORT_NAMES)
diff --git a/include/cdrom.h b/include/cdrom.h
index 660325c..18bdd73 100644
--- a/include/cdrom.h
+++ b/include/cdrom.h
@@ -54,7 +54,8 @@
#define WINE_CDA_STOP 0x04
#define WINE_CDA_PAUSE 0x05
-int CDAUDIO_Open(WINE_CDAUDIO* wcda);
+int CDAUDIO_Open(WINE_CDAUDIO* wcda, int drive);
+int CDAUDIO_GetMediaType(WINE_CDAUDIO* wcda);
int CDAUDIO_Close(WINE_CDAUDIO* wcda);
int CDAUDIO_Reset(WINE_CDAUDIO* wcda);
int CDAUDIO_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop);
@@ -74,5 +75,9 @@
#define CDROM_DATA_TRACK 0x04
#endif
+/* values borrowed from Linux 2.2.x cdrom.h */
+#define CDS_NO_INFO 0
+#define CDS_AUDIO 100
+
#endif
diff --git a/include/debugdefs.h b/include/debugdefs.h
index dd649e4..4ee0ba6 100644
--- a/include/debugdefs.h
+++ b/include/debugdefs.h
@@ -128,48 +128,49 @@
const int dbch_selector = 117;
const int dbch_sendmsg = 118;
const int dbch_server = 119;
-const int dbch_shell = 120;
-const int dbch_snoop = 121;
-const int dbch_sound = 122;
-const int dbch_static = 123;
-const int dbch_statusbar = 124;
-const int dbch_storage = 125;
-const int dbch_stress = 126;
-const int dbch_string = 127;
-const int dbch_syscolor = 128;
-const int dbch_system = 129;
-const int dbch_tab = 130;
-const int dbch_tape = 131;
-const int dbch_tapi = 132;
-const int dbch_task = 133;
-const int dbch_text = 134;
-const int dbch_thread = 135;
-const int dbch_thunk = 136;
-const int dbch_timer = 137;
-const int dbch_toolbar = 138;
-const int dbch_toolhelp = 139;
-const int dbch_tooltips = 140;
-const int dbch_trackbar = 141;
-const int dbch_treeview = 142;
-const int dbch_ttydrv = 143;
-const int dbch_tweak = 144;
-const int dbch_typelib = 145;
-const int dbch_updown = 146;
-const int dbch_ver = 147;
-const int dbch_virtual = 148;
-const int dbch_vxd = 149;
-const int dbch_wave = 150;
-const int dbch_win = 151;
-const int dbch_win16drv = 152;
-const int dbch_win32 = 153;
-const int dbch_wing = 154;
-const int dbch_winsock = 155;
-const int dbch_winspool = 156;
-const int dbch_wnet = 157;
-const int dbch_x11 = 158;
-const int dbch_x11drv = 159;
+const int dbch_setupx = 120;
+const int dbch_shell = 121;
+const int dbch_snoop = 122;
+const int dbch_sound = 123;
+const int dbch_static = 124;
+const int dbch_statusbar = 125;
+const int dbch_storage = 126;
+const int dbch_stress = 127;
+const int dbch_string = 128;
+const int dbch_syscolor = 129;
+const int dbch_system = 130;
+const int dbch_tab = 131;
+const int dbch_tape = 132;
+const int dbch_tapi = 133;
+const int dbch_task = 134;
+const int dbch_text = 135;
+const int dbch_thread = 136;
+const int dbch_thunk = 137;
+const int dbch_timer = 138;
+const int dbch_toolbar = 139;
+const int dbch_toolhelp = 140;
+const int dbch_tooltips = 141;
+const int dbch_trackbar = 142;
+const int dbch_treeview = 143;
+const int dbch_ttydrv = 144;
+const int dbch_tweak = 145;
+const int dbch_typelib = 146;
+const int dbch_updown = 147;
+const int dbch_ver = 148;
+const int dbch_virtual = 149;
+const int dbch_vxd = 150;
+const int dbch_wave = 151;
+const int dbch_win = 152;
+const int dbch_win16drv = 153;
+const int dbch_win32 = 154;
+const int dbch_wing = 155;
+const int dbch_winsock = 156;
+const int dbch_winspool = 157;
+const int dbch_wnet = 158;
+const int dbch_x11 = 159;
+const int dbch_x11drv = 160;
-#define DEBUG_CHANNEL_COUNT 160
+#define DEBUG_CHANNEL_COUNT 161
char __debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = {
{1, 1, 0, 0},
@@ -331,6 +332,7 @@
{1, 1, 0, 0},
{1, 1, 0, 0},
{1, 1, 0, 0},
+{1, 1, 0, 0},
{1, 1, 0, 0}
};
@@ -455,6 +457,7 @@
"selector",
"sendmsg",
"server",
+"setupx",
"shell",
"snoop",
"sound",
diff --git a/include/drive.h b/include/drive.h
index 891ae7e..9328af8 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -35,6 +35,7 @@
extern const char * DRIVE_GetRoot( int drive );
extern const char * DRIVE_GetDosCwd( int drive );
extern const char * DRIVE_GetUnixCwd( int drive );
+extern const char * DRIVE_GetDevice( int drive );
extern const char * DRIVE_GetLabel( int drive );
extern DWORD DRIVE_GetSerialNumber( int drive );
extern int DRIVE_SetSerialNumber( int drive, DWORD serial );
diff --git a/libtest/volinfo.c b/libtest/volinfo.c
index 7b64afc..26d112a 100644
--- a/libtest/volinfo.c
+++ b/libtest/volinfo.c
@@ -13,7 +13,7 @@
printf("Drive Serial Flags Filename-Length "
"Label Fsname\n");
- for (drive = 'C'; drive <= 'Z'; drive++)
+ for (drive = 'A'; drive <= 'Z'; drive++)
{
root[0] = drive;
if (GetVolumeInformation(root,label,labellen,&serial,
diff --git a/misc/cdrom.c b/misc/cdrom.c
index 098737c..d2c6e0d 100644
--- a/misc/cdrom.c
+++ b/misc/cdrom.c
@@ -11,29 +11,53 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include "cdrom.h"
+#include "drive.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(cdaudio)
-#if defined(__NetBSD__)
-# define CDAUDIO_DEV "/dev/rcd0d"
-#elif defined(__FreeBSD__)
-# define CDAUDIO_DEV "/dev/rcd0c"
-#else
-# define CDAUDIO_DEV "/dev/cdrom"
-#endif
-
#define MAX_CDAUDIO_TRACKS 256
/**************************************************************************
* CDAUDIO_Open [internal]
+ *
+ * drive = 0, 1, ...
+ * or -1 (figure it out)
*/
-int CDAUDIO_Open(WINE_CDAUDIO* wcda)
+int CDAUDIO_Open(WINE_CDAUDIO* wcda, int drive)
{
-#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
- wcda->unixdev = open(CDAUDIO_DEV, O_RDONLY | O_NONBLOCK, 0);
+ int i;
+ BOOL avail = FALSE;
+ const char *dev;
+
+ if (drive == -1)
+ {
+ for (i=0; i < MAX_DOS_DRIVES; i++)
+ if (DRIVE_GetType(i) == TYPE_CDROM)
+ {
+ drive = i;
+ avail = TRUE;
+ break;
+ }
+ }
+ else
+ avail = TRUE;
+
+ if (avail == FALSE)
+ {
+ WARN("No CD-ROM #%d found !\n", drive);
+ return -1;
+ }
+ if ((dev = DRIVE_GetDevice(drive)) == NULL)
+{
+ WARN("No device entry for CD-ROM #%d (drive %c:) found !\n",
+ drive, 'A' + drive);
+ return -1;
+ }
+
+ wcda->unixdev = open(dev, O_RDONLY | O_NONBLOCK, 0);
if (wcda->unixdev == -1) {
- WARN("can't open '%s'!. errno=%d\n", CDAUDIO_DEV, errno);
+ WARN("can't open '%s'!. errno=%d\n", dev, errno);
return -1;
}
wcda->cdaMode = WINE_CDA_OPEN; /* to force reading tracks info */
@@ -45,8 +69,16 @@
wcda->lpdwTrackPos = NULL;
wcda->lpbTrackFlags = NULL;
return 0;
+}
+
+/**************************************************************************
+ * CDAUDIO_GetMediaType [internal]
+ */
+int CDAUDIO_GetMediaType(WINE_CDAUDIO* wcda)
+{
+#ifdef linux
+ return ioctl(wcda->unixdev, CDROM_DISC_STATUS);
#else
- wcda->unixdev = -1;
return -1;
#endif
}
diff --git a/msdos/int2f.c b/msdos/int2f.c
index 517185f5..e66cf1a 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -490,7 +490,7 @@
TRACE("Get drive letters\n");
break;
- case 0x10: /* direct driver acces */
+ case 0x10: /* direct driver access */
{
static WINE_CDAUDIO wcda;
BYTE* driver_request;
@@ -511,12 +511,12 @@
driver_request[3] = 5; /* bad request length */
return;
}
- /* FIXME - would be better to open the device at the begining of the wine session...
+ /* FIXME - would be better to open the device at the beginning of the wine session...
* - the device is also never closed...
* - the current implementation only supports a single CD ROM
*/
if (wcda.unixdev <= 0)
- CDAUDIO_Open(&wcda);
+ CDAUDIO_Open(&wcda, -1);
TRACE("CDROM device driver -> command <%d>\n", (unsigned char)driver_request[2]);
for (drive = 0;
diff --git a/wine.ini b/wine.ini
index efad4d8..268fcc1 100644
--- a/wine.ini
+++ b/wine.ini
@@ -34,6 +34,8 @@
Type=cdrom
Label=CD-Rom
Filesystem=win95
+; make sure that device is correct and has proper permissions !
+Device=/dev/cdrom
[Drive E]
Path=/tmp