I am tring to use urlopenstream and read the data from the file on the internet.. Right now the file on the internet has the word Test in it. I am pretty sure i got it set up most the way but there is still a few things that i have not figured out. If i create a stream then my IStream.Read works or appears to work as it does not crash the program. This leaves my problem to geting the pointer of the stream from pstgmed passed into my OnDataAvailableProc. I have some c/c++ code commented out but i am not really well with that so i failed to translate it. If someone could fix this and explain it to me or point me in the direction of getting it to work i would appreciate it.
[attachment deleted by admin]
Error on
"mov ecx, [objIStream]" OnDataAvailableProc PROC lpThis:DWORD, grfBSCF:DWORD, dwSize:DWORD,pfmtetc:DWORD,pstgmed:DWORD
; INVOKE CreateStreamOnHGlobal,0,1,ADDR objIStream
mov ecx, [objIStream]
push ecx
mov eax, [ecx]
call [eax+IStream.Read]
mov eax,[objIStream]
mov ecx,[eax]
push eax
call [ecx+IStream.IUnknown.Release]
Quote#include "stdafx.h"
#include "URLStreamCallback.h"
// URLStreamCallback-Factory
URLStreamCallback *CreateURLStreamCallback()
{
URLStreamCallback *pCallback = new URLStreamCallback;
pCallback->AddRef();
return pCallback;
}
//////////////////////////////////////////////////////777
URLStreamCallback::URLStreamCallback()
{
refCounter = 0;
onFinished = NULL;
dataAvailable = false;
}
HRESULT URLStreamCallback::OnStartBinding(
/* [in] */ DWORD dwReserved,
/* [in] */ IBinding __RPC_FAR *pib)
{
TRACE("OnStartBinding\n");
return S_OK;
}
HRESULT URLStreamCallback::GetPriority(
/* [out] */ LONG __RPC_FAR *pnPriority)
{
TRACE("GetPriority\n");
return S_OK;
}
HRESULT URLStreamCallback::OnLowResource(
/* [in] */ DWORD reserved)
{
TRACE("OnLowResource\n");
return S_OK;
}
HRESULT URLStreamCallback::OnProgress(
/* [in] */ ULONG ulProgress,
/* [in] */ ULONG ulProgressMax,
/* [in] */ ULONG ulStatusCode,
/* [in] */ LPCWSTR szStatusText)
{
TRACE("OnProgress(%s)\n",szStatusText);
return S_OK;
}
HRESULT URLStreamCallback::OnStopBinding(
/* [in] */ HRESULT hresult,
/* [unique][in] */ LPCWSTR szError)
{
TRACE("OnStopBinding(%s)\n",szError);
if(onFinished) onFinished();
return S_OK;
}
HRESULT URLStreamCallback::GetBindInfo(
/* [out] */ DWORD __RPC_FAR *grfBINDF,
/* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo)
{
TRACE("GetBindInfo\n");
return S_OK;
}
HRESULT URLStreamCallback::OnDataAvailable(
/* [in] */ DWORD grfBSCF,
/* [in] */ DWORD dwSize,
/* [in] */ FORMATETC __RPC_FAR *pformatetc,
/* [in] */ STGMEDIUM __RPC_FAR *pstgmed)
{
TRACE("OnDataAvailable\n");
CString buf;
char*p=buf.GetBufferSetLength(1001);
ULONG nRead;
if(S_OK==pstgmed->pstm->Read(p,1000,&nRead))
{
p[nRead]=0;
buf.ReleaseBuffer();
CString upper(buf); upper.MakeUpper();
int a=upper.Find("<TITLE>");
int b=upper.Find("</TITLE>");
if(a>=0 && b>=0 && a<b){
readTitle = buf.Mid(a+7,b-a-7);
TRACE("Title: %s\n",readTitle);
}
}
dataAvailable = true;
return S_OK;
}
HRESULT URLStreamCallback::OnObjectAvailable(
/* [in] */ REFIID riid,
/* [iid_is][in] */ IUnknown __RPC_FAR *punk)
{
TRACE("OnObjectAvailable\n");
return S_OK;
}
// IUnknown mehthods
HRESULT URLStreamCallback::QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
{
TRACE("URLStreamCallback::QueryInterface\n");
if(riid==IID_IUnknown)
*ppvObject = (IUnknown*)this;
else if(riid==IID_IBindStatusCallback)
*ppvObject = (IBindStatusCallback*)this;
else
return E_NOINTERFACE;
return S_OK;
}
ULONG URLStreamCallback::AddRef( void)
{
TRACE("URLStreamCallback::AddRef\n");
return ++refCounter;
}
ULONG URLStreamCallback::Release( void)
{
TRACE("URLStreamCallback::Release\n");
if(0==--refCounter){
delete this;
return 0;
}
return refCounter;
}
;//==============================================================================
// URLStreamCallback.h
class URLStreamCallback : public IBindStatusCallback
{
public:
URLStreamCallback();
void SetOnFinished( void (*finished)() )
{ onFinished=finished; }
bool hasData()
{ return dataAvailable; }
CString getTitle() { return readTitle; }
// IBindStatusCallback methods
virtual HRESULT STDMETHODCALLTYPE OnStartBinding(
/* [in] */ DWORD dwReserved,
/* [in] */ IBinding __RPC_FAR *pib);
virtual HRESULT STDMETHODCALLTYPE GetPriority(
/* [out] */ LONG __RPC_FAR *pnPriority);
virtual HRESULT STDMETHODCALLTYPE OnLowResource(
/* [in] */ DWORD reserved);
virtual HRESULT STDMETHODCALLTYPE OnProgress(
/* [in] */ ULONG ulProgress,
/* [in] */ ULONG ulProgressMax,
/* [in] */ ULONG ulStatusCode,
/* [in] */ LPCWSTR szStatusText);
virtual HRESULT STDMETHODCALLTYPE OnStopBinding(
/* [in] */ HRESULT hresult,
/* [unique][in] */ LPCWSTR szError);
virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetBindInfo(
/* [out] */ DWORD __RPC_FAR *grfBINDF,
/* [unique][out][in] */ BINDINFO __RPC_FAR *pbindinfo);
virtual /* [local] */ HRESULT STDMETHODCALLTYPE OnDataAvailable(
/* [in] */ DWORD grfBSCF,
/* [in] */ DWORD dwSize,
/* [in] */ FORMATETC __RPC_FAR *pformatetc,
/* [in] */ STGMEDIUM __RPC_FAR *pstgmed);
virtual HRESULT STDMETHODCALLTYPE OnObjectAvailable(
/* [in] */ REFIID riid,
/* [iid_is][in] */ IUnknown __RPC_FAR *punk);
// IUnknown mehthods
virtual HRESULT STDMETHODCALLTYPE QueryInterface(
/* [in] */ REFIID riid,
/* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
virtual ULONG STDMETHODCALLTYPE AddRef( void);
virtual ULONG STDMETHODCALLTYPE Release( void);
protected:
ULONG refCounter;
CString readTitle; // read title
bool dataAvailable;
void (*onFinished)();
};
// URLStreamCallback-Factory
URLStreamCallback *CreateURLStreamCallback();
i dont think that is what i need. I am writing the code in masm and i dont have an error on mov ecx, [objIStream] that i am aware of. It compiles fine. Well it does if you uncomment the line above it that creates the stream. From what i gather is the stream is already created and passed into this fuction. I am not sure if that is accurate and that could be why icant get this to work but where i have the call to create the stream, i think is the point where i need to get the stream handle from the pstm member passeed in through pstgmed. Then once the IStream.Read is called how to store the information. Is it returned in eax?
anyone have an idea how to get this working in masm?
maybe someone has an example of using URLOpenStream in MASM??
Well after lots of tring different things i have managed to get it working. :dance:
For those of you who care here is the new code that works...
OnDataAvailableProc PROC lpThis:DWORD, grfBSCF:DWORD, dwSize:DWORD,pfmtetc:DWORD,pstgmed:DWORD
LOCAL dwRead:DWORD
lea eax, DWORD PTR dwRead
push eax
push 255
lea ecx, DWORD PTR tmpString
push ecx
mov edx, DWORD PTR pstgmed
mov eax, DWORD PTR [edx+4]
mov ecx, DWORD PTR pstgmed
mov edx, DWORD PTR [ecx+4]
mov ecx, DWORD PTR [edx]
push eax
call DWORD PTR [ecx+12]
@@:
xor eax, eax
ret
OnDataAvailableProc ENDP
whatever you read will be in tmpString. This is just the basics though since you can recieve data in chunks from what i gather. This works just fine for me as i read 4 bytes however i will add code to check and see if the read was successful or not.
And shorter as i had stuff that was not needed fom what i can tell..
OnDataAvailableProc PROC lpThis:DWORD, grfBSCF:DWORD, dwSize:DWORD,pfmtetc:DWORD,pstgmed:DWORD
LOCAL dwRead:DWORD
lea eax, DWORD PTR dwRead
push eax
push 255
lea ecx, DWORD PTR tmpString
push ecx
mov edx, DWORD PTR pstgmed
mov eax, DWORD PTR [edx+4]
mov ecx, DWORD PTR [eax]
push eax
call DWORD PTR [ecx+12]
xor eax, eax
ret
OnDataAvailableProc ENDP