windows-nt/Source/XPSP1/NT/windows/appcompat/shims/specific/threedjungletrain.cpp
2020-09-26 16:20:57 +08:00

132 lines
2.6 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
ThreeDJungleTrain.cpp
Abstract:
ThreedJungleTrain created a new DirectSound object every time
it entered the "3D Train Ride" part of the game, and destroyed
the object every time it went to a "2D interior" part. It was
keeping and using an old pointer to the first DirectSound object
it ever created even after it was destroyed. It was only luck that
Win9x would continue to allocate new objects in the same place that
allowed the game to work. This shim never allows the release of
that first object and then continues to hand back pointers to the
first object when new objects are requested so that the old pointer
the app uses always points to a (the) valid DirectSound object.
History:
08/09/2000 t-adams Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(ThreeDJungleTrain)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(DirectSoundCreate)
APIHOOK_ENUM_END
// Pointer to the first DirectSound object created.
LPDIRECTSOUND g_pDS = NULL;
/*++
Hook DirectSoundCreate to remeber the first DS object created and afterwards
return a pointer to that object when new DS objects are requested.
--*/
HRESULT
APIHOOK(DirectSoundCreate)(
LPCGUID lpcGuid,
LPDIRECTSOUND *ppDS,
LPUNKNOWN pUnkOuter)
{
HRESULT hRet = DS_OK;
// Check to see if we have an old DS yet.
if( NULL == g_pDS ) {
// If not, then get a new DS
hRet = ORIGINAL_API(DirectSoundCreate)(lpcGuid, ppDS, pUnkOuter);
if ( DS_OK == hRet )
{
HookObject(
NULL,
IID_IDirectSound,
(PVOID*)ppDS,
NULL,
FALSE);
g_pDS = *ppDS;
}
goto exit;
} else {
// If so, then give back the old DS
*ppDS = g_pDS;
goto exit;
}
exit:
return hRet;
}
/*++
Hook IDirectSound_Release so DirectSound object isn't released.
--*/
HRESULT
COMHOOK(IDirectSound, Release)(
PVOID pThis)
{
// Don't release.
return 0;
}
/*++
Release global DirectSound object.
--*/
BOOL
NOTIFY_FUNCTION(
DWORD fdwReason)
{
if (fdwReason == DLL_PROCESS_DETACH) {
if (NULL != g_pDS) {
ORIGINAL_COM(IDirectSound, Release, g_pDS)(g_pDS);
}
}
return TRUE;
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(DSOUND.DLL, DirectSoundCreate)
COMHOOK_ENTRY(DirectSound, IDirectSound, Release, 2)
CALL_NOTIFY_FUNCTION
HOOK_END
IMPLEMENT_SHIM_END