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
461b5e56
Commit
461b5e56
authored
Nov 05, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move support for running wineboot to ntdll.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
326df4c1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
96 additions
and
312 deletions
+96
-312
process.c
dlls/kernel32/process.c
+0
-294
env.c
dlls/ntdll/env.c
+88
-12
wineboot.c
programs/wineboot/wineboot.c
+8
-6
No files found.
dlls/kernel32/process.c
View file @
461b5e56
...
...
@@ -449,156 +449,6 @@ static BOOL find_exe_file( const WCHAR *name, WCHAR *buffer, int buflen, HANDLE
/***********************************************************************
* set_registry_variables
*
* Set environment variables by enumerating the values of a key;
* helper for set_registry_environment().
* Note that Windows happily truncates the value if it's too big.
*/
static
void
set_registry_variables
(
HANDLE
hkey
,
ULONG
type
)
{
static
const
WCHAR
pathW
[]
=
{
'P'
,
'A'
,
'T'
,
'H'
};
static
const
WCHAR
sep
[]
=
{
';'
,
0
};
UNICODE_STRING
env_name
,
env_value
;
NTSTATUS
status
;
DWORD
size
;
int
index
;
char
buffer
[
1024
*
sizeof
(
WCHAR
)
+
sizeof
(
KEY_VALUE_FULL_INFORMATION
)];
WCHAR
tmpbuf
[
1024
];
UNICODE_STRING
tmp
;
KEY_VALUE_FULL_INFORMATION
*
info
=
(
KEY_VALUE_FULL_INFORMATION
*
)
buffer
;
tmp
.
Buffer
=
tmpbuf
;
tmp
.
MaximumLength
=
sizeof
(
tmpbuf
);
for
(
index
=
0
;
;
index
++
)
{
status
=
NtEnumerateValueKey
(
hkey
,
index
,
KeyValueFullInformation
,
buffer
,
sizeof
(
buffer
),
&
size
);
if
(
status
!=
STATUS_SUCCESS
&&
status
!=
STATUS_BUFFER_OVERFLOW
)
break
;
if
(
info
->
Type
!=
type
)
continue
;
env_name
.
Buffer
=
info
->
Name
;
env_name
.
Length
=
env_name
.
MaximumLength
=
info
->
NameLength
;
env_value
.
Buffer
=
(
WCHAR
*
)(
buffer
+
info
->
DataOffset
);
env_value
.
Length
=
info
->
DataLength
;
env_value
.
MaximumLength
=
sizeof
(
buffer
)
-
info
->
DataOffset
;
if
(
env_value
.
Length
&&
!
env_value
.
Buffer
[
env_value
.
Length
/
sizeof
(
WCHAR
)
-
1
])
env_value
.
Length
-=
sizeof
(
WCHAR
);
/* don't count terminating null if any */
if
(
!
env_value
.
Length
)
continue
;
if
(
info
->
Type
==
REG_EXPAND_SZ
)
{
status
=
RtlExpandEnvironmentStrings_U
(
NULL
,
&
env_value
,
&
tmp
,
NULL
);
if
(
status
!=
STATUS_SUCCESS
&&
status
!=
STATUS_BUFFER_OVERFLOW
)
continue
;
RtlCopyUnicodeString
(
&
env_value
,
&
tmp
);
}
/* PATH is magic */
if
(
env_name
.
Length
==
sizeof
(
pathW
)
&&
!
strncmpiW
(
env_name
.
Buffer
,
pathW
,
ARRAY_SIZE
(
pathW
))
&&
!
RtlQueryEnvironmentVariable_U
(
NULL
,
&
env_name
,
&
tmp
))
{
RtlAppendUnicodeToString
(
&
tmp
,
sep
);
if
(
RtlAppendUnicodeStringToString
(
&
tmp
,
&
env_value
))
continue
;
RtlCopyUnicodeString
(
&
env_value
,
&
tmp
);
}
RtlSetEnvironmentVariable
(
NULL
,
&
env_name
,
&
env_value
);
}
}
/***********************************************************************
* has_registry_environment
*/
static
BOOL
has_registry_environment
(
void
)
{
static
const
WCHAR
env_keyW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'\\'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'S'
,
'e'
,
't'
,
'\\'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'\\'
,
'S'
,
'e'
,
's'
,
's'
,
'i'
,
'o'
,
'n'
,
' '
,
'M'
,
'a'
,
'n'
,
'a'
,
'g'
,
'e'
,
'r'
,
'\\'
,
'E'
,
'n'
,
'v'
,
'i'
,
'r'
,
'o'
,
'n'
,
'm'
,
'e'
,
'n'
,
't'
,
0
};
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
;
HANDLE
hkey
;
BOOL
ret
;
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
0
,
0
,
NULL
);
RtlInitUnicodeString
(
&
nameW
,
env_keyW
);
ret
=
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
);
if
(
ret
)
NtClose
(
hkey
);
return
ret
;
}
/***********************************************************************
* set_registry_environment
*
* Set the environment variables specified in the registry.
*
* Note: Windows handles REG_SZ and REG_EXPAND_SZ in one pass with the
* consequence that REG_EXPAND_SZ cannot be used reliably as it depends
* on the order in which the variables are processed. But on Windows it
* does not really matter since they only use %SystemDrive% and
* %SystemRoot% which are predefined. But Wine defines these in the
* registry, so we need two passes.
*/
static
void
set_registry_environment
(
BOOL
volatile_only
)
{
static
const
WCHAR
env_keyW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'S'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'\\'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'S'
,
'e'
,
't'
,
'\\'
,
'C'
,
'o'
,
'n'
,
't'
,
'r'
,
'o'
,
'l'
,
'\\'
,
'S'
,
'e'
,
's'
,
's'
,
'i'
,
'o'
,
'n'
,
' '
,
'M'
,
'a'
,
'n'
,
'a'
,
'g'
,
'e'
,
'r'
,
'\\'
,
'E'
,
'n'
,
'v'
,
'i'
,
'r'
,
'o'
,
'n'
,
'm'
,
'e'
,
'n'
,
't'
,
0
};
static
const
WCHAR
envW
[]
=
{
'E'
,
'n'
,
'v'
,
'i'
,
'r'
,
'o'
,
'n'
,
'm'
,
'e'
,
'n'
,
't'
,
0
};
static
const
WCHAR
volatile_envW
[]
=
{
'V'
,
'o'
,
'l'
,
'a'
,
't'
,
'i'
,
'l'
,
'e'
,
' '
,
'E'
,
'n'
,
'v'
,
'i'
,
'r'
,
'o'
,
'n'
,
'm'
,
'e'
,
'n'
,
't'
,
0
};
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
;
HANDLE
hkey
;
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
ObjectName
=
&
nameW
;
attr
.
Attributes
=
0
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
/* first the system environment variables */
RtlInitUnicodeString
(
&
nameW
,
env_keyW
);
if
(
!
volatile_only
&&
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
)
==
STATUS_SUCCESS
)
{
set_registry_variables
(
hkey
,
REG_SZ
);
set_registry_variables
(
hkey
,
REG_EXPAND_SZ
);
NtClose
(
hkey
);
}
/* then the ones for the current user */
if
(
RtlOpenCurrentUser
(
KEY_READ
,
&
attr
.
RootDirectory
)
!=
STATUS_SUCCESS
)
return
;
RtlInitUnicodeString
(
&
nameW
,
envW
);
if
(
!
volatile_only
&&
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
)
==
STATUS_SUCCESS
)
{
set_registry_variables
(
hkey
,
REG_SZ
);
set_registry_variables
(
hkey
,
REG_EXPAND_SZ
);
NtClose
(
hkey
);
}
RtlInitUnicodeString
(
&
nameW
,
volatile_envW
);
if
(
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
)
==
STATUS_SUCCESS
)
{
set_registry_variables
(
hkey
,
REG_SZ
);
set_registry_variables
(
hkey
,
REG_EXPAND_SZ
);
NtClose
(
hkey
);
}
NtClose
(
attr
.
RootDirectory
);
}
/***********************************************************************
* get_reg_value
*/
static
WCHAR
*
get_reg_value
(
HKEY
hkey
,
const
WCHAR
*
name
)
...
...
@@ -659,71 +509,6 @@ static void set_wine_path_variable( const WCHAR *name, const char *unix_path )
/***********************************************************************
* set_additional_environment
*
* Set some additional environment variables not specified in the registry.
*/
static
void
set_additional_environment
(
void
)
{
static
const
WCHAR
profile_keyW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
'S'
,
'o'
,
'f'
,
't'
,
'w'
,
'a'
,
'r'
,
'e'
,
'\\'
,
'M'
,
'i'
,
'c'
,
'r'
,
'o'
,
's'
,
'o'
,
'f'
,
't'
,
'\\'
,
'W'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
' '
,
'N'
,
'T'
,
'\\'
,
'C'
,
'u'
,
'r'
,
'r'
,
'e'
,
'n'
,
't'
,
'V'
,
'e'
,
'r'
,
's'
,
'i'
,
'o'
,
'n'
,
'\\'
,
'P'
,
'r'
,
'o'
,
'f'
,
'i'
,
'l'
,
'e'
,
'L'
,
'i'
,
's'
,
't'
,
0
};
static
const
WCHAR
profiles_valueW
[]
=
{
'P'
,
'r'
,
'o'
,
'f'
,
'i'
,
'l'
,
'e'
,
's'
,
'D'
,
'i'
,
'r'
,
'e'
,
'c'
,
't'
,
'o'
,
'r'
,
'y'
,
0
};
static
const
WCHAR
public_valueW
[]
=
{
'P'
,
'u'
,
'b'
,
'l'
,
'i'
,
'c'
,
0
};
static
const
WCHAR
computernameW
[]
=
{
'C'
,
'O'
,
'M'
,
'P'
,
'U'
,
'T'
,
'E'
,
'R'
,
'N'
,
'A'
,
'M'
,
'E'
,
0
};
static
const
WCHAR
allusersW
[]
=
{
'A'
,
'L'
,
'L'
,
'U'
,
'S'
,
'E'
,
'R'
,
'S'
,
'P'
,
'R'
,
'O'
,
'F'
,
'I'
,
'L'
,
'E'
,
0
};
static
const
WCHAR
programdataW
[]
=
{
'P'
,
'r'
,
'o'
,
'g'
,
'r'
,
'a'
,
'm'
,
'D'
,
'a'
,
't'
,
'a'
,
0
};
static
const
WCHAR
publicW
[]
=
{
'P'
,
'U'
,
'B'
,
'L'
,
'I'
,
'C'
,
0
};
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
;
WCHAR
*
profile_dir
=
NULL
,
*
program_data_dir
=
NULL
,
*
public_dir
=
NULL
;
WCHAR
buf
[
32
];
HANDLE
hkey
;
DWORD
len
;
/* ComputerName */
len
=
ARRAY_SIZE
(
buf
);
if
(
GetComputerNameW
(
buf
,
&
len
))
SetEnvironmentVariableW
(
computernameW
,
buf
);
/* set the ALLUSERSPROFILE variables */
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
ObjectName
=
&
nameW
;
attr
.
Attributes
=
0
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
RtlInitUnicodeString
(
&
nameW
,
profile_keyW
);
if
(
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
))
{
profile_dir
=
get_reg_value
(
hkey
,
profiles_valueW
);
program_data_dir
=
get_reg_value
(
hkey
,
programdataW
);
public_dir
=
get_reg_value
(
hkey
,
public_valueW
);
NtClose
(
hkey
);
}
if
(
program_data_dir
)
{
SetEnvironmentVariableW
(
allusersW
,
program_data_dir
);
SetEnvironmentVariableW
(
programdataW
,
program_data_dir
);
}
if
(
public_dir
)
{
SetEnvironmentVariableW
(
publicW
,
public_dir
);
}
HeapFree
(
GetProcessHeap
(),
0
,
profile_dir
);
HeapFree
(
GetProcessHeap
(),
0
,
program_data_dir
);
HeapFree
(
GetProcessHeap
(),
0
,
public_dir
);
}
/***********************************************************************
* set_wow64_environment
*
* Set the environment variables that change across 32/64/Wow64.
...
...
@@ -883,61 +668,6 @@ static void init_windows_dirs(void)
}
/***********************************************************************
* start_wineboot
*
* Start the wineboot process if necessary. Return the handles to wait on.
*/
static
void
start_wineboot
(
HANDLE
handles
[
2
]
)
{
static
const
WCHAR
wineboot_eventW
[]
=
{
'_'
,
'_'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'_'
,
'e'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
handles
[
1
]
=
0
;
if
(
!
(
handles
[
0
]
=
CreateEventW
(
NULL
,
TRUE
,
FALSE
,
wineboot_eventW
)))
{
ERR
(
"failed to create wineboot event, expect trouble
\n
"
);
return
;
}
if
(
GetLastError
()
!=
ERROR_ALREADY_EXISTS
)
/* we created it */
{
static
const
WCHAR
wineboot
[]
=
{
'\\'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
args
[]
=
{
' '
,
'-'
,
'-'
,
'i'
,
'n'
,
'i'
,
't'
,
0
};
STARTUPINFOW
si
;
PROCESS_INFORMATION
pi
;
void
*
redir
;
WCHAR
app
[
MAX_PATH
];
WCHAR
cmdline
[
MAX_PATH
+
ARRAY_SIZE
(
wineboot
)
+
ARRAY_SIZE
(
args
)];
memset
(
&
si
,
0
,
sizeof
(
si
)
);
si
.
cb
=
sizeof
(
si
);
si
.
dwFlags
=
STARTF_USESTDHANDLES
;
si
.
hStdInput
=
0
;
si
.
hStdOutput
=
0
;
si
.
hStdError
=
GetStdHandle
(
STD_ERROR_HANDLE
);
GetSystemDirectoryW
(
app
,
MAX_PATH
-
ARRAY_SIZE
(
wineboot
));
lstrcatW
(
app
,
wineboot
);
Wow64DisableWow64FsRedirection
(
&
redir
);
strcpyW
(
cmdline
,
app
);
strcatW
(
cmdline
,
args
);
if
(
CreateProcessW
(
app
,
cmdline
,
NULL
,
NULL
,
FALSE
,
DETACHED_PROCESS
,
NULL
,
NULL
,
&
si
,
&
pi
))
{
TRACE
(
"started wineboot pid %04x tid %04x
\n
"
,
pi
.
dwProcessId
,
pi
.
dwThreadId
);
CloseHandle
(
pi
.
hThread
);
handles
[
1
]
=
pi
.
hProcess
;
}
else
{
ERR
(
"failed to start wineboot, err %u
\n
"
,
GetLastError
()
);
CloseHandle
(
handles
[
0
]
);
handles
[
0
]
=
0
;
}
Wow64RevertWow64FsRedirection
(
redir
);
}
}
#ifdef __i386__
extern
DWORD
call_process_entry
(
PEB
*
peb
,
LPTHREAD_START_ROUTINE
entry
);
__ASM_GLOBAL_FUNC
(
call_process_entry
,
...
...
@@ -1026,8 +756,6 @@ void * CDECL __wine_kernel_init(void)
WCHAR
*
p
,
main_exe_name
[
MAX_PATH
+
1
];
PEB
*
peb
=
NtCurrentTeb
()
->
Peb
;
RTL_USER_PROCESS_PARAMETERS
*
params
=
peb
->
ProcessParameters
;
HANDLE
boot_events
[
2
];
BOOL
got_environment
=
TRUE
;
/* Initialize everything */
...
...
@@ -1039,15 +767,7 @@ void * CDECL __wine_kernel_init(void)
LOCALE_Init
();
init_windows_dirs
();
boot_events
[
0
]
=
boot_events
[
1
]
=
0
;
if
(
!
peb
->
ProcessParameters
->
WindowTitle
.
Buffer
)
{
/* convert old configuration to new format */
convert_old_config
();
got_environment
=
has_registry_environment
();
start_wineboot
(
boot_events
);
}
/* if there's no extension, append a dot to prevent LoadLibrary from appending .dll */
strcpyW
(
main_exe_name
,
peb
->
ProcessParameters
->
ImagePathName
.
Buffer
);
...
...
@@ -1057,20 +777,6 @@ void * CDECL __wine_kernel_init(void)
TRACE
(
"starting process name=%s argv[0]=%s
\n
"
,
debugstr_w
(
main_exe_name
),
debugstr_w
(
__wine_main_wargv
[
0
])
);
if
(
boot_events
[
0
])
{
DWORD
timeout
=
2
*
60
*
1000
,
count
=
1
;
if
(
boot_events
[
1
])
count
++
;
if
(
!
got_environment
)
timeout
=
5
*
60
*
1000
;
/* initial prefix creation can take longer */
if
(
WaitForMultipleObjects
(
count
,
boot_events
,
FALSE
,
timeout
)
==
WAIT_TIMEOUT
)
ERR
(
"boot event wait timed out
\n
"
);
CloseHandle
(
boot_events
[
0
]
);
if
(
boot_events
[
1
])
CloseHandle
(
boot_events
[
1
]
);
/* reload environment now that wineboot has run */
set_registry_environment
(
got_environment
);
set_additional_environment
();
}
set_wow64_environment
();
set_library_argv
(
__wine_main_wargv
);
...
...
dlls/ntdll/env.c
View file @
461b5e56
...
...
@@ -51,6 +51,8 @@ static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
static
const
WCHAR
windows_dir
[]
=
{
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
0
};
static
BOOL
first_prefix_start
;
/* first ever process start in this prefix? */
static
inline
SIZE_T
get_env_length
(
const
WCHAR
*
env
)
{
const
WCHAR
*
end
=
env
;
...
...
@@ -153,7 +155,7 @@ static void set_registry_variables( WCHAR **env, HANDLE hkey, ULONG type )
* %SystemRoot% which are predefined. But Wine defines these in the
* registry, so we need two passes.
*/
static
void
set_registry_environment
(
WCHAR
**
env
)
static
BOOL
set_registry_environment
(
WCHAR
**
env
,
BOOL
first_time
)
{
static
const
WCHAR
env_keyW
[]
=
{
'\\'
,
'R'
,
'e'
,
'g'
,
'i'
,
's'
,
't'
,
'r'
,
'y'
,
'\\'
,
'M'
,
'a'
,
'c'
,
'h'
,
'i'
,
'n'
,
'e'
,
'\\'
,
...
...
@@ -168,27 +170,23 @@ static void set_registry_environment( WCHAR **env )
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
;
HANDLE
hkey
;
attr
.
Length
=
sizeof
(
attr
);
attr
.
RootDirectory
=
0
;
attr
.
ObjectName
=
&
nameW
;
attr
.
Attributes
=
0
;
attr
.
SecurityDescriptor
=
NULL
;
attr
.
SecurityQualityOfService
=
NULL
;
BOOL
ret
=
FALSE
;
/* first the system environment variables */
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
0
,
0
,
NULL
);
RtlInitUnicodeString
(
&
nameW
,
env_keyW
);
if
(
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
))
if
(
first_time
&&
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
))
{
set_registry_variables
(
env
,
hkey
,
REG_SZ
);
set_registry_variables
(
env
,
hkey
,
REG_EXPAND_SZ
);
NtClose
(
hkey
);
}
else
ret
=
TRUE
;
/* then the ones for the current user */
if
(
RtlOpenCurrentUser
(
KEY_READ
,
&
attr
.
RootDirectory
)
!=
STATUS_SUCCESS
)
return
;
if
(
RtlOpenCurrentUser
(
KEY_READ
,
&
attr
.
RootDirectory
)
!=
STATUS_SUCCESS
)
return
ret
;
RtlInitUnicodeString
(
&
nameW
,
envW
);
if
(
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
))
if
(
first_time
&&
!
NtOpenKey
(
&
hkey
,
KEY_READ
,
&
attr
))
{
set_registry_variables
(
env
,
hkey
,
REG_SZ
);
set_registry_variables
(
env
,
hkey
,
REG_EXPAND_SZ
);
...
...
@@ -204,6 +202,7 @@ static void set_registry_environment( WCHAR **env )
}
NtClose
(
attr
.
RootDirectory
);
return
ret
;
}
...
...
@@ -365,7 +364,7 @@ static WCHAR *build_initial_environment( char **env )
p
+=
strlenW
(
p
)
+
1
;
}
*
p
=
0
;
set_registry_environment
(
&
ptr
);
first_prefix_start
=
set_registry_environment
(
&
ptr
,
TRUE
);
set_additional_environment
(
&
ptr
);
return
ptr
;
}
...
...
@@ -1133,6 +1132,81 @@ static inline void get_unicode_string( UNICODE_STRING *str, WCHAR **src, UINT le
*
src
+=
len
/
sizeof
(
WCHAR
);
}
/***********************************************************************
* run_wineboot
*/
static
void
run_wineboot
(
WCHAR
**
env
)
{
static
const
WCHAR
wineboot_eventW
[]
=
{
'\\'
,
'K'
,
'e'
,
'r'
,
'n'
,
'e'
,
'l'
,
'O'
,
'b'
,
'j'
,
'e'
,
'c'
,
't'
,
's'
,
'\\'
,
'_'
,
'_'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'_'
,
'e'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
static
const
WCHAR
wineboot
[]
=
{
'\\'
,
'?'
,
'?'
,
'\\'
,
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
0
};
static
const
WCHAR
cmdline
[]
=
{
'C'
,
':'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'd'
,
'o'
,
'w'
,
's'
,
'\\'
,
's'
,
'y'
,
's'
,
't'
,
'e'
,
'm'
,
'3'
,
'2'
,
'\\'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'.'
,
'e'
,
'x'
,
'e'
,
' '
,
'-'
,
'-'
,
'i'
,
'n'
,
'i'
,
't'
,
0
};
UNICODE_STRING
nameW
,
cmdlineW
,
dllpathW
;
RTL_USER_PROCESS_PARAMETERS
*
params
;
RTL_USER_PROCESS_INFORMATION
info
;
WCHAR
*
load_path
,
*
dummy
;
OBJECT_ATTRIBUTES
attr
;
LARGE_INTEGER
timeout
;
HANDLE
handles
[
2
];
NTSTATUS
status
;
ULONG
redir
=
0
;
int
count
=
1
;
RtlInitUnicodeString
(
&
nameW
,
wineboot_eventW
);
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
OBJ_OPENIF
,
0
,
NULL
);
status
=
NtCreateEvent
(
&
handles
[
0
],
EVENT_ALL_ACCESS
,
&
attr
,
NotificationEvent
,
0
);
if
(
status
==
STATUS_OBJECT_NAME_EXISTS
)
goto
wait
;
if
(
status
)
{
ERR
(
"failed to create wineboot event, expect trouble
\n
"
);
return
;
}
LdrGetDllPath
(
wineboot
+
4
,
LOAD_WITH_ALTERED_SEARCH_PATH
,
&
load_path
,
&
dummy
);
RtlInitUnicodeString
(
&
nameW
,
wineboot
+
4
);
RtlInitUnicodeString
(
&
dllpathW
,
load_path
);
RtlInitUnicodeString
(
&
cmdlineW
,
cmdline
);
RtlCreateProcessParametersEx
(
&
params
,
&
nameW
,
&
dllpathW
,
NULL
,
&
cmdlineW
,
*
env
,
NULL
,
NULL
,
NULL
,
NULL
,
PROCESS_PARAMS_FLAG_NORMALIZED
);
params
->
hStdInput
=
0
;
params
->
hStdOutput
=
0
;
params
->
hStdError
=
NtCurrentTeb
()
->
Peb
->
ProcessParameters
->
hStdError
;
RtlInitUnicodeString
(
&
nameW
,
wineboot
);
RtlWow64EnableFsRedirectionEx
(
TRUE
,
&
redir
);
status
=
RtlCreateUserProcess
(
&
nameW
,
OBJ_CASE_INSENSITIVE
,
params
,
NULL
,
NULL
,
0
,
FALSE
,
0
,
0
,
&
info
);
RtlWow64EnableFsRedirection
(
!
redir
);
RtlReleasePath
(
load_path
);
RtlDestroyProcessParameters
(
params
);
if
(
status
)
{
ERR
(
"failed to start wineboot %x
\n
"
,
status
);
NtClose
(
handles
[
0
]
);
return
;
}
NtResumeThread
(
info
.
Thread
,
NULL
);
NtClose
(
info
.
Thread
);
handles
[
count
++
]
=
info
.
Process
;
wait:
timeout
.
QuadPart
=
(
ULONGLONG
)(
first_prefix_start
?
5
:
2
)
*
60
*
1000
*
-
10000
;
if
(
NtWaitForMultipleObjects
(
count
,
handles
,
TRUE
,
FALSE
,
&
timeout
)
==
WAIT_TIMEOUT
)
ERR
(
"boot event wait timed out
\n
"
);
while
(
count
)
NtClose
(
handles
[
--
count
]
);
/* reload environment now that wineboot has run */
set_registry_environment
(
env
,
first_prefix_start
);
set_additional_environment
(
env
);
}
/***********************************************************************
* init_user_process_params
*
...
...
@@ -1173,6 +1247,8 @@ void init_user_process_params( SIZE_T data_size )
if
(
!
isatty
(
2
))
wine_server_fd_to_handle
(
2
,
GENERIC_WRITE
|
SYNCHRONIZE
,
OBJ_INHERIT
,
&
params
->
hStdError
);
params
->
wShowWindow
=
1
;
/* SW_SHOWNORMAL */
run_wineboot
(
&
params
->
Environment
);
goto
done
;
}
...
...
programs/wineboot/wineboot.c
View file @
461b5e56
...
...
@@ -1278,13 +1278,15 @@ int __cdecl main( int argc, char *argv[] )
static
const
WCHAR
RunOnceW
[]
=
{
'R'
,
'u'
,
'n'
,
'O'
,
'n'
,
'c'
,
'e'
,
0
};
static
const
WCHAR
RunServicesW
[]
=
{
'R'
,
'u'
,
'n'
,
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
0
};
static
const
WCHAR
RunServicesOnceW
[]
=
{
'R'
,
'u'
,
'n'
,
'S'
,
'e'
,
'r'
,
'v'
,
'i'
,
'c'
,
'e'
,
's'
,
'O'
,
'n'
,
'c'
,
'e'
,
0
};
static
const
WCHAR
wineboot_eventW
[]
=
{
'_'
,
'_'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'_'
,
'e'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
static
const
WCHAR
wineboot_eventW
[]
=
{
'\\'
,
'K'
,
'e'
,
'r'
,
'n'
,
'e'
,
'l'
,
'O'
,
'b'
,
'j'
,
'e'
,
'c'
,
't'
,
's'
,
'\\'
,
'_'
,
'_'
,
'w'
,
'i'
,
'n'
,
'e'
,
'b'
,
'o'
,
'o'
,
't'
,
'_'
,
'e'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
/* First, set the current directory to SystemRoot */
int
i
,
j
;
BOOL
end_session
,
force
,
init
,
kill
,
restart
,
shutdown
,
update
;
HANDLE
event
;
SECURITY_ATTRIBUTES
sa
;
OBJECT_ATTRIBUTES
attr
;
UNICODE_STRING
nameW
;
BOOL
is_wow64
;
end_session
=
force
=
init
=
kill
=
restart
=
shutdown
=
update
=
FALSE
;
...
...
@@ -1362,10 +1364,10 @@ int __cdecl main( int argc, char *argv[] )
if
(
shutdown
)
return
0
;
sa
.
nLength
=
sizeof
(
sa
);
sa
.
lpSecurityDescriptor
=
NULL
;
sa
.
bInheritHandle
=
TRUE
;
/* so that services.exe inherits it */
event
=
CreateEventW
(
&
sa
,
TRUE
,
FALSE
,
wineboot_eventW
);
/* create event to be inherited by services.exe */
InitializeObjectAttributes
(
&
attr
,
&
nameW
,
OBJ_OPENIF
|
OBJ_INHERIT
,
0
,
NULL
)
;
RtlInitUnicodeString
(
&
nameW
,
wineboot_eventW
);
NtCreateEvent
(
&
event
,
EVENT_ALL_ACCESS
,
&
attr
,
NotificationEvent
,
0
);
ResetEvent
(
event
);
/* in case this is a restart */
...
...
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