[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r8643: Try to make mingw capable of producing a working tor binary (in tor/trunk: . src/or)
- To: or-cvs@xxxxxxxxxxxxx
- Subject: [or-cvs] r8643: Try to make mingw capable of producing a working tor binary (in tor/trunk: . src/or)
- From: nickm@xxxxxxxx
- Date: Sat, 7 Oct 2006 20:33:35 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Sat, 07 Oct 2006 20:33:45 -0400
- Reply-to: or-talk@xxxxxxxxxxxxx
- Sender: owner-or-cvs@xxxxxxxxxxxxx
Author: nickm
Date: 2006-10-07 20:33:35 -0400 (Sat, 07 Oct 2006)
New Revision: 8643
Modified:
tor/trunk/
tor/trunk/src/or/main.c
Log:
r8932@totoro: nickm | 2006-10-07 20:29:03 -0400
Try to make mingw capable of producing a working tor binary for win98: make all NT-service-related functions get lazy-loaded on demand. I have no idea if this even compiles.
Property changes on: tor/trunk
___________________________________________________________________
svk:merge ticket from /tor/trunk [r8932] on 96637b51-b116-0410-a10e-9941ebb49b64
Modified: tor/trunk/src/or/main.c
===================================================================
--- tor/trunk/src/or/main.c 2006-10-07 19:56:49 UTC (rev 8642)
+++ tor/trunk/src/or/main.c 2006-10-08 00:33:35 UTC (rev 8643)
@@ -1654,6 +1654,117 @@
}
#ifdef MS_WINDOWS_SERVICE
+
+struct service_fns {
+ int loaded;
+
+ BOOL WINAPI (ChangeServiceConfig2_fn*)(
+ SC_HANDLE hService,
+ DWORD dwInfoLevel,
+ LPVOID lpInfo);
+
+ BOOL WINAPI (CloseServiceHandle_fn*)(
+ SC_HANDLE hSCObject);
+
+ BOOL WINAPI (ControlService_fn*)(
+ SC_HANDLE hService,
+ DWORD dwControl,
+ LPSERVICE_STATUS lpServiceStatus);
+
+ SC_HANDLE WINAPI (CreateService_fn*)(
+ SC_HANDLE hSCManager,
+ LPCTSTR lpServiceName,
+ LPCTSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPCTSTR lpBinaryPathName,
+ LPCTSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPCTSTR lpDependencies,
+ LPCTSTR lpServiceStartName,
+ LPCTSTR lpPassword);
+
+ BOOL WINAPI (DeleteService_fn*)(
+ SC_HANDLE hService);
+
+ SC_HANDLE WINAPI (OpenSCManager_fn*)(
+ LPCTSTR lpMachineName,
+ LPCTSTR lpDatabaseName,
+ DWORD dwDesiredAccess);
+
+ SC_HANDLE WINAPI (OpenService_fn*)(
+ SC_HANDLE hSCManager,
+ LPCTSTR lpServiceName,
+ DWORD dwDesiredAccess);
+
+ BOOL WINAPI (QueryServiceStatus_fn*)(
+ SC_HANDLE hService,
+ LPSERVICE_STATUS lpServiceStatus);
+
+ SERVICE_STATUS_HANDLE WINAPI (RegisterServiceCtrlHandler_fn*)(
+ LPCTSTR lpServiceName,
+ LPHANDLER_FUNCTION lpHandlerProc);
+
+ BOOL WINAPI (SetServiceStatus_fn*)(SERVICE_STATUS_HANDLE,
+ LPSERVICE_STATUS);
+
+ BOOL WINAPI (StartServiceCtrlDispatcher_fn*)(
+ const SERVICE_TABLE_ENTRY* lpServiceTable);
+
+ BOOL WINAPI (StartService_fn*)(
+ SC_HANDLE hService,
+ DWORD dwNumServiceArgs,
+ LPCTSTR* lpServiceArgVectors);
+
+} service_fns = { 0,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, };
+
+static int
+nt_service_loadlibrary(void)
+{
+ HMODULE library = 0;
+ void *fn;
+
+ if (loaded)
+ return 0;
+
+ if (!(library = LoadLibrary("advapi32.dll"))) {
+ log_err(LD_GENERAL, "Couldn't open advapi32.dll. Are you trying to use "
+ "NT services on Windows 98? That doesn't work.");
+ return -1;
+ }
+
+#define LOAD(f) do { \
+ if (!(fn = GetProcAddress(library, #f))) { \
+ log_err(LD_BUF, "Couldn't find %s in advapi32.dll! We probably got " \
+ "the name wrong.", #f); \
+ return -1; \
+ } else { \
+ service_fns.f ## _fn = fn; \
+ } \
+ } while (0)
+
+ LOAD(ChangeServiceConfig2);
+ LOAD(CloseServiceHandle);
+ LOAD(ControlService);
+ LOAD(CreateService);
+ LOAD(DeleteService);
+ LOAD(OpenSCManager);
+ LOAD(OpenService);
+ LOAD(QueryServiceStatus);
+ LOAD(RegisterServiceCtrlHandler);
+ LOAD(SetServiceStatus);
+ LOAD(StartServiceCtrlDispatcher);
+ LOAD(StartService);
+
+ service_fns.loaded = 1;
+
+ return 0;
+}
+
/** Checks if torrc is present in the same directory
* as the service executable.
* Return 1 if it is, 0 if it is not present. */
@@ -1704,10 +1815,13 @@
static int
nt_service_is_stopped(void)
{
+ if (nt_service_loadlibrary()<0)
+ return -1;
+
if (service_status.dwCurrentState == SERVICE_STOP_PENDING) {
service_status.dwWin32ExitCode = 0;
service_status.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(hStatus, &service_status);
+ service_fns.SetServiceStatus_fn(hStatus, &service_status);
return 1;
} else if (service_status.dwCurrentState == SERVICE_STOPPED) {
return 1;
@@ -1723,6 +1837,9 @@
exit_now.tv_sec = 0;
exit_now.tv_usec = 0;
+ if (nt_service_loadlibrary()<0)
+ return;
+
switch (request) {
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
@@ -1732,7 +1849,7 @@
event_loopexit(&exit_now);
return;
}
- SetServiceStatus(hStatus, &service_status);
+ service_fns.SetServiceStatus_fn(hStatus, &service_status);
}
/** DOCDOC */
@@ -1740,6 +1857,8 @@
nt_service_body(int argc, char **argv)
{
int r;
+ if (nt_service_loadlibrary()<0)
+ return;
service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
service_status.dwCurrentState = SERVICE_START_PENDING;
service_status.dwControlsAccepted =
@@ -1748,7 +1867,7 @@
service_status.dwServiceSpecificExitCode = 0;
service_status.dwCheckPoint = 0;
service_status.dwWaitHint = 1000;
- hStatus = RegisterServiceCtrlHandler(GENSRV_SERVICENAME,
+ hStatus = service_fns.RegisterServiceCtrlHandler_fn(GENSRV_SERVICENAME,
(LPHANDLER_FUNCTION) nt_service_control);
if (hStatus == 0) {
@@ -1775,11 +1894,11 @@
service_status.dwCurrentState = SERVICE_STOPPED;
service_status.dwWin32ExitCode = r;
service_status.dwServiceSpecificExitCode = r;
- SetServiceStatus(hStatus, &service_status);
+ service_fns.SetServiceStatus_fn(hStatus, &service_status);
return;
}
service_status.dwCurrentState = SERVICE_RUNNING;
- SetServiceStatus(hStatus, &service_status);
+ service_fns.SetServiceStatus_fn(hStatus, &service_status);
do_main_loop();
tor_cleanup();
return;
@@ -1792,12 +1911,14 @@
SERVICE_TABLE_ENTRY table[2];
DWORD result = 0;
char *errmsg;
+ if (nt_service_loadlibrary()<0)
+ return;
table[0].lpServiceName = GENSRV_SERVICENAME;
table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)nt_service_body;
table[1].lpServiceName = NULL;
table[1].lpServiceProc = NULL;
- if (!StartServiceCtrlDispatcher(table)) {
+ if (!service_fns.StartServiceCtrlDispatcher_fn(table)) {
result = GetLastError();
errmsg = nt_strerror(result);
printf("Service error %d : %s\n", (int) result, errmsg);
@@ -1833,9 +1954,10 @@
{
SC_HANDLE hSCManager;
char *errmsg = NULL;
-
- if ((hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE))
- == NULL) {
+ if (nt_service_loadlibrary()<0)
+ return 0;
+ if ((hSCManager = service_fns.OpenSCManager_fn(
+ NULL, NULL, SC_MANAGER_CREATE_SERVICE)) == NULL) {
errmsg = nt_strerror(GetLastError());
printf("OpenSCManager() failed : %s\n", errmsg);
LocalFree(errmsg);
@@ -1850,7 +1972,9 @@
SC_HANDLE hService;
char *errmsg = NULL;
- if ((hService = OpenService(hSCManager, GENSRV_SERVICENAME,
+ if (nt_service_loadlibrary()<0)
+ return 0;
+ if ((hService = service_fns.OpenService_fn(hSCManager, GENSRV_SERVICENAME,
SERVICE_ALL_ACCESS)) == NULL) {
errmsg = nt_strerror(GetLastError());
printf("OpenService() failed : %s\n", errmsg);
@@ -1865,15 +1989,18 @@
{
char *errmsg = NULL;
- QueryServiceStatus(hService, &service_status);
+ if (nt_service_loadlibrary()<0)
+ return -1;
+
+ service_fns.QueryServiceStatus_fn(hService, &service_status);
if (service_status.dwCurrentState == SERVICE_RUNNING) {
printf("Service is already running\n");
return 1;
}
- if (StartService(hService, 0, NULL)) {
+ if (service_fns.StartService_fn(hService, 0, NULL)) {
/* Loop until the service has finished attempting to start */
- while (QueryServiceStatus(hService, &service_status)) {
+ while (service_fns.QueryServiceStatus_fn(hService, &service_status)) {
if (service_status.dwCurrentState == SERVICE_START_PENDING)
Sleep(500);
else
@@ -1904,15 +2031,18 @@
nt_service_stop(SC_HANDLE hService)
{
char *errmsg = NULL;
+ if (nt_service_loadlibrary()<0)
+ return -1;
- QueryServiceStatus(hService, &service_status);
+ service_fns.QueryServiceStatus_fn(hService, &service_status);
if (service_status.dwCurrentState == SERVICE_STOPPED) {
printf("Service is already stopped\n");
return 1;
}
- if (ControlService(hService, SERVICE_CONTROL_STOP, &service_status)) {
- while (QueryServiceStatus(hService, &service_status)) {
+ if (service_fns.ControlService_fn(hService, SERVICE_CONTROL_STOP,
+ &service_status)) {
+ while (service_fns.QueryServiceStatus_fn(hService, &service_status)) {
if (service_status.dwCurrentState == SERVICE_STOP_PENDING)
Sleep(500);
else
@@ -1972,6 +2102,8 @@
char *errmsg;
int len = 0;
+ if (nt_service_loadlibrary()<0)
+ return -1;
if (0 == GetModuleFileName(NULL, szPath, MAX_PATH))
return 0;
@@ -2002,7 +2134,7 @@
* - and changed the lpPassword param to "" instead of NULL as per an
* MSDN article.
*/
- if ((hService = CreateService(hSCManager, GENSRV_SERVICENAME,
+ if ((hService = service_fns.CreateService_fn(hSCManager, GENSRV_SERVICENAME,
GENSRV_DISPLAYNAME,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_IGNORE,
@@ -2010,7 +2142,7 @@
NULL, NULL, NULL, NULL, "")) == NULL) {
errmsg = nt_strerror(GetLastError());
printf("CreateService() failed : %s\n", errmsg);
- CloseServiceHandle(hSCManager);
+ service_fns.CloseServiceHandle_fn(hSCManager);
LocalFree(errmsg);
tor_free(command);
return 0;
@@ -2018,14 +2150,15 @@
/* Set the service's description */
sdBuff.lpDescription = GENSRV_DESCRIPTION;
- ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sdBuff);
+ service_fns.ChangeServiceConfig2_fn(hService, SERVICE_CONFIG_DESCRIPTION,
+ &sdBuff);
printf("Service installed successfully\n");
/* Start the service initially */
nt_service_start(hService);
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCManager);
+ service_fns.CloseServiceHandle_fn(hService);
+ service_fns.CloseServiceHandle_fn(hSCManager);
tor_free(command);
return 0;
@@ -2039,17 +2172,20 @@
SC_HANDLE hService = NULL;
char *errmsg;
+ if (nt_service_loadlibrary()<0)
+ return -1;
+
if ((hSCManager = nt_service_open_scm()) == NULL) {
return 0;
}
if ((hService = nt_service_open(hSCManager)) == NULL) {
- CloseServiceHandle(hSCManager);
+ service_fns.CloseServiceHandle_fn(hSCManager);
return 0;
}
if (nt_service_stop(hService)) {
- if (DeleteService(hService)) {
+ if (service_fns.DeleteService_fn(hService)) {
printf("Removed service successfully\n");
}
else {
@@ -2062,8 +2198,8 @@
printf("Service could not be removed\n");
}
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCManager);
+ service_fns.CloseServiceHandle_fn(hService);
+ service_fns.CloseServiceHandle_fn(hSCManager);
return 0;
}
@@ -2151,6 +2287,10 @@
backup_argc = argc;
if ((argc >= 3) &&
(!strcmp(argv[1], "-service") || !strcmp(argv[1], "--service"))) {
+ if (nt_service_loadlibrary() < 0) {
+ printf("Unable to load library support for NT services.\n");
+ return -1;
+ }
if (!strcmp(argv[2], "install"))
return nt_service_install();
if (!strcmp(argv[2], "remove"))
@@ -2164,6 +2304,10 @@
}
// These are left so as not to confuse people who are used to these options
if (argc >= 2) {
+ if (nt_service_loadlibrary() < 0) {
+ printf("Unable to load library support for NT services.\n");
+ return -1;
+ }
if (!strcmp(argv[1], "-install") || !strcmp(argv[1], "--install"))
return nt_service_install();
if (!strcmp(argv[1], "-remove") || !strcmp(argv[1], "--remove"))