20#if !defined(_MSWSOCK_)
38static int WIN32_StoreKey(
const char *, DWORD,
unsigned char *,
int);
53#undef NotifyAddrChange
55#define NOTIFYADDRCHANGE "NotifyAddrChange"
64#define VENDOR "squid-cache.org"
66#define SOFTWARENAME PACKAGE_NAME
68#define SOFTWARE "SOFTWARE"
70#define COMMANDLINE "CommandLine"
71#define CONFIGFILE "ConfigFile"
72#undef ChangeServiceConfig2
75#define CHANGESERVICECONFIG2 "ChangeServiceConfig2W"
77#define CHANGESERVICECONFIG2 "ChangeServiceConfig2A"
109 hKey = HKEY_LOCAL_MACHINE;
115 while (
keys[index]) {
116 unsigned long result;
117 rv = RegCreateKeyEx(hKey,
keys[index],
120 REG_OPTION_NON_VOLATILE, KEY_WRITE,
nullptr, &hKeyNext, &result);
122 if (rv != ERROR_SUCCESS) {
123 fprintf(stderr,
"RegCreateKeyEx(%s),%d\n",
keys[index], (
int) rv);
128 rv = RegCloseKey(hKey);
130 if (rv != ERROR_SUCCESS) {
131 fprintf(stderr,
"RegCloseKey %d\n", (
int) rv);
151 rv = RegCloseKey(hKey);
153 if (rv != ERROR_SUCCESS) {
154 fprintf(stderr,
"RegCloseKey %d\n", (
int) rv);
174 rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGKEY, 0, KEY_WRITE, &hKey);
176 if (rv == ERROR_FILE_NOT_FOUND) {
187 rv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGKEY, 0, KEY_WRITE, &hKey);
189 if (rv == ERROR_FILE_NOT_FOUND) {
190 fprintf(stderr,
"Registry does not contain key %s after creation\n",
196 if (rv != ERROR_SUCCESS) {
197 fprintf(stderr,
"RegOpenKeyEx HKLM\\%s, %d\n",
REGKEY, (
int) rv);
202 rv = RegSetValueEx(hKey, key,
210 if (rv != ERROR_SUCCESS) {
211 fprintf(stderr,
"RegQueryValueEx(key %s),%d\n", key, (
int) rv);
214 fprintf(stderr,
"Registry stored HKLM\\%s\\%s value %s\n",
217 type == REG_SZ ? value : (
unsigned char *)
"(not displayable)");
223 rv = RegCloseKey(hKey);
225 if (rv != ERROR_SUCCESS) {
226 fprintf(stderr,
"RegCloseKey HKLM\\%s, %d\n",
REGKEY, (
int) rv);
287 OSVERSIONINFOEX osvi;
288 BOOL bOsVersionInfoEx;
291 memset(&osvi,
'\0',
sizeof(OSVERSIONINFOEX));
296 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFOEX);
298 if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) & osvi))) {
299 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
300 if (!GetVersionEx((OSVERSIONINFO *) & osvi))
303 switch (osvi.dwPlatformId) {
304 case VER_PLATFORM_WIN32_NT:
305 if (osvi.dwMajorVersion <= 4) {
306 WIN32_OS_string =
xstrdup(
"Windows NT");
307 return _WIN_OS_WINNT;
309 if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 0)) {
310 WIN32_OS_string =
xstrdup(
"Windows 2000");
311 return _WIN_OS_WIN2K;
313 if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 1)) {
314 WIN32_OS_string =
xstrdup(
"Windows XP");
315 return _WIN_OS_WINXP;
317 if ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion == 2)) {
318 WIN32_OS_string =
xstrdup(
"Windows Server 2003");
319 return _WIN_OS_WINNET;
321 if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion == 0)) {
322 if (osvi.wProductType == VER_NT_WORKSTATION)
323 WIN32_OS_string =
xstrdup(
"Windows Vista");
325 WIN32_OS_string =
xstrdup(
"Windows Server 2008");
326 return _WIN_OS_WINLON;
328 if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion == 1)) {
329 if (osvi.wProductType == VER_NT_WORKSTATION)
330 WIN32_OS_string =
xstrdup(
"Windows 7");
332 WIN32_OS_string =
xstrdup(
"Windows Server 2008 R2");
335 if (((osvi.dwMajorVersion > 6)) || ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion > 1))) {
336 if (osvi.wProductType == VER_NT_WORKSTATION)
337 WIN32_OS_string =
xstrdup(
"Unknown Windows version, assuming Windows 7 capabilities");
339 WIN32_OS_string =
xstrdup(
"Unknown Windows version, assuming Windows Server 2008 R2 capabilities");
343 case VER_PLATFORM_WIN32_WINDOWS:
344 if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 0)) {
345 WIN32_OS_string =
xstrdup(
"Windows 95");
346 return _WIN_OS_WIN95;
348 if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 10)) {
349 WIN32_OS_string =
xstrdup(
"Windows 98");
350 return _WIN_OS_WIN98;
352 if ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion == 90)) {
353 WIN32_OS_string =
xstrdup(
"Windows Me");
354 return _WIN_OS_WINME;
357 case VER_PLATFORM_WIN32s:
358 WIN32_OS_string =
xstrdup(
"Windows 3.1 with WIN32S");
359 return _WIN_OS_WIN32S;
365 WIN32_OS_string =
xstrdup(
"Unknown Windows system");
366 return _WIN_OS_UNKNOWN;
377 svcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
387 DWORD status = ERROR_SUCCESS;
401 if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
403 svcStatus.dwCurrentState = SERVICE_STOPPED;
421 HMODULE IPHLPAPIHandle;
424 if ((IPHLPAPIHandle = GetModuleHandle(
"IPHLPAPI")) ==
NULL)
425 IPHLPAPIHandle = LoadLibrary(
"IPHLPAPI");
429 Result = NotifyAddrChange(
nullptr,
nullptr);
430 if (Result != NO_ERROR) {
434 debugs(1,
DBG_IMPORTANT,
"Notification of IP address change received, requesting Squid reconfiguration ...");
443 DWORD status = ERROR_SUCCESS;
444 DWORD threadID = 0, ThrdParam = 0;
448 &ThrdParam, 0, &threadID);
450 status = GetLastError();
454 debugs(1, 2,
"Starting IP monitor thread [" << threadID <<
"] ...");
462 _invalid_parameter_handler oldHandler, newHandler;
467 if ((WIN32_OS_version == _WIN_OS_UNKNOWN) || (WIN32_OS_version == _WIN_OS_WIN32S))
477 oldHandler = _set_invalid_parameter_handler(newHandler);
479 _CrtSetReportMode(_CRT_ASSERT, 0);
484 if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
498 GetModuleFileName(
nullptr, path, 512);
502 path[strlen(path) - 10] =
'\0';
504 if (SetCurrentDirectory(path) == 0)
510 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
REGKEY, 0, KEY_QUERY_VALUE, &hndKey) == ERROR_SUCCESS) {
514 Result = RegQueryValueEx(hndKey,
CONFIGFILE,
nullptr, &
Type,
nullptr, &Size);
516 if (Result == ERROR_SUCCESS && Size) {
526 Result = RegQueryValueEx(hndKey,
COMMANDLINE,
nullptr, &
Type,
nullptr, &Size);
528 if (Result == ERROR_SUCCESS && Size) {
529 WIN32_Service_Command_Line =
static_cast<char *
>(
xmalloc(Size));
530 RegQueryValueEx(hndKey,
COMMANDLINE,
nullptr, &
Type, (
unsigned char *)WIN32_Service_Command_Line, &Size);
532 WIN32_Service_Command_Line =
xstrdup(
"");
537 WIN32_Service_Command_Line =
xstrdup(
"");
544 svcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
545 svcStatus.dwCurrentState = SERVICE_START_PENDING;
547 SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
569 if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) {
584 case _WIN_SQUID_SERVICE_CONTROL_STOP:
586 case _WIN_SQUID_SERVICE_CONTROL_SHUTDOWN:
589 svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
595 status = GetLastError();
602 case _WIN_SQUID_SERVICE_CONTROL_INTERROGATE:
606 status = GetLastError();
612 case _WIN_SQUID_SERVICE_CONTROL_ROTATE:
616 case _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE:
620 case _WIN_SQUID_SERVICE_CONTROL_DEBUG:
624 case _WIN_SQUID_SERVICE_CONTROL_INTERRUPT:
627 svcStatus.dwCurrentState = SERVICE_STOP_PENDING;
633 status = GetLastError();
650 SC_HANDLE schService;
651 SC_HANDLE schSCManager;
659 keys[4] =
const_cast<char*
>(service);
661 schSCManager = OpenSCManager(
nullptr,
663 SC_MANAGER_ALL_ACCESS
667 fprintf(stderr,
"OpenSCManager failed\n");
669 schService = OpenService(schSCManager, service, SERVICE_ALL_ACCESS);
671 if (schService ==
NULL)
672 fprintf(stderr,
"OpenService failed\n");
678 if (ControlService(schService, _WIN_SQUID_SERVICE_CONTROL_STOP,
682 while (QueryServiceStatus(schService, &
svcStatus)) {
683 if (
svcStatus.dwCurrentState == SERVICE_STOP_PENDING)
691 if (DeleteService(schService) == 0)
692 fprintf(stderr,
"DeleteService failed.\n");
696 CloseServiceHandle(schService);
699 CloseServiceHandle(schSCManager);
712 keys[4] =
const_cast<char*
>(service);
721 SC_HANDLE schService;
722 SC_HANDLE schSCManager;
723 char ServicePath[512];
733 keys[4] =
const_cast<char*
>(service);
735 if ((lenpath = GetModuleFileName(
nullptr, ServicePath, 512)) == 0) {
736 fprintf(stderr,
"Can't get executable path\n");
741 schSCManager = OpenSCManager(
nullptr,
743 SC_MANAGER_ALL_ACCESS
747 fprintf(stderr,
"OpenSCManager failed\n");
750 schService = CreateService(schSCManager,
754 SERVICE_WIN32_OWN_PROCESS,
756 SERVICE_ERROR_NORMAL,
757 (
const char *) szPath,
765 if (WIN32_OS_version > _WIN_OS_WINNT) {
766 HMODULE ADVAPI32Handle;
768 DWORD dwInfoLevel = SERVICE_CONFIG_DESCRIPTION;
770 ADVAPI32Handle = GetModuleHandle(
"advapi32");
773 dwInfoLevel = SERVICE_CONFIG_FAILURE_ACTIONS;
777 CloseServiceHandle(schService);
785 printf(
"Squid Cache version %s for %s\n",
version_string, CONFIG_HOST_TYPE);
787 printf(
"To run, start it from the Services Applet of Control Panel.\n");
788 printf(
"Don't forget to edit squid.conf before starting it.\n\n");
790 fprintf(stderr,
"CreateService failed\n");
794 CloseServiceHandle(schSCManager);
801 SERVICE_STATUS ssStatus;
802 DWORD fdwAccess, fdwControl;
803 SC_HANDLE schService;
804 SC_HANDLE schSCManager;
809 schSCManager = OpenSCManager(
nullptr,
811 SC_MANAGER_ALL_ACCESS
815 fprintf(stderr,
"OpenSCManager failed\n");
820 switch (WIN32_signal) {
823 fdwAccess = SERVICE_INTERROGATE;
824 fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERROGATE;
828 fdwAccess = SERVICE_USER_DEFINED_CONTROL;
829 fdwControl = _WIN_SQUID_SERVICE_CONTROL_ROTATE;
833 fdwAccess = SERVICE_USER_DEFINED_CONTROL;
834 fdwControl = _WIN_SQUID_SERVICE_CONTROL_DEBUG;
838 fdwAccess = SERVICE_USER_DEFINED_CONTROL;
839 fdwControl = _WIN_SQUID_SERVICE_CONTROL_RECONFIGURE;
843 fdwAccess = SERVICE_STOP;
844 fdwControl = _WIN_SQUID_SERVICE_CONTROL_STOP;
850 fdwAccess = SERVICE_USER_DEFINED_CONTROL;
851 fdwControl = _WIN_SQUID_SERVICE_CONTROL_INTERRUPT;
859 schService = OpenService(schSCManager,
863 if (schService ==
NULL) {
869 if (!ControlService(schService,
872 fprintf(stderr,
"%s: ERROR: Could not Control Service " SQUIDSBUFPH "\n",
878 printf(
" Service Type: 0x%lx\n", ssStatus.dwServiceType);
879 printf(
" Current State: 0x%lx\n", ssStatus.dwCurrentState);
880 printf(
" Controls Accepted: 0x%lx\n", ssStatus.dwControlsAccepted);
881 printf(
" Exit Code: %ld\n", ssStatus.dwWin32ExitCode);
882 printf(
" Service Specific Exit Code: %ld\n",
883 ssStatus.dwServiceSpecificExitCode);
884 printf(
" Check Point: %ld\n", ssStatus.dwCheckPoint);
885 printf(
" Wait Hint: %ld\n", ssStatus.dwWaitHint);
888 CloseServiceHandle(schService);
891 CloseServiceHandle(schSCManager);
896 SERVICE_TABLE_ENTRY DispatchTable[] = {
901 char stderr_path[256];
903 strcpy(stderr_path, argv[0]);
904 strcat(stderr_path,
".log");
905 freopen(stderr_path,
"w", stderr);
906 setmode(fileno(stderr),
O_TEXT);
907 WIN32_run_mode = _WIN_SQUID_RUN_MODE_SERVICE;
909 if (!(c=strchr(argv[1],
':'))) {
910 fprintf(stderr,
"Bad Service Parameter: %s\n", argv[1]);
916 DispatchTable[0].lpServiceName =
const_cast<char*
>(service);
918 keys[4] =
const_cast<char*
>(service);
920 if (!StartServiceCtrlDispatcher(DispatchTable)) {
921 fprintf(stderr,
"StartServiceCtrlDispatcher error = %ld\n", GetLastError());
932 int iVersionRequested;
935 int optlen =
sizeof(opt);
944 iVersionRequested = MAKEWORD(2, 0);
946 err = WSAStartup((
WORD) iVersionRequested, &wsaData);
953 if (LOBYTE(wsaData.wVersion) != 2 ||
954 HIBYTE(wsaData.wVersion) != 0) {
960 if (WIN32_OS_version !=_WIN_OS_WINNT) {
961 if (::getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (
char *)&opt, &optlen)) {
966 opt = opt | SO_SYNCHRONOUS_NONALERT;
968 if (::setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (
char *) &opt, optlen)) {
976 WIN32_Socks_initialized = 1;
#define SQUIDSBUFPRINT(s)
static SC_ACTION Squid_SCAction[]
void Squid_Win32InvalidParameterHandler(const wchar_t *expression, const wchar_t *function, const wchar_t *file, unsigned int line, uintptr_t pReserved)
static int WIN32_create_key(void)
static char VENDORString[]
static void WIN32_Abort(int)
static DWORD WINAPI WIN32_IpAddrChangeMonitor(LPVOID lpParam)
static char SOFTWARENAMEString[]
void WIN32_IpAddrChangeMonitorExit()
static SERVICE_FAILURE_ACTIONS Squid_ServiceFailureActions
static int Squid_Aborting
static char Squid_ServiceDescriptionString[]
static SERVICE_STATUS_HANDLE svcHandle
void WIN32_ExceptionHandlerCleanup(void)
static int WIN32_StoreKey(const char *, DWORD, unsigned char *, int)
void WIN32_SetServiceCommandLine()
static int Win32SockInit(void)
int WIN32_StartService(int argc, char **argv)
int WIN32_Subsystem_Init(int *argc, char ***argv)
static unsigned int GetOSVersion()
static void WIN32_Exit(void)
static char * WIN32_module_name
static char ** WIN32_argv
static SERVICE_STATUS svcStatus
void WINAPI WIN32_svcHandler(DWORD)
static void Win32SockCleanup(void)
void WIN32_svcstatusupdate(DWORD, DWORD)
void WIN32_RemoveService()
#define CHANGESERVICECONFIG2
void WINAPI SquidWinSvcMain(DWORD, char **)
static HANDLE NotifyAddrChange_thread
void WIN32_InstallService()
SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex
static SERVICE_DESCRIPTION Squid_ServiceDescription
static void WIN32_build_argv(char *)
DWORD(WINAPI * PFNotifyAddrChange)(OUT PHANDLE, IN LPOVERLAPPED)
DWORD WIN32_IpAddrChangeMonitorInit()
static char SOFTWAREString[]
void WIN32_sendSignal(int WIN32_signal)
BOOL(WINAPI * PFChangeServiceConfig2)(SC_HANDLE, DWORD, LPVOID)
struct SquidConfig::@106 onoff
int WIN32_IpAddrChangeMonitor
#define debugs(SECTION, LEVEL, CONTENT)
const char * version_string
void rotate_logs(int sig)
void reconfigure(int sig)
void * xrealloc(void *s, size_t sz)