/*
 * DOS drives handling functions
 *
 * 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)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/port.h"

#include <assert.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#ifdef STATFS_DEFINED_BY_SYS_VFS
# include <sys/vfs.h>
#else
# ifdef STATFS_DEFINED_BY_SYS_MOUNT
#  include <sys/mount.h>
# else
#  ifdef STATFS_DEFINED_BY_SYS_STATFS
#   include <sys/statfs.h>
#  endif
# endif
#endif

#include "winbase.h"
#include "ntddk.h"
#include "wine/winbase16.h"   /* for GetCurrentTask */
#include "winerror.h"
#include "winioctl.h"
#include "ntddstor.h"
#include "ntddcdrm.h"
#include "drive.h"
#include "file.h"
#include "heap.h"
#include "msdos.h"
#include "task.h"
#include "wine/library.h"
#include "wine/server.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dosfs);
WINE_DECLARE_DEBUG_CHANNEL(file);

typedef struct
{
    char     *root;      /* root dir in Unix format without trailing / */
    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_conf[12]; /* drive label as cfg'd in wine config */
    char      label_read[12]; /* drive label as read from device */
    DWORD     serial_conf;    /* drive serial number as cfg'd in wine config */
    UINT      type;      /* drive type */
    UINT      flags;     /* drive flags */
    dev_t     dev;       /* unix device number */
    ino_t     ino;       /* unix inode number */
} DOSDRIVE;


static const char * const DRIVE_Types[] =
{
    "",         /* DRIVE_UNKNOWN */
    "",         /* DRIVE_NO_ROOT_DIR */
    "floppy",   /* DRIVE_REMOVABLE */
    "hd",       /* DRIVE_FIXED */
    "network",  /* DRIVE_REMOTE */
    "cdrom",    /* DRIVE_CDROM */
    "ramdisk"   /* DRIVE_RAMDISK */
};


/* Known filesystem types */

typedef struct
{
    const char *name;
    UINT      flags;
} FS_DESCR;

static const FS_DESCR DRIVE_Filesystems[] =
{
    { "unix",   DRIVE_CASE_SENSITIVE | DRIVE_CASE_PRESERVING },
    { "msdos",  DRIVE_SHORT_NAMES },
    { "dos",    DRIVE_SHORT_NAMES },
    { "fat",    DRIVE_SHORT_NAMES },
    { "vfat",   DRIVE_CASE_PRESERVING },
    { "win95",  DRIVE_CASE_PRESERVING },
    { NULL, 0 }
};


static DOSDRIVE DOSDrives[MAX_DOS_DRIVES];
static int DRIVE_CurDrive = -1;

static HTASK16 DRIVE_LastTask = 0;

/* strdup on the process heap */
inline static char *heap_strdup( const char *str )
{
    INT len = strlen(str) + 1;
    LPSTR p = HeapAlloc( GetProcessHeap(), 0, len );
    if (p) memcpy( p, str, len );
    return p;
}

extern void CDROM_InitRegistry(int dev);

/***********************************************************************
 *           DRIVE_GetDriveType
 */
static UINT DRIVE_GetDriveType( const char *name )
{
    char buffer[20];
    int i;

    PROFILE_GetWineIniString( name, "Type", "hd", buffer, sizeof(buffer) );
    for (i = 0; i < sizeof(DRIVE_Types)/sizeof(DRIVE_Types[0]); i++)
    {
        if (!strcasecmp( buffer, DRIVE_Types[i] )) return i;
    }
    MESSAGE("%s: unknown drive type '%s', defaulting to 'hd'.\n",
	name, buffer );
    return DRIVE_FIXED;
}


/***********************************************************************
 *           DRIVE_GetFSFlags
 */
static UINT DRIVE_GetFSFlags( const char *name, const char *value )
{
    const FS_DESCR *descr;

    for (descr = DRIVE_Filesystems; descr->name; descr++)
        if (!strcasecmp( value, descr->name )) return descr->flags;
    MESSAGE("%s: unknown filesystem type '%s', defaulting to 'win95'.\n",
	name, value );
    return DRIVE_CASE_PRESERVING;
}


/***********************************************************************
 *           DRIVE_Init
 */
int DRIVE_Init(void)
{
    int i, len, count = 0;
    char name[] = "Drive A";
    char drive_env[] = "=A:";
    char path[MAX_PATHNAME_LEN];
    char buffer[80];
    struct stat drive_stat_buffer;
    char *p;
    DOSDRIVE *drive;

    for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, name[6]++, drive++)
    {
        PROFILE_GetWineIniString( name, "Path", "", path, sizeof(path)-1 );
        if (path[0])
        {
            p = path + strlen(path) - 1;
            while ((p > path) && (*p == '/')) *p-- = '\0';

            if (path[0] == '/')
            {
                drive->root = heap_strdup( path );
            }
            else
            {
                /* relative paths are relative to config dir */
                const char *config = wine_get_config_dir();
                drive->root = HeapAlloc( GetProcessHeap(), 0, strlen(config) + strlen(path) + 2 );
                sprintf( drive->root, "%s/%s", config, path );
            }

            if (stat( drive->root, &drive_stat_buffer ))
            {
                MESSAGE("Could not stat %s (%s), ignoring drive %c:\n",
                        drive->root, strerror(errno), 'A' + i);
                HeapFree( GetProcessHeap(), 0, drive->root );
                drive->root = NULL;
                continue;
            }
            if (!S_ISDIR(drive_stat_buffer.st_mode))
            {
                MESSAGE("%s is not a directory, ignoring drive %c:\n",
                        drive->root, 'A' + i );
                HeapFree( GetProcessHeap(), 0, drive->root );
                drive->root = NULL;
                continue;
            }

            drive->dos_cwd  = heap_strdup( "" );
            drive->unix_cwd = heap_strdup( "" );
            drive->type     = DRIVE_GetDriveType( name );
            drive->device   = NULL;
            drive->flags    = 0;
            drive->dev      = drive_stat_buffer.st_dev;
            drive->ino      = drive_stat_buffer.st_ino;

            /* Get the drive label */
            PROFILE_GetWineIniString( name, "Label", "", drive->label_conf, 12 );
            if ((len = strlen(drive->label_conf)) < 11)
            {
                /* Pad label with spaces */
                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_conf = strtoul( buffer, NULL, 16 );

            /* Get the filesystem type */
            PROFILE_GetWineIniString( name, "Filesystem", "win95",
                                      buffer, sizeof(buffer) );
            drive->flags = DRIVE_GetFSFlags( name, buffer );

            /* Get the device */
            PROFILE_GetWineIniString( name, "Device", "",
                                      buffer, sizeof(buffer) );
            if (buffer[0])
	    {
		int cd_fd;
                drive->device = heap_strdup( buffer );
		if (PROFILE_GetWineIniBool( name, "ReadVolInfo", 1))
                    drive->flags |= DRIVE_READ_VOL_INFO;
                if (drive->type == DRIVE_CDROM)
                {
                    if ((cd_fd = open(buffer,O_RDONLY|O_NONBLOCK)) != -1) {
                        CDROM_InitRegistry(cd_fd);
                        close(cd_fd);
                    }
                }
	    }

            /* Get the FailReadOnly flag */
            if (PROFILE_GetWineIniBool( name, "FailReadOnly", 0 ))
                drive->flags |= DRIVE_FAIL_READ_ONLY;

            /* Make the first hard disk the current drive */
            if ((DRIVE_CurDrive == -1) && (drive->type == DRIVE_FIXED))
                DRIVE_CurDrive = i;

            count++;
            TRACE("%s: path=%s type=%s label='%s' serial=%08lx "
                  "flags=%08x dev=%x ino=%x\n",
                  name, drive->root, DRIVE_Types[drive->type],
                  drive->label_conf, drive->serial_conf, drive->flags,
                  (int)drive->dev, (int)drive->ino );
        }
        else WARN("%s: not defined\n", name );
    }

    if (!count)
    {
        MESSAGE("Warning: no valid DOS drive found, check your configuration file.\n" );
        /* Create a C drive pointing to Unix root dir */
        DOSDrives[2].root     = heap_strdup( "/" );
        DOSDrives[2].dos_cwd  = heap_strdup( "" );
        DOSDrives[2].unix_cwd = heap_strdup( "" );
        strcpy( DOSDrives[2].label_conf, "Drive C    " );
        DOSDrives[2].serial_conf   = 12345678;
        DOSDrives[2].type     = DRIVE_FIXED;
        DOSDrives[2].device   = NULL;
        DOSDrives[2].flags    = 0;
        DRIVE_CurDrive = 2;
    }

    /* Make sure the current drive is valid */
    if (DRIVE_CurDrive == -1)
    {
        for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
        {
            if (drive->root && !(drive->flags & DRIVE_DISABLED))
            {
                DRIVE_CurDrive = i;
                break;
            }
        }
    }

    /* get current working directory info for all drives */
    for (i = 0; i < MAX_DOS_DRIVES; i++, drive_env[1]++)
    {
        if (!GetEnvironmentVariableA(drive_env, path, sizeof(path))) continue;
        /* sanity check */
        if (toupper(path[0]) != drive_env[1] || path[1] != ':') continue;
        DRIVE_Chdir( i, path + 2 );
    }
    return 1;
}


/***********************************************************************
 *           DRIVE_IsValid
 */
int DRIVE_IsValid( int drive )
{
    if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
    return (DOSDrives[drive].root &&
            !(DOSDrives[drive].flags & DRIVE_DISABLED));
}


/***********************************************************************
 *           DRIVE_GetCurrentDrive
 */
int DRIVE_GetCurrentDrive(void)
{
    TDB *pTask = TASK_GetCurrent();
    if (pTask && (pTask->curdrive & 0x80)) return pTask->curdrive & ~0x80;
    return DRIVE_CurDrive;
}


/***********************************************************************
 *           DRIVE_SetCurrentDrive
 */
int DRIVE_SetCurrentDrive( int drive )
{
    TDB *pTask = TASK_GetCurrent();
    if (!DRIVE_IsValid( drive ))
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }
    TRACE("%c:\n", 'A' + drive );
    DRIVE_CurDrive = drive;
    if (pTask) pTask->curdrive = drive | 0x80;
    chdir(DRIVE_GetUnixCwd(drive));
    return 1;
}


/***********************************************************************
 *           DRIVE_FindDriveRoot
 *
 * Find a drive for which the root matches the beginning of the given path.
 * This can be used to translate a Unix path into a drive + DOS path.
 * Return value is the drive, or -1 on error. On success, path is modified
 * to point to the beginning of the DOS path.
 */
int DRIVE_FindDriveRoot( const char **path )
{
    /* Starting with the full path, check if the device and inode match any of
     * the wine 'drives'. If not then remove the last path component and try
     * again. If the last component was a '..' then skip a normal component
     * since it's a directory that's ascended back out of.
     */
    int drive, level, len;
    char buffer[MAX_PATHNAME_LEN];
    char *p;
    struct stat st;

    strcpy( buffer, *path );
    while ((p = strchr( buffer, '\\' )) != NULL)
        *p = '/';
    len = strlen(buffer);

    /* strip off trailing slashes */
    while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0;

    for (;;)
    {
        /* Find the drive */
        if (stat( buffer, &st ) == 0 && S_ISDIR( st.st_mode ))
        {
            for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
            {
               if (!DOSDrives[drive].root ||
                   (DOSDrives[drive].flags & DRIVE_DISABLED))
                   continue;

               if ((DOSDrives[drive].dev == st.st_dev) &&
                   (DOSDrives[drive].ino == st.st_ino))
               {
                   if (len == 1) len = 0;  /* preserve root slash in returned path */
                   TRACE( "%s -> drive %c:, root='%s', name='%s'\n",
                       *path, 'A' + drive, buffer, *path + len);
                   *path += len;
                   if (!**path) *path = "\\";
                   return drive;
               }
            }
        }
        if (len <= 1) return -1;  /* reached root */

        level = 0;
        while (level < 1)
        {
            /* find start of the last path component */
            while (len > 1 && buffer[len - 1] != '/') len--;
            if (!buffer[len]) break;  /* empty component -> reached root */
            /* does removing it take us up a level? */
            if (strcmp( buffer + len, "." ) != 0)
                level += strcmp( buffer + len, ".." ) ? 1 : -1;
            buffer[len] = 0;
            /* strip off trailing slashes */
            while (len > 1 && buffer[len - 1] == '/') buffer[--len] = 0;
        }
    }
}


/***********************************************************************
 *           DRIVE_GetRoot
 */
const char * DRIVE_GetRoot( int drive )
{
    if (!DRIVE_IsValid( drive )) return NULL;
    return DOSDrives[drive].root;
}


/***********************************************************************
 *           DRIVE_GetDosCwd
 */
const char * DRIVE_GetDosCwd( int drive )
{
    TDB *pTask = TASK_GetCurrent();
    if (!DRIVE_IsValid( drive )) return NULL;

    /* Check if we need to change the directory to the new task. */
    if (pTask && (pTask->curdrive & 0x80) &&    /* The task drive is valid */
        ((pTask->curdrive & ~0x80) == drive) && /* and it's the one we want */
        (DRIVE_LastTask != GetCurrentTask()))   /* and the task changed */
    {
        /* Perform the task-switch */
        if (!DRIVE_Chdir( drive, pTask->curdir )) DRIVE_Chdir( drive, "\\" );
        DRIVE_LastTask = GetCurrentTask();
    }
    return DOSDrives[drive].dos_cwd;
}


/***********************************************************************
 *           DRIVE_GetUnixCwd
 */
const char * DRIVE_GetUnixCwd( int drive )
{
    TDB *pTask = TASK_GetCurrent();
    if (!DRIVE_IsValid( drive )) return NULL;

    /* Check if we need to change the directory to the new task. */
    if (pTask && (pTask->curdrive & 0x80) &&    /* The task drive is valid */
        ((pTask->curdrive & ~0x80) == drive) && /* and it's the one we want */
        (DRIVE_LastTask != GetCurrentTask()))   /* and the task changed */
    {
        /* Perform the task-switch */
        if (!DRIVE_Chdir( drive, pTask->curdir )) DRIVE_Chdir( drive, "\\" );
        DRIVE_LastTask = GetCurrentTask();
    }
    return DOSDrives[drive].unix_cwd;
}


/***********************************************************************
 *           DRIVE_GetDevice
 */
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
 *
 * NOTE
 *      DRIVE_SetLabel and DRIVE_SetSerialNumber use this in order
 * to check, that they are writing on a FAT filesystem !
 */
int DRIVE_ReadSuperblock (int drive, char * buff)
{
#define DRIVE_SUPER 96
    int fd;
    off_t offs;
    int ret = 0;

    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 DRIVE_REMOVABLE:
	case DRIVE_FIXED:
	    offs = 0;
	    break;
	case DRIVE_CDROM:
	    offs = CDROM_Data_FindBestVoldesc(fd);
	    break;
        default:
            offs = 0;
            break;
    }

    if ((offs) && (lseek(fd,offs,SEEK_SET)!=offs))
    {
        ret = -4;
        goto the_end;
    }
    if (read(fd,buff,DRIVE_SUPER)!=DRIVE_SUPER)
    {
        ret = -2;
        goto the_end;
    }

    switch(DOSDrives[drive].type)
    {
	case DRIVE_REMOVABLE:
	case DRIVE_FIXED:
	    if ((buff[0x26]!=0x29) ||  /* Check for FAT present */
                /* FIXME: do really all FAT have their name beginning with
                   "FAT" ? (At least FAT12, FAT16 and FAT32 have :) */
	    	memcmp( buff+0x36,"FAT",3))
            {
                ERR("The filesystem is not FAT !! (device=%s)\n",
                    DOSDrives[drive].device);
                ret = -3;
                goto the_end;
            }
            break;
	case DRIVE_CDROM:
	    if (strncmp(&buff[1],"CD001",5)) /* Check for iso9660 present */
            {
		ret = -3;
                goto the_end;
            }
	    /* FIXME: do we need to check for "CDROM", too ? (high sierra) */
            break;
	default:
            ret = -3;
            goto the_end;
    }

    return close(fd);
 the_end:
    close(fd);
    return ret;
}


/***********************************************************************
 *           DRIVE_WriteSuperblockEntry
 *
 * NOTE
 *	We are writing as little as possible (ie. not the whole SuperBlock)
 * not to interfere with kernel. The drive can be mounted !
 */
int DRIVE_WriteSuperblockEntry (int drive, off_t ofs, size_t len, char * buff)
{
    int fd;

    if ((fd=open(DOSDrives[drive].device,O_WRONLY))==-1)
    {
        ERR("Cannot open the device %s (for writing)\n",
            DOSDrives[drive].device);
        return -1;
    }
    if (lseek(fd,ofs,SEEK_SET)!=ofs)
    {
        ERR("lseek failed on device %s !\n",
            DOSDrives[drive].device);
        close(fd);
        return -2;
    }
    if (write(fd,buff,len)!=len)
    {
        close(fd);
        ERR("Cannot write on %s !\n",
            DOSDrives[drive].device);
        return -3;
    }
    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;
        break;
    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
 */
const char * DRIVE_GetLabel( int drive )
{
    int read = 0;
    char buff[DRIVE_SUPER];
    int offs = -1;

    if (!DRIVE_IsValid( drive )) return NULL;
    if (DOSDrives[drive].type == DRIVE_CDROM)
    {
	read = CDROM_GetLabel(drive, DOSDrives[drive].label_read);
    }
    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 == DRIVE_REMOVABLE ||
		DOSDrives[drive].type == DRIVE_FIXED)
		offs = 0x2b;

	    /* 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;
	}
    }

    return (read) ?
	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
 */
DWORD DRIVE_GetSerialNumber( int drive )
{
    DWORD serial = 0;
    char buff[DRIVE_SUPER];

    if (!DRIVE_IsValid( drive )) return 0;

    if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
    {
	switch(DOSDrives[drive].type)
	{
        case DRIVE_REMOVABLE:
        case DRIVE_FIXED:
            if (DRIVE_ReadSuperblock(drive,(char *) buff))
                MESSAGE("Invalid or unreadable superblock on %s (%c:)."
                        " Maybe not FAT?\n" ,
                        DOSDrives[drive].device, 'A'+drive);
            else
                serial = *((DWORD*)(buff+0x27));
            break;
        case DRIVE_CDROM:
            serial = CDROM_GetSerial(drive);
            break;
        default:
            FIXME("Serial number reading from file system on drive %c: not supported yet.\n", drive+'A');
	}
    }

    return (serial) ? serial : DOSDrives[drive].serial_conf;
}


/***********************************************************************
 *           DRIVE_SetSerialNumber
 */
int DRIVE_SetSerialNumber( int drive, DWORD serial )
{
    char buff[DRIVE_SUPER];

    if (!DRIVE_IsValid( drive )) return 0;

    if (DOSDrives[drive].flags & DRIVE_READ_VOL_INFO)
    {
        if ((DOSDrives[drive].type != DRIVE_REMOVABLE) &&
            (DOSDrives[drive].type != DRIVE_FIXED)) return 0;
        /* check, if the drive has a FAT filesystem */
        if (DRIVE_ReadSuperblock(drive, buff)) return 0;
        if (DRIVE_WriteSuperblockEntry(drive, 0x27, 4, (char *) &serial)) return 0;
        return 1;
    }

    if (DOSDrives[drive].type == DRIVE_CDROM) return 0;
    DOSDrives[drive].serial_conf = serial;
    return 1;
}


/***********************************************************************
 *           DRIVE_GetType
 */
static UINT DRIVE_GetType( int drive )
{
    if (!DRIVE_IsValid( drive )) return DRIVE_UNKNOWN;
    return DOSDrives[drive].type;
}


/***********************************************************************
 *           DRIVE_GetFlags
 */
UINT DRIVE_GetFlags( int drive )
{
    if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
    return DOSDrives[drive].flags;
}


/***********************************************************************
 *           DRIVE_Chdir
 */
int DRIVE_Chdir( int drive, const char *path )
{
    DOS_FULL_NAME full_name;
    char buffer[MAX_PATHNAME_LEN];
    LPSTR unix_cwd;
    BY_HANDLE_FILE_INFORMATION info;
    TDB *pTask = TASK_GetCurrent();

    strcpy( buffer, "A:" );
    buffer[0] += drive;
    TRACE("(%s,%s)\n", buffer, path );
    lstrcpynA( buffer + 2, path, sizeof(buffer) - 2 );

    if (!DOSFS_GetFullName( buffer, TRUE, &full_name )) return 0;
    if (!FILE_Stat( full_name.long_name, &info )) return 0;
    if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }
    unix_cwd = full_name.long_name + strlen( DOSDrives[drive].root );
    while (*unix_cwd == '/') unix_cwd++;

    TRACE("(%c:): unix_cwd=%s dos_cwd=%s\n",
                   'A' + drive, unix_cwd, full_name.short_name + 3 );

    HeapFree( GetProcessHeap(), 0, DOSDrives[drive].dos_cwd );
    HeapFree( GetProcessHeap(), 0, DOSDrives[drive].unix_cwd );
    DOSDrives[drive].dos_cwd  = heap_strdup( full_name.short_name + 3 );
    DOSDrives[drive].unix_cwd = heap_strdup( unix_cwd );

    if (pTask && (pTask->curdrive & 0x80) &&
        ((pTask->curdrive & ~0x80) == drive))
    {
        lstrcpynA( pTask->curdir, full_name.short_name + 2,
                     sizeof(pTask->curdir) );
        DRIVE_LastTask = GetCurrentTask();
        chdir(unix_cwd); /* Only change if on current drive */
    }
    return 1;
}


/***********************************************************************
 *           DRIVE_Disable
 */
int DRIVE_Disable( int drive  )
{
    if ((drive < 0) || (drive >= MAX_DOS_DRIVES) || !DOSDrives[drive].root)
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }
    DOSDrives[drive].flags |= DRIVE_DISABLED;
    return 1;
}


/***********************************************************************
 *           DRIVE_Enable
 */
int DRIVE_Enable( int drive  )
{
    if ((drive < 0) || (drive >= MAX_DOS_DRIVES) || !DOSDrives[drive].root)
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }
    DOSDrives[drive].flags &= ~DRIVE_DISABLED;
    return 1;
}


/***********************************************************************
 *           DRIVE_SetLogicalMapping
 */
int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive )
{
 /* If new_drive is already valid, do nothing and return 0
    otherwise, copy DOSDrives[existing_drive] to DOSDrives[new_drive] */

    DOSDRIVE *old, *new;

    old = DOSDrives + existing_drive;
    new = DOSDrives + new_drive;

    if ((existing_drive < 0) || (existing_drive >= MAX_DOS_DRIVES) ||
        !old->root ||
	(new_drive < 0) || (new_drive >= MAX_DOS_DRIVES))
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }

    if ( new->root )
    {
        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;
	return 0;
    }

    new->root     = heap_strdup( old->root );
    new->dos_cwd  = heap_strdup( old->dos_cwd );
    new->unix_cwd = heap_strdup( old->unix_cwd );
    new->device   = heap_strdup( 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",
          'A' + new_drive, 'A' + existing_drive );

    return 1;
}


/***********************************************************************
 *           DRIVE_OpenDevice
 *
 * Open the drive raw device and return a Unix fd (or -1 on error).
 */
int DRIVE_OpenDevice( int drive, int flags )
{
    if (!DRIVE_IsValid( drive )) return -1;
    return open( DOSDrives[drive].device, flags );
}


/***********************************************************************
 *           DRIVE_RawRead
 *
 * Read raw sectors from a device
 */
int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success)
{
    int fd;

    if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
    {
        lseek( fd, begin * 512, SEEK_SET );
        /* FIXME: check errors */
        read( fd, dataptr, nr_sect * 512 );
        close( fd );
    }
    else
    {
        memset(dataptr, 0, nr_sect * 512);
	if (fake_success)
        {
	    if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8;
	    if (begin == 1) *dataptr = 0xf8;
	}
	else
	    return 0;
    }
    return 1;
}


/***********************************************************************
 *           DRIVE_RawWrite
 *
 * Write raw sectors to a device
 */
int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success)
{
    int fd;

    if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
    {
        lseek( fd, begin * 512, SEEK_SET );
        /* FIXME: check errors */
        write( fd, dataptr, nr_sect * 512 );
        close( fd );
    }
    else
    if (!(fake_success))
	return 0;

    return 1;
}


/***********************************************************************
 *           DRIVE_GetFreeSpace
 */
static int DRIVE_GetFreeSpace( int drive, PULARGE_INTEGER size,
			       PULARGE_INTEGER available )
{
    struct statfs info;

    if (!DRIVE_IsValid(drive))
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }

/* FIXME: add autoconf check for this */
#if defined(__svr4__) || defined(_SCO_DS) || defined(__sun)
    if (statfs( DOSDrives[drive].root, &info, 0, 0) < 0)
#else
    if (statfs( DOSDrives[drive].root, &info) < 0)
#endif
    {
        FILE_SetDosError();
        WARN("cannot do statfs(%s)\n", DOSDrives[drive].root);
        return 0;
    }

    size->QuadPart = RtlEnlargedUnsignedMultiply( info.f_bsize, info.f_blocks );
#ifdef STATFS_HAS_BAVAIL
    available->QuadPart = RtlEnlargedUnsignedMultiply( info.f_bavail, info.f_bsize );
#else
# ifdef STATFS_HAS_BFREE
    available->QuadPart = RtlEnlargedUnsignedMultiply( info.f_bfree, info.f_bsize );
# else
#  error "statfs has no bfree/bavail member!"
# endif
#endif
    if (DOSDrives[drive].type == DRIVE_CDROM)
    { /* ALWAYS 0, even if no real CD-ROM mounted there !! */
        available->QuadPart = 0;
    }
    return 1;
}

/***********************************************************************
 *       DRIVE_GetCurrentDirectory
 * Returns "X:\\path\\etc\\".
 *
 * Despite the API description, return required length including the
 * terminating null when buffer too small. This is the real behaviour.
*/

static UINT DRIVE_GetCurrentDirectory( UINT buflen, LPSTR buf )
{
    UINT ret;
    const char *s = DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() );

    assert(s);
    ret = strlen(s) + 3; /* length of WHOLE current directory */
    if (ret >= buflen) return ret + 1;
    lstrcpynA( buf, "A:\\", min( 4u, buflen ) );
    if (buflen) buf[0] += DRIVE_GetCurrentDrive();
    if (buflen > 3) lstrcpynA( buf + 3, s, buflen - 3 );
    return ret;
}


/***********************************************************************
 *           DRIVE_BuildEnv
 *
 * Build the environment array containing the drives' current directories.
 * Resulting pointer must be freed with HeapFree.
 */
char *DRIVE_BuildEnv(void)
{
    int i, length = 0;
    const char *cwd[MAX_DOS_DRIVES];
    char *env, *p;

    for (i = 0; i < MAX_DOS_DRIVES; i++)
    {
        if ((cwd[i] = DRIVE_GetDosCwd(i)) && cwd[i][0]) length += strlen(cwd[i]) + 8;
    }
    if (!(env = HeapAlloc( GetProcessHeap(), 0, length+1 ))) return NULL;
    for (i = 0, p = env; i < MAX_DOS_DRIVES; i++)
    {
        if (cwd[i] && cwd[i][0])
            p += sprintf( p, "=%c:=%c:\\%s", 'A'+i, 'A'+i, cwd[i] ) + 1;
    }
    *p = 0;
    return env;
}


/***********************************************************************
 *           GetDiskFreeSpace   (KERNEL.422)
 */
BOOL16 WINAPI GetDiskFreeSpace16( LPCSTR root, LPDWORD cluster_sectors,
                                  LPDWORD sector_bytes, LPDWORD free_clusters,
                                  LPDWORD total_clusters )
{
    return GetDiskFreeSpaceA( root, cluster_sectors, sector_bytes,
                                free_clusters, total_clusters );
}


/***********************************************************************
 *           GetDiskFreeSpaceA   (KERNEL32.@)
 *
 * Fails if expression resulting from current drive's dir and "root"
 * is not a root dir of the target drive.
 *
 * UNDOC: setting some LPDWORDs to NULL is perfectly possible
 * if the corresponding info is unneeded.
 *
 * FIXME: needs to support UNC names from Win95 OSR2 on.
 *
 * Behaviour under Win95a:
 * CurrDir     root   result
 * "E:\\TEST"  "E:"   FALSE
 * "E:\\"      "E:"   TRUE
 * "E:\\"      "E"    FALSE
 * "E:\\"      "\\"   TRUE
 * "E:\\TEST"  "\\"   TRUE
 * "E:\\TEST"  ":\\"  FALSE
 * "E:\\TEST"  "E:\\" TRUE
 * "E:\\TEST"  ""     FALSE
 * "E:\\"      ""     FALSE (!)
 * "E:\\"      0x0    TRUE
 * "E:\\TEST"  0x0    TRUE  (!)
 * "E:\\TEST"  "C:"   TRUE  (when CurrDir of "C:" set to "\\")
 * "E:\\TEST"  "C:"   FALSE (when CurrDir of "C:" set to "\\TEST")
 */
BOOL WINAPI GetDiskFreeSpaceA( LPCSTR root, LPDWORD cluster_sectors,
                                   LPDWORD sector_bytes, LPDWORD free_clusters,
                                   LPDWORD total_clusters )
{
    int	drive, sec_size;
    ULARGE_INTEGER size,available;
    LPCSTR path;
    DWORD cluster_sec;

    if ((!root) || (strcmp(root,"\\") == 0))
	drive = DRIVE_GetCurrentDrive();
    else
    if ( (strlen(root) >= 2) && (root[1] == ':')) /* root contains drive tag */
    {
        drive = toupper(root[0]) - 'A';
	path = &root[2];
	if (path[0] == '\0')
	    path = DRIVE_GetDosCwd(drive);
	else
	if (path[0] == '\\')
	    path++;
        if (path[0]) /* oops, we are in a subdir */
        {
            SetLastError(ERROR_INVALID_NAME);
            return FALSE;
        }
    }
    else
    {
        SetLastError(ERROR_INVALID_NAME);
        return FALSE;
    }

    if (!DRIVE_GetFreeSpace(drive, &size, &available)) return FALSE;

    /* Cap the size and available at 2GB as per specs.  */
    if ((size.s.HighPart) ||(size.s.LowPart > 0x7fffffff))
    {
	size.s.HighPart = 0;
	size.s.LowPart = 0x7fffffff;
    }
    if ((available.s.HighPart) ||(available.s.LowPart > 0x7fffffff))
    {
	available.s.HighPart =0;
	available.s.LowPart = 0x7fffffff;
    }
    sec_size = (DRIVE_GetType(drive)==DRIVE_CDROM) ? 2048 : 512;
    size.s.LowPart            /= sec_size;
    available.s.LowPart       /= sec_size;
    /* FIXME: probably have to adjust those variables too for CDFS */
    cluster_sec = 1;
    while (cluster_sec * 65536 < size.s.LowPart) cluster_sec *= 2;

    if (cluster_sectors)
	*cluster_sectors = cluster_sec;
    if (sector_bytes)
	*sector_bytes    = sec_size;
    if (free_clusters)
	*free_clusters   = available.s.LowPart / cluster_sec;
    if (total_clusters)
	*total_clusters  = size.s.LowPart / cluster_sec;
    return TRUE;
}


/***********************************************************************
 *           GetDiskFreeSpaceW   (KERNEL32.@)
 */
BOOL WINAPI GetDiskFreeSpaceW( LPCWSTR root, LPDWORD cluster_sectors,
                                   LPDWORD sector_bytes, LPDWORD free_clusters,
                                   LPDWORD total_clusters )
{
    LPSTR xroot;
    BOOL ret;

    xroot = HEAP_strdupWtoA( GetProcessHeap(), 0, root);
    ret = GetDiskFreeSpaceA( xroot,cluster_sectors, sector_bytes,
                               free_clusters, total_clusters );
    HeapFree( GetProcessHeap(), 0, xroot );
    return ret;
}


/***********************************************************************
 *           GetDiskFreeSpaceExA   (KERNEL32.@)
 *
 *  This function is used to acquire the size of the available and
 *  total space on a logical volume.
 *
 * RETURNS
 *
 *  Zero on failure, nonzero upon success. Use GetLastError to obtain
 *  detailed error information.
 *
 */
BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root,
				     PULARGE_INTEGER avail,
				     PULARGE_INTEGER total,
				     PULARGE_INTEGER totalfree)
{
    int	drive;
    ULARGE_INTEGER size,available;

    if (!root) drive = DRIVE_GetCurrentDrive();
    else
    { /* C: always works for GetDiskFreeSpaceEx */
        if ((root[1]) && ((root[1] != ':') || (root[2] && root[2] != '\\')))
        {
            FIXME("there are valid root names which are not supported yet\n");
	    /* ..like UNC names, for instance. */

            WARN("invalid root '%s'\n", root );
            return FALSE;
        }
        drive = toupper(root[0]) - 'A';
    }

    if (!DRIVE_GetFreeSpace(drive, &size, &available)) return FALSE;

    if (total)
    {
        total->s.HighPart = size.s.HighPart;
        total->s.LowPart = size.s.LowPart;
    }

    if (totalfree)
    {
        totalfree->s.HighPart = available.s.HighPart;
        totalfree->s.LowPart = available.s.LowPart;
    }

    if (avail)
    {
        if (FIXME_ON(dosfs))
	{
            /* On Windows2000, we need to check the disk quota
	       allocated for the user owning the calling process. We
	       don't want to be more obtrusive than necessary with the
	       FIXME messages, so don't print the FIXME unless Wine is
	       actually masquerading as Windows2000. */

            OSVERSIONINFOA ovi;
	    ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
	    if (GetVersionExA(&ovi))
	    {
	      if (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT && ovi.dwMajorVersion > 4)
                  FIXME("no per-user quota support yet\n");
	    }
	}

        /* 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;
    }

    return TRUE;
}

/***********************************************************************
 *           GetDiskFreeSpaceExW   (KERNEL32.@)
 */
BOOL WINAPI GetDiskFreeSpaceExW( LPCWSTR root, PULARGE_INTEGER avail,
				     PULARGE_INTEGER total,
				     PULARGE_INTEGER  totalfree)
{
    LPSTR xroot;
    BOOL ret;

    xroot = HEAP_strdupWtoA( GetProcessHeap(), 0, root);
    ret = GetDiskFreeSpaceExA( xroot, avail, total, totalfree);
    HeapFree( GetProcessHeap(), 0, xroot );
    return ret;
}

/***********************************************************************
 *           GetDriveType   (KERNEL.136)
 * 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 return value DRIVE_REMOTE for CD-ROMs has been
 * verified on Win 3.11 and Windows 95. Some programs rely on it, so don't
 * do any pseudo-clever changes.
 *
 * RETURNS
 *	drivetype DRIVE_xxx
 */
UINT16 WINAPI GetDriveType16( UINT16 drive ) /* [in] number (NOT letter) of drive */
{
    UINT type = DRIVE_GetType(drive);
    TRACE("(%c:)\n", 'A' + drive );
    if (type == DRIVE_CDROM) type = DRIVE_REMOTE;
    return type;
}


/***********************************************************************
 *           GetDriveTypeA   (KERNEL32.@)
 *
 * Returns the type of the disk drive specified. If root is NULL the
 * root of the current directory is used.
 *
 * RETURNS
 *
 *  Type of drive (from Win32 SDK):
 *
 *   DRIVE_UNKNOWN     unable to find out anything about the drive
 *   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
 */
UINT WINAPI GetDriveTypeA(LPCSTR root) /* [in] String describing drive */
{
    int drive;
    TRACE("(%s)\n", debugstr_a(root));

    if (NULL == root) drive = DRIVE_GetCurrentDrive();
    else
    {
        if ((root[1]) && (root[1] != ':'))
	{
	    WARN("invalid root %s\n", debugstr_a(root));
	    return DRIVE_NO_ROOT_DIR;
	}
	drive = toupper(root[0]) - 'A';
    }
    return DRIVE_GetType(drive);
}


/***********************************************************************
 *           GetDriveTypeW   (KERNEL32.@)
 */
UINT WINAPI GetDriveTypeW( LPCWSTR root )
{
    LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, root );
    UINT ret = GetDriveTypeA( xpath );
    HeapFree( GetProcessHeap(), 0, xpath );
    return ret;
}


/***********************************************************************
 *           GetCurrentDirectory   (KERNEL.411)
 */
UINT16 WINAPI GetCurrentDirectory16( UINT16 buflen, LPSTR buf )
{
    return (UINT16)DRIVE_GetCurrentDirectory(buflen, buf);
}


/***********************************************************************
 *           GetCurrentDirectoryA   (KERNEL32.@)
 */
UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf )
{
    UINT ret;
    char longname[MAX_PATHNAME_LEN];
    char shortname[MAX_PATHNAME_LEN];
    ret = DRIVE_GetCurrentDirectory(MAX_PATHNAME_LEN, shortname);
    if ( ret > MAX_PATHNAME_LEN ) {
      ERR_(file)("pathnamelength (%d) > MAX_PATHNAME_LEN!\n", ret );
      return ret;
    }
    GetLongPathNameA(shortname, longname, MAX_PATHNAME_LEN);
    ret = strlen( longname ) + 1;
    if (ret > buflen) return ret;
    strcpy(buf, longname);
    return ret - 1;
}

/***********************************************************************
 *           GetCurrentDirectoryW   (KERNEL32.@)
 */
UINT WINAPI GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
{
    LPSTR xpath = HeapAlloc( GetProcessHeap(), 0, buflen+1 );
    UINT ret = GetCurrentDirectoryA( buflen, xpath );
    if (ret < buflen) ret = MultiByteToWideChar( CP_ACP, 0, xpath, -1, buf, buflen ) - 1;
    HeapFree( GetProcessHeap(), 0, xpath );
    return ret;
}


/***********************************************************************
 *           SetCurrentDirectory   (KERNEL.412)
 */
BOOL16 WINAPI SetCurrentDirectory16( LPCSTR dir )
{
    return SetCurrentDirectoryA( dir );
}


/***********************************************************************
 *           SetCurrentDirectoryA   (KERNEL32.@)
 */
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
{
    int drive, olddrive = DRIVE_GetCurrentDrive();

    if (!dir) {
    	ERR_(file)("(NULL)!\n");
	return FALSE;
    }
    if (dir[0] && (dir[1]==':'))
    {
        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 */
    if (!(DRIVE_SetCurrentDrive( drive )))
	return FALSE;
    /* FIXME: what about empty strings? Add a \\ ? */
    if (!DRIVE_Chdir( drive, dir )) {
	DRIVE_SetCurrentDrive(olddrive);
	return FALSE;
    }
    return TRUE;
}


/***********************************************************************
 *           SetCurrentDirectoryW   (KERNEL32.@)
 */
BOOL WINAPI SetCurrentDirectoryW( LPCWSTR dirW )
{
    LPSTR dir = HEAP_strdupWtoA( GetProcessHeap(), 0, dirW );
    BOOL res = SetCurrentDirectoryA( dir );
    HeapFree( GetProcessHeap(), 0, dir );
    return res;
}


/***********************************************************************
 *           GetLogicalDriveStringsA   (KERNEL32.@)
 */
UINT WINAPI GetLogicalDriveStringsA( UINT len, LPSTR buffer )
{
    int drive, count;

    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
        if (DRIVE_IsValid(drive)) count++;
    if ((count * 4) + 1 <= len)
    {
        LPSTR p = buffer;
        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
            if (DRIVE_IsValid(drive))
            {
                *p++ = 'a' + drive;
                *p++ = ':';
                *p++ = '\\';
                *p++ = '\0';
            }
        *p = '\0';
        return count * 4;
    }
    else
        return (count * 4) + 1; /* account for terminating null */
    /* The API tells about these different return values */
}


/***********************************************************************
 *           GetLogicalDriveStringsW   (KERNEL32.@)
 */
UINT WINAPI GetLogicalDriveStringsW( UINT len, LPWSTR buffer )
{
    int drive, count;

    for (drive = count = 0; drive < MAX_DOS_DRIVES; drive++)
        if (DRIVE_IsValid(drive)) count++;
    if (count * 4 * sizeof(WCHAR) <= len)
    {
        LPWSTR p = buffer;
        for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
            if (DRIVE_IsValid(drive))
            {
                *p++ = (WCHAR)('a' + drive);
                *p++ = (WCHAR)':';
                *p++ = (WCHAR)'\\';
                *p++ = (WCHAR)'\0';
            }
        *p = (WCHAR)'\0';
    }
    return count * 4 * sizeof(WCHAR);
}


/***********************************************************************
 *           GetLogicalDrives   (KERNEL32.@)
 */
DWORD WINAPI GetLogicalDrives(void)
{
    DWORD ret = 0;
    int drive;

    for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
    {
        if ( (DRIVE_IsValid(drive)) ||
            (DOSDrives[drive].type == DRIVE_CDROM)) /* audio CD is also valid */
            ret |= (1 << drive);
    }
    return ret;
}


/***********************************************************************
 *           GetVolumeInformationA   (KERNEL32.@)
 */
BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label,
                                       DWORD label_len, DWORD *serial,
                                       DWORD *filename_len, DWORD *flags,
                                       LPSTR fsname, DWORD fsname_len )
{
    int drive;
    char *cp;

    /* FIXME, SetLastError()s missing */

    if (!root) drive = DRIVE_GetCurrentDrive();
    else
    {
        if ((root[1]) && (root[1] != ':'))
        {
            WARN("invalid root '%s'\n",root);
            return FALSE;
        }
        drive = toupper(root[0]) - 'A';
    }
    if (!DRIVE_IsValid( drive )) return FALSE;
    if (label)
    {
       lstrcpynA( label, DRIVE_GetLabel(drive), label_len );
       cp = label + strlen(label);
       while (cp != label && *(cp-1) == ' ') cp--;
       *cp = '\0';
    }
    if (serial) *serial = DRIVE_GetSerialNumber(drive);

    /* Set the filesystem information */
    /* Note: we only emulate a FAT fs at present */

    if (filename_len) {
    	if (DOSDrives[drive].flags & DRIVE_SHORT_NAMES)
	    *filename_len = 12;
	else
	    *filename_len = 255;
    }
    if (flags)
      {
       *flags=0;
       if (DOSDrives[drive].flags & DRIVE_CASE_SENSITIVE)
         *flags|=FS_CASE_SENSITIVE;
       if (DOSDrives[drive].flags & DRIVE_CASE_PRESERVING)
         *flags|=FS_CASE_IS_PRESERVED;
      }
    if (fsname) {
    	/* Diablo checks that return code ... */
        if (DOSDrives[drive].type == DRIVE_CDROM)
	    lstrcpynA( fsname, "CDFS", fsname_len );
	else
	    lstrcpynA( fsname, "FAT", fsname_len );
    }
    return TRUE;
}


/***********************************************************************
 *           GetVolumeInformationW   (KERNEL32.@)
 */
BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label,
                                       DWORD label_len, DWORD *serial,
                                       DWORD *filename_len, DWORD *flags,
                                       LPWSTR fsname, DWORD fsname_len )
{
    LPSTR xroot    = HEAP_strdupWtoA( GetProcessHeap(), 0, root );
    LPSTR xvolname = label ? HeapAlloc(GetProcessHeap(),0,label_len) : NULL;
    LPSTR xfsname  = fsname ? HeapAlloc(GetProcessHeap(),0,fsname_len) : NULL;
    BOOL ret = GetVolumeInformationA( xroot, xvolname, label_len, serial,
                                          filename_len, flags, xfsname,
                                          fsname_len );
    if (ret)
    {
        if (label) MultiByteToWideChar( CP_ACP, 0, xvolname, -1, label, label_len );
        if (fsname) MultiByteToWideChar( CP_ACP, 0, xfsname, -1, fsname, fsname_len );
    }
    HeapFree( GetProcessHeap(), 0, xroot );
    HeapFree( GetProcessHeap(), 0, xvolname );
    HeapFree( GetProcessHeap(), 0, xfsname );
    return ret;
}

/***********************************************************************
 *           SetVolumeLabelA   (KERNEL32.@)
 */
BOOL WINAPI SetVolumeLabelA( LPCSTR root, LPCSTR volname )
{
    int drive;

    /* FIXME, SetLastErrors missing */

    if (!root) drive = DRIVE_GetCurrentDrive();
    else
    {
        if ((root[1]) && (root[1] != ':'))
        {
            WARN("invalid root '%s'\n",root);
            return FALSE;
        }
        drive = toupper(root[0]) - 'A';
    }
    if (!DRIVE_IsValid( drive )) return FALSE;

    /* some copy protection stuff check this */
    if (DOSDrives[drive].type == DRIVE_CDROM) return FALSE;

    FIXME("(%s,%s),stub!\n", root, volname);
    return TRUE;
}

/***********************************************************************
 *           SetVolumeLabelW   (KERNEL32.@)
 */
BOOL WINAPI SetVolumeLabelW(LPCWSTR rootpath,LPCWSTR volname)
{
    LPSTR xroot, xvol;
    BOOL ret;

    xroot = HEAP_strdupWtoA( GetProcessHeap(), 0, rootpath);
    xvol = HEAP_strdupWtoA( GetProcessHeap(), 0, volname);
    ret = SetVolumeLabelA( xroot, xvol );
    HeapFree( GetProcessHeap(), 0, xroot );
    HeapFree( GetProcessHeap(), 0, xvol );
    return ret;
}
