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 
36 THREADLOCAL int ws32_result;
37 LPCRITICAL_SECTION dbg_mutex = nullptr;
38 
39 void GetProcessName(pid_t, char *);
40 
41 #if HAVE_GETPAGESIZE > 1
42 size_t
43 getpagesize()
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 
55 int
56 chroot(const char *dirname)
57 {
58  if (SetCurrentDirectory(dirname))
59  return 0;
60  else
61  return GetLastError();
62 }
63 
64 void
65 GetProcessName(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 
88 int
89 kill(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
111 int
112 gettimeofday(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 
129 int
130 WIN32_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 
159 int
160 WIN32_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 
176 struct passwd *
177 getpwnam(char *unused) {
178  static struct passwd pwd = {nullptr, nullptr, 100, 100, nullptr, nullptr, nullptr};
179  return &pwd;
180 }
181 
182 struct group *
183 getgrnam(char *unused) {
184  static struct group grp = {nullptr, nullptr, 100, nullptr};
185  return &grp;
186 }
187 
188 /* syslog emulation layer derived from git */
189 static HANDLE ms_eventlog;
190 
191 void
192 openlog(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 
204 void
205 syslog(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_*/
#define FALSE
Definition: defines.h:16
SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex
void error(char *format,...)
static pid_t pid
Definition: IcmpSquid.cc:35
int size
Definition: ModDevPoll.cc:70
int xopen(const char *filename, int oflag, int pmode=0)
POSIX open(2) equivalent.
Definition: unistd.h:55

 

Introduction

Documentation

Support

Miscellaneous