📄 vboostapp.cpp
字号:
#include "stdafx.h"
#include "VBoostApp.h"
#include "UnkHook.h"
#include "FixedMemMgr.h"
#include "blinddel.h"
HRESULT CVBoostApp::CreateInstance(CVBoostApp** ppApp)
{
if (NULL == (*ppApp = new CVBoostApp()))
{
return E_OUTOFMEMORY;
}
(*ppApp)->AddRef();
return NOERROR;
}
STDMETHODIMP
CVBoostApp::HookQI(IUnknown *pUnk, IQIHook* pQIHook, UnkHookFlags uhFlags, UnknownHook** ppOwner)
{
if (pUnk == NULL || pQIHook == NULL)
{
// Note: we can't check ppOwner for NULL because VB will always
// send us a pointer to the out parameter, even if it is to a temp.
return 0x800A005B; // Object variable not set
}
// Note: We regenerate the typelib with mktyplib to force the typelib
// to contain stdole.IUnknown instead of VT_UNKNOWN. This means that,
// when VB calls this, pUnk will always be the controlling IUnknown.
// Otherwise, we would have to QI for IID_IUnknown here.
return CUnkHook::CreateInstance(pUnk, (IQIARHook*)pQIHook, uhFlags, false, ppOwner);
}
STDMETHODIMP
CVBoostApp::HookQIAR(IUnknown *pUnk, IQIARHook* pQIARHook, UnkHookFlags uhFlags, UnknownHook** ppOwner)
{
if (pUnk == NULL || pQIARHook == NULL)
{
// Note: we can't check ppOwner for NULL because VB will always
// send us a pointer to the out parameter, even if it is to a temp.
return 0x800A005B; // Object variable not set
}
// Note: We regenerate the typelib with mktyplib to force the typelib
// to contain stdole.IUnknown instead of VT_UNKNOWN. This means that,
// when VB calls this, pUnk will always be the controlling IUnknown.
// Otherwise, we would have to QI for IID_IUnknown here.
return CUnkHook::CreateInstance(pUnk, pQIARHook, uhFlags, true, ppOwner);
}
// This looks bizarre, but the IDL definition takes a true VT_UNKNOWN
// as the input and returns a stdole.IUnknown. When assigning
// to a stdole.IUnkown parameter that requires the true pointer instead
// of the controlling IUnknown, wrap the assignment with this function.
STDMETHODIMP
CVBoostApp::SafeUnknown(IUnknown* pUnknown, IUnknown** retVal)
{
if (*retVal = pUnknown)
{
pUnknown->AddRef();
}
return NOERROR;
}
// Blind delegator creation
STDMETHODIMP
CVBoostApp::CreateDelegator(IUnknown* punkOuter, IUnknown* punkDelegatee, VBGUIDPtr piid, BlindDelegatorPtr pEmbedded, long pfnDestroyEmbedded, IUnknown** ppvObj)
{
if (punkOuter == NULL ||
punkDelegatee == NULL ||
(pEmbedded == NULL && pfnDestroyEmbedded != NULL))
{
*ppvObj = NULL;
return E_INVALIDARG;
}
return _BlindDelegator::CreateDelegator(punkOuter, punkDelegatee, (IID*)piid, (_BlindDelegator*)pEmbedded, (DestroyBlindDelegator)pfnDestroyEmbedded, ppvObj);
}
// Blind delegator function pointer access
STDMETHODIMP
CVBoostApp::BlindFunctionPointer(long FunctionNumber, long *retVal)
{
// Test special value to get the whole vtable
if (FunctionNumber == -1)
{
*retVal = (long)&g_bdvtbl;
return NOERROR;
}
else
{
return ((ULONG)FunctionNumber > MAX_VTABLE_ENTRIES) ?
DISP_E_BADINDEX :
*retVal = (long)g_bdvtbl[FunctionNumber], NOERROR;
}
}
// Aggregate an existing unknown. This is similar to HookUnknown, but a QIHook
// implementation is provided based on the passed in data.
STDMETHODIMP
CVBoostApp::AggregateUnknown(IUnknown* pUnk, SAFEARRAY** pData, SAFEARRAY** pIIDs, UnknownHook** ppOwner)
{
return CUnkHookAggregate::CreateInstance(pUnk, *pData, *pIIDs, ppOwner);
}
// Helper function to turn a weak reference into a strong reference
// with the most efficient code possible. StrongRef is an [out] parameter
// so we don't have to worry about Releasing it, just setting the value. You
// either pass in a WeakRef (or variable) or a normal reference as the src.
STDMETHODIMP_(void)
CVBoostApp::AssignAddRef(void* pDst, void* pSrc)
{
if (*(IUnknown**)pDst = *(IUnknown**)pSrc)
{
(*(IUnknown**)pDst)->AddRef();
}
}
//STDMETHODIMP_(void)
void _declspec(naked) STDMETHODCALLTYPE
CVBoostApp::AssignSwap(void *pLeft, void *pRight)
{
// Optimized asm code
_asm
{
mov eax, [esp + 8]
mov edx, [esp + 12]
mov ecx, [eax]
xchg ecx, [edx]
mov [eax], ecx
ret 12
}
//C++ code, asm beats this by 3x
//void* tmp = *(void**)pLeft;
//*(void**)pLeft = *(void**)pRight;
//*(void**)pRight = tmp;
}
STDMETHODIMP
CVBoostApp::CreateFixedSizeMemoryManager(long ElementSize, long ElementsPerBlock, VARIANT_BOOL fCompactible, FixedSizeMemoryManager** retVal)
{
return fCompactible ?
CFixedMemMgrCompact::CreateInstance(ElementSize, ElementsPerBlock, retVal) :
CFixedMemMgr::CreateInstance(ElementSize, ElementsPerBlock, retVal);
}
// Like AggregateUnknown, except creates a new object instead of
// hooking to aggregate on top of an existing one.
STDMETHODIMP
CVBoostApp::CreateAggregate(SAFEARRAY** pData, SAFEARRAY** pIIDs, long pOwner, IUnknown** ppvObj)
{
return CAggregateObject::CreateInstance(*pData, *pIIDs, (IUnknown**)pOwner, ppvObj);
}
// VBoost Application Object ClassFactory
HRESULT CVBoostAppCF::Create(IUnknown** ppUnk)
{
return CVBoostApp::CreateInstance((CVBoostApp**)ppUnk);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -