typedef struct IBindStatusCallbackVtbl { BEGIN_INTERFACE HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IBindStatusCallback * This, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject); ULONG ( STDMETHODCALLTYPE *AddRef )( IBindStatusCallback * This); ULONG ( STDMETHODCALLTYPE *Release )( IBindStatusCallback * This); HRESULT ( STDMETHODCALLTYPE *OnStartBinding )( IBindStatusCallback * This, /* [in] */ DWORD dwReserved, /* [in] */ IBinding *pib); HRESULT ( STDMETHODCALLTYPE *GetPriority )( IBindStatusCallback * This, /* [out] */ LONG *pnPriority); HRESULT ( STDMETHODCALLTYPE *OnLowResource )( IBindStatusCallback * This, /* [in] */ DWORD reserved); HRESULT ( STDMETHODCALLTYPE *OnProgress )( IBindStatusCallback * This, /* [in] */ ULONG ulProgress, /* [in] */ ULONG ulProgressMax, /* [in] */ ULONG ulStatusCode, /* [in] */ LPCWSTR szStatusText); HRESULT ( STDMETHODCALLTYPE *OnStopBinding )( IBindStatusCallback * This, /* [in] */ HRESULT hresult, /* [unique][in] */ LPCWSTR szError); /* [local] */ HRESULT ( STDMETHODCALLTYPE *GetBindInfo )( IBindStatusCallback * This, /* [out] */ DWORD *grfBINDF, /* [unique][out][in] */ BINDINFO *pbindinfo); /* [local] */ HRESULT ( STDMETHODCALLTYPE *OnDataAvailable )( IBindStatusCallback * This, /* [in] */ DWORD grfBSCF, /* [in] */ DWORD dwSize, /* [in] */ FORMATETC *pformatetc, /* [in] */ STGMEDIUM *pstgmed); HRESULT ( STDMETHODCALLTYPE *OnObjectAvailable )( IBindStatusCallback * This, /* [in] */ REFIID riid, /* [iid_is][in] */ IUnknown *punk); END_INTERFACE } IBindStatusCallbackVtbl; interface IBindStatusCallback { CONST_VTBL struct IBindStatusCallbackVtbl *lpVtbl; };So, I've changed the fll so that I can define 16 callback functions in the order above
#define S_OK 0x0 #define E_NOTIMPL 0x80004001 #define E_NOINTERFACE 0x80004002 #undefine T_HANDLE #define POINTER Long #define LPVOID POINTER #define T_HANDLE POINTER #define DWORD Long #define Size_T DWORD #define VOID #define BOOL Integer #define THREAD_PRIORITY_NORMAL 0 #define BINDF_ASYNCHRONOUS 0x00000001 *--------------------------------------------------------------------------- function do_it() declare T_HANDLE GetProcessHeap in Win32api declare LPVOID HeapAlloc in Win32api T_HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes declare BOOL HeapFree in Win32api T_HANDLE hHeap, DWORD dwFlags, POINTER dwBytes declare VOID RtlMoveMemory in Kernel32 POINTER Dest, string @src, Size_T BytesToCopy Declare Integer URLDownloadToFile In urlmon.Dll ; Integer pCaller, String szURL, String szFileName, ; Integer dwReserved, long @lpfnCB local i,fn[11] fn[1] = CallBack_Set('iQueryInterface', 'iii') fn[2] = CallBack_Set('iAddRef', 'i') fn[3] = CallBack_Set('iRelease', 'i') fn[4] = CallBack_Set('OnStartBinding', 'iii') fn[5] = CallBack_Set('GetPriority', 'ii') fn[6] = CallBack_Set('OnLowResource', 'ii') fn[7] = CallBack_Set('OnProgress', 'iiiis') fn[8] = CallBack_Set('OnStopBinding', 'iii') fn[9] = CallBack_Set('GetBindInfo', 'iii') fn[10] = CallBack_Set('OnDataAvailable', 'iiiii') fn[11] = CallBack_Set('OnObjectAvailable', 'iii') local h0, h1, s s = bintochar(fn[1]) ; && iQueryInterface + bintochar(fn[2]) ; && iAddRef + bintochar(fn[3]) ; && iRelease + bintochar(fn[4]) ; && + bintochar(fn[5]) ; && + bintochar(fn[6]) ; && + bintochar(fn[7]) ; && + bintochar(fn[8]) ; && + bintochar(fn[9]) ; && + bintochar(fn[10]) ; && + bintochar(fn[11]) ; && *h0 = HeapAlloc(GetProcessHeap(), 0, 4) h1 = HeapAlloc(GetProcessHeap(), 0, len(m.s)) *=RtlMoveMemory(m.h0, bintochar(m.h1), 4) =RtlMoveMemory(m.h1, @m.s, len(m.s)) ?h0, h1 ?URLDownloadToFile(0, 'http://www.google.com', 'test.htm', 0, @m.h1) for i = 1 to 11 ?i, CallBack_Release(fn[m.i]) endfor *=HeapFree(GetProcessHeap(), 0, m.h0) =HeapFree(GetProcessHeap(), 0, m.h1) endfunc *--------------------------------------------------------------------------- function iQueryInterface(a, iid, ppvObject ) ?'iQueryInterface', a, iid, ppvObject *=RtlMoveMemory(m.ppvObject , bintochar(0), 4) return E_NOINTERFACE endfunc *--------------------------------------------------------------------------- function iAddRef(a) ?'iAddRef', a return 1 endfunc *--------------------------------------------------------------------------- function iRelease(a) ?'iRelease', a return 0 endfunc *--------------------------------------------------------------------------- function GetBindInfo(a, p_grfBINDF, p_pbindinfo) ?'GetBindInfo', a, p_grfBINDF, p_pbindinfo =RtlMoveMemory(m.p_grfBINDF, bintochar(BINDF_ASYNCHRONOUS), 4) return E_NOTIMPL endfunc *--------------------------------------------------------------------------- function GetPriority(a, pnPriority) ?'GetPriority', a, pnPriority =RtlMoveMemory(m.pnPriority, bintochar(THREAD_PRIORITY_NORMAL), 4) return S_OK endfunc *--------------------------------------------------------------------------- function OnDataAvailable(a, grfBSCF, dwSize, pformatetc, pstgmed) ?'OnDataAvailable', a, grfBSCF, dwSize, pformatetc, pstgmed return E_NOTIMPL endfunc *--------------------------------------------------------------------------- function OnLowResource(a, b) ?'OnLowResource', a, b return E_NOTIMPL endfunc *--------------------------------------------------------------------------- function OnObjectAvailable(a, riid, punk) ?'OnObjectAvailable', a, riid, punk return E_NOTIMPL endfunc *--------------------------------------------------------------------------- function OnProgress(x, ulProgress, ulProgressMax, ulStatusCode, szStatusText) ?'OnProgress', x, ulProgress, ulProgressMax, ulStatusCode, szStatusText return S_OK endfunc *--------------------------------------------------------------------------- function OnStartBinding(a, dwReserved, pib) ?'OnStartBinding', a, dwReserved, pib return S_OK endfunc *--------------------------------------------------------------------------- function OnStopBinding(a, hresult, szError) ?'OnStopBinding', a, hresult, szError return S_OK endfunc *---------------------------------------------------------------------------You see that all of the above functions receive one extra first parameter, a reference to this (com object)
iAddRef 1501576 && this is 'this'. You'll find it in the next two calls as well GetBindInfo 1501576, 1541308, 1541460 iQueryInterface 1501576, 1998995068, 1301804 && exeption here. I ignore the error so that the program releases the callback functionsNo doubt that I'm doing something wrong somewhere. But now, at the end of the day (no pun), I don't see it