From 425decdf7e9284d15aa726e3ae96b9942fb0e3ea Mon Sep 17 00:00:00 2001 From: IronClawTrem Date: Sun, 16 Feb 2020 03:40:06 +0000 Subject: create tremded branch --- src/sys/sys_win32.cpp | 842 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 842 insertions(+) create mode 100644 src/sys/sys_win32.cpp (limited to 'src/sys/sys_win32.cpp') diff --git a/src/sys/sys_win32.cpp b/src/sys/sys_win32.cpp new file mode 100644 index 0000000..0ec1f2c --- /dev/null +++ b/src/sys/sys_win32.cpp @@ -0,0 +1,842 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. +Copyright (C) 2000-2013 Darklegion Development +Copyright (C) 2015-2019 GrangerHub + + +This file is part of Tremulous. + +Tremulous is free software; you can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation; either version 3 of the License, +or (at your option) any later version. + +Tremulous is distributed in the hope that it will be +useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Tremulous; if not, see +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "qcommon/q_shared.h" +#include "qcommon/qcommon.h" +#include "dialog.h" +#include "sys_local.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef DEDICATED +static UINT timerResolution = 0; +#endif + +/* +================ +Sys_SetFPUCW +Set FPU control word to default value +================ +*/ + +#ifndef _RC_CHOP +// mingw doesn't seem to have these defined :( + + #define _MCW_EM 0x0008001fU + #define _MCW_RC 0x00000300U + #define _MCW_PC 0x00030000U + #define _RC_NEAR 0x00000000U + #define _PC_53 0x00010000U + + extern "C" unsigned int _controlfp(unsigned int _new, unsigned int mask); +#endif + +#define FPUCWMASK1 (_MCW_RC | _MCW_EM) +#define FPUCW (_RC_NEAR | _MCW_EM | _PC_53) + +#if idx64 +#define FPUCWMASK (FPUCWMASK1) +#else +#define FPUCWMASK (FPUCWMASK1 | _MCW_PC) +#endif + +void Sys_SetFloatEnv(void) +{ + _controlfp(FPUCW, FPUCWMASK); +} + +/* +================ +Sys_Milliseconds +================ +*/ +int sys_timeBase; +int Sys_Milliseconds (void) +{ + int sys_curtime; + static bool initialized = false; + + if (!initialized) { + sys_timeBase = timeGetTime(); + initialized = true; + } + sys_curtime = timeGetTime() - sys_timeBase; + + return sys_curtime; +} + +/* +================ +Sys_RandomBytes +================ +*/ +bool Sys_RandomBytes( byte *string, int len ) +{ + HCRYPTPROV prov; + + if( !CryptAcquireContext( &prov, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) ) { + + return false; + } + + if( !CryptGenRandom( prov, len, (BYTE *)string ) ) { + CryptReleaseContext( prov, 0 ); + return false; + } + CryptReleaseContext( prov, 0 ); + return true; +} + +/* +================ +Sys_GetCurrentUser +================ +*/ +char *Sys_GetCurrentUser( void ) +{ + static char s_userName[1024]; + unsigned long size = sizeof( s_userName ); + + if( !GetUserName( s_userName, &size ) ) + strcpy( s_userName, "player" ); + + if( !s_userName[0] ) + { + strcpy( s_userName, "player" ); + } + + return s_userName; +} + +/* +================== +Sys_CryptoRandomBytes +================== +*/ +void Sys_CryptoRandomBytes( byte *string, int len ) +{ + if ( !Sys_RandomBytes( string, len ) ) + Com_Error( ERR_FATAL, "Sys_CryptoRandomBytes: error generating random data" ); +} + +#define MEM_THRESHOLD 96*1024*1024 + +/* +================== +Sys_LowPhysicalMemory +================== +*/ +bool Sys_LowPhysicalMemory( void ) +{ + MEMORYSTATUS stat; + GlobalMemoryStatus (&stat); + return (stat.dwTotalPhys <= MEM_THRESHOLD) ? true : false; +} + +/* +============== +Sys_Basename +============== +*/ +const char *Sys_Basename( char *path ) +{ + static char base[ MAX_OSPATH ] = { 0 }; + int length; + + length = strlen( path ) - 1; + + // Skip trailing slashes + while( length > 0 && path[ length ] == '\\' ) + length--; + + while( length > 0 && path[ length - 1 ] != '\\' ) + length--; + + Q_strncpyz( base, &path[ length ], sizeof( base ) ); + + length = strlen( base ) - 1; + + // Strip trailing slashes + while( length > 0 && base[ length ] == '\\' ) + base[ length-- ] = '\0'; + + return base; +} + +/* +============== +Sys_Dirname +============== +*/ +const char *Sys_Dirname( char *path ) +{ + static char dir[ MAX_OSPATH ] = { 0 }; + int length; + + Q_strncpyz( dir, path, sizeof( dir ) ); + length = strlen( dir ) - 1; + + while( length > 0 && dir[ length ] != '\\' ) + length--; + + dir[ length ] = '\0'; + + return dir; +} + +/* +============== +Sys_FOpen +============== +*/ +FILE *Sys_FOpen( const char *ospath, const char *mode ) { + return fopen( ospath, mode ); +} + +/* +============== +Sys_Mkdir +============== +*/ +bool Sys_Mkdir( const char *path ) +{ + if( !CreateDirectory( path, NULL ) ) + { + if( GetLastError( ) != ERROR_ALREADY_EXISTS ) + return false; + } + + return true; +} + +/* +================== +Sys_Mkfifo +Noop on windows because named pipes do not function the same way +================== +*/ +FILE *Sys_Mkfifo( const char *ospath ) +{ + return NULL; +} + +/* +============== +Sys_OpenWithDefault + +Opens a path with the default application +============== +*/ +bool Sys_OpenWithDefault( const char *path ) +{ + HINSTANCE hInst; + uint64_t err; + + Com_Printf( S_COLOR_WHITE "Sys_OpenWithDefault: opening %s .....\n", path ); + + hInst = ShellExecute(0, "open", path, 0, 0 , SW_SHOWNORMAL ); + err = (uint64_t)hInst; + + if( err > 32 ) + { + //success + return true; + } + + // failure + switch ( err ) + { + case 0: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The operating system is out of memory or resources.\n", + "warning" ); + break; + + case ERROR_FILE_NOT_FOUND: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The specified file was not found.\n", + "warning" ); + break; + + case ERROR_PATH_NOT_FOUND: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The specified path was not found.\n", + "warning" ); + break; + + case ERROR_BAD_FORMAT: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The .exe file is invalid (non-Win32 .exe or error in .exe image).\n", + "warning" ); + break; + + case SE_ERR_ACCESSDENIED: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The operating system denied access to the specified file.\n", + "warning" ); + break; + + case SE_ERR_ASSOCINCOMPLETE: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The file name association is incomplete or invalid.\n", + "warning" ); + break; + + case SE_ERR_DDEBUSY: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The DDE transaction could not be completed because other DDE transactions were being processed.\n", + "warning" ); + break; + + case SE_ERR_DDEFAIL: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The DDE transaction failed.\n", + "warning" ); + break; + + case SE_ERR_DDETIMEOUT: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The DDE transaction could not be completed because the request timed out.\n", + "warning" ); + break; + + case SE_ERR_DLLNOTFOUND: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: The specified DLL was not found.\n", + "warning" ); + break; + + case SE_ERR_NOASSOC: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable.\n", + "warning" ); + break; + + case SE_ERR_OOM: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: There was not enough memory to complete the operation.\n", + "warning" ); + break; + + case SE_ERR_SHARE: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: A sharing violation occurred.\n", + "warning" ); + break; + + default: + Sys_Dialog( DT_WARNING, + "Sys_OpenWithDefault: Failed to open path.\n", + "warning" ); + break; + } + + return false; +} + +/* +============== +Sys_Cwd +============== +*/ +char *Sys_Cwd( void ) { + static char cwd[MAX_OSPATH]; + + _getcwd( cwd, sizeof( cwd ) - 1 ); + cwd[MAX_OSPATH-1] = 0; + + return cwd; +} + +/* +============================================================== + +DIRECTORY SCANNING + +============================================================== +*/ + +#define MAX_FOUND_FILES 0x1000 + +/* +============== +Sys_ListFilteredFiles +============== +*/ +void Sys_ListFilteredFiles( const char *basedir, const char *subdirs, + const char *filter, char **list, int *numfiles ) +{ + char search[MAX_OSPATH], newsubdirs[MAX_OSPATH]; + char filename[MAX_OSPATH]; + intptr_t findhandle; + struct _finddata_t findinfo; + + if ( *numfiles >= MAX_FOUND_FILES - 1 ) { + return; + } + + if (strlen(subdirs)) { + Com_sprintf( search, sizeof(search), "%s\\%s\\*", basedir, subdirs ); + } + else { + Com_sprintf( search, sizeof(search), "%s\\*", basedir ); + } + + findhandle = _findfirst (search, &findinfo); + if (findhandle == -1) { + return; + } + + do { + if (findinfo.attrib & _A_SUBDIR) { + if (Q_stricmp(findinfo.name, ".") && Q_stricmp(findinfo.name, "..")) { + if (strlen(subdirs)) { + Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s\\%s", subdirs, findinfo.name); + } + else { + Com_sprintf( newsubdirs, sizeof(newsubdirs), "%s", findinfo.name); + } + Sys_ListFilteredFiles( basedir, newsubdirs, filter, list, numfiles ); + } + } + if ( *numfiles >= MAX_FOUND_FILES - 1 ) { + break; + } + Com_sprintf( filename, sizeof(filename), "%s\\%s", subdirs, findinfo.name ); + if (!Com_FilterPath( filter, filename, false )) + continue; + list[ *numfiles ] = CopyString( filename ); + (*numfiles)++; + } while ( _findnext (findhandle, &findinfo) != -1 ); + + _findclose (findhandle); +} + +/* +============== +strgtr +============== +*/ +static bool strgtr(const char *s0, const char *s1) +{ + int l0, l1, i; + + l0 = strlen(s0); + l1 = strlen(s1); + + if (l1 s0[i]) { + return true; + } + if (s1[i] < s0[i]) { + return false; + } + } + return false; +} + +/* +============== +Sys_ListFiles +============== +*/ +char **Sys_ListFiles( const char *directory, const char *extension, + const char *filter, int *numfiles, bool wantsubs ) +{ + char search[MAX_OSPATH]; + int nfiles; + char **listCopy; + char *list[MAX_FOUND_FILES]; + struct _finddata_t findinfo; + intptr_t findhandle; + int flag; + int i; + int extLen; + + if (filter) { + + nfiles = 0; + Sys_ListFilteredFiles( directory, "", filter, list, &nfiles ); + + list[ nfiles ] = 0; + *numfiles = nfiles; + + if (!nfiles) + return NULL; + + listCopy = (char**)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); + for ( i = 0 ; i < nfiles ; i++ ) { + listCopy[i] = list[i]; + } + listCopy[i] = NULL; + + return listCopy; + } + + if ( !extension) { + extension = ""; + } + + // passing a slash as extension will find directories + if ( extension[0] == '/' && extension[1] == 0 ) { + extension = ""; + flag = 0; + } else { + flag = _A_SUBDIR; + } + + extLen = strlen( extension ); + + Com_sprintf( search, sizeof(search), "%s\\*%s", directory, extension ); + + // search + nfiles = 0; + + findhandle = _findfirst (search, &findinfo); + if (findhandle == -1) { + *numfiles = 0; + return NULL; + } + + do { + if ( (!wantsubs && flag ^ ( findinfo.attrib & _A_SUBDIR )) || (wantsubs && findinfo.attrib & _A_SUBDIR) ) { + if (*extension) { + if ( strlen( findinfo.name ) < extLen || + Q_stricmp( + findinfo.name + strlen( findinfo.name ) - extLen, + extension ) ) { + continue; // didn't match + } + } + if ( nfiles == MAX_FOUND_FILES - 1 ) { + break; + } + list[ nfiles ] = CopyString( findinfo.name ); + nfiles++; + } + } while ( _findnext (findhandle, &findinfo) != -1 ); + + list[ nfiles ] = 0; + + _findclose (findhandle); + + // return a copy of the list + *numfiles = nfiles; + + if ( !nfiles ) { + return NULL; + } + + listCopy = (char**)Z_Malloc( ( nfiles + 1 ) * sizeof( *listCopy ) ); + for ( i = 0 ; i < nfiles ; i++ ) { + listCopy[i] = list[i]; + } + listCopy[i] = NULL; + + do { + flag = 0; + for(i=1; i 0 ) + { + memcpy( p, buffer, size ); + p += size; + } + + *p = '\0'; + + if( OpenClipboard( NULL ) && EmptyClipboard( ) ) + SetClipboardData( CF_TEXT, memoryHandle ); + + GlobalUnlock( clipMemory ); + CloseClipboard( ); + } + } +} + +/* +============== +Sys_Dialog + +Display a win32 dialog box +============== +*/ +dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *title ) +{ + UINT uType; + + switch( type ) + { + default: + case DT_INFO: uType = MB_ICONINFORMATION|MB_OK; break; + case DT_WARNING: uType = MB_ICONWARNING|MB_OK; break; + case DT_ERROR: uType = MB_ICONERROR|MB_OK; break; + case DT_YES_NO: uType = MB_ICONQUESTION|MB_YESNO; break; + case DT_OK_CANCEL: uType = MB_ICONWARNING|MB_OKCANCEL; break; + } + + switch( MessageBox( NULL, message, title, uType ) ) + { + default: + case IDOK: return DR_OK; + case IDCANCEL: return DR_CANCEL; + case IDYES: return DR_YES; + case IDNO: return DR_NO; + } +} + +/* +============== +Sys_GLimpSafeInit + +Windows specific "safe" GL implementation initialisation +============== +*/ +void Sys_GLimpSafeInit( void ) +{ +} + +/* +============== +Sys_GLimpInit + +Windows specific GL implementation initialisation +============== +*/ +void Sys_GLimpInit( void ) +{ +} + +/* +============== +Sys_PlatformInit + +Windows specific initialisation +============== +*/ +void Sys_PlatformInit( void ) +{ +#ifndef DEDICATED + TIMECAPS ptc; +#endif + + Sys_SetFloatEnv(); + +#ifndef DEDICATED + if(timeGetDevCaps(&ptc, sizeof(ptc)) == MMSYSERR_NOERROR) + { + timerResolution = ptc.wPeriodMin; + + if(timerResolution > 1) + { + Com_Printf("Warning: Minimum supported timer resolution is %ums " + "on this system, recommended resolution 1ms\n", timerResolution); + } + + timeBeginPeriod(timerResolution); + } + else + timerResolution = 0; +#endif +} + +/* +============== +Sys_PlatformExit + +Windows specific initialisation +============== +*/ +void Sys_PlatformExit( void ) +{ +#ifndef DEDICATED + if(timerResolution) + timeEndPeriod(timerResolution); +#endif +} + +/* +============== +Sys_SetEnv + +set/unset environment variables (empty value removes it) +============== +*/ +void Sys_SetEnv(const char *name, const char *value) +{ + if(value) + _putenv(va("%s=%s", name, value)); + else + _putenv(va("%s=", name)); +} + +/* +============== +Sys_PID +============== +*/ +int Sys_PID( void ) +{ + return GetCurrentProcessId( ); +} + +/* +============== +Sys_PIDIsRunning +============== +*/ +bool Sys_PIDIsRunning( int pid ) +{ + DWORD processes[ 1024 ]; + DWORD numBytes, numProcesses; + int i; + + if( !EnumProcesses( processes, sizeof( processes ), &numBytes ) ) + return false; // Assume it's not running + + numProcesses = numBytes / sizeof( DWORD ); + + // Search for the pid + for( i = 0; i < numProcesses; i++ ) + { + if( processes[ i ] == pid ) + return true; + } + + return false; +} + +/* +================= +Sys_DllExtension + +Check if filename should be allowed to be loaded as a DLL. +================= +*/ +bool Sys_DllExtension( const char *name ) +{ + return COM_CompareExtension( name, DLL_EXT ); +} -- cgit