Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
4e44e153
Commit
4e44e153
authored
Jan 18, 2011
by
Charles Davis
Committed by
Alexandre Julliard
Jan 28, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Check for case-insensitive volumes.
parent
1c255778
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
255 additions
and
0 deletions
+255
-0
configure
configure
+2
-0
configure.ac
configure.ac
+2
-0
directory.c
dlls/ntdll/directory.c
+245
-0
config.h.in
include/config.h.in
+6
-0
No files found.
configure
View file @
4e44e153
...
...
@@ -5849,6 +5849,7 @@ for ac_header in \
strings.h
\
stropts.h
\
sys/asoundlib.h
\
sys/attr.h
\
sys/cdio.h
\
sys/elf32.h
\
sys/epoll.h
\
...
...
@@ -12755,6 +12756,7 @@ for ac_func in \
ftruncate
\
futimes
\
futimesat
\
getattrlist
\
getdirentries
\
getopt_long
\
getpagesize
\
...
...
configure.ac
View file @
4e44e153
...
...
@@ -456,6 +456,7 @@ AC_CHECK_HEADERS(\
strings.h \
stropts.h \
sys/asoundlib.h \
sys/attr.h \
sys/cdio.h \
sys/elf32.h \
sys/epoll.h \
...
...
@@ -1909,6 +1910,7 @@ AC_CHECK_FUNCS(\
ftruncate \
futimes \
futimesat \
getattrlist \
getdirentries \
getopt_long \
getpagesize \
...
...
dlls/ntdll/directory.c
View file @
4e44e153
...
...
@@ -44,6 +44,9 @@
#ifdef HAVE_SYS_SYSCALL_H
# include <sys/syscall.h>
#endif
#ifdef HAVE_SYS_ATTR_H
#include <sys/attr.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
...
...
@@ -59,6 +62,9 @@
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#include <time.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
...
...
@@ -774,6 +780,243 @@ static char *get_device_mount_point( dev_t dev )
}
#if defined(HAVE_GETATTRLIST) && defined(ATTR_VOL_CAPABILITIES) && \
defined(VOL_CAPABILITIES_FORMAT) && defined(VOL_CAP_FMT_CASE_SENSITIVE)
struct
get_fsid
{
ULONG
size
;
dev_t
dev
;
fsid_t
fsid
;
};
struct
fs_cache
{
dev_t
dev
;
fsid_t
fsid
;
BOOLEAN
case_sensitive
;
}
fs_cache
[
64
];
struct
vol_caps
{
ULONG
size
;
vol_capabilities_attr_t
caps
;
};
/***********************************************************************
* look_up_fs_cache
*
* Checks if the specified file system is in the cache.
*/
static
struct
fs_cache
*
look_up_fs_cache
(
dev_t
dev
)
{
int
i
;
for
(
i
=
0
;
i
<
sizeof
(
fs_cache
)
/
sizeof
(
fs_cache
[
0
]);
i
++
)
if
(
fs_cache
[
i
].
dev
==
dev
)
return
fs_cache
+
i
;
return
NULL
;
}
/***********************************************************************
* add_fs_cache
*
* Adds the specified file system to the cache.
*/
static
void
add_fs_cache
(
dev_t
dev
,
fsid_t
fsid
,
BOOLEAN
case_sensitive
)
{
int
i
;
struct
fs_cache
*
entry
=
look_up_fs_cache
(
dev
);
static
int
once
=
0
;
if
(
entry
)
{
/* Update the cache */
entry
->
fsid
=
fsid
;
entry
->
case_sensitive
=
case_sensitive
;
return
;
}
/* Add a new entry */
for
(
i
=
0
;
i
<
sizeof
(
fs_cache
)
/
sizeof
(
fs_cache
[
0
]);
i
++
)
if
(
fs_cache
[
i
].
dev
==
0
)
{
/* This entry is empty, use it */
fs_cache
[
i
].
dev
=
dev
;
fs_cache
[
i
].
fsid
=
fsid
;
fs_cache
[
i
].
case_sensitive
=
case_sensitive
;
return
;
}
/* Cache is out of space, warn */
if
(
once
++
)
WARN
(
"FS cache is out of space, expect performance problems
\n
"
);
}
/***********************************************************************
* get_dir_case_sensitivity_attr
*
* Checks if the volume containing the specified directory is case
* sensitive or not. Uses getattrlist(2).
*/
static
int
get_dir_case_sensitivity_attr
(
const
char
*
dir
)
{
char
*
mntpoint
=
NULL
;
struct
attrlist
attr
;
struct
vol_caps
caps
;
struct
get_fsid
get_fsid
;
struct
fs_cache
*
entry
;
/* First get the FS ID of the volume */
attr
.
bitmapcount
=
ATTR_BIT_MAP_COUNT
;
attr
.
reserved
=
0
;
attr
.
commonattr
=
ATTR_CMN_DEVID
|
ATTR_CMN_FSID
;
attr
.
volattr
=
attr
.
dirattr
=
attr
.
fileattr
=
attr
.
forkattr
=
0
;
get_fsid
.
size
=
0
;
if
(
getattrlist
(
dir
,
&
attr
,
&
get_fsid
,
sizeof
(
get_fsid
),
0
)
!=
0
||
get_fsid
.
size
!=
sizeof
(
get_fsid
))
return
-
1
;
/* Try to look it up in the cache */
entry
=
look_up_fs_cache
(
get_fsid
.
dev
);
if
(
entry
&&
!
memcmp
(
&
entry
->
fsid
,
&
get_fsid
.
fsid
,
sizeof
(
fsid_t
)
))
/* Cache lookup succeeded */
return
entry
->
case_sensitive
;
/* Cache is stale at this point, we have to update it */
mntpoint
=
get_device_mount_point
(
get_fsid
.
dev
);
/* Now look up the case-sensitivity */
attr
.
commonattr
=
0
;
attr
.
volattr
=
ATTR_VOL_INFO
|
ATTR_VOL_CAPABILITIES
;
if
(
getattrlist
(
mntpoint
,
&
attr
,
&
caps
,
sizeof
(
caps
),
0
)
<
0
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
mntpoint
);
add_fs_cache
(
get_fsid
.
dev
,
get_fsid
.
fsid
,
TRUE
);
return
TRUE
;
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
mntpoint
);
if
(
caps
.
size
==
sizeof
(
caps
)
&&
(
caps
.
caps
.
valid
[
VOL_CAPABILITIES_FORMAT
]
&
(
VOL_CAP_FMT_CASE_SENSITIVE
|
VOL_CAP_FMT_CASE_PRESERVING
))
==
(
VOL_CAP_FMT_CASE_SENSITIVE
|
VOL_CAP_FMT_CASE_PRESERVING
))
{
BOOLEAN
ret
;
if
((
caps
.
caps
.
capabilities
[
VOL_CAPABILITIES_FORMAT
]
&
VOL_CAP_FMT_CASE_SENSITIVE
)
!=
VOL_CAP_FMT_CASE_SENSITIVE
)
ret
=
FALSE
;
else
ret
=
TRUE
;
/* Update the cache */
add_fs_cache
(
get_fsid
.
dev
,
get_fsid
.
fsid
,
ret
);
return
ret
;
}
return
FALSE
;
}
#endif
/***********************************************************************
* get_dir_case_sensitivity_stat
*
* Checks if the volume containing the specified directory is case
* sensitive or not. Uses statfs(2) or statvfs(2).
*/
static
BOOLEAN
get_dir_case_sensitivity_stat
(
const
char
*
dir
)
{
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
struct
statfs
stfs
;
statfs
(
dir
,
&
stfs
);
/* Assume these file systems are always case insensitive on Mac OS.
* For FreeBSD, only assume CIOPFS is case insensitive (AFAIK, Mac OS
* is the only UNIX that supports case-insensitive lookup).
*/
if
(
!
strcmp
(
stfs
.
f_fstypename
,
"fusefs"
)
&&
!
strncmp
(
stfs
.
f_mntfromname
,
"ciopfs"
,
5
))
return
FALSE
;
#ifdef __APPLE__
if
(
!
strcmp
(
stfs
.
f_fstypename
,
"msdos"
)
||
!
strcmp
(
stfs
.
f_fstypename
,
"cd9660"
)
||
!
strcmp
(
stfs
.
f_fstypename
,
"udf"
)
||
!
strcmp
(
stfs
.
f_fstypename
,
"ntfs"
)
||
!
strcmp
(
stfs
.
f_fstypename
,
"smbfs"
))
return
FALSE
;
#ifdef _DARWIN_FEATURE_64_BIT_INODE
if
(
!
strcmp
(
stfs
.
f_fstypename
,
"hfs"
)
&&
(
stfs
.
f_fssubtype
==
0
||
stfs
.
f_fssubtype
==
1
||
stfs
.
f_fssubtype
==
128
))
return
FALSE
;
#else
/* The field says "reserved", but a quick look at the kernel source
* tells us that this "reserved" field is really the same as the
* "fssubtype" field from the inode64 structure (see munge_statfs()
* in <xnu-source>/bsd/vfs/vfs_syscalls.c).
*/
if
(
!
strcmp
(
stfs
.
f_fstypename
,
"hfs"
)
&&
(
stfs
.
f_reserved1
==
0
||
stfs
.
f_reserved1
==
1
||
stfs
.
f_reserved1
==
128
))
return
FALSE
;
#endif
#endif
return
TRUE
;
#elif defined(__NetBSD__)
struct
statvfs
stfs
;
statvfs
(
dir
,
&
stfs
);
/* Only assume CIOPFS is case insensitive. */
if
(
strcmp
(
stfs
.
f_fstypename
,
"fusefs"
)
||
strncmp
(
stfs
.
f_mntfromname
,
"ciopfs"
,
5
))
return
TRUE
;
return
FALSE
;
#elif defined(__linux__)
struct
statfs
stfs
;
struct
stat
st
;
char
*
cifile
;
/* Only assume CIOPFS is case insensitive. */
statfs
(
dir
,
&
stfs
);
if
(
stfs
.
f_type
!=
0x65735546
/* FUSE_SUPER_MAGIC */
)
return
TRUE
;
/* Normally, we'd have to parse the mtab to find out exactly what
* kind of FUSE FS this is. But, someone on wine-devel suggested
* a shortcut. We'll stat a special file in the directory. If it's
* there, we'll assume it's a CIOPFS, else not.
* This will break if somebody puts a file named ".ciopfs" in a non-
* CIOPFS directory.
*/
cifile
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
strlen
(
dir
)
+
sizeof
(
"/.ciopfs"
)
);
if
(
!
cifile
)
return
TRUE
;
strcpy
(
cifile
,
dir
);
strcat
(
cifile
,
"/.ciopfs"
);
if
(
stat
(
cifile
,
&
st
)
==
0
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
cifile
);
return
FALSE
;
}
RtlFreeHeap
(
GetProcessHeap
(),
0
,
cifile
);
return
TRUE
;
#else
return
TRUE
;
#endif
}
/***********************************************************************
* get_dir_case_sensitivity
*
* Checks if the volume containing the specified directory is case
* sensitive or not. Uses statfs(2) or statvfs(2).
*/
static
BOOLEAN
get_dir_case_sensitivity
(
const
char
*
dir
)
{
#if defined(HAVE_GETATTRLIST) && defined(ATTR_VOL_CAPABILITIES) && \
defined(VOL_CAPABILITIES_FORMAT) && defined(VOL_CAP_FMT_CASE_SENSITIVE)
int
case_sensitive
=
get_dir_case_sensitivity_attr
(
dir
);
if
(
case_sensitive
!=
-
1
)
return
case_sensitive
;
#endif
return
get_dir_case_sensitivity_stat
(
dir
);
}
/***********************************************************************
* init_options
*
...
...
@@ -1837,6 +2080,8 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
str
.
MaximumLength
=
str
.
Length
;
is_name_8_dot_3
=
RtlIsNameLegalDOS8Dot3
(
&
str
,
NULL
,
&
spaces
)
&&
!
spaces
;
if
(
!
is_name_8_dot_3
&&
!
get_dir_case_sensitivity
(
unix_name
))
goto
not_found
;
/* now look for it through the directory */
#ifdef VFAT_IOCTL_READDIR_BOTH
...
...
include/config.h.in
View file @
4e44e153
...
...
@@ -200,6 +200,9 @@
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getattrlist' function. */
#undef HAVE_GETATTRLIST
/* Define to 1 if you have the `getdirentries' function. */
#undef HAVE_GETDIRENTRIES
...
...
@@ -875,6 +878,9 @@
/* Define to 1 if you have the <sys/asoundlib.h> header file. */
#undef HAVE_SYS_ASOUNDLIB_H
/* Define to 1 if you have the <sys/attr.h> header file. */
#undef HAVE_SYS_ATTR_H
/* Define to 1 if you have the <sys/cdio.h> header file. */
#undef HAVE_SYS_CDIO_H
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment