Squid Web Cache master
Loading...
Searching...
No Matches
mswindows.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9/* Windows support
10 * Inspired by previous work by Romeo Anghelache & Eric Stern. */
11
12#include "squid.h"
13
14#include "compat/unistd.h"
15
16// The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port.
17// Compiles only on MS Visual C++
18// CygWin appears not to need any of these
19#if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
20
21#define sys_nerr _sys_nerr
22
23#undef assert
24#include <cassert>
25#include <cstring>
26#include <fcntl.h>
27#include <memory>
28#include <sys/timeb.h>
29#if HAVE_PSAPI_H
30#include <psapi.h>
31#endif
32#ifndef _MSWSOCK_
33#include <mswsock.h>
34#endif
35
36THREADLOCAL int ws32_result;
37LPCRITICAL_SECTION dbg_mutex = nullptr;
38
39void GetProcessName(pid_t, char *);
40
41#if HAVE_GETPAGESIZE > 1
42size_t
43getpagesize()
44{
45 static DWORD system_pagesize = 0;
46 if (!system_pagesize) {
47 SYSTEM_INFO system_info;
48 GetSystemInfo(&system_info);
49 system_pagesize = system_info.dwPageSize;
50 }
51 return system_pagesize;
52}
53#endif /* HAVE_GETPAGESIZE > 1 */
54
55int
56chroot(const char *dirname)
57{
58 if (SetCurrentDirectory(dirname))
59 return 0;
60 else
61 return GetLastError();
62}
63
64void
65GetProcessName(pid_t pid, char *ProcessName)
66{
67 strcpy(ProcessName, "unknown");
68#if defined(PSAPI_VERSION)
69 /* Get a handle to the process. */
70 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
71 /* Get the process name. */
72 if (hProcess) {
73 HMODULE hMod;
74 DWORD cbNeeded;
75
76 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
77 GetModuleBaseName(hProcess, hMod, ProcessName, sizeof(ProcessName));
78 else {
79 CloseHandle(hProcess);
80 return;
81 }
82 } else
83 return;
84 CloseHandle(hProcess);
85#endif
86}
87
88int
89kill(pid_t pid, int sig)
90{
91 HANDLE hProcess;
92 char MyProcessName[MAX_PATH];
93 char ProcessNameToCheck[MAX_PATH];
94
95 if (sig == 0) {
96 if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)))
97 return -1;
98 else {
99 CloseHandle(hProcess);
100 GetProcessName(getpid(), MyProcessName);
101 GetProcessName(pid, ProcessNameToCheck);
102 if (strcmp(MyProcessName, ProcessNameToCheck) == 0)
103 return 0;
104 return -1;
105 }
106 } else
107 return 0;
108}
109
110#if !HAVE_GETTIMEOFDAY
111int
112gettimeofday(struct timeval *pcur_time, void *tzp)
113{
114 struct _timeb current;
115 struct timezone *tz = (struct timezone *) tzp;
116
117 _ftime(&current);
118
119 pcur_time->tv_sec = current.time;
120 pcur_time->tv_usec = current.millitm * 1000L;
121 if (tz) {
122 tz->tz_minuteswest = current.timezone; /* minutes west of Greenwich */
123 tz->tz_dsttime = current.dstflag; /* type of dst correction */
124 }
125 return 0;
126}
127#endif /* !HAVE_GETTIMEOFDAY */
128
129int
130WIN32_ftruncate(int fd, off_t size)
131{
132 HANDLE hfile;
133 unsigned int curpos;
134
135 if (fd < 0)
136 return -1;
137
138 hfile = (HANDLE) _get_osfhandle(fd);
139 curpos = SetFilePointer(hfile, 0, nullptr, FILE_CURRENT);
140 if (curpos == 0xFFFFFFFF
141 || SetFilePointer(hfile, size, nullptr, FILE_BEGIN) == 0xFFFFFFFF
142 || !SetEndOfFile(hfile)) {
143 int error = GetLastError();
144
145 switch (error) {
146 case ERROR_INVALID_HANDLE:
147 errno = EBADF;
148 break;
149 default:
150 errno = EIO;
151 break;
152 }
153
154 return -1;
155 }
156 return 0;
157}
158
159int
160WIN32_truncate(const char *pathname, off_t length)
161{
162 int res = -1;
163
164 const auto fd = xopen(pathname, O_RDWR);
165
166 if (fd == -1)
167 errno = EBADF;
168 else {
169 res = WIN32_ftruncate(fd, length);
170 _close(fd);
171 }
172
173 return res;
174}
175
176struct passwd *
177getpwnam(char *unused) {
178 static struct passwd pwd = {nullptr, nullptr, 100, 100, nullptr, nullptr, nullptr};
179 return &pwd;
180}
181
182struct group *
183getgrnam(char *unused) {
184 static struct group grp = {nullptr, nullptr, 100, nullptr};
185 return &grp;
186}
187
188/* syslog emulation layer derived from git */
189static HANDLE ms_eventlog;
190
191void
192openlog(const char *ident, int logopt, int facility)
193{
194 if (ms_eventlog)
195 return;
196
197 ms_eventlog = RegisterEventSourceA(nullptr, ident);
198
199 // note: RegisterEventAtSourceA may fail and return nullptr.
200 // in that case we'll just retry at the next message or not log
201}
202#define SYSLOG_MAX_MSG_SIZE 1024
203
204void
205syslog(int priority, const char *fmt, ...)
206{
207 WORD logtype;
208 int str_len;
209 va_list ap;
210
211 if (!ms_eventlog)
212 return;
213
214 va_start(ap, fmt);
215 auto buf = std::make_unique<char[]>(SYSLOG_MAX_MSG_SIZE);
216 str_len = vsnprintf(buf.get(), SYSLOG_MAX_MSG_SIZE, fmt, ap);
217 va_end(ap);
218
219 if (str_len < 0) {
220 /* vsnprintf failed */
221 return;
222 }
223
224 switch (priority) {
225 case LOG_EMERG:
226 case LOG_ALERT:
227 case LOG_CRIT:
228 case LOG_ERR:
229 logtype = EVENTLOG_ERROR_TYPE;
230 break;
231
232 case LOG_WARNING:
233 logtype = EVENTLOG_WARNING_TYPE;
234 break;
235
236 case LOG_NOTICE:
237 case LOG_INFO:
238 case LOG_DEBUG:
239 default:
240 logtype = EVENTLOG_INFORMATION_TYPE;
241 break;
242 }
243
244 //Windows API suck. They are overengineered
245 const auto strings[1] = { buf.get() };
246 ReportEventA(ms_eventlog, logtype, 0, 0, nullptr, 1, 0,
247 strings, nullptr);
248}
249
250/* note: this is all MSWindows-specific code; all of it should be conditional */
251#endif /* _SQUID_WINDOWS_ && !_SQUID_CYGWIN_*/
static pid_t pid
Definition IcmpSquid.cc:36
int size
Definition ModDevPoll.cc:70
void error(char *format,...)
#define FALSE
Definition defines.h:16
int xopen(const char *filename, int oflag, int pmode=0)
POSIX open(2) equivalent.
Definition unistd.h:55
SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex