Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Using vfp.fll for callback to URLDownloadToFile
Message
From
19/06/2005 12:55:35
 
General information
Forum:
Visual FoxPro
Category:
Windows API functions
Environment versions
Visual FoxPro:
VFP 6 SP5
Miscellaneous
Thread ID:
01024680
Message ID:
01024703
Views:
24
hi Michael,

I've googled a lot. I've gotten a bit further than you, but stuck too
I'm afraid it is not as simple as that

The fll I provided makes it possible (emulates) to pass an address of a vfp function

The last parameter to URLDownloadToFile is a pointer to an IBindStatusCallback interface. ( and I'm not too familiar with that)

As I understand it you are passing an address. That address is a pointer to a structure which contains 11 addresses. Each address (of the 11) is an address of a function
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

Here's the program
#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)

I receive exactly 3 calls, with a DLL exeption on the last
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 functions
No doubt that I'm doing something wrong somewhere. But now, at the end of the day (no pun), I don't see it
Gregory
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform