mswindows.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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// The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port.
15// Compiles only on MS Visual C++
16// CygWin appears not to need any of these
17#if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
18
19#define sys_nerr _sys_nerr
20
21#undef assert
22#include <cassert>
23#include <cstring>
24#include <fcntl.h>
25#include <sys/timeb.h>
26#if HAVE_PSAPI_H
27#include <psapi.h>
28#endif
29#ifndef _MSWSOCK_
30#include <mswsock.h>
31#endif
32
33THREADLOCAL int ws32_result;
34LPCRITICAL_SECTION dbg_mutex = nullptr;
35
36void GetProcessName(pid_t, char *);
37
38#if HAVE_GETPAGESIZE > 1
39size_t
40getpagesize()
41{
42 static DWORD system_pagesize = 0;
43 if (!system_pagesize) {
44 SYSTEM_INFO system_info;
45 GetSystemInfo(&system_info);
46 system_pagesize = system_info.dwPageSize;
47 }
48 return system_pagesize;
49}
50#endif /* HAVE_GETPAGESIZE > 1 */
51
52int
53chroot(const char *dirname)
54{
55 if (SetCurrentDirectory(dirname))
56 return 0;
57 else
58 return GetLastError();
59}
60
61void
62GetProcessName(pid_t pid, char *ProcessName)
63{
64 strcpy(ProcessName, "unknown");
65#if defined(PSAPI_VERSION)
66 /* Get a handle to the process. */
67 HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
68 /* Get the process name. */
69 if (hProcess) {
70 HMODULE hMod;
71 DWORD cbNeeded;
72
73 if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
74 GetModuleBaseName(hProcess, hMod, ProcessName, sizeof(ProcessName));
75 else {
76 CloseHandle(hProcess);
77 return;
78 }
79 } else
80 return;
81 CloseHandle(hProcess);
82#endif
83}
84
85int
86kill(pid_t pid, int sig)
87{
88 HANDLE hProcess;
89 char MyProcessName[MAX_PATH];
90 char ProcessNameToCheck[MAX_PATH];
91
92 if (sig == 0) {
93 if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid)))
94 return -1;
95 else {
96 CloseHandle(hProcess);
97 GetProcessName(getpid(), MyProcessName);
98 GetProcessName(pid, ProcessNameToCheck);
99 if (strcmp(MyProcessName, ProcessNameToCheck) == 0)
100 return 0;
101 return -1;
102 }
103 } else
104 return 0;
105}
106
107#if !HAVE_GETTIMEOFDAY
108int
109gettimeofday(struct timeval *pcur_time, void *tzp)
110{
111 struct _timeb current;
112 struct timezone *tz = (struct timezone *) tzp;
113
114 _ftime(&current);
115
116 pcur_time->tv_sec = current.time;
117 pcur_time->tv_usec = current.millitm * 1000L;
118 if (tz) {
119 tz->tz_minuteswest = current.timezone; /* minutes west of Greenwich */
120 tz->tz_dsttime = current.dstflag; /* type of dst correction */
121 }
122 return 0;
123}
124#endif /* !HAVE_GETTIMEOFDAY */
125
126int
127WIN32_ftruncate(int fd, off_t size)
128{
129 HANDLE hfile;
130 unsigned int curpos;
131
132 if (fd < 0)
133 return -1;
134
135 hfile = (HANDLE) _get_osfhandle(fd);
136 curpos = SetFilePointer(hfile, 0, nullptr, FILE_CURRENT);
137 if (curpos == 0xFFFFFFFF
138 || SetFilePointer(hfile, size, nullptr, FILE_BEGIN) == 0xFFFFFFFF
139 || !SetEndOfFile(hfile)) {
140 int error = GetLastError();
141
142 switch (error) {
143 case ERROR_INVALID_HANDLE:
144 errno = EBADF;
145 break;
146 default:
147 errno = EIO;
148 break;
149 }
150
151 return -1;
152 }
153 return 0;
154}
155
156int
157WIN32_truncate(const char *pathname, off_t length)
158{
159 int fd;
160 int res = -1;
161
162 fd = open(pathname, O_RDWR);
163
164 if (fd == -1)
165 errno = EBADF;
166 else {
167 res = WIN32_ftruncate(fd, length);
168 _close(fd);
169 }
170
171 return res;
172}
173
174struct passwd *
175getpwnam(char *unused) {
176 static struct passwd pwd = {nullptr, nullptr, 100, 100, nullptr, nullptr, nullptr};
177 return &pwd;
178}
179
180struct group *
181getgrnam(char *unused) {
182 static struct group grp = {nullptr, nullptr, 100, nullptr};
183 return &grp;
184}
185
186struct errorentry {
187 unsigned long WIN32_code;
188 int POSIX_errno;
189};
190
191static struct errorentry errortable[] = {
192 {ERROR_INVALID_FUNCTION, EINVAL},
193 {ERROR_FILE_NOT_FOUND, ENOENT},
194 {ERROR_PATH_NOT_FOUND, ENOENT},
195 {ERROR_TOO_MANY_OPEN_FILES, EMFILE},
196 {ERROR_ACCESS_DENIED, EACCES},
197 {ERROR_INVALID_HANDLE, EBADF},
198 {ERROR_ARENA_TRASHED, ENOMEM},
199 {ERROR_NOT_ENOUGH_MEMORY, ENOMEM},
200 {ERROR_INVALID_BLOCK, ENOMEM},
201 {ERROR_BAD_ENVIRONMENT, E2BIG},
202 {ERROR_BAD_FORMAT, ENOEXEC},
203 {ERROR_INVALID_ACCESS, EINVAL},
204 {ERROR_INVALID_DATA, EINVAL},
205 {ERROR_INVALID_DRIVE, ENOENT},
206 {ERROR_CURRENT_DIRECTORY, EACCES},
207 {ERROR_NOT_SAME_DEVICE, EXDEV},
208 {ERROR_NO_MORE_FILES, ENOENT},
209 {ERROR_LOCK_VIOLATION, EACCES},
210 {ERROR_BAD_NETPATH, ENOENT},
211 {ERROR_NETWORK_ACCESS_DENIED, EACCES},
212 {ERROR_BAD_NET_NAME, ENOENT},
213 {ERROR_FILE_EXISTS, EEXIST},
214 {ERROR_CANNOT_MAKE, EACCES},
215 {ERROR_FAIL_I24, EACCES},
216 {ERROR_INVALID_PARAMETER, EINVAL},
217 {ERROR_NO_PROC_SLOTS, EAGAIN},
218 {ERROR_DRIVE_LOCKED, EACCES},
219 {ERROR_BROKEN_PIPE, EPIPE},
220 {ERROR_DISK_FULL, ENOSPC},
221 {ERROR_INVALID_TARGET_HANDLE, EBADF},
222 {ERROR_INVALID_HANDLE, EINVAL},
223 {ERROR_WAIT_NO_CHILDREN, ECHILD},
224 {ERROR_CHILD_NOT_COMPLETE, ECHILD},
225 {ERROR_DIRECT_ACCESS_HANDLE, EBADF},
226 {ERROR_NEGATIVE_SEEK, EINVAL},
227 {ERROR_SEEK_ON_DEVICE, EACCES},
228 {ERROR_DIR_NOT_EMPTY, ENOTEMPTY},
229 {ERROR_NOT_LOCKED, EACCES},
230 {ERROR_BAD_PATHNAME, ENOENT},
231 {ERROR_MAX_THRDS_REACHED, EAGAIN},
232 {ERROR_LOCK_FAILED, EACCES},
233 {ERROR_ALREADY_EXISTS, EEXIST},
234 {ERROR_FILENAME_EXCED_RANGE, ENOENT},
235 {ERROR_NESTING_NOT_ALLOWED, EAGAIN},
236 {ERROR_NOT_ENOUGH_QUOTA, ENOMEM}
237};
238
239#define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
240#define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
241
242#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
243#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
244
245void
246WIN32_maperror(unsigned long WIN32_oserrno)
247{
248 _doserrno = WIN32_oserrno;
249 for (size_t i = 0; i < (sizeof(errortable) / sizeof(struct errorentry)); ++i) {
250 if (WIN32_oserrno == errortable[i].WIN32_code) {
251 errno = errortable[i].POSIX_errno;
252 return;
253 }
254 }
255 if (WIN32_oserrno >= MIN_EACCES_RANGE && WIN32_oserrno <= MAX_EACCES_RANGE)
256 errno = EACCES;
257 else if (WIN32_oserrno >= MIN_EXEC_ERROR && WIN32_oserrno <= MAX_EXEC_ERROR)
258 errno = ENOEXEC;
259 else
260 errno = EINVAL;
261}
262
263/* syslog emulation layer derived from git */
264static HANDLE ms_eventlog;
265
266void
267openlog(const char *ident, int logopt, int facility)
268{
269 if (ms_eventlog)
270 return;
271
272 ms_eventlog = RegisterEventSourceA(nullptr, ident);
273
274 // note: RegisterEventAtSourceA may fail and return nullptr.
275 // in that case we'll just retry at the next message or not log
276}
277#define SYSLOG_MAX_MSG_SIZE 1024
278
279void
280syslog(int priority, const char *fmt, ...)
281{
282 WORD logtype;
283 char *str=static_cast<char *>(xmalloc(SYSLOG_MAX_MSG_SIZE));
284 int str_len;
285 va_list ap;
286
287 if (!ms_eventlog)
288 return;
289
290 va_start(ap, fmt);
291 str_len = vsnprintf(str, SYSLOG_MAX_MSG_SIZE-1, fmt, ap);
292 va_end(ap);
293
294 if (str_len < 0) {
295 /* vsnprintf failed */
296 return;
297 }
298
299 switch (priority) {
300 case LOG_EMERG:
301 case LOG_ALERT:
302 case LOG_CRIT:
303 case LOG_ERR:
304 logtype = EVENTLOG_ERROR_TYPE;
305 break;
306
307 case LOG_WARNING:
308 logtype = EVENTLOG_WARNING_TYPE;
309 break;
310
311 case LOG_NOTICE:
312 case LOG_INFO:
313 case LOG_DEBUG:
314 default:
315 logtype = EVENTLOG_INFORMATION_TYPE;
316 break;
317 }
318
319 //Windows API suck. They are overengineered
320 ReportEventA(ms_eventlog, logtype, 0, 0, nullptr, 1, 0,
321 const_cast<const char **>(&str), nullptr);
322}
323
324/* note: this is all MSWindows-specific code; all of it should be conditional */
325#endif /* _SQUID_WINDOWS_ */
326
static pid_t pid
Definition: IcmpSquid.cc:34
int size
Definition: ModDevPoll.cc:75
SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex
Definition: WinSvc.cc:48
void error(char *format,...)
#define xmalloc
unsigned short WORD
Definition: smblib-priv.h:145
#define FALSE
Definition: std-includes.h:56

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors