/*
 * 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 <stdarg.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

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.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 "task.h"
#include "wine/unicode.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 / */
    LPWSTR    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 */
    WCHAR     label_conf[12]; /* drive label as cfg'd in wine config */
    WCHAR     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 WCHAR DRIVE_Types[][8] =
{
    { 0 }, /* DRIVE_UNKNOWN */
    { 0 }, /* DRIVE_NO_ROOT_DIR */
    {'f','l','o','p','p','y',0}, /* DRIVE_REMOVABLE */
    {'h','d',0}, /* DRIVE_FIXED */
    {'n','e','t','w','o','r','k',0}, /* DRIVE_REMOTE */
    {'c','d','r','o','m',0}, /* DRIVE_CDROM */
    {'r','a','m','d','i','s','k',0} /* DRIVE_RAMDISK */
};


/* Known filesystem types */

typedef struct
{
    const WCHAR name[6];
    UINT      flags;
} FS_DESCR;

static const FS_DESCR DRIVE_Filesystems[] =
{
    { {'u','n','i','x',0}, DRIVE_CASE_SENSITIVE | DRIVE_CASE_PRESERVING },
    { {'m','s','d','o','s',0}, DRIVE_SHORT_NAMES },
    { {'d','o','s',0}, DRIVE_SHORT_NAMES },
    { {'f','a','t',0}, DRIVE_SHORT_NAMES },
    { {'v','f','a','t',0}, DRIVE_CASE_PRESERVING },
    { {'w','i','n','9','5',0}, DRIVE_CASE_PRESERVING },
    { { 0 }, 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;
}

#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')

extern void CDROM_InitRegistry(int dev, int id, const char *device);

/***********************************************************************
 *           DRIVE_GetDriveType
 */
static inline UINT DRIVE_GetDriveType( INT drive, LPCWSTR value )
{
    int i;

    for (i = 0; i < sizeof(DRIVE_Types)/sizeof(DRIVE_Types[0]); i++)
    {
        if (!strcmpiW( value, DRIVE_Types[i] )) return i;
    }
    MESSAGE("Drive %c: unknown drive type %s, defaulting to 'hd'.\n",
            'A' + drive, debugstr_w(value) );
    return DRIVE_FIXED;
}


/***********************************************************************
 *           DRIVE_GetFSFlags
 */
static UINT DRIVE_GetFSFlags( INT drive, LPCWSTR value )
{
    const FS_DESCR *descr;

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


/***********************************************************************
 *           DRIVE_Init
 */
int DRIVE_Init(void)
{
    int i, len, count = 0;
    WCHAR driveW[] = {'M','a','c','h','i','n','e','\\','S','o','f','t','w','a','r','e','\\',
                      'W','i','n','e','\\','W','i','n','e','\\',
                      'C','o','n','f','i','g','\\','D','r','i','v','e',' ','A',0};
    WCHAR drive_env[] = {'=','A',':',0};
    WCHAR path[MAX_PATHNAME_LEN];
    char tmp[MAX_PATHNAME_LEN*sizeof(WCHAR) + sizeof(KEY_VALUE_PARTIAL_INFORMATION)];
    struct stat drive_stat_buffer;
    WCHAR *p;
    DOSDRIVE *drive;
    HKEY hkey;
    DWORD dummy;
    OBJECT_ATTRIBUTES attr;
    UNICODE_STRING nameW;

    static const WCHAR PathW[] = {'P','a','t','h',0};
    static const WCHAR LabelW[] = {'L','a','b','e','l',0};
    static const WCHAR SerialW[] = {'S','e','r','i','a','l',0};
    static const WCHAR TypeW[] = {'T','y','p','e',0};
    static const WCHAR FilesystemW[] = {'F','i','l','e','s','y','s','t','e','m',0};
    static const WCHAR DeviceW[] = {'D','e','v','i','c','e',0};
    static const WCHAR ReadVolInfoW[] = {'R','e','a','d','V','o','l','I','n','f','o',0};
    static const WCHAR FailReadOnlyW[] = {'F','a','i','l','R','e','a','d','O','n','l','y',0};
    static const WCHAR driveC_labelW[] = {'D','r','i','v','e',' ','C',' ',' ',' ',' ',0};


    attr.Length = sizeof(attr);
    attr.RootDirectory = 0;
    attr.ObjectName = &nameW;
    attr.Attributes = 0;
    attr.SecurityDescriptor = NULL;
    attr.SecurityQualityOfService = NULL;

    for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
    {
        RtlInitUnicodeString( &nameW, driveW );
        nameW.Buffer[(nameW.Length / sizeof(WCHAR)) - 1] = 'A' + i;
        if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ) != STATUS_SUCCESS) continue;

        /* Get the root path */
        RtlInitUnicodeString( &nameW, PathW );
        if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
        {
            WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
            ExpandEnvironmentStringsW( data, path, sizeof(path)/sizeof(WCHAR) );

            p = path + strlenW(path) - 1;
            while ((p > path) && (*p == '/')) *p-- = '\0';

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

            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;
                goto next;
            }
            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;
                goto next;
            }

            drive->dos_cwd  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(drive->dos_cwd[0]));
            drive->unix_cwd = heap_strdup( "" );
            drive->device   = NULL;
            drive->flags    = 0;
            drive->dev      = drive_stat_buffer.st_dev;
            drive->ino      = drive_stat_buffer.st_ino;

            /* Get the drive type */
            RtlInitUnicodeString( &nameW, TypeW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                drive->type = DRIVE_GetDriveType( i, data );
            }
            else drive->type = DRIVE_FIXED;

            /* Get the drive label */
            RtlInitUnicodeString( &nameW, LabelW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                lstrcpynW( drive->label_conf, data, 12 );
            }
            if ((len = strlenW(drive->label_conf)) < 11)
            {
                /* Pad label with spaces */
                while(len < 11) drive->label_conf[len++] = ' ';
                drive->label_conf[11] = '\0';
            }

            /* Get the serial number */
            RtlInitUnicodeString( &nameW, SerialW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                drive->serial_conf = strtoulW( data, NULL, 16 );
            }
            else drive->serial_conf = 12345678;

            /* Get the filesystem type */
            RtlInitUnicodeString( &nameW, FilesystemW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                drive->flags = DRIVE_GetFSFlags( i, data );
            }
            else drive->flags = DRIVE_CASE_PRESERVING;

            /* Get the device */
            RtlInitUnicodeString( &nameW, DeviceW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                len = WideCharToMultiByte(CP_UNIXCP, 0, data, -1, NULL, 0, NULL, NULL);
                drive->device = HeapAlloc(GetProcessHeap(), 0, len);
                WideCharToMultiByte(CP_UNIXCP, 0, data, -1, drive->device, len, NULL, NULL);

                RtlInitUnicodeString( &nameW, ReadVolInfoW );
                if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
                {
                    WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                    if (IS_OPTION_TRUE(data[0])) drive->flags |= DRIVE_READ_VOL_INFO;
                }
                else drive->flags |= DRIVE_READ_VOL_INFO;

                if (drive->type == DRIVE_CDROM)
                {
                    int cd_fd;
                    if ((cd_fd = open(drive->device, O_RDONLY|O_NONBLOCK)) != -1)
                    {
                        CDROM_InitRegistry(cd_fd, i, drive->device);
                        close(cd_fd);
                    }
                }
            }

            /* Get the FailReadOnly flag */
            RtlInitUnicodeString( &nameW, FailReadOnlyW );
            if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
            {
                WCHAR *data = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
                if (IS_OPTION_TRUE(data[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("Drive %c: path=%s type=%s label=%s serial=%08lx "
                  "flags=%08x dev=%x ino=%x\n",
                  'A' + i, drive->root, debugstr_w(DRIVE_Types[drive->type]),
                  debugstr_w(drive->label_conf), drive->serial_conf, drive->flags,
                  (int)drive->dev, (int)drive->ino );
        }

    next:
        NtClose( hkey );
    }

    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  = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DOSDrives[2].dos_cwd[0]));
        DOSDrives[2].unix_cwd = heap_strdup( "" );
        strcpyW( DOSDrives[2].label_conf, driveC_labelW );
        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 (!GetEnvironmentVariableW(drive_env, path, MAX_PATHNAME_LEN)) continue;
        /* sanity check */
        if (toupperW(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 = GlobalLock16(GetCurrentTask());
    if (pTask && (pTask->curdrive & 0x80)) return pTask->curdrive & ~0x80;
    return DRIVE_CurDrive;
}


/***********************************************************************
 *           DRIVE_SetCurrentDrive
 */
int DRIVE_SetCurrentDrive( int drive )
{
    TDB *pTask = GlobalLock16(GetCurrentTask());
    if (!DRIVE_IsValid( drive ))
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }
    TRACE("%c:\n", 'A' + drive );
    DRIVE_CurDrive = drive;
    if (pTask) pTask->curdrive = drive | 0x80;
    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.
 *
 * Note: path must be in the encoding of the underlying Unix file system.
 */
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 );
    for (p = buffer; *p; p++) if (*p == '\\') *p = '/';
    len = p - 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_FindDriveRootW
 *
 * Unicode version of DRIVE_FindDriveRoot.
 */
int DRIVE_FindDriveRootW( LPCWSTR *path )
{
    int drive, level, len;
    WCHAR buffer[MAX_PATHNAME_LEN];
    WCHAR *p;
    struct stat st;

    strcpyW( buffer, *path );
    for (p = buffer; *p; p++) if (*p == '\\') *p = '/';
    len = p - buffer;

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

    for (;;)
    {
        char buffA[MAX_PATHNAME_LEN];

        WideCharToMultiByte( CP_UNIXCP, 0, buffer, -1, buffA, sizeof(buffA), NULL, NULL );
        if (stat( buffA, &st ) == 0 && S_ISDIR( st.st_mode ))
        {
            /* Find the drive */
            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))
                {
                    static const WCHAR rootW[] = {'\\',0};

                    if (len == 1) len = 0;  /* preserve root slash in returned path */
                    TRACE( "%s -> drive %c:, root=%s, name=%s\n",
                           debugstr_w(*path), 'A' + drive, debugstr_w(buffer), debugstr_w(*path + len));
                    *path += len;
                    if (!**path) *path = rootW;
                    return drive;
                }
            }
        }
        if (len <= 1) return -1;  /* reached root */

        level = 0;
        while (level < 1)
        {
            static const WCHAR dotW[] = {'.',0};
            static const WCHAR dotdotW[] = {'.','.',0};

            /* 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 (strcmpW( buffer + len, dotW ) != 0)
                level += strcmpW( buffer + len, dotdotW ) ? 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
 */
LPCWSTR DRIVE_GetDosCwd( int drive )
{
    TDB *pTask = GlobalLock16(GetCurrentTask());
    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 */
    {
        static const WCHAR rootW[] = {'\\',0};
        WCHAR curdirW[MAX_PATH];
        MultiByteToWideChar(CP_ACP, 0, pTask->curdir, -1, curdirW, MAX_PATH);
        /* Perform the task-switch */
        if (!DRIVE_Chdir( drive, curdirW )) DRIVE_Chdir( drive, rootW );
        DRIVE_LastTask = GetCurrentTask();
    }
    return DOSDrives[drive].dos_cwd;
}


/***********************************************************************
 *           DRIVE_GetUnixCwd
 */
const char * DRIVE_GetUnixCwd( int drive )
{
    TDB *pTask = GlobalLock16(GetCurrentTask());
    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 */
    {
        static const WCHAR rootW[] = {'\\',0};
        WCHAR curdirW[MAX_PATH];
        MultiByteToWideChar(CP_ACP, 0, pTask->curdir, -1, curdirW, MAX_PATH);
        /* Perform the task-switch */
        if (!DRIVE_Chdir( drive, curdirW )) DRIVE_Chdir( drive, rootW );
        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;
    struct stat stat_buf;

    memset(buff, 0, DRIVE_SUPER);
       /* O_NONBLOCK in case we're opening FIFO; will be reset later */
    if ((fd = open(DOSDrives[drive].device, O_RDONLY|O_NOCTTY|O_NONBLOCK)) != -1) {
	if (fstat(fd, &stat_buf) < 0) {	/* shouldn't happen since we just opened that file */
	    ERR("fstat() failed for opened device '%s' (drive %c:) ! IT SHOULDN'T HAPPEN !!!\n",
		DOSDrives[drive].device, 'A'+drive);
	    ret = -1;
	} else if (!S_ISBLK(stat_buf.st_mode)) {
	    ERR("Device '%s' (drive %c:) is not a block device - check your config\n",
		DOSDrives[drive].device, 'A'+drive);
	    ret = -1;
			/* reset O_NONBLOCK */
        } else if (fcntl(fd, F_SETFL, 0) < 0 || fcntl(fd, F_GETFL) & O_NONBLOCK) {
	    ERR("fcntl() failed to reset O_NONBLOCK for device '%s' (drive %c:)\n",
		DOSDrives[drive].device, 'A'+drive);
	    ret = -1;
	}
	if (ret) {
	    close(fd);
	    fd = -1;
	}
    } else {
	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, &stat_buf)) ?
			"not available or symlink not valid ?" : "no permission");
    }
    if (fd == -1) {
	ERR("Can't read drive volume info ! Either pre-set it or make sure the device to read it from is accessible !\n");
	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)
{
    WCHAR root[] = {'\\','\\','.','\\','A',':',0};
    root[4] += drive;
    return CreateFileW(root, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
}

/**************************************************************************
 *                              CDROM_Data_GetLabel             [internal]
 */
DWORD CDROM_Data_GetLabel(int drive, WCHAR *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);
                }
                strncpyW(label, label_read, 11);
                label[11] = 0;
            }
            else
            {
                MultiByteToWideChar(CP_UNIXCP, 0, (LPSTR)label_read, -1, label, 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, WCHAR *label)
{
    HANDLE              h;
    CDROM_DISK_DATA     cdd;
    DWORD               br, ret = 1;
    BOOL                r;

    h = CDROM_Open(drive);
    if( !h ) 
        return 0;
    r = DeviceIoControl(h, IOCTL_CDROM_DISK_TYPE, NULL, 
                        0, &cdd, sizeof(cdd), &br, 0);
    CloseHandle( h );
    if( !r )
        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:
    {
        static const WCHAR audioCD[] = {'A','u','d','i','o',' ','C','D',' ',' ',' ',0};
        strcpyW(label, audioCD);
        break;
    }
    case CDROM_DISK_DATA_TRACK|CDROM_DISK_AUDIO_TRACK:
        FIXME("Need to get the label of a mixed mode CD!\n");
	/* This assumes that the first track is a data track! */
	/* I guess the correct way would be to enumerate all data tracks
	   and check each for the title */
        if (!CDROM_Data_GetLabel(drive, label))
            ret = 0;
        break;
    case 0:
        ret = 0;
        break;
    }
    TRACE("CD: label is %s\n", debugstr_w(label));

    return ret;
}
/***********************************************************************
 *           DRIVE_GetLabel
 */
LPCWSTR 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)
                MultiByteToWideChar(CP_UNIXCP, 0, buff+offs, 11,
                                    DOSDrives[drive].label_read, 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];
        RTL_OSVERSIONINFOEXW 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(ovi);
        RtlGetVersion(&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_DISK_DATA     cdd;
    DWORD               br;
    BOOL                r;

    TRACE("%d\n", drive);

    h = CDROM_Open(drive);
    if( !h ) 
        return 0;
    r = DeviceIoControl(h, IOCTL_CDROM_DISK_TYPE, NULL, 
                        0, &cdd, sizeof(cdd), &br, 0);
    if (!r)
    {
        CloseHandle(h);
        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];

    TRACE("drive %d, type = %d\n", drive, DOSDrives[drive].type);

    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_NO_ROOT_DIR;
    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, LPCWSTR path )
{
    DOS_FULL_NAME full_name;
    WCHAR buffer[MAX_PATHNAME_LEN];
    LPSTR unix_cwd;
    BY_HANDLE_FILE_INFORMATION info;
    TDB *pTask = GlobalLock16(GetCurrentTask());

    buffer[0] = 'A' + drive;
    buffer[1] = ':';
    buffer[2] = 0;
    TRACE("(%s,%s)\n", debugstr_w(buffer), debugstr_w(path) );
    strncpyW( buffer + 2, path, MAX_PATHNAME_LEN - 2 );
    buffer[MAX_PATHNAME_LEN - 1] = 0; /* ensure 0 termination */

    if (!DOSFS_GetFullName( buffer, TRUE, &full_name )) return 0;
    if (!FILE_Stat( full_name.long_name, &info, NULL )) 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, debugstr_w(full_name.short_name + 3) );

    HeapFree( GetProcessHeap(), 0, DOSDrives[drive].dos_cwd );
    HeapFree( GetProcessHeap(), 0, DOSDrives[drive].unix_cwd );
    DOSDrives[drive].dos_cwd  = HeapAlloc(GetProcessHeap(), 0, (strlenW(full_name.short_name) - 2) * sizeof(WCHAR));
    strcpyW(DOSDrives[drive].dos_cwd, full_name.short_name + 3);
    DOSDrives[drive].unix_cwd = heap_strdup( unix_cwd );

    if (drive == DRIVE_CurDrive)
    {
        UNICODE_STRING dirW;

        RtlInitUnicodeString( &dirW, full_name.short_name );
        RtlSetCurrentDirectory_U( &dirW );
    }

    if (pTask && (pTask->curdrive & 0x80) &&
        ((pTask->curdrive & ~0x80) == drive))
    {
        WideCharToMultiByte(CP_ACP, 0, full_name.short_name + 2, -1,
                            pTask->curdir, sizeof(pTask->curdir), NULL, NULL);
        DRIVE_LastTask = GetCurrentTask();
    }
    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;
}


/***********************************************************************
 *           DefineDosDeviceA       (KERNEL32.@)
 */
BOOL WINAPI DefineDosDeviceA(DWORD flags,LPCSTR devname,LPCSTR targetpath)
{
    UNICODE_STRING d, t;
    BOOL           ret;

    if (!RtlCreateUnicodeStringFromAsciiz(&d, devname))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }
    if (!RtlCreateUnicodeStringFromAsciiz(&t, targetpath))
    {
        RtlFreeUnicodeString(&d);
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }
    ret = DefineDosDeviceW(flags, d.Buffer, t.Buffer);
    RtlFreeUnicodeString(&d);
    RtlFreeUnicodeString(&t);
    return ret;
}


/***********************************************************************
 *           DefineDosDeviceA       (KERNEL32.@)
 */
BOOL WINAPI DefineDosDeviceW(DWORD flags,LPCWSTR devname,LPCWSTR targetpath) 
{
    DOSDRIVE *old, *new;

    /* this is a temporary hack for int21 support. better implementation has to be done */
    if (flags != DDD_RAW_TARGET_PATH ||
        !(toupperW(devname[0]) >= 'A' && toupperW(devname[0]) <= 'Z') ||
        devname[1] != ':' || devname[2] != 0 ||
        !(toupperW(targetpath[0]) >= 'A' && toupperW(targetpath[0]) <= 'Z') ||
        targetpath[1] != ':' || targetpath[2] != '\\' || targetpath[3] != 0)
    {
        FIXME("(0x%08lx,%s,%s),stub!\n", flags, debugstr_w(devname), debugstr_w(targetpath));
        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
        return FALSE;
    }

    old = DOSDrives + devname[0] - 'A';
    new = DOSDrives + targetpath[0] - 'A';

    if (!old->root)
    {
        SetLastError( ERROR_INVALID_DRIVE );
        return 0;
    }

    if ( new->root )
    {
        TRACE("Can't map drive %c: to already existing drive %c:\n",
              devname[0], targetpath[0] );
	/* 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  = HeapAlloc(GetProcessHeap(), 0, (strlenW(old->dos_cwd) + 1) * sizeof(WCHAR));
    strcpyW(new->dos_cwd, 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",
          targetpath[0], devname[0] );

    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_GetFreeSpace
 */
static int DRIVE_GetFreeSpace( int drive, PULARGE_INTEGER size,
			       PULARGE_INTEGER available )
{
    struct statfs info;

    if (!DRIVE_IsValid(drive))
    {
        SetLastError( ERROR_PATH_NOT_FOUND );
        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 HAVE_STRUCT_STATFS_F_BAVAIL
    available->QuadPart = RtlEnlargedUnsignedMultiply( info.f_bavail, info.f_bsize );
#else
# ifdef HAVE_STRUCT_STATFS_F_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, LPWSTR buf )
{
    UINT ret;
    LPCWSTR dos_cwd = DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() );
    static const WCHAR driveA_rootW[] = {'A',':','\\',0};

    ret = strlenW(dos_cwd) + 3; /* length of WHOLE current directory */
    if (ret >= buflen) return ret + 1;

    strcpyW( buf, driveA_rootW );
    buf[0] += DRIVE_GetCurrentDrive();
    strcatW( buf, dos_cwd );
    return ret;
}


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

    for (i = 0; i < MAX_DOS_DRIVES; i++)
    {
        if ((cwd[i] = DRIVE_GetDosCwd(i)) && cwd[i][0])
            length += strlenW(cwd[i]) + 8;
    }
    if (!(env = HeapAlloc( GetProcessHeap(), 0, (length+1) * sizeof(WCHAR) ))) return NULL;
    for (i = 0, p = env; i < MAX_DOS_DRIVES; i++)
    {
        if (cwd[i] && cwd[i][0])
        {
            *p++ = '='; *p++ = 'A' + i; *p++ = ':';
            *p++ = '='; *p++ = 'A' + i; *p++ = ':'; *p++ = '\\';
            strcpyW( p, cwd[i] );
            p += strlenW(p) + 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 );
}


/***********************************************************************
 *           GetDiskFreeSpaceW   (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 GetDiskFreeSpaceW( LPCWSTR root, LPDWORD cluster_sectors,
                                   LPDWORD sector_bytes, LPDWORD free_clusters,
                                   LPDWORD total_clusters )
{
    int	drive, sec_size;
    ULARGE_INTEGER size,available;
    LPCWSTR path;
    DWORD cluster_sec;

    TRACE("%s,%p,%p,%p,%p\n", debugstr_w(root), cluster_sectors, sector_bytes,
          free_clusters, total_clusters);

    if (!root || root[0] == '\\' || root[0] == '/')
	drive = DRIVE_GetCurrentDrive();
    else
    if (root[0] && root[1] == ':') /* root contains drive tag */
    {
        drive = toupperW(root[0]) - 'A';
	path = &root[2];
	if (path[0] == '\0')
        {
	    path = DRIVE_GetDosCwd(drive);
            if (!path)
            {
                SetLastError(ERROR_PATH_NOT_FOUND);
                return FALSE;
            }
        }
	else
	if (path[0] == '\\')
	    path++;

        if (path[0]) /* oops, we are in a subdir */
        {
            SetLastError(ERROR_INVALID_NAME);
            return FALSE;
        }
    }
    else
    {
        if (!root[0])
            SetLastError(ERROR_PATH_NOT_FOUND);
        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;
}


/***********************************************************************
 *           GetDiskFreeSpaceA   (KERNEL32.@)
 */
BOOL WINAPI GetDiskFreeSpaceA( LPCSTR root, LPDWORD cluster_sectors,
                                   LPDWORD sector_bytes, LPDWORD free_clusters,
                                   LPDWORD total_clusters )
{
    UNICODE_STRING rootW;
    BOOL ret = FALSE;

    if (root)
    {
        if(!RtlCreateUnicodeStringFromAsciiz(&rootW, root))
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
    }
    else
        rootW.Buffer = NULL;

    ret = GetDiskFreeSpaceW(rootW.Buffer, cluster_sectors, sector_bytes,
                            free_clusters, total_clusters );
    RtlFreeUnicodeString(&rootW);

    return ret;
}


/***********************************************************************
 *           GetDiskFreeSpaceExW   (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 GetDiskFreeSpaceExW( LPCWSTR 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", debugstr_w(root));
            return FALSE;
        }
        drive = toupperW(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. */

            RTL_OSVERSIONINFOEXW ovi;
	    ovi.dwOSVersionInfoSize = sizeof(ovi);
	    if (RtlGetVersion(&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;
}

/***********************************************************************
 *           GetDiskFreeSpaceExA   (KERNEL32.@)
 */
BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root, PULARGE_INTEGER avail,
				     PULARGE_INTEGER total,
				     PULARGE_INTEGER  totalfree)
{
    UNICODE_STRING rootW;
    BOOL ret;

    if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
    else rootW.Buffer = NULL;

    ret = GetDiskFreeSpaceExW( rootW.Buffer, avail, total, totalfree);

    RtlFreeUnicodeString(&rootW);
    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;
}


/***********************************************************************
 *           GetDriveTypeW   (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 GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
{
    int drive;
    TRACE("(%s)\n", debugstr_w(root));

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


/***********************************************************************
 *           GetDriveTypeA   (KERNEL32.@)
 */
UINT WINAPI GetDriveTypeA( LPCSTR root )
{
    UNICODE_STRING rootW;
    UINT ret = 0;

    if (root)
    {
        if( !RtlCreateUnicodeStringFromAsciiz(&rootW, root))
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return 0;
        }
    }
    else
        rootW.Buffer = NULL;

    ret = GetDriveTypeW(rootW.Buffer);

    RtlFreeUnicodeString(&rootW);
    return ret;

}


/***********************************************************************
 *           GetCurrentDirectory   (KERNEL.411)
 */
UINT16 WINAPI GetCurrentDirectory16( UINT16 buflen, LPSTR buf )
{
    WCHAR cur_dirW[MAX_PATH];

    DRIVE_GetCurrentDirectory(MAX_PATH, cur_dirW);
    return (UINT16)WideCharToMultiByte(CP_ACP, 0, cur_dirW, -1, buf, buflen, NULL, NULL);
}


/***********************************************************************
 *           GetCurrentDirectoryW   (KERNEL32.@)
 */
UINT WINAPI GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
{
    UINT ret;
    WCHAR longname[MAX_PATHNAME_LEN];
    WCHAR 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;
    }
    GetLongPathNameW(shortname, longname, MAX_PATHNAME_LEN);
    ret = strlenW( longname ) + 1;
    if (ret > buflen) return ret;
    strcpyW(buf, longname);
    return ret - 1;
}

/***********************************************************************
 *           GetCurrentDirectoryA   (KERNEL32.@)
 */
UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf )
{
    WCHAR bufferW[MAX_PATH];
    DWORD ret, retW;

    retW = GetCurrentDirectoryW(MAX_PATH, bufferW);

    if (!retW)
        ret = 0;
    else if (retW > MAX_PATH)
    {
        SetLastError(ERROR_FILENAME_EXCED_RANGE);
        ret = 0;
    }
    else
    {
        ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
        if (buflen >= ret)
        {
            WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buf, buflen, NULL, NULL);
            ret--; /* length without 0 */
        }
    }
    return ret;
}


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


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

    if (!dir)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
	return FALSE;
    }
    if (dir[0] && (dir[1]==':'))
    {
        drive = toupperW( *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;
}


/***********************************************************************
 *           SetCurrentDirectoryA   (KERNEL32.@)
 */
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
{
    UNICODE_STRING dirW;
    BOOL ret = FALSE;

    if (!dir)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
	return FALSE;
    }

    if (RtlCreateUnicodeStringFromAsciiz(&dirW, dir))
    {
        ret = SetCurrentDirectoryW(dirW.Buffer);
        RtlFreeUnicodeString(&dirW);
    }
    else
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    return ret;
}


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


/***********************************************************************
 *           GetVolumeInformationW   (KERNEL32.@)
 */
BOOL WINAPI GetVolumeInformationW( LPCWSTR root, LPWSTR label,
                                       DWORD label_len, DWORD *serial,
                                       DWORD *filename_len, DWORD *flags,
                                       LPWSTR fsname, DWORD fsname_len )
{
    int drive;
    LPWSTR cp;

    /* FIXME, SetLastError()s missing */

    if (!root) drive = DRIVE_GetCurrentDrive();
    else
    {
        if (root[0] && root[1] != ':')
        {
            WARN("invalid root %s\n", debugstr_w(root));
            return FALSE;
        }
        drive = toupperW(root[0]) - 'A';
    }
    if (!DRIVE_IsValid( drive )) return FALSE;
    if (label && label_len)
    {
       strncpyW( label, DRIVE_GetLabel(drive), label_len );
       label[label_len - 1] = 0; /* ensure 0 termination */
       cp = label + strlenW(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 && fsname_len)
    {
    	/* Diablo checks that return code ... */
        if (DOSDrives[drive].type == DRIVE_CDROM)
        {
            static const WCHAR cdfsW[] = {'C','D','F','S',0};
            strncpyW( fsname, cdfsW, fsname_len );
        }
	else
        {
            static const WCHAR fatW[] = {'F','A','T',0};
            strncpyW( fsname, fatW, fsname_len );
        }
        fsname[fsname_len - 1] = 0; /* ensure 0 termination */
    }
    return TRUE;
}


/***********************************************************************
 *           GetVolumeInformationA   (KERNEL32.@)
 */
BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label,
                                       DWORD label_len, DWORD *serial,
                                       DWORD *filename_len, DWORD *flags,
                                       LPSTR fsname, DWORD fsname_len )
{
    UNICODE_STRING rootW;
    LPWSTR labelW, fsnameW;
    BOOL ret;

    if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
    else rootW.Buffer = NULL;
    labelW = label ? HeapAlloc(GetProcessHeap(), 0, label_len * sizeof(WCHAR)) : NULL;
    fsnameW = fsname ? HeapAlloc(GetProcessHeap(), 0, fsname_len * sizeof(WCHAR)) : NULL;

    if ((ret = GetVolumeInformationW(rootW.Buffer, labelW, label_len, serial,
                                    filename_len, flags, fsnameW, fsname_len)))
    {
        if (label) WideCharToMultiByte(CP_ACP, 0, labelW, -1, label, label_len, NULL, NULL);
        if (fsname) WideCharToMultiByte(CP_ACP, 0, fsnameW, -1, fsname, fsname_len, NULL, NULL);
    }

    RtlFreeUnicodeString(&rootW);
    if (labelW) HeapFree( GetProcessHeap(), 0, labelW );
    if (fsnameW) HeapFree( GetProcessHeap(), 0, fsnameW );
    return ret;
}

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

    /* FIXME, SetLastErrors missing */

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

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

    strncpyW(DOSDrives[drive].label_conf, volname, 12);
    DOSDrives[drive].label_conf[12 - 1] = 0; /* ensure 0 termination */
    return TRUE;
}

/***********************************************************************
 *           SetVolumeLabelA   (KERNEL32.@)
 */
BOOL WINAPI SetVolumeLabelA(LPCSTR root, LPCSTR volname)
{
    UNICODE_STRING rootW, volnameW;
    BOOL ret;

    if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
    else rootW.Buffer = NULL;
    if (volname) RtlCreateUnicodeStringFromAsciiz(&volnameW, volname);
    else volnameW.Buffer = NULL;

    ret = SetVolumeLabelW( rootW.Buffer, volnameW.Buffer );

    RtlFreeUnicodeString(&rootW);
    RtlFreeUnicodeString(&volnameW);
    return ret;
}

/***********************************************************************
 *           GetVolumeNameForVolumeMountPointW   (KERNEL32.@)
 */
BOOL WINAPI GetVolumeNameForVolumeMountPointW(LPCWSTR str, LPWSTR dst, DWORD size)
{
    FIXME("(%s, %p, %lx): stub\n", debugstr_w(str), dst, size);
    return 0;
}
