---------------------
PatchSet 3727
Date: 2006/09/11 19:27:05
Author: serassio
Branch: nt
Tag: (none)
Log:
Split Windows service code from win32.cc to WinSvc.cc
Members:
port/win32/squid/squid.vcproj:1.1.2.13->1.1.2.14
src/WinSvc.cc:1.1->1.1.2.1
src/win32.cc:1.4.2.25->1.4.2.26
Index: squid3/port/win32/squid/squid.vcproj
===================================================================
RCS file: /cvsroot/squid-sf//squid3/port/win32/squid/Attic/squid.vcproj,v
retrieving revision 1.1.2.13
retrieving revision 1.1.2.14
diff -u -r1.1.2.13 -r1.1.2.14
--- squid3/port/win32/squid/squid.vcproj 11 Sep 2006 16:55:14 -0000 1.1.2.13
+++ squid3/port/win32/squid/squid.vcproj 11 Sep 2006 19:27:05 -0000 1.1.2.14
@@ -748,6 +748,10 @@
>
+
+
@@ -1097,6 +1101,10 @@
>
+
+
--- /dev/null Wed Feb 14 13:37:19 2007
+++ squid3/src/WinSvc.cc Wed Feb 14 13:37:53 2007
@@ -0,0 +1,981 @@
+
+/*
+ * $Id: WinSvc.cc,v 1.1.2.1 2006/09/11 19:27:07 serassio Exp $
+ *
+ * Windows support
+ * AUTHOR: Guido Serassio
+ * inspired by previous work by Romeo Anghelache & Eric Stern.
+ *
+ * SQUID Web Proxy Cache http://www.squid-cache.org/
+ * ----------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from
+ * the Internet community; see the CONTRIBUTORS file for full
+ * details. Many organizations have provided support for Squid's
+ * development; see the SPONSORS file for full details. Squid is
+ * Copyrighted (C) 2001 by the Regents of the University of
+ * California; see the COPYRIGHT file for full details. Squid
+ * incorporates software developed and/or copyrighted by other
+ * sources; see the CREDITS file for full details.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "squid.h"
+#include "squid_windows.h"
+
+#ifdef _SQUID_MSWIN_
+#ifndef _MSWSOCK_
+#include
+#endif
+#include
+#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
+#include
+#endif
+#endif
+
+static unsigned int GetOSVersion();
+void WIN32_svcstatusupdate(DWORD, DWORD);
+void WINAPI WIN32_svcHandler(DWORD);
+#if USE_WIN32_SERVICE
+static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int);
+static int WIN32_create_key(void);
+static void WIN32_build_argv (char *);
+#endif
+extern "C" void WINAPI SquidWinSvcMain(DWORD, char **);
+
+#if defined(_SQUID_MSWIN_)
+#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
+void Squid_Win32InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t);
+#endif
+static int Win32SockInit(void);
+static void Win32SockCleanup(void);
+SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex;
+void WIN32_ExceptionHandlerCleanup(void);
+static LPTOP_LEVEL_EXCEPTION_FILTER Win32_Old_ExceptionHandler = NULL;
+static int s_iInitCount = 0;
+#endif
+
+static int Squid_Aborting = 0;
+
+#if USE_WIN32_SERVICE
+static SERVICE_STATUS svcStatus;
+static SERVICE_STATUS_HANDLE svcHandle;
+static int WIN32_argc;
+static char ** WIN32_argv;
+static char * WIN32_module_name;
+
+#define VENDOR "GNU"
+static char VENDORString[] = VENDOR;
+#define SOFTWARENAME "Squid"
+static char SOFTWARENAMEString[] = SOFTWARENAME;
+#define WIN32_VERSION "3.0"
+static char WIN32_VERSIONString[] = WIN32_VERSION;
+#define SOFTWARE "SOFTWARE"
+static char SOFTWAREString[] = SOFTWARE;
+#define COMMANDLINE "CommandLine"
+#define CONFIGFILE "ConfigFile"
+#undef ChangeServiceConfig2
+typedef BOOL (WINAPI * PFChangeServiceConfig2) (SC_HANDLE, DWORD, LPVOID);
+#ifdef UNICODE
+#define CHANGESERVICECONFIG2 "ChangeServiceConfig2W"
+#else
+#define CHANGESERVICECONFIG2 "ChangeServiceConfig2A"
+#endif
+static SC_ACTION Squid_SCAction[] = { { SC_ACTION_RESTART, 60000 } };
+static char Squid_ServiceDescriptionString[] = SOFTWARENAME " " VERSION " WWW Proxy Server";
+static SERVICE_DESCRIPTION Squid_ServiceDescription = { Squid_ServiceDescriptionString };
+static SERVICE_FAILURE_ACTIONS Squid_ServiceFailureActions = { INFINITE, NULL, NULL, 1, Squid_SCAction };
+static char REGKEY[256]=SOFTWARE"\\"VENDOR"\\"SOFTWARENAME"\\"WIN32_VERSION"\\";
+static char *keys[] = {
+ SOFTWAREString, /* key[0] */
+ VENDORString, /* key[1] */
+ SOFTWARENAMEString, /* key[2] */
+ WIN32_VERSIONString, /* key[3] */
+ NULL, /* key[4] */
+ NULL /* key[5] */
+ };
+#endif
+
+/* ====================================================================== */
+/* LOCAL FUNCTIONS */
+/* ====================================================================== */
+
+#if USE_WIN32_SERVICE
+static int
+WIN32_create_key(void)
+{
+ int index;
+ HKEY hKey;
+ HKEY hKeyNext;
+ int retval;
+ LONG rv;
+
+ hKey = HKEY_LOCAL_MACHINE;
+ index = 0;
+ retval = 0;
+
+ /* Walk the tree, creating at each stage if necessary */
+
+ while (keys[index]) {
+ unsigned long result;
+ rv = RegCreateKeyEx(hKey, keys[index], /* subkey */
+ 0, /* reserved */
+ NULL, /* class */
+ REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyNext, &result);
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegCreateKeyEx(%s),%d\n", keys[index], (int) rv);
+ retval = -4;
+ }
+
+ /* Close the old key */
+ rv = RegCloseKey(hKey);
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegCloseKey %d\n", (int) rv);
+
+ if (retval == 0) {
+ /* Keep error status from RegCreateKeyEx, if any */
+ retval = -4;
+ }
+ }
+
+ if (retval) {
+ break;
+ }
+
+ hKey = hKeyNext;
+ index++;
+ }
+
+ if (keys[index] == NULL) {
+ /* Close the final key we opened, if we walked the entire
+ * tree
+ */
+ rv = RegCloseKey(hKey);
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegCloseKey %d\n", (int) rv);
+
+ if (retval == 0) {
+ /* Keep error status from RegCreateKeyEx, if any */
+ retval = -4;
+ }
+ }
+ }
+
+ return retval;
+}
+
+static int
+WIN32_StoreKey(const char *key, DWORD type, unsigned char *value,
+ int value_size)
+{
+ LONG rv;
+ HKEY hKey;
+ int retval;
+
+ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
+
+ if (rv == ERROR_FILE_NOT_FOUND) {
+ /* Key could not be opened -- try to create it
+ */
+
+ if (WIN32_create_key() < 0) {
+ /* Creation failed (error already reported) */
+ return -4;
+ }
+
+ /* Now it has been created we should be able to open it
+ */
+ rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
+
+ if (rv == ERROR_FILE_NOT_FOUND) {
+ fprintf(stderr, "Registry does not contain key %s after creation\n",
+ REGKEY);
+ return -1;
+ }
+ }
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegOpenKeyEx HKLM\\%s, %d\n", REGKEY, (int) rv);
+ return -4;
+ }
+
+ /* Now set the value and data */
+ rv = RegSetValueEx(hKey, key, /* value key name */
+ 0, /* reserved */
+ type, /* type */
+ value, /* value data */
+ (DWORD) value_size); /* for size of "value" */
+
+ retval = 0; /* Return value */
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegQueryValueEx(key %s),%d\n", key, (int) rv);
+ retval = -4;
+ } else {
+ fprintf(stderr, "Registry stored HKLM\\%s\\%s value %s\n",
+ REGKEY,
+ key,
+ type == REG_SZ ? value : (unsigned char *) "(not displayable)");
+ }
+
+ /* Make sure we close the key even if there was an error storing
+ * the data
+ */
+ rv = RegCloseKey(hKey);
+
+ if (rv != ERROR_SUCCESS) {
+ fprintf(stderr, "RegCloseKey HKLM\\%s, %d\n", REGKEY, (int) rv);
+
+ if (retval == 0) {
+ /* Keep error status from RegQueryValueEx, if any */
+ retval = -4;
+ }
+ }
+
+ return retval;
+}
+
+/* Build argv, argc from string passed from Windows. */
+static void WIN32_build_argv(char *cmd)
+{
+ int argvlen = 0;
+ char *word;
+
+ WIN32_argc = 1;
+ WIN32_argv = (char **) xmalloc ((WIN32_argc+1) * sizeof (char *));
+ WIN32_argv[0]=xstrdup(WIN32_module_name);
+ /* Scan command line until there is nothing left. */
+
+ while (*cmd) {
+ /* Ignore spaces */
+
+ if (xisspace(*cmd)) {
+ cmd++;
+ continue;
+ }
+
+ /* Found the beginning of an argument. */
+ word = cmd;
+
+ while (*cmd) {
+ cmd++; /* Skip over this character */
+
+ if (xisspace(*cmd)) /* End of argument if space */
+ break;
+ }
+
+ if (*cmd)
+ *cmd++ = '\0'; /* Terminate `word' */
+
+ /* See if we need to allocate more space for argv */
+ if (WIN32_argc >= argvlen) {
+ argvlen = WIN32_argc + 1;
+ WIN32_argv = (char **) xrealloc (WIN32_argv, (1 + argvlen) * sizeof (char *));
+ }
+
+ /* Add word to argv file. */
+ WIN32_argv[WIN32_argc++] = word;
+ }
+
+ WIN32_argv[WIN32_argc] = NULL;
+}
+
+#endif /* USE_WIN32_SERVICE */
+
+static unsigned int
+GetOSVersion()
+{
+ OSVERSIONINFO osvi;
+
+ safe_free(WIN32_OS_string);
+ memset(&osvi, '\0', sizeof(OSVERSIONINFO));
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ GetVersionEx((OSVERSIONINFO *) & osvi);
+
+ switch (osvi.dwPlatformId) {
+
+ case VER_PLATFORM_WIN32_NT:
+
+ if (osvi.dwMajorVersion <= 4) {
+ WIN32_OS_string = xstrdup("Windows NT");
+ return _WIN_OS_WINNT;
+ }
+
+ if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)) {
+ WIN32_OS_string = xstrdup("Windows 2000");
+ return _WIN_OS_WIN2K;
+ }
+
+ if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1)) {
+ WIN32_OS_string = xstrdup("Windows XP");
+ return _WIN_OS_WINXP;
+ }
+
+ if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2)) {
+ WIN32_OS_string = xstrdup("Windows Server 2003");
+ return _WIN_OS_WINNET;
+ }
+
+ if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion == 0)) {
+ WIN32_OS_string = xstrdup("Windows code name \"Longhorn\"");
+ return _WIN_OS_WINLON;
+ }
+
+ break;
+
+ case VER_PLATFORM_WIN32_WINDOWS:
+
+ if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0)) {
+ WIN32_OS_string = xstrdup("Windows 95");
+ return _WIN_OS_WIN95;
+ }
+
+ if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 10)) {
+ WIN32_OS_string = xstrdup("Windows 98");
+ return _WIN_OS_WIN98;
+ }
+
+ if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 90)) {
+ WIN32_OS_string = xstrdup("Windows Me");
+ return _WIN_OS_WINME;
+ }
+
+ break;
+
+ case VER_PLATFORM_WIN32s:
+ WIN32_OS_string = xstrdup("Windows 3.1 with WIN32S");
+ return _WIN_OS_WIN32S;
+ break;
+
+ default:
+ break;
+ }
+
+ WIN32_OS_string = xstrdup("Unknown Windows system");
+ return _WIN_OS_UNKNOWN;
+}
+
+/* ====================================================================== */
+/* PUBLIC FUNCTIONS */
+/* ====================================================================== */
+
+void
+WIN32_Abort(int sig)
+{
+#if USE_WIN32_SERVICE
+ svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
+ svcStatus.dwServiceSpecificExitCode = 1;
+#endif
+
+ Squid_Aborting = 1;
+ WIN32_Exit();
+}
+
+void
+WIN32_Exit()
+{
+#ifdef _SQUID_MSWIN_
+ Win32SockCleanup();
+#endif
+#if USE_WIN32_SERVICE
+
+ if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+ if (!Squid_Aborting) {
+ svcStatus.dwCurrentState = SERVICE_STOPPED;
+ SetServiceStatus(svcHandle, &svcStatus);
+ }
+ }
+
+#endif
+#ifdef _SQUID_MSWIN_
+ if (dbg_mutex)
+ DeleteCriticalSection(dbg_mutex);
+
+ WIN32_ExceptionHandlerCleanup();
+
+#endif
+
+ _exit(0);
+}
+
+int WIN32_Subsystem_Init(int * argc, char *** argv)
+{
+#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
+ _invalid_parameter_handler oldHandler, newHandler;
+#endif
+
+ WIN32_OS_version = GetOSVersion();
+
+ if ((WIN32_OS_version == _WIN_OS_UNKNOWN) || (WIN32_OS_version == _WIN_OS_WIN32S))
+ return 1;
+
+ if (atexit(WIN32_Exit) != 0)
+ return 1;
+
+#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
+
+ newHandler = Squid_Win32InvalidParameterHandler;
+
+ oldHandler = _set_invalid_parameter_handler(newHandler);
+
+ _CrtSetReportMode(_CRT_ASSERT, 0);
+
+#endif
+#if USE_WIN32_SERVICE
+
+ if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+ char path[512];
+ HKEY hndKey;
+
+ if (signal(SIGABRT, WIN32_Abort) == SIG_ERR)
+ return 1;
+
+ /* Register the service Handler function */
+ svcHandle =
+ RegisterServiceCtrlHandler(WIN32_Service_name,
+ WIN32_svcHandler);
+
+ if (svcHandle == 0)
+ return 1;
+
+ /* Set Process work dir to directory cointaining squid.exe */
+ GetModuleFileName(NULL, path, 512);
+
+ WIN32_module_name=xstrdup(path);
+
+ path[strlen(path) - 10] = '\0';
+
+ if (SetCurrentDirectory(path) == 0)
+ return 1;
+
+ safe_free(ConfigFile);
+
+ /* get config file from Windows Registry */
+ if (RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY, &hndKey) == ERROR_SUCCESS) {
+ DWORD Type = 0;
+ DWORD Size = 0;
+ LONG Result;
+ Result =
+ RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size);
+
+ if (Result == ERROR_SUCCESS && Size) {
+ ConfigFile = static_cast(xmalloc(Size));
+ RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, (unsigned char *)ConfigFile,
+ &Size);
+ } else
+ ConfigFile = xstrdup(DefaultConfigFile);
+
+ Size = 0;
+
+ Type = 0;
+
+ Result =
+ RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size);
+
+ if (Result == ERROR_SUCCESS && Size) {
+ WIN32_Service_Command_Line = static_cast(xmalloc(Size));
+ RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, (unsigned char *)WIN32_Service_Command_Line,
+ &Size);
+ } else
+ WIN32_Service_Command_Line = xstrdup("");
+
+ RegCloseKey(hndKey);
+ } else {
+ ConfigFile = xstrdup(DefaultConfigFile);
+ WIN32_Service_Command_Line = xstrdup("");
+ }
+
+ WIN32_build_argv(WIN32_Service_Command_Line);
+ *argc = WIN32_argc;
+ *argv = WIN32_argv;
+ /* Set Service Status to SERVICE_START_PENDING */
+ svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ svcStatus.dwCurrentState = SERVICE_START_PENDING;
+ svcStatus.dwControlsAccepted =
+ SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+ svcStatus.dwWin32ExitCode = 0;
+ svcStatus.dwServiceSpecificExitCode = 0;
+ svcStatus.dwCheckPoint = 0;
+ svcStatus.dwWaitHint = 10000;
+ SetServiceStatus(svcHandle, &svcStatus);
+#ifdef _SQUID_MSWIN_
+
+ _setmaxstdio(Squid_MaxFD);
+#endif
+ }
+
+#endif /* USE_WIN32_SERVICE */
+#ifdef _SQUID_MSWIN_
+ if (Win32SockInit() < 0)
+ return 1;
+
+#endif
+
+ return 0;
+}
+
+#if USE_WIN32_SERVICE
+void
+WIN32_svcstatusupdate(DWORD svcstate, DWORD WaitHint)
+{
+ if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
+ svcStatus.dwCheckPoint++;
+ svcStatus.dwWaitHint = WaitHint;
+ svcStatus.dwCurrentState = svcstate;
+ SetServiceStatus(svcHandle, &svcStatus);
+ }
+}
+
+VOID WINAPI
+WIN32_svcHandler(DWORD Opcode)
+{
+ DWORD status;
+
+ switch (Opcode) {
+
+ case _WIN_SQUID_SERVICE_CONTROL_STOP:
+
+ case _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN:
+ /* Do whatever it takes to stop here. */
+ svcStatus.dwWin32ExitCode = 0;
+ svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ svcStatus.dwCheckPoint = 0;
+ svcStatus.dwWaitHint = 10000;
+ shut_down(SIGTERM);
+
+ if (!SetServiceStatus(svcHandle, &svcStatus)) {
+ status = GetLastError();
+ debug(1, 1) ("SetServiceStatus error %ld\n", status);
+ }
+
+ debug(1, 1) ("Leaving Squid service\n");
+ return;
+
+ case _WIN_SQUID_SERVICE_CONTROL_INTERROGATE:
+ /* Fall through to send current status. */
+
+ if (!SetServiceStatus(svcHandle, &svcStatus)) {
+ status = GetLastError();
+ debug(1, 1) ("SetServiceStatus error %ld\n", status);
+ }
+
+ break;
+
+ case _WIN_SQUID_SERVICE_CONTROL_ROTATE:
+ rotate_logs(SIGUSR1);
+ break;
+
+ case _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE:
+ reconfigure(SIGHUP);
+ break;
+
+ case _WIN_SQUID_SERVICE_CONTROL_DEBUG:
+ sigusr2_handle(SIGUSR2);
+ break;
+
+ case _WIN_SQUID_SERVICE_CONTROL_INTERRUPT:
+ /* Do whatever it takes to stop here. */
+ svcStatus.dwWin32ExitCode = 0;
+ svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ svcStatus.dwCheckPoint = 0;
+ svcStatus.dwWaitHint = 10000;
+ shut_down(SIGINT);
+
+ if (!SetServiceStatus(svcHandle, &svcStatus)) {
+ status = GetLastError();
+ debug(1, 1) ("SetServiceStatus error %ld\n", status);
+ }
+
+ debug(1, 1) ("Leaving Squid service\n");
+ break;
+
+ default:
+ debug(1, 1) ("Unrecognized opcode %ld\n", Opcode);
+ }
+
+ return;
+}
+
+void
+WIN32_RemoveService()
+{
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+ if (!WIN32_Service_name)
+ WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+
+ strcat(REGKEY, WIN32_Service_name);
+
+ keys[4] = WIN32_Service_name;
+
+ schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
+ NULL, /* database (NULL == default) */
+ SC_MANAGER_ALL_ACCESS /* access required */
+ );
+
+ if (!schSCManager)
+ fprintf(stderr, "OpenSCManager failed\n");
+ else {
+ schService = OpenService(schSCManager, WIN32_Service_name, SERVICE_ALL_ACCESS);
+
+ if (schService == NULL)
+ fprintf(stderr, "OpenService failed\n");
+
+ /* Could not open the service */
+ else {
+ /* try to stop the service */
+
+ if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP,
+ &svcStatus)) {
+ sleep(1);
+
+ while (QueryServiceStatus(schService, &svcStatus)) {
+ if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
+ sleep(1);
+ else
+ break;
+ }
+ }
+
+ /* now remove the service */
+ if (DeleteService(schService) == 0)
+ fprintf(stderr, "DeleteService failed.\n");
+ else
+ printf("Service %s deleted successfully.\n",
+ WIN32_Service_name);
+
+ CloseServiceHandle(schService);
+ }
+
+ CloseServiceHandle(schSCManager);
+ }
+}
+
+void
+WIN32_SetServiceCommandLine()
+{
+ if (!WIN32_Service_name)
+ WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+
+ strcat(REGKEY, WIN32_Service_name);
+
+ keys[4] = WIN32_Service_name;
+
+ /* Now store the Service Command Line in the registry */
+ WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line, strlen(WIN32_Command_Line) + 1);
+}
+
+void
+WIN32_InstallService()
+{
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+ char ServicePath[512];
+ char szPath[512];
+ int lenpath;
+
+ if (!WIN32_Service_name)
+ WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+
+ strcat(REGKEY, WIN32_Service_name);
+
+ keys[4] = WIN32_Service_name;
+
+ if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) {
+ fprintf(stderr, "Can't get executable path\n");
+ exit(1);
+ }
+
+ snprintf(szPath, sizeof(szPath), "%s %s:%s", ServicePath, _WIN_SQUID_SERVICE_OPTION, WIN32_Service_name);
+ schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
+ NULL, /* database (NULL == default) */
+ SC_MANAGER_ALL_ACCESS /* access required */
+ );
+
+ if (!schSCManager) {
+ fprintf(stderr, "OpenSCManager failed\n");
+ exit(1);
+ } else {
+ schService = CreateService(schSCManager, /* SCManager database */
+ WIN32_Service_name, /* name of service */
+ WIN32_Service_name, /* name to display */
+ SERVICE_ALL_ACCESS, /* desired access */
+ SERVICE_WIN32_OWN_PROCESS, /* service type */
+ SERVICE_AUTO_START, /* start type */
+ SERVICE_ERROR_NORMAL, /* error control type */
+ (const char *) szPath, /* service's binary */
+ NULL, /* no load ordering group */
+ NULL, /* no tag identifier */
+ "Tcpip\0AFD\0", /* dependencies */
+ NULL, /* LocalSystem account */
+ NULL); /* no password */
+
+ if (schService) {
+ if (WIN32_OS_version > _WIN_OS_WINNT) {
+ HMODULE ADVAPI32Handle;
+ PFChangeServiceConfig2 ChangeServiceConfig2;
+ DWORD dwInfoLevel = SERVICE_CONFIG_DESCRIPTION;
+
+ ADVAPI32Handle = GetModuleHandle("advapi32");
+ ChangeServiceConfig2 = (PFChangeServiceConfig2) GetProcAddress(ADVAPI32Handle, CHANGESERVICECONFIG2);
+ ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceDescription);
+ dwInfoLevel = SERVICE_CONFIG_FAILURE_ACTIONS;
+ ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceFailureActions);
+ }
+
+ CloseServiceHandle(schService);
+ /* Now store the config file location in the registry */
+
+ if (!ConfigFile)
+ ConfigFile = xstrdup(DefaultConfigFile);
+
+ WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile, strlen(ConfigFile) + 1);
+
+ printf("Squid Cache version %s for %s\n", version_string,
+ CONFIG_HOST_TYPE);
+
+ printf("installed successfully as %s Windows System Service.\n",
+ WIN32_Service_name);
+
+ printf
+ ("To run, start it from the Services Applet of Control Panel.\n");
+
+ printf("Don't forget to edit squid.conf before starting it.\n\n");
+ } else {
+ fprintf(stderr, "CreateService failed\n");
+ exit(1);
+ }
+
+ CloseServiceHandle(schSCManager);
+ }
+}
+
+void
+WIN32_sendSignal(int WIN32_signal)
+{
+ SERVICE_STATUS ssStatus;
+ DWORD fdwAccess, fdwControl;
+ SC_HANDLE schService;
+ SC_HANDLE schSCManager;
+
+ if (!WIN32_Service_name)
+ WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
+
+ schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
+ NULL, /* database (NULL == default) */
+ SC_MANAGER_ALL_ACCESS /* access required */
+ );
+
+ if (!schSCManager) {
+ fprintf(stderr, "OpenSCManager failed\n");
+ exit(1);
+ }
+
+ /* The required service object access depends on the control. */
+ switch (WIN32_signal) {
+
+ case 0: /* SIGNULL */
+ fdwAccess = SERVICE_INTERROGATE;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE;
+ break;
+
+ case SIGUSR1:
+ fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_ROTATE;
+ break;
+
+ case SIGUSR2:
+ fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_DEBUG;
+ break;
+
+ case SIGHUP:
+ fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE;
+ break;
+
+ case SIGTERM:
+ fdwAccess = SERVICE_STOP;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP;
+ break;
+
+ case SIGINT:
+
+ case SIGKILL:
+ fdwAccess = SERVICE_USER_DEFINED_CONTROL;
+ fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT;
+ break;
+
+ default:
+ exit(1);
+ }
+
+ /* Open a handle to the service. */
+ schService = OpenService(schSCManager, /* SCManager database */
+ WIN32_Service_name, /* name of service */
+ fdwAccess); /* specify access */
+
+ if (schService == NULL) {
+ fprintf(stderr, "%s: ERROR: Could not open Service %s\n", appname,
+ WIN32_Service_name);
+ exit(1);
+ } else {
+ /* Send a control value to the service. */
+
+ if (!ControlService(schService, /* handle of service */
+ fdwControl, /* control value to send */
+ &ssStatus)) { /* address of status info */
+ fprintf(stderr, "%s: ERROR: Could not Control Service %s\n",
+ appname, WIN32_Service_name);
+ exit(1);
+ } else {
+ /* Print the service status. */
+ printf("\nStatus of %s Service:\n", WIN32_Service_name);
+ printf(" Service Type: 0x%lx\n", ssStatus.dwServiceType);
+ printf(" Current State: 0x%lx\n", ssStatus.dwCurrentState);
+ printf(" Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted);
+ printf(" Exit Code: %ld\n", ssStatus.dwWin32ExitCode);
+ printf(" Service Specific Exit Code: %ld\n",
+ ssStatus.dwServiceSpecificExitCode);
+ printf(" Check Point: %ld\n", ssStatus.dwCheckPoint);
+ printf(" Wait Hint: %ld\n", ssStatus.dwWaitHint);
+ }
+
+ CloseServiceHandle(schService);
+ }
+
+ CloseServiceHandle(schSCManager);
+}
+
+int main(int argc, char **argv)
+{
+ SERVICE_TABLE_ENTRY DispatchTable[] = {
+ {NULL, SquidWinSvcMain},
+ {NULL, NULL}
+ };
+ char *c;
+ char stderr_path[256];
+
+ if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION)) {
+ strcpy(stderr_path, argv[0]);
+ strcat(stderr_path,".log");
+ freopen(stderr_path, "w", stderr);
+ setmode(fileno(stderr), O_TEXT);
+ WIN32_run_mode = _WIN_SQUID_RUN_MODE_SERVICE;
+ opt_no_daemon = 1;
+
+ if (!(c=strchr(argv[1],':'))) {
+ fprintf(stderr, "Bad Service Parameter: %s\n", argv[1]);
+ return 1;
+ }
+
+ WIN32_Service_name = xstrdup(c+1);
+ DispatchTable[0].lpServiceName=WIN32_Service_name;
+ strcat(REGKEY, WIN32_Service_name);
+ keys[4] = WIN32_Service_name;
+
+ if (!StartServiceCtrlDispatcher(DispatchTable)) {
+ fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n",
+ GetLastError());
+ return 1;
+ }
+ } else {
+ WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
+#ifdef _SQUID_MSWIN_
+
+ opt_no_daemon = 1;
+
+#endif
+
+ return SquidMain(argc, argv);
+ }
+
+ return 0;
+}
+
+#endif /* USE_WIN32_SERVICE */
+
+#if defined(_SQUID_MSWIN_)
+static int Win32SockInit(void)
+{
+ int iVersionRequested;
+ WSADATA wsaData;
+ int err, opt;
+ int optlen = sizeof(opt);
+
+ if (s_iInitCount > 0) {
+ s_iInitCount++;
+ return (0);
+ } else if (s_iInitCount < 0)
+ return (s_iInitCount);
+
+ /* s_iInitCount == 0. Do the initailization */
+ iVersionRequested = MAKEWORD(2, 0);
+
+ err = WSAStartup((WORD) iVersionRequested, &wsaData);
+
+ if (err) {
+ s_iInitCount = -1;
+ return (s_iInitCount);
+ }
+
+ if (LOBYTE(wsaData.wVersion) != 2 ||
+ HIBYTE(wsaData.wVersion) != 0) {
+ s_iInitCount = -2;
+ WSACleanup();
+ return (s_iInitCount);
+ }
+
+ if (WIN32_OS_version !=_WIN_OS_WINNT) {
+ if (::getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&opt, &optlen)) {
+ s_iInitCount = -3;
+ WSACleanup();
+ return (s_iInitCount);
+ } else {
+ opt = opt | SO_SYNCHRONOUS_NONALERT;
+
+ if (::setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &opt, optlen)) {
+ s_iInitCount = -3;
+ WSACleanup();
+ return (s_iInitCount);
+ }
+ }
+ }
+
+ WIN32_Socks_initialized = 1;
+ s_iInitCount++;
+ return (s_iInitCount);
+}
+
+static void Win32SockCleanup(void)
+{
+ if (--s_iInitCount == 0)
+ WSACleanup();
+
+ return;
+}
+
+void Squid_Win32InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
+{
+ return;
+}
+
+#endif /* SQUID_MSWIN_ */
Index: squid3/src/win32.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/win32.cc,v
retrieving revision 1.4.2.25
retrieving revision 1.4.2.26
diff -u -r1.4.2.25 -r1.4.2.26
--- squid3/src/win32.cc 10 Sep 2006 08:27:38 -0000 1.4.2.25
+++ squid3/src/win32.cc 11 Sep 2006 19:27:07 -0000 1.4.2.26
@@ -1,6 +1,6 @@
/*
- * $Id: win32.cc,v 1.4.2.25 2006/09/10 08:27:38 serassio Exp $
+ * $Id: win32.cc,v 1.4.2.26 2006/09/11 19:27:07 serassio Exp $
*
* Windows support
* AUTHOR: Guido Serassio
@@ -34,8 +34,6 @@
*
*/
-#define WIN32_C
-
#include "squid.h"
#include "squid_windows.h"
@@ -46,880 +44,13 @@
#ifndef _MSWSOCK_
#include
#endif
-#include
-#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
-#include
-#endif
-#endif
#include
-static unsigned int GetOSVersion();
-void WIN32_svcstatusupdate(DWORD, DWORD);
-void WINAPI WIN32_svcHandler(DWORD);
-#if USE_WIN32_SERVICE
-static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int);
-static int WIN32_create_key(void);
-static void WIN32_build_argv (char *);
-#endif
-extern "C" void WINAPI SquidWinSvcMain(DWORD, char **);
-
-#if defined(_SQUID_MSWIN_)
-#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
-void Squid_Win32InvalidParameterHandler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t);
-#endif
-static int Win32SockInit(void);
-static void Win32SockCleanup(void);
SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex;
void WIN32_ExceptionHandlerCleanup(void);
static LPTOP_LEVEL_EXCEPTION_FILTER Win32_Old_ExceptionHandler = NULL;
-static int s_iInitCount = 0;
-#endif
-
-static int Squid_Aborting = 0;
-
-#if USE_WIN32_SERVICE
-static SERVICE_STATUS svcStatus;
-static SERVICE_STATUS_HANDLE svcHandle;
-static int WIN32_argc;
-static char ** WIN32_argv;
-static char * WIN32_module_name;
-
-#define VENDOR "GNU"
-static char VENDORString[] = VENDOR;
-#define SOFTWARENAME "Squid"
-static char SOFTWARENAMEString[] = SOFTWARENAME;
-#define WIN32_VERSION "3.0"
-static char WIN32_VERSIONString[] = WIN32_VERSION;
-#define SOFTWARE "SOFTWARE"
-static char SOFTWAREString[] = SOFTWARE;
-#define COMMANDLINE "CommandLine"
-#define CONFIGFILE "ConfigFile"
-#undef ChangeServiceConfig2
-typedef BOOL (WINAPI * PFChangeServiceConfig2) (SC_HANDLE, DWORD, LPVOID);
-#ifdef UNICODE
-#define CHANGESERVICECONFIG2 "ChangeServiceConfig2W"
-#else
-#define CHANGESERVICECONFIG2 "ChangeServiceConfig2A"
-#endif
-static SC_ACTION Squid_SCAction[] = { { SC_ACTION_RESTART, 60000 } };
-static char Squid_ServiceDescriptionString[] = SOFTWARENAME " " VERSION " WWW Proxy Server";
-static SERVICE_DESCRIPTION Squid_ServiceDescription = { Squid_ServiceDescriptionString };
-static SERVICE_FAILURE_ACTIONS Squid_ServiceFailureActions = { INFINITE, NULL, NULL, 1, Squid_SCAction };
-static char REGKEY[256]=SOFTWARE"\\"VENDOR"\\"SOFTWARENAME"\\"WIN32_VERSION"\\";
-static char *keys[] = {
- SOFTWAREString, /* key[0] */
- VENDORString, /* key[1] */
- SOFTWARENAMEString, /* key[2] */
- WIN32_VERSIONString, /* key[3] */
- NULL, /* key[4] */
- NULL /* key[5] */
- };
-#endif
-
-/* ====================================================================== */
-/* LOCAL FUNCTIONS */
-/* ====================================================================== */
-
-#if USE_WIN32_SERVICE
-static int
-WIN32_create_key(void)
-{
- int index;
- HKEY hKey;
- HKEY hKeyNext;
- int retval;
- LONG rv;
-
- hKey = HKEY_LOCAL_MACHINE;
- index = 0;
- retval = 0;
-
- /* Walk the tree, creating at each stage if necessary */
-
- while (keys[index]) {
- unsigned long result;
- rv = RegCreateKeyEx(hKey, keys[index], /* subkey */
- 0, /* reserved */
- NULL, /* class */
- REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKeyNext, &result);
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegCreateKeyEx(%s),%d\n", keys[index], (int) rv);
- retval = -4;
- }
-
- /* Close the old key */
- rv = RegCloseKey(hKey);
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegCloseKey %d\n", (int) rv);
-
- if (retval == 0) {
- /* Keep error status from RegCreateKeyEx, if any */
- retval = -4;
- }
- }
-
- if (retval) {
- break;
- }
-
- hKey = hKeyNext;
- index++;
- }
-
- if (keys[index] == NULL) {
- /* Close the final key we opened, if we walked the entire
- * tree
- */
- rv = RegCloseKey(hKey);
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegCloseKey %d\n", (int) rv);
-
- if (retval == 0) {
- /* Keep error status from RegCreateKeyEx, if any */
- retval = -4;
- }
- }
- }
-
- return retval;
-}
-
-static int
-WIN32_StoreKey(const char *key, DWORD type, unsigned char *value,
- int value_size)
-{
- LONG rv;
- HKEY hKey;
- int retval;
-
- rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
-
- if (rv == ERROR_FILE_NOT_FOUND) {
- /* Key could not be opened -- try to create it
- */
-
- if (WIN32_create_key() < 0) {
- /* Creation failed (error already reported) */
- return -4;
- }
-
- /* Now it has been created we should be able to open it
- */
- rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGKEY, 0, KEY_WRITE, &hKey);
-
- if (rv == ERROR_FILE_NOT_FOUND) {
- fprintf(stderr, "Registry does not contain key %s after creation\n",
- REGKEY);
- return -1;
- }
- }
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegOpenKeyEx HKLM\\%s, %d\n", REGKEY, (int) rv);
- return -4;
- }
-
- /* Now set the value and data */
- rv = RegSetValueEx(hKey, key, /* value key name */
- 0, /* reserved */
- type, /* type */
- value, /* value data */
- (DWORD) value_size); /* for size of "value" */
-
- retval = 0; /* Return value */
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegQueryValueEx(key %s),%d\n", key, (int) rv);
- retval = -4;
- } else {
- fprintf(stderr, "Registry stored HKLM\\%s\\%s value %s\n",
- REGKEY,
- key,
- type == REG_SZ ? value : (unsigned char *) "(not displayable)");
- }
-
- /* Make sure we close the key even if there was an error storing
- * the data
- */
- rv = RegCloseKey(hKey);
-
- if (rv != ERROR_SUCCESS) {
- fprintf(stderr, "RegCloseKey HKLM\\%s, %d\n", REGKEY, (int) rv);
-
- if (retval == 0) {
- /* Keep error status from RegQueryValueEx, if any */
- retval = -4;
- }
- }
-
- return retval;
-}
-
-/* Build argv, argc from string passed from Windows. */
-static void WIN32_build_argv(char *cmd)
-{
- int argvlen = 0;
- char *word;
-
- WIN32_argc = 1;
- WIN32_argv = (char **) xmalloc ((WIN32_argc+1) * sizeof (char *));
- WIN32_argv[0]=xstrdup(WIN32_module_name);
- /* Scan command line until there is nothing left. */
-
- while (*cmd) {
- /* Ignore spaces */
-
- if (xisspace(*cmd)) {
- cmd++;
- continue;
- }
-
- /* Found the beginning of an argument. */
- word = cmd;
-
- while (*cmd) {
- cmd++; /* Skip over this character */
-
- if (xisspace(*cmd)) /* End of argument if space */
- break;
- }
-
- if (*cmd)
- *cmd++ = '\0'; /* Terminate `word' */
-
- /* See if we need to allocate more space for argv */
- if (WIN32_argc >= argvlen) {
- argvlen = WIN32_argc + 1;
- WIN32_argv = (char **) xrealloc (WIN32_argv, (1 + argvlen) * sizeof (char *));
- }
-
- /* Add word to argv file. */
- WIN32_argv[WIN32_argc++] = word;
- }
-
- WIN32_argv[WIN32_argc] = NULL;
-}
-
-#endif /* USE_WIN32_SERVICE */
-
-static unsigned int
-GetOSVersion()
-{
- OSVERSIONINFO osvi;
-
- safe_free(WIN32_OS_string);
- memset(&osvi, '\0', sizeof(OSVERSIONINFO));
- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx((OSVERSIONINFO *) & osvi);
-
- switch (osvi.dwPlatformId) {
-
- case VER_PLATFORM_WIN32_NT:
-
- if (osvi.dwMajorVersion <= 4) {
- WIN32_OS_string = xstrdup("Windows NT");
- return _WIN_OS_WINNT;
- }
-
- if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)) {
- WIN32_OS_string = xstrdup("Windows 2000");
- return _WIN_OS_WIN2K;
- }
-
- if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1)) {
- WIN32_OS_string = xstrdup("Windows XP");
- return _WIN_OS_WINXP;
- }
-
- if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2)) {
- WIN32_OS_string = xstrdup("Windows Server 2003");
- return _WIN_OS_WINNET;
- }
-
- if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion == 0)) {
- WIN32_OS_string = xstrdup("Windows code name \"Longhorn\"");
- return _WIN_OS_WINLON;
- }
-
- break;
-
- case VER_PLATFORM_WIN32_WINDOWS:
-
- if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0)) {
- WIN32_OS_string = xstrdup("Windows 95");
- return _WIN_OS_WIN95;
- }
-
- if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 10)) {
- WIN32_OS_string = xstrdup("Windows 98");
- return _WIN_OS_WIN98;
- }
-
- if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 90)) {
- WIN32_OS_string = xstrdup("Windows Me");
- return _WIN_OS_WINME;
- }
-
- break;
-
- case VER_PLATFORM_WIN32s:
- WIN32_OS_string = xstrdup("Windows 3.1 with WIN32S");
- return _WIN_OS_WIN32S;
- break;
-
- default:
- break;
- }
-
- WIN32_OS_string = xstrdup("Unknown Windows system");
- return _WIN_OS_UNKNOWN;
-}
-
-/* ====================================================================== */
-/* PUBLIC FUNCTIONS */
-/* ====================================================================== */
-
-void
-WIN32_Abort(int sig)
-{
-#if USE_WIN32_SERVICE
- svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
- svcStatus.dwServiceSpecificExitCode = 1;
-#endif
-
- Squid_Aborting = 1;
- WIN32_Exit();
-}
-
-void
-WIN32_Exit()
-{
-#ifdef _SQUID_MSWIN_
- Win32SockCleanup();
-#endif
-#if USE_WIN32_SERVICE
-
- if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
- if (!Squid_Aborting) {
- svcStatus.dwCurrentState = SERVICE_STOPPED;
- SetServiceStatus(svcHandle, &svcStatus);
- }
- }
-
-#endif
-#ifdef _SQUID_MSWIN_
- if (dbg_mutex)
- DeleteCriticalSection(dbg_mutex);
-
- WIN32_ExceptionHandlerCleanup();
-
-#endif
-
- _exit(0);
-}
-
-int WIN32_Subsystem_Init(int * argc, char *** argv)
-{
-#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
- _invalid_parameter_handler oldHandler, newHandler;
-#endif
-
- WIN32_OS_version = GetOSVersion();
-
- if ((WIN32_OS_version == _WIN_OS_UNKNOWN) || (WIN32_OS_version == _WIN_OS_WIN32S))
- return 1;
-
- if (atexit(WIN32_Exit) != 0)
- return 1;
-
-#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
-
- newHandler = Squid_Win32InvalidParameterHandler;
-
- oldHandler = _set_invalid_parameter_handler(newHandler);
-
- _CrtSetReportMode(_CRT_ASSERT, 0);
-
-#endif
-#if USE_WIN32_SERVICE
-
- if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
- char path[512];
- HKEY hndKey;
-
- if (signal(SIGABRT, WIN32_Abort) == SIG_ERR)
- return 1;
-
- /* Register the service Handler function */
- svcHandle =
- RegisterServiceCtrlHandler(WIN32_Service_name,
- WIN32_svcHandler);
-
- if (svcHandle == 0)
- return 1;
-
- /* Set Process work dir to directory cointaining squid.exe */
- GetModuleFileName(NULL, path, 512);
-
- WIN32_module_name=xstrdup(path);
-
- path[strlen(path) - 10] = '\0';
-
- if (SetCurrentDirectory(path) == 0)
- return 1;
-
- safe_free(ConfigFile);
-
- /* get config file from Windows Registry */
- if (RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY, &hndKey) == ERROR_SUCCESS) {
- DWORD Type = 0;
- DWORD Size = 0;
- LONG Result;
- Result =
- RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, NULL, &Size);
-
- if (Result == ERROR_SUCCESS && Size) {
- ConfigFile = static_cast(xmalloc(Size));
- RegQueryValueEx(hndKey, CONFIGFILE, NULL, &Type, (unsigned char *)ConfigFile,
- &Size);
- } else
- ConfigFile = xstrdup(DefaultConfigFile);
-
- Size = 0;
-
- Type = 0;
-
- Result =
- RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, NULL, &Size);
- if (Result == ERROR_SUCCESS && Size) {
- WIN32_Service_Command_Line = static_cast(xmalloc(Size));
- RegQueryValueEx(hndKey, COMMANDLINE, NULL, &Type, (unsigned char *)WIN32_Service_Command_Line,
- &Size);
- } else
- WIN32_Service_Command_Line = xstrdup("");
- RegCloseKey(hndKey);
- } else {
- ConfigFile = xstrdup(DefaultConfigFile);
- WIN32_Service_Command_Line = xstrdup("");
- }
-
- WIN32_build_argv(WIN32_Service_Command_Line);
- *argc = WIN32_argc;
- *argv = WIN32_argv;
- /* Set Service Status to SERVICE_START_PENDING */
- svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- svcStatus.dwCurrentState = SERVICE_START_PENDING;
- svcStatus.dwControlsAccepted =
- SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
- svcStatus.dwWin32ExitCode = 0;
- svcStatus.dwServiceSpecificExitCode = 0;
- svcStatus.dwCheckPoint = 0;
- svcStatus.dwWaitHint = 10000;
- SetServiceStatus(svcHandle, &svcStatus);
-#ifdef _SQUID_MSWIN_
-
- _setmaxstdio(Squid_MaxFD);
-#endif
- }
-
-#endif /* USE_WIN32_SERVICE */
-#ifdef _SQUID_MSWIN_
- if (Win32SockInit() < 0)
- return 1;
-
-#endif
-
- return 0;
-}
-
-#if USE_WIN32_SERVICE
-void
-WIN32_svcstatusupdate(DWORD svcstate, DWORD WaitHint)
-{
- if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
- svcStatus.dwCheckPoint++;
- svcStatus.dwWaitHint = WaitHint;
- svcStatus.dwCurrentState = svcstate;
- SetServiceStatus(svcHandle, &svcStatus);
- }
-}
-
-VOID WINAPI
-WIN32_svcHandler(DWORD Opcode)
-{
- DWORD status;
-
- switch (Opcode) {
-
- case _WIN_SQUID_SERVICE_CONTROL_STOP:
-
- case _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN:
- /* Do whatever it takes to stop here. */
- svcStatus.dwWin32ExitCode = 0;
- svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
- svcStatus.dwCheckPoint = 0;
- svcStatus.dwWaitHint = 10000;
- shut_down(SIGTERM);
-
- if (!SetServiceStatus(svcHandle, &svcStatus)) {
- status = GetLastError();
- debug(1, 1) ("SetServiceStatus error %ld\n", status);
- }
-
- debug(1, 1) ("Leaving Squid service\n");
- return;
-
- case _WIN_SQUID_SERVICE_CONTROL_INTERROGATE:
- /* Fall through to send current status. */
-
- if (!SetServiceStatus(svcHandle, &svcStatus)) {
- status = GetLastError();
- debug(1, 1) ("SetServiceStatus error %ld\n", status);
- }
-
- break;
-
- case _WIN_SQUID_SERVICE_CONTROL_ROTATE:
- rotate_logs(SIGUSR1);
- break;
-
- case _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE:
- reconfigure(SIGHUP);
- break;
-
- case _WIN_SQUID_SERVICE_CONTROL_DEBUG:
- sigusr2_handle(SIGUSR2);
- break;
-
- case _WIN_SQUID_SERVICE_CONTROL_INTERRUPT:
- /* Do whatever it takes to stop here. */
- svcStatus.dwWin32ExitCode = 0;
- svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
- svcStatus.dwCheckPoint = 0;
- svcStatus.dwWaitHint = 10000;
- shut_down(SIGINT);
-
- if (!SetServiceStatus(svcHandle, &svcStatus)) {
- status = GetLastError();
- debug(1, 1) ("SetServiceStatus error %ld\n", status);
- }
-
- debug(1, 1) ("Leaving Squid service\n");
- break;
-
- default:
- debug(1, 1) ("Unrecognized opcode %ld\n", Opcode);
- }
-
- return;
-}
-
-void
-WIN32_RemoveService()
-{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
-
- if (!WIN32_Service_name)
- WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
-
- strcat(REGKEY, WIN32_Service_name);
-
- keys[4] = WIN32_Service_name;
-
- schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
- NULL, /* database (NULL == default) */
- SC_MANAGER_ALL_ACCESS /* access required */
- );
-
- if (!schSCManager)
- fprintf(stderr, "OpenSCManager failed\n");
- else {
- schService = OpenService(schSCManager, WIN32_Service_name, SERVICE_ALL_ACCESS);
-
- if (schService == NULL)
- fprintf(stderr, "OpenService failed\n");
-
- /* Could not open the service */
- else {
- /* try to stop the service */
-
- if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP,
- &svcStatus)) {
- sleep(1);
-
- while (QueryServiceStatus(schService, &svcStatus)) {
- if (svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
- sleep(1);
- else
- break;
- }
- }
-
- /* now remove the service */
- if (DeleteService(schService) == 0)
- fprintf(stderr, "DeleteService failed.\n");
- else
- printf("Service %s deleted successfully.\n",
- WIN32_Service_name);
-
- CloseServiceHandle(schService);
- }
-
- CloseServiceHandle(schSCManager);
- }
-}
-
-void
-WIN32_SetServiceCommandLine()
-{
- if (!WIN32_Service_name)
- WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
-
- strcat(REGKEY, WIN32_Service_name);
-
- keys[4] = WIN32_Service_name;
-
- /* Now store the Service Command Line in the registry */
- WIN32_StoreKey(COMMANDLINE, REG_SZ, (unsigned char *) WIN32_Command_Line, strlen(WIN32_Command_Line) + 1);
-}
-
-void
-WIN32_InstallService()
-{
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
- char ServicePath[512];
- char szPath[512];
- int lenpath;
-
- if (!WIN32_Service_name)
- WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
-
- strcat(REGKEY, WIN32_Service_name);
-
- keys[4] = WIN32_Service_name;
-
- if ((lenpath = GetModuleFileName(NULL, ServicePath, 512)) == 0) {
- fprintf(stderr, "Can't get executable path\n");
- exit(1);
- }
-
- snprintf(szPath, sizeof(szPath), "%s %s:%s", ServicePath, _WIN_SQUID_SERVICE_OPTION, WIN32_Service_name);
- schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
- NULL, /* database (NULL == default) */
- SC_MANAGER_ALL_ACCESS /* access required */
- );
-
- if (!schSCManager) {
- fprintf(stderr, "OpenSCManager failed\n");
- exit(1);
- } else {
- schService = CreateService(schSCManager, /* SCManager database */
- WIN32_Service_name, /* name of service */
- WIN32_Service_name, /* name to display */
- SERVICE_ALL_ACCESS, /* desired access */
- SERVICE_WIN32_OWN_PROCESS, /* service type */
- SERVICE_AUTO_START, /* start type */
- SERVICE_ERROR_NORMAL, /* error control type */
- (const char *) szPath, /* service's binary */
- NULL, /* no load ordering group */
- NULL, /* no tag identifier */
- "Tcpip\0AFD\0", /* dependencies */
- NULL, /* LocalSystem account */
- NULL); /* no password */
-
- if (schService) {
- if (WIN32_OS_version > _WIN_OS_WINNT) {
- HMODULE ADVAPI32Handle;
- PFChangeServiceConfig2 ChangeServiceConfig2;
- DWORD dwInfoLevel = SERVICE_CONFIG_DESCRIPTION;
-
- ADVAPI32Handle = GetModuleHandle("advapi32");
- ChangeServiceConfig2 = (PFChangeServiceConfig2) GetProcAddress(ADVAPI32Handle, CHANGESERVICECONFIG2);
- ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceDescription);
- dwInfoLevel = SERVICE_CONFIG_FAILURE_ACTIONS;
- ChangeServiceConfig2(schService, dwInfoLevel, &Squid_ServiceFailureActions);
- }
-
- CloseServiceHandle(schService);
- /* Now store the config file location in the registry */
-
- if (!ConfigFile)
- ConfigFile = xstrdup(DefaultConfigFile);
-
- WIN32_StoreKey(CONFIGFILE, REG_SZ, (unsigned char *) ConfigFile, strlen(ConfigFile) + 1);
-
- printf("Squid Cache version %s for %s\n", version_string,
- CONFIG_HOST_TYPE);
-
- printf("installed successfully as %s Windows System Service.\n",
- WIN32_Service_name);
-
- printf
- ("To run, start it from the Services Applet of Control Panel.\n");
-
- printf("Don't forget to edit squid.conf before starting it.\n\n");
- } else {
- fprintf(stderr, "CreateService failed\n");
- exit(1);
- }
-
- CloseServiceHandle(schSCManager);
- }
-}
-
-void
-WIN32_sendSignal(int WIN32_signal)
-{
- SERVICE_STATUS ssStatus;
- DWORD fdwAccess, fdwControl;
- SC_HANDLE schService;
- SC_HANDLE schSCManager;
-
- if (!WIN32_Service_name)
- WIN32_Service_name = xstrdup(_WIN_SQUID_DEFAULT_SERVICE_NAME);
-
- schSCManager = OpenSCManager(NULL, /* machine (NULL == local) */
- NULL, /* database (NULL == default) */
- SC_MANAGER_ALL_ACCESS /* access required */
- );
-
- if (!schSCManager) {
- fprintf(stderr, "OpenSCManager failed\n");
- exit(1);
- }
-
- /* The required service object access depends on the control. */
- switch (WIN32_signal) {
-
- case 0: /* SIGNULL */
- fdwAccess = SERVICE_INTERROGATE;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE;
- break;
-
- case SIGUSR1:
- fdwAccess = SERVICE_USER_DEFINED_CONTROL;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_ROTATE;
- break;
-
- case SIGUSR2:
- fdwAccess = SERVICE_USER_DEFINED_CONTROL;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_DEBUG;
- break;
-
- case SIGHUP:
- fdwAccess = SERVICE_USER_DEFINED_CONTROL;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE;
- break;
-
- case SIGTERM:
- fdwAccess = SERVICE_STOP;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP;
- break;
-
- case SIGINT:
-
- case SIGKILL:
- fdwAccess = SERVICE_USER_DEFINED_CONTROL;
- fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT;
- break;
-
- default:
- exit(1);
- }
-
- /* Open a handle to the service. */
- schService = OpenService(schSCManager, /* SCManager database */
- WIN32_Service_name, /* name of service */
- fdwAccess); /* specify access */
-
- if (schService == NULL) {
- fprintf(stderr, "%s: ERROR: Could not open Service %s\n", appname,
- WIN32_Service_name);
- exit(1);
- } else {
- /* Send a control value to the service. */
-
- if (!ControlService(schService, /* handle of service */
- fdwControl, /* control value to send */
- &ssStatus)) { /* address of status info */
- fprintf(stderr, "%s: ERROR: Could not Control Service %s\n",
- appname, WIN32_Service_name);
- exit(1);
- } else {
- /* Print the service status. */
- printf("\nStatus of %s Service:\n", WIN32_Service_name);
- printf(" Service Type: 0x%lx\n", ssStatus.dwServiceType);
- printf(" Current State: 0x%lx\n", ssStatus.dwCurrentState);
- printf(" Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted);
- printf(" Exit Code: %ld\n", ssStatus.dwWin32ExitCode);
- printf(" Service Specific Exit Code: %ld\n",
- ssStatus.dwServiceSpecificExitCode);
- printf(" Check Point: %ld\n", ssStatus.dwCheckPoint);
- printf(" Wait Hint: %ld\n", ssStatus.dwWaitHint);
- }
-
- CloseServiceHandle(schService);
- }
-
- CloseServiceHandle(schSCManager);
-}
-
-int main(int argc, char **argv)
-{
- SERVICE_TABLE_ENTRY DispatchTable[] = {
- {NULL, SquidWinSvcMain},
- {NULL, NULL}
- };
- char *c;
- char stderr_path[256];
-
- if ((argc == 2) && strstr(argv[1], _WIN_SQUID_SERVICE_OPTION)) {
- strcpy(stderr_path, argv[0]);
- strcat(stderr_path,".log");
- freopen(stderr_path, "w", stderr);
- setmode(fileno(stderr), O_TEXT);
- WIN32_run_mode = _WIN_SQUID_RUN_MODE_SERVICE;
- opt_no_daemon = 1;
-
- if (!(c=strchr(argv[1],':'))) {
- fprintf(stderr, "Bad Service Parameter: %s\n", argv[1]);
- return 1;
- }
-
- WIN32_Service_name = xstrdup(c+1);
- DispatchTable[0].lpServiceName=WIN32_Service_name;
- strcat(REGKEY, WIN32_Service_name);
- keys[4] = WIN32_Service_name;
-
- if (!StartServiceCtrlDispatcher(DispatchTable)) {
- fprintf(stderr, "StartServiceCtrlDispatcher error = %ld\n",
- GetLastError());
- return 1;
- }
- } else {
- WIN32_run_mode = _WIN_SQUID_RUN_MODE_INTERACTIVE;
-#ifdef _SQUID_MSWIN_
-
- opt_no_daemon = 1;
-
-#endif
-
- return SquidMain(argc, argv);
- }
-
- return 0;
-}
-
-#endif /* USE_WIN32_SERVICE */
-
-#if defined(_SQUID_MSWIN_)
int WIN32_pipe(int handles[2])
{
int new_socket;
@@ -1022,64 +153,6 @@
return 0;
}
-static int Win32SockInit(void)
-{
- int iVersionRequested;
- WSADATA wsaData;
- int err, opt;
- int optlen = sizeof(opt);
-
- if (s_iInitCount > 0) {
- s_iInitCount++;
- return (0);
- } else if (s_iInitCount < 0)
- return (s_iInitCount);
-
- /* s_iInitCount == 0. Do the initailization */
- iVersionRequested = MAKEWORD(2, 0);
-
- err = WSAStartup((WORD) iVersionRequested, &wsaData);
-
- if (err) {
- s_iInitCount = -1;
- return (s_iInitCount);
- }
-
- if (LOBYTE(wsaData.wVersion) != 2 ||
- HIBYTE(wsaData.wVersion) != 0) {
- s_iInitCount = -2;
- WSACleanup();
- return (s_iInitCount);
- }
-
- if (WIN32_OS_version !=_WIN_OS_WINNT) {
- if (::getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&opt, &optlen)) {
- s_iInitCount = -3;
- WSACleanup();
- return (s_iInitCount);
- } else {
- opt = opt | SO_SYNCHRONOUS_NONALERT;
-
- if (::setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &opt, optlen)) {
- s_iInitCount = -3;
- WSACleanup();
- return (s_iInitCount);
- }
- }
- }
-
- WIN32_Socks_initialized = 1;
- s_iInitCount++;
- return (s_iInitCount);
-}
-
-static void Win32SockCleanup(void)
-{
- if (--s_iInitCount == 0)
- WSACleanup();
-
- return;
-}
int Win32__WSAFDIsSet(int fd, fd_set FAR * set
)
@@ -1091,11 +164,6 @@
);
}
-void Squid_Win32InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
-{
- return;
-}
-
LONG CALLBACK WIN32_ExceptionHandler(EXCEPTION_POINTERS* ep)
{
EXCEPTION_RECORD* er;