1721 lines
36 KiB
C++
1721 lines
36 KiB
C++
/***************************************************************************
|
|
*
|
|
* Copyright (C) 2001 Microsoft Corporation. All Rights Reserved.
|
|
*
|
|
* File: controlobj.cpp
|
|
*
|
|
* Content: DP8SIM control interface wrapper object class.
|
|
*
|
|
* History:
|
|
* Date By Reason
|
|
* ======== ======== =========
|
|
* 04/24/01 VanceO Created.
|
|
*
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
#include "dp8simi.h"
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::CDP8SimControl"
|
|
//=============================================================================
|
|
// CDP8SimControl constructor
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Initializes the new CDP8SimControl object.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: None (the object).
|
|
//=============================================================================
|
|
CDP8SimControl::CDP8SimControl(void)
|
|
{
|
|
this->m_blList.Initialize();
|
|
|
|
|
|
this->m_Sig[0] = 'D';
|
|
this->m_Sig[1] = 'P';
|
|
this->m_Sig[2] = '8';
|
|
this->m_Sig[3] = 'S';
|
|
|
|
this->m_lRefCount = 1; // someone must have a pointer to this object
|
|
this->m_dwFlags = 0;
|
|
} // CDP8SimControl::CDP8SimControl
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::~CDP8SimControl"
|
|
//=============================================================================
|
|
// CDP8SimControl destructor
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Frees the CDP8SimControl object.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: None.
|
|
//=============================================================================
|
|
CDP8SimControl::~CDP8SimControl(void)
|
|
{
|
|
DNASSERT(this->m_blList.IsEmpty());
|
|
|
|
|
|
DNASSERT(this->m_lRefCount == 0);
|
|
DNASSERT(this->m_dwFlags == 0);
|
|
|
|
//
|
|
// For grins, change the signature before deleting the object.
|
|
//
|
|
this->m_Sig[3] = 's';
|
|
} // CDP8SimControl::~CDP8SimControl
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::QueryInterface"
|
|
//=============================================================================
|
|
// CDP8SimControl::QueryInterface
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Retrieves a new reference for an interfaces supported by this
|
|
// CDP8SimControl object.
|
|
//
|
|
// Arguments:
|
|
// REFIID riid - Reference to interface ID GUID.
|
|
// LPVOID * ppvObj - Place to store pointer to object.
|
|
//
|
|
// Returns: HRESULT
|
|
// S_OK - Returning a valid interface pointer.
|
|
// DPNHERR_INVALIDOBJECT - The interface object is invalid.
|
|
// DPNHERR_INVALIDPOINTER - The destination pointer is invalid.
|
|
// E_NOINTERFACE - Invalid interface was specified.
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::QueryInterface(REFIID riid, LPVOID * ppvObj)
|
|
{
|
|
HRESULT hr = DPN_OK;
|
|
|
|
|
|
DPFX(DPFPREP, 3, "(0x%p) Parameters: (REFIID, 0x%p)", this, ppvObj);
|
|
|
|
|
|
//
|
|
// Validate the object.
|
|
//
|
|
if (! this->IsValidObject())
|
|
{
|
|
DPFX(DPFPREP, 0, "Invalid DP8SimControl object!");
|
|
hr = DPNERR_INVALIDOBJECT;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Validate the parameters.
|
|
//
|
|
|
|
if ((! IsEqualIID(riid, IID_IUnknown)) &&
|
|
(! IsEqualIID(riid, IID_IDP8SimControl)))
|
|
{
|
|
DPFX(DPFPREP, 0, "Unsupported interface!");
|
|
hr = E_NOINTERFACE;
|
|
goto Failure;
|
|
}
|
|
|
|
if ((ppvObj == NULL) ||
|
|
(IsBadWritePtr(ppvObj, sizeof(void*))))
|
|
{
|
|
DPFX(DPFPREP, 0, "Invalid interface pointer specified!");
|
|
hr = DPNERR_INVALIDPOINTER;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Add a reference, and return the interface pointer (which is actually
|
|
// just the object pointer, they line up because CDP8SimControl inherits
|
|
// from the interface declaration).
|
|
//
|
|
this->AddRef();
|
|
(*ppvObj) = this;
|
|
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 3, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
goto Exit;
|
|
} // CDP8SimControl::QueryInterface
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::AddRef"
|
|
//=============================================================================
|
|
// CDP8SimControl::AddRef
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Adds a reference to this CDP8SimControl object.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: New refcount.
|
|
//=============================================================================
|
|
STDMETHODIMP_(ULONG) CDP8SimControl::AddRef(void)
|
|
{
|
|
LONG lRefCount;
|
|
|
|
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// There must be at least 1 reference to this object, since someone is
|
|
// calling AddRef.
|
|
//
|
|
DNASSERT(this->m_lRefCount > 0);
|
|
|
|
lRefCount = InterlockedIncrement(&this->m_lRefCount);
|
|
|
|
DPFX(DPFPREP, 3, "[0x%p] RefCount [0x%lx]", this, lRefCount);
|
|
|
|
return lRefCount;
|
|
} // CDP8SimControl::AddRef
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::Release"
|
|
//=============================================================================
|
|
// CDP8SimControl::Release
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Removes a reference to this CDP8SimControl object. When the
|
|
// refcount reaches 0, this object is destroyed.
|
|
// You must NULL out your pointer to this object after calling
|
|
// this function.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: New refcount.
|
|
//=============================================================================
|
|
STDMETHODIMP_(ULONG) CDP8SimControl::Release(void)
|
|
{
|
|
LONG lRefCount;
|
|
|
|
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
//
|
|
// There must be at least 1 reference to this object, since someone is
|
|
// calling Release.
|
|
//
|
|
DNASSERT(this->m_lRefCount > 0);
|
|
|
|
lRefCount = InterlockedDecrement(&this->m_lRefCount);
|
|
|
|
//
|
|
// Was that the last reference? If so, we're going to destroy this object.
|
|
//
|
|
if (lRefCount == 0)
|
|
{
|
|
DPFX(DPFPREP, 3, "[0x%p] RefCount hit 0, destroying object.", this);
|
|
|
|
//
|
|
// First pull it off the global list.
|
|
//
|
|
DNEnterCriticalSection(&g_csGlobalsLock);
|
|
|
|
this->m_blList.RemoveFromList();
|
|
|
|
DNASSERT(g_lOutstandingInterfaceCount > 0);
|
|
g_lOutstandingInterfaceCount--; // update count so DLL can unload now works correctly
|
|
|
|
DNLeaveCriticalSection(&g_csGlobalsLock);
|
|
|
|
|
|
//
|
|
// Make sure it's closed.
|
|
//
|
|
if (this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED)
|
|
{
|
|
//
|
|
// Assert so that the user can fix his/her broken code!
|
|
//
|
|
DNASSERT(! "DP8SimControl object being released without calling Close first!");
|
|
|
|
//
|
|
// Then go ahead and do the right thing. Ignore error, we can't do
|
|
// much about it.
|
|
//
|
|
this->Close(0);
|
|
}
|
|
|
|
|
|
//
|
|
// Then uninitialize the object.
|
|
//
|
|
this->UninitializeObject();
|
|
|
|
//
|
|
// Finally delete this (!) object.
|
|
//
|
|
delete this;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 3, "[0x%p] RefCount [0x%lx]", this, lRefCount);
|
|
}
|
|
|
|
return lRefCount;
|
|
} // CDP8SimControl::Release
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::Initialize"
|
|
//=============================================================================
|
|
// CDP8SimControl::Initialize
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Initializes this DP8Sim Control interface.
|
|
//
|
|
// Arguments:
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::Initialize(const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
BOOL fHaveLock = FALSE;
|
|
BOOL fInitializedIPCObject = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%x)", this, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags == 0);
|
|
|
|
|
|
//
|
|
// Connect the shared memory.
|
|
//
|
|
hr = this->m_DP8SimIPC.Initialize();
|
|
if (hr != DPN_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't initialize IPC object!");
|
|
goto Failure;
|
|
}
|
|
|
|
fInitializedIPCObject = TRUE;
|
|
|
|
|
|
//
|
|
// We're now initialized.
|
|
//
|
|
this->m_dwFlags |= DP8SIMCONTROLOBJ_INITIALIZED;
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
if (fInitializedIPCObject)
|
|
{
|
|
this->m_DP8SimIPC.Close();
|
|
fInitializedIPCObject = FALSE;
|
|
}
|
|
|
|
goto Exit;
|
|
} // CDP8SimControl::Initialize
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::Close"
|
|
//=============================================================================
|
|
// CDP8SimControl::Close
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Closes this DP8Sim Control interface.
|
|
//
|
|
// Arguments:
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::Close(const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
//BOOL fHaveLock = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%x)", this, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
//fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
|
|
|
|
//
|
|
// Disconnect the shared memory.
|
|
//
|
|
this->m_DP8SimIPC.Close();
|
|
|
|
|
|
|
|
//
|
|
// Turn off the initialized flags.
|
|
//
|
|
this->m_dwFlags &= ~DP8SIMCONTROLOBJ_INITIALIZED;
|
|
DNASSERT(this->m_dwFlags == 0);
|
|
|
|
|
|
//
|
|
// Drop the lock, nobody should be touching this object now.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
//fHaveLock = FALSE;
|
|
|
|
|
|
//Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
/*
|
|
Failure:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
goto Exit;
|
|
*/
|
|
} // CDP8SimControl::Close
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::EnableControlForSP"
|
|
//=============================================================================
|
|
// CDP8SimControl::EnableControlForSP
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Inserts the DP8Sim Control shim in front of the SP with the
|
|
// given GUID.
|
|
//
|
|
// Arguments:
|
|
// GUID * pguidSP - Pointer to GUID of SP to intercept.
|
|
// WCHAR * wszNewFriendlyName - New friendly name for intercepted SP.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::EnableControlForSP(const GUID * const pguidSP,
|
|
const WCHAR * const wszNewFriendlyName,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
char szLocalPath[_MAX_PATH];
|
|
WCHAR wszLocalPath[_MAX_PATH];
|
|
WCHAR wszInProcServer32[_MAX_PATH];
|
|
CRegistry RegObjectCOM;
|
|
CRegistry RegObjectDP8SP;
|
|
CRegistry RegObjectDP8SPSubkey;
|
|
DWORD dwMaxLength;
|
|
DWORD dwLength;
|
|
WCHAR * pwszTemp = NULL;
|
|
DWORD dwTemp;
|
|
GUID guidTemp;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, \"%S\" 0x%x)",
|
|
this, pguidSP, wszNewFriendlyName, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pguidSP != NULL);
|
|
DNASSERT(wszNewFriendlyName != NULL);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
#ifdef DEBUG
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
#endif // DEBUG
|
|
|
|
|
|
//
|
|
// Retrieve the location of this DLL.
|
|
//
|
|
dwLength = GetModuleFileNameA(g_hDLLInstance, szLocalPath, _MAX_PATH);
|
|
if (dwLength == 0)
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't read local path!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Include NULL termination.
|
|
//
|
|
dwLength++;
|
|
|
|
|
|
//
|
|
// Convert it to Unicode.
|
|
//
|
|
hr = STR_AnsiToWide(szLocalPath, dwLength, wszLocalPath, &dwLength);
|
|
if (hr != S_OK)
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not convert ANSI path to Unicode!");
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Open the SP's COM object information key.
|
|
//
|
|
|
|
swprintf(wszInProcServer32, L"CLSID\\{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}\\InProcServer32",
|
|
pguidSP->Data1, pguidSP->Data2, pguidSP->Data3,
|
|
pguidSP->Data4[0], pguidSP->Data4[1],
|
|
pguidSP->Data4[2], pguidSP->Data4[3],
|
|
pguidSP->Data4[4], pguidSP->Data4[5],
|
|
pguidSP->Data4[6], pguidSP->Data4[7]);
|
|
|
|
if (! RegObjectCOM.Open(HKEY_CLASSES_ROOT, wszInProcServer32, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open SP InProcServer32 key!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure this SP hasn't already been modified.
|
|
//
|
|
dwLength = 0;
|
|
RegObjectCOM.ReadString(DP8SIM_REG_REALSPDLL, NULL, &dwLength);
|
|
if (dwLength > 0)
|
|
{
|
|
DPFX(DPFPREP, 0, "SP has already been redirected!");
|
|
hr = DP8SIMERR_ALREADYENABLEDFORSP;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Find out the size of the original DLL name.
|
|
//
|
|
dwLength = 0;
|
|
RegObjectCOM.ReadString(L"", NULL, &dwLength);
|
|
|
|
|
|
dwLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObjectCOM.ReadString(L"", pwszTemp, &dwLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't read existing SP's DLL location!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Save it so we can restore it later.
|
|
//
|
|
if (! RegObjectCOM.WriteString(DP8SIM_REG_REALSPDLL, pwszTemp))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't save SP's existing DLL location to value \"%S\"!",
|
|
DP8SIM_REG_REALSPDLL);
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
|
|
|
|
|
|
//
|
|
// Find the SP key. First allocate enough memory to hold the name the
|
|
// longest subkey.
|
|
//
|
|
|
|
if (! RegObjectDP8SP.Open(HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open DirectPlay8 SP key!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObjectDP8SP.GetMaxKeyLen(dwMaxLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not get longest SP key name length!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
dwMaxLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwMaxLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Walk through every key, looking for the right one.
|
|
//
|
|
dwTemp = 0;
|
|
do
|
|
{
|
|
dwLength = dwMaxLength;
|
|
if (! RegObjectDP8SP.EnumKeys(pwszTemp, &dwLength, dwTemp))
|
|
{
|
|
//
|
|
// We couldn't get the next key. Assume we're done.
|
|
//
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Open the subkey.
|
|
//
|
|
if (! RegObjectDP8SPSubkey.Open((HKEY) RegObjectDP8SP, pwszTemp, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open DirectPlay8 SP sub key \"%S\"! Ignoring.", pwszTemp);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// See if the GUID matches.
|
|
//
|
|
RegObjectDP8SPSubkey.ReadGUID(DPN_REG_KEYNAME_GUID, guidTemp);
|
|
|
|
if (guidTemp == (*pguidSP))
|
|
{
|
|
//
|
|
// Found SP.
|
|
//
|
|
DPFX(DPFPREP, 5, "Found SP under sub key \"%S\".", pwszTemp);
|
|
break;
|
|
}
|
|
|
|
RegObjectDP8SPSubkey.Close();
|
|
}
|
|
|
|
//
|
|
// Got to next subkey.
|
|
//
|
|
dwTemp++;
|
|
}
|
|
while (TRUE);
|
|
|
|
|
|
//
|
|
// If we didn't find the SP, the subkey will be closed.
|
|
//
|
|
if (! RegObjectDP8SPSubkey.IsOpen())
|
|
{
|
|
DPFX(DPFPREP, 0, "Didn't find DirectPlay8 SP matching given GUID!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// We don't need the main SP key or name buffer anymore.
|
|
//
|
|
RegObjectDP8SP.Close();
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
|
|
|
|
//
|
|
// Find the size of the original SP friendly name.
|
|
//
|
|
dwLength = 0;
|
|
RegObjectDP8SPSubkey.ReadString(DPN_REG_KEYNAME_FRIENDLY_NAME, NULL, &dwLength);
|
|
|
|
|
|
dwLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObjectDP8SPSubkey.ReadString(DPN_REG_KEYNAME_FRIENDLY_NAME, pwszTemp, &dwLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't read existing SP's friendly name!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Save it so we can restore it later.
|
|
//
|
|
if (! RegObjectDP8SPSubkey.WriteString(DP8SIM_REG_REALSPFRIENDLYNAME, pwszTemp))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't save SP's existing friendly name to value \"%S\"!",
|
|
DP8SIM_REG_REALSPFRIENDLYNAME);
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Write our replacement DLL's friendly name.
|
|
//
|
|
if (! RegObjectDP8SPSubkey.WriteString(DPN_REG_KEYNAME_FRIENDLY_NAME, wszNewFriendlyName))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't write our new SP friendly name to registry!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
RegObjectDP8SPSubkey.Close();
|
|
|
|
|
|
|
|
//
|
|
// Finally write our replacement DLL's location.
|
|
//
|
|
if (! RegObjectCOM.WriteString(L"", wszLocalPath))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't write our DLL location to registry!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
RegObjectCOM.Close();
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
if (pwszTemp != NULL)
|
|
{
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
}
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
//
|
|
// RegObjectCOM, RegObjectDP8SP, and RegObjectDP8SPSubkey are all
|
|
// implicitly closed by their destructors, if necessary.
|
|
//
|
|
|
|
goto Exit;
|
|
} // EnableControlForSP
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "DisableControlForSP"
|
|
//=============================================================================
|
|
// CDP8SimControl::DisableControlForSP
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Removes the DP8Sim Control shim from the SP with the given
|
|
// GUID.
|
|
//
|
|
// Arguments:
|
|
// GUID * pguidSP - Pointer to GUID of SP that should no longer be
|
|
// intercepted.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::DisableControlForSP(const GUID * const pguidSP,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
WCHAR wszInProcServer32[_MAX_PATH];
|
|
CRegistry RegObject;
|
|
CRegistry RegObjectSubkey;
|
|
DWORD dwMaxLength;
|
|
DWORD dwLength;
|
|
WCHAR * pwszTemp = NULL;
|
|
DWORD dwTemp;
|
|
GUID guidTemp;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%x)", this, pguidSP, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pguidSP != NULL);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
#ifdef DEBUG
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
#endif // DEBUG
|
|
|
|
|
|
//
|
|
// Find the SP key. First allocate enough memory to hold the name the
|
|
// longest subkey.
|
|
//
|
|
|
|
if (! RegObject.Open(HKEY_LOCAL_MACHINE, DPN_REG_LOCAL_SP_SUBKEY, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open DirectPlay8 SP key!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObject.GetMaxKeyLen(dwMaxLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not get longest SP key name length!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
dwMaxLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwMaxLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Walk through every key, looking for the right one.
|
|
//
|
|
dwTemp = 0;
|
|
do
|
|
{
|
|
dwLength = dwMaxLength;
|
|
if (! RegObject.EnumKeys(pwszTemp, &dwLength, dwTemp))
|
|
{
|
|
//
|
|
// We couldn't get the next key. Assume we're done.
|
|
//
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Open the subkey.
|
|
//
|
|
if (! RegObjectSubkey.Open((HKEY) RegObject, pwszTemp, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open DirectPlay8 SP sub key \"%S\"! Ignoring.", pwszTemp);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// See if the GUID matches.
|
|
//
|
|
RegObjectSubkey.ReadGUID(DPN_REG_KEYNAME_GUID, guidTemp);
|
|
|
|
if (guidTemp == (*pguidSP))
|
|
{
|
|
//
|
|
// Found SP.
|
|
//
|
|
DPFX(DPFPREP, 5, "Found SP under sub key \"%S\".", pwszTemp);
|
|
break;
|
|
}
|
|
|
|
RegObjectSubkey.Close();
|
|
}
|
|
|
|
|
|
//
|
|
// Got to next subkey.
|
|
//
|
|
dwTemp++;
|
|
}
|
|
while (TRUE);
|
|
|
|
|
|
//
|
|
// If we didn't find the SP, the subkey will be closed.
|
|
//
|
|
if (! RegObjectSubkey.IsOpen())
|
|
{
|
|
DPFX(DPFPREP, 0, "Didn't find DirectPlay8 SP matching given GUID!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// We don't need the main SP key or name buffer anymore.
|
|
//
|
|
RegObject.Close();
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
|
|
|
|
//
|
|
// Find the size of the original SP friendly name.
|
|
//
|
|
dwLength = 0;
|
|
RegObjectSubkey.ReadString(DP8SIM_REG_REALSPFRIENDLYNAME, NULL, &dwLength);
|
|
|
|
|
|
dwLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObjectSubkey.ReadString(DP8SIM_REG_REALSPFRIENDLYNAME, pwszTemp, &dwLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't read SP's original friendly name!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Restore the value.
|
|
//
|
|
if (! RegObjectSubkey.WriteString(DPN_REG_KEYNAME_FRIENDLY_NAME, pwszTemp))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't restore SP's original friendly name!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Delete the restoration key.
|
|
//
|
|
if (! RegObjectSubkey.DeleteValue(DP8SIM_REG_REALSPFRIENDLYNAME))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't delete friendly name restoration key \"%S\"!",
|
|
DP8SIM_REG_REALSPDLL);
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
RegObjectSubkey.Close();
|
|
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
|
|
|
|
|
|
//
|
|
// Open the SP's COM object information key.
|
|
//
|
|
|
|
swprintf(wszInProcServer32, L"CLSID\\{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}\\InProcServer32",
|
|
pguidSP->Data1, pguidSP->Data2, pguidSP->Data3,
|
|
pguidSP->Data4[0], pguidSP->Data4[1],
|
|
pguidSP->Data4[2], pguidSP->Data4[3],
|
|
pguidSP->Data4[4], pguidSP->Data4[5],
|
|
pguidSP->Data4[6], pguidSP->Data4[7]);
|
|
|
|
if (! RegObject.Open(HKEY_CLASSES_ROOT, wszInProcServer32, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open SP InProcServer32 key!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Read the location of the original DLL.
|
|
//
|
|
dwLength = 0;
|
|
RegObject.ReadString(DP8SIM_REG_REALSPDLL, NULL, &dwLength);
|
|
|
|
|
|
dwLength++;
|
|
pwszTemp = (WCHAR*) DNMalloc(dwLength * sizeof(WCHAR));
|
|
if (pwszTemp == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
if (! RegObject.ReadString(DP8SIM_REG_REALSPDLL, pwszTemp, &dwLength))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't read original SP's DLL location (\"%S\"), assuming DP8Sim was not enabled!",
|
|
DP8SIM_REG_REALSPDLL);
|
|
hr = DP8SIMERR_NOTENABLEDFORSP;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Restore the value.
|
|
//
|
|
if (! RegObject.WriteString(L"", pwszTemp))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't restore SP's original DLL location!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Delete the restoration key.
|
|
//
|
|
if (! RegObject.DeleteValue(DP8SIM_REG_REALSPDLL))
|
|
{
|
|
DPFX(DPFPREP, 0, "Couldn't delete restoration key \"%S\"!",
|
|
DP8SIM_REG_REALSPDLL);
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
RegObject.Close();
|
|
|
|
|
|
//
|
|
// Since we can't actually unload the wrapper from any processes already
|
|
// using it, those will continue using the current settings
|
|
//
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
if (pwszTemp != NULL)
|
|
{
|
|
DNFree(pwszTemp);
|
|
pwszTemp = NULL;
|
|
}
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
//
|
|
// RegObject, and RegObjectSubkey are implicitly closed by their
|
|
// destructors, if necessary.
|
|
//
|
|
|
|
goto Exit;
|
|
} // DisableControlForSP
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "GetControlEnabledForSP"
|
|
//=============================================================================
|
|
// CDP8SimControl::GetControlEnabledForSP
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Determines whether the DP8Sim Control shim is enabled for the
|
|
// SP with the given GUID or not. TRUE is returned in pfEnabled
|
|
// if so, FALSE if not.
|
|
//
|
|
// Arguments:
|
|
// GUID * pguidSP - Pointer to GUID of SP that should be checked.
|
|
// BOOL * pfEnabled - Place to store boolean indicating status.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::GetControlEnabledForSP(const GUID * const pguidSP,
|
|
BOOL * const pfEnabled,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
WCHAR wszInProcServer32[_MAX_PATH];
|
|
CRegistry RegObject;
|
|
CRegistry RegObjectSubkey;
|
|
DWORD dwLength;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%p, 0x%x)",
|
|
this, pguidSP, pfEnabled, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pguidSP != NULL);
|
|
DNASSERT(pfEnabled != NULL);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
#ifdef DEBUG
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
#endif // DEBUG
|
|
|
|
|
|
//
|
|
// Open the SP's COM object information key.
|
|
//
|
|
|
|
swprintf(wszInProcServer32, L"CLSID\\{%-08.8X-%-04.4X-%-04.4X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X}\\InProcServer32",
|
|
pguidSP->Data1, pguidSP->Data2, pguidSP->Data3,
|
|
pguidSP->Data4[0], pguidSP->Data4[1],
|
|
pguidSP->Data4[2], pguidSP->Data4[3],
|
|
pguidSP->Data4[4], pguidSP->Data4[5],
|
|
pguidSP->Data4[6], pguidSP->Data4[7]);
|
|
|
|
if (! RegObject.Open(HKEY_CLASSES_ROOT, wszInProcServer32, FALSE, FALSE, FALSE))
|
|
{
|
|
DPFX(DPFPREP, 0, "Could not open SP InProcServer32 key!");
|
|
hr = E_FAIL;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Try reading the location of the original DLL. dwLength will stay 0 if
|
|
// the registry key could not be opened.
|
|
//
|
|
dwLength = 0;
|
|
RegObject.ReadString(DP8SIM_REG_REALSPDLL, NULL, &dwLength);
|
|
if (dwLength == 0)
|
|
{
|
|
DPFX(DPFPREP, 1, "Couldn't read original SP's DLL location (\"%S\"), assuming DP8Sim was not enabled.",
|
|
DP8SIM_REG_REALSPDLL);
|
|
(*pfEnabled) = FALSE;
|
|
}
|
|
else
|
|
{
|
|
DPFX(DPFPREP, 1, "Retrieved original SP's DLL location value size, assuming DP8Sim was enabled.");
|
|
(*pfEnabled) = TRUE;
|
|
}
|
|
|
|
|
|
RegObject.Close();
|
|
|
|
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
//
|
|
// RegObject, and RegObjectSubkey are implicitly closed by their
|
|
// destructors, if necessary.
|
|
//
|
|
|
|
goto Exit;
|
|
} // GetControlEnabledForSP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::GetAllParameters"
|
|
//=============================================================================
|
|
// CDP8SimControl::GetAllParameters
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Retrieves all of the current DP8Sim settings.
|
|
//
|
|
// Arguments:
|
|
// DP8SIM_PARAMETERS * pdp8spSend - Place to store current send
|
|
// parameters.
|
|
// DP8SIM_PARAMETERS * pdp8spReceive - Place to store current receive
|
|
// parameters.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::GetAllParameters(DP8SIM_PARAMETERS * const pdp8spSend,
|
|
DP8SIM_PARAMETERS * const pdp8spReceive,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
//BOOL fHaveLock = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%p, 0x%x)",
|
|
this, pdp8spSend, pdp8spReceive, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pdp8spSend != NULL);
|
|
DNASSERT(pdp8spReceive != NULL);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
//fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Retrieve the settings from the IPC object.
|
|
//
|
|
this->m_DP8SimIPC.GetAllParameters(pdp8spSend, pdp8spReceive);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
//fHaveLock = FALSE;
|
|
|
|
|
|
//Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
/*
|
|
Failure:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
goto Exit;
|
|
*/
|
|
} // CDP8SimControl::GetAllParameters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::SetAllParameters"
|
|
//=============================================================================
|
|
// CDP8SimControl::SetAllParameters
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Modifies the current DP8Sim settings.
|
|
//
|
|
// Arguments:
|
|
// DP8SIM_PARAMETERS * pdp8spSend - Structure containing desired send
|
|
// parameters.
|
|
// DP8SIM_PARAMETERS * pdp8spReceive - Structure containing desired
|
|
// receive parameters.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::SetAllParameters(const DP8SIM_PARAMETERS * const pdp8spSend,
|
|
const DP8SIM_PARAMETERS * const pdp8spReceive,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
//BOOL fHaveLock = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%p, 0x%x)",
|
|
this, pdp8spSend, pdp8spReceive, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pdp8spSend != NULL);
|
|
DNASSERT(pdp8spSend->dwMinLatencyMS <= pdp8spSend->dwMaxLatencyMS);
|
|
DNASSERT(pdp8spReceive != NULL);
|
|
DNASSERT(pdp8spReceive->dwMinLatencyMS <= pdp8spReceive->dwMaxLatencyMS);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
//fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Store the settings with the IPC object.
|
|
//
|
|
this->m_DP8SimIPC.SetAllParameters(pdp8spSend, pdp8spReceive);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
//fHaveLock = FALSE;
|
|
|
|
|
|
//Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
/*
|
|
Failure:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
goto Exit;
|
|
*/
|
|
} // CDP8SimControl::SetAllParameters
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::GetAllStatistics"
|
|
//=============================================================================
|
|
// CDP8SimControl::GetAllStatistics
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Retrieves all of the current DP8Sim statistics.
|
|
//
|
|
// Arguments:
|
|
// DP8SIM_STATISTICS * pdp8ssSend - Place to store current send
|
|
// statistics.
|
|
// DP8SIM_STATISTICS * pdp8ssReceive - Place to store current receive
|
|
// statistics.
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::GetAllStatistics(DP8SIM_STATISTICS * const pdp8ssSend,
|
|
DP8SIM_STATISTICS * const pdp8ssReceive,
|
|
const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
//BOOL fHaveLock = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%p, 0x%p, 0x%x)",
|
|
this, pdp8ssSend, pdp8ssReceive, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(pdp8ssSend != NULL);
|
|
DNASSERT(pdp8ssReceive != NULL);
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
//fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Retrieve the stats from the IPC object.
|
|
//
|
|
this->m_DP8SimIPC.GetAllStatistics(pdp8ssSend, pdp8ssReceive);
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
//fHaveLock = FALSE;
|
|
|
|
|
|
//Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
/*
|
|
Failure:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
goto Exit;
|
|
*/
|
|
} // CDP8SimControl::GetAllStatistics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::ClearAllStatistics"
|
|
//=============================================================================
|
|
// CDP8SimControl::ClearAllStatistics
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Clears all of the current DP8Sim statistics.
|
|
//
|
|
// Arguments:
|
|
// DWORD dwFlags - Unused, must be zero.
|
|
//
|
|
// Returns: HRESULT
|
|
//=============================================================================
|
|
STDMETHODIMP CDP8SimControl::ClearAllStatistics(const DWORD dwFlags)
|
|
{
|
|
HRESULT hr = DP8SIM_OK;
|
|
//BOOL fHaveLock = FALSE;
|
|
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Parameters: (0x%x)", this, dwFlags);
|
|
|
|
|
|
//
|
|
// Validate (actually assert) the object.
|
|
//
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Assert the parameters.
|
|
//
|
|
DNASSERT(dwFlags == 0);
|
|
|
|
|
|
DNEnterCriticalSection(&this->m_csLock);
|
|
//fHaveLock = TRUE;
|
|
|
|
|
|
//
|
|
// Assert the object state.
|
|
//
|
|
DNASSERT(this->m_dwFlags & DP8SIMCONTROLOBJ_INITIALIZED);
|
|
|
|
|
|
//
|
|
// Have the IPC object clear the stats.
|
|
//
|
|
this->m_DP8SimIPC.ClearAllStatistics();
|
|
|
|
|
|
//
|
|
// Drop the lock.
|
|
//
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
//fHaveLock = FALSE;
|
|
|
|
|
|
//Exit:
|
|
|
|
DPFX(DPFPREP, 2, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
/*
|
|
Failure:
|
|
|
|
if (fHaveLock)
|
|
{
|
|
DNLeaveCriticalSection(&this->m_csLock);
|
|
}
|
|
|
|
goto Exit;
|
|
*/
|
|
} // CDP8SimControl::ClearAllStatistics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::InitializeObject"
|
|
//=============================================================================
|
|
// CDP8SimControl::InitializeObject
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Sets up the object for use like the constructor, but may
|
|
// fail with OUTOFMEMORY. Should only be called by class factory
|
|
// creation routine.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: HRESULT
|
|
// S_OK - Initialization was successful.
|
|
// E_OUTOFMEMORY - There is not enough memory to initialize.
|
|
//=============================================================================
|
|
HRESULT CDP8SimControl::InitializeObject(void)
|
|
{
|
|
HRESULT hr;
|
|
|
|
|
|
DPFX(DPFPREP, 5, "(0x%p) Enter", this);
|
|
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
//
|
|
// Create the lock.
|
|
//
|
|
if (! DNInitializeCriticalSection(&this->m_csLock))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Failure;
|
|
}
|
|
|
|
|
|
//
|
|
// Don't allow critical section reentry.
|
|
//
|
|
DebugSetCriticalSectionRecursionCount(&this->m_csLock, 0);
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
Exit:
|
|
|
|
DPFX(DPFPREP, 5, "(0x%p) Returning: [0x%lx]", this, hr);
|
|
|
|
return hr;
|
|
|
|
|
|
Failure:
|
|
|
|
goto Exit;
|
|
} // CDP8SimControl::InitializeObject
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#undef DPF_MODNAME
|
|
#define DPF_MODNAME "CDP8SimControl::UninitializeObject"
|
|
//=============================================================================
|
|
// CDP8SimControl::UninitializeObject
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Description: Cleans up the object like the destructor, mostly to balance
|
|
// InitializeObject.
|
|
//
|
|
// Arguments: None.
|
|
//
|
|
// Returns: None.
|
|
//=============================================================================
|
|
void CDP8SimControl::UninitializeObject(void)
|
|
{
|
|
DPFX(DPFPREP, 5, "(0x%p) Enter", this);
|
|
|
|
|
|
DNASSERT(this->IsValidObject());
|
|
|
|
|
|
DNDeleteCriticalSection(&this->m_csLock);
|
|
|
|
|
|
DPFX(DPFPREP, 5, "(0x%p) Returning", this);
|
|
} // CDP8SimControl::UninitializeObject
|
|
|