Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

COM WinHttpRequest ResponseStream


  • Please log in to reply
18 replies to this topic
  • Guests
  • Last active:
  • Joined: --
First of all, what does the ResponseStream property contain? MSDNsays,

Property value

A Variant that receives a pointer to an IUnknown interface that can be queried for an IStream interface. This stream returns the raw data as received directly from the server.

When I run this, it doesn't return a interface ID. So it's not an COM interface pointer.
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif", True) 	
pWHttp.Send()
pWHttp.WaitForResponse(5)
vStream := pWHttp.ResponseStream
msgbox % "Is Obect:`t" IsObject(vStream) "`n" 
	. "IID:`t" ComObjType(vStream, "IID")		;empty. this means it's not an COM interface pointer.
It also says,

Remarks

Call QueryInterface on the returned pointer to obtain a pointer to an IStream interface. This property returns the response data as an IStream. This property can only be invoked after the Send method has been called.

So I guess ComObjQuery() is requried for this task. This doesn't work. Any idea?
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif", True) 	
pWHttp.Send()
pWHttp.WaitForResponse(5)
vStream := pWHttp.ResponseStream
pIStream := ComObjQuery(vStream, "0000000c-0000-0000-C000-000000000046")	;IID for the IStr
msgbox % IsObject(pIStream) ;returns 0


  • Guests
  • Last active:
  • Joined: --
Got it working. 8)
#include <Class_DllStruct>		;DllStruct by just me http://www.autohotkey.com/forum/topic74240.html

	pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	pWHttp.Open("GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif", False) 	
	pWHttp.Send()
	pWHttp.WaitForResponse(5)
	vStream := pWHttp.ResponseStream
	if (ComObjType(vStream) = 0xD) {      ;VT_UNKNOWN = 0xD
		pIStream := ComObjQuery(vStream, "{0000000c-0000-0000-C000-000000000046}")	;defined in ObjIdl.h
		tagSTATSTG := new DllStruct(def_tagSTATSTG())

		hResult := DllCall(NumGet(NumGet(pIStream + 0) + 12 * A_PtrSize)	 ; IStream::Stat defined in ObjIdl.h
			, "ptr", pIStream
			, "ptr", tagSTATSTG.GetPtr()
			, "uint", STATFLAG_NONAME := 1)
		if (hResult != 0x00000000)
			msgbox % "IStream::Stat Failed `nError Code: " hResult
		
		VarSetCapacity(strBuffer, tagSTATSTG.cbSize)
		VarSetCapacity(cbRead, tagSTATSTG.cbSize)
		hResult := DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)	; IStream::Read 
			, "ptr", pIStream
			, "ptr", &strBuffer
			, "uint", tagSTATSTG.cbSize
			, "uint*", &cbRead)
		if (hResult != 0x00000000)
			msgbox IStream::Read Failed`nError Code: %hResult%

      if (cbRead < tagSTATSTG.cbSize)
      {
		;here we need a way to extract binary data with a specified byte size.
		; VarSetCapacity(strBuffer, cbRead)   ;doesn't work
      }
       
	pIStream := ""
	oFile := FileOpen( A_ScriptDIr "\ms-banner.gif", "w")
	oFile.RawWrite(&strBuffer, tagSTATSTG.cbSize)
	oFile.Close() 		
   
	msgbox File saved
	run % A_ScriptDIr "\ms-banner.gif"
	}
   
def_tagSTATSTG() {
	def_mtime := "
	(LTrim Join
	  DWORD dwLowDateTime1;
	  DWORD dwHighDateTime1;
	)"
	def_ctime := "
	(LTrim Join
		DWORD dwLowDateTime2;
		DWORD dwHighDateTime2;
	)"
	def_atime := "
	(LTrim Join
		DWORD dwLowDateTime3;
		DWORD dwHighDateTime3;
	)"
	;CLSID is the same as a GUID structure
	def_clsid := "	
	(LTrim Join
		DWORD Data1;    
		WORD Data2;     
		WORD Data3;     
		BYTE Data4[8];   
	)"
	def_tagSTATSTG := "
	(LTrim Join
		HANDLE       pwcsName;
		DWORD          type;
		INT64 cbSize;
		" def_mtime "
		" def_ctime "
		" def_atime "
		DWORD          grfMode;
		DWORD          grfLocksSupported;
		" def_clsid "
		DWORD          grfStateBits;
		DWORD          reserved;
	)"
	return def_tagSTATSTG 
}


  • Guests
  • Last active:
  • Joined: --
Now can somebody translate this? This one reads the data by chunks.
' ========================================================================================
' The following example shows how to open an HTTP connection, send an HTTP request, and
' read the response as an IStream. The data from the IStream is written to a file.
' ========================================================================================

#COMPILE EXE
#DIM ALL
#DEBUG ERROR ON
#INCLUDE "httprequest.inc"
#INCLUDE "ole2utils.inc"

' ========================================================================================
' Main
' ========================================================================================
FUNCTION PBMAIN

   LOCAL pWHttp AS IWinHttpRequest
   LOCAL vSTream AS VARIANT
   LOCAL pIStream AS IStream
   LOCAL Buffer AS STRING * 8192
   LOCAL strBuffer AS STRING
   LOCAL cb AS DWORD
   LOCAL cbRead AS DWORD
   LOCAL iSucceeded AS INTEGER

   ' Creates an instance of the HTTP service
   pWHttp = NEWCOM "WinHttp.WinHttpRequest.5.1"
   IF ISNOTHING(pWHttp) THEN EXIT FUNCTION

   TRY
      ' Opens an HTTP connection to an HTTP resource
      pWHttp.Open UCODE$("GET"), UCODE$("http://www.microsoft.com/library/homepage/images/ms-banner.gif")
      ' Sends an HTTP request to the HTTP server
      pWHttp.Send
      ' Wait for response with a timeout of 5 seconds
      iSucceeded = pWHttp.WaitForResponse(5)
      ' Get the response as a stream
      vStream = pWHttp.ResponseStream
      IF VARIANTVT(vStream) = %VT_UNKNOWN THEN
         pIStream = vStream
         vStream = EMPTY
         ' Read the stream in chunks
         DO
            pIStream.Read VARPTR(buffer), SIZEOF(buffer), cbRead
            IF cbRead = 0 THEN EXIT DO
            IF cbRead < SIZEOF(buffer) THEN
               strBuffer = strBuffer & LEFT$(buffer, cbRead)
            ELSE
               strBuffer = strBuffer & buffer
            END IF
         LOOP
         pIStream = NOTHING
         ' Save the buffer into a file
         OPEN "ms-banner.gif" FOR BINARY AS #1
         PUT #1, 1, strBuffer
         CLOSE #1
         MSGBOX "File saved"
      END IF
   CATCH
      OleShowErrorInfo OBJRESULT
   END TRY

END FUNCTION
' ========================================================================================

I cannot figure out the part in the loop.
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif", False) 	
pWHttp.Send()
pWHttp.WaitForResponse(5)
vStream := pWHttp.ResponseStream

if (ComObjType(vStream) = 0xD) {      ;VT_UNKNOWN = 0xD
	pIStream := ComObjQuery(vStream, "{0000000c-0000-0000-C000-000000000046}")	;defined in ObjIdl.h
/*
	pIStream.Read VARPTR(buffer), SIZEOF(buffer), cbRead
	IF cbRead = 0 THEN EXIT DO
	IF cbRead < SIZEOF(buffer) THEN
	   strBuffer = strBuffer & LEFT$(buffer, cbRead)
	ELSE
	   strBuffer = strBuffer & buffer
	END IF	
*/
	VarSetCapacity(Buffer, 8192)
	VarSetCapacity(cbRead, 4)	
	Loop {	
		hResult := DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)	; IStream::Read 
			, "ptr", pIStream	
			, "ptr", &Buffer				;pv [out] A pointer to the buffer which the stream data is read into.
			, "uint", 8192				;cb [in] The number of bytes of data to read from the stream object.
			, "uint*", &cbRead)		;pcbRead [out] A pointer to a ULONG variable that receives the actual number of bytes read from the stream object. 
		; If (cbRead < SIZEOF(buffer))
		
		; strBuffer .= Buffer
	} Until (cbRead = 0)
	

	ObjRelease(pIStream) 
	pIStream := ""
	FileAppend, % strBuffer, "*" A_ScriptDIr "\ms-banner.gif"
	; oFile := FileOpen( A_ScriptDIr "\ms-banner.gif", "w")
	; oFile.RawWrite(&strBuffer, tagSTATSTG.cbSize)
	; oFile.Close() 		

	msgbox File saved
	run % A_ScriptDIr "\ms-banner.gif"
}


  • Guests
  • Last active:
  • Joined: --
Got it working 8)
pWHttp := ComObjCreate("WinHttp.WinHttpRequest.5.1")
pWHttp.Open("GET", "http://www.microsoft.com/library/homepage/images/ms-banner.gif", False) 	
pWHttp.Send()
pWHttp.WaitForResponse(5)
vStream := pWHttp.ResponseStream

if (ComObjType(vStream) = 0xD) {      ;VT_UNKNOWN = 0xD
	pIStream := ComObjQuery(vStream, "{0000000c-0000-0000-C000-000000000046}")	;defined in ObjIdl.h

	oFile := FileOpen( A_ScriptDIr "\ms-banner.gif", "w")
	Loop {	
		VarSetCapacity(Buffer, 8192)
		hResult := DllCall(NumGet(NumGet(pIStream + 0) + 3 * A_PtrSize)	; IStream::Read 
			, "ptr", pIStream	
			, "ptr", &Buffer			;pv [out] A pointer to the buffer which the stream data is read into.
			, "uint", 8192			;cb [in] The number of bytes of data to read from the stream object.
			, "ptr*", cbRead)		;pcbRead [out] A pointer to a ULONG variable that receives the actual number of bytes read from the stream object. 
		oFile.RawWrite(&Buffer, cbRead)
	} Until (cbRead = 0)
	ObjRelease(pIStream) 
	oFile.Close() 			
	if FileExist(A_ScriptDIr "\ms-banner.gif")
		run % A_ScriptDIr "\ms-banner.gif"
	else
		msgbox File Not Exist
}