📄 blinddel.cpp
字号:
#include "stdafx.h"
#include "blinddel.h"
//
// Create a blind or callback delegator
// punkOuter Controlling IUnknown
// punkDelegatee vtable being wrapped
// piid iid to QI for, or NULL if punkDelegatee is the correct vtable
// pEmbeddedThis A pointer to a _BlindDelegator struct that has already been created.
// pfnDestroy A function pointer used to destroy the value in pEmbeddedThis
// ppvObj output parameter
//
HRESULT _BlindDelegator::CreateDelegator(IUnknown *punkOuter, IUnknown *punkDelegatee, const IID* piid, _BlindDelegator* pEmbeddedThis, DestroyBlindDelegator pfnDestroy, IUnknown **ppvObj)
{
IUnknown *pItf;
HRESULT hr;
*ppvObj = NULL;
if (piid)
{
// Make sure we're delegating to the correct interface
hr = punkDelegatee->QueryInterface(*piid, (void**)&pItf);
}
else
{
// The correct interface is being passed in, no need to QI
(pItf = punkDelegatee)->AddRef();
hr = NOERROR;
}
if (SUCCEEDED(hr))
{
_BlindDelegator *pDel = pEmbeddedThis;
if (pDel)
{
// We must have some value for the a function pointer
// because destruction keys off this value to determine
// if we're embedded or heap allocated.
if (pfnDestroy == NULL)
{
pfnDestroy = (DestroyBlindDelegator)-1;
}
}
else if (pDel = new _BlindDelegator())
{
ADD_OBJECT;
}
if (pDel)
{
pDel->m_dwRefs = 1;
(pDel->m_punkOuter = punkOuter)->AddRef();
pDel->m_punkInner = pItf;
pDel->m_pVTable = &g_bdvtbl;
pDel->m_pfnDestroy = pfnDestroy;
*ppvObj = (IUnknown*)(LPBYTE(pDel) + offsetof(_BlindDelegator, m_pVTable));
}
else
{
pItf->Release();
hr = E_OUTOFMEMORY;
}
}
return hr;
}
ULONG _BlindDelegator::DestroyThis()
{
IUnknown *punkOuter = m_punkOuter;
ULONG retVal = 0;
if (m_pfnDestroy)
{
IUnknown *punkInner = m_punkInner;
m_punkOuter = NULL;
m_punkInner = NULL;
if ((long)m_pfnDestroy != -1)
{
retVal = m_pfnDestroy(this, &punkInner, &punkOuter);
}
if (punkInner)
{
punkInner->Release();
}
if (punkOuter)
{
retVal = punkOuter->Release();
}
}
else
{
m_punkInner->Release();
delete this;
REMOVE_OBJECT;
retVal = punkOuter->Release();
}
return retVal;
}
__declspec(naked) void BDQueryInterface()
{
_asm
{
mov eax, DWORD PTR [esp + 4] // move BD::this into eax
mov eax, DWORD PTR [eax + 8] // move BD::this->m_punkOuter into eax
mov DWORD PTR [esp + 4], eax // move eax into "this" position on stack
mov eax, DWORD PTR [eax] // move base of vtable into eax
jmp DWORD PTR [eax] // jmp to the actual function, which is eax + function number
}
}
__declspec(naked) void Thunk()
{
_asm
{
mov eax, DWORD PTR [esp + 4] // move BD::this into eax
mov eax, DWORD PTR [eax + 4] // move BD::this->m_punkInner into eax
mov [esp + 4], eax // move eax into "this" position on stack
mov eax, DWORD PTR [eax] // move base of vtable into eax
jmp DWORD PTR [eax + ecx] // jmp to the actual function, which is eax + function number
}
}
enum { SZPFN = sizeof(void (*)()) };
#define METHODTHUNK(n) void __declspec(naked) methodthunk##n() { _asm { mov ecx, (n * SZPFN) } _asm { jmp Thunk } }
#define METHODTHUNK10(n10) \
METHODTHUNK(n10##0) \
METHODTHUNK(n10##1) \
METHODTHUNK(n10##2) \
METHODTHUNK(n10##3) \
METHODTHUNK(n10##4) \
METHODTHUNK(n10##5) \
METHODTHUNK(n10##6) \
METHODTHUNK(n10##7) \
METHODTHUNK(n10##8) \
METHODTHUNK(n10##9) \
#define METHODTHUNK100(n100) \
METHODTHUNK10(n100##0) \
METHODTHUNK10(n100##1) \
METHODTHUNK10(n100##2) \
METHODTHUNK10(n100##3) \
METHODTHUNK10(n100##4) \
METHODTHUNK10(n100##5) \
METHODTHUNK10(n100##6) \
METHODTHUNK10(n100##7) \
METHODTHUNK10(n100##8) \
METHODTHUNK10(n100##9) \
METHODTHUNK(3)
METHODTHUNK(4)
METHODTHUNK(5)
METHODTHUNK(6)
METHODTHUNK(7)
METHODTHUNK(8)
METHODTHUNK(9)
METHODTHUNK10(1)
METHODTHUNK10(2)
METHODTHUNK10(3)
METHODTHUNK10(4)
METHODTHUNK10(5)
METHODTHUNK10(6)
METHODTHUNK10(7)
METHODTHUNK10(8)
METHODTHUNK10(9)
METHODTHUNK100(1)
METHODTHUNK100(2)
METHODTHUNK100(3)
METHODTHUNK100(4)
METHODTHUNK100(5)
METHODTHUNK100(6)
METHODTHUNK100(7)
METHODTHUNK100(8)
METHODTHUNK100(9)
METHODTHUNK10(100)
METHODTHUNK10(101)
METHODTHUNK(1020)
METHODTHUNK(1021)
METHODTHUNK(1022)
METHODTHUNK(1023)
#define UMTHUNK(n) reinterpret_cast<VTBL_ENTRY>(methodthunk##n),
#define UMTHUNK10(n) \
UMTHUNK(n##0) \
UMTHUNK(n##1) \
UMTHUNK(n##2) \
UMTHUNK(n##3) \
UMTHUNK(n##4) \
UMTHUNK(n##5) \
UMTHUNK(n##6) \
UMTHUNK(n##7) \
UMTHUNK(n##8) \
UMTHUNK(n##9) \
#define UMTHUNK100(n) \
UMTHUNK10(n##0) \
UMTHUNK10(n##1) \
UMTHUNK10(n##2) \
UMTHUNK10(n##3) \
UMTHUNK10(n##4) \
UMTHUNK10(n##5) \
UMTHUNK10(n##6) \
UMTHUNK10(n##7) \
UMTHUNK10(n##8) \
UMTHUNK10(n##9) \
const VTABLE g_bdvtbl = {
//reinterpret_cast<VTBL_ENTRY>(_BlindDelegator::QueryInterface),
reinterpret_cast<VTBL_ENTRY>(BDQueryInterface),
reinterpret_cast<VTBL_ENTRY>(_BlindDelegator::AddRef),
reinterpret_cast<VTBL_ENTRY>(_BlindDelegator::Release),
UMTHUNK(3)
UMTHUNK(4)
UMTHUNK(5)
UMTHUNK(6)
UMTHUNK(7)
UMTHUNK(8)
UMTHUNK(9)
UMTHUNK10(1)
UMTHUNK10(2)
UMTHUNK10(3)
UMTHUNK10(4)
UMTHUNK10(5)
UMTHUNK10(6)
UMTHUNK10(7)
UMTHUNK10(8)
UMTHUNK10(9)
UMTHUNK100(1)
UMTHUNK100(2)
UMTHUNK100(3)
UMTHUNK100(4)
UMTHUNK100(5)
UMTHUNK100(6)
UMTHUNK100(7)
UMTHUNK100(8)
UMTHUNK100(9)
UMTHUNK10(100)
UMTHUNK10(101)
UMTHUNK(1020)
UMTHUNK(1021)
UMTHUNK(1022)
UMTHUNK(1023)
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -