possibly controversial commit: remove all windows sources, keeping only the windows cmake so that we can generate an sln to edit the code

This commit is contained in:
DarthArgus
2016-01-27 15:22:22 -06:00
parent 3dccead5d5
commit 48ba7961eb
201 changed files with 0 additions and 21403 deletions
@@ -1,58 +0,0 @@
// ======================================================================
//
// ByteOrder.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/ByteOrder.h"
// ======================================================================
// I'm using the arguments, but the compiler can't tell that
#pragma warning(disable: 4100)
__declspec(naked) ulong ntohl(ulong netLong)
{
_asm
{
mov eax, [esp+4]
bswap eax
ret
}
} //lint !e533 !e715 // function should return a value, argument not referenced
__declspec(naked) ulong htonl(ulong hostLong)
{
_asm
{
mov eax, [esp+4]
bswap eax
ret
}
} //lint !e533 !e715 // function should return a value, argument not referenced
__declspec(naked) ushort ntohs(ushort netShort)
{
_asm
{
mov eax, [esp+4]
bswap eax
shr eax, 16
ret
}
} //lint !e533 !e715 // function should return a value, argument not referenced
__declspec(naked) ushort htons(ushort hostShort)
{
_asm
{
mov eax, [esp+4]
bswap eax
shr eax, 16
ret
}
} //lint !e533 !e715 // function should return a value, argument not referenced
// ======================================================================
@@ -1,22 +0,0 @@
// ======================================================================
//
// ByteOrder.h
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef BYTE_ORDER_H
#define BYTE_ORDER_H
// ======================================================================
ulong __cdecl ntohl(ulong netLong);
ushort __cdecl ntohs(ushort netShort);
ulong __cdecl htonl(ulong hostLong);
ushort __cdecl htons(ushort hostShort);
// ======================================================================
#endif
@@ -1,324 +0,0 @@
// ======================================================================
//
// ConfigSharedFoundation.cpp
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/ConfigSharedFoundation.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedFoundation/Production.h"
// ======================================================================
#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt("SharedFoundation", #a, b))
#define KEY_BOOL(a,b) (ms_ ## a = ConfigFile::getKeyBool("SharedFoundation", #a, b))
#define KEY_FLOAT(a,b) (ms_ ## a = ConfigFile::getKeyFloat("SharedFoundation", #a, b))
#define KEY_STRING(a,b) (ms_ ## a = ConfigFile::getKeyString("SharedFoundation", #a, b))
// ======================================================================
const int c_defaultFatalCallStackDepth = 32;
const int c_defaultWarningCallStackDepth = PRODUCTION ? -1 : 8;
// ======================================================================
namespace ConfigSharedFoundationNamespace
{
bool ms_noExceptionHandling;
bool ms_fpuExceptionPrecision;
bool ms_fpuExceptionUnderflow;
bool ms_fpuExceptionOverflow;
bool ms_fpuExceptionZeroDivide;
bool ms_fpuExceptionDenormal;
bool ms_fpuExceptionInvalid;
bool ms_demoMode;
real ms_frameRateLimit;
real ms_minFrameRate;
bool ms_useRemoteDebug;
int ms_defaultRemoteDebugPort;
bool ms_profilerExpandAllBranches;
bool ms_memoryManagerReportAllocations;
bool ms_memoryManagerReportOnOutOfMemory;
bool ms_useMemoryBlockManager;
bool ms_memoryBlockManagerDebugDumpOnRemove;
int ms_fatalCallStackDepth;
int ms_warningCallStackDepth;
bool ms_lookUpCallStackNames;
int ms_processPriority;
bool ms_verboseHardwareLogging;
bool ms_verboseWarnings;
bool ms_causeAccessViolation;
float ms_debugReportLongFrameTime;
}
using namespace ConfigSharedFoundationNamespace;
// ======================================================================
// Determine the Platform-specific configuration information
//
// Remarks:
//
// This routine inspects the ConfigFile class to set some variables for rapid access
// by the rest of the engine.
void ConfigSharedFoundation::install (const Defaults &defaults)
{
KEY_BOOL(noExceptionHandling, false);
KEY_BOOL(fpuExceptionPrecision, false);
KEY_BOOL(fpuExceptionUnderflow, false);
KEY_BOOL(fpuExceptionOverflow, false);
KEY_BOOL(fpuExceptionZeroDivide, false);
KEY_BOOL(fpuExceptionDenormal, false);
KEY_BOOL(fpuExceptionInvalid, false);
KEY_BOOL(demoMode, defaults.demoMode);
#if defined (WIN32) && PRODUCTION == 1
// In production builds, force our frame rate limit to be the application defined limit
ms_frameRateLimit = defaults.frameRateLimit;
#else
KEY_FLOAT(frameRateLimit, defaults.frameRateLimit);
#endif
KEY_FLOAT(minFrameRate, 1.0f);
KEY_BOOL(useRemoteDebug, false);
KEY_INT(defaultRemoteDebugPort, 4445);
KEY_BOOL(profilerExpandAllBranches, false);
KEY_BOOL(memoryManagerReportAllocations, true);
KEY_BOOL(memoryManagerReportOnOutOfMemory, true);
KEY_BOOL(useMemoryBlockManager, true);
KEY_BOOL(memoryBlockManagerDebugDumpOnRemove, false);
KEY_INT(fatalCallStackDepth, c_defaultFatalCallStackDepth);
KEY_INT(warningCallStackDepth, PRODUCTION ? -1 : c_defaultWarningCallStackDepth);
KEY_BOOL(lookUpCallStackNames, true);
KEY_INT(processPriority, 0);
KEY_BOOL(verboseHardwareLogging, false);
KEY_BOOL(verboseWarnings, defaults.verboseWarnings);
KEY_BOOL(causeAccessViolation, false);
KEY_FLOAT(debugReportLongFrameTime, 0.25f);
}
// ----------------------------------------------------------------------
/**
* Return whether to run with exception handling enabled.
*
* @return True to run without exception handling
*/
bool ConfigSharedFoundation::getNoExceptionHandling()
{
return ms_noExceptionHandling;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionPrecision()
{
return ms_fpuExceptionPrecision;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionUnderflow()
{
return ms_fpuExceptionUnderflow;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionOverflow()
{
return ms_fpuExceptionOverflow;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionZeroDivide()
{
return ms_fpuExceptionZeroDivide;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionDenormal()
{
return ms_fpuExceptionDenormal;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getFpuExceptionInvalid()
{
return ms_fpuExceptionInvalid;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getDemoMode()
{
return ms_demoMode;
}
// ----------------------------------------------------------------------
/**
* Return the frame rate limit value for the game.
*
* @return The initial frame rate limiter value
*/
real ConfigSharedFoundation::getFrameRateLimit()
{
return ms_frameRateLimit;
}
// ----------------------------------------------------------------------
/**
* Return the minimum frame rate value for the game. Frames that take longer
* will log a warning and be hard set to the given value.
*
* @return The initial min frame rate value
*/
real ConfigSharedFoundation::getMinFrameRate()
{
return ms_minFrameRate;
}
// ----------------------------------------------------------------------
int ConfigSharedFoundation::getDefaultRemoteDebugPort()
{
return ms_defaultRemoteDebugPort;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getUseRemoteDebug()
{
return ms_useRemoteDebug;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getProfilerExpandAllBranches()
{
return ms_profilerExpandAllBranches;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getMemoryManagerReportAllocations()
{
return ms_memoryManagerReportAllocations;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getMemoryManagerReportOnOutOfMemory()
{
return ms_memoryManagerReportOnOutOfMemory;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getUseMemoryBlockManager()
{
return ms_useMemoryBlockManager;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getMemoryBlockManagerDebugDumpOnRemove ()
{
return ms_memoryBlockManagerDebugDumpOnRemove;
}
// ----------------------------------------------------------------------
int ConfigSharedFoundation::getFatalCallStackDepth()
{
return ms_fatalCallStackDepth;
}
// ----------------------------------------------------------------------
int ConfigSharedFoundation::getWarningCallStackDepth()
{
return ms_warningCallStackDepth;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getLookUpCallStackNames()
{
return ms_lookUpCallStackNames;
}
// ----------------------------------------------------------------------
int ConfigSharedFoundation::getProcessPriority()
{
return ms_processPriority;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getVerboseHardwareLogging()
{
return ms_verboseHardwareLogging;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getVerboseWarnings()
{
return ms_verboseWarnings;
}
// ----------------------------------------------------------------------
void ConfigSharedFoundation::setVerboseWarnings(bool const verboseWarnings)
{
ms_verboseWarnings = verboseWarnings;
}
// ----------------------------------------------------------------------
bool ConfigSharedFoundation::getCauseAccessViolation()
{
return ms_causeAccessViolation;
}
// ----------------------------------------------------------------------
float ConfigSharedFoundation::getDebugReportLongFrameTime()
{
return ms_debugReportLongFrameTime;
}
// ======================================================================
@@ -1,74 +0,0 @@
// ======================================================================
//
// ConfigSharedFoundation.h
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ConfigSharedFoundation_H
#define INCLUDED_ConfigSharedFoundation_H
// ======================================================================
class ConfigSharedFoundation
{
public:
struct Defaults
{
int screenHeight;
int screenWidth;
bool windowed;
real frameRateLimit;
bool demoMode;
bool verboseWarnings;
};
public:
static void install(const Defaults &defaults);
static bool getNoExceptionHandling();
static bool getFpuExceptionPrecision();
static bool getFpuExceptionUnderflow();
static bool getFpuExceptionOverflow();
static bool getFpuExceptionZeroDivide();
static bool getFpuExceptionDenormal();
static bool getFpuExceptionInvalid();
static bool getDemoMode();
static real getFrameRateLimit();
static real getMinFrameRate();
static bool getUseRemoteDebug();
static int getDefaultRemoteDebugPort();
static bool getProfilerExpandAllBranches();
static bool getMemoryManagerReportAllocations();
static bool getMemoryManagerReportOnOutOfMemory();
static bool getUseMemoryBlockManager();
static bool getMemoryBlockManagerDebugDumpOnRemove();
static int getFatalCallStackDepth();
static int getWarningCallStackDepth();
static bool getLookUpCallStackNames();
static int getProcessPriority();
static DLLEXPORT bool getVerboseHardwareLogging();
static bool getVerboseWarnings();
static void setVerboseWarnings(bool verboseWarnings);
static bool getCauseAccessViolation();
static float getDebugReportLongFrameTime();
};
// ======================================================================
#endif
@@ -1,82 +0,0 @@
// ======================================================================
//
// FirstPlatform.h
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_FirstPlatform_H
#define INCLUDED_FirstPlatform_H
#ifdef WIN32
#include <WinNT.h>
#include <WinDef.h>
#endif
// ======================================================================
// C4127 conditional expression is constant
// C4291 no matching operator delete found; memory will not be freed if initialization throws an exception
// C4503 decorated name length exceeded, name was truncated
// C4514 unreferenced inline function has been removed
// C4702 unreachable code
// C4710 inline function not expanded
// C4786 identifier was truncated to 'number' characters in the debug
#pragma warning(disable: 4127 4291 4503 4514 4702 4710 4786)
// ======================================================================
// If we haven't defined this yet, then we're not compiling a DLL
#ifndef COMPILE_DLL
#define COMPILE_DLL 0
#endif
#if COMPILE_DLL
#define DLLEXPORT __declspec(dllimport)
#else
#define DLLEXPORT __declspec(dllexport)
#endif
// ======================================================================
template <class T>
inline int ComGetReferenceCount(T *t)
{
t->AddRef();
return t->Release();
}
// ======================================================================
// forward declare some windows stuff to avoid having to include <windows.h> here
struct HCURSOR__;
struct HICON__;
struct HINSTANCE__;
struct HWND__;
typedef void *HANDLE;
typedef HICON__ *HCURSOR;
typedef HICON__ *HICON;
typedef HINSTANCE__ *HINSTANCE;
typedef HWND__ *HWND;
// @todo codereorg still working on this
#include "sharedFoundation/WindowsWrapper.h"
// ======================================================================
// convienent fatal macros that check windows HRESULT codes
#define FATAL_HR(a,b) FATAL(FAILED(b), (a, HRESULT_CODE(b)))
#define DEBUG_FATAL_HR(a,b) DEBUG_FATAL(FAILED(b), (a, HRESULT_CODE(b)))
// ======================================================================
// include anything we need to replace missing functionality that other platforms provide
#include "sharedFoundation/PlatformGlue.h"
// ======================================================================
#endif
@@ -1,8 +0,0 @@
// ======================================================================
//
// FirstFoundation.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
@@ -1,257 +0,0 @@
// ======================================================================
//
// FloatingPointUnit.cpp
// copyright 1999 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/FloatingPointUnit.h"
#include "sharedFoundation/ConfigSharedFoundation.h"
// ======================================================================
int FloatingPointUnit::updateNumber;
ushort FloatingPointUnit::status;
FloatingPointUnit::Precision FloatingPointUnit::precision;
FloatingPointUnit::Rounding FloatingPointUnit::rounding;
bool FloatingPointUnit::exceptionEnabled[E_max];
// ======================================================================
const WORD PRECISION_MASK = BINARY4(0000,0011,0000,0000);
const WORD PRECISION_24 = BINARY4(0000,0000,0000,0000);
const WORD PRECISION_53 = BINARY4(0000,0010,0000,0000);
const WORD PRECISION_64 = BINARY4(0000,0011,0000,0000);
const WORD ROUND_MASK = BINARY4(0000,1100,0000,0000);
const WORD ROUND_NEAREST = BINARY4(0000,0000,0000,0000);
const WORD ROUND_CHOP = BINARY4(0000,1100,0000,0000);
const WORD ROUND_DOWN = BINARY4(0000,0100,0000,0000);
const WORD ROUND_UP = BINARY4(0000,1000,0000,0000);
const WORD EXCEPTION_PRECISION = BINARY4(0000,0000,0010,0000);
const WORD EXCEPTION_UNDERFLOW = BINARY4(0000,0000,0001,0000);
const WORD EXCEPTION_OVERFLOW = BINARY4(0000,0000,0000,1000);
const WORD EXCEPTION_ZERO_DIVIDE = BINARY4(0000,0000,0000,0100);
const WORD EXCEPTION_DENORMAL = BINARY4(0000,0000,0000,0010);
const WORD EXCEPTION_INVALID = BINARY4(0000,0000,0000,0001);
const WORD EXCEPTION_ALL = BINARY4(0000,0000,0011,1111);
// ======================================================================
void FloatingPointUnit::install(void)
{
precision = P_24;
rounding = R_roundToNearestOrEven;
memset(exceptionEnabled, 0, sizeof(exceptionEnabled));
// preserve all other bits
status = getControlWord();
status &= ~(PRECISION_MASK | ROUND_MASK | EXCEPTION_ALL);
// set to single precision, rounding, and all exceptions masked
status |= PRECISION_24 | ROUND_NEAREST | EXCEPTION_ALL;
// check the config platform flags to see if we should enable some exceptions
if (ConfigSharedFoundation::getFpuExceptionPrecision())
{
exceptionEnabled[E_precision] = true;
status &= ~EXCEPTION_PRECISION;
}
if (ConfigSharedFoundation::getFpuExceptionUnderflow())
{
exceptionEnabled[E_underflow] = true;
status &= ~EXCEPTION_UNDERFLOW;
}
if (ConfigSharedFoundation::getFpuExceptionOverflow())
{
exceptionEnabled[E_overflow] = true;
status &= ~EXCEPTION_OVERFLOW;
}
if (ConfigSharedFoundation::getFpuExceptionZeroDivide())
{
exceptionEnabled[E_zeroDivide] = true;
status &= ~EXCEPTION_ZERO_DIVIDE;
}
if (ConfigSharedFoundation::getFpuExceptionDenormal())
{
exceptionEnabled[E_denormal] = true;
status &= ~EXCEPTION_DENORMAL;
}
if (ConfigSharedFoundation::getFpuExceptionInvalid())
{
exceptionEnabled[E_invalid] = true;
status &= ~EXCEPTION_INVALID;
}
setControlWord(status);
}
// ----------------------------------------------------------------------
void FloatingPointUnit::update(void)
{
WORD currentStatus = getControlWord();
if (currentStatus != status)
{
// DEBUG_REPORT_LOG_PRINT(true, ("FPU: update=%d, in mode=%04x, should be in mode=%04x\n", updateNumber, static_cast<int>(currentStatus), static_cast<int>(status)));
setControlWord(status);
}
++updateNumber;
}
// ----------------------------------------------------------------------
WORD FloatingPointUnit::getControlWord(void)
{
WORD controlWord = 0;
__asm fnstcw controlWord;
return controlWord;
}
// ----------------------------------------------------------------------
void FloatingPointUnit::setControlWord(WORD controlWord)
{
UNREF(controlWord);
__asm fldcw controlWord;
}
// ----------------------------------------------------------------------
void FloatingPointUnit::setPrecision(Precision newPrecision)
{
WORD bits = 0;
switch (precision)
{
case P_24:
bits = PRECISION_24;
break;
case P_53:
bits = PRECISION_53;
break;
case P_64:
bits = PRECISION_64;
break;
case P_max:
default:
DEBUG_FATAL(true, ("bad case"));
}
// record the current state
precision = newPrecision;
// set the proper bit pattern
status &= ~PRECISION_MASK;
status |= bits;
// slam it into the FPU
setControlWord(status);
}
// ----------------------------------------------------------------------
void FloatingPointUnit::setRounding(Rounding newRounding)
{
WORD bits = 0;
switch (newRounding)
{
case R_roundToNearestOrEven:
bits = ROUND_NEAREST;
break;
case R_chop:
bits = ROUND_CHOP;
break;
case R_roundDown:
bits = ROUND_DOWN;
break;
case R_roundUp:
bits = ROUND_UP;
break;
case R_max:
default:
DEBUG_FATAL(true, ("bad case"));
}
// record the current state
rounding = newRounding;
// set the proper bit pattern
status &= ~ROUND_MASK;
status |= bits;
// slam it into the FPU
setControlWord(status);
}
// ----------------------------------------------------------------------
void FloatingPointUnit::setExceptionEnabled(Exception exception, bool enabled)
{
WORD bits = 0;
switch (exception)
{
case E_precision:
bits = EXCEPTION_PRECISION;
break;
case E_underflow:
bits = EXCEPTION_UNDERFLOW;
break;
case E_overflow:
bits = EXCEPTION_OVERFLOW;
break;
case E_zeroDivide:
bits = EXCEPTION_ZERO_DIVIDE;
break;
case E_denormal:
bits = EXCEPTION_DENORMAL;
break;
case E_invalid:
bits = EXCEPTION_INVALID;
break;
case E_max:
default:
DEBUG_FATAL(true, ("bad case"));
}
// record the current state
exceptionEnabled[exception] = enabled;
// twiddle the bit appropriately. these bits masks, so set the bit to disable the exception, clear the bit to enable it.
if (enabled)
status &= ~bits;
else
status |= bits;
// slam it into the FPU
setControlWord(status);
}
// ======================================================================
@@ -1,104 +0,0 @@
// ======================================================================
//
// FloatingPointUnit.h
// jeff grills
//
// copyright 1999 Bootprint Entertainment
//
// ======================================================================
#ifndef FLOATING_POINT_UNIT_H
#define FLOATING_POINT_UNIT_H
// ======================================================================
class FloatingPointUnit
{
public:
typedef unsigned short WORD;
enum Precision
{
P_24,
P_53,
P_64,
P_max
};
enum Rounding
{
R_roundToNearestOrEven,
R_chop,
R_roundDown,
R_roundUp,
R_max
};
enum Exception
{
E_precision,
E_underflow,
E_overflow,
E_zeroDivide,
E_denormal,
E_invalid,
E_max
};
private:
static int updateNumber;
static WORD status;
static Precision precision;
static Rounding rounding;
static bool exceptionEnabled[E_max];
public:
static WORD getControlWord(void);
static void setControlWord(WORD controlWord);
public:
static void install(void);
static void update(void);
static void setPrecision(Precision newPrecision);
static void setRounding(Rounding newRounding);
static void setExceptionEnabled(Exception exception, bool enabled);
static Precision getPrecision(void);
static Rounding getRounding(void);
static bool getExceptionEnabled(Exception exception);
};
// ======================================================================
inline FloatingPointUnit::Precision FloatingPointUnit::getPrecision(void)
{
return precision;
}
// ----------------------------------------------------------------------
inline FloatingPointUnit::Rounding FloatingPointUnit::getRounding(void)
{
return rounding;
}
// ----------------------------------------------------------------------
inline bool FloatingPointUnit::getExceptionEnabled(Exception theException)
{
DEBUG_FATAL(static_cast<int>(theException) < 0 || static_cast<int>(theException) >= static_cast<int>(E_max), ("exception out of range")); //lint !e568 // non-negative quantity is never less than 0
return exceptionEnabled[theException];
}
// ======================================================================
#endif
File diff suppressed because it is too large Load Diff
@@ -1,152 +0,0 @@
// ======================================================================
//
// Os.h
//
// Portions copyright 1998 Bootprint Entertainment
// Portions copyright 2000-2002 Sony Online Entertainment
// All Rights Reserved
//
// ======================================================================
#ifndef INCLUDED_Os_H
#define INCLUDED_Os_H
// ======================================================================
#include <ctime>
// ======================================================================
class Os
{
public:
typedef bool (*IsGdiVisibleHookFunction)();
typedef void (*LostFocusHookFunction)();
typedef void (*AcquiredFocusHookFunction)();
typedef void (*QueueCharacterHookFunction)(int keyboard, int character);
typedef void (*SetSystemMouseCursorPositionHookFunction)(int x, int y);
typedef bool (*GetHardwareMouseCursorEnabled)();
typedef void (*GetOtherAdapterRectsHookFunction)(stdvector<RECT>::fwd &);
typedef void (*WindowPositionChangedHookFunction)();
typedef void (*DisplayModeChangedHookFunction)();
typedef void (*InputLanguageChangedHookFunction)();
typedef int (*IMEHookFunction)(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
typedef void (*QueueKeyDownHookFunction)(int keyboard, int character);
typedef uint ThreadId;
typedef DWORD OsPID_t;
enum Priority
{
P_high,
P_normal,
P_low
};
enum
{
MAX_PATH_LENGTH = 512
};
public:
static void install(HINSTANCE newInstance, const char *windowName, HICON normalIcon, HICON smallIcon);
static void install(HWND newWindow, bool processMessagePump);
static void install();
static bool isGameOver();
static DLLEXPORT bool isMainThread();
static bool wasFocusLost();
static void checkChildThreads();
static void setProcessPriority(Priority priority);
static bool update();
static void returnFromAbort();
static void abort();
static void enablePopupDebugMenu();
static void requestPopupDebugMenu();
static bool createDirectories (const char *dirname);
static bool writeFile(const char *fileName, const void *data, int length);
static HWND getWindow();
static bool engineOwnsWindow();
static int getNumberOfUpdates();
static char *getLastError();
static const char *getProgramName();
static const char *getShortProgramName();
static const char *getProgramStartupDirectory();
static void setIsGdiVisibleHookFunction(IsGdiVisibleHookFunction newGlIsGdiVisible);
static void setLostFocusHookFunction(LostFocusHookFunction lostFocusHookFunction);
static void setQueueCharacterHookFunction(QueueCharacterHookFunction queueCharacterHookFunction);
static void setSetSystemMouseCursorPositionHookFunction(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction);
static void setSetSystemMouseCursorPositionHookFunction2(SetSystemMouseCursorPositionHookFunction setSystemMouseCursorPositionHookFunction);
static void setAcquiredFocusHookFunction(AcquiredFocusHookFunction acquiredFocusHookFunction);
static void setAcquiredFocusHookFunction2(AcquiredFocusHookFunction acquiredFocusHookFunction);
static void setGetHardwareMouseCursorEnabled(GetHardwareMouseCursorEnabled getHardwareMouseCursorEnabled);
static void setGetOtherAdapterRectsHookFunction(GetOtherAdapterRectsHookFunction getOtherAdapterRectsHookFunction);
static void setWindowPositionChangedHookFunction(WindowPositionChangedHookFunction windowPositionChangedHookFunction);
static void setDisplayModeChangedHookFunction(DisplayModeChangedHookFunction displayModeChangedHookFunction);
static void setInputLanguageChangedHookFunction(InputLanguageChangedHookFunction inputLanguageChangedHookFunction);
static void setIMEHookFunction(IMEHookFunction imeHookFunction);
static void setQueueKeyDownHookFunction(QueueKeyDownHookFunction queueKeyDownHookFunction);
static DLLEXPORT ThreadId getThreadId();
static void setThreadName(ThreadId threadID, const char* name);
static void sleep(int ms);
static time_t getRealSystemTime();
static void convertTimeToGMT(const time_t &time, tm &zulu);
static time_t convertGMTToTime(const tm &zulu);
static bool isMultiprocessor();
static int getProcessorCount();
static void buildRelativePath(const char *baseDirectory, const char *targetPathname, std::string &relativePath);
static bool getAbsolutePath(const char *relativePath, char *absolutePath, int absolutePathBufferSize);
static bool copyTextToClipboard(const char *text);
static bool getUserName(char *buffer, int &bufferSize);
static OsPID_t getProcessId();
static bool isFocused();
static bool launchBrowser(std::string const & website);
static bool isNumPadValue(unsigned char asciiChar);
static bool isNumPadChar(unsigned char asciiChar);
private:
Os();
Os(const Os &);
Os &operator =(const Os &);
private:
static void remove();
static void installCommon();
static LRESULT CALLBACK Os::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
private:
static bool handleDebugMenu();
};
// ======================================================================
#endif
@@ -1,465 +0,0 @@
// ======================================================================
//
// PerThreadData.cpp
//
// Portions copyright 1998 Bootprint Entertainment
// Portions Copyright 2002 Sony Online Entertainment
// All Rights Reserved
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/PerThreadData.h"
#include "sharedSynchronization/RecursiveMutex.h"
#include "sharedSynchronization/Gate.h"
#include "sharedFoundation/Os.h"
#include <winbase.h>
#include <vector>
// ======================================================================
// ======================================================================
namespace PerThreadDataNamespace
{
struct Data
{
bool exitChainRunning;
bool exitChainFataling;
ExitChain::Entry *exitChainFirstEntry;
int debugPrintFlags;
Gate *fileStreamerReadGate;
HANDLE watchHandle;
};
typedef std::vector<Data *> DataAllocations;
// ------------------------------------------------------
static char buffer1[sizeof(RecursiveMutex)];
static char buffer2[sizeof(DataAllocations)];
static const DWORD BadSlot = 0xffffffff;
static DWORD slot = BadSlot;
static RecursiveMutex *criticalSection;
static DataAllocations *dataAllocations;
// ------------------------------------------------------
static void _threadRemove(Data *data);
static void _removeFromList(Data *data);
static void _watchThreads();
/*----------------------------------------------------------------------
* Get access to the per-thread-data.
*
* This routine will verify the per-thread-data subsystem has been installed and the
* threadInstall() function has been called for the current thread.
*
* @return A pointer to the per-thread-data.
*/
inline static Data *_getData(bool allowReturnNull=false)
{
UNREF(allowReturnNull);
if (slot == BadSlot)
{
DEBUG_FATAL(true && !allowReturnNull, ("not installed"));
return NULL;
}
Data * const data = reinterpret_cast<Data *>(TlsGetValue(slot));
DEBUG_FATAL(!data && !allowReturnNull, ("not installed for this thread"));
return data;
}
// ------------------------------------------------------
inline static void _closeData(Data *data)
{
if (data->fileStreamerReadGate)
{
delete data->fileStreamerReadGate;
data->fileStreamerReadGate=0;
}
if (data->watchHandle)
{
CloseHandle(data->watchHandle);
data->watchHandle=0;
}
}
// ------------------------------------------------------
inline static void _freeData(Data *data)
{
delete data;
}
// ------------------------------------------------------
}
using namespace PerThreadDataNamespace;
// ======================================================================
// ======================================================================
// Install the per-thread-data subsystem
//
// Remarks:
//
// This routine will install the per-thread-data subsystem that is required for several
// other subsystems in the engine. It should be called from the primary thread before
// any other threads have been created. It will also call threadInstall() for the
// primary thread.
//
// See Also:
//
// PerThreadData::remove()
void PerThreadData::install()
{
slot = TlsAlloc();
FATAL(slot == BadSlot, ("TlsAlloc failed"));
criticalSection = new(buffer1) RecursiveMutex;
dataAllocations = new(buffer2) DataAllocations;
dataAllocations->reserve(8);
threadInstall();
}
// ----------------------------------------------------------------------
/**
* Remove the per-thread-subsystem.
*
* This routine should be called by the primary thread after all other threads have
* terminated, and no other uses of per-thread-data will occur.
*
* @see PerThreadData::install()
*/
void PerThreadData::remove()
{
criticalSection->enter();
{
// remove this thread.
threadRemove();
// clean up after any threads which didn't clean up after themselves (like the miles sound system)
const DataAllocations::iterator iEnd = dataAllocations->end();
for (DataAllocations::iterator i = dataAllocations->begin(); i != iEnd; ++i)
{
_closeData(*i);
_freeData(*i);
}
dataAllocations->clear();
}
criticalSection->leave();
criticalSection->~RecursiveMutex();
dataAllocations->~vector();
memset(buffer1, 0, sizeof(buffer1));
memset(buffer2, 0, sizeof(buffer2));
const BOOL result = TlsFree(slot);
FATAL(!result, ("TlsFree failed"));
}
// ----------------------------------------------------------------------
/**
* Create the per-thread-data for a new thread.
*
* This routine should be called in a thread before the first usage of per-thread-data.
*
* If the client is calling this function on a thread that existed before the engine was
* installed, the client should set isNewThread to false. Setting isNewThread to false
* prevents the function from validating that the thread's TLS is NULL. For threads existing
* before the engine is installed, the TLS data for the thread is undefined.
*
* @param isNewThread [IN] true if the thread was created after the engine was installed, false otherwise
* @see PerThreadData::threadRemove()
*/
void PerThreadData::threadInstall(bool isNewThread)
{
UNREF(isNewThread);
DEBUG_FATAL(slot == BadSlot, ("not installed"));
// only check for already-set data if this is supposed to be a new thread
DEBUG_FATAL(isNewThread && TlsGetValue(slot), ("already installed for this thread"));
// create the data
Data * const data = new Data;
// initialize the data
memset(data, 0, sizeof(*data));
//create the event for file streaming reads
data->fileStreamerReadGate = new Gate(false);
// set the data into the thread slot
const BOOL result = TlsSetValue(slot, data);
UNREF(result);
DEBUG_FATAL(!result, ("TlsSetValue failed"));
criticalSection->enter();
{
_watchThreads();
dataAllocations->push_back(data);
// This is most likely a thread created by a 3rd party library such as Miles or Bink.
// Add a watch handle to it so we can clean it up.
if (!isNewThread)
{
const HANDLE processHandle = GetCurrentProcess();
DuplicateHandle(processHandle, GetCurrentThread(), processHandle, &data->watchHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
}
}
criticalSection->leave();
}
// ----------------------------------------------------------------------
void PerThreadDataNamespace::_removeFromList(Data *data)
{
const DataAllocations::iterator iEnd = dataAllocations->end();
const DataAllocations::iterator i = std::find(dataAllocations->begin(), iEnd, data);
if (i!=iEnd)
{
dataAllocations->erase(i);
}
}
// ----------------------------------------------------------------------
// Synchronization is left up to the user
// Unless this is called during shutdown, the critical section
// needs to be entered.
void PerThreadDataNamespace::_watchThreads()
{
DataAllocations::iterator tiDest = dataAllocations->begin();
DataAllocations::iterator tiSrc = tiDest;
DataAllocations::iterator tiEnd = dataAllocations->end();
while (tiSrc!=tiEnd)
{
Data *const data = *tiSrc;
const HANDLE h = data->watchHandle;
if (h!=0 && WaitForSingleObject(h, 0)==WAIT_OBJECT_0)
{
_closeData(data);
_freeData(data);
}
else
{
*tiDest++=data;
}
++tiSrc;
}
if (tiSrc!=tiDest)
{
const int newSize = tiDest - dataAllocations->begin();
dataAllocations->resize(newSize);
}
}
// ----------------------------------------------------------------------
void PerThreadDataNamespace::_threadRemove(Data *data)
{
//close the event used for file streaming reads
_closeData(data);
_removeFromList(data);
// free the memory
_freeData(data);
}
// ----------------------------------------------------------------------
/**
* Destroy the per-thread-data for a terminating thread.
*
* This routine should be called in a thread after the last usage of per-thread-data.
*
* @see PerThreadData::threadInstall()
*/
void PerThreadData::threadRemove()
{
DEBUG_FATAL(slot == BadSlot, ("not installed"));
DEBUG_FATAL(!TlsGetValue(slot), ("thread not installed"));
// find our thread record and free the memory
criticalSection->enter();
_threadRemove(_getData());
// wipe the data in the thread slot
const BOOL result = TlsSetValue(slot, NULL);
UNREF(result);
DEBUG_FATAL(!result, ("TlsSetValue failed"));
criticalSection->leave();
}
// ======================================================================
// ======================================================================
// Determine if the per-thread-data is available for this thread
//
// Return value:
//
// True if the per-thread-data is installed correctly, false otherwise
//
// Remarks:
//
// This routine is not intended for general use; it should only be used by the ExitChain class.
//
// -TRF- looks like Win98 does not zero out a new TLS slot for
// threads existing at the time of slot creation. Thus, if you build a
// plugin that only initializes the engine the first time it is
// used, and other threads already exist in the app, those threads
// will contain bogus non-null data in the TLS slot. If the plugin really
// wants to do lazy initialization of the engine, it will need
// to handle calling PerThreadData::threadInstall() for all existing threads
// (except the thread that initialized the engine, which already
// has its PerThreadData::threadInstall() called).
bool PerThreadData::isThreadInstalled()
{
return (_getData(true) != NULL);
}
// ----------------------------------------------------------------------
/**
* Get the exit chain running flag value.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
*
* @return True if the exit chain is running, false otherwise.
* @see ExitChain::isRunning()
*/
bool PerThreadData::getExitChainRunning()
{
return _getData()->exitChainRunning;
}
// ----------------------------------------------------------------------
/**
* Set the exit chain running flag value.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
*
* @param newValue New value for the exit chain running flag
*/
void PerThreadData::setExitChainRunning(bool newValue)
{
_getData()->exitChainRunning = newValue;
}
// ----------------------------------------------------------------------
/**
* Get the exit chain fataling flag value.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
*
* @return True if the exit chain is fataling, false otherwise.
* @see ExitChain::isFataling()
*/
bool PerThreadData::getExitChainFataling()
{
return _getData()->exitChainFataling;
}
// ----------------------------------------------------------------------
/**
* Set the exit chain fataling flag value.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
*
* @param newValue New value for the exit chain fataling flag
*/
void PerThreadData::setExitChainFataling(bool newValue)
{
_getData()->exitChainFataling = newValue;
}
// ----------------------------------------------------------------------
/**
* Get the first entry for the exit chain.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
* This routine may return NULL.
*
* @return Pointer to the first entry on the exit chain
* @see ExitChain::isFataling()
*/
ExitChain::Entry *PerThreadData::getExitChainFirstEntry()
{
return _getData()->exitChainFirstEntry;
}
// ----------------------------------------------------------------------
/**
* Set the exit chain fataling flag value.
*
* This routine is not intended for general use; it should only be used by the ExitChain class.
* The parameter to this routine may be NULL.
*
* @param newValue New value for the exit chain first entry
*/
void PerThreadData::setExitChainFirstEntry(ExitChain::Entry *newValue)
{
_getData()->exitChainFirstEntry = newValue;
}
// ----------------------------------------------------------------------
/**
* Get the debug print flags.
*
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
*
* @return Current value of the debug print flags
*/
int PerThreadData::getDebugPrintFlags()
{
return _getData()->debugPrintFlags;
}
// ----------------------------------------------------------------------
/**
* Set the debug print flags value.
*
* This routine is not intended for general use; it should only be used by the DebugPrint functions.
*/
void PerThreadData::setDebugPrintFlags(int newValue)
{
_getData()->debugPrintFlags = newValue;
}
// ----------------------------------------------------------------------
Gate *PerThreadData::getFileStreamerReadGate()
{
return _getData()->fileStreamerReadGate;
}
// ======================================================================
@@ -1,57 +0,0 @@
// ======================================================================
//
// PerThreadData.h
//
// Portions copyright 1998 Bootprint Entertainment
// Portions Copyright 2002 Sony Online Entertainment
// All Rights Reserved
//
// ======================================================================
#ifndef INCLUDED_PerThreadData_H
#define INCLUDED_PerThreadData_H
// ======================================================================
class Gate;
#include "sharedFoundation/ExitChain.h"
// ======================================================================
// Provide thread local storage functionality.
//
// This class' purpose is to allow each thread to maintain some storage that is local and private to each thread.
// The system must be installed before use. Each thread that may use per-thread-data will also need to call the
// threadInstall() routine after creation and threadRemove() just before termination of the thread.
class PerThreadData
{
public:
static void install(void);
static void remove(void);
static void threadInstall(bool isNewThread = true);
static void threadRemove(void);
static bool isThreadInstalled(void);
static bool getExitChainRunning(void);
static void setExitChainRunning(bool newValue);
static bool getExitChainFataling(void);
static void setExitChainFataling(bool newValue);
static ExitChain::Entry *getExitChainFirstEntry(void);
static void setExitChainFirstEntry(ExitChain::Entry *newValue);
static int getDebugPrintFlags(void);
static void setDebugPrintFlags(int newValue);
static Gate *getFileStreamerReadGate(void);
};
// ======================================================================
#endif
@@ -1,124 +0,0 @@
// ======================================================================
//
// PlatformGlue.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/PlatformGlue.h"
#include <cstdio>
#include <cstdarg>
// ======================================================================
namespace
{
// ----------------------------------------------------------------------
class GmTimeSection
{
public:
GmTimeSection()
{
InitializeCriticalSection(&m_section);
}
~GmTimeSection()
{
DeleteCriticalSection(&m_section);
}
void enter()
{
EnterCriticalSection(&m_section);
}
void leave()
{
LeaveCriticalSection(&m_section);
}
private:
CRITICAL_SECTION m_section;
};
// ----------------------------------------------------------------------
static GmTimeSection s_gmTimeSection;
// ----------------------------------------------------------------------
}
// ======================================================================
// Tokenizing a string.
// Like strtok, except re-entrant.
char *strsep(char **string, const char *delim)
{
char *result = *string;
// handle no string specified, or the end of the string
if (result == 0)
return 0;
// skip leading delimiters
result = result + strspn(result, delim);
// handle trailing delimiters
if (*result == '\0')
return 0;
// look for the first delimiter
const int len = strcspn(result, delim);
if (result[len] == '\0')
{
// hit the end of the string
*string = 0;
}
else
{
// terminate the string and return the substring
result[len] = '\0';
*string = result + len + 1;
}
return result;
}
// ----------------------------------------------------------------------
int snprintf(char *buffer, size_t count, const char *format, ...)
{
va_list va;
va_start(va, format);
const int result = _vsnprintf(buffer, count, format, va);
va_end(va);
return result;
}
// ----------------------------------------------------------------------
struct tm *gmtime_r(const time_t *timep, struct tm *result)
{
s_gmTimeSection.enter();
tm *t = gmtime(timep);
*result = *t;
s_gmTimeSection.leave();
return result;
}
// ----------------------------------------------------------------------
int finite(double value)
{
return _finite(value);
}
// ======================================================================
@@ -1,32 +0,0 @@
// ======================================================================
//
// PlatformGlue.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_PlatformGlue_H
#define INCLUDED_PlatformGlue_H
// ======================================================================
#include <time.h>
// ======================================================================
char * strsep(char **string, const char *delim);
int snprintf(char *buffer, size_t count, const char *format, ...);
struct tm * gmtime_r(const time_t *timep, struct tm *result);
int finite(double value);
//Format specifier for non-portable printf
#define UINT64_FORMAT_SPECIFIER "%I64u"
#define INT64_FORMAT_SPECIFIER "%I64i"
//Constant definition macro for 64 bit values
#define UINT64_LITERAL(a) a ## ui64
#define INT64_LITERAL(a) a ## i64
// ======================================================================
#endif
@@ -1,310 +0,0 @@
//
// ProcessSpawner.cpp
//
//-------------------------------------------------------------------
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/ProcessSpawner.h"
#include "sharedFoundation/Os.h"
#include <minmax.h>
ProcessSpawner::ProcessSpawner()
{
m_asConsole=false;
hProcess=0;
hOutputRead=0;
hInputWrite=0;
currentLine=currentRead=readBuffer;
}
ProcessSpawner::~ProcessSpawner()
{
if (hProcess)
{
CloseHandle(hProcess);
hProcess=0;
}
if (hOutputRead)
{
CloseHandle(hOutputRead);
hOutputRead=0;
}
if (hInputWrite)
{
CloseHandle(hInputWrite);
hInputWrite=0;
}
}
bool ProcessSpawner::terminate(unsigned exitCode)
{
if (!hProcess)
{
return false;
}
return TerminateProcess(hProcess, exitCode)!=0;
}
bool ProcessSpawner::create(const char *commandLine, const char *startupFolder, bool asConsole)
{
if (hProcess)
{
return false;
}
if (!commandLine)
{
return false;
}
if (!startupFolder)
{
startupFolder=Os::getProgramStartupDirectory();
}
m_asConsole=asConsole;
STARTUPINFO sinfo;
memset(&sinfo, 0, sizeof(sinfo));
sinfo.cb=sizeof(sinfo);
HANDLE hOutputWrite=0;
HANDLE hErrorWrite=0;
HANDLE hInputRead=0;
if (asConsole)
{
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(sa);
sa.lpSecurityDescriptor=0;
sa.bInheritHandle=true;
// -----------------------------------------------------
// Create the child output pipe.
HANDLE hOutputReadTmp;
CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0);
// Create a duplicate of the output write handle for the std error
// write handle. This is necessary in case the child application
// closes one of its std output handles.
DuplicateHandle(
GetCurrentProcess(), hOutputWrite,
GetCurrentProcess(),&hErrorWrite,
0,
TRUE,DUPLICATE_SAME_ACCESS
);
// Create the child input pipe.
HANDLE hInputWriteTmp;
CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0);
// Create new output read handle and the input write handles. Set
// the Properties to FALSE. Otherwise, the child inherits the
// properties and, as a result, non-closeable handles to the pipes
// are created.
DuplicateHandle(
GetCurrentProcess(), hOutputReadTmp,
GetCurrentProcess(), &hOutputRead, // Address of new handle.
0, FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS
);
DuplicateHandle(
GetCurrentProcess(), hInputWriteTmp,
GetCurrentProcess(), &hInputWrite, // Address of new handle.
0,FALSE, // Make it uninheritable.
DUPLICATE_SAME_ACCESS
);
// Close inheritable copies of the handles you do not want to be
// inherited.
CloseHandle(hOutputReadTmp); hOutputReadTmp=0;
CloseHandle(hInputWriteTmp); hInputWriteTmp=0;
sinfo.dwFlags|=(STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);
sinfo.hStdError=hErrorWrite;
sinfo.hStdInput=hInputRead;
sinfo.hStdOutput=hOutputWrite;
sinfo.wShowWindow = SW_HIDE;
}
PROCESS_INFORMATION pinfo;
BOOL result = CreateProcess(
0,
(char *)commandLine,
0,
0,
TRUE,
CREATE_NEW_CONSOLE,
0,
startupFolder,
&sinfo,
&pinfo
);
if (asConsole)
{
// Close pipe handles (do not continue to modify the parent).
// You need to make sure that no handles to the write end of the
// output pipe are maintained in this process or else the pipe will
// not close when the child process exits and the ReadFile will hang.
CloseHandle(hOutputWrite); hOutputWrite=0;
CloseHandle(hErrorWrite); hErrorWrite=0;
CloseHandle(hInputRead); hInputRead=0;
}
if (result)
{
CloseHandle(pinfo.hThread);
hProcess=pinfo.hProcess;
return true;
}
else
{
// Failed to launch turf
hProcess=0;
return false;
}
}
bool ProcessSpawner::isFinished(unsigned waitTime)
{
if (!hProcess)
{
return true;
}
DWORD waitResult = WaitForSingleObject(hProcess, waitTime);
return waitResult==WAIT_OBJECT_0;
}
bool ProcessSpawner::getExitCode(unsigned &o_code)
{
if (!hProcess)
{
return false;
}
DWORD exitCode;
BOOL result = GetExitCodeProcess(hProcess, &exitCode);
if (result)
{
o_code=exitCode;
return true;
}
else
{
return false;
}
}
bool ProcessSpawner::_returnExistingLine(char *buffer, const int bufferSize)
{
const char *const bufferStop = buffer + bufferSize;
char *iter = currentLine;
while (iter!=currentRead)
{
if (buffer==bufferStop)
{
currentLine=iter;
return true;
}
if (*iter=='\n')
{
*buffer++=0;
_stepIter(iter);
currentLine=iter;
return true;
}
else
{
*buffer++=*iter;
_stepIter(iter);
}
}
return false;
}
bool ProcessSpawner::getOutputString(char *buffer, int bufferSize)
{
if (_returnExistingLine(buffer, bufferSize))
{
return true;
}
// ----------------------------------------------
if (!hOutputRead)
{
return false;
}
DWORD dwAvail = 0;
if (!::PeekNamedPipe(hOutputRead, NULL, 0, NULL, &dwAvail, NULL))
{
// ERROR
return false;
}
if (!dwAvail)
{
return false;
}
DWORD dwRead;
if (currentRead >= currentLine)
{
const unsigned bufferAvailable = sizeof(readBuffer) - (currentRead - readBuffer);
unsigned toRead = dwAvail;
if (toRead > bufferAvailable)
{
toRead=bufferAvailable;
}
dwRead=0;
if (!::ReadFile(hOutputRead, currentRead, min(bufferAvailable, dwAvail), &dwRead, NULL) || !dwRead)
{
return false;
}
dwAvail-=dwRead;
currentRead+=dwRead;
if (currentRead==readBuffer+sizeof(readBuffer))
{
currentRead=readBuffer;
}
}
if (dwAvail>0)
{
const unsigned bufferAvailable = currentLine - currentRead - 1;
if (bufferAvailable)
{
unsigned toRead = dwAvail;
if (toRead > bufferAvailable)
{
toRead=bufferAvailable;
}
dwRead=0;
if (!::ReadFile(hOutputRead, currentRead, min(bufferAvailable, dwAvail), &dwRead, NULL) || !dwRead)
{
return false;
}
currentRead+=dwRead;
DEBUG_FATAL(currentRead>=currentLine, (""));
}
}
return _returnExistingLine(buffer, bufferSize);
}
@@ -1,43 +0,0 @@
#ifndef INCLUDED_ProcessSpawner_H
#define INCLUDED_ProcessSpawner_H
class ProcessSpawner
{
public:
ProcessSpawner();
~ProcessSpawner();
bool create(const char *commandLine, const char *startupFolder=0, bool asConsole=true);
bool terminate(unsigned exitCode=0);
bool isFinished(unsigned waitTime=0);
bool getExitCode(unsigned &o_code);
bool getOutputString(char *buffer, int bufferSize);
protected:
bool _returnExistingLine(char *buffer, int bufferSize);
void _stepIter(char *&i)
{
if (i==readBuffer+sizeof(readBuffer)-1)
{
i=readBuffer;
}
else
{
i++;
}
}
HANDLE hProcess;
HANDLE hOutputRead, hInputWrite;
bool m_asConsole;
char *currentLine, *currentRead, readBuffer[4096];
};
#endif
@@ -1,918 +0,0 @@
// ======================================================================
//
// RegistryKey.cpp
// Todd Fiala
//
// copyright 1998 Bootprint Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/RegistryKey.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFoundation/ConfigFile.h"
#if USE_REGISTRY_EXECUTION_STATISTICS
#include <cstdio>
#include <ctime>
#endif
// ======================================================================
// keyname for config file parameter containing relative registry path
// for the product
const char * const RegistryKey::PRODUCT_REGISTRY_PATH_KEYNAME = "ProductRegistryPath";
const char * const RegistryKey::DEFAULT_PRODUCT_REGISTRY_PATH = "Software\\Sony Online Entertainment\\Default";
#if USE_REGISTRY_EXECUTION_STATISTICS
const char * const RegistryKey::STATISTICS_KEYNAME = "Statistics";
const char * const RegistryKey::STAT_EXEC_STARTED_COUNT_VALUENAME = "StartedExecutions";
const char * const RegistryKey::STAT_EXEC_INCOMPLETE_COUNT_VALUENAME = "IncompleteExecutions";
const char * const RegistryKey::STAT_TIME_AVERAGE_VALUENAME = "AverageClockTime";
const char * const RegistryKey::STAT_TIME_MIN_VALUENAME = "MinimumClockTime";
const char * const RegistryKey::STAT_TIME_MAX_VALUENAME = "MaximumClockTime";
const char * const RegistryKey::STAT_TIME_START_VALUENAME = "StartClockTime";
#endif
bool RegistryKey::installed;
bool RegistryKey::setProductKeyPathFromConfig;
RegistryKey *RegistryKey::usersKey;
RegistryKey *RegistryKey::currentUserKey;
RegistryKey *RegistryKey::classRootKey;
RegistryKey *RegistryKey::localMachineKey;
RegistryKey *RegistryKey::productUserKey;
RegistryKey *RegistryKey::productMachineKey;
// ======================================================================
// construct a RegistryKey instance
//
// Remarks:
// This function does not create the underlying registry object. It
// solely attaches such a registry object with a RegistryKey class
// instance.
RegistryKey::RegistryKey(
HKEY newKeyHandle, // [IN] handle of existing registry key
bool newCloseKeyOnDestroy // [IN] true if RegCloseKey() should be called on key at destruction time
) :
keyHandle(newKeyHandle),
closeKeyOnDestroy(newCloseKeyOnDestroy)
{
// -qq- don't know which of these indicates an invalid handle, so check for both
DEBUG_FATAL(!newKeyHandle, ("null newKeyHandle arg"));
DEBUG_FATAL(newKeyHandle == INVALID_HANDLE_VALUE, ("newKeyHandle arg is an invalid handle"));
}
// ----------------------------------------------------------------------
/**
* destroy a RegistryKey instance.
*/
RegistryKey::~RegistryKey(void)
{
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
if (closeKeyOnDestroy)
{
const LONG result = RegCloseKey(keyHandle);
UNREF(result);
DEBUG_FATAL(result != ERROR_SUCCESS, ("failed to close registry key, error = %ld\n", result));
}
keyHandle = 0;
}
// ----------------------------------------------------------------------
/**
* enumerate all child subkeys of the current key.
*
* @param context [IN] user-specified context variable passed to callback
* @param callback [IN] function to call for each subkey enumerated
* @see EnumerateKeyCallback, enumerateValues()
*/
void RegistryKey::enumerateSubkeys(void *context, EnumerateKeyCallback callback) const
{
const size_t MAX_NAME_LENGTH = 256;
LONG result;
FILETIME lastModifiedFileTime;
char subkeyName[MAX_NAME_LENGTH];
DWORD subkeyNameLength;
DWORD index;
DEBUG_FATAL(!callback, ("null callback arg\n"));
for (
index = 0, subkeyNameLength = MAX_NAME_LENGTH;
ERROR_SUCCESS == (result = RegEnumKeyEx(keyHandle, index, subkeyName, &subkeyNameLength, 0, 0, 0, &lastModifiedFileTime));
++index, subkeyNameLength = MAX_NAME_LENGTH
)
{
bool continueEnum = callback(context, subkeyName, &lastModifiedFileTime);
if (!continueEnum) break;
}
// ensure we finished enumeration cleanly
FATAL(
(result != ERROR_SUCCESS) && (result != ERROR_NO_MORE_ITEMS),
("failed to enumerate registry subkeys, error = %ld\n", result));
}
// ----------------------------------------------------------------------
/**
* open and return a subkey under this RegistryKey instance.
*
* The function will fail if the specified subkey does not exist.
*
* @param subkeyName [IN] registry path for subkey to open, relative to this RegistryKey instance
* @param accessFlags [IN] flags indicating access granted to the returned RegistryKey
* @return This function returns a RegistryKey instance for the specified
* subkey.
*/
RegistryKey *RegistryKey::openSubkey(const char *subkeyName, uint32 accessFlags) const
{
REGSAM samDesired = 0;
LONG result;
HKEY newKey = 0;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!subkeyName, ("null subkeyName arg"));
DEBUG_FATAL(!strlen(subkeyName), ("zero-length subkeyName arg"));
// configure security access desired
if (accessFlags & AF_READ)
samDesired |= KEY_READ;
if (accessFlags & AF_WRITE)
samDesired |= KEY_WRITE;
// open the key
result = RegOpenKeyEx(keyHandle, subkeyName, 0, samDesired, &newKey);
FATAL(result != ERROR_SUCCESS, ("failed to open registry subkey \"%s\", error = %ld\n", subkeyName, result));
// Create the RegistryKey object. Assume the key must be closed upon
// destruction.
return new RegistryKey(newKey, true);
}
// ----------------------------------------------------------------------
/**
* create and return a subkey under this RegistryKey instance.
*
* The function will succeed even if the specified subkey
* already exists.
*
* @return This function returns a RegistryKey instance for the specified
* subkey.
*/
RegistryKey *RegistryKey::createSubkey(const char *subkeyName, uint32 accessFlags) const
{
REGSAM samDesired = 0;
LONG result;
HKEY newKey = 0;
DWORD disposition;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!subkeyName, ("null subkeyName arg"));
DEBUG_FATAL(!strlen(subkeyName), ("zero-length subkeyName arg"));
// configure security access desired
if (accessFlags & AF_READ)
samDesired |= KEY_READ;
if (accessFlags & AF_WRITE)
samDesired |= KEY_WRITE;
// open the key
result = RegCreateKeyEx(
keyHandle,
subkeyName,
0, // reserved
const_cast<char *>(""), // class
REG_OPTION_NON_VOLATILE, // options
samDesired,
NULL, // security
&newKey,
&disposition);
FATAL(result != ERROR_SUCCESS, ("failed to create registry subkey \"%s\", error = %ld\n", subkeyName, result));
// Create the RegistryKey object. Assume the key must be closed upon
// destruction.
return new RegistryKey(newKey, true);
}
// ----------------------------------------------------------------------
/**
* delete a subkey relative to this RegistryKey instance.
*
* Under Windows NT, deleting a key that has subkeys is considered an
* error. Therefore, the client should ensure the target key for
* deletion does not have any subkeys. (Under Windows 9X, deletion of
* the target registry key will automatically delete all subkeys
* underneath the target key.)
*/
void RegistryKey::deleteSubkey(const char *subkeyName)
{
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!subkeyName, ("null subkeyName arg"));
DEBUG_FATAL(!strlen(subkeyName), ("zero-length subkeyName arg"));
IGNORE_RETURN(RegDeleteKey(keyHandle, subkeyName));
}
// ----------------------------------------------------------------------
/**
* test for the existence of a subkey under this RegistryKey instance.
*
* @param subkeyName [IN] registry path for subkey to open, relative to this RegistryKey instance
*/
bool RegistryKey::subKeyExists(const char *subkeyName)
{
REGSAM samDesired = KEY_READ;
LONG result;
HKEY newKey = 0;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!subkeyName, ("null subkeyName arg"));
DEBUG_FATAL(!strlen(subkeyName), ("zero-length subkeyName arg"));
// open the key
result = RegOpenKeyEx(keyHandle, subkeyName, 0, samDesired, &newKey);
return (result == ERROR_SUCCESS);
}
// ----------------------------------------------------------------------
/**
* enumerate all values under the current key.
*
* @param context [IN] user-specified context variable passed to callback
* @param callback [IN] function to call for each value enumerated
* @see EnumerateValueCallback, enumerateSubkeys()
*/
void RegistryKey::enumerateValues(void *context, EnumerateValueCallback callback) const
{
const size_t MAX_NAME_LENGTH = 256;
LONG result;
char valueName[MAX_NAME_LENGTH];
DWORD valueNameLength;
DWORD index;
DWORD dataSize;
DWORD valueType;
DEBUG_FATAL(!callback, ("null callback arg\n"));
for (
index = 0, valueNameLength = MAX_NAME_LENGTH, dataSize = 0;
ERROR_SUCCESS == (result = RegEnumValue(keyHandle, index, valueName, &valueNameLength, 0, &valueType, 0, &dataSize));
++index, valueNameLength = MAX_NAME_LENGTH, dataSize = 0
)
{
bool continueEnum = callback(context, valueName, static_cast<uint32>(dataSize), valueType);
if (!continueEnum) break;
}
// ensure we finished enumeration cleanly
FATAL(
(result != ERROR_SUCCESS) && (result != ERROR_NO_MORE_ITEMS),
("failed to enumerate registry values, error = %ld\n", result));
}
// ----------------------------------------------------------------------
/**
* query if a value exists and how many bytes that value occupies.
*
* The client does can pass null for the valueSize and/or valueType
* parameter if that information is not desired. The value returned
* within the valueSize and valueType parameter is only valid
* if the doesExist parameter is set to true upon function return.
* The value of the valueType parameter is one of the Windows-defined
* REG_* constants provided for use with the Win32 Reg* registry
* API. Common values are REG_BINARY (binary data), REG_DWORD
* (unsigned integral type data) and REG_SZ (C-style zero-terminated
* strings). Consult the Win32 documentation for RegGetValueEx()
* for a description of all the type constants.
*
* @param valueName [IN] name of the value to query
* @param doesExist [OUT] true if value exists under this key, false otherwise
* @param valueSize [OUT] number of bytes occupied by value's data
* @param valueType [OUT] type flag for registry value (see REG_* in RegSetValueEx())
*/
void RegistryKey::getValueInfo(const char *valueName, bool *doesExist, uint32 *valueSize, DWORD *valueType) const
{
LONG result;
DWORD dwSize = 0;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!valueName, ("null valueName arg"));
DEBUG_FATAL(!doesExist, ("null doesExist arg"));
DEBUG_FATAL(!strlen(valueName), ("zero-length valueName arg"));
// get information on the value
result = RegQueryValueEx(keyHandle, valueName, 0, valueType, 0, &dwSize);
// assume a query failure indicates the value was not found
*doesExist = (result == ERROR_SUCCESS);
if (valueSize)
*valueSize = static_cast<uint32>(dwSize);
}
// ----------------------------------------------------------------------
/**
* set the data for this key's value.
*
* The value of the valueType parameter is one of the Windows-defined
* REG_* constants provided for use with the Win32 Reg* registry
* API. Common values are REG_BINARY (binary data), REG_DWORD
* (unsigned integral type data) and REG_SZ (C-style zero-terminated
* strings). Consult the Win32 documentation for RegGetValueEx()
* for a description of all the type constants.
*
* @param valueName [IN] name of value under which data will be stored
* @param dataPtr [IN] pointer to buffer containing value's data
* @param dataSize [IN] # bytes to store
* @param valueType [IN] type field for value (indicates nature of data stored with value)
*/
void RegistryKey::setValue(const char *valueName, const void *dataPtr, uint32 dataSize, DWORD valueType)
{
LONG result;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!valueName, ("null valueName arg"));
DEBUG_FATAL(!strlen(valueName), ("zero-length valueName arg"));
DEBUG_FATAL(!dataPtr, ("null dataPtr arg"));
// get information on the value
result = RegSetValueEx(keyHandle, valueName, 0, valueType, static_cast<CONST BYTE*>(dataPtr), static_cast<DWORD>(dataSize));
FATAL(result != ERROR_SUCCESS, ("failed to set registry value \"%s\", error = %ld\n", valueName, result));
}
// ----------------------------------------------------------------------
/**
* retrieve the data for the this key's value.
*
* The valueType and/or the valueDataSize parameter may be set
* to null if the client doesn't need this information.
* The value of the valueType parameter is one of the Windows-defined
* REG_* constants provided for use with the Win32 Reg* registry
* API. Common values are REG_BINARY (binary data), REG_DWORD
* (unsigned integral type data) and REG_SZ (C-style zero-terminated
* strings). Consult the Win32 documentation for RegGetValueEx()
* for a description of all the type constants.
*
* @param valueName [IN] the name of the value to retrieve
* @param dataPtr [OUT] the buffer where the value's data will be stored
* @param maxDataSize [IN] size of the data buffer in bytes
* @param valueDataSize [OUT] number of bytes retrieved from the named value
* @param valueType [OUT] type field for value's data (see REG_* codes in RegSetValueEx)
*/
void RegistryKey::getValue(const char *valueName, void *dataPtr, uint32 maxDataSize, uint32 *valueDataSize, DWORD *valueType) const
{
LONG result;
DWORD dwSize = maxDataSize;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!valueName, ("null valueName arg"));
DEBUG_FATAL(!strlen(valueName), ("zero-length valueName arg"));
// get information on the value
result = RegQueryValueEx(keyHandle, valueName, 0, valueType, static_cast<LPBYTE>(dataPtr), &dwSize);
FATAL(result != ERROR_SUCCESS, ("failed to read registry value \"%s\", error = %ld\n", valueName, result));
// assume a query failure indicates the value was not found
if (valueDataSize)
*valueDataSize = static_cast<uint32>(dwSize);
}
// ----------------------------------------------------------------------
/**
* retrieve a string from of this key's values, returning a default string
* if the value doesn't exist.
*
* The defaultValue arg is required, must be non-null.
*
* If the specified value exists but is not of type REG_SZ, the default
* string will be returned.
*
* This routine will DEBUG_FATAL on null args, even if optional is set.
* Optional only controls whether a FATAL occurs if there is an issue
* retrieving the value.
*
* @param valueName [IN] name of the string value to retrieve
* @param defaultValue [IN] string to return if registry key does not contain thev value
* @param dest [OUT] buffer for returned string
* @param destSize [IN] max number of bytes (including terminating null) that can be placed in dest
* @param optional [IN] if set, the function will return false if there is a problem retrieving the value. otherwise, a DEBUG_FATAL will occur
*/
bool RegistryKey::getStringValue(const char *valueName, const char *defaultValue, char *dest, DWORD destSize, bool optional)
{
DEBUG_FATAL(!defaultValue, ("null defaultValue arg"));
DEBUG_FATAL(!dest, ("null dest arg"));
bool doesExist;
DWORD valueType;
DWORD valueSize;
// clear out string
memset(dest, 0, static_cast<size_t>(destSize));
// get info on the value
getValueInfo (valueName, &doesExist, &valueSize, &valueType);
if (!doesExist || (valueType != REG_SZ))
strncpy(dest, defaultValue, destSize-1);
else
{
// value exists and is a string, retrieve it
getValue (valueName, dest, destSize, &valueSize);
if (!valueSize)
{
FATAL(!optional, ("failed to get registry data for key %s\n", valueName));
return false;
}
// terminate the string
dest [valueSize] = 0;
}
return true;
}
// ----------------------------------------------------------------------
/**
* delete a value from this registry key.
*/
void RegistryKey::deleteValue(const char *valueName)
{
LONG result;
DEBUG_FATAL(!keyHandle, ("null keyHandle"));
DEBUG_FATAL(!valueName, ("null valueName arg"));
DEBUG_FATAL(!strlen(valueName), ("zero-length valueName arg"));
result = RegDeleteValue(keyHandle, valueName);
FATAL(result != ERROR_SUCCESS, ("failed to delete registry value \"%s\", error = %ld\n", valueName, result));
}
#if USE_REGISTRY_EXECUTION_STATISTICS
// ----------------------------------------------------------------------
/**
* updates beginning-of-execution statistics using the values under a
* given key.
*
* Call this function at the beginning of execution of the code
* for which statistics are desired. At the end of execution,
* call updateShutdownKey() to finish generating statistics.
* This function should only be called once per execution,
* and should be followed by a call to updateShutdownKey().
* If the latter is not called, the next call to updateStartupKey()
* will assume the application terminated abnormally before
* proper shutdown could occur.
*/
void RegistryKey::updateStartupKey(RegistryKey *key)
{
bool valueExist;
uint32 valueSize;
DWORD valueType;
DWORD execStartedCount = 0;
clock_t startTime = clock();
DEBUG_FATAL(!key, ("null key arg\n"));
// handle improper shutdown of last run
key->getValueInfo(STAT_TIME_START_VALUENAME, &valueExist);
if (valueExist)
{
// appears the product did not run to completion on last run.
// increment the incomplete run counts
DWORD execIncompleteCount = 0;
key->getValueInfo(STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, &valueExist);
if (valueExist)
{
key->getValue(STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, &execIncompleteCount, sizeof(DWORD), &valueSize, &valueType);
DEBUG_FATAL((valueType != REG_DWORD) || (valueSize != sizeof(DWORD)), ("%s key not DWORD type as expected\n", STAT_EXEC_INCOMPLETE_COUNT_VALUENAME));
}
++execIncompleteCount;
key->setValue(STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, &execIncompleteCount, sizeof(DWORD), REG_DWORD);
}
// get the start count
key->getValueInfo(STAT_EXEC_STARTED_COUNT_VALUENAME, &valueExist);
if (valueExist)
{
key->getValue(STAT_EXEC_STARTED_COUNT_VALUENAME, &execStartedCount, sizeof(DWORD), &valueSize, &valueType);
DEBUG_FATAL((valueType != REG_DWORD) || (valueSize != sizeof(DWORD)), ("%s key not DWORD type as expected\n", STAT_EXEC_STARTED_COUNT_VALUENAME));
}
++execStartedCount;
// save the data
key->setValue(STAT_EXEC_STARTED_COUNT_VALUENAME, &execStartedCount, sizeof(DWORD), REG_DWORD);
key->setValue(STAT_TIME_START_VALUENAME, &startTime, sizeof(clock_t));
}
#endif
#if USE_REGISTRY_EXECUTION_STATISTICS
// ----------------------------------------------------------------------
/**
* updates end-of-execution statistics using the values under a given key.
*
* This function should only be called after updateStartupKey()
* has been called on the same key. After this call returns,
* this function should not be called again until another
* call to updateStartupKey() is made.
*/
void RegistryKey::updateShutdownKey(RegistryKey *key)
{
bool valueExist;
uint32 valueSize;
DWORD valueType;
clock_t minTime;
clock_t maxTime;
clock_t averageTime = 0;
clock_t startTime;
clock_t stopTime = clock();
clock_t runTime;
DWORD startExecCount;
DWORD incompleteExecCount = 0;
DWORD completeExecCount;
real averageFraction;
DEBUG_FATAL(!key, ("null key arg\n"));
// find the number of complete execution runs of the product
key->getValue(STAT_EXEC_STARTED_COUNT_VALUENAME, &startExecCount, sizeof(DWORD), &valueSize, &valueType);
DEBUG_FATAL((valueSize != sizeof(DWORD)) || (valueType != REG_DWORD), ("invalid start count statistic registry value\n"));
key->getValueInfo(STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, &valueExist);
if (valueExist)
{
key->getValue(STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, &incompleteExecCount, sizeof(DWORD), &valueSize, &valueType);
DEBUG_FATAL((valueType != REG_DWORD) || (valueSize != sizeof(DWORD)), ("%s expected to be DWORD type, was %lu instead\n", STAT_EXEC_INCOMPLETE_COUNT_VALUENAME, valueType));
}
completeExecCount = startExecCount - incompleteExecCount;
// retrieve the start time
key->getValue(STAT_TIME_START_VALUENAME, &startTime, sizeof(clock_t), &valueSize, &valueType);
DEBUG_FATAL((valueSize != sizeof(clock_t)) || (valueType != REG_BINARY), ("invalid start time statistic registry value\n"));
// -qq- we don't handle clock wraparound
runTime = stopTime - startTime;
minTime = runTime;
maxTime = runTime;
// calculate average time
key->getValueInfo(STAT_TIME_AVERAGE_VALUENAME, &valueExist);
if (valueExist)
{
key->getValue(STAT_TIME_AVERAGE_VALUENAME, &averageTime, sizeof(clock_t), &valueSize, &valueType);
DEBUG_FATAL((valueSize != sizeof(clock_t)) || (valueType != REG_BINARY), ("invalid average exec time statistic registry value\n"));
}
averageFraction = CONST_REAL(1.0 / completeExecCount);
averageTime = static_cast<clock_t>(( CONST_REAL(averageTime) * (completeExecCount-1) + runTime) * averageFraction);
if (averageTime < 1)
averageTime = 1;
// check min exec time
key->getValueInfo(STAT_TIME_MIN_VALUENAME, &valueExist);
if (valueExist)
{
clock_t testValue;
key->getValue(STAT_TIME_MIN_VALUENAME, &testValue, sizeof(clock_t), &valueSize, &valueType);
DEBUG_FATAL((valueSize != sizeof(clock_t)) || (valueType != REG_BINARY), ("invalid min exec time statistic registry value\n"));
if (testValue < minTime)
minTime = testValue;
}
// check for max exec time
key->getValueInfo(STAT_TIME_MAX_VALUENAME, &valueExist);
if (valueExist)
{
clock_t testValue;
key->getValue(STAT_TIME_MAX_VALUENAME, &testValue, sizeof(clock_t), &valueSize, &valueType);
DEBUG_FATAL((valueSize != sizeof(clock_t)) || (valueType != REG_BINARY), ("invalid max exec time statistic registry value\n"));
if (testValue > maxTime)
maxTime = testValue;
}
// save the data
key->setValue(STAT_TIME_AVERAGE_VALUENAME, &averageTime, sizeof(clock_t));
key->setValue(STAT_TIME_MIN_VALUENAME, &minTime, sizeof(clock_t));
key->setValue(STAT_TIME_MAX_VALUENAME, &maxTime, sizeof(clock_t));
// delete the start time value
key->deleteValue(STAT_TIME_START_VALUENAME);
}
#endif
#if USE_REGISTRY_EXECUTION_STATISTICS
// ----------------------------------------------------------------------
/**
* An EnumValueCallback that prints each value name, type and size
*
* @param valueName name of value
* @param valueSize size of value in bytes
* @param valueTye type of value
*/
bool RegistryKey::enumValueInfoPrint(
void*, // unused user context
const char *valueName,
uint32 valueSize,
DWORD valueType
)
{
char *valueTypeStr;
char buffer[64];
switch (valueType)
{
case REG_BINARY:
valueTypeStr = "REG_BINARY";
break;
case REG_DWORD:
valueTypeStr = "REG_DWORD [little endian]";
break;
case REG_DWORD_BIG_ENDIAN:
valueTypeStr = "REG_DWORD_BIG_ENDIAN";
break;
case REG_EXPAND_SZ:
valueTypeStr = "REG_EXPAND_SZ";
break;
case REG_NONE:
valueTypeStr = "REG_NONE";
break;
case REG_SZ:
valueTypeStr = "REG_SZ";
break;
default:
valueTypeStr = buffer;
sprintf(buffer, "<TYPE %lu>", valueType);
break;
}
DEBUG_PRINT_LOG(true, (" Key: \"%s\", %s, %u bytes\n", valueName, valueTypeStr, valueSize));
// continue enumerating
return true;
}
#endif
#if USE_REGISTRY_EXECUTION_STATISTICS
// ----------------------------------------------------------------------
/**
* Update per-startup registry values.
*
* This routine is used primarily to test registry read/write
* functionality; however, it does provide statistics related
* to game usage. These include the following statistics on
* a per-game and per-machine basis:
* # times product was executed
* average real-time duration of execution
* minimum execution time
* maximum execution time
* # times product failed to execute to completion
* (i.e. updateRegistryShutdown() never executed---hard crash, stop debugging)
*/
void RegistryKey::updateStartupStatistics(void)
{
DEBUG_FATAL(!productUserKey, ("null productUserKey\n"));
DEBUG_FATAL(!productMachineKey, ("null productMachineKey\n"));
// create required keys
RegistryKey *userStatKey = productUserKey->createSubkey(STATISTICS_KEYNAME);
RegistryKey *machineStatKey = productMachineKey->createSubkey(STATISTICS_KEYNAME);
FATAL(!userStatKey, ("failed to create user statistics key"));
FATAL(!machineStatKey, ("failed to create machine statistics key"));
// handle machine stat key
#if 1
// print existing machine stat keys
DEBUG_PRINT_LOG(true, ("BEGIN machine stat key enumeration:\n"));
machineStatKey->enumerateValues(0, enumValueInfoPrint);
DEBUG_PRINT_LOG(true, ("END machine stat key enumeration:\n"));
#endif
updateStartupKey(machineStatKey);
// handle user stat key
#if 1
// print existing user stat keys
DEBUG_PRINT_LOG(true, ("BEGIN user stat key enumeration:\n"));
userStatKey->enumerateValues(0, enumValueInfoPrint);
DEBUG_PRINT_LOG(true, ("END user stat key enumeration:\n"));
#endif
updateStartupKey(userStatKey);
// cleanup
delete machineStatKey;
delete userStatKey;
}
#endif
#if USE_REGISTRY_EXECUTION_STATISTICS
// ----------------------------------------------------------------------
/**
* Update per-shutdown registry values.
*
* @see updateRegistryStartup()
*/
void RegistryKey::updateShutdownStatistics(void)
{
DEBUG_FATAL(!productUserKey, ("null productUserKey\n"));
DEBUG_FATAL(!productMachineKey, ("null productMachineKey\n"));
// create required keys
RegistryKey *userStatKey = productUserKey->createSubkey(STATISTICS_KEYNAME);
RegistryKey *machineStatKey = productMachineKey->createSubkey(STATISTICS_KEYNAME);
FATAL(!userStatKey, ("failed to create user statistics key"));
FATAL(!machineStatKey, ("failed to create machine statistics key"));
// handle machine stat key
updateShutdownKey(machineStatKey);
// handle user stat key
updateShutdownKey(userStatKey);
// cleanup
delete machineStatKey;
delete userStatKey;
}
#endif
// ----------------------------------------------------------------------
/**
* install the RegistryKey class.
*
* After installation, the following predefined keys are available:
*
* usersKey: HKEY_USERS
* currentUserKey: HKEY_CURRENT_USER
* classRootKey: HKEY_CLASSES_ROOT
* localMachineKey: HKEY_LOCAL_MACHINE
* productUserKey: HKEY_CURENT_USER\<product relative registry path>
* productMachineKey: HKEY_LOCAL_MACHINE\<product relative registry path>
*
* The client is free to create any other keys required.
*
* The product relative registry path is determined by the first of the
* following methods that succeed:
* 1. If the config file key "ProductRegistryPath" is set, that value is
* used for the relative path. If the product relative path is set
* in this manner, the client's attempt to change the product relative
* path via the setProductKey() function will silently fail.
* 2. If the productKeyRelativePath parameter is a non-null positive length
* string, that value is used as the product keys' relative path.
* 3. The default value DEFAULT_PRODUCT_REGISTRY_PATH ("Software\\Bootprint\\Default")
* is used.
*
* RegistryKey::remove() is added to the exit chain.
*
* Do not delete any of the predefined registry keys.
*
* @param productKeyRelativePath [IN] relative registry path for the product keys
* @see setProductKeyPath()
*/
void RegistryKey::install(const char *productKeyRelativePath)
{
UNREF(productKeyRelativePath);
char *useRegistryPath = 0;
DEBUG_FATAL(installed, ("attempted to install RegistryKey when already installed\n"));
installed = true;
// add to exit chain
ExitChain::add(remove, "RegistryKey::remove", 0, true);
// if no passed in value, use the default
setProductKeyPathFromConfig = false;
useRegistryPath = DuplicateString(DEFAULT_PRODUCT_REGISTRY_PATH);
// create the Windows-defined RegistryKeys (these keys don't get closed at object destruction time)
usersKey = new RegistryKey(HKEY_USERS, false); //lint !e1924 // Note -- C-style cast
currentUserKey = new RegistryKey(HKEY_CURRENT_USER, false); //lint !e1924 // Note -- C-style cast
classRootKey = new RegistryKey(HKEY_CLASSES_ROOT, false); //lint !e1924 // Note -- C-style cast
localMachineKey = new RegistryKey(HKEY_LOCAL_MACHINE, false); //lint !e1924 // Note -- C-style cast
// check for errors --- unnecessary if new cannot return NULL
FATAL(
!usersKey || !currentUserKey || !classRootKey || !localMachineKey,
("failed to create standard RegistryKey objects"));
// create/open the product user key
productUserKey = currentUserKey->createSubkey(useRegistryPath, AF_READ | AF_WRITE);
// create/open the product machine key
productMachineKey = localMachineKey->createSubkey(useRegistryPath, AF_READ);
delete [] useRegistryPath;
#if USE_REGISTRY_EXECUTION_STATISTICS
updateStartupStatistics();
#endif
}
// ----------------------------------------------------------------------
/**
* release all resources and state associated with the RegistryKey system.
*
* It is invalid to call any RegistryKey functions other than install()
* after calling remove().
*/
void RegistryKey::remove(void)
{
#if USE_REGISTRY_EXECUTION_STATISTICS
updateShutdownStatistics();
#endif
DEBUG_FATAL(!installed, ("attempted to remove RegistryKey when not installed\n"));
installed = false;
delete productMachineKey;
delete productUserKey;
delete localMachineKey;
delete classRootKey;
delete currentUserKey;
delete usersKey;
productMachineKey = 0;
productUserKey = 0;
localMachineKey = 0;
classRootKey = 0;
currentUserKey = 0;
usersKey = 0;
}
// ----------------------------------------------------------------------
/**
* reset the path to the product's machine and user keys.
*
* This routine will redefine the following keys:
* productUserKey: HKEY_CURENT_USER\<productKeyRelativePath>
* productMachineKey: HKEY_LOCAL_MACHINE\<productKeyRelativePath>
*
* If the product key relative paths were specified in the config
* file, this routine will essentially do nothing --- the client
* is not able to ovveride the config file settings.
*/
void RegistryKey::setProductKeyPath(const char *productKeyRelativePath)
{
DEBUG_FATAL(
!productKeyRelativePath || !productKeyRelativePath[0],
("invalid productKeyRelativePath arg\n"));
// don't allow client to overwrite if path set by config file
if (setProductKeyPathFromConfig)
{
DEBUG_REPORT_LOG_PRINT(true, ("attempted to set product registry key path to '%s' but config file setting will override\n", productKeyRelativePath));
return;
}
delete productUserKey;
delete productMachineKey;
productUserKey = currentUserKey->createSubkey(productKeyRelativePath, AF_READ | AF_WRITE);
productMachineKey = localMachineKey->createSubkey(productKeyRelativePath, AF_READ | AF_WRITE);
}
// ======================================================================
@@ -1,270 +0,0 @@
#ifndef REGISTRY_KEY_H
#define REGISTRY_KEY_H
// ======================================================================
//
// RegistryKey.h
// Todd Fiala
//
// copyright 1998 Bootprint Entertainment
//
// ======================================================================
// provide read and write access to the Windows Registry
//
// Remarks:
//
// Each RegistryKey can create or open a subkey relative to that
// key. This process produces another RegistryKey. RegistryKeys
// provide a mechanism to enumerate all the child subkeys and values
// associated with the key. In addition, clients may query for
// the presence, type and size of a specific value, get a specific
// value's data, and set a named value's data and type.
//
// The RegistryKey class provides the client with six RegistryKey
// objects as starting points into the registry. See documentation
// for install() for more info on these starting points.
//
// The client must install() the RegistryKey class before using it.
class RegistryKey
{
public:
// ----------------------------------------------------------------------
// flags used to indicate what type of access (e.g. read, write) should
// be granted when creating or opening a key.
//
// See Also:
//
// createSubkey(), openSubkey()
enum // AccessFlags
{
AF_READ = BINARY1(0001), // query values, enumerate subkeys
AF_WRITE = BINARY1(0010) // set values, create subkeys
};
// ----------------------------------------------------------------------
// callback prototype for subkey enumeration
//
// Return Value:
//
// A return value of true indicates the enumeration of subkeys should
// continue. A return value of false stops further enumeration of
// subkeys.
//
// Remarks:
//
// The context parameter is specified in the call to
// enumerateSubkeys(). One use for this could be to pass a class
// instance, with the callack defined as a static member function.
// The function can then cast the context to a pointer to class
// instance, allowing the static function to access per-instance
// data explicitly in place of an assumed this pointer.
//
// See Also:
//
// enumerateSubkeys()
typedef bool (*EnumerateKeyCallback)(
void *context, // [IN] user-specified context variable
const char *keyName, // [IN] name of the key being enumerated
const FILETIME *lastWriteTime // [IN] last time this key was modified
);
// ----------------------------------------------------------------------
// callback prototype for value enumeration
//
// Return Value:
//
// A return value of true indicates the enumeration of values should
// continue. A return value of false stops further enumeration of
// values .
//
// Remarks:
//
// The context parameter is specified in the call to
// enumerateValues(). One use for this could be to pass a class
// instance, with the callack defined as a static member function.
// The function can then cast the context to a pointer to class
// instance, allowing the static function to access per-instance
// data explicitly in place of an assumed this pointer.
//
// See Also:
//
// enumerateValues()
typedef bool (*EnumerateValueCallback)(
void *context, // [IN] user-specified context variable
const char *valueName, // [IN] name of the value being enumerated
uint32 valueSize, // [IN] number of bytes occupied by this value's data
DWORD valueType // [IN] type of value (one of REG_* as in RegSetValueEx documentation)
);
private:
static const char * const PRODUCT_REGISTRY_PATH_KEYNAME;
static const char * const DEFAULT_PRODUCT_REGISTRY_PATH;
#if USE_REGISTRY_EXECUTION_STATISTICS
static const char * const STATISTICS_KEYNAME;
static const char * const STAT_EXEC_STARTED_COUNT_VALUENAME;
static const char * const STAT_EXEC_INCOMPLETE_COUNT_VALUENAME;
static const char * const STAT_TIME_AVERAGE_VALUENAME;
static const char * const STAT_TIME_MIN_VALUENAME;
static const char * const STAT_TIME_MAX_VALUENAME;
static const char * const STAT_TIME_START_VALUENAME;
#endif
static bool installed;
static bool setProductKeyPathFromConfig;
// private instance member variables
HKEY keyHandle;
bool closeKeyOnDestroy;
private:
// public member variables
static RegistryKey *usersKey;
static RegistryKey *currentUserKey;
static RegistryKey *classRootKey;
static RegistryKey *localMachineKey;
static RegistryKey *productUserKey;
static RegistryKey *productMachineKey;
private:
// private member functions
static void remove(void);
RegistryKey(HKEY newKeyHandle, bool newCloseKeyOnDestroy);
#if USE_REGISTRY_EXECUTION_STATISTICS
static void updateStartupKey(RegistryKey *key);
static void updateShutdownKey(RegistryKey *key);
static bool enumValueInfoPrint(void *context, const char *valueName, uint32 valueSize, DWORD valueType);
static void updateStartupStatistics(void);
static void updateShutdownStatistics(void);
#endif
private:
// disable: default constructor, copy constructor, assignment operator
// NOTE: last two can be implemented, but must be specially handled
RegistryKey(void);
RegistryKey(const RegistryKey&);
RegistryKey &operator =(const RegistryKey&);
public:
// public member functions
static void install(const char *productKeyRelativePath = 0);
static void setProductKeyPath(const char *productKeyRelativePath);
// pre-defined RegistryKey retrieval
static RegistryKey *getUsersKey(void);
static RegistryKey *getCurrentUserKey(void);
static RegistryKey *getClassRootKey(void);
static RegistryKey *getLocalMachineKey(void);
static RegistryKey *getProductUserKey(void);
static RegistryKey *getProductMachineKey(void);
~RegistryKey(void);
// subkey interface
void enumerateSubkeys(void *context, EnumerateKeyCallback callback) const;
RegistryKey *openSubkey(const char *subkeyName, uint32 accessFlags = AF_READ) const;
RegistryKey *createSubkey(const char *subkeyName, uint32 accessFlags = AF_READ | AF_WRITE) const;
void deleteSubkey(const char *subkeyName);
bool subKeyExists(const char *subkeyName);
// value interface
void enumerateValues(void *context, EnumerateValueCallback callback) const;
void setValue(const char *valueName, const void *dataPtr, uint32 dataSize, DWORD valueType = REG_BINARY);
void deleteValue(const char *valueName);
void getValueInfo(const char *valueName, bool *doesExist, uint32 *valueSize = 0, DWORD *valueType = 0) const;
void getValue(const char *valueName, void *dataPtr, uint32 maxDataSize, uint32 *valueDataSize, DWORD *valueType = 0) const;
bool getStringValue(const char *valueName, const char *defaultValue, char *dest, DWORD destSize, bool optional = false);
};
// ======================================================================
// retrieve a key to the HKEY_USERS registry key with read access
inline RegistryKey *RegistryKey::getUsersKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return usersKey;
}
// ----------------------------------------------------------------------
/**
* retrieve a key to the HKEY_CURRENT_USER registry key with read/write
* access.
*/
inline RegistryKey *RegistryKey::getCurrentUserKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return currentUserKey;
}
// ----------------------------------------------------------------------
/**
* retrieve a key to the HKEY_CLASSES_ROOT registry key with read/write
* access.
*/
inline RegistryKey *RegistryKey::getClassRootKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return classRootKey;
}
// ----------------------------------------------------------------------
/**
* retrieve a key to the HKEY_LOCAL_MACHINE registry key with read/write
* access.
*/
inline RegistryKey *RegistryKey::getLocalMachineKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return localMachineKey;
}
// ----------------------------------------------------------------------
/**
* retrieve a key to the product's user key with read/write access.
*
* The product user key is the root key for storing user-specific
* product-related information. install() describes where this
* information exists in the registry.
*
* @see install(), getProductMachineKey()
*/
inline RegistryKey *RegistryKey::getProductUserKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return productUserKey;
}
// ----------------------------------------------------------------------
/**
* retrieve a key to the product's machine key with read/write access.
*
* The product machine key is the root key for storing machine-specific
* product-related information. install() describes where this
* information exists in the registry.
*
* @see install(), getProductUserKey()
*/
inline RegistryKey *RegistryKey::getProductMachineKey(void)
{
DEBUG_FATAL(!installed, ("Attempted to use RegistryKey when not installed\n"));
return productMachineKey;
}
// ======================================================================
#endif
@@ -1,410 +0,0 @@
// ======================================================================
//
// SetupSharedFoundation.cpp
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#include "sharedFoundation/FirstSharedFoundation.h"
#include "sharedFoundation/SetupSharedFoundation.h"
#include "sharedDebug/DebugMonitor.h"
#include "sharedDebug/InstallTimer.h"
#include "sharedDebug/Profiler.h"
#include "sharedFoundation/ApplicationVersion.h"
#include "sharedFoundation/Clock.h"
#include "sharedFoundation/CommandLine.h"
#include "sharedFoundation/ConfigFile.h"
#include "sharedFoundation/ConfigSharedFoundation.h"
#include "sharedFoundation/CrashReportInformation.h"
#include "sharedFoundation/CrcLowerString.h"
#include "sharedFoundation/ExitChain.h"
#include "sharedFoundation/Os.h"
#include "sharedFoundation/Production.h"
#include "sharedFoundation/RegistryKey.h"
#include "sharedFoundation/StaticCallbackEntry.h"
#include "sharedFoundation/MemoryBlockManager.h"
#include "sharedFoundation/Watcher.h"
#include "sharedLog/TailFileLogObserver.h"
#include <eh.h>
#include <cstdio>
// ======================================================================
namespace FatalNamespace
{
extern char ms_buffer[32 * 1024];
}
namespace SetupSharedFoundationNamespace
{
LONG __stdcall MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS exceptionPointers);
bool ms_writeMiniDumps;
}
using namespace SetupSharedFoundationNamespace;
// ======================================================================
LONG __stdcall SetupSharedFoundationNamespace::MyUnhandledExceptionFilter(LPEXCEPTION_POINTERS exceptionPointers)
{
// make the routine somewhat safe from re-entrance
static bool entered = false;
if (entered)
return EXCEPTION_CONTINUE_SEARCH;
entered = true;
// log some important information
static char buffer[128];
sprintf(buffer, "Exception %08x(%d)=code %08x=addr\n", exceptionPointers->ExceptionRecord->ExceptionCode, exceptionPointers->ExceptionRecord->ExceptionCode, exceptionPointers->ExceptionRecord->ExceptionAddress);
OutputDebugString(buffer);
// write the minidump if we're in here for the first time
static bool ms_alreadyWroteMiniDump = false;
if (ms_writeMiniDumps && !ms_alreadyWroteMiniDump)
{
ms_alreadyWroteMiniDump = true;
uint64 timestamp;
time_t now;
tm t;
IGNORE_RETURN(time(&now));
IGNORE_RETURN(gmtime_r(&now, &t));
timestamp = t.tm_year+1900; //lint !e732 !e737 !e776
timestamp *= 100;
timestamp += t.tm_mon+1; //lint !e737 !e776
timestamp *= 100;
timestamp += static_cast<unsigned int>(t.tm_mday);
timestamp *= 100;
timestamp += static_cast<unsigned int>(t.tm_hour);
timestamp *= 100;
timestamp += static_cast<unsigned int>(t.tm_min);
timestamp *= 100;
timestamp += static_cast<unsigned int>(t.tm_sec);
static char fileName[512];
sprintf(fileName, "%s-%s-%I64d.txt", Os::getShortProgramName(), ApplicationVersion::getInternalVersion(), timestamp);
HANDLE const file = CreateFile(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (file != INVALID_HANDLE_VALUE)
{
char text1[] = "automated crash dump from ";
DWORD bytesWritten;
WriteFile(file, text1, strlen(text1), &bytesWritten, NULL);
char const * text2 = Os::getShortProgramName();
WriteFile(file, text2, strlen(text2), &bytesWritten, NULL);
char text3[] = " ";
WriteFile(file, text3, strlen(text3), &bytesWritten, NULL);
char const * text4 = ApplicationVersion::getInternalVersion();
WriteFile(file, text4, strlen(text4), &bytesWritten, NULL);
char text5[] = "\n\n\n";
WriteFile(file, text5, strlen(text5), &bytesWritten, NULL);
if (exceptionPointers->ExceptionRecord->ExceptionCode == 0x80000003)
{
// write out the fatal buffer
char const * text6 = FatalNamespace::ms_buffer;
WriteFile(file, text6, strlen(text6), &bytesWritten, NULL);
}
else
{
char const * text6 = buffer;
WriteFile(file, text6, strlen(text6), &bytesWritten, NULL);
}
char text7[] = "\n\n";
WriteFile(file, text7, strlen(text7), &bytesWritten, NULL);
char const * text8 = "";
for (int i = 0; text8; ++i)
{
text8 = CrashReportInformation::getEntry(i);
if (text8)
{
int const text8Length = strlen(text8);
if (text8Length)
WriteFile(file, text8, text8Length, &bytesWritten, NULL);
}
}
CloseHandle(file);
}
sprintf(fileName, "%s-%s-%I64d.mdmp", Os::getShortProgramName(), ApplicationVersion::getInternalVersion(), timestamp);
OutputDebugString("Generating minidump ");
OutputDebugString(fileName);
OutputDebugString("\n");
DebugHelp::writeMiniDump(fileName, exceptionPointers);
sprintf(fileName, "%s-%s-%I64d.log", Os::getShortProgramName(), ApplicationVersion::getInternalVersion(), timestamp);
TailFileLogObserver::flushAllTailFileLogObservers(fileName);
}
// tell the Os not to abort so we can rethrow the exception
Os::returnFromAbort();
// Let the ExitChain do its job
Fatal("ExceptionHandler invoked");
// rethrow the exception so that the debugger can catch it
entered = false;
return EXCEPTION_CONTINUE_SEARCH; //lint !e527 // Unreachable
}
// ----------------------------------------------------------------------
static void setFatalVersionString()
{
char buffer[256];
sprintf(buffer, "%s: %s\n", Os::getShortProgramName(), ApplicationVersion::getInternalVersion());
FatalSetVersionString(buffer);
}
// ======================================================================
// Install the engine
//
// Remarks:
//
// The settings in the Data structure will determine which subsystems
// get initialized.
void SetupSharedFoundation::install(const Data &data)
{
InstallTimer const installTimer("SetupSharedFoundation::install");
DEBUG_REPORT_LOG(true, ("SetupSharedFoundation::install: version %s\n", ApplicationVersion::getInternalVersion()));
ms_writeMiniDumps = data.writeMiniDumps;
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
// and get the command line stuff in quick so we can make decisions based on the command line settings
CommandLine::install();
// feed CommandLine with appropriate strings
if (data.commandLine)
CommandLine::absorbString(data.commandLine);
if (data.argc)
CommandLine::absorbStrings(const_cast<const char**>(data.argv+1), data.argc-1);
// load the config file
ConfigFile::install();
if (data.configFile)
IGNORE_RETURN(ConfigFile::loadFile(data.configFile));
// get the post command-line text for the ConfigFile (key-value pairs)
const char *configString = CommandLine::getPostCommandLineString();
if (configString)
{
IGNORE_RETURN(ConfigFile::loadFromCommandLine(configString));
}
// @todo codereorg should this be here?
MemoryManager::registerDebugFlags();
#if PRODUCTION == 0
Profiler::registerDebugFlags();
#endif
FatalInstall();
// @todo move these, it's part of sharedDebug. However, sharedDebug is installed before sharedFoundation, but these need the ConfigFile. ugh.
#if PRODUCTION == 0
DebugMonitor::install();
#endif
SetWarningStrictFatal(ConfigFile::getKeyBool("SharedDebug", "strict", false));
{
ConfigSharedFoundation::Defaults defaults;
defaults.frameRateLimit = data.frameRateLimit;
defaults.demoMode = data.demoMode;
defaults.verboseWarnings = data.verboseWarnings;
ConfigSharedFoundation::install(defaults);
if (ConfigSharedFoundation::getCauseAccessViolation())
static_cast<int*>(0)[0] = 0;
}
// @todo codereorg should this be here?
#ifdef _DEBUG
MemoryManager::setReportAllocations (ConfigSharedFoundation::getMemoryManagerReportAllocations ());
#endif
MemoryBlockManager::install (ConfigSharedFoundation::getMemoryBlockManagerDebugDumpOnRemove ());
ExitChain::install();
Report::install();
Clock::install(data.clockUsesSleep, data.clockUsesRecalibrationThread);
CrashReportInformation::install();
RegistryKey::install(data.productRegistryKey);
PersistentCrcString::install();
CrcLowerString::install();
WatchedByList::install();
if (data.createWindow)
{
DEBUG_FATAL(data.useWindowHandle, ("exactly one of createWindow and useWindowHandle must be true"));
Os::install(data.hInstance, data.windowName, data.windowNormalIcon, data.windowSmallIcon);
}
else
{
if (data.useWindowHandle)
Os::install(data.windowHandle, data.processMessagePump);
else
Os::install();
}
StaticCallbackEntry::install();
setFatalVersionString();
}
// ----------------------------------------------------------------------
// Call a function with appropriate exception handling
//
// Remarks:
//
// If exception handling has been disabled in the config file, this routine
// will call the callback without exception handling.
void SetupSharedFoundation::callbackWithExceptionHandling(
void (*callback)(void) // Routine to call with exception handling
)
{
callback();
}
// ----------------------------------------------------------------------
// Uninstall the engine
//
// Remarks:
//
// This routine will properly uninstall the engine componenets that were
// installed by SetupSharedFoundation::install().
void SetupSharedFoundation::remove(void)
{
ExitChain::quit();
if (!ConfigSharedFoundation::getDemoMode() && GetNumberOfWarnings())
REPORT(true, Report::RF_print | Report::RF_log | Report::RF_dialog, ("%d warnings logged", GetNumberOfWarnings()));
}
// ======================================================================
SetupSharedFoundation::Data::Data(Defaults defaults)
{
Zero(*this);
switch (defaults)
{
case D_console: setupConsoleDefaults(); break;
case D_game: setupGameDefaults(); break;
case D_mfc: setupMfcDefaults(); break;
default: DEBUG_FATAL(true, ("invalid enum value"));
}
}
// ----------------------------------------------------------------------
void SetupSharedFoundation::Data::setupGameDefaults()
{
createWindow = true;
windowName = NULL;
windowNormalIcon = NULL;
windowSmallIcon = NULL;
hInstance = NULL;
useWindowHandle = false;
processMessagePump = true;
windowHandle = NULL;
clockUsesSleep = false;
clockUsesRecalibrationThread = true;
writeMiniDumps = false;
commandLine = NULL;
argc = 0;
argv = NULL;
configFile = NULL;
productRegistryKey = NULL;
frameRateLimit = CONST_REAL(0);
lostFocusCallback = NULL;
demoMode = false;
verboseWarnings = false;
}
// ----------------------------------------------------------------------
void SetupSharedFoundation::Data::setupConsoleDefaults()
{
createWindow = false;
windowName = NULL;
windowNormalIcon = NULL;
windowSmallIcon = NULL;
hInstance = NULL;
useWindowHandle = false;
processMessagePump = true;
windowHandle = NULL;
clockUsesSleep = false;
clockUsesRecalibrationThread = false;
writeMiniDumps = false;
commandLine = NULL;
argc = NULL;
argv = NULL;
configFile = NULL;
productRegistryKey = NULL;
frameRateLimit = CONST_REAL(0);
lostFocusCallback = NULL;
demoMode = false;
verboseWarnings = false;
}
// ----------------------------------------------------------------------
void SetupSharedFoundation::Data::setupMfcDefaults()
{
createWindow = false;
windowName = NULL;
windowNormalIcon = NULL;
windowSmallIcon = NULL;
hInstance = NULL;
useWindowHandle = false;
processMessagePump = true;
windowHandle = NULL;
clockUsesSleep = false;
clockUsesRecalibrationThread = false;
writeMiniDumps = false;
commandLine = NULL;
argc = 0;
argv = NULL;
configFile = NULL;
productRegistryKey = NULL;
frameRateLimit = CONST_REAL(0);
demoMode = false;
verboseWarnings = false;
}
// ======================================================================
@@ -1,99 +0,0 @@
// ======================================================================
//
// SetupSharedFoundation.h
// copyright 1998 Bootprint Entertainment
// copyright 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_SetupSharedFoundation_H
#define INCLUDED_SetupSharedFoundation_H
// ======================================================================
class SetupSharedFoundation
{
public:
struct Data
{
typedef void (*LostFocusCallbackFuction)();
// window creation stuff
bool createWindow;
const char *windowName;
HICON windowNormalIcon;
HICON windowSmallIcon;
HINSTANCE hInstance;
// window use stuff
bool useWindowHandle;
bool processMessagePump;
HWND windowHandle;
bool writeMiniDumps;
bool clockUsesSleep;
bool clockUsesRecalibrationThread;
// pointer to command line
const char *commandLine;
int argc;
char **argv;
// name of the config file to lead
const char *configFile;
// registry stuff
const char *productRegistryKey;
real frameRateLimit;
bool demoMode;
bool verboseWarnings;
LostFocusCallbackFuction lostFocusCallback;
public:
enum Defaults
{
D_console,
D_game,
D_mfc
};
Data(Defaults defaults);
private:
Data();
void setupGameDefaults();
void setupConsoleDefaults();
void setupMfcDefaults();
};
public:
typedef void (*MainFunction)();
public:
static void install(const Data &data);
static void remove(void);
static void callbackWithExceptionHandling(MainFunction mainFunction);
private:
SetupSharedFoundation();
SetupSharedFoundation(const SetupSharedFoundation &);
SetupSharedFoundation &operator =(const SetupSharedFoundation &);
};
// ======================================================================
#endif
@@ -1,51 +0,0 @@
// ======================================================================
//
// WindowsWrapper.h
// copyright (c) 1998 Bootprint Entertainment
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_WindowsWrapper_H
#define INCLUDED_WindowsWrapper_H
// ======================================================================
// C4201 nonstandard extension used : nameless struct/union
#pragma warning(disable: 4201)
// make windows.h more strict in the types of handles
#ifndef STRICT
#define STRICT 1
#endif
// trim down the amount of stuff windows.h includes
#define NOGDICAPMASKS
#define NOVIRTUALKEYCODE
#define NOKEYSTATES
#define NORASTEROPS
#define NOATOM
#define NOCOLOR
#define NODRAWTEXT
#define NOMEMMGR
#define NOMETAFILE
#define NOMINMAX
#define NOOPENFILE
#define NOSERVICE
#define NOSOUND
#define NOCOMM
#define NOHELP
#define NOPROFILER
#define NODEFERWINDOWPOS
#define NOMCX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wtypes.h>
// reenable warnings disables for windows.h
#pragma warning(default: 4201)
// ======================================================================
#endif