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
a420a207
Commit
a420a207
authored
Dec 01, 2009
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move the directory lookup part of wine_nt_to_unix_file_name to a separate helper.
parent
77d58529
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
121 additions
and
115 deletions
+121
-115
directory.c
dlls/ntdll/directory.c
+121
-115
No files found.
dlls/ntdll/directory.c
View file @
a420a207
...
@@ -2212,6 +2212,120 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name )
...
@@ -2212,6 +2212,120 @@ static inline int get_dos_prefix_len( const UNICODE_STRING *name )
/******************************************************************************
/******************************************************************************
* lookup_unix_name
*
* Helper for nt_to_unix_file_name
*/
static
NTSTATUS
lookup_unix_name
(
const
WCHAR
*
name
,
int
name_len
,
char
**
buffer
,
int
unix_len
,
int
pos
,
UINT
disposition
,
BOOLEAN
check_case
)
{
NTSTATUS
status
;
int
ret
,
used_default
,
len
;
struct
stat
st
;
char
*
unix_name
=
*
buffer
;
const
BOOL
redirect
=
nb_redirects
&&
ntdll_get_thread_data
()
->
wow64_redir
;
/* try a shortcut first */
ret
=
ntdll_wcstoumbs
(
0
,
name
,
name_len
,
unix_name
+
pos
,
unix_len
-
pos
-
1
,
NULL
,
&
used_default
);
while
(
name_len
&&
IS_SEPARATOR
(
*
name
))
{
name
++
;
name_len
--
;
}
if
(
ret
>
0
&&
!
used_default
)
/* if we used the default char the name didn't convert properly */
{
char
*
p
;
unix_name
[
pos
+
ret
]
=
0
;
for
(
p
=
unix_name
+
pos
;
*
p
;
p
++
)
if
(
*
p
==
'\\'
)
*
p
=
'/'
;
if
((
!
redirect
||
!
strstr
(
unix_name
,
"/windows/"
))
&&
!
stat
(
unix_name
,
&
st
))
{
/* creation fails with STATUS_ACCESS_DENIED for the root of the drive */
if
(
disposition
==
FILE_CREATE
)
return
name_len
?
STATUS_OBJECT_NAME_COLLISION
:
STATUS_ACCESS_DENIED
;
return
STATUS_SUCCESS
;
}
}
if
(
!
name_len
)
/* empty name -> drive root doesn't exist */
return
STATUS_OBJECT_PATH_NOT_FOUND
;
if
(
check_case
&&
!
redirect
&&
(
disposition
==
FILE_OPEN
||
disposition
==
FILE_OVERWRITE
))
return
STATUS_OBJECT_NAME_NOT_FOUND
;
/* now do it component by component */
while
(
name_len
)
{
const
WCHAR
*
end
,
*
next
;
int
is_win_dir
=
0
;
end
=
name
;
while
(
end
<
name
+
name_len
&&
!
IS_SEPARATOR
(
*
end
))
end
++
;
next
=
end
;
while
(
next
<
name
+
name_len
&&
IS_SEPARATOR
(
*
next
))
next
++
;
name_len
-=
next
-
name
;
/* grow the buffer if needed */
if
(
unix_len
-
pos
<
MAX_DIR_ENTRY_LEN
+
2
)
{
char
*
new_name
;
unix_len
+=
2
*
MAX_DIR_ENTRY_LEN
;
if
(
!
(
new_name
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
unix_name
,
unix_len
)))
return
STATUS_NO_MEMORY
;
unix_name
=
*
buffer
=
new_name
;
}
status
=
find_file_in_dir
(
unix_name
,
pos
,
name
,
end
-
name
,
check_case
,
redirect
?
&
is_win_dir
:
NULL
);
/* if this is the last element, not finding it is not necessarily fatal */
if
(
!
name_len
)
{
if
(
status
==
STATUS_OBJECT_PATH_NOT_FOUND
)
{
status
=
STATUS_OBJECT_NAME_NOT_FOUND
;
if
(
disposition
!=
FILE_OPEN
&&
disposition
!=
FILE_OVERWRITE
)
{
ret
=
ntdll_wcstoumbs
(
0
,
name
,
end
-
name
,
unix_name
+
pos
+
1
,
MAX_DIR_ENTRY_LEN
,
NULL
,
&
used_default
);
if
(
ret
>
0
&&
!
used_default
)
{
unix_name
[
pos
]
=
'/'
;
unix_name
[
pos
+
1
+
ret
]
=
0
;
status
=
STATUS_NO_SUCH_FILE
;
break
;
}
}
}
else
if
(
status
==
STATUS_SUCCESS
&&
disposition
==
FILE_CREATE
)
{
status
=
STATUS_OBJECT_NAME_COLLISION
;
}
}
if
(
status
!=
STATUS_SUCCESS
)
break
;
pos
+=
strlen
(
unix_name
+
pos
);
name
=
next
;
if
(
is_win_dir
&&
(
len
=
get_redirect_path
(
unix_name
,
pos
,
name
,
name_len
,
check_case
)))
{
name
+=
len
;
name_len
-=
len
;
pos
+=
strlen
(
unix_name
+
pos
);
TRACE
(
"redirecting -> %s + %s
\n
"
,
debugstr_a
(
unix_name
),
debugstr_w
(
name
)
);
}
}
return
status
;
}
/******************************************************************************
* wine_nt_to_unix_file_name (NTDLL.@) Not a Windows API
* wine_nt_to_unix_file_name (NTDLL.@) Not a Windows API
*
*
* Convert a file name from NT namespace to Unix namespace.
* Convert a file name from NT namespace to Unix namespace.
...
@@ -2234,7 +2348,6 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
...
@@ -2234,7 +2348,6 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
int
pos
,
ret
,
name_len
,
unix_len
,
prefix_len
,
used_default
;
int
pos
,
ret
,
name_len
,
unix_len
,
prefix_len
,
used_default
;
WCHAR
prefix
[
MAX_DIR_ENTRY_LEN
];
WCHAR
prefix
[
MAX_DIR_ENTRY_LEN
];
BOOLEAN
is_unix
=
FALSE
;
BOOLEAN
is_unix
=
FALSE
;
const
BOOL
redirect
=
nb_redirects
&&
ntdll_get_thread_data
()
->
wow64_redir
;
name
=
nameW
->
Buffer
;
name
=
nameW
->
Buffer
;
name_len
=
nameW
->
Length
/
sizeof
(
WCHAR
);
name_len
=
nameW
->
Length
/
sizeof
(
WCHAR
);
...
@@ -2315,126 +2428,19 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
...
@@ -2315,126 +2428,19 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, ANSI_STRI
}
}
}
}
/* try a shortcut first */
status
=
lookup_unix_name
(
name
,
name_len
,
&
unix_name
,
unix_len
,
pos
,
disposition
,
check_case
);
if
(
status
==
STATUS_SUCCESS
||
status
==
STATUS_NO_SUCH_FILE
)
ret
=
ntdll_wcstoumbs
(
0
,
name
,
name_len
,
unix_name
+
pos
,
unix_len
-
pos
-
1
,
NULL
,
&
used_default
);
while
(
name_len
&&
IS_SEPARATOR
(
*
name
))
{
name
++
;
name_len
--
;
}
if
(
ret
>
0
&&
!
used_default
)
/* if we used the default char the name didn't convert properly */
{
char
*
p
;
unix_name
[
pos
+
ret
]
=
0
;
for
(
p
=
unix_name
+
pos
;
*
p
;
p
++
)
if
(
*
p
==
'\\'
)
*
p
=
'/'
;
if
((
!
redirect
||
!
strstr
(
unix_name
,
"/windows/"
))
&&
!
stat
(
unix_name
,
&
st
))
{
/* creation fails with STATUS_ACCESS_DENIED for the root of the drive */
if
(
disposition
==
FILE_CREATE
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
return
name_len
?
STATUS_OBJECT_NAME_COLLISION
:
STATUS_ACCESS_DENIED
;
}
goto
done
;
}
}
if
(
!
name_len
)
/* empty name -> drive root doesn't exist */
{
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
TRACE
(
"%s -> %s
\n
"
,
debugstr_us
(
nameW
),
debugstr_a
(
unix_name
)
);
return
STATUS_OBJECT_PATH_NOT_FOUND
;
unix_name_ret
->
Buffer
=
unix_name
;
}
unix_name_ret
->
Length
=
strlen
(
unix_name
);
if
(
check_case
&&
!
redirect
&&
(
disposition
==
FILE_OPEN
||
disposition
==
FILE_OVERWRITE
))
unix_name_ret
->
MaximumLength
=
unix_len
;
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
return
STATUS_OBJECT_NAME_NOT_FOUND
;
}
/* now do it component by component */
while
(
name_len
)
{
const
WCHAR
*
end
,
*
next
;
int
is_win_dir
=
0
;
end
=
name
;
while
(
end
<
name
+
name_len
&&
!
IS_SEPARATOR
(
*
end
))
end
++
;
next
=
end
;
while
(
next
<
name
+
name_len
&&
IS_SEPARATOR
(
*
next
))
next
++
;
name_len
-=
next
-
name
;
/* grow the buffer if needed */
if
(
unix_len
-
pos
<
MAX_DIR_ENTRY_LEN
+
2
)
{
char
*
new_name
;
unix_len
+=
2
*
MAX_DIR_ENTRY_LEN
;
if
(
!
(
new_name
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
unix_name
,
unix_len
)))
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
return
STATUS_NO_MEMORY
;
}
unix_name
=
new_name
;
}
status
=
find_file_in_dir
(
unix_name
,
pos
,
name
,
end
-
name
,
check_case
,
redirect
?
&
is_win_dir
:
NULL
);
/* if this is the last element, not finding it is not necessarily fatal */
if
(
!
name_len
)
{
if
(
status
==
STATUS_OBJECT_PATH_NOT_FOUND
)
{
status
=
STATUS_OBJECT_NAME_NOT_FOUND
;
if
(
disposition
!=
FILE_OPEN
&&
disposition
!=
FILE_OVERWRITE
)
{
ret
=
ntdll_wcstoumbs
(
0
,
name
,
end
-
name
,
unix_name
+
pos
+
1
,
MAX_DIR_ENTRY_LEN
,
NULL
,
&
used_default
);
if
(
ret
>
0
&&
!
used_default
)
{
unix_name
[
pos
]
=
'/'
;
unix_name
[
pos
+
1
+
ret
]
=
0
;
status
=
STATUS_NO_SUCH_FILE
;
break
;
}
}
}
else
if
(
status
==
STATUS_SUCCESS
&&
disposition
==
FILE_CREATE
)
{
status
=
STATUS_OBJECT_NAME_COLLISION
;
}
}
}
else
if
(
status
!=
STATUS_SUCCESS
)
{
{
/* couldn't find it at all, fail */
TRACE
(
"%s not found in %s
\n
"
,
debugstr_w
(
name
),
unix_name
);
TRACE
(
"%s not found in %s
\n
"
,
debugstr_w
(
name
),
unix_name
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
RtlFreeHeap
(
GetProcessHeap
(),
0
,
unix_name
);
return
status
;
}
}
pos
+=
strlen
(
unix_name
+
pos
);
name
=
next
;
if
(
is_win_dir
&&
(
prefix_len
=
get_redirect_path
(
unix_name
,
pos
,
name
,
name_len
,
check_case
)))
{
name
+=
prefix_len
;
name_len
-=
prefix_len
;
pos
+=
strlen
(
unix_name
+
pos
);
TRACE
(
"redirecting %s -> %s + %s
\n
"
,
debugstr_us
(
nameW
),
debugstr_a
(
unix_name
),
debugstr_w
(
name
)
);
}
}
done:
TRACE
(
"%s -> %s
\n
"
,
debugstr_us
(
nameW
),
debugstr_a
(
unix_name
)
);
unix_name_ret
->
Buffer
=
unix_name
;
unix_name_ret
->
Length
=
strlen
(
unix_name
);
unix_name_ret
->
MaximumLength
=
unix_len
;
return
status
;
return
status
;
}
}
...
...
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