Module: wine Branch: master Commit: 9bc84d81df330610a52c7b6cd1805dfed84b8f12 URL: http://source.winehq.org/git/wine.git/?a=commit;h=9bc84d81df330610a52c7b6cd1...
Author: Rob Shearman rob@codeweavers.com Date: Tue Apr 1 12:48:46 2008 +0100
wineboot: Start services.exe on startup instead of on demand in the advapi32 services code.
---
dlls/advapi32/service.c | 62 +----------------------------------------- programs/wineboot/wineboot.c | 44 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 61 deletions(-)
diff --git a/dlls/advapi32/service.c b/dlls/advapi32/service.c index c95fcd9..77dc30b 100644 --- a/dlls/advapi32/service.c +++ b/dlls/advapi32/service.c @@ -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); diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index 30c7752..4d0236e 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -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 )))