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
7ef35b33
Commit
7ef35b33
authored
Apr 15, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Reimplement file system redirection using NT pathname comparisons.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
8e7c6422
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
239 additions
and
182 deletions
+239
-182
env.c
dlls/ntdll/unix/env.c
+8
-3
file.c
dlls/ntdll/unix/file.c
+197
-165
loader.c
dlls/ntdll/unix/loader.c
+14
-5
process.c
dlls/ntdll/unix/process.c
+16
-6
unix_private.h
dlls/ntdll/unix/unix_private.h
+4
-3
No files found.
dlls/ntdll/unix/env.c
View file @
7ef35b33
...
...
@@ -2133,16 +2133,21 @@ void init_startup_info(void)
/***********************************************************************
* create_startup_info
*/
void
*
create_startup_info
(
const
RTL_USER_PROCESS_PARAMETERS
*
params
,
DWORD
*
info_size
)
void
*
create_startup_info
(
const
UNICODE_STRING
*
nt_image
,
const
RTL_USER_PROCESS_PARAMETERS
*
params
,
DWORD
*
info_size
)
{
startup_info_t
*
info
;
UNICODE_STRING
dos_image
=
*
nt_image
;
DWORD
size
;
void
*
ptr
;
dos_image
.
Buffer
=
get_dos_path
(
nt_image
->
Buffer
);
dos_image
.
Length
=
nt_image
->
Length
-
(
dos_image
.
Buffer
-
nt_image
->
Buffer
)
*
sizeof
(
WCHAR
);
size
=
sizeof
(
*
info
);
size
+=
params
->
CurrentDirectory
.
DosPath
.
Length
;
size
+=
params
->
DllPath
.
Length
;
size
+=
params
->
ImagePathNam
e
.
Length
;
size
+=
dos_imag
e
.
Length
;
size
+=
params
->
CommandLine
.
Length
;
size
+=
params
->
WindowTitle
.
Length
;
size
+=
params
->
Desktop
.
Length
;
...
...
@@ -2172,7 +2177,7 @@ void *create_startup_info( const RTL_USER_PROCESS_PARAMETERS *params, DWORD *inf
ptr
=
info
+
1
;
info
->
curdir_len
=
append_string
(
&
ptr
,
params
,
&
params
->
CurrentDirectory
.
DosPath
);
info
->
dllpath_len
=
append_string
(
&
ptr
,
params
,
&
params
->
DllPath
);
info
->
imagepath_len
=
append_string
(
&
ptr
,
params
,
&
params
->
ImagePathNam
e
);
info
->
imagepath_len
=
append_string
(
&
ptr
,
params
,
&
dos_imag
e
);
info
->
cmdline_len
=
append_string
(
&
ptr
,
params
,
&
params
->
CommandLine
);
info
->
title_len
=
append_string
(
&
ptr
,
params
,
&
params
->
WindowTitle
);
info
->
desktop_len
=
append_string
(
&
ptr
,
params
,
&
params
->
Desktop
);
...
...
dlls/ntdll/unix/file.c
View file @
7ef35b33
...
...
@@ -241,8 +241,6 @@ static mode_t start_umask;
/* at some point we may want to allow Winelib apps to set this */
static
const
BOOL
is_case_sensitive
=
FALSE
;
static
struct
file_identity
windir
;
static
pthread_mutex_t
dir_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
pthread_mutex_t
mnt_mutex
=
PTHREAD_MUTEX_INITIALIZER
;
...
...
@@ -2477,7 +2475,7 @@ NTSTATUS WINAPI NtQueryDirectoryFile( HANDLE handle, HANDLE event, PIO_APC_ROUTI
* There must be at least MAX_DIR_ENTRY_LEN+2 chars available at pos.
*/
static
NTSTATUS
find_file_in_dir
(
char
*
unix_name
,
int
pos
,
const
WCHAR
*
name
,
int
length
,
BOOLEAN
check_case
,
BOOLEAN
*
is_win_dir
)
BOOLEAN
check_case
)
{
WCHAR
buffer
[
MAX_DIR_ENTRY_LEN
];
BOOLEAN
is_name_8_dot_3
;
...
...
@@ -2493,11 +2491,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
if
(
ret
>=
0
&&
ret
<=
MAX_DIR_ENTRY_LEN
)
{
unix_name
[
pos
+
ret
]
=
0
;
if
(
!
stat
(
unix_name
,
&
st
))
{
if
(
is_win_dir
)
*
is_win_dir
=
is_same_file
(
&
windir
,
&
st
);
return
STATUS_SUCCESS
;
}
if
(
!
stat
(
unix_name
,
&
st
))
return
STATUS_SUCCESS
;
}
if
(
check_case
)
goto
not_found
;
/* we want an exact match */
...
...
@@ -2536,7 +2530,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
{
strcpy
(
unix_name
+
pos
,
kde
[
1
].
d_name
);
close
(
fd
);
goto
success
;
return
STATUS_SUCCESS
;
}
}
ret
=
ntdll_umbstowcs
(
kde
[
0
].
d_name
,
strlen
(
kde
[
0
].
d_name
),
...
...
@@ -2546,7 +2540,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
strcpy
(
unix_name
+
pos
,
kde
[
1
].
d_name
[
0
]
?
kde
[
1
].
d_name
:
kde
[
0
].
d_name
);
close
(
fd
);
goto
success
;
return
STATUS_SUCCESS
;
}
if
(
ioctl
(
fd
,
VFAT_IOCTL_READDIR_BOTH
,
(
long
)
kde
)
==
-
1
)
{
...
...
@@ -2573,7 +2567,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
{
strcpy
(
unix_name
+
pos
,
de
->
d_name
);
closedir
(
dir
);
goto
success
;
return
STATUS_SUCCESS
;
}
if
(
!
is_name_8_dot_3
)
continue
;
...
...
@@ -2586,7 +2580,7 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
{
strcpy
(
unix_name
+
pos
,
de
->
d_name
);
closedir
(
dir
);
goto
success
;
return
STATUS_SUCCESS
;
}
}
}
...
...
@@ -2595,10 +2589,6 @@ static NTSTATUS find_file_in_dir( char *unix_name, int pos, const WCHAR *name, i
not_found:
unix_name
[
pos
-
1
]
=
0
;
return
STATUS_OBJECT_PATH_NOT_FOUND
;
success:
if
(
is_win_dir
&&
!
stat
(
unix_name
,
&
st
))
*
is_win_dir
=
is_same_file
(
&
windir
,
&
st
);
return
STATUS_SUCCESS
;
}
...
...
@@ -2611,116 +2601,164 @@ static const WCHAR driversetcW[] = {'s','y','s','t','e','m','3','2','\\','d','r'
static
const
WCHAR
logfilesW
[]
=
{
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
'l'
,
'o'
,
'g'
,
'f'
,
'i'
,
'l'
,
'e'
,
's'
,
0
};
static
const
WCHAR
spoolW
[]
=
{
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
's'
,
'p'
,
'o'
,
'o'
,
'l'
,
0
};
static
const
WCHAR
system32W
[]
=
{
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
0
};
static
const
WCHAR
syswow64W
[]
=
{
's'
,
'y'
,
's'
,
'w'
,
'o'
,
'w'
,
'6'
,
'4'
,
0
};
static
const
WCHAR
sysnativeW
[]
=
{
's'
,
'y'
,
's'
,
'n'
,
'a'
,
't'
,
'i'
,
'v'
,
'e'
,
0
};
static
const
WCHAR
regeditW
[]
=
{
'r'
,
'e'
,
'g'
,
'e'
,
'd'
,
'i'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
struct
{
const
WCHAR
*
source
;
const
char
*
unix_target
;
}
redirects
[]
=
{
{
catrootW
,
NULL
},
{
catroot2W
,
NULL
},
{
driversstoreW
,
NULL
},
{
driversetcW
,
NULL
},
{
logfilesW
,
NULL
},
{
spoolW
,
NULL
},
{
system32W
,
"syswow64"
},
{
sysnativeW
,
"system32"
},
{
regeditW
,
"syswow64/regedit.exe"
}
static
const
WCHAR
syswow64_regeditW
[]
=
{
's'
,
'y'
,
's'
,
'w'
,
'o'
,
'w'
,
'6'
,
'4'
,
'\\'
,
'r'
,
'e'
,
'g'
,
'e'
,
'd'
,
'i'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
windirW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
0
};
static
const
WCHAR
syswow64dirW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
'w'
,
'o'
,
'w'
,
'6'
,
'4'
,
'\\'
};
static
const
WCHAR
*
const
no_redirect
[]
=
{
catrootW
,
catroot2W
,
driversstoreW
,
driversetcW
,
logfilesW
,
spoolW
};
static
unsigned
int
nb_redirects
;
static
struct
file_identity
windir
,
sysdir
;
static
inline
ULONG
starts_with_path
(
const
WCHAR
*
name
,
ULONG
name_len
,
const
WCHAR
*
prefix
)
{
ULONG
len
=
wcslen
(
prefix
);
if
(
name_len
<
len
)
return
0
;
if
(
wcsnicmp
(
name
,
prefix
,
len
))
return
0
;
if
(
name_len
>
len
&&
name
[
len
]
!=
'\\'
)
return
0
;
return
len
;
}
static
BOOL
replace_path
(
OBJECT_ATTRIBUTES
*
attr
,
UNICODE_STRING
*
str
,
ULONG
prefix_len
,
const
WCHAR
*
match
,
const
WCHAR
*
replace
)
{
const
WCHAR
*
name
=
attr
->
ObjectName
->
Buffer
;
ULONG
match_len
,
replace_len
,
len
=
attr
->
ObjectName
->
Length
/
sizeof
(
WCHAR
);
WCHAR
*
p
;
if
(
!
starts_with_path
(
name
+
prefix_len
,
len
-
prefix_len
,
match
))
return
FALSE
;
match_len
=
wcslen
(
match
);
replace_len
=
wcslen
(
replace
);
str
->
Length
=
(
len
+
replace_len
-
match_len
)
*
sizeof
(
WCHAR
);
str
->
MaximumLength
=
str
->
Length
+
sizeof
(
WCHAR
);
if
(
!
(
p
=
str
->
Buffer
=
malloc
(
str
->
MaximumLength
)))
return
FALSE
;
memcpy
(
p
,
name
,
prefix_len
*
sizeof
(
WCHAR
)
);
p
+=
prefix_len
;
memcpy
(
p
,
replace
,
replace_len
*
sizeof
(
WCHAR
)
);
p
+=
replace_len
;
name
+=
prefix_len
+
match_len
;
len
-=
prefix_len
+
match_len
;
memcpy
(
p
,
name
,
len
*
sizeof
(
WCHAR
)
);
p
[
len
]
=
0
;
attr
->
ObjectName
=
str
;
return
TRUE
;
}
/***********************************************************************
* init_redirects
*/
static
void
init_redirects
(
void
)
{
static
const
char
windows_dir
[]
=
"/dosdevices/c:/windows
"
;
static
const
char
system_dir
[]
=
"/dosdevices/c:/windows/system32
"
;
char
*
dir
;
struct
stat
st
;
if
(
!
(
dir
=
malloc
(
strlen
(
config_dir
)
+
sizeof
(
windows
_dir
)
)))
return
;
if
(
!
(
dir
=
malloc
(
strlen
(
config_dir
)
+
sizeof
(
system
_dir
)
)))
return
;
strcpy
(
dir
,
config_dir
);
strcat
(
dir
,
windows_dir
);
strcat
(
dir
,
system_dir
);
if
(
!
stat
(
dir
,
&
st
))
{
sysdir
.
dev
=
st
.
st_dev
;
sysdir
.
ino
=
st
.
st_ino
;
}
*
strrchr
(
dir
,
'/'
)
=
0
;
if
(
!
stat
(
dir
,
&
st
))
{
windir
.
dev
=
st
.
st_dev
;
windir
.
ino
=
st
.
st_ino
;
nb_redirects
=
ARRAY_SIZE
(
redirects
);
}
else
ERR
(
"%s: %s
\n
"
,
dir
,
strerror
(
errno
)
);
free
(
dir
);
}
/***********************************************************************
* match_redirect
*
* Check if path matches a redirect name. If yes, return matched length.
* get_redirect
*/
static
int
match_redirect
(
const
WCHAR
*
path
,
int
len
,
const
WCHAR
*
redir
,
BOOLEAN
check_case
)
BOOL
get_redirect
(
OBJECT_ATTRIBUTES
*
attr
,
UNICODE_STRING
*
redir
)
{
int
i
=
0
;
const
WCHAR
*
name
=
attr
->
ObjectName
->
Buffer
;
unsigned
int
i
,
prefix_len
=
0
,
len
=
attr
->
ObjectName
->
Length
/
sizeof
(
WCHAR
);
redir
->
Buffer
=
NULL
;
if
(
!
NtCurrentTeb64
())
return
FALSE
;
if
(
!
len
)
return
FALSE
;
while
(
i
<
len
)
if
(
!
attr
->
RootDirectory
)
{
int
start
=
i
;
while
(
i
<
len
&&
!
IS_SEPARATOR
(
path
[
i
]))
i
++
;
if
(
check_case
)
{
if
(
wcsncmp
(
path
+
start
,
redir
,
i
-
start
))
return
0
;
}
else
{
if
(
wcsnicmp
(
path
+
start
,
redir
,
i
-
start
))
return
0
;
}
redir
+=
i
-
start
;
while
(
i
<
len
&&
IS_SEPARATOR
(
path
[
i
]))
i
++
;
if
(
!*
redir
)
return
i
;
if
(
*
redir
++
!=
'\\'
)
return
0
;
prefix_len
=
wcslen
(
windirW
);
if
(
len
<
prefix_len
||
wcsnicmp
(
name
,
windirW
,
prefix_len
))
return
FALSE
;
}
return
0
;
}
else
{
int
fd
,
needs_close
;
struct
stat
st
;
if
(
server_get_unix_fd
(
attr
->
RootDirectory
,
0
,
&
fd
,
&
needs_close
,
NULL
,
NULL
))
return
FALSE
;
fstat
(
fd
,
&
st
);
if
(
needs_close
)
close
(
fd
);
if
(
!
is_same_file
(
&
windir
,
&
st
))
{
if
(
!
is_same_file
(
&
sysdir
,
&
st
))
return
FALSE
;
if
(
NtCurrentTeb64
()
->
TlsSlots
[
WOW64_TLS_FILESYSREDIR
])
return
FALSE
;
if
(
name
[
0
]
==
'\\'
)
return
FALSE
;
/***********************************************************************
* get_redirect_path
*
* Retrieve the Unix path corresponding to a redirected path if any.
*/
static
int
get_redirect_path
(
char
*
unix_name
,
int
pos
,
const
WCHAR
*
name
,
int
length
,
BOOLEAN
check_case
)
{
unsigned
int
i
;
int
len
;
/* only check for paths that should NOT be redirected */
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
no_redirect
);
i
++
)
if
(
starts_with_path
(
name
,
len
,
no_redirect
[
i
]
+
9
/* "system32\\" */
))
return
FALSE
;
for
(
i
=
0
;
i
<
nb_redirects
;
i
++
)
{
if
((
len
=
match_redirect
(
name
,
length
,
redirects
[
i
].
source
,
check_case
)))
{
if
(
!
redirects
[
i
].
unix_target
)
break
;
unix_name
[
pos
++
]
=
'/'
;
strcpy
(
unix_name
+
pos
,
redirects
[
i
].
unix_target
);
return
len
;
/* redirect everything else */
redir
->
Length
=
sizeof
(
syswow64dirW
)
+
len
*
sizeof
(
WCHAR
);
redir
->
MaximumLength
=
redir
->
Length
+
sizeof
(
WCHAR
);
if
(
!
(
redir
->
Buffer
=
malloc
(
redir
->
MaximumLength
)))
return
FALSE
;
memcpy
(
redir
->
Buffer
,
syswow64dirW
,
sizeof
(
syswow64dirW
)
);
memcpy
(
redir
->
Buffer
+
ARRAY_SIZE
(
syswow64dirW
),
name
,
len
*
sizeof
(
WCHAR
)
);
redir
->
Buffer
[
redir
->
Length
/
sizeof
(
WCHAR
)]
=
0
;
attr
->
RootDirectory
=
0
;
attr
->
ObjectName
=
redir
;
return
TRUE
;
}
}
return
0
;
/* sysnative is redirected even when redirection is disabled */
if
(
replace_path
(
attr
,
redir
,
prefix_len
,
sysnativeW
,
system32W
))
return
TRUE
;
if
(
NtCurrentTeb64
()
->
TlsSlots
[
WOW64_TLS_FILESYSREDIR
])
return
FALSE
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
no_redirect
);
i
++
)
if
(
starts_with_path
(
name
+
prefix_len
,
len
-
prefix_len
,
no_redirect
[
i
]
))
return
FALSE
;
if
(
replace_path
(
attr
,
redir
,
prefix_len
,
system32W
,
syswow64W
))
return
TRUE
;
if
(
replace_path
(
attr
,
redir
,
prefix_len
,
regeditW
,
syswow64_regeditW
))
return
TRUE
;
return
FALSE
;
}
#else
/* _WIN64 */
/* there are no redirects on 64-bit */
static
int
get_redirect_path
(
char
*
unix_name
,
int
pos
,
const
WCHAR
*
name
,
int
length
,
BOOLEAN
check_case
)
BOOL
get_redirect
(
OBJECT_ATTRIBUTES
*
attr
,
UNICODE_STRING
*
redir
)
{
return
0
;
redir
->
Buffer
=
NULL
;
return
FALSE
;
}
#endif
#define IS_OPTION_TRUE(ch) ((ch) == 'y' || (ch) == 'Y' || (ch) == 't' || (ch) == 'T' || (ch) == '1')
/***********************************************************************
...
...
@@ -3018,6 +3056,7 @@ static NTSTATUS file_id_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char *
ULONGLONG
file_id
;
struct
stat
st
,
root_st
;
nt_name
->
Buffer
=
NULL
;
if
(
attr
->
ObjectName
->
Length
!=
sizeof
(
ULONGLONG
))
return
STATUS_OBJECT_PATH_SYNTAX_BAD
;
if
(
!
attr
->
RootDirectory
)
return
STATUS_INVALID_PARAMETER
;
memcpy
(
&
file_id
,
attr
->
ObjectName
->
Buffer
,
sizeof
(
file_id
)
);
...
...
@@ -3093,11 +3132,10 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
{
static
const
WCHAR
invalid_charsW
[]
=
{
INVALID_NT_CHARS
,
'/'
,
0
};
NTSTATUS
status
;
int
ret
,
len
;
int
ret
;
struct
stat
st
;
char
*
unix_name
=
*
buffer
;
const
WCHAR
*
ptr
,
*
end
;
const
BOOL
redirect
=
NtCurrentTeb64
()
&&
!
NtCurrentTeb64
()
->
TlsSlots
[
WOW64_TLS_FILESYSREDIR
];
/* check syntax of individual components */
...
...
@@ -3132,20 +3170,16 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
char
*
p
;
unix_name
[
pos
+
1
+
ret
]
=
0
;
for
(
p
=
unix_name
+
pos
;
*
p
;
p
++
)
if
(
*
p
==
'\\'
)
*
p
=
'/'
;
if
(
!
name_len
||
!
redirect
||
(
!
strstr
(
unix_name
,
"/windows/"
)
&&
strncmp
(
unix_name
,
"windows/"
,
8
)
))
if
(
!
stat
(
unix_name
,
&
st
))
{
if
(
!
stat
(
unix_name
,
&
st
))
{
if
(
disposition
==
FILE_CREATE
)
return
STATUS_OBJECT_NAME_COLLISION
;
return
STATUS_SUCCESS
;
}
if
(
disposition
==
FILE_CREATE
)
return
STATUS_OBJECT_NAME_COLLISION
;
return
STATUS_SUCCESS
;
}
}
if
(
!
name_len
)
/* empty name -> drive root doesn't exist */
return
STATUS_OBJECT_PATH_NOT_FOUND
;
if
(
is_unix
&&
!
redirect
&&
(
disposition
==
FILE_OPEN
||
disposition
==
FILE_OVERWRITE
))
if
(
is_unix
&&
(
disposition
==
FILE_OPEN
||
disposition
==
FILE_OVERWRITE
))
return
STATUS_OBJECT_NAME_NOT_FOUND
;
/* now do it component by component */
...
...
@@ -3153,7 +3187,6 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
while
(
name_len
)
{
const
WCHAR
*
end
,
*
next
;
BOOLEAN
is_win_dir
=
FALSE
;
end
=
name
;
while
(
end
<
name
+
name_len
&&
*
end
!=
'\\'
)
end
++
;
...
...
@@ -3171,8 +3204,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
unix_name
=
*
buffer
=
new_name
;
}
status
=
find_file_in_dir
(
unix_name
,
pos
,
name
,
end
-
name
,
is_unix
,
redirect
?
&
is_win_dir
:
NULL
);
status
=
find_file_in_dir
(
unix_name
,
pos
,
name
,
end
-
name
,
is_unix
);
/* if this is the last element, not finding it is not necessarily fatal */
if
(
!
name_len
)
...
...
@@ -3202,14 +3234,6 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
pos
+=
strlen
(
unix_name
+
pos
);
name
=
next
;
if
(
is_win_dir
&&
(
len
=
get_redirect_path
(
unix_name
,
pos
,
name
,
name_len
,
is_unix
)))
{
name
+=
len
;
name_len
-=
len
;
pos
+=
strlen
(
unix_name
+
pos
);
TRACE
(
"redirecting -> %s + %s
\n
"
,
debugstr_a
(
unix_name
),
debugstr_w
(
name
)
);
}
}
return
status
;
...
...
@@ -3220,7 +3244,7 @@ static NTSTATUS lookup_unix_name( const WCHAR *name, int name_len, char **buffer
* nt_to_unix_file_name_no_root
*/
static
NTSTATUS
nt_to_unix_file_name_no_root
(
const
UNICODE_STRING
*
nameW
,
char
**
unix_name_ret
,
U
NICODE_STRING
*
nt_name
,
U
INT
disposition
)
UINT
disposition
)
{
static
const
WCHAR
unixW
[]
=
{
'u'
,
'n'
,
'i'
,
'x'
};
static
const
WCHAR
invalid_charsW
[]
=
{
INVALID_NT_CHARS
,
0
};
...
...
@@ -3313,7 +3337,6 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
{
TRACE
(
"%s -> %s
\n
"
,
debugstr_us
(
nameW
),
debugstr_a
(
unix_name
)
);
*
unix_name_ret
=
unix_name
;
if
(
nt_name
)
rebuild_nt_name
(
nameW
,
name
-
nameW
->
Buffer
,
unix_name
+
pos
,
nt_name
);
}
else
{
...
...
@@ -3333,8 +3356,7 @@ static NTSTATUS nt_to_unix_file_name_no_root( const UNICODE_STRING *nameW, char
* element doesn't have to exist; in that case STATUS_NO_SUCH_FILE is
* returned, but the unix name is still filled in properly.
*/
NTSTATUS
nt_to_unix_file_name
(
const
OBJECT_ATTRIBUTES
*
attr
,
char
**
name_ret
,
UNICODE_STRING
*
nt_name
,
UINT
disposition
)
NTSTATUS
nt_to_unix_file_name
(
const
OBJECT_ATTRIBUTES
*
attr
,
char
**
name_ret
,
UINT
disposition
)
{
enum
server_fd_type
type
;
int
old_cwd
,
root_fd
,
needs_close
;
...
...
@@ -3344,7 +3366,7 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret,
NTSTATUS
status
;
if
(
!
attr
->
RootDirectory
)
/* without root dir fall back to normal lookup */
return
nt_to_unix_file_name_no_root
(
attr
->
ObjectName
,
name_ret
,
nt_name
,
disposition
);
return
nt_to_unix_file_name_no_root
(
attr
->
ObjectName
,
name_ret
,
disposition
);
name
=
attr
->
ObjectName
->
Buffer
;
name_len
=
attr
->
ObjectName
->
Length
/
sizeof
(
WCHAR
);
...
...
@@ -3382,7 +3404,6 @@ NTSTATUS nt_to_unix_file_name( const OBJECT_ATTRIBUTES *attr, char **name_ret,
{
TRACE
(
"%s -> %s
\n
"
,
debugstr_us
(
attr
->
ObjectName
),
debugstr_a
(
unix_name
)
);
*
name_ret
=
unix_name
;
if
(
nt_name
)
rebuild_nt_name
(
attr
->
ObjectName
,
0
,
unix_name
,
nt_name
);
}
else
{
...
...
@@ -3407,10 +3428,12 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nam
{
char
*
buffer
=
NULL
;
NTSTATUS
status
;
UNICODE_STRING
redir
;
OBJECT_ATTRIBUTES
attr
;
InitializeObjectAttributes
(
&
attr
,
(
UNICODE_STRING
*
)
nameW
,
OBJ_CASE_INSENSITIVE
,
0
,
NULL
);
status
=
nt_to_unix_file_name
(
&
attr
,
&
buffer
,
NULL
,
disposition
);
get_redirect
(
&
attr
,
&
redir
);
status
=
nt_to_unix_file_name
(
&
attr
,
&
buffer
,
disposition
);
if
(
buffer
)
{
...
...
@@ -3419,6 +3442,7 @@ NTSTATUS CDECL wine_nt_to_unix_file_name( const UNICODE_STRING *nameW, char *nam
*
size
=
strlen
(
buffer
)
+
1
;
free
(
buffer
);
}
free
(
redir
.
Buffer
);
return
status
;
}
...
...
@@ -3703,7 +3727,8 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
ULONG
attributes
,
ULONG
sharing
,
ULONG
disposition
,
ULONG
options
,
void
*
ea_buffer
,
ULONG
ea_length
)
{
UNICODE_STRING
nt_name
=
{
0
};
OBJECT_ATTRIBUTES
new_attr
;
UNICODE_STRING
nt_name
;
char
*
unix_name
;
BOOL
created
=
FALSE
;
...
...
@@ -3717,10 +3742,17 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
if
(
alloc_size
)
FIXME
(
"alloc_size not supported
\n
"
);
new_attr
=
*
attr
;
if
(
options
&
FILE_OPEN_BY_FILE_ID
)
io
->
u
.
Status
=
file_id_to_unix_file_name
(
attr
,
&
unix_name
,
&
nt_name
);
{
io
->
u
.
Status
=
file_id_to_unix_file_name
(
&
new_attr
,
&
unix_name
,
&
nt_name
);
if
(
!
io
->
u
.
Status
)
new_attr
.
ObjectName
=
&
nt_name
;
}
else
io
->
u
.
Status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
&
nt_name
,
disposition
);
{
get_redirect
(
&
new_attr
,
&
nt_name
);
io
->
u
.
Status
=
nt_to_unix_file_name
(
&
new_attr
,
&
unix_name
,
disposition
);
}
if
(
io
->
u
.
Status
==
STATUS_BAD_DEVICE_TYPE
)
{
...
...
@@ -3731,12 +3763,13 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
req
->
rootdir
=
wine_server_obj_handle
(
attr
->
RootDirectory
);
req
->
sharing
=
sharing
;
req
->
options
=
options
;
wine_server_add_data
(
req
,
attr
->
ObjectName
->
Buffer
,
attr
->
ObjectName
->
Length
);
wine_server_add_data
(
req
,
new_attr
.
ObjectName
->
Buffer
,
new_attr
.
ObjectName
->
Length
);
io
->
u
.
Status
=
wine_server_call
(
req
);
*
handle
=
wine_server_ptr_handle
(
reply
->
handle
);
}
SERVER_END_REQ
;
if
(
io
->
u
.
Status
==
STATUS_SUCCESS
)
io
->
Information
=
FILE_OPENED
;
free
(
nt_name
.
Buffer
);
return
io
->
u
.
Status
;
}
...
...
@@ -3748,12 +3781,8 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
if
(
io
->
u
.
Status
==
STATUS_SUCCESS
)
{
OBJECT_ATTRIBUTES
nt_attr
=
*
attr
;
if
(
nt_name
.
Buffer
)
nt_attr
.
ObjectName
=
&
nt_name
;
io
->
u
.
Status
=
open_unix_file
(
handle
,
unix_name
,
access
,
&
nt_attr
,
attributes
,
io
->
u
.
Status
=
open_unix_file
(
handle
,
unix_name
,
access
,
&
new_attr
,
attributes
,
sharing
,
disposition
,
options
,
ea_buffer
,
ea_length
);
free
(
nt_name
.
Buffer
);
free
(
unix_name
);
}
else
WARN
(
"%s not found (%x)
\n
"
,
debugstr_us
(
attr
->
ObjectName
),
io
->
u
.
Status
);
...
...
@@ -3785,6 +3814,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
if
(
!
once
++
)
ERR_
(
winediag
)(
"Too many open files, ulimit -n probably needs to be increased
\n
"
);
}
free
(
nt_name
.
Buffer
);
return
io
->
u
.
Status
;
}
...
...
@@ -3906,8 +3936,11 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
{
char
*
unix_name
;
NTSTATUS
status
;
UNICODE_STRING
redir
;
OBJECT_ATTRIBUTES
new_attr
=
*
attr
;
if
(
!
(
status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
NULL
,
FILE_OPEN
)))
get_redirect
(
&
new_attr
,
&
redir
);
if
(
!
(
status
=
nt_to_unix_file_name
(
&
new_attr
,
&
unix_name
,
FILE_OPEN
)))
{
ULONG
attributes
;
struct
stat
st
;
...
...
@@ -3936,6 +3969,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
free
(
unix_name
);
}
else
WARN
(
"%s not found (%x)
\n
"
,
debugstr_us
(
attr
->
ObjectName
),
status
);
free
(
redir
.
Buffer
);
return
status
;
}
...
...
@@ -3947,8 +3981,11 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
{
char
*
unix_name
;
NTSTATUS
status
;
UNICODE_STRING
redir
;
OBJECT_ATTRIBUTES
new_attr
=
*
attr
;
if
(
!
(
status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
NULL
,
FILE_OPEN
)))
get_redirect
(
&
new_attr
,
&
redir
);
if
(
!
(
status
=
nt_to_unix_file_name
(
&
new_attr
,
&
unix_name
,
FILE_OPEN
)))
{
ULONG
attributes
;
struct
stat
st
;
...
...
@@ -3965,6 +4002,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
free
(
unix_name
);
}
else
WARN
(
"%s not found (%x)
\n
"
,
debugstr_us
(
attr
->
ObjectName
),
status
);
free
(
redir
.
Buffer
);
return
status
;
}
...
...
@@ -4497,38 +4535,35 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
if
(
len
>=
sizeof
(
FILE_RENAME_INFORMATION
))
{
FILE_RENAME_INFORMATION
*
info
=
ptr
;
UNICODE_STRING
name_str
,
nt_name
=
{
0
}
;
UNICODE_STRING
name_str
,
redir
;
OBJECT_ATTRIBUTES
attr
;
char
*
unix_name
;
name_str
.
Buffer
=
info
->
FileName
;
name_str
.
Length
=
info
->
FileNameLength
;
name_str
.
MaximumLength
=
info
->
FileNameLength
+
sizeof
(
WCHAR
);
InitializeObjectAttributes
(
&
attr
,
&
name_str
,
OBJ_CASE_INSENSITIVE
,
info
->
RootDirectory
,
NULL
);
get_redirect
(
&
attr
,
&
redir
);
attr
.
Length
=
sizeof
(
attr
);
attr
.
ObjectName
=
&
name_str
;
attr
.
RootDirectory
=
info
->
RootDirectory
;
attr
.
Attributes
=
OBJ_CASE_INSENSITIVE
;
io
->
u
.
Status
=
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
&
nt_name
,
FILE_OPEN_IF
);
if
(
io
->
u
.
Status
!=
STATUS_SUCCESS
&&
io
->
u
.
Status
!=
STATUS_NO_SUCH_FILE
)
break
;
SERVER_START_REQ
(
set_fd_name_info
)
io
->
u
.
Status
=
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
FILE_OPEN_IF
);
if
(
io
->
u
.
Status
==
STATUS_SUCCESS
||
io
->
u
.
Status
==
STATUS_NO_SUCH_FILE
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
rootdir
=
wine_server_obj_handle
(
attr
.
RootDirectory
);
req
->
namelen
=
nt_name
.
Length
;
req
->
link
=
FALSE
;
req
->
replace
=
info
->
ReplaceIfExists
;
wine_server_add_data
(
req
,
nt_name
.
Buffer
,
nt_name
.
Length
);
wine_server_add_data
(
req
,
unix_name
,
strlen
(
unix_name
)
);
io
->
u
.
Status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
SERVER_START_REQ
(
set_fd_name_info
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
rootdir
=
wine_server_obj_handle
(
attr
.
RootDirectory
);
req
->
namelen
=
attr
.
ObjectName
->
Length
;
req
->
link
=
FALSE
;
req
->
replace
=
info
->
ReplaceIfExists
;
wine_server_add_data
(
req
,
attr
.
ObjectName
->
Buffer
,
attr
.
ObjectName
->
Length
);
wine_server_add_data
(
req
,
unix_name
,
strlen
(
unix_name
)
);
io
->
u
.
Status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
free
(
unix_name
);
free
(
nt_name
.
Buffer
);
free
(
unix_name
);
}
free
(
redir
.
Buffer
);
}
else
io
->
u
.
Status
=
STATUS_INVALID_PARAMETER_3
;
break
;
...
...
@@ -4537,38 +4572,35 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
if
(
len
>=
sizeof
(
FILE_LINK_INFORMATION
))
{
FILE_LINK_INFORMATION
*
info
=
ptr
;
UNICODE_STRING
name_str
,
nt_name
=
{
0
}
;
UNICODE_STRING
name_str
,
redir
;
OBJECT_ATTRIBUTES
attr
;
char
*
unix_name
;
name_str
.
Buffer
=
info
->
FileName
;
name_str
.
Length
=
info
->
FileNameLength
;
name_str
.
MaximumLength
=
info
->
FileNameLength
+
sizeof
(
WCHAR
);
InitializeObjectAttributes
(
&
attr
,
&
name_str
,
OBJ_CASE_INSENSITIVE
,
info
->
RootDirectory
,
NULL
);
get_redirect
(
&
attr
,
&
redir
);
attr
.
Length
=
sizeof
(
attr
);
attr
.
ObjectName
=
&
name_str
;
attr
.
RootDirectory
=
info
->
RootDirectory
;
attr
.
Attributes
=
OBJ_CASE_INSENSITIVE
;
io
->
u
.
Status
=
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
&
nt_name
,
FILE_OPEN_IF
);
if
(
io
->
u
.
Status
!=
STATUS_SUCCESS
&&
io
->
u
.
Status
!=
STATUS_NO_SUCH_FILE
)
break
;
SERVER_START_REQ
(
set_fd_name_info
)
io
->
u
.
Status
=
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
FILE_OPEN_IF
);
if
(
io
->
u
.
Status
==
STATUS_SUCCESS
||
io
->
u
.
Status
==
STATUS_NO_SUCH_FILE
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
rootdir
=
wine_server_obj_handle
(
attr
.
RootDirectory
);
req
->
namelen
=
nt_name
.
Length
;
req
->
link
=
TRUE
;
req
->
replace
=
info
->
ReplaceIfExists
;
wine_server_add_data
(
req
,
nt_name
.
Buffer
,
nt_name
.
Length
);
wine_server_add_data
(
req
,
unix_name
,
strlen
(
unix_name
)
);
io
->
u
.
Status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
SERVER_START_REQ
(
set_fd_name_info
)
{
req
->
handle
=
wine_server_obj_handle
(
handle
);
req
->
rootdir
=
wine_server_obj_handle
(
attr
.
RootDirectory
);
req
->
namelen
=
attr
.
ObjectName
->
Length
;
req
->
link
=
TRUE
;
req
->
replace
=
info
->
ReplaceIfExists
;
wine_server_add_data
(
req
,
attr
.
ObjectName
->
Buffer
,
attr
.
ObjectName
->
Length
);
wine_server_add_data
(
req
,
unix_name
,
strlen
(
unix_name
)
);
io
->
u
.
Status
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
free
(
unix_name
);
free
(
nt_name
.
Buffer
);
free
(
unix_name
);
}
free
(
redir
.
Buffer
);
}
else
io
->
u
.
Status
=
STATUS_INVALID_PARAMETER_3
;
break
;
...
...
dlls/ntdll/unix/loader.c
View file @
7ef35b33
...
...
@@ -1105,6 +1105,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
{
static
const
WCHAR
soW
[]
=
{
'.'
,
's'
,
'o'
,
0
};
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
redir
;
pe_image_info_t
info
;
char
*
unix_name
;
NTSTATUS
status
;
...
...
@@ -1112,7 +1113,13 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
if
(
get_load_order
(
nt_name
)
==
LO_DISABLED
)
return
STATUS_DLL_NOT_FOUND
;
InitializeObjectAttributes
(
&
attr
,
nt_name
,
OBJ_CASE_INSENSITIVE
,
0
,
0
);
if
(
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
NULL
,
FILE_OPEN
))
return
STATUS_DLL_NOT_FOUND
;
get_redirect
(
&
attr
,
&
redir
);
if
(
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
FILE_OPEN
))
{
free
(
redir
.
Buffer
);
return
STATUS_DLL_NOT_FOUND
;
}
/* remove .so extension from Windows name */
len
=
nt_name
->
Length
/
sizeof
(
WCHAR
);
...
...
@@ -1120,6 +1127,7 @@ static NTSTATUS CDECL load_so_dll( UNICODE_STRING *nt_name, void **module )
status
=
dlopen_dll
(
unix_name
,
nt_name
,
module
,
&
info
,
FALSE
);
free
(
unix_name
);
free
(
redir
.
Buffer
);
return
status
;
}
...
...
@@ -1398,8 +1406,7 @@ BOOL is_builtin_path( const UNICODE_STRING *path, WORD *machine )
if
(
path
->
Length
>
wcslen
(
system_dir
)
*
sizeof
(
WCHAR
)
&&
!
wcsnicmp
(
path
->
Buffer
,
system_dir
,
wcslen
(
system_dir
)
))
{
if
(
NtCurrentTeb64
()
&&
NtCurrentTeb64
()
->
TlsSlots
[
WOW64_TLS_FILESYSREDIR
])
*
machine
=
IMAGE_FILE_MACHINE_AMD64
;
if
(
is_wow64
)
*
machine
=
IMAGE_FILE_MACHINE_AMD64
;
goto
found
;
}
if
((
is_win64
||
is_wow64
)
&&
path
->
Length
>
sizeof
(
wow64W
)
&&
...
...
@@ -1439,7 +1446,7 @@ static NTSTATUS open_main_image( WCHAR *image, void **module, SECTION_IMAGE_INFO
init_unicode_string
(
&
nt_name
,
image
);
InitializeObjectAttributes
(
&
attr
,
&
nt_name
,
OBJ_CASE_INSENSITIVE
,
0
,
NULL
);
if
(
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
NULL
,
FILE_OPEN
))
return
STATUS_DLL_NOT_FOUND
;
if
(
nt_to_unix_file_name
(
&
attr
,
&
unix_name
,
FILE_OPEN
))
return
STATUS_DLL_NOT_FOUND
;
status
=
open_dll_file
(
unix_name
,
&
attr
,
&
mapping
);
if
(
!
status
)
...
...
@@ -1536,11 +1543,13 @@ NTSTATUS load_start_exe( WCHAR **image, void **module )
{
static
const
WCHAR
startW
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
's'
,
't'
,
'a'
,
'r'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
startwow64W
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
'w'
,
'o'
,
'w'
,
'6'
,
'4'
,
'\\'
,
's'
,
't'
,
'a'
,
'r'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
UNICODE_STRING
nt_name
;
NTSTATUS
status
;
SIZE_T
size
;
init_unicode_string
(
&
nt_name
,
startW
);
init_unicode_string
(
&
nt_name
,
is_wow64
?
startwow64W
:
startW
);
status
=
find_builtin_dll
(
&
nt_name
,
module
,
&
size
,
&
main_image_info
,
current_machine
,
FALSE
);
if
(
status
)
{
...
...
dlls/ntdll/unix/process.c
View file @
7ef35b33
...
...
@@ -267,12 +267,18 @@ static NTSTATUS get_pe_file_info( OBJECT_ATTRIBUTES *attr, HANDLE *handle, pe_im
{
NTSTATUS
status
;
HANDLE
mapping
;
IO_STATUS_BLOCK
io
;
char
*
unix_name
;
*
handle
=
0
;
memset
(
info
,
0
,
sizeof
(
*
info
)
);
if
((
status
=
NtOpenFile
(
handle
,
GENERIC_READ
,
attr
,
&
io
,
FILE_SHARE_READ
|
FILE_SHARE_DELETE
,
FILE_SYNCHRONOUS_IO_NONALERT
)))
if
(
!
(
status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
FILE_OPEN
)))
{
status
=
open_unix_file
(
handle
,
unix_name
,
GENERIC_READ
,
attr
,
0
,
FILE_SHARE_READ
|
FILE_SHARE_DELETE
,
FILE_OPEN
,
FILE_SYNCHRONOUS_IO_NONALERT
,
NULL
,
0
);
free
(
unix_name
);
}
if
(
status
)
{
if
(
is_builtin_path
(
attr
->
ObjectName
,
&
info
->
machine
))
{
...
...
@@ -479,7 +485,7 @@ static NTSTATUS fork_and_exec( OBJECT_ATTRIBUTES *attr, int unixdir,
char
*
unix_name
;
NTSTATUS
status
;
status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
NULL
,
FILE_OPEN
);
status
=
nt_to_unix_file_name
(
attr
,
&
unix_name
,
FILE_OPEN
);
if
(
status
)
return
status
;
#ifdef HAVE_PIPE2
...
...
@@ -613,7 +619,7 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
pe_image_info_t
pe_info
;
CLIENT_ID
id
;
HANDLE
parent
=
0
,
debug
=
0
,
token
=
0
;
UNICODE_STRING
path
=
{
0
};
UNICODE_STRING
redir
,
path
=
{
0
};
OBJECT_ATTRIBUTES
attr
,
empty_attr
=
{
sizeof
(
empty_attr
)
};
SIZE_T
i
,
attr_count
=
(
ps_attr
->
TotalLength
-
sizeof
(
ps_attr
->
TotalLength
))
/
sizeof
(
PS_ATTRIBUTE
);
const
PS_ATTRIBUTE
*
handles_attr
=
NULL
;
...
...
@@ -655,16 +661,19 @@ NTSTATUS WINAPI NtCreateUserProcess( HANDLE *process_handle_ptr, HANDLE *thread_
unixdir
=
get_unix_curdir
(
params
);
InitializeObjectAttributes
(
&
attr
,
&
path
,
OBJ_CASE_INSENSITIVE
,
0
,
0
);
get_redirect
(
&
attr
,
&
redir
);
if
((
status
=
get_pe_file_info
(
&
attr
,
&
file_handle
,
&
pe_info
)))
{
if
(
status
==
STATUS_INVALID_IMAGE_NOT_MZ
&&
!
fork_and_exec
(
&
attr
,
unixdir
,
params
))
{
memset
(
info
,
0
,
sizeof
(
*
info
)
);
free
(
redir
.
Buffer
);
return
STATUS_SUCCESS
;
}
goto
done
;
}
if
(
!
(
startup_info
=
create_startup_info
(
params
,
&
startup_info_size
)))
goto
done
;
if
(
!
(
startup_info
=
create_startup_info
(
attr
.
ObjectName
,
params
,
&
startup_info_size
)))
goto
done
;
env_size
=
get_env_size
(
params
,
&
winedebug
);
if
((
status
=
alloc_object_attributes
(
process_attr
,
&
objattr
,
&
attr_len
)))
goto
done
;
...
...
@@ -830,6 +839,7 @@ done:
if
(
unixdir
!=
-
1
)
close
(
unixdir
);
free
(
startup_info
);
free
(
winedebug
);
free
(
redir
.
Buffer
);
return
status
;
}
...
...
dlls/ntdll/unix/unix_private.h
View file @
7ef35b33
...
...
@@ -141,7 +141,8 @@ extern struct ldt_copy __wine_ldt_copy DECLSPEC_HIDDEN;
extern
void
init_environment
(
int
argc
,
char
*
argv
[],
char
*
envp
[]
)
DECLSPEC_HIDDEN
;
extern
void
init_startup_info
(
void
)
DECLSPEC_HIDDEN
;
extern
void
*
create_startup_info
(
const
RTL_USER_PROCESS_PARAMETERS
*
params
,
DWORD
*
info_size
)
DECLSPEC_HIDDEN
;
extern
void
*
create_startup_info
(
const
UNICODE_STRING
*
nt_image
,
const
RTL_USER_PROCESS_PARAMETERS
*
params
,
DWORD
*
info_size
)
DECLSPEC_HIDDEN
;
extern
DWORD
ntdll_umbstowcs
(
const
char
*
src
,
DWORD
srclen
,
WCHAR
*
dst
,
DWORD
dstlen
)
DECLSPEC_HIDDEN
;
extern
int
ntdll_wcstoumbs
(
const
WCHAR
*
src
,
DWORD
srclen
,
char
*
dst
,
DWORD
dstlen
,
BOOL
strict
)
DECLSPEC_HIDDEN
;
extern
char
**
build_envp
(
const
WCHAR
*
envW
)
DECLSPEC_HIDDEN
;
...
...
@@ -250,8 +251,8 @@ extern NTSTATUS tape_DeviceIoControl( HANDLE device, HANDLE event, PIO_APC_ROUTI
ULONG
in_size
,
void
*
out_buffer
,
ULONG
out_size
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
errno_to_status
(
int
err
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
nt_to_unix_file_name
(
const
OBJECT_ATTRIBUTES
*
attr
,
char
**
name_ret
,
UNICODE_STRING
*
nt_name
,
UINT
disposition
)
DECLSPEC_HIDDEN
;
extern
BOOL
get_redirect
(
OBJECT_ATTRIBUTES
*
attr
,
UNICODE_STRING
*
redir
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
nt_to_unix_file_name
(
const
OBJECT_ATTRIBUTES
*
attr
,
char
**
name_ret
,
UINT
disposition
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
unix_to_nt_file_name
(
const
char
*
name
,
WCHAR
**
nt
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
get_full_path
(
const
WCHAR
*
name
,
const
WCHAR
*
curdir
,
WCHAR
**
path
)
DECLSPEC_HIDDEN
;
extern
NTSTATUS
open_unix_file
(
HANDLE
*
handle
,
const
char
*
unix_name
,
ACCESS_MASK
access
,
...
...
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