wineboot: Start services.exe on startup instead of on demand in the advapi32 services code.

This commit is contained in:
Rob Shearman 2008-04-01 12:48:46 +01:00 committed by Alexandre Julliard
parent e4c8d763c9
commit 9bc84d81df
2 changed files with 45 additions and 61 deletions

View file

@ -244,78 +244,18 @@ static inline DWORD multisz_cb(LPCWSTR wmultisz)
}
/******************************************************************************
* RPC connection with servies.exe
* RPC connection with services.exe
*/
static BOOL check_services_exe(void)
{
static const WCHAR svcctl_started_event[] = SVCCTL_STARTED_EVENT;
HANDLE hEvent = OpenEventW(SYNCHRONIZE, FALSE, svcctl_started_event);
if (hEvent == NULL) /* need to start services.exe */
{
static const WCHAR services[] = {'\\','s','e','r','v','i','c','e','s','.','e','x','e',0};
PROCESS_INFORMATION out;
STARTUPINFOW si;
HANDLE wait_handles[2];
WCHAR path[MAX_PATH];
if (!GetSystemDirectoryW(path, MAX_PATH - strlenW(services)))
return FALSE;
strcatW(path, services);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcessW(path, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &out))
{
ERR("Couldn't start services.exe: error %u\n", GetLastError());
return FALSE;
}
CloseHandle(out.hThread);
hEvent = CreateEventW(NULL, TRUE, FALSE, svcctl_started_event);
wait_handles[0] = hEvent;
wait_handles[1] = out.hProcess;
/* wait for the event to become available or the process to exit */
if ((WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE)) == WAIT_OBJECT_0 + 1)
{
DWORD exit_code;
GetExitCodeProcess(out.hProcess, &exit_code);
ERR("Unexpected termination of services.exe - exit code %d\n", exit_code);
CloseHandle(out.hProcess);
CloseHandle(hEvent);
return FALSE;
}
TRACE("services.exe started successfully\n");
CloseHandle(out.hProcess);
CloseHandle(hEvent);
return TRUE;
}
TRACE("Waiting for services.exe to be available\n");
WaitForSingleObject(hEvent, INFINITE);
TRACE("Services.exe are available\n");
CloseHandle(hEvent);
return TRUE;
}
handle_t __RPC_USER MACHINE_HANDLEW_bind(MACHINE_HANDLEW MachineName)
{
WCHAR transport[] = SVCCTL_TRANSPORT;
WCHAR endpoint[] = SVCCTL_ENDPOINT;
LPWSTR server_copy = NULL;
RPC_WSTR binding_str;
RPC_STATUS status;
handle_t rpc_handle;
/* unlike Windows we start services.exe on demand. We start it always as
* checking if this is our address can be tricky */
if (!check_services_exe())
return NULL;
status = RpcStringBindingComposeW(NULL, transport, (RPC_WSTR)MachineName, endpoint, NULL, &binding_str);
HeapFree(GetProcessHeap(), 0, server_copy);
if (status != RPC_S_OK)
{
ERR("RpcStringBindingComposeW failed (%d)\n", (DWORD)status);

View file

@ -61,6 +61,7 @@
# include <getopt.h>
#endif
#include <windows.h>
#include <wine/svcctl.h>
#include <wine/unicode.h>
#include <wine/debug.h>
@ -542,6 +543,46 @@ static int ProcessWindowsFileProtection(void)
return 1;
}
static BOOL start_services_process(void)
{
static const WCHAR svcctl_started_event[] = SVCCTL_STARTED_EVENT;
static const WCHAR services[] = {'\\','s','e','r','v','i','c','e','s','.','e','x','e',0};
PROCESS_INFORMATION pi;
STARTUPINFOW si;
HANDLE wait_handles[2];
WCHAR path[MAX_PATH];
if (!GetSystemDirectoryW(path, MAX_PATH - strlenW(services)))
return FALSE;
strcatW(path, services);
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
if (!CreateProcessW(path, path, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
WINE_ERR("Couldn't start services.exe: error %u\n", GetLastError());
return FALSE;
}
CloseHandle(pi.hThread);
wait_handles[0] = CreateEventW(NULL, TRUE, FALSE, svcctl_started_event);
wait_handles[1] = pi.hProcess;
/* wait for the event to become available or the process to exit */
if ((WaitForMultipleObjects(2, wait_handles, FALSE, INFINITE)) == WAIT_OBJECT_0 + 1)
{
DWORD exit_code;
GetExitCodeProcess(pi.hProcess, &exit_code);
WINE_ERR("Unexpected termination of services.exe - exit code %d\n", exit_code);
CloseHandle(pi.hProcess);
CloseHandle(wait_handles[0]);
return FALSE;
}
CloseHandle(pi.hProcess);
CloseHandle(wait_handles[0]);
return TRUE;
}
/* start services */
static void start_services(void)
{
@ -554,6 +595,9 @@ static void start_services(void)
WCHAR name[MAX_PATH];
SC_HANDLE manager;
if (!start_services_process()) return;
/* FIXME: do all of this in services.exe instead */
if (RegOpenKeyW( HKEY_LOCAL_MACHINE, servicesW, &hkey )) return;
if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ALL_ACCESS )))