From 1fe93345c4d95733f69062b0a2a626f2a8d02ea2 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Sat, 29 Jan 2000 21:11:47 +0000 Subject: [PATCH] - 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 --- dlls/winmm/mcicda/mcicda.c | 2 +- documentation/cdrom-labels | 102 ++++++++++--------- files/drive.c | 203 +++++++++++++++++++++++++++++++++---- include/cdrom.h | 7 +- include/debugdefs.h | 85 ++++++++-------- include/drive.h | 1 + libtest/volinfo.c | 2 +- misc/cdrom.c | 58 ++++++++--- msdos/int2f.c | 6 +- wine.ini | 2 + 10 files changed, 341 insertions(+), 127 deletions(-) diff --git a/dlls/winmm/mcicda/mcicda.c b/dlls/winmm/mcicda/mcicda.c index 9a87d187004..77451c34c6a 100644 --- a/dlls/winmm/mcicda/mcicda.c +++ b/dlls/winmm/mcicda/mcicda.c @@ -242,7 +242,7 @@ static DWORD CDAUDIO_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpe } 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 a2f2bca8f71..ce3bc7c81f7 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= 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= + * 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 -#include +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 + +Nov 14 1999 Jan 25 2000 diff --git a/files/drive.c b/files/drive.c index 7363c2f7333..865439f020f 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 + * (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 @@ typedef struct 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 @@ static DRIVETYPE DRIVE_GetDriveType( const char *name ) { 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 @@ int DRIVE_Init(void) 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 @@ int DRIVE_Init(void) 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 @@ int DRIVE_Init(void) 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 @@ int DRIVE_Init(void) 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; @@ -395,23 +410,162 @@ const char * DRIVE_GetUnixCwd( int drive ) } +/*********************************************************************** + * 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 @@ DWORD DRIVE_GetSerialNumber( int drive ) 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 @@ int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive ) 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 @@ BOOL WINAPI GetDiskFreeSpaceExW( LPCWSTR root, PULARGE_INTEGER avail, /*********************************************************************** * 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 @@ UINT16 WINAPI GetDriveType16( * * 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 @@ DWORD WINAPI GetLogicalDrives(void) 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 @@ BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label, int drive; char *cp; - /* FIXME, SetLastErrors missing */ + /* FIXME, SetLastError()s missing */ if (!root) drive = DRIVE_GetCurrentDrive(); else @@ -1212,7 +1373,7 @@ BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label, 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 660325ce5d8..18bdd7316eb 100644 --- a/include/cdrom.h +++ b/include/cdrom.h @@ -54,7 +54,8 @@ typedef struct { #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 @@ BOOL CDAUDIO_GetCDStatus(WINE_CDAUDIO* wcda); #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 dd649e449d4..4ee0ba68bd9 100644 --- a/include/debugdefs.h +++ b/include/debugdefs.h @@ -128,48 +128,49 @@ const int dbch_seh = 116; 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 @@ char __debug_msg_enabled[DEBUG_CHANNEL_COUNT][DEBUG_CLASS_COUNT] = { {1, 1, 0, 0}, {1, 1, 0, 0}, {1, 1, 0, 0}, +{1, 1, 0, 0}, {1, 1, 0, 0} }; @@ -455,6 +457,7 @@ const char * const debug_ch_name[DEBUG_CHANNEL_COUNT] = { "selector", "sendmsg", "server", +"setupx", "shell", "snoop", "sound", diff --git a/include/drive.h b/include/drive.h index 891ae7e9c9b..9328af8c85b 100644 --- a/include/drive.h +++ b/include/drive.h @@ -35,6 +35,7 @@ extern int DRIVE_FindDriveRoot( const char **path ); 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 7b64afcf6ef..26d112a2f1e 100644 --- a/libtest/volinfo.c +++ b/libtest/volinfo.c @@ -13,7 +13,7 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 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 098737c56cb..d2c6e0d1192 100644 --- a/misc/cdrom.c +++ b/misc/cdrom.c @@ -11,29 +11,53 @@ #include #include #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 @@ int CDAUDIO_Open(WINE_CDAUDIO* wcda) 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 517185f511c..e66cf1ac0e3 100644 --- a/msdos/int2f.c +++ b/msdos/int2f.c @@ -490,7 +490,7 @@ static void MSCDEX_Handler(CONTEXT86* context) 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 @@ static void MSCDEX_Handler(CONTEXT86* context) 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 efad4d80542..268fcc1f43c 100644 --- a/wine.ini +++ b/wine.ini @@ -34,6 +34,8 @@ Path=/cdrom Type=cdrom Label=CD-Rom Filesystem=win95 +; make sure that device is correct and has proper permissions ! +Device=/dev/cdrom [Drive E] Path=/tmp