Найти индекс конкретной функции в таблице Vtable COM-интерфейса

Я пытаюсь подключить функцию SetCooperativeLevel в объекте DirectDraw. Моя цель очень похожа на цель в этом вопросе Перехват API для функции объекта COM ? однако единственная проблема в том, что я не знаю точного смещения в vtable IDirectDraw для SetCooperativeLevel. Есть ли способ почерпнуть это, возможно, <ddraw.h> или программно?

Вот объявление интерфейса для IDirectDraw, однако я не уверен, как это соответствует vtable.

DECLARE_INTERFACE_( IDirectDraw, IUnknown )
{
    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
    STDMETHOD_(ULONG,Release) (THIS) PURE;
    STDMETHOD(Compact)(THIS) PURE;
    STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE;
    STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE;
    STDMETHOD(CreateSurface)(THIS_  LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE;
    STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE;
    STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE;
    STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE;
    STDMETHOD(FlipToGDISurface)(THIS) PURE;
    STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE;
    STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE;
    STDMETHOD(GetFourCCCodes)(THIS_  LPDWORD, LPDWORD ) PURE;
    STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE;
    STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE;
    STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE;
    STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE;
    STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE;
    STDMETHOD(RestoreDisplayMode)(THIS) PURE;
    STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE;    // I'm trying to hook this
    STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE;
    STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE;
};

person cplusplus    schedule 31.03.2012    source источник
comment
Просто посчитайте, начиная с 0. Итак, это 20 * 4 для 32-битного кода, 20 * 8 для 64-битного кода. Остерегайтесь унаследованных интерфейсов. Этот только наследует IUnknown и уже имеет перечисленные 3 метода. Не совсем типично для IDL.   -  person Hans Passant    schedule 01.04.2012


Ответы (1)


Отвечая на свой вопрос: vtable выложена в том же порядке, в котором объявлены интерфейсные функции.

person cplusplus    schedule 01.04.2012
comment
Да, в основном вам нужно знать две вещи: фактический порядок - это порядок объявления (включая унаследованные интерфейсы, особенно IUnknown) и то, что вы можете создать двоичный файл с определенным вызовом, установить точку останова, переключиться на разборку и быстро найти индекс проверка того, какой компилятор сгенерирован для конкретного метода. - person Roman R.; 01.04.2012