mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 19:54:06 +00:00
Get rid of the Filesystem option in the drive config, this was more
confusing than useful.
This commit is contained in:
parent
f8c24212ae
commit
00777ec914
|
@ -327,16 +327,6 @@
|
||||||
<entry>yes</entry>
|
<entry>yes</entry>
|
||||||
<entry>General settings for Wine</entry>
|
<entry>General settings for Wine</entry>
|
||||||
</row>
|
</row>
|
||||||
<row>
|
|
||||||
<entry>[DllDefaults]</entry>
|
|
||||||
<entry>recmd</entry>
|
|
||||||
<entry>Defaults for loading DLL's</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
|
||||||
<entry>[DllPairs]</entry>
|
|
||||||
<entry>recmd</entry>
|
|
||||||
<entry>Sanity checkers for DLL's</entry>
|
|
||||||
</row>
|
|
||||||
<row>
|
<row>
|
||||||
<entry>[DllOverrides]</entry>
|
<entry>[DllOverrides]</entry>
|
||||||
<entry>recmd</entry>
|
<entry>recmd</entry>
|
||||||
|
@ -503,34 +493,6 @@
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
<sect3 id="config-dlldefaults">
|
|
||||||
<title>The [DllDefaults] Section</title>
|
|
||||||
<para>
|
|
||||||
These settings provide wine's default handling of DLL loading.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<programlisting>"DefaultLoadOrder" =" native, builtin"</programlisting>
|
|
||||||
This setting is a comma-delimited list of the order in
|
|
||||||
which to attempt loading DLLs. If the first option fails,
|
|
||||||
it will try the second, and so on. The order specified
|
|
||||||
above is probably the best in most conditions.
|
|
||||||
</para>
|
|
||||||
</sect3>
|
|
||||||
|
|
||||||
<sect3>
|
|
||||||
<title>The [DllPairs] Section</title>
|
|
||||||
<para>
|
|
||||||
At one time, there was a section called [DllPairs] in the
|
|
||||||
default configuration file, but this has been obsoleted
|
|
||||||
because the pairing information has now been embedded into
|
|
||||||
Wine itself. (The purpose of this section was merely to be
|
|
||||||
able to issue warnings if the user attempted to pair
|
|
||||||
codependent 16-bit/32-bit DLLs of different types.) If you
|
|
||||||
still have this in your <filename>~/.wine/.config</filename> or
|
|
||||||
<filename>wine.conf</filename>, you may safely delete it.
|
|
||||||
</para>
|
|
||||||
</sect3>
|
|
||||||
|
|
||||||
<sect3 id="config-dlloverrides">
|
<sect3 id="config-dlloverrides">
|
||||||
<title>The [DllOverrides] Section</title>
|
<title>The [DllOverrides] Section</title>
|
||||||
<para>
|
<para>
|
||||||
|
@ -982,20 +944,13 @@
|
||||||
[Drive C]
|
[Drive C]
|
||||||
"Path" = "%HOME%/wine"
|
"Path" = "%HOME%/wine"
|
||||||
"Type" = "hd"
|
"Type" = "hd"
|
||||||
"Label" = "MS-DOS"
|
|
||||||
"Filesystem" = "win95"
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
With this configuration, what windows apps think of as
|
With this configuration, what windows apps think of as
|
||||||
"c:\windows\system" would map to
|
"c:\windows\system" would map to
|
||||||
<filename>/home/user/wine/windows/system</filename> in the UNIX
|
<filename>/home/user/wine/windows/system</filename> in the UNIX
|
||||||
filesystem. Note that you need to specify
|
filesystem.
|
||||||
<literal>"Filesystem" = "win95"</literal>,
|
|
||||||
<emphasis>not</emphasis>
|
|
||||||
<literal>"Filesystem" = "unix"</literal>, to make Wine simulate a
|
|
||||||
Windows compatible (case insensitive) filesystem, otherwise
|
|
||||||
most apps won't work.
|
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
|
@ -1082,79 +1037,6 @@ C:\ Root directory of primary disk drive
|
||||||
exported over the network via NFS and thus can have slow response
|
exported over the network via NFS and thus can have slow response
|
||||||
times.
|
times.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
|
||||||
<programlisting>"Label" = "blah"</programlisting>
|
|
||||||
Defines the drive label. Generally only needed
|
|
||||||
for programs that look for a special CD-ROM.
|
|
||||||
The label may be up to 11 characters.
|
|
||||||
Note that the preferred way of managing labels and serial numbers
|
|
||||||
of CD-ROMs and floppies is to give Wine raw device access for
|
|
||||||
reading these on a per-CD case (see "Device" below) instead of
|
|
||||||
hardcoding one specific "Label".
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<programlisting>"Serial" = "deadbeef"</programlisting>
|
|
||||||
Tells Wine the serial number of the drive. A few programs with
|
|
||||||
intense protection for pirating might need this, but otherwise
|
|
||||||
it's not needed. Up to 8 characters and hexadecimal.
|
|
||||||
Using a "Device" entry instead of hardcoding the "Serial" probably
|
|
||||||
is a smarter choice.
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
<programlisting>"Filesystem" = "win95|unix|msdos"</programlisting>
|
|
||||||
Sets up the way Wine looks at files on the drive.
|
|
||||||
This setting controls the file name lookup and mapping of
|
|
||||||
Wine to existing file systems on your PC, it does
|
|
||||||
<emphasis>not</emphasis> tell anything about the filesystem
|
|
||||||
used itself.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<variablelist>
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>win95</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Case insensitive. Alike to Windows 9x/NT 4. This is
|
|
||||||
the long filename filesystem you are probably used
|
|
||||||
to working with. The filesystem behavior of choice for most
|
|
||||||
programs to be run under wine. <emphasis>Probably the one
|
|
||||||
you want!</emphasis>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>unix</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Case sensitive. This filesystem has almost no use
|
|
||||||
(Windows apps expect case insensitive filenames),
|
|
||||||
except maybe for Winelib applications.
|
|
||||||
Try it if you dare, but win95 is a much better
|
|
||||||
and always recommended choice.
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
<varlistentry>
|
|
||||||
<term><literal>msdos</literal></term>
|
|
||||||
<listitem>
|
|
||||||
<para>
|
|
||||||
Case insensitive filesystem. Alike to DOS and
|
|
||||||
Windows 3.x. <literal>8.3</literal> is the maximum
|
|
||||||
length of files (eightdot.123) - longer ones will be
|
|
||||||
truncated.
|
|
||||||
<note>
|
|
||||||
<para>
|
|
||||||
This is a <emphasis>very bad choice</emphasis> if
|
|
||||||
you plan on running apps that use long filenames.
|
|
||||||
win95 should work fine with apps that were designed
|
|
||||||
to run under the msdos system. In other words, you
|
|
||||||
might not want to use this.
|
|
||||||
</para>
|
|
||||||
</note>
|
|
||||||
</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
|
||||||
|
|
||||||
<programlisting>"Device" = "/dev/xx"</programlisting>
|
<programlisting>"Device" = "/dev/xx"</programlisting>
|
||||||
<para>
|
<para>
|
||||||
|
@ -1184,22 +1066,15 @@ Here is a setup for Drive C, a generic hard drive:
|
||||||
[Drive C]
|
[Drive C]
|
||||||
"Path" = "/dosc"
|
"Path" = "/dosc"
|
||||||
"Type" = "hd"
|
"Type" = "hd"
|
||||||
"Label" = "Hard Drive"
|
|
||||||
"Filesystem" = "win95"
|
|
||||||
This is a setup for Drive E, a generic CD-ROM drive:
|
This is a setup for Drive E, a generic CD-ROM drive:
|
||||||
[Drive E]
|
[Drive E]
|
||||||
"Path" = "/mnt/cdrom"
|
"Path" = "/mnt/cdrom"
|
||||||
"Type" = "cdrom"
|
"Type" = "cdrom"
|
||||||
"Label" = "Total Annihilation"
|
|
||||||
"Filesystem" = "win95"
|
|
||||||
"Device" = "/dev/cdrom"
|
"Device" = "/dev/cdrom"
|
||||||
And here is a setup for Drive A, a generic floppy drive:
|
And here is a setup for Drive A, a generic floppy drive:
|
||||||
[Drive A]
|
[Drive A]
|
||||||
"Type" = "floppy"
|
"Type" = "floppy"
|
||||||
"Path" = "/mnt/floppy"
|
"Path" = "/mnt/floppy"
|
||||||
"Label" = "Floppy Drive"
|
|
||||||
"Serial" = "87654321"
|
|
||||||
"Filesystem" = "win95"
|
|
||||||
"Device" = "/dev/fd0"
|
"Device" = "/dev/fd0"
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
@ -1391,8 +1266,6 @@ And here is a setup for Drive A, a generic floppy drive:
|
||||||
The directory to be used for emulating a C: drive will be
|
The directory to be used for emulating a C: drive will be
|
||||||
the base directory for some Windows specific directories
|
the base directory for some Windows specific directories
|
||||||
created below.
|
created below.
|
||||||
Remember to use
|
|
||||||
<userinput>"Filesystem" = "win95"</userinput>!
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -1794,55 +1667,30 @@ And here is a setup for Drive A, a generic floppy drive:
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
If you don't want to read labels and serial numbers directly from
|
If you don't want to read labels and serial numbers directly from
|
||||||
the device, then you should give fixed
|
the device, you can create files at the root of the drive
|
||||||
<literal>"Label" =</literal> or <literal>"Serial" =</literal>
|
named <filename>.windows-label</filename> and
|
||||||
entries in <filename>~/.wine/config</filename>, as Wine returns
|
<filename>.windows-serial</filename> respectively. These are
|
||||||
these entries instead if no device is given. If they don't
|
simple ASCII files that you can create with any text editor;
|
||||||
exist, then Wine will return default values (label
|
the label can be set to any string you like, the serial
|
||||||
<literal>Drive X</literal> and serial
|
number should be expressed as an hexadecimal number.
|
||||||
<literal>12345678</literal>).
|
|
||||||
</para>
|
|
||||||
<para>
|
|
||||||
If you want to give a <literal>"Device" =</literal> entry
|
|
||||||
<emphasis>only</emphasis> for drive raw sector accesses,
|
|
||||||
but not for reading the volume info from the device (i.e. you want
|
|
||||||
a <emphasis>fixed</emphasis>, preconfigured label), you need
|
|
||||||
to specify <literal>"ReadVolInfo" = "0"</literal> to tell Wine
|
|
||||||
to skip the volume reading.
|
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
<sect3>
|
<sect3>
|
||||||
<title>Examples</title>
|
<title>Examples</title>
|
||||||
<para>
|
<para>
|
||||||
Here's a simple example of CD-ROM and floppy; labels will be
|
Here's a simple example of CD-ROM and floppy:
|
||||||
read from the device on both CD-ROM and floppy; serial
|
|
||||||
numbers on floppy only:
|
|
||||||
</para>
|
</para>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
[Drive A]
|
[Drive A]
|
||||||
"Path" = "/mnt/floppy"
|
"Path" = "/mnt/floppy"
|
||||||
"Type" = "floppy"
|
"Type" = "floppy"
|
||||||
"Device" = "/dev/fd0"
|
"Device" = "/dev/fd0"
|
||||||
"Filesystem" = "msdos"
|
|
||||||
|
|
||||||
[Drive R]
|
[Drive R]
|
||||||
"Path" = "/mnt/cdrom"
|
"Path" = "/mnt/cdrom"
|
||||||
"Type" = "cdrom"
|
"Type" = "cdrom"
|
||||||
"Device" = "/dev/hda1"
|
"Device" = "/dev/hda1"
|
||||||
"Filesystem" = "win95"
|
|
||||||
</programlisting>
|
|
||||||
<para>
|
|
||||||
Here's an example of overriding the CD-ROM label:
|
|
||||||
</para>
|
|
||||||
<programlisting>
|
|
||||||
[Drive J]
|
|
||||||
"Path" = "/mnt/cdrom"
|
|
||||||
"Type" = "cdrom"
|
|
||||||
"Label" = "X234GCDSE"
|
|
||||||
; note that the device isn't really needed here as we have a fixed label
|
|
||||||
"Device" = "/dev/cdrom"
|
|
||||||
"Filesystem" = "msdos"
|
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
|
@ -1853,19 +1701,10 @@ And here is a setup for Drive A, a generic floppy drive:
|
||||||
The CD-ROM label can be read only if the data track of
|
The CD-ROM label can be read only if the data track of
|
||||||
the disk resides in the first track and the cdrom is
|
the disk resides in the first track and the cdrom is
|
||||||
iso9660.
|
iso9660.
|
||||||
</para> </listitem>
|
|
||||||
<listitem> <para>
|
|
||||||
Better checking for FAT superblock (it now checks only
|
|
||||||
one byte). </para>
|
|
||||||
</listitem>
|
|
||||||
<listitem> <para>
|
<listitem> <para>
|
||||||
Support for labels/serial nums WRITING.
|
Support for labels/serial nums WRITING.
|
||||||
</para> </listitem>
|
</para> </listitem>
|
||||||
<listitem> <para>
|
<listitem> <para>
|
||||||
Can the label be longer than 11 chars? (iso9660 has 32
|
|
||||||
chars).
|
|
||||||
</para> </listitem>
|
|
||||||
<listitem> <para>
|
|
||||||
What about reading ext2 volume label? ....
|
What about reading ext2 volume label? ....
|
||||||
</para> </listitem>
|
</para> </listitem>
|
||||||
</itemizedlist>
|
</itemizedlist>
|
||||||
|
|
|
@ -11,47 +11,34 @@ WINE REGISTRY Version 2
|
||||||
;; [Drive X]
|
;; [Drive X]
|
||||||
;; "Path"="xxx" (Unix path for drive root)
|
;; "Path"="xxx" (Unix path for drive root)
|
||||||
;; "Type"="xxx" (supported types are 'floppy', 'hd', 'cdrom' and 'network')
|
;; "Type"="xxx" (supported types are 'floppy', 'hd', 'cdrom' and 'network')
|
||||||
;; "Filesystem"="xxx" (supported types are 'msdos'/'dos'/'fat', 'win95'/'vfat', 'unix')
|
|
||||||
;; This is the FS Wine is supposed to emulate on a certain
|
|
||||||
;; directory structure.
|
|
||||||
;; Recommended:
|
|
||||||
;; - "win95" for ext2fs, VFAT and FAT32
|
|
||||||
;; - "msdos" for FAT16 (ugly, upgrading to VFAT driver strongly recommended)
|
|
||||||
;; DON'T use "unix" unless you intend to port programs using Winelib !
|
|
||||||
;; "Device"="/dev/xx" (only if you want to allow raw device access)
|
;; "Device"="/dev/xx" (only if you want to allow raw device access)
|
||||||
;;
|
;;
|
||||||
[Drive A]
|
[Drive A]
|
||||||
"Path" = "/mnt/fd0"
|
"Path" = "/mnt/fd0"
|
||||||
"Type" = "floppy"
|
"Type" = "floppy"
|
||||||
"Filesystem" = "win95"
|
|
||||||
"Device" = "/dev/fd0"
|
"Device" = "/dev/fd0"
|
||||||
|
|
||||||
[Drive C]
|
[Drive C]
|
||||||
"Path" = "/c"
|
"Path" = "/c"
|
||||||
"Type" = "hd"
|
"Type" = "hd"
|
||||||
"Filesystem" = "win95"
|
|
||||||
|
|
||||||
[Drive D]
|
[Drive D]
|
||||||
"Path" = "/cdrom"
|
"Path" = "/cdrom"
|
||||||
"Type" = "cdrom"
|
"Type" = "cdrom"
|
||||||
"Filesystem" = "win95"
|
|
||||||
; make sure that device is correct and has proper permissions !
|
; make sure that device is correct and has proper permissions !
|
||||||
"Device" = "/dev/cdrom"
|
"Device" = "/dev/cdrom"
|
||||||
|
|
||||||
[Drive E]
|
[Drive E]
|
||||||
"Path" = "/tmp"
|
"Path" = "/tmp"
|
||||||
"Type" = "hd"
|
"Type" = "hd"
|
||||||
"Filesystem" = "win95"
|
|
||||||
|
|
||||||
[Drive F]
|
[Drive F]
|
||||||
"Path" = "%HOME%"
|
"Path" = "%HOME%"
|
||||||
"Type" = "network"
|
"Type" = "network"
|
||||||
"Filesystem" = "win95"
|
|
||||||
|
|
||||||
[Drive Z]
|
[Drive Z]
|
||||||
"Path" = "/"
|
"Path" = "/"
|
||||||
"Type" = "hd"
|
"Type" = "hd"
|
||||||
"Filesystem" = "win95"
|
|
||||||
|
|
||||||
[wine]
|
[wine]
|
||||||
"Windows" = "c:\\windows"
|
"Windows" = "c:\\windows"
|
||||||
|
|
|
@ -60,25 +60,6 @@ Used to specify the drive type this drive appears as in Windows
|
||||||
or DOS programs; supported types are "floppy", "hd", "cdrom"
|
or DOS programs; supported types are "floppy", "hd", "cdrom"
|
||||||
and "network".
|
and "network".
|
||||||
.PP
|
.PP
|
||||||
.I format: """Filesystem""=""<fstype>"""
|
|
||||||
.br
|
|
||||||
default: "win95"
|
|
||||||
.br
|
|
||||||
Used to specify the type of the file system Wine should emulate on a given
|
|
||||||
directory structure/underlying file system.
|
|
||||||
.br
|
|
||||||
Supported types are "msdos" (or "fat"), "win95" (or "vfat"), "unix".
|
|
||||||
.br
|
|
||||||
Recommended:
|
|
||||||
.br
|
|
||||||
"win95" for ext2fs, ReiserFS, ..., VFAT and FAT32
|
|
||||||
.br
|
|
||||||
"msdos" for FAT16 file systems (ugly, 8.3 naming)
|
|
||||||
.br
|
|
||||||
You definitely do not want to use "unix" unless you intend to port
|
|
||||||
programs using Winelib. Always try to avoid using a FAT16 FS. Use the
|
|
||||||
VFAT/FAT32 OS file system driver instead.
|
|
||||||
.PP
|
|
||||||
.I format: """FailReadOnly""=""<boolean>"""
|
.I format: """FailReadOnly""=""<boolean>"""
|
||||||
.br
|
.br
|
||||||
Read-only files may not be opened in write mode (the default is to
|
Read-only files may not be opened in write mode (the default is to
|
||||||
|
|
|
@ -689,8 +689,7 @@ static BOOL DIR_TryPath( const DOS_FULL_NAME *dir, LPCWSTR name,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!DOSFS_FindUnixName( dir, name, p_l,
|
if (!DOSFS_FindUnixName( dir, name, p_l,
|
||||||
sizeof(full_name->long_name) - (p_l - full_name->long_name),
|
sizeof(full_name->long_name) - (p_l - full_name->long_name), p_s ))
|
||||||
p_s, !(DRIVE_GetFlags(dir->drive) & DRIVE_CASE_SENSITIVE) ))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
full_name->drive = dir->drive;
|
full_name->drive = dir->drive;
|
||||||
|
|
|
@ -133,6 +133,9 @@ static const WCHAR parW[] = {'P','a','r','a','l','l','e','l',0};
|
||||||
static const WCHAR serW[] = {'S','e','r','i','a','l',0};
|
static const WCHAR serW[] = {'S','e','r','i','a','l',0};
|
||||||
static const WCHAR oneW[] = {'1',0};
|
static const WCHAR oneW[] = {'1',0};
|
||||||
|
|
||||||
|
/* at some point we may want to allow Winelib apps to set this */
|
||||||
|
static const BOOL is_case_sensitive = FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Directory info for DOSFS_ReadDir
|
* Directory info for DOSFS_ReadDir
|
||||||
* contains the names of *all* the files in the directory
|
* contains the names of *all* the files in the directory
|
||||||
|
@ -175,11 +178,11 @@ static WINE_EXCEPTION_FILTER(page_fault)
|
||||||
* (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
|
* (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
|
||||||
* File name can be terminated by '\0', '\\' or '/'.
|
* File name can be terminated by '\0', '\\' or '/'.
|
||||||
*/
|
*/
|
||||||
static int DOSFS_ValidDOSName( LPCWSTR name, int ignore_case )
|
static int DOSFS_ValidDOSName( LPCWSTR name )
|
||||||
{
|
{
|
||||||
static const char invalid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INVALID_DOS_CHARS;
|
static const char invalid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INVALID_DOS_CHARS;
|
||||||
const WCHAR *p = name;
|
const WCHAR *p = name;
|
||||||
const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars;
|
const char *invalid = !is_case_sensitive ? (invalid_chars + 26) : invalid_chars;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (*p == '.')
|
if (*p == '.')
|
||||||
|
@ -352,13 +355,13 @@ static void DOSFS_ToDosDTAFormat( LPCWSTR name, LPWSTR buffer )
|
||||||
* *test1.txt* test1.txt *
|
* *test1.txt* test1.txt *
|
||||||
* h?l?o*t.dat hellothisisatest.dat *
|
* h?l?o*t.dat hellothisisatest.dat *
|
||||||
*/
|
*/
|
||||||
static int DOSFS_MatchLong( LPCWSTR mask, LPCWSTR name, int case_sensitive )
|
static int DOSFS_MatchLong( LPCWSTR mask, LPCWSTR name )
|
||||||
{
|
{
|
||||||
LPCWSTR lastjoker = NULL;
|
LPCWSTR lastjoker = NULL;
|
||||||
LPCWSTR next_to_retry = NULL;
|
LPCWSTR next_to_retry = NULL;
|
||||||
static const WCHAR asterisk_dot_asterisk[] = {'*','.','*',0};
|
static const WCHAR asterisk_dot_asterisk[] = {'*','.','*',0};
|
||||||
|
|
||||||
TRACE("(%s, %s, %x)\n", debugstr_w(mask), debugstr_w(name), case_sensitive);
|
TRACE("(%s, %s)\n", debugstr_w(mask), debugstr_w(name));
|
||||||
|
|
||||||
if (!strcmpW( mask, asterisk_dot_asterisk )) return 1;
|
if (!strcmpW( mask, asterisk_dot_asterisk )) return 1;
|
||||||
while (*name && *mask)
|
while (*name && *mask)
|
||||||
|
@ -371,7 +374,7 @@ static int DOSFS_MatchLong( LPCWSTR mask, LPCWSTR name, int case_sensitive )
|
||||||
if (!*mask) return 1; /* end of mask is all '*', so match */
|
if (!*mask) return 1; /* end of mask is all '*', so match */
|
||||||
|
|
||||||
/* skip to the next match after the joker(s) */
|
/* skip to the next match after the joker(s) */
|
||||||
if (case_sensitive) while (*name && (*name != *mask)) name++;
|
if (is_case_sensitive) while (*name && (*name != *mask)) name++;
|
||||||
else while (*name && (toupperW(*name) != toupperW(*mask))) name++;
|
else while (*name && (toupperW(*name) != toupperW(*mask))) name++;
|
||||||
|
|
||||||
if (!*name) break;
|
if (!*name) break;
|
||||||
|
@ -380,7 +383,7 @@ static int DOSFS_MatchLong( LPCWSTR mask, LPCWSTR name, int case_sensitive )
|
||||||
else if (*mask != '?')
|
else if (*mask != '?')
|
||||||
{
|
{
|
||||||
int mismatch = 0;
|
int mismatch = 0;
|
||||||
if (case_sensitive)
|
if (is_case_sensitive)
|
||||||
{
|
{
|
||||||
if (*mask != *name) mismatch = 1;
|
if (*mask != *name) mismatch = 1;
|
||||||
}
|
}
|
||||||
|
@ -637,8 +640,7 @@ static BOOL DOSFS_ReadDir( DOS_DIR *dir, LPCWSTR *long_name,
|
||||||
* File name can be terminated by '\0', '\\' or '/'.
|
* File name can be terminated by '\0', '\\' or '/'.
|
||||||
* 'buffer' must be at least 13 characters long.
|
* 'buffer' must be at least 13 characters long.
|
||||||
*/
|
*/
|
||||||
static void DOSFS_Hash( LPCWSTR name, LPWSTR buffer, BOOL dir_format,
|
static void DOSFS_Hash( LPCWSTR name, LPWSTR buffer, BOOL dir_format )
|
||||||
BOOL ignore_case )
|
|
||||||
{
|
{
|
||||||
static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
|
static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
|
||||||
static const char hash_chars[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
|
static const char hash_chars[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
|
||||||
|
@ -654,7 +656,7 @@ static void DOSFS_Hash( LPCWSTR name, LPWSTR buffer, BOOL dir_format,
|
||||||
buffer[11] = 0;
|
buffer[11] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DOSFS_ValidDOSName( name, ignore_case ))
|
if (DOSFS_ValidDOSName( name ))
|
||||||
{
|
{
|
||||||
/* Check for '.' and '..' */
|
/* Check for '.' and '..' */
|
||||||
if (*name == '.')
|
if (*name == '.')
|
||||||
|
@ -683,7 +685,7 @@ static void DOSFS_Hash( LPCWSTR name, LPWSTR buffer, BOOL dir_format,
|
||||||
/* Compute the hash code of the file name */
|
/* Compute the hash code of the file name */
|
||||||
/* If you know something about hash functions, feel free to */
|
/* If you know something about hash functions, feel free to */
|
||||||
/* insert a better algorithm here... */
|
/* insert a better algorithm here... */
|
||||||
if (ignore_case)
|
if (!is_case_sensitive)
|
||||||
{
|
{
|
||||||
for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
|
for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
|
||||||
hash = (hash<<3) ^ (hash>>5) ^ tolowerW(*p) ^ (tolowerW(p[1]) << 8);
|
hash = (hash<<3) ^ (hash>>5) ^ tolowerW(*p) ^ (tolowerW(p[1]) << 8);
|
||||||
|
@ -740,7 +742,7 @@ static void DOSFS_Hash( LPCWSTR name, LPWSTR buffer, BOOL dir_format,
|
||||||
* 'short_buf' must be at least 13 characters long.
|
* 'short_buf' must be at least 13 characters long.
|
||||||
*/
|
*/
|
||||||
BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
|
BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
|
||||||
INT long_len, LPWSTR short_buf, BOOL ignore_case)
|
INT long_len, LPWSTR short_buf )
|
||||||
{
|
{
|
||||||
DOS_DIR *dir;
|
DOS_DIR *dir;
|
||||||
LPCWSTR long_name, short_name;
|
LPCWSTR long_name, short_name;
|
||||||
|
@ -770,7 +772,7 @@ BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf
|
||||||
/* Check against Unix name */
|
/* Check against Unix name */
|
||||||
if (len == strlenW(long_name))
|
if (len == strlenW(long_name))
|
||||||
{
|
{
|
||||||
if (!ignore_case)
|
if (is_case_sensitive)
|
||||||
{
|
{
|
||||||
if (!strncmpW( long_name, name, len )) break;
|
if (!strncmpW( long_name, name, len )) break;
|
||||||
}
|
}
|
||||||
|
@ -784,7 +786,7 @@ BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf
|
||||||
/* Check against hashed DOS name */
|
/* Check against hashed DOS name */
|
||||||
if (!short_name)
|
if (!short_name)
|
||||||
{
|
{
|
||||||
DOSFS_Hash( long_name, tmp_buf, TRUE, ignore_case );
|
DOSFS_Hash( long_name, tmp_buf, TRUE );
|
||||||
short_name = tmp_buf;
|
short_name = tmp_buf;
|
||||||
}
|
}
|
||||||
if (!strcmpW( dos_name, short_name )) break;
|
if (!strcmpW( dos_name, short_name )) break;
|
||||||
|
@ -798,7 +800,7 @@ BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf
|
||||||
if (short_name)
|
if (short_name)
|
||||||
DOSFS_ToDosDTAFormat( short_name, short_buf );
|
DOSFS_ToDosDTAFormat( short_name, short_buf );
|
||||||
else
|
else
|
||||||
DOSFS_Hash( long_name, short_buf, FALSE, ignore_case );
|
DOSFS_Hash( long_name, short_buf, FALSE );
|
||||||
}
|
}
|
||||||
TRACE("(%s,%s) -> %s (%s)\n", path->long_name, debugstr_w(name),
|
TRACE("(%s,%s) -> %s (%s)\n", path->long_name, debugstr_w(name),
|
||||||
debugstr_w(long_name), short_buf ? debugstr_w(short_buf) : "***");
|
debugstr_w(long_name), short_buf ? debugstr_w(short_buf) : "***");
|
||||||
|
@ -984,7 +986,6 @@ static int DOSFS_GetPathDrive( LPCWSTR *name )
|
||||||
BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
|
BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
|
||||||
{
|
{
|
||||||
BOOL found;
|
BOOL found;
|
||||||
UINT flags;
|
|
||||||
char *p_l, *root;
|
char *p_l, *root;
|
||||||
LPWSTR p_s;
|
LPWSTR p_s;
|
||||||
static const WCHAR driveA_rootW[] = {'A',':','\\',0};
|
static const WCHAR driveA_rootW[] = {'A',':','\\',0};
|
||||||
|
@ -999,7 +1000,6 @@ BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((full->drive = DOSFS_GetPathDrive( &name )) == -1) return FALSE;
|
if ((full->drive = DOSFS_GetPathDrive( &name )) == -1) return FALSE;
|
||||||
flags = DRIVE_GetFlags( full->drive );
|
|
||||||
|
|
||||||
lstrcpynA( full->long_name, DRIVE_GetRoot( full->drive ),
|
lstrcpynA( full->long_name, DRIVE_GetRoot( full->drive ),
|
||||||
sizeof(full->long_name) );
|
sizeof(full->long_name) );
|
||||||
|
@ -1063,8 +1063,7 @@ BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
|
||||||
/* Get the long and short name matching the file name */
|
/* Get the long and short name matching the file name */
|
||||||
|
|
||||||
if ((found = DOSFS_FindUnixName( full, name, p_l + 1,
|
if ((found = DOSFS_FindUnixName( full, name, p_l + 1,
|
||||||
sizeof(full->long_name) - (p_l - full->long_name) - 1,
|
sizeof(full->long_name) - (p_l - full->long_name) - 1, p_s + 1 )))
|
||||||
p_s + 1, !(flags & DRIVE_CASE_SENSITIVE) )))
|
|
||||||
{
|
{
|
||||||
*p_l++ = '/';
|
*p_l++ = '/';
|
||||||
p_l += strlen(p_l);
|
p_l += strlen(p_l);
|
||||||
|
@ -1085,7 +1084,7 @@ BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
|
||||||
/* If the drive is case-sensitive we want to create new */
|
/* If the drive is case-sensitive we want to create new */
|
||||||
/* files in lower-case otherwise we can't reopen them */
|
/* files in lower-case otherwise we can't reopen them */
|
||||||
/* under the same short name. */
|
/* under the same short name. */
|
||||||
if (flags & DRIVE_CASE_SENSITIVE) wch = tolowerW(*name);
|
if (is_case_sensitive) wch = tolowerW(*name);
|
||||||
else wch = *name;
|
else wch = *name;
|
||||||
p_l += WideCharToMultiByte(CP_UNIXCP, 0, &wch, 1, p_l, 2, NULL, NULL);
|
p_l += WideCharToMultiByte(CP_UNIXCP, 0, &wch, 1, p_l, 2, NULL, NULL);
|
||||||
name++;
|
name++;
|
||||||
|
@ -1186,7 +1185,6 @@ static BOOL get_show_dir_symlinks_option(void)
|
||||||
*/
|
*/
|
||||||
static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATAW *entry )
|
static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATAW *entry )
|
||||||
{
|
{
|
||||||
UINT flags = DRIVE_GetFlags( info->drive );
|
|
||||||
char *p, buffer[MAX_PATHNAME_LEN];
|
char *p, buffer[MAX_PATHNAME_LEN];
|
||||||
const char *drive_path;
|
const char *drive_path;
|
||||||
int drive_root;
|
int drive_root;
|
||||||
|
@ -1215,8 +1213,7 @@ static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATAW *entry )
|
||||||
|
|
||||||
if (info->long_mask && *info->long_mask)
|
if (info->long_mask && *info->long_mask)
|
||||||
{
|
{
|
||||||
if (!DOSFS_MatchLong( info->long_mask, long_name,
|
if (!DOSFS_MatchLong( info->long_mask, long_name )) continue;
|
||||||
flags & DRIVE_CASE_SENSITIVE )) continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the file attributes */
|
/* Check the file attributes */
|
||||||
|
@ -1247,11 +1244,9 @@ static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATAW *entry )
|
||||||
if (short_name)
|
if (short_name)
|
||||||
DOSFS_ToDosDTAFormat( short_name, entry->cAlternateFileName );
|
DOSFS_ToDosDTAFormat( short_name, entry->cAlternateFileName );
|
||||||
else
|
else
|
||||||
DOSFS_Hash( long_name, entry->cAlternateFileName, FALSE,
|
DOSFS_Hash( long_name, entry->cAlternateFileName, FALSE );
|
||||||
!(flags & DRIVE_CASE_SENSITIVE) );
|
|
||||||
|
|
||||||
lstrcpynW( entry->cFileName, long_name, sizeof(entry->cFileName)/sizeof(entry->cFileName[0]) );
|
lstrcpynW( entry->cFileName, long_name, sizeof(entry->cFileName)/sizeof(entry->cFileName[0]) );
|
||||||
if (!(flags & DRIVE_CASE_PRESERVING)) strlwrW( entry->cFileName );
|
|
||||||
TRACE("returning %s (%s) %02lx %ld\n",
|
TRACE("returning %s (%s) %02lx %ld\n",
|
||||||
debugstr_w(entry->cFileName), debugstr_w(entry->cAlternateFileName),
|
debugstr_w(entry->cFileName), debugstr_w(entry->cAlternateFileName),
|
||||||
entry->dwFileAttributes, entry->nFileSizeLow );
|
entry->dwFileAttributes, entry->nFileSizeLow );
|
||||||
|
|
|
@ -89,27 +89,6 @@ static const WCHAR DRIVE_Types[][8] =
|
||||||
{'r','a','m','d','i','s','k',0} /* DRIVE_RAMDISK */
|
{'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 DOSDRIVE DOSDrives[MAX_DOS_DRIVES];
|
||||||
static int DRIVE_CurDrive = -1;
|
static int DRIVE_CurDrive = -1;
|
||||||
|
|
||||||
|
@ -145,21 +124,6 @@ static inline UINT DRIVE_GetDriveType( INT drive, LPCWSTR value )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* 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
|
* DRIVE_Init
|
||||||
*/
|
*/
|
||||||
|
@ -182,7 +146,6 @@ int DRIVE_Init(void)
|
||||||
|
|
||||||
static const WCHAR PathW[] = {'P','a','t','h',0};
|
static const WCHAR PathW[] = {'P','a','t','h',0};
|
||||||
static const WCHAR TypeW[] = {'T','y','p','e',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 DeviceW[] = {'D','e','v','i','c','e',0};
|
||||||
static const WCHAR FailReadOnlyW[] = {'F','a','i','l','R','e','a','d','O','n','l','y',0};
|
static const WCHAR FailReadOnlyW[] = {'F','a','i','l','R','e','a','d','O','n','l','y',0};
|
||||||
|
|
||||||
|
@ -260,15 +223,6 @@ int DRIVE_Init(void)
|
||||||
}
|
}
|
||||||
else drive->type = DRIVE_FIXED;
|
else drive->type = DRIVE_FIXED;
|
||||||
|
|
||||||
/* 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 */
|
/* Get the device */
|
||||||
RtlInitUnicodeString( &nameW, DeviceW );
|
RtlInitUnicodeString( &nameW, DeviceW );
|
||||||
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
|
||||||
|
@ -329,7 +283,7 @@ int DRIVE_Init(void)
|
||||||
{
|
{
|
||||||
for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
|
||||||
{
|
{
|
||||||
if (drive->root && !(drive->flags & DRIVE_DISABLED))
|
if (drive->root)
|
||||||
{
|
{
|
||||||
DRIVE_CurDrive = i;
|
DRIVE_CurDrive = i;
|
||||||
break;
|
break;
|
||||||
|
@ -355,8 +309,7 @@ int DRIVE_Init(void)
|
||||||
int DRIVE_IsValid( int drive )
|
int DRIVE_IsValid( int drive )
|
||||||
{
|
{
|
||||||
if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
|
if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
|
||||||
return (DOSDrives[drive].root &&
|
return (DOSDrives[drive].root != NULL);
|
||||||
!(DOSDrives[drive].flags & DRIVE_DISABLED));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -425,9 +378,7 @@ int DRIVE_FindDriveRoot( const char **path )
|
||||||
{
|
{
|
||||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
{
|
{
|
||||||
if (!DOSDrives[drive].root ||
|
if (!DOSDrives[drive].root) continue;
|
||||||
(DOSDrives[drive].flags & DRIVE_DISABLED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((DOSDrives[drive].dev == st.st_dev) &&
|
if ((DOSDrives[drive].dev == st.st_dev) &&
|
||||||
(DOSDrives[drive].ino == st.st_ino))
|
(DOSDrives[drive].ino == st.st_ino))
|
||||||
|
@ -489,9 +440,7 @@ int DRIVE_FindDriveRootW( LPCWSTR *path )
|
||||||
/* Find the drive */
|
/* Find the drive */
|
||||||
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
|
||||||
{
|
{
|
||||||
if (!DOSDrives[drive].root ||
|
if (!DOSDrives[drive].root) continue;
|
||||||
(DOSDrives[drive].flags & DRIVE_DISABLED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((DOSDrives[drive].dev == st.st_dev) &&
|
if ((DOSDrives[drive].dev == st.st_dev) &&
|
||||||
(DOSDrives[drive].ino == st.st_ino))
|
(DOSDrives[drive].ino == st.st_ino))
|
||||||
|
|
|
@ -27,11 +27,7 @@
|
||||||
|
|
||||||
/* Drive flags */
|
/* Drive flags */
|
||||||
|
|
||||||
#define DRIVE_DISABLED 0x0001 /* Drive is disabled */
|
#define DRIVE_FAIL_READ_ONLY 0x0001 /* Fail opening read-only files for writing */
|
||||||
#define DRIVE_SHORT_NAMES 0x0002 /* Drive fs has 8.3 file names */
|
|
||||||
#define DRIVE_CASE_SENSITIVE 0x0004 /* Drive fs is case sensitive */
|
|
||||||
#define DRIVE_CASE_PRESERVING 0x0008 /* Drive fs is case preserving */
|
|
||||||
#define DRIVE_FAIL_READ_ONLY 0x0010 /* Fail opening read-only files for writing */
|
|
||||||
|
|
||||||
extern int DRIVE_Init(void);
|
extern int DRIVE_Init(void);
|
||||||
extern int DRIVE_IsValid( int drive );
|
extern int DRIVE_IsValid( int drive );
|
||||||
|
|
|
@ -81,7 +81,7 @@ extern DWORD DIR_SearchPath( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
|
||||||
extern BOOL DOSFS_ToDosFCBFormat( LPCWSTR name, LPWSTR buffer );
|
extern BOOL DOSFS_ToDosFCBFormat( LPCWSTR name, LPWSTR buffer );
|
||||||
extern HANDLE DOSFS_OpenDevice( LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa);
|
extern HANDLE DOSFS_OpenDevice( LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa);
|
||||||
extern BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
|
extern BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
|
||||||
INT long_len, LPWSTR short_buf, BOOL ignore_case );
|
INT long_len, LPWSTR short_buf );
|
||||||
extern BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last,
|
extern BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last,
|
||||||
DOS_FULL_NAME *full );
|
DOS_FULL_NAME *full );
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue