Skip to content

Commit

Permalink
replace detourd with easyhook, plus fix core-audio hook
Browse files Browse the repository at this point in the history
  • Loading branch information
Chun-Ying Huang committed Jan 29, 2015
1 parent e16e6f5 commit 7bc2237
Show file tree
Hide file tree
Showing 12 changed files with 226 additions and 499 deletions.
12 changes: 6 additions & 6 deletions deps.pkg.win32/install.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,12 @@ move /y easyhook-2.6s\*.lib %GADEPS%\lib\
move /y easyhook-2.6s\*.dll %GADEPS%\bin\
rmdir /s /q easyhook-2.6s
@REM
echo Installing detour library ...
bin\7za x detour.7z
move /y detour\*.h %GADEPS%\include\
move /y detour\*.lib %GADEPS%\lib\
move /y detour\*.dll %GADEPS%\bin\
rmdir /s /q detour
@REM echo Installing detour library ...
@REM bin\7za x detour.7z
@REM move /y detour\*.h %GADEPS%\include\
@REM move /y detour\*.lib %GADEPS%\lib\
@REM move /y detour\*.dll %GADEPS%\bin\
@REM rmdir /s /q detour
@REM
echo Installation finished
pause
4 changes: 2 additions & 2 deletions ga/server/event-driven/NMakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
CXX_FLAGS = $(CXX_FLAGS) -I"C:\Microsoft DirectX SDK\Include"
LIB_PATH = $(LIB_PATH) /libpath:..\..\core /libpath:"C:\Microsoft DirectX SDK\Lib\x86"
LIBS = $(LIB_SYSTEM) $(LIB_SDL) $(LIB_FFMPEG) $(LIB_PTHREAD) \
libga.lib $(LIB_D3D)
libga.lib $(LIB_D3D) EasyHook32.lib
#LDFLAGS = -rdynamic -L../../core -Wl,--whole-archive -lga -Wl,--no-whole-archive $(AVCLD) $(SDLLD)
LDFLAGS = $(LIB_PATH) /libpath:..\..\core $(LIBS) /opt:noref

Expand All @@ -19,7 +19,7 @@ ga-hook.dll: ga-hook.obj ga-hook-common.obj \
ga-hook-sdl.obj ga-hook-sdlaudio.obj \
ga-hook-coreaudio.obj \
hook-function.obj ctrl-sdl.obj
$(CXX) /LD /MD $** $(LIBS) /link /DLL $(LIB_PATH) detours.lib detoured.lib opengl32.lib glu32.lib /opt:noref
$(CXX) /LD /MD $** $(LIBS) /link /DLL $(LIB_PATH) opengl32.lib glu32.lib /opt:noref

ga-server-event-driven.exe: ga-server-event-driven.obj
$(CXX) /MD $** $(LIBS) /link $(LIB_PATH) /opt:noref
Expand Down
232 changes: 50 additions & 182 deletions ga/server/event-driven/ga-hook-coreaudio.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 Chun-Ying Huang
* Copyright (c) 2012-2015 Chun-Ying Huang
*
* This file is part of GamingAnywhere (GA).
*
Expand All @@ -22,6 +22,7 @@
#include "ga-avcodec.h"
#include "rtspconf.h"
#include "asource.h"
#include "ga-hook-common.h"
#include "ga-hook-coreaudio.h"

#define CA_MAX_SAMPLES 32768
Expand All @@ -33,140 +34,11 @@ static int ga_channels = 0;
static struct SwrContext *swrctx = NULL;
static unsigned char *audio_buf = NULL;

static t_CoCreateInstance old_CoCreateInstance = NULL;
static t_EnumAudioEndpoints old_EnumAudioEndpoints = NULL;
static t_GetDefaultAudioEndpoint old_GetDefaultAudioEndpoint = NULL; /* member of IMMDevice */
static t_GetDevice old_GetDevice = NULL;
static t_Activate old_Activate = NULL; /* member of IMMDevice */
static t_Item old_Item = NULL;
static t_GetService old_GetService = NULL;
static t_GetBuffer old_GetBuffer = NULL;
static t_ReleaseBuffer old_ReleaseBuffer = NULL;
static t_GetMixFormat old_GetMixFormat = NULL;

#define CA_DO_HOOK(name) \
DetourTransactionBegin(); \
DetourUpdateThread(GetCurrentThread()); \
DetourAttach(&(PVOID&)old_##name, hook_##name); \
DetourTransactionCommit();

DllExport HRESULT __stdcall
hook_EnumAudioEndpoints(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
DWORD dwStateMask,
IMMDeviceCollection **ppDevices)
{
HRESULT hr;
hr = old_EnumAudioEndpoints(thiz, dataFlow, dwStateMask, ppDevices);
if(hr==S_OK && old_Item==NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppDevices;
old_Item = (t_Item) pvtbl[4];
CA_DO_HOOK(Item);
}
return hr;
}

DllExport HRESULT __stdcall
hook_GetDefaultAudioEndpoint(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
ERole role,
IMMDevice **ppDevice)
{
HRESULT hr;
hr = old_GetDefaultAudioEndpoint(thiz, dataFlow, role, ppDevice);
if(hr==S_OK && old_Activate==NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppDevice;
old_Activate = (t_Activate) pvtbl[3];
CA_DO_HOOK(Activate);
}
return hr;
}

DllExport HRESULT __stdcall
hook_GetDevice( IMMDeviceEnumerator *thiz,
LPCWSTR pwstrId,
IMMDevice **ppDevice)
{
HRESULT hr;
hr = old_GetDevice(thiz, pwstrId, ppDevice);
if(hr==S_OK && old_Activate==NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppDevice;
old_Activate = (t_Activate) pvtbl[3];
CA_DO_HOOK(Activate);
}
return hr;
}

DllExport HRESULT __stdcall
hook_Item( IMMDeviceCollection *thiz,
UINT nDevice,
IMMDevice **ppDevice)
{
HRESULT hr;
hr = old_Item(thiz, nDevice, ppDevice);
if(hr==S_OK && old_Activate==NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppDevice;
old_Activate = (t_Activate) pvtbl[3];
CA_DO_HOOK(Activate);
}
return hr;
}

DllExport HRESULT __stdcall
hook_Activate(
IMMDeviceActivator *thiz,
REFIID iid,
DWORD dwClsCtx,
PROPVARIANT *pActivationParams,
void **ppInterface
)
{
const IID IID_IAudioClient = __uuidof(IAudioClient);
HRESULT hr;
//
hr = old_Activate(thiz, iid, dwClsCtx, pActivationParams, ppInterface);
if(hr==S_OK && iid==IID_IAudioClient) {
if(old_GetService==NULL){
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppInterface;
old_GetService = (t_GetService) pvtbl[14];
CA_DO_HOOK(GetService);
}
if(old_GetMixFormat==NULL){
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppInterface;
old_GetMixFormat= (t_GetMixFormat) pvtbl[8];
CA_DO_HOOK(GetMixFormat);
}
}
return hr;
}


DllExport HRESULT __stdcall
hook_GetService(
IAudioClient *thiz,
REFIID iid,
void **ppv
)
{
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
HRESULT hr;
hr = old_GetService(thiz, iid, ppv);
if(hr==S_OK && iid==IID_IAudioRenderClient) {
if(old_ReleaseBuffer==NULL){
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppv;
old_ReleaseBuffer = (t_ReleaseBuffer) pvtbl[4];
CA_DO_HOOK(ReleaseBuffer);
}
if(old_GetBuffer==NULL){
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppv;
old_GetBuffer = (t_GetBuffer) pvtbl[3];
CA_DO_HOOK(GetBuffer);
}
}
return hr;
}
#define CA_DO_HOOK(name) ga_hook_function(#name, old_##name, hook_##name)

static enum AVSampleFormat
CA2SWR_format(WAVEFORMATEX *w) {
Expand Down Expand Up @@ -359,64 +231,60 @@ hook_GetBuffer(
return S_OK;
}

DllExport HRESULT __stdcall
hook_CoCreateInstance(
REFCLSID clsid,
LPUNKNOWN punknown,
DWORD dwClsContext,
REFIID iid,
LPVOID *ppv
)
{
const IID IID_IMMDeviceEnumerator = __uuidof(MMDeviceEnumerator);

int
hook_coreaudio() {
int ret = -1;

HRESULT hr;
IMMDeviceEnumerator *deviceEnumerator = NULL;
IMMDevice *device = NULL;
IAudioClient *audioClient = NULL;
IAudioRenderClient *renderClient = NULL;
WAVEFORMATEX *pwfx = NULL;

hr = old_CoCreateInstance(clsid, punknown, dwClsContext, iid, ppv);
if(hr != S_OK)
return hr;
// obtain core-audio objects and functions
#define RET_ON_ERROR(hr, prefix) if(hr!=S_OK) { ga_error("[core-audio] %s failed (%08x).\n", prefix, hr); goto hook_ca_quit; }
hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**) &deviceEnumerator);
RET_ON_ERROR(hr, "CoCreateInstance");

if(clsid != IID_IMMDeviceEnumerator)
return hr;
hr = deviceEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &device);
RET_ON_ERROR(hr, "GetDefaultAudioEndpoint");

if(old_EnumAudioEndpoints == NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppv;
old_EnumAudioEndpoints = (t_EnumAudioEndpoints) pvtbl[3];
CA_DO_HOOK(EnumAudioEndpoints);
}
hr = device->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**) &audioClient);
RET_ON_ERROR(hr, "Activate");

if(old_GetDefaultAudioEndpoint == NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppv;
old_GetDefaultAudioEndpoint = (t_GetDefaultAudioEndpoint) pvtbl[4];
CA_DO_HOOK(GetDefaultAudioEndpoint);
}

if(old_GetDevice == NULL) {
DWORD* pvtbl = (DWORD*) *(DWORD*) *ppv;
old_GetDevice = (t_GetDevice) pvtbl[5];
CA_DO_HOOK(GetDevice);
}
hr = audioClient->GetMixFormat(&pwfx);
RET_ON_ERROR(hr, "GetMixFormat");

return hr;
}
hr = audioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, 0, 10000000/*REFTIME_PER_SEC*/, 0, pwfx, NULL);
RET_ON_ERROR(hr, "Initialize");

hr = audioClient->GetService(__uuidof(IAudioRenderClient), (void**) &renderClient);
RET_ON_ERROR(hr, "GetService[IAudioRenderClient]");
#undef RET_ON_ERROR

// do hook stuff
old_GetMixFormat = (t_GetMixFormat) ((comobj_t*) audioClient)->vtbl->func[8];
CA_DO_HOOK(GetMixFormat);

old_GetBuffer = (t_GetBuffer) ((comobj_t*) renderClient)->vtbl->func[3];
CA_DO_HOOK(GetBuffer);

old_ReleaseBuffer = (t_ReleaseBuffer) ((comobj_t*) renderClient)->vtbl->func[4];
CA_DO_HOOK(ReleaseBuffer);

ret = 0;

int
hook_coreaudio() {
HMODULE hMod;
if((hMod = LoadLibrary("ole32.dll")) == NULL) {
ga_error("Load ole32.dll failed.\n");
return -1;
}
if(old_CoCreateInstance != NULL)
return 0;
old_CoCreateInstance =
(t_CoCreateInstance) GetProcAddress(hMod, "CoCreateInstance");
if(old_CoCreateInstance == NULL) {
ga_error("GetProcAddress(CoCreateInstance) failed.\n");
return -1;
}
CA_DO_HOOK(CoCreateInstance);
ga_error("hook_coreaudio: done\n");
return 0;

hook_ca_quit:
if(renderClient) { renderClient->Release(); renderClient = NULL; }
if(pwfx) { CoTaskMemFree(pwfx); pwfx= NULL; }
if(audioClient) { audioClient->Release(); audioClient = NULL; }
if(device) { device->Release(); device = NULL; }
if(deviceEnumerator) { deviceEnumerator->Release(); deviceEnumerator = NULL; }

return ret;
}

70 changes: 1 addition & 69 deletions ga/server/event-driven/ga-hook-coreaudio.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013 Chun-Ying Huang
* Copyright (c) 2012-2015 Chun-Ying Huang
*
* This file is part of GamingAnywhere (GA).
*
Expand Down Expand Up @@ -27,40 +27,6 @@
#ifdef __cplusplus
extern "C" {
#endif
typedef HRESULT (STDMETHODCALLTYPE *t_CoCreateInstance)(
REFCLSID clsid,
LPUNKNOWN punknown,
DWORD dwClsContext,
REFIID iid,
LPVOID *ppv);
typedef HRESULT (STDMETHODCALLTYPE *t_EnumAudioEndpoints)(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
DWORD dwStateMask,
IMMDeviceCollection **ppDevices);
typedef HRESULT (STDMETHODCALLTYPE *t_GetDefaultAudioEndpoint)(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
ERole role,
IMMDevice **ppDevice);
typedef HRESULT (STDMETHODCALLTYPE *t_GetDevice)(
IMMDeviceEnumerator *thiz,
LPCWSTR pwstrId,
IMMDevice **ppDevice);
typedef HRESULT (STDMETHODCALLTYPE * t_Activate)(
IMMDeviceActivator *thiz,
REFIID iid,
DWORD dwClsCtx,
PROPVARIANT *pActivationParams,
void **ppInterface);
typedef HRESULT (STDMETHODCALLTYPE *t_Item)(
IMMDeviceCollection *thiz,
UINT nDevice,
IMMDevice **ppDevice);
typedef HRESULT (STDMETHODCALLTYPE *t_GetService)(
IAudioClient *thiz,
REFIID riid,
void **ppv);
typedef HRESULT (STDMETHODCALLTYPE *t_GetBuffer)(
IAudioRenderClient *thiz,
UINT32 NumFramesRequested,
Expand All @@ -77,40 +43,6 @@ typedef HRESULT (STDMETHODCALLTYPE *t_GetMixFormat)(
#endif

// prototypes
DllExport HRESULT __stdcall hook_CoCreateInstance(
REFCLSID clsid,
LPUNKNOWN punknown,
DWORD dwClsContext,
REFIID iid,
LPVOID *ppv);
DllExport HRESULT __stdcall hook_GetDevice (
IMMDeviceEnumerator *thiz,
LPCWSTR pwstrId,
IMMDevice **ppDevice);
DllExport HRESULT __stdcall hook_Activate(
IMMDeviceActivator *thiz,
REFIID iid,
DWORD dwClsCtx,
PROPVARIANT *pActivationParams,
void **ppInterface);
DllExport HRESULT __stdcall hook_GetDefaultAudioEndpoint(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
ERole role,
IMMDevice **ppDevice);
DllExport HRESULT __stdcall hook_EnumAudioEndpoints(
IMMDeviceEnumerator *thiz,
EDataFlow dataFlow,
DWORD dwStateMask,
IMMDeviceCollection **ppDevices);
DllExport HRESULT __stdcall hook_Item(
IMMDeviceCollection *thiz,
UINT nDevice,
IMMDevice **ppDevice);
DllExport HRESULT __stdcall hook_GetService(
IAudioClient *thiz,
REFIID iid,
void **ppv);
DllExport HRESULT __stdcall hook_GetBuffer(
IAudioRenderClient *thiz,
UINT32 NumFramesRequested,
Expand Down
Loading

0 comments on commit 7bc2237

Please sign in to comment.