UFO: Alien Invasion
Doxygen documentation generating
win_shared.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 1997-2001 Id Software, Inc.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "../../common/common.h"
27 #include "win_local.h"
28 #include <fcntl.h>
29 #include <direct.h>
30 #include <io.h>
31 #include <conio.h>
32 #include <mmsystem.h>
33 #include <shellapi.h>
34 
35 #if defined(_MSC_VER)
36 #include <intrin.h>
37 #endif
38 
39 HINSTANCE global_hInstance;
40 
41 static void Sys_Utf8ToUtf16 (const char* source, LPWSTR dest, size_t destlen)
42 {
43  const int len = MultiByteToWideChar(CP_UTF8, 0, source, -1, dest, destlen - 1);
44  dest[len] = 0;
45 }
46 
47 static void Sys_Utf16ToUtf8 (const LPWSTR source, char* dest, size_t destsize)
48 {
49  const int len = WideCharToMultiByte(CP_UTF8, 0, source, -1, dest, destsize - 1, nullptr, nullptr);
50  dest[len] = '\0';
51 }
52 
53 int Sys_Milliseconds (void)
54 {
55  static int base = 0;
56 
57  /* let base retain 16 bits of effectively random data */
58  if (!base)
59  base = timeGetTime() & 0xffff0000;
60 
61  return timeGetTime() - base;
62 }
63 
64 void Sys_Mkdir (const char* path)
65 {
66  WCHAR wpath[MAX_OSPATH];
67  Sys_Utf8ToUtf16(path, wpath, lengthof(wpath));
68  _wmkdir(wpath);
69 }
70 
71 void Sys_Breakpoint (void)
72 {
73 #if defined(_MSC_VER)
74  __debugbreak();
75 #elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
76  __asm__ __volatile__ ( "int $3\n\t" );
77 #endif
78 }
79 
80 #ifdef COMPILE_UFO
81 
86 {
87  SYSTEM_INFO sysInfo;
88  /* 1 - use core #0
89  * 2 - use core #1
90  * 3 - use cores #0 and #1 */
91  HANDLE proc = GetCurrentProcess();
92 
93  if (sys_priority->modified) {
94  if (sys_priority->integer < 0)
95  Cvar_SetValue("sys_priority", 0);
96  else if (sys_priority->integer > 2)
97  Cvar_SetValue("sys_priority", 2);
98 
99  sys_priority->modified = false;
100 
101  switch (sys_priority->integer) {
102  case 0:
103  SetPriorityClass(proc, NORMAL_PRIORITY_CLASS);
104  Com_Printf("Priority changed to NORMAL\n");
105  break;
106  case 1:
107  SetPriorityClass(proc, HIGH_PRIORITY_CLASS);
108  Com_Printf("Priority changed to HIGH\n");
109  break;
110  default:
111  SetPriorityClass(proc, REALTIME_PRIORITY_CLASS);
112  Com_Printf("Priority changed to REALTIME\n");
113  break;
114  }
115  }
116 
117  if (sys_affinity->modified) {
118  DWORD_PTR procAffinity = 0;
119  GetSystemInfo(&sysInfo);
120  Com_Printf("Found %i processors\n", (int)sysInfo.dwNumberOfProcessors);
121  sys_affinity->modified = false;
122  if (sysInfo.dwNumberOfProcessors >= 2) {
123  switch (sys_affinity->integer) {
124  case 0:
125  Com_Printf("Use all cores\n");
126  procAffinity = (1 << sysInfo.dwNumberOfProcessors) - 1;
127  break;
128  case 1:
129  Com_Printf("Use two cores\n");
130  procAffinity = 3;
131  break;
132  case 2:
133  Com_Printf("Only use one core\n");
134  procAffinity = 1;
135  break;
136  }
137  } else {
138  Com_Printf("...only found one processor\n");
139  }
140  SetProcessAffinityMask(proc, procAffinity);
141  }
142 
143  CloseHandle(proc);
144 }
145 #endif
146 
147 const char* Sys_SetLocale (const char* localeID)
148 {
149  Sys_Setenv("LANG", localeID);
150  Sys_Setenv("LANGUAGE", localeID);
151  Sys_Setenv("LC_NUMERIC", "C");
152 
153  return localeID;
154 }
155 
156 const char* Sys_GetLocale (void)
157 {
158  if (getenv("LANGUAGE"))
159  return getenv("LANGUAGE");
160  else
161  /* Setting to en will always work in every windows. */
162  return "en";
163 }
164 
165 static char findbase[MAX_OSPATH];
166 static char findpath[MAX_OSPATH];
167 static char findname[MAX_OSPATH];
168 static WCHAR wfindpath[MAX_OSPATH];
169 static intptr_t findhandle;
170 
171 static bool CompareAttributes (unsigned found, unsigned musthave, unsigned canthave)
172 {
173  if ((found & _A_RDONLY) && (canthave & SFF_RDONLY))
174  return false;
175  if ((found & _A_HIDDEN) && (canthave & SFF_HIDDEN))
176  return false;
177  if ((found & _A_SYSTEM) && (canthave & SFF_SYSTEM))
178  return false;
179  if ((found & _A_SUBDIR) && (canthave & SFF_SUBDIR))
180  return false;
181  if ((found & _A_ARCH) && (canthave & SFF_ARCH))
182  return false;
183 
184  if ((musthave & SFF_RDONLY) && !(found & _A_RDONLY))
185  return false;
186  if ((musthave & SFF_HIDDEN) && !(found & _A_HIDDEN))
187  return false;
188  if ((musthave & SFF_SYSTEM) && !(found & _A_SYSTEM))
189  return false;
190  if ((musthave & SFF_SUBDIR) && !(found & _A_SUBDIR))
191  return false;
192  if ((musthave & SFF_ARCH) && !(found & _A_ARCH))
193  return false;
194 
195  return true;
196 }
197 
202 char* Sys_FindFirst (const char* path, unsigned musthave, unsigned canthave)
203 {
204  struct _wfinddata_t findinfo;
205 
206  if (findhandle)
207  Sys_Error("Sys_BeginFind without close");
208  findhandle = 0;
209 
210  Com_FilePath(path, findbase, sizeof(findbase));
212  findhandle = _wfindfirst(wfindpath, &findinfo);
213  while (findhandle != -1) {
214  /* found one that matched */
215  if (!Q_streq(findname, ".") && !Q_streq(findname, "..") &&
216  CompareAttributes(findinfo.attrib, musthave, canthave)) {
217  Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
218  Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findname);
219  return findpath;
220  /* doesn't match - try the next one */
221  } else if (_wfindnext(findhandle, &findinfo) == -1) {
222  /* ok, no further entries here - leave the while loop */
223  _findclose(findhandle);
224  findhandle = -1;
225  }
226  }
227 
228  /* none found */
229  return nullptr;
230 }
231 
236 char* Sys_FindNext (unsigned musthave, unsigned canthave)
237 {
238  struct _wfinddata_t findinfo;
239 
240  if (findhandle == -1)
241  return nullptr;
242 
243  /* until we found the next entry */
244  while (_wfindnext(findhandle, &findinfo) != -1) {
245  if (!Q_streq(findname, ".") && !Q_streq(findname, "..") &&
246  CompareAttributes(findinfo.attrib, musthave, canthave)) {
247  Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
248  Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, findname);
249  return findpath;
250  }
251  }
252 
253  /* none found */
254  return nullptr;
255 }
256 
263 void Sys_FindClose (void)
264 {
265  if (findhandle != -1)
266  _findclose(findhandle);
267  findhandle = 0;
268 }
269 
270 #define MAX_FOUND_FILES 0x1000
271 
272 void Sys_ListFilteredFiles (const char* basedir, const char* subdirs, const char* filter, linkedList_t** list)
273 {
274  char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
275  char filename[MAX_OSPATH];
276  struct _wfinddata_t findinfo;
277 
278  if (subdirs[0] != '\0') {
279  Com_sprintf(search, sizeof(search), "%s\\%s\\*", basedir, subdirs);
280  } else {
281  Com_sprintf(search, sizeof(search), "%s\\*", basedir);
282  }
283 
285  const int findhandle = _wfindfirst(wfindpath, &findinfo);
286  if (findhandle == -1)
287  return;
288 
289  do {
290  if (findinfo.attrib & _A_SUBDIR) {
291  if (Q_strcasecmp(findname, ".") && Q_strcasecmp(findname, "..")) {
292  Sys_Utf16ToUtf8(findinfo.name, findname, sizeof(findname));
293  if (subdirs[0] != '\0') {
294  Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findname);
295  } else {
296  Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", findname);
297  }
298  Sys_ListFilteredFiles(basedir, newsubdirs, filter, list);
299  }
300  }
301  Com_sprintf(filename, sizeof(filename), "%s\\%s", subdirs, findname);
302  if (!Com_Filter(filter, filename))
303  continue;
304  LIST_AddString(list, filename);
305  } while (_wfindnext(findhandle, &findinfo) != -1);
306 
307  _findclose(findhandle);
308 }
309 
310 void Sys_Quit (void)
311 {
312  timeEndPeriod(1);
313 
314 #ifdef COMPILE_UFO
315  CL_Shutdown();
317 #elif COMPILE_MAP
318  Mem_Shutdown();
319 #endif
320 
321  /* exit(0) */
322  ExitProcess(0);
323 }
324 
325 #ifdef COMPILE_MAP
326 
332 static void Sys_ColoredOutput (const char* text, unsigned int fgColor, bool toStdOut)
333 {
334  /* paint this colors (gray on black). */
335  unsigned int cliPaintColor = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
336  /* store default current colors. */
337  unsigned int cliCurColor = cliPaintColor;
338  CONSOLE_SCREEN_BUFFER_INFO cliInfo;
339  const DWORD handle = toStdOut ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE;
340  const HANDLE console = GetStdHandle(handle);
341 
342  if (GetConsoleScreenBufferInfo(console, &cliInfo)) {
343  /* store current colors. */
344  cliCurColor = cliInfo.wAttributes;
345  /* is BACKGROUND == FOREGROUND */
346  if (cliCurColor == (fgColor << 4)) {
347  /* your fgColor on black background. */
348  cliPaintColor = fgColor;
349  } else {
350  /* remove foreground color. */
351  cliPaintColor = cliCurColor >> 4;
352  cliPaintColor <<= 4;
353  /* set foreground color. */
354  cliPaintColor |= fgColor;
355  }
356  }
357 
358  SetConsoleTextAttribute(console, cliPaintColor);
359  if (toStdOut)
360  fprintf(stdout, "%s\n", text);
361  else
362  fprintf(stderr, "Error: %s\n", text);
363  SetConsoleTextAttribute(console, cliCurColor);
364 
365  CloseHandle(console);
366 }
367 
368 void Sys_Error (const char* error, ...)
369 {
370  va_list argptr;
371  char text[1024];
372 
373  va_start(argptr, error);
374  Q_vsnprintf(text, sizeof(text), error, argptr);
375  va_end(argptr);
376 
377  /* red text to stderr. */
378  Sys_ColoredOutput(text, FOREGROUND_RED | FOREGROUND_INTENSITY, false);
379 
380  ExitProcess(1);
381 }
382 #endif
383 
387 const char* Sys_GetCurrentUser (void)
388 {
389  static char s_userName[1024];
390  WCHAR w_userName[1024];
391  unsigned long size = lengthof(w_userName);
392 
393  if (!GetUserNameW(w_userName, &size))
394  Q_strncpyz(s_userName, "", sizeof(s_userName));
395  else
396  Sys_Utf16ToUtf8(w_userName, s_userName, sizeof(s_userName));
397 
398  return s_userName;
399 }
400 
404 char* Sys_Cwd (void)
405 {
406  static char cwd[MAX_OSPATH];
407  WCHAR wcwd[MAX_OSPATH];
408 
409  if (_wgetcwd(wcwd, lengthof(wcwd)) == nullptr)
410  return nullptr;
411  else
412  Sys_Utf16ToUtf8(wcwd, cwd, sizeof(cwd));
413 
414  return cwd;
415 }
416 
420 void Sys_NormPath (char* path)
421 {
422  char* tmp = path;
423 
424  while (*tmp) {
425  if (*tmp == '\\')
426  *tmp = '/';
427  else
428  *tmp = tolower(*tmp);
429  tmp++;
430  }
431 }
432 
440 {
441  static char path[MAX_PATH];
442 
443  const HMODULE shfolder = LoadLibrary("shfolder.dll");
444 
445  if (shfolder == nullptr) {
446  Com_Printf("Unable to load SHFolder.dll\n");
447  return nullptr;
448  }
449 
450  typedef HRESULT WINAPI SHGetFolderPath_t(HWND, int, HANDLE, DWORD, LPWSTR);
451  SHGetFolderPath_t* const qSHGetFolderPath = (SHGetFolderPath_t*)GetProcAddress(shfolder, "SHGetFolderPathW");
452  if (qSHGetFolderPath == nullptr) {
453  Com_Printf("Unable to find SHGetFolderPath in SHFolder.dll\n");
454  FreeLibrary(shfolder);
455  return nullptr;
456  }
457 
458  WCHAR wpath[MAX_PATH];
459  if (!SUCCEEDED(qSHGetFolderPath(nullptr, CSIDL_APPDATA, nullptr, 0, wpath))) {
460  Com_Printf("Unable to detect CSIDL_APPDATA\n");
461  FreeLibrary(shfolder);
462  return nullptr;
463  }
464 
465  Sys_Utf16ToUtf8(wpath, path, sizeof(path));
466  Q_strcat(path, sizeof(path), "\\UFOAI");
467  FreeLibrary(shfolder);
468 
469  Sys_Utf8ToUtf16(path, wpath, MAX_PATH);
470  if (!CreateDirectoryW(wpath, nullptr)) {
471  if (GetLastError() != ERROR_ALREADY_EXISTS) {
472  Com_Printf("Unable to create directory \"%s\"\n", path);
473  return nullptr;
474  }
475  }
476 
477  Sys_Utf16ToUtf8(wpath, path, sizeof(path));
478  return path;
479 }
480 
484 void Sys_Sleep (int milliseconds)
485 {
486  if (milliseconds < 1)
487  milliseconds = 1;
488  Sleep(milliseconds);
489 }
490 
496 int Sys_Setenv (const char* name, const char* value)
497 {
498  const size_t n = strlen(name) + strlen(value) + 2;
499  char* str = (char*)malloc(n); /* do not convert this to allocation from managed pool, using malloc is intentional */
500 
501  strcat(strcat(strcpy(str, name), "="), value);
502  if (putenv(str))
503  return 0; /* putenv returns nonzero if fails */
504 
505  return SetEnvironmentVariable(name, value);
506 }
507 
508 void Sys_InitSignals (void)
509 {
510 }
511 
512 void Sys_Mkfifo (const char* ospath, qFILE* f)
513 {
514 }
515 
516 void Sys_OpenURL (const char* url)
517 {
518  ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
519 }
520 
521 FILE* Sys_Fopen (const char* filename, const char* mode)
522 {
523  WCHAR wname[MAX_OSPATH];
524  WCHAR wmode[MAX_VAR];
525  Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
526  Sys_Utf8ToUtf16(mode, wmode, lengthof(wmode));
527  return _wfopen(wname, wmode);
528 }
529 
530 int Sys_Remove (const char* filename)
531 {
532  WCHAR wname[MAX_OSPATH];
533  Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
534  return _wremove(wname);
535 }
536 
537 int Sys_Rename (const char* oldname, const char* newname)
538 {
539  WCHAR woldname[MAX_OSPATH];
540  WCHAR wnewname[MAX_OSPATH];
541  Sys_Utf8ToUtf16(oldname, woldname, lengthof(woldname));
542  Sys_Utf8ToUtf16(newname, wnewname, lengthof(wnewname));
543  return _wrename(woldname, wnewname);
544 }
545 
546 int Sys_Access (const char* filename, int mode)
547 {
548  WCHAR wname[MAX_OSPATH];
549  Sys_Utf8ToUtf16(filename, wname, lengthof(wname));
550  return _waccess(wname, mode);
551 }
#define SFF_ARCH
Definition: filesys.h:123
void Sys_Mkdir(const char *path)
Definition: win_shared.cpp:64
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition: shared.cpp:535
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
void Sys_Sleep(int milliseconds)
Calls the win32 sleep function.
Definition: win_shared.cpp:484
Definition: filesys.h:54
char * Sys_FindNext(unsigned musthave, unsigned canthave)
Returns the next file of the already opened directory (Sys_FindFirst) that matches our search mask...
Definition: win_shared.cpp:236
void Sys_SetAffinityAndPriority(void)
void Mem_Shutdown(void)
Definition: mem.cpp:518
cvar_t * sys_affinity
Definition: common.cpp:60
void Sys_Breakpoint(void)
Definition: win_shared.cpp:71
const char * Sys_GetCurrentUser(void)
Get current user.
Definition: win_shared.cpp:387
static void Sys_Utf16ToUtf8(const LPWSTR source, char *dest, size_t destsize)
Definition: win_shared.cpp:47
int Sys_Setenv(const char *name, const char *value)
set/unset environment variables (empty value removes it)
Definition: win_shared.cpp:496
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
const char * filename
Definition: ioapi.h:41
#define FILE
Definition: test_webapi.cpp:30
void Com_FilePath(const char *in, char *out, size_t size)
Returns the path up to, but not including the last /.
Definition: shared.cpp:319
int integer
Definition: cvar.h:81
voidpf void uLong size
Definition: ioapi.h:42
void Sys_FindClose(void)
Closes the find handle.
Definition: win_shared.cpp:263
#define SFF_SYSTEM
Definition: filesys.h:127
#define MAX_OSPATH
Definition: filesys.h:44
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
#define SFF_SUBDIR
Definition: filesys.h:126
const char * Sys_SetLocale(const char *localeID)
Definition: win_shared.cpp:147
static char findbase[MAX_OSPATH]
Definition: win_shared.cpp:165
static char findname[MAX_OSPATH]
Definition: win_shared.cpp:167
#define SFF_HIDDEN
Definition: filesys.h:124
FILE * Sys_Fopen(const char *filename, const char *mode)
Definition: win_shared.cpp:521
void Sys_OpenURL(const char *url)
Definition: win_shared.cpp:516
Win32-specific UFO header file.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
void Sys_ListFilteredFiles(const char *basedir, const char *subdirs, const char *filter, linkedList_t **list)
Definition: win_shared.cpp:272
void LIST_AddString(linkedList_t **listDest, const char *data)
Adds an string to a new or to an already existing linked list. The string is copied here...
Definition: list.cpp:139
#define MAX_VAR
Definition: shared.h:36
int Sys_Remove(const char *filename)
Definition: win_shared.cpp:530
int Com_Filter(const char *pattern, const char *text)
Match the pattern PATTERN against the string TEXT;.
Definition: shared.cpp:145
char * Sys_GetHomeDirectory(void)
Get the home directory in Application Data.
Definition: win_shared.cpp:439
const char * Sys_GetLocale(void)
Definition: win_shared.cpp:156
void Sys_InitSignals(void)
Definition: win_shared.cpp:508
#define SFF_RDONLY
Definition: filesys.h:125
void Sys_Mkfifo(const char *ospath, qFILE *f)
Definition: win_shared.cpp:512
char * Sys_FindFirst(const char *path, unsigned musthave, unsigned canthave)
Opens the directory and returns the first file that matches our searchrules.
Definition: win_shared.cpp:202
#define Q_strcasecmp(a, b)
Definition: shared.h:131
char * Sys_Cwd(void)
Get current working dir.
Definition: win_shared.cpp:404
QGL_EXTERN GLenum GLuint * dest
Definition: r_gl.h:101
int Sys_Milliseconds(void)
Definition: win_shared.cpp:53
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
static char findpath[MAX_OSPATH]
Definition: win_shared.cpp:166
static WCHAR wfindpath[MAX_OSPATH]
Definition: win_shared.cpp:168
int Sys_Access(const char *filename, int mode)
Definition: win_shared.cpp:546
static void Sys_Utf8ToUtf16(const char *source, LPWSTR dest, size_t destlen)
Definition: win_shared.cpp:41
static intptr_t findhandle
Definition: win_shared.cpp:169
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
#define DWORD_PTR
Definition: win_local.h:34
static bool CompareAttributes(unsigned found, unsigned musthave, unsigned canthave)
Definition: win_shared.cpp:171
int Sys_Rename(const char *oldname, const char *newname)
Definition: win_shared.cpp:537
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
void CL_Shutdown(void)
Saves configuration file and shuts the client systems down.
Definition: cl_main.cpp:1219
void Qcommon_Shutdown(void)
Definition: common.cpp:1540
void Sys_Quit(void)
Definition: win_shared.cpp:310
const char int mode
Definition: ioapi.h:41
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition: shared.cpp:475
HINSTANCE global_hInstance
Definition: win_shared.cpp:39
#define lengthof(x)
Definition: shared.h:105
#define Q_streq(a, b)
Definition: shared.h:136
void Sys_NormPath(char *path)
Normalize path (remove all \ )
Definition: win_shared.cpp:420
bool modified
Definition: cvar.h:79
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition: cvar.cpp:671
cvar_t * sys_priority
Definition: common.cpp:59