mirror of
https://github.com/SWG-Source/src.git
synced 2026-10-02 19:13:07 -04:00
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:
@@ -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
|
||||
Reference in New Issue
Block a user