Comment on new file implementation
Eric Pouech
pouech-eric at wanadoo.fr
Tue Jan 6 15:25:16 CST 2004
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
More information about the wine-devel
mailing list