- fixed a gross bug in SetCurrentDirectoryA (where changing to a new
non-existent directory would leave the new drive enabled upon aborting (fixes CuteFTP install and should fix MANY apps) This has probably been caused by myself. *brownpaperbag* - added GetVolumeInformation serial number bug-for-bug compatibility - corrected Unicode labels (better CD-ROM handling in general) - moved CD-ROM label detection code to misc/cdrom.c - possible to use loopback mounted ISO9660 files - init some uninitialised drive fields - remove some unnecessary header includes
This commit is contained in:
parent
f2355e0f15
commit
3084b58606
|
@ -239,6 +239,7 @@ int DRIVE_Init(void)
|
|||
strcpy( DOSDrives[2].label_conf, "Drive C " );
|
||||
DOSDrives[2].serial_conf = 12345678;
|
||||
DOSDrives[2].type = TYPE_HD;
|
||||
DOSDrives[2].device = NULL;
|
||||
DOSDrives[2].flags = 0;
|
||||
DRIVE_CurDrive = 2;
|
||||
}
|
||||
|
@ -456,9 +457,7 @@ int DRIVE_ReadSuperblock (int drive, char * buff)
|
|||
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);
|
||||
offs = CDROM_Data_FindBestVoldesc(fd);
|
||||
break;
|
||||
default:
|
||||
offs = 0;
|
||||
|
@ -473,7 +472,7 @@ int DRIVE_ReadSuperblock (int drive, char * buff)
|
|||
case TYPE_FLOPPY:
|
||||
case TYPE_HD:
|
||||
if ((buff[0x26]!=0x29) || /* Check for FAT present */
|
||||
/* FIXME: do really all Fat have their name beginning with
|
||||
/* FIXME: do really all FAT have their name beginning with
|
||||
"FAT" ? (At least FAT12, FAT16 and FAT32 have :) */
|
||||
memcmp( buff+0x36,"FAT",3))
|
||||
{
|
||||
|
@ -544,41 +543,20 @@ const char * DRIVE_GetLabel( int drive )
|
|||
if (!DRIVE_IsValid( drive )) return NULL;
|
||||
if (DRIVE_GetType(drive) == TYPE_CDROM)
|
||||
{
|
||||
WINE_CDAUDIO wcda;
|
||||
|
||||
if (!(CDROM_Open(&wcda, drive)))
|
||||
{
|
||||
int media = CDROM_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;
|
||||
}
|
||||
|
||||
CDROM_Close(&wcda);
|
||||
}
|
||||
read = CDROM_GetLabel(drive, DOSDrives[drive].label_read);
|
||||
}
|
||||
if ((!read) && (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO))
|
||||
else
|
||||
if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
|
||||
{
|
||||
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? */
|
||||
/* FIXME: ISO9660 uses a 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;
|
||||
|
@ -683,7 +661,7 @@ int DRIVE_Chdir( int drive, const char *path )
|
|||
|
||||
strcpy( buffer, "A:" );
|
||||
buffer[0] += drive;
|
||||
TRACE("(%c:,%s)\n", buffer[0], path );
|
||||
TRACE("(%s,%s)\n", buffer, path );
|
||||
lstrcpynA( buffer + 2, path, sizeof(buffer) - 2 );
|
||||
|
||||
if (!DOSFS_GetFullName( buffer, TRUE, &full_name )) return 0;
|
||||
|
@ -769,8 +747,8 @@ int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
|
|||
|
||||
if ( new->root )
|
||||
{
|
||||
TRACE("Can\'t map drive %c to drive %c - drive %c already exists\n",
|
||||
'A' + existing_drive, 'A' + new_drive, 'A' + new_drive );
|
||||
TRACE("Can't map drive %c: to already existing drive %c:\n",
|
||||
'A' + existing_drive, 'A' + new_drive );
|
||||
/* it is already mapped there, so return success */
|
||||
if (!strcmp(old->root,new->root))
|
||||
return 1;
|
||||
|
@ -780,14 +758,16 @@ int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
|
|||
new->root = HEAP_strdupA( GetProcessHeap(), 0, old->root );
|
||||
new->dos_cwd = HEAP_strdupA( GetProcessHeap(), 0, old->dos_cwd );
|
||||
new->unix_cwd = HEAP_strdupA( GetProcessHeap(), 0, old->unix_cwd );
|
||||
new->device = HEAP_strdupA( GetProcessHeap(), 0, old->device );
|
||||
memcpy ( new->label_conf, old->label_conf, 12 );
|
||||
memcpy ( new->label_read, old->label_read, 12 );
|
||||
new->serial_conf = old->serial_conf;
|
||||
new->type = old->type;
|
||||
new->flags = old->flags;
|
||||
new->dev = old->dev;
|
||||
new->ino = old->ino;
|
||||
|
||||
TRACE("Drive %c is now equal to drive %c\n",
|
||||
TRACE("Drive %c: is now equal to drive %c:\n",
|
||||
'A' + new_drive, 'A' + existing_drive );
|
||||
|
||||
return 1;
|
||||
|
@ -825,15 +805,15 @@ int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fa
|
|||
else
|
||||
{
|
||||
memset(dataptr, 0, nr_sect * 512);
|
||||
if (fake_success)
|
||||
if (fake_success)
|
||||
{
|
||||
if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8;
|
||||
if (begin == 1) *dataptr = 0xf8;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8;
|
||||
if (begin == 1) *dataptr = 0xf8;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -844,7 +824,7 @@ int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fa
|
|||
*/
|
||||
int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success)
|
||||
{
|
||||
int fd;
|
||||
int fd;
|
||||
|
||||
if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
|
||||
{
|
||||
|
@ -854,10 +834,10 @@ int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL f
|
|||
close( fd );
|
||||
}
|
||||
else
|
||||
if (!(fake_success))
|
||||
return 0;
|
||||
if (!(fake_success))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1093,13 +1073,13 @@ BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root,
|
|||
if (total)
|
||||
{
|
||||
total->s.HighPart = size.s.HighPart;
|
||||
total->s.LowPart = size.s.LowPart ;
|
||||
total->s.LowPart = size.s.LowPart;
|
||||
}
|
||||
|
||||
if (totalfree)
|
||||
{
|
||||
totalfree->s.HighPart = available.s.HighPart;
|
||||
totalfree->s.LowPart = available.s.LowPart ;
|
||||
totalfree->s.LowPart = available.s.LowPart;
|
||||
}
|
||||
|
||||
if (avail)
|
||||
|
@ -1124,7 +1104,7 @@ BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root,
|
|||
/* Quick hack, should eventually be fixed to work 100% with
|
||||
Windows2000 (see comment above). */
|
||||
avail->s.HighPart = available.s.HighPart;
|
||||
avail->s.LowPart = available.s.LowPart ;
|
||||
avail->s.LowPart = available.s.LowPart;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
@ -1176,7 +1156,7 @@ UINT16 WINAPI GetDriveType16(
|
|||
/***********************************************************************
|
||||
* GetDriveTypeA (KERNEL32.208)
|
||||
*
|
||||
* Returns the type of the disk drive specified. If root is NULL the
|
||||
* Returns the type of the disk drive specified. If root is NULL the
|
||||
* root of the current directory is used.
|
||||
*
|
||||
* RETURNS
|
||||
|
@ -1184,15 +1164,15 @@ UINT16 WINAPI GetDriveType16(
|
|||
* Type of drive (from Win32 SDK):
|
||||
*
|
||||
* DRIVE_UNKNOWN unable to find out anything about the drive
|
||||
* DRIVE_NO_ROOT_DIR nonexistand root dir
|
||||
* DRIVE_NO_ROOT_DIR nonexistent root dir
|
||||
* DRIVE_REMOVABLE the disk can be removed from the machine
|
||||
* DRIVE_FIXED the disk can not be removed from the machine
|
||||
* DRIVE_REMOTE network disk
|
||||
* DRIVE_CDROM CDROM drive
|
||||
* DRIVE_RAMDISK virtual disk in ram
|
||||
* DRIVE_RAMDISK virtual disk in RAM
|
||||
*
|
||||
* DRIVE_DOESNOTEXIST XXX Not valid return value
|
||||
* DRIVE_CANNOTDETERMINE XXX Not valid return value
|
||||
* DRIVE_DOESNOTEXIST FIXME Not valid return value
|
||||
* DRIVE_CANNOTDETERMINE FIXME Not valid return value
|
||||
*
|
||||
* BUGS
|
||||
*
|
||||
|
@ -1297,7 +1277,7 @@ BOOL16 WINAPI SetCurrentDirectory16( LPCSTR dir )
|
|||
*/
|
||||
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
|
||||
{
|
||||
int olddrive, drive = DRIVE_GetCurrentDrive();
|
||||
int drive, olddrive = DRIVE_GetCurrentDrive();
|
||||
|
||||
if (!dir) {
|
||||
ERR_(file)("(NULL)!\n");
|
||||
|
@ -1305,13 +1285,14 @@ BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
|
|||
}
|
||||
if (dir[0] && (dir[1]==':'))
|
||||
{
|
||||
drive = tolower( *dir ) - 'a';
|
||||
drive = toupper( *dir ) - 'A';
|
||||
dir += 2;
|
||||
}
|
||||
else
|
||||
drive = olddrive;
|
||||
|
||||
/* WARNING: we need to set the drive before the dir, as DRIVE_Chdir
|
||||
sets pTask->curdir only if pTask->curdrive is drive */
|
||||
olddrive = drive; /* in case DRIVE_Chdir fails */
|
||||
if (!(DRIVE_SetCurrentDrive( drive )))
|
||||
return FALSE;
|
||||
/* FIXME: what about empty strings? Add a \\ ? */
|
||||
|
@ -1356,10 +1337,10 @@ UINT WINAPI GetLogicalDriveStringsA( UINT len, LPSTR buffer )
|
|||
*p++ = '\0';
|
||||
}
|
||||
*p = '\0';
|
||||
return count * 4;
|
||||
return count * 4;
|
||||
}
|
||||
else
|
||||
return (count * 4) + 1;/* account for terminating null */
|
||||
return (count * 4) + 1; /* account for terminating null */
|
||||
/* The API tells about these different return values */
|
||||
}
|
||||
|
||||
|
|
|
@ -67,9 +67,11 @@ int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open);
|
|||
UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda);
|
||||
BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda);
|
||||
BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda);
|
||||
WORD CDROM_Data_FindBestVoldesc(int fd);
|
||||
DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda);
|
||||
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda);
|
||||
DWORD CDROM_GetSerial(int drive);
|
||||
DWORD CDROM_GetLabel(int drive, char *label);
|
||||
|
||||
#define CDFRAMES_PERSEC 75
|
||||
#define SECONDS_PERMIN 60
|
||||
|
|
132
misc/cdrom.c
132
misc/cdrom.c
|
@ -16,6 +16,7 @@
|
|||
#include "cdrom.h"
|
||||
#include "drive.h"
|
||||
#include "debugtools.h"
|
||||
#include "winbase.h"
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(cdrom);
|
||||
|
||||
|
@ -205,7 +206,7 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda)
|
|||
entry.cdte_track = CDROM_LEADOUT;
|
||||
#else
|
||||
#define LEADOUT 0xaa
|
||||
entry.starting_track = LEADOUT; /* XXX */
|
||||
entry.starting_track = LEADOUT; /* FIXME */
|
||||
#endif
|
||||
else
|
||||
#ifdef linux
|
||||
|
@ -553,7 +554,7 @@ int CDROM_Reset(WINE_CDAUDIO* wcda)
|
|||
#endif
|
||||
}
|
||||
|
||||
unsigned int get_offs_best_voldesc(int fd)
|
||||
WORD CDROM_Data_FindBestVoldesc(int fd)
|
||||
{
|
||||
BYTE cur_vd_type, max_vd_type = 0;
|
||||
unsigned int offs, best_offs = 0;
|
||||
|
@ -562,7 +563,7 @@ unsigned int get_offs_best_voldesc(int fd)
|
|||
{
|
||||
lseek(fd, offs, SEEK_SET);
|
||||
read(fd, &cur_vd_type, 1);
|
||||
if (cur_vd_type == 0xff)
|
||||
if (cur_vd_type == 0xff) /* voldesc set terminator */
|
||||
break;
|
||||
if (cur_vd_type > max_vd_type)
|
||||
{
|
||||
|
@ -602,27 +603,41 @@ DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda)
|
|||
*/
|
||||
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda)
|
||||
{
|
||||
unsigned int offs = get_offs_best_voldesc(wcda->unixdev);
|
||||
WORD offs = CDROM_Data_FindBestVoldesc(wcda->unixdev);
|
||||
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(wcda->unixdev,offs,SEEK_SET);
|
||||
read(wcda->unixdev,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[0] += buf[i+0];
|
||||
serial.p[1] += buf[i+1];
|
||||
serial.p[2] += buf[i+2];
|
||||
serial.p[3] += buf[i+3];
|
||||
serial.p[b0] += buf[i+b0];
|
||||
serial.p[b1] += buf[i+b1];
|
||||
serial.p[b2] += buf[i+b2];
|
||||
serial.p[b3] += buf[i+b3];
|
||||
}
|
||||
}
|
||||
return serial.val;
|
||||
|
@ -655,9 +670,13 @@ DWORD CDROM_GetSerial(int drive)
|
|||
serial = CDROM_Audio_GetSerial(&wcda);
|
||||
}
|
||||
else
|
||||
if (media > CDS_AUDIO)
|
||||
if ((media > CDS_AUDIO)
|
||||
|| (media == -1) /* ioctl() error: ISO9660 image file given ? */
|
||||
)
|
||||
/* hopefully a data CD */
|
||||
serial = CDROM_Data_GetSerial(&wcda);
|
||||
else
|
||||
WARN("Strange CD type (%d) or empty ?\n", media);
|
||||
|
||||
p = (media == CDS_AUDIO) ? "Audio " :
|
||||
(media > CDS_AUDIO) ? "Data " : "";
|
||||
|
@ -671,3 +690,96 @@ DWORD CDROM_GetSerial(int drive)
|
|||
return serial;
|
||||
}
|
||||
|
||||
static const char empty_label[] = " ";
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_Data_GetLabel [internal]
|
||||
*/
|
||||
DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label)
|
||||
{
|
||||
#define LABEL_LEN 32+1
|
||||
WORD offs = CDROM_Data_FindBestVoldesc(wcda->unixdev);
|
||||
WCHAR label_read[LABEL_LEN]; /* Unicode possible, too */
|
||||
DWORD unicode_id = 0;
|
||||
|
||||
if (offs)
|
||||
{
|
||||
if ((lseek(wcda->unixdev, offs+0x58, SEEK_SET) == offs+0x58)
|
||||
&& (read(wcda->unixdev, &unicode_id, 3) == 3))
|
||||
{
|
||||
int ver = (unicode_id & 0xff0000) >> 16;
|
||||
|
||||
if ((lseek(wcda->unixdev, offs+0x28, SEEK_SET) != offs+0x28)
|
||||
|| (read(wcda->unixdev, &label_read, LABEL_LEN) != LABEL_LEN))
|
||||
goto failure;
|
||||
|
||||
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);
|
||||
}
|
||||
lstrcpynWtoA(label, label_read, 11);
|
||||
}
|
||||
else
|
||||
{
|
||||
strncpy(label, (LPSTR)label_read, 11);
|
||||
label[11] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
failure:
|
||||
ERR("error reading label !\n");
|
||||
strcpy(label, empty_label);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* CDROM_GetLabel [internal]
|
||||
*/
|
||||
DWORD CDROM_GetLabel(int drive, char *label)
|
||||
{
|
||||
WINE_CDAUDIO wcda;
|
||||
DWORD res = 1;
|
||||
|
||||
if (!(CDROM_Open(&wcda, drive)))
|
||||
{
|
||||
int media = CDROM_GetMediaType(&wcda);
|
||||
LPSTR p;
|
||||
|
||||
if (media == CDS_AUDIO)
|
||||
{
|
||||
strcpy(label, "Audio CD ");
|
||||
}
|
||||
else
|
||||
if (media == CDS_NO_INFO)
|
||||
{
|
||||
strcpy(label, empty_label);
|
||||
}
|
||||
else
|
||||
if ((media > CDS_AUDIO)
|
||||
|| (media == -1) /* ioctl() error: ISO9660 image file given ? */
|
||||
)
|
||||
/* hopefully a data CD */
|
||||
CDROM_Data_GetLabel(&wcda, label);
|
||||
else
|
||||
{
|
||||
WARN("Strange CD type (%d) or empty ?\n", media);
|
||||
strcpy(label, empty_label);
|
||||
res = 0;
|
||||
}
|
||||
|
||||
p = (media == CDS_AUDIO) ? "Audio " :
|
||||
(media > CDS_AUDIO) ? "Data " : "";
|
||||
TRACE("%sCD label is '%s'.\n",
|
||||
p, label);
|
||||
CDROM_Close(&wcda);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,19 +9,11 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "wine/winbase16.h"
|
||||
#include "ldt.h"
|
||||
#include "drive.h"
|
||||
#include "msdos.h"
|
||||
#include "miscemu.h"
|
||||
#include "module.h"
|
||||
#include "task.h"
|
||||
#include "dosexe.h"
|
||||
#include "heap.h"
|
||||
/* #define DEBUG_INT */
|
||||
#include "debugtools.h"
|
||||
#include "cdrom.h"
|
||||
|
@ -582,7 +574,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
|
|||
MSCDEX_StoreMSF(wcda.dwCurFrame, io_stru + 2);
|
||||
break;
|
||||
default:
|
||||
ERR("CDRom-Driver: Unsupported addressing mode !!\n");
|
||||
ERR("CD-ROM driver: unsupported addressing mode !!\n");
|
||||
Error = 0x0c;
|
||||
}
|
||||
TRACE(" ----> HEAD LOCATION <%ld>\n", PTR_AT(io_stru, 2, DWORD));
|
||||
|
|
Loading…
Reference in New Issue