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