Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
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-winehq
Commits
a9f214cb
Commit
a9f214cb
authored
Nov 13, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Added support for reading directories using the BSD getdirentries function.
parent
d4796304
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
116 additions
and
4 deletions
+116
-4
configure
configure
+2
-0
configure.ac
configure.ac
+1
-0
directory.c
dlls/ntdll/directory.c
+110
-4
config.h.in
include/config.h.in
+3
-0
No files found.
configure
View file @
a9f214cb
...
...
@@ -18185,6 +18185,7 @@ fi
for
ac_func
in
\
_pclose
\
_popen
\
...
...
@@ -18209,6 +18210,7 @@ for ac_func in \
futimes
\
futimesat
\
getaddrinfo
\
getdirentries
\
gethostbyname
\
getnameinfo
\
getnetbyname
\
...
...
configure.ac
View file @
a9f214cb
...
...
@@ -1200,6 +1200,7 @@ AC_CHECK_FUNCS(\
futimes \
futimesat \
getaddrinfo \
getdirentries \
gethostbyname \
getnameinfo \
getnetbyname \
...
...
dlls/ntdll/directory.c
View file @
a9f214cb
...
...
@@ -135,6 +135,8 @@ static inline int getdents64( int fd, KERNEL_DIRENT64 *de, unsigned int size )
#define MAX_DIR_ENTRY_LEN 255
/* max length of a directory entry in chars */
static
const
unsigned
int
max_dir_info_size
=
FIELD_OFFSET
(
FILE_BOTH_DIR_INFORMATION
,
FileName
[
MAX_DIR_ENTRY_LEN
]
);
static
int
show_dot_files
=
-
1
;
/* at some point we may want to allow Winelib apps to set this */
...
...
@@ -971,7 +973,6 @@ static int read_directory_vfat( int fd, IO_STATUS_BLOCK *io, void *buffer, ULONG
size_t
len
;
KERNEL_DIRENT
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
;
static
const
unsigned
int
max_dir_info_size
=
sizeof
(
*
info
)
+
(
MAX_DIR_ENTRY_LEN
-
1
)
*
sizeof
(
WCHAR
);
io
->
u
.
Status
=
STATUS_SUCCESS
;
...
...
@@ -1063,7 +1064,6 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
char
local_buffer
[
8192
];
KERNEL_DIRENT64
*
data
,
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
;
static
const
unsigned
int
max_dir_info_size
=
sizeof
(
*
info
)
+
(
MAX_DIR_ENTRY_LEN
-
1
)
*
sizeof
(
WCHAR
);
if
(
size
<=
sizeof
(
local_buffer
)
||
!
(
data
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
)))
{
...
...
@@ -1135,7 +1135,111 @@ done:
if
((
char
*
)
data
!=
local_buffer
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
return
res
;
}
#endif
/* USE_GETDENTS */
#elif defined HAVE_GETDIRENTRIES
/***********************************************************************
* read_directory_getdirentries
*
* Read a directory using the BSD getdirentries system call; helper for NtQueryDirectoryFile.
*/
static
int
read_directory_getdirentries
(
int
fd
,
IO_STATUS_BLOCK
*
io
,
void
*
buffer
,
ULONG
length
,
BOOLEAN
single_entry
,
const
UNICODE_STRING
*
mask
,
BOOLEAN
restart_scan
)
{
long
restart_pos
;
ULONG_PTR
restart_info_pos
=
0
;
size_t
size
,
initial_size
=
length
;
int
res
;
char
*
data
,
local_buffer
[
8192
];
struct
dirent
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
,
*
restart_last_info
=
NULL
;
size
=
initial_size
;
data
=
local_buffer
;
if
(
size
>
sizeof
(
local_buffer
)
&&
!
(
data
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
)))
{
io
->
u
.
Status
=
STATUS_NO_MEMORY
;
return
io
->
u
.
Status
;
}
if
(
restart_scan
)
lseek
(
fd
,
0
,
SEEK_SET
);
io
->
u
.
Status
=
STATUS_SUCCESS
;
/* FIXME: should make sure size is larger than filesystem block size */
res
=
getdirentries
(
fd
,
data
,
size
,
&
restart_pos
);
if
(
res
==
-
1
)
{
io
->
u
.
Status
=
FILE_GetNtStatus
();
res
=
0
;
goto
done
;
}
de
=
(
struct
dirent
*
)
data
;
while
(
res
>
0
)
{
res
-=
de
->
d_reclen
;
if
(
de
->
d_fileno
&&
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
))))
{
last_info
=
info
;
if
((
char
*
)
info
->
FileName
+
info
->
FileNameLength
>
(
char
*
)
buffer
+
length
)
{
lseek
(
fd
,
(
unsigned
long
)
restart_pos
,
SEEK_SET
);
if
(
restart_info_pos
)
/* if we have a complete read already, return it */
{
io
->
Information
=
restart_info_pos
;
last_info
=
restart_last_info
;
break
;
}
/* otherwise restart from the start with a smaller size */
size
=
(
char
*
)
de
-
data
;
if
(
!
size
)
{
io
->
u
.
Status
=
STATUS_BUFFER_OVERFLOW
;
break
;
}
io
->
Information
=
0
;
last_info
=
NULL
;
goto
restart
;
}
/* if we have to return but the buffer contains more data, restart with a smaller size */
if
(
res
>
0
&&
(
single_entry
||
io
->
Information
+
max_dir_info_size
>
length
))
{
lseek
(
fd
,
(
unsigned
long
)
restart_pos
,
SEEK_SET
);
size
=
(
char
*
)
de
-
data
;
io
->
Information
=
restart_info_pos
;
last_info
=
restart_last_info
;
goto
restart
;
}
}
/* move on to the next entry */
if
(
res
>
0
)
{
de
=
(
struct
dirent
*
)((
char
*
)
de
+
de
->
d_reclen
);
continue
;
}
if
(
size
<
initial_size
)
break
;
/* already restarted once, give up now */
size
=
min
(
size
,
length
-
io
->
Information
);
/* if size is too small don't bother to continue */
if
(
size
<
max_dir_info_size
&&
last_info
)
break
;
restart_last_info
=
last_info
;
restart_info_pos
=
io
->
Information
;
restart:
res
=
getdirentries
(
fd
,
data
,
size
,
&
restart_pos
);
de
=
(
struct
dirent
*
)
data
;
}
if
(
last_info
)
last_info
->
NextEntryOffset
=
0
;
else
io
->
u
.
Status
=
restart_scan
?
STATUS_NO_SUCH_FILE
:
STATUS_NO_MORE_FILES
;
res
=
0
;
done:
if
(
data
!=
local_buffer
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
return
res
;
}
#endif
/* HAVE_GETDIRENTRIES */
/***********************************************************************
...
...
@@ -1151,7 +1255,6 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
off_t
i
,
old_pos
=
0
;
struct
dirent
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
;
static
const
unsigned
int
max_dir_info_size
=
sizeof
(
*
info
)
+
(
MAX_DIR_ENTRY_LEN
-
1
)
*
sizeof
(
WCHAR
);
if
(
!
(
dir
=
opendir
(
"."
)))
{
...
...
@@ -1326,6 +1429,9 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event,
#ifdef USE_GETDENTS
if
((
read_directory_getdents
(
fd
,
io
,
buffer
,
length
,
single_entry
,
mask
,
restart_scan
))
!=
-
1
)
goto
done
;
#elif defined HAVE_GETDIRENTRIES
if
((
read_directory_getdirentries
(
fd
,
io
,
buffer
,
length
,
single_entry
,
mask
,
restart_scan
))
!=
-
1
)
goto
done
;
#endif
read_directory_readdir
(
fd
,
io
,
buffer
,
length
,
single_entry
,
mask
,
restart_scan
);
...
...
include/config.h.in
View file @
a9f214cb
...
...
@@ -180,6 +180,9 @@
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getdirentries' function. */
#undef HAVE_GETDIRENTRIES
/* Define to 1 if you have the `gethostbyname' function. */
#undef HAVE_GETHOSTBYNAME
...
...
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