I've been working lately on rehauling the file handling in Wine.

The current output is a large patch, available here: http://perso.wanadoo.fr/pouech-eric/ep-file.diff.gz (400 KB uncompressed)

It's not completly ready yet for inclusion, however some ongoing discussions could overlap with what I've currently done (like how to configure drive without a config file, SMB handling...). So better discuss it widely (yet another flame war).

The benefit of the patch:
- all file creation, opening, directory browsing is now done in ntdll instead of kernel32
- file IO management can be cleanly separated between kernel32 and ntdll (1)
- files/ directory could be removed (not done in the patch (also nuked include/drive.h and include/file.h)
- homogenous drive & device handling (we no longer store those objects in the server). Drive and device are now standard file handles (from a Windows point of view).
- a few current Wine bugs have been fixed (see the todo_wine removed in the tests subdirs)
- we no longer rely on the Wine config dir for the drive settings
- partial NT volume management implementation
- most of the volume related information (& ioctl) are done on the real unix device attached to the volume


What has been removed (from current implementation):
- file system options (all FS are considered case insensitive)
- per drive code page (all drives are now handled with the wine specfic UNIXCP code page)


What still need some improvement
- fix all the introduced bugs (even if all the current tests actually pass)
- setting a first default environment (even if tools/winefs provides it - see below)


Drives (and all their attributes - mount points, labels...) are defined this way:

1 Volumes & drives
------------------

Every volume on each available volume (partition on a physical disk) on the system will be listed in
${WINEPREFIX}/device directory. This directory will also be populated by other needed devices (serial, parallel, physical disks). Each item in this devices list will be stored as a subdirectory of ${WINEPREFIX}/device. Each subdirectory will contain various files &
symlinks related to this device.
Every volume will be named volume{XXX} where XXX is the actual unix
device name. We're using this syntax so that we can distinguish from
other (non-volume) devices and because under windows, volumes are
named as Volume{<UID>} where <UID> is the unique identifier of the
volume.


Every DOS drive letter will be known from a (directory) entry in
${WINEPREFIX}/dosdevices. This directory will also contains entries
for VxDs. A drive letter entry will in fact be a symlink to
$WINEPREFIX/device/volume{XXX}/mount. This later will be another
symlink to the actual mount point of volume XXX.
This double indirection is needed: a DOS drive can be mounted either
at the root of a volume, or as a subdirectory on that volume. The
first symlink (in the dosdevices directory) will point to subdirectory
we want to mount on, and the second will hold where the volume itself
is mounted.

For convenience reasons, we also list, for every DOS drive, the volume
on which it is mounted, by creating a symlink between
${WINEPREFIX}/device/x: and ${WINEPREFIX}/device/volume{XXX}

2 Example
---------
Unix side:
/dev/scd0 on /mnt/cdrom
/dev/fd0  on /mnt/floppy
/dev/hda1 on /mnt/ntfs
/dev/hda5 on /mnt/windows
/dev/hda6 on /
/dev/hda8 on /opt
/dev/hda9 on /home

Note, from now on, all paths are relative to ${WINEPREFIX}
From this, we will define this hierarchy:
device/
        volume{fd0}/
                device -> /dev/fd0
                mount -> /mnt/floppy/
        volume{hda1}/
                device -> /dev/hda1
                mount -> /mnt/ntfs/
        volume{hda5}/
                device -> /dev/hda5
                mount -> /mnt/windows/
        volume{hda6}/
                device -> /dev/hda6
                mount -> /
        volume{hda8}/
                device -> /dev/hda8
                mount -> /opt/
        volume{hda9}/
                device -> /dev/hda9
                mount -> /home/
        volume{scd0}/
                device -> /dev/scd0
                mount -> /mnt/cdrom/
This hierarchy doesn't depend on what's actually mounted (both on unix
side and windows side), it's just the volume definition.

We also define a few more disks related entries:
device/
        harddisk0/
                device -> /dev/hda
and some other devices as well:
device/
        null/
                device -> /dev/null
        parallel0/
                device -> /dev/lp0
        serial0/
                device -> /dev/ttyS0

Now, assume we want to define our DOS drives as follow:
a: -> /mnt/fd0/
c: -> /home/eric/.wine/c_copy/
d: -> /opt/winapps/
e: -> /mnt/cdrom/
f: -> /tmp
g: -> /home/eric/
m: -> /mnt/windows/

We will create two new symlinks per drive: one in $WINEPREFIX/device
which will point to the device of the volume, another one in
$WINEPREFIX/dosdevices which will point to the unix root we want for
the drive.

device/
        a: -> volume{fd0}
        c: -> volume{hda9}
        d: -> volume{hda8}
        e: -> volume{scd0}
        f: -> volume{hda6}
        g: -> volume{hda9}
        m: -> volume{hda5}
dosdevices/
        a: -> ../device/volume{fd0}/mount/
        c: -> ../device/volume{hda9}/mount/eric/.wine/c_copy/
        d: -> ../device/volume{hda8}/mount/winapps/
        e: -> ../device/volume{scd0}/mount/
        f: -> ../device/volume{hda6}/mount/tmp/
        g: -> ../device/volume{hda9}/mount/eric/
        m: -> ../device/volume{hda5}/mount/

We also define some more DOS devices (for the other devices we
defined):
dosdevices/
        com1 -> ../device/serial0/device
        lpt1 -> ../device/parallel0/device
        nul -> ../device/null/device
        physicaldrive0 -> ../device/harddisk0/device

3 More details on volumes
-------------------------

In a volume subdirectory in ${WINEPREFIX}/volume{XXX} we can also find
some other files used for:
- getting volume label. We try to get information in the following order:
1/ read it from device (done for disks with FAT partition,
and AUDIO or data CDROM - mixed mode is not supported)
2/ if 1/ fails, read the file .windows-label at (unix) root
of volume (handy for hard, floppy disks)
3/ if 2/ fails, read the file label from the file
${WINEPREFIX}/device/volume{XXX}/label
- getting volume serial number. We try to get information in the following order:
1/ read it from device (done for disks with FAT partition,
and CDROMs)
2/ if 1/ fails, read the file .windows-serial at (unix) root
of volume (handy for hard, floppy disks)
3/ if 2/ fails, read the file label from the file
${WINEPREFIX}/device/volume{XXX}/serial
- some specific attributes are stored in
${WINEPREFIX}/device/volume{XXX}/flags. This file stores an
unsigned value, which high word is the device characteristics, while
its low word is the device type (from include/winioctl.h
FILE_DEVICE_????).


The VxDs and TSRs will be defined as an empty file (which name is VxD
or TSR name) in ${WINEPREFIX}/dosdevices.

Every filename will be case insensitive (device, VxD, TSR...) as we
always do case insensitive matching.

4 Example of the full configuration
-----------------------------------

-> is a symlink to
<> contains

device/
        a: -> volume{fd0}
        c: -> volume{hda9}
        d: -> volume{hda8}
        e: -> volume{scd0}
        f: -> volume{hda6}
        g: -> volume{hda9}
        harddisk0/
                device -> /dev/hda
        m: -> volume{hda5}
        null/
                device -> /dev/null
        parallel0/
                device -> /dev/lp0
        serial0/
                device -> /dev/ttyS0
        volume{fd0}/
                device -> /dev/fd0
                flags <> FILE_DEVICE_DISK + FILE_REMOVABLE_MEDIA|FILE_FLOPPY_DISKETTE
                mount -> /mnt/floppy/
        volume{hda1}/
                device -> /dev/hda1
                flags <> FILE_DEVICE_DISK
                mount -> /mnt/ntfs/
        volume{hda5}/
                device -> /dev/hda5
                flags <> FILE_DEVICE_DISK
                label <> VolumeC
                mount -> /mnt/windows/
        volume{hda6}/
                device -> /dev/hda6
                flags <> FILE_DEVICE_DISK
                mount -> /
        volume{hda8}/
                device -> /dev/hda8
                flags <> FILE_DEVICE_DISK
                mount -> /opt/
        volume{hda9}/
                device -> /dev/hda9
                flags <> FILE_DEVICE_DISK
                mount -> /home/
        volume{scd0}/
                device -> /dev/scd0
                flags <> FILE_DEVICE_CD_ROM + 
FILE_READ_ONLY_DEVICE|FILE_REMOVABLE_DEVICE
                mount -> /mnt/cdrom/
dosdevices/
        a: -> ../device/volume{fd0}/mount/
        afilter
        awredir
        aux -> ../dosdevices/com1
        bios
        bios_ext
        bioshook
        biosxlat
        blockdev
        c: -> ../device/volume{hda9}/mount/eric/.wine/standalone/c_copy/
        chbios
        com1 -> ../device/serial0/device
        configmg
        d: -> ../device/volume{hda8}/mount/winapps/
        debug
        debugcmd
        dosmgr
        dosnet
        dragcli
        dragsrv
        dsvxd
        dwcfgmg
        e: -> ../device/volume{scd0}/mount/
        ebios
        efax
        efilter
        eisa
        emmxxxx0
        enable
        eten
        f: -> ../device/volume{hda6}/mount/tmp/
        ffilter
        filesec
        g: -> ../device/volume{hda9}/mount/eric/
        hasp95
        hpscan
        ifsmgr
        int13
        irlamp
        isapnp
        logger
        lpt1 -> ../device/parallel0/device
        m: -> ../device/volume{hda5}/mount/
        mca_pos
        memprobe
        mmdevldr
        monodebg.vxd
        mrci2
        msodisup
        ndis
        ndis2sup
        nscl
        nul -> ../device/null/device
        nwlink
        nwredir
        nwserver
        nwsup
        pagefile
        pageswap
        parity
        pccard
        pci
        peloader
        perf
        physicaldrive0 -> ../device/harddisk0/device
        ppp
        reboot
        scsi
        scsifd
        scsimgr$
        scsiport
        secprov
        server
        shell
        splitter
        spooler
        stat80
        tfilter
        tsrload
        v86mmgr
        vasync
        vbrowse
        vcache
        vcd
        vcdfsd
        vcomm
        vcond
        vdd
        vdd2
        vdhcp
        vdmad
        vfat
        vfbackup
        vfd
        vhbiosd
        vime
        vip
        vkd20
        vmcpd
        vmd
        vmm
        vmpoll
        vmsgd
        vnb
        vnbt
        vnetbios
        vnetsup
        vnwlink
        vpd
        vpend
        vpicd
        vpowerd
        vppid
        vprod
        vredir
        vsd
        vshare
        vtcp
        vtd
        vtdapi
        vtdi
        vudp
        vwin32
        vxdldr
        win32s
        windebug
        winload
        winsock
        wsipx
        wsock
        wstcp

5 Configuration
---------------
All this configuration is done automatically by a new tool: tools/winefs.
This tool :
a/ creates (in all cases) from the /etc/fstab entries (and the known VxD and TSR) all possible entries in ~/.wine/device and ~/.wine/dosdevice
b/ will try to define the DOS drives depending on various sources


You can run it in several fashions:
1/ winefs ~/.wine
Will get all possible information from the current ~/.wine/config for Wine drive settings (mount points, device, labels, serial number...)
2/ winefs ~/.wine --bios-assign
Will do as previously, but creating the DOS drive assignments as the BIOS would do
3/ winefs ~/.wine --no-assign
Will only provide step a/
Beware, rerunning winefs will erase all your previous settings.


Have fun !!
A+

(1): not entirely true in this patch => the volume management (even if most of the code exists in ntdll) doesn't work as expected from ntdll. So the current kernel32 implementation remains




Reply via email to