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
df29fd3a
Commit
df29fd3a
authored
Dec 01, 2006
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Always return . and .. as the first two entries in directory searches.
parent
a411b858
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
134 additions
and
26 deletions
+134
-26
file.c
dlls/kernel32/file.c
+26
-12
directory.c
dlls/ntdll/directory.c
+108
-14
No files found.
dlls/kernel32/file.c
View file @
df29fd3a
...
...
@@ -1677,20 +1677,34 @@ HANDLE WINAPI FindFirstFileExW( LPCWSTR filename, FINDEX_INFO_LEVELS level,
CloseHandle
(
info
->
handle
);
info
->
handle
=
0
;
}
else
if
(
!
FindNextFileW
(
(
HANDLE
)
info
,
data
))
{
TRACE
(
"%s not found
\n
"
,
debugstr_w
(
filename
)
);
FindClose
(
(
HANDLE
)
info
);
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
INVALID_HANDLE_VALUE
;
}
else
if
(
!
strpbrkW
(
info
->
mask
.
Buffer
,
wildcardsW
))
else
{
/* we can't find two files with the same name */
CloseHandle
(
info
->
handle
);
info
->
handle
=
0
;
IO_STATUS_BLOCK
io
;
NtQueryDirectoryFile
(
info
->
handle
,
0
,
NULL
,
NULL
,
&
io
,
info
->
data
,
sizeof
(
info
->
data
),
FileBothDirectoryInformation
,
FALSE
,
&
info
->
mask
,
TRUE
);
if
(
io
.
u
.
Status
)
{
FindClose
(
info
);
SetLastError
(
RtlNtStatusToDosError
(
io
.
u
.
Status
)
);
return
INVALID_HANDLE_VALUE
;
}
info
->
data_len
=
io
.
Information
;
if
(
!
FindNextFileW
(
info
,
data
))
{
TRACE
(
"%s not found
\n
"
,
debugstr_w
(
filename
)
);
FindClose
(
info
);
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
INVALID_HANDLE_VALUE
;
}
if
(
!
strpbrkW
(
info
->
mask
.
Buffer
,
wildcardsW
))
{
/* we can't find two files with the same name */
CloseHandle
(
info
->
handle
);
info
->
handle
=
0
;
}
}
return
(
HANDLE
)
info
;
return
info
;
error:
HeapFree
(
GetProcessHeap
(),
0
,
info
);
...
...
dlls/ntdll/directory.c
View file @
df29fd3a
...
...
@@ -107,7 +107,7 @@ typedef struct
char
d_name
[
256
];
}
KERNEL_DIRENT64
;
static
inline
int
getdents64
(
int
fd
,
KERNEL_DIRENT64
*
de
,
unsigned
int
size
)
static
inline
int
getdents64
(
int
fd
,
char
*
de
,
unsigned
int
size
)
{
int
ret
;
__asm__
(
"pushl %%ebx; movl %2,%%ebx; int $0x80; popl %%ebx"
...
...
@@ -1060,15 +1060,15 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
{
off_t
old_pos
=
0
;
size_t
size
=
length
;
int
res
;
char
local_buffer
[
8192
];
KERNEL_DIRENT64
*
d
ata
,
*
d
e
;
int
res
,
fake_dot_dot
=
1
;
char
*
data
,
local_buffer
[
8192
];
KERNEL_DIRENT64
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
;
if
(
size
<=
sizeof
(
local_buffer
)
||
!
(
data
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
size
)))
{
size
=
sizeof
(
local_buffer
);
data
=
(
KERNEL_DIRENT64
*
)
local_buffer
;
data
=
local_buffer
;
}
if
(
restart_scan
)
lseek
(
fd
,
0
,
SEEK_SET
);
...
...
@@ -1096,13 +1096,52 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
goto
done
;
}
de
=
data
;
de
=
(
KERNEL_DIRENT64
*
)
data
;
if
(
restart_scan
)
{
/* check if we got . and .. from getdents */
if
(
res
>
0
)
{
if
(
!
strcmp
(
de
->
d_name
,
"."
)
&&
res
>
de
->
d_reclen
)
{
KERNEL_DIRENT64
*
next_de
=
(
KERNEL_DIRENT64
*
)(
data
+
de
->
d_reclen
);
if
(
!
strcmp
(
next_de
->
d_name
,
".."
))
fake_dot_dot
=
0
;
}
}
/* make sure we have enough room for both entries */
if
(
fake_dot_dot
)
{
static
const
ULONG
min_info_size
=
(
FIELD_OFFSET
(
FILE_BOTH_DIR_INFORMATION
,
FileName
[
1
])
+
FIELD_OFFSET
(
FILE_BOTH_DIR_INFORMATION
,
FileName
[
2
])
+
3
)
&
~
3
;
if
(
length
<
min_info_size
||
single_entry
)
{
FIXME
(
"not enough room %u/%u for fake . and .. entries
\n
"
,
length
,
single_entry
);
fake_dot_dot
=
0
;
}
}
if
(
fake_dot_dot
)
{
if
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
"."
,
NULL
,
mask
)))
last_info
=
info
;
if
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
".."
,
NULL
,
mask
)))
last_info
=
info
;
/* check if we still have enough space for the largest possible entry */
if
(
last_info
&&
io
->
Information
+
max_dir_info_size
>
length
)
{
lseek
(
fd
,
0
,
SEEK_SET
);
/* reset pos to first entry */
res
=
0
;
}
}
}
while
(
res
>
0
)
{
res
-=
de
->
d_reclen
;
i
nfo
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
);
if
(
info
)
i
f
(
!
(
fake_dot_dot
&&
(
!
strcmp
(
de
->
d_name
,
"."
)
||
!
strcmp
(
de
->
d_name
,
".."
)))
&&
(
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
))
)
{
last_info
=
info
;
if
((
char
*
)
info
->
FileName
+
info
->
FileNameLength
>
(
char
*
)
buffer
+
length
)
...
...
@@ -1124,7 +1163,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
else
{
res
=
getdents64
(
fd
,
data
,
size
);
de
=
data
;
de
=
(
KERNEL_DIRENT64
*
)
data
;
}
}
...
...
@@ -1132,7 +1171,7 @@ static int read_directory_getdents( int fd, IO_STATUS_BLOCK *io, void *buffer, U
else
io
->
u
.
Status
=
restart_scan
?
STATUS_NO_SUCH_FILE
:
STATUS_NO_MORE_FILES
;
res
=
0
;
done:
if
(
(
char
*
)
data
!=
local_buffer
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
if
(
data
!=
local_buffer
)
RtlFreeHeap
(
GetProcessHeap
(),
0
,
data
);
return
res
;
}
...
...
@@ -1150,7 +1189,7 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
long
restart_pos
;
ULONG_PTR
restart_info_pos
=
0
;
size_t
size
,
initial_size
=
length
;
int
res
;
int
res
,
fake_dot_dot
=
1
;
char
*
data
,
local_buffer
[
8192
];
struct
dirent
*
de
;
FILE_BOTH_DIR_INFORMATION
*
info
,
*
last_info
=
NULL
,
*
restart_last_info
=
NULL
;
...
...
@@ -1178,10 +1217,53 @@ static int read_directory_getdirentries( int fd, IO_STATUS_BLOCK *io, void *buff
de
=
(
struct
dirent
*
)
data
;
if
(
restart_scan
)
{
/* check if we got . and .. from getdirentries */
if
(
res
>
0
)
{
if
(
!
strcmp
(
de
->
d_name
,
"."
)
&&
res
>
de
->
d_reclen
)
{
struct
dirent
*
next_de
=
(
struct
dirent
*
)(
data
+
de
->
d_reclen
);
if
(
!
strcmp
(
next_de
->
d_name
,
".."
))
fake_dot_dot
=
0
;
}
}
/* make sure we have enough room for both entries */
if
(
fake_dot_dot
)
{
static
const
ULONG
min_info_size
=
(
FIELD_OFFSET
(
FILE_BOTH_DIR_INFORMATION
,
FileName
[
1
])
+
FIELD_OFFSET
(
FILE_BOTH_DIR_INFORMATION
,
FileName
[
2
])
+
3
)
&
~
3
;
if
(
length
<
min_info_size
||
single_entry
)
{
FIXME
(
"not enough room %u/%u for fake . and .. entries
\n
"
,
length
,
single_entry
);
fake_dot_dot
=
0
;
}
}
if
(
fake_dot_dot
)
{
if
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
"."
,
NULL
,
mask
)))
last_info
=
info
;
if
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
".."
,
NULL
,
mask
)))
last_info
=
info
;
restart_last_info
=
last_info
;
restart_info_pos
=
io
->
Information
;
/* check if we still have enough space for the largest possible entry */
if
(
last_info
&&
io
->
Information
+
max_dir_info_size
>
length
)
{
lseek
(
fd
,
0
,
SEEK_SET
);
/* reset pos to first entry */
res
=
0
;
}
}
}
while
(
res
>
0
)
{
res
-=
de
->
d_reclen
;
if
(
de
->
d_fileno
&&
!
(
fake_dot_dot
&&
(
!
strcmp
(
de
->
d_name
,
"."
)
||
!
strcmp
(
de
->
d_name
,
".."
)))
&&
((
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
))))
{
last_info
=
info
;
...
...
@@ -1266,7 +1348,7 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
{
old_pos
=
lseek
(
fd
,
0
,
SEEK_CUR
);
/* skip the right number of entries */
for
(
i
=
0
;
i
<
old_pos
;
i
++
)
for
(
i
=
0
;
i
<
old_pos
-
2
;
i
++
)
{
if
(
!
readdir
(
dir
))
{
...
...
@@ -1278,10 +1360,22 @@ static void read_directory_readdir( int fd, IO_STATUS_BLOCK *io, void *buffer, U
}
io
->
u
.
Status
=
STATUS_SUCCESS
;
while
((
de
=
readdir
(
dir
))
)
for
(;;
)
{
if
(
old_pos
==
0
)
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
"."
,
NULL
,
mask
);
else
if
(
old_pos
==
1
)
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
".."
,
NULL
,
mask
);
else
if
((
de
=
readdir
(
dir
)))
{
if
(
strcmp
(
de
->
d_name
,
"."
)
&&
strcmp
(
de
->
d_name
,
".."
))
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
);
else
info
=
NULL
;
}
else
break
;
old_pos
++
;
info
=
append_entry
(
buffer
,
&
io
->
Information
,
length
,
de
->
d_name
,
NULL
,
mask
);
if
(
info
)
{
last_info
=
info
;
...
...
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