Issue with WinHTTP

Windows specific questions.
Post Reply
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Issue with WinHTTP

Post by UEZ »

I'm trying to read the source code from a web site using the WinHTTP example code from MS but the code is crashing with memory access violation.

The test code:

Code: Select all

#Include Once "windows.bi"

Type HINTERNET As LPVOID

Const CRLF = Chr(10, 13), WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0, WINHTTP_ACCESS_TYPE_NO_PROXY = 1, WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4, WINHTTP_FLAG_ESCAPE_DISABLE = &h00000040, INTERNET_DEFAULT_HTTPS_PORT = 443, INTERNET_DEFAULT_HTTP_PORT = 80, INTERNET_DEFAULT_PORT = 0, WINHTTP_NO_PROXY_NAME = 0, WINHTTP_NO_PROXY_BYPASS = 0, WINHTTP_NO_REFERER = 0, WINHTTP_DEFAULT_ACCEPT_TYPES = 0, WINHTTP_FLAG_SECURE = &h00800000, WINHTTP_NO_ADDITIONAL_HEADERS = 0, WINHTTP_NO_REQUEST_DATA = 0

Dim Shared As Boolean __bStartup_WinHTTP = False
Dim Shared As Any Ptr __hWinHTTPLib
Dim Shared WinHttpOpen As Function(sUserAgent As LPCWSTR, iAccessType As Long, sProxyName As LPCWSTR, sProxyBypass As LPCWSTR, iFlag As Long) As HINTERNET
Dim Shared WinHttpCloseHandle As Function(__hWinHTTPLib As Any Ptr) As Boolean
Dim Shared WinHttpConnect As Function(hSession As HINTERNET, sServerName As LPCWSTR, iServerPort As Long, Reserved As DWORD) As HINTERNET
Dim Shared WinHttpOpenRequest As Function(hConnect As HINTERNET, sVerb As LPCWSTR, sObjectName As LPCWSTR, sVersion As LPCWSTR, sReferrer As LPCWSTR, pAcceptTypes As Any Ptr, iFlags As Long) As HINTERNET
Dim Shared WinHttpSendRequest As Function(hInternet As HINTERNET, sHeader As LPCWSTR, iHeadersLength As Long, pOptionalBuff As HINTERNET, iOptionalLength As Long, iTotalLength As Long, pContext As DWORD_PTR) As Boolean
Dim Shared WinHttpReceiveResponse As Function(hInternet As HINTERNET, iReserved As LPVOID) As Boolean
Dim Shared WinHttpReadData As Function(hRequest As HINTERNET, pBuffer As LPVOID, iumberOfBytesToRead As Long, pNumberOfBytesRead As LPDWORD) As Boolean
Dim Shared WinHttpQueryDataAvailable As Function(hRequest As HINTERNET, pNumberOfBytesAvailable As LPDWORD) As Boolean

Sub _WinHttpStartup()
	__hWinHTTPLib = Dylibload("Winhttp.dll")
	If __hWinHTTPLib = 0 Then Return
	WinHttpOpen = Dylibsymbol(__hWinHTTPLib, "WinHttpOpen")
	WinHttpCloseHandle = Dylibsymbol(__hWinHTTPLib, "WinHttpCloseHandle")
	WinHttpConnect = Dylibsymbol(__hWinHTTPLib, "WinHttpConnect")
	WinHttpOpenRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpOpenRequest")
	WinHttpSendRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpSendRequest")
	WinHttpReceiveResponse = Dylibsymbol(__hWinHTTPLib, "WinHttpReceiveResponse")
	WinHttpReadData = Dylibsymbol(__hWinHTTPLib, "WinHttpReadData")
	__bStartup_WinHTTP = True
End Sub

Sub _WinHttpShutdown()
	If __hWinHTTPLib Then Dylibfree(__hWinHTTPLib)
End Sub

Dim As Any Ptr hSession = 0, hConnect = 0, hRequest = 0
Dim As String sRead

_WinHttpStartup()

hSession = WinHttpOpen( WStr("WinHTTP Example/1.0"), _ 
						WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, _
						WINHTTP_NO_PROXY_NAME, _
						WINHTTP_NO_PROXY_BYPASS, 0)
? "hSession = " & Hex(hSession)

If hSession Then
	hConnect = WinHttpConnect( hSession, Wstr("www.microsoft.com"), _
                               INTERNET_DEFAULT_PORT, 0)
End If
? "hConnect = " & Hex(hConnect)

If hConnect Then
	hRequest = WinHttpOpenRequest( hConnect, Wstr("GET"), NULL, _
										   NULL, WINHTTP_NO_REFERER, _
										   WINHTTP_DEFAULT_ACCEPT_TYPES, _
										   WINHTTP_FLAG_SECURE)	
End If
? "hRequest = " & Hex(hRequest)

Dim As Boolean bResults

If hRequest Then
	bResults = WinHttpSendRequest( hRequest, _
								   WINHTTP_NO_ADDITIONAL_HEADERS, _
								   0, WINHTTP_NO_REQUEST_DATA, 0, _
								   0, 0)
End If
? "bResult = " &  bResults

If bResults Then
	bResults = WinHttpReceiveResponse( hRequest, NULL)
End If
? "bResult = " &  bResults

If bResults Then
	Dim As ULong dwSize = 0
	Do 
		If WinHttpQueryDataAvailable( hRequest, @dwSize) = 0 Then ? "Error in WinHttpQueryDataAvailable. " & GetLastError()
		 
	Loop Until dwSize = 0
End If

WinHttpCloseHandle(hRequest)
WinHttpCloseHandle(hConnect)
WinHttpCloseHandle(hSession)
_WinHttpShutdown()
Sleep
As soon as line 78 will be executed (WinHttpQueryDataAvailable) the program crashes with exception code: 0xc0000005.

Any help?

Thx.
erik
Posts: 39
Joined: Dec 28, 2020 17:27
Location: Krasnoyarsk
Contact:

Re: Issue with WinHTTP

Post by erik »

Beekause WinHttpQueryDataAvailable is NULL. You should get a pointer to a function like this:

Code: Select all

WinHttpQueryDataAvailable = Dylibsymbol(__hWinHTTPLib, "WinHttpQueryDataAvailable")
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Issue with WinHTTP

Post by UEZ »

erik wrote:Beekause WinHttpQueryDataAvailable is NULL. You should get a pointer to a function like this:
Oh my god, how did I miss that. Image
Thx.

Edit: here the complete code

Code: Select all

#Include Once "windows.bi"

Type HINTERNET As LPVOID

Const WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0, WINHTTP_ACCESS_TYPE_NO_PROXY = 1, WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3, WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4, WINHTTP_FLAG_ESCAPE_DISABLE = &h00000040, INTERNET_DEFAULT_HTTPS_PORT = 443, INTERNET_DEFAULT_HTTP_PORT = 80, INTERNET_DEFAULT_PORT = 0, WINHTTP_NO_PROXY_NAME = 0, WINHTTP_NO_PROXY_BYPASS = 0, WINHTTP_NO_REFERER = 0, WINHTTP_DEFAULT_ACCEPT_TYPES = 0, WINHTTP_FLAG_SECURE = &h00800000, WINHTTP_NO_ADDITIONAL_HEADERS = 0, WINHTTP_NO_REQUEST_DATA = 0

Dim Shared As Any Ptr __hWinHTTPLib
Dim Shared WinHttpOpen As Function(sUserAgent As LPCWSTR, iAccessType As Long, sProxyName As LPCWSTR, sProxyBypass As LPCWSTR, iFlag As Long) As HINTERNET
Dim Shared WinHttpCloseHandle As Function(__hWinHTTPLib As Any Ptr) As Boolean
Dim Shared WinHttpConnect As Function(hSession As HINTERNET, sServerName As LPCWSTR, iServerPort As Long, Reserved As DWORD) As HINTERNET
Dim Shared WinHttpOpenRequest As Function(hConnect As HINTERNET, sVerb As LPCWSTR, sObjectName As LPCWSTR, sVersion As LPCWSTR, sReferrer As LPCWSTR, pAcceptTypes As Any Ptr, iFlags As Long) As HINTERNET
Dim Shared WinHttpSendRequest As Function(hInternet As HINTERNET, sHeader As LPCWSTR, iHeadersLength As Long, pOptionalBuff As HINTERNET, iOptionalLength As Long, iTotalLength As Long, pContext As DWORD_PTR) As Boolean
Dim Shared WinHttpReceiveResponse As Function(hInternet As HINTERNET, iReserved As LPVOID) As Boolean
Dim Shared WinHttpReadData As Function(hRequest As HINTERNET, pBuffer As LPVOID, iumberOfBytesToRead As Long, pNumberOfBytesRead As LPDWORD) As Boolean
Dim Shared WinHttpQueryDataAvailable As Function(hRequest As HINTERNET, pNumberOfBytesAvailable As LPDWORD) As Boolean

Sub _WinHttpStartup()
   __hWinHTTPLib = Dylibload("Winhttp.dll")
   If __hWinHTTPLib = 0 Then Return
   WinHttpOpen = Dylibsymbol(__hWinHTTPLib, "WinHttpOpen")
   WinHttpCloseHandle = Dylibsymbol(__hWinHTTPLib, "WinHttpCloseHandle")
   WinHttpConnect = Dylibsymbol(__hWinHTTPLib, "WinHttpConnect")
   WinHttpOpenRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpOpenRequest")
   WinHttpSendRequest = Dylibsymbol(__hWinHTTPLib, "WinHttpSendRequest")
   WinHttpReceiveResponse = Dylibsymbol(__hWinHTTPLib, "WinHttpReceiveResponse")
   WinHttpReadData = Dylibsymbol(__hWinHTTPLib, "WinHttpReadData")
   WinHttpQueryDataAvailable = Dylibsymbol(__hWinHTTPLib, "WinHttpQueryDataAvailable")
End Sub

Sub _WinHttpShutdown()
   If __hWinHTTPLib Then Dylibfree(__hWinHTTPLib)
End Sub

Dim As Any Ptr hSession = 0, hConnect = 0, hRequest = 0
Dim As String sRead

_WinHttpStartup()

hSession = WinHttpOpen( WStr("WinHTTP Example/1.0"), _
                  WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, _
                  WINHTTP_NO_PROXY_NAME, _
                  WINHTTP_NO_PROXY_BYPASS, 0)
? "hSession = " & Hex(hSession)

If hSession Then
   hConnect = WinHttpConnect( hSession, Wstr("forum.qbasic.at"), _
                               INTERNET_DEFAULT_PORT, 0)
End If
? "hConnect = " & Hex(hConnect)

If hConnect Then
   hRequest = WinHttpOpenRequest( hConnect, Wstr("GET"), NULL, _
                                 NULL, WINHTTP_NO_REFERER, _
                                 WINHTTP_DEFAULT_ACCEPT_TYPES, _
                                 WINHTTP_FLAG_SECURE)   
End If
? "hRequest = " & Hex(hRequest)

Dim As Boolean bResults

If hRequest Then
   bResults = WinHttpSendRequest( hRequest, _
                           WINHTTP_NO_ADDITIONAL_HEADERS, _
                           0, WINHTTP_NO_REQUEST_DATA, 0, _
                           0, 0)
End If
? "bResult = " &  bResults

If bResults Then
   bResults = WinHttpReceiveResponse( hRequest, NULL)
End If
? "bResult = " &  bResults

If bResults Then
	Dim As ULong dwSize = 0, dwDownloaded, i
	Dim as string sHTML
	Dim as ubyte aOutBuffer()
	Do
		dwSize = 0
		If WinHttpQueryDataAvailable( hRequest, @dwSize) = 0 Then ? "Error in WinHttpQueryDataAvailable. Error: " & GetLastError()
		Redim as Ubyte aOutBuffer(dwSize + 1)
		If WinHttpReadData( hRequest, @aOutBuffer(0), dwSize, @dwDownloaded) = False Then
			? "Error in WinHttpReadData. Error: " & GetLastError()
		Else
			For i = 0 to Ubound(aOutBuffer)
				sHTML &= Chr(aOutBuffer(i))
			next
		Endif
	Loop Until dwSize = 0
	? sHTML
Else
	? "Error has occurred. Error: " & GetLastError()	
End If

WinHttpCloseHandle(hRequest)
WinHttpCloseHandle(hConnect)
WinHttpCloseHandle(hSession)
_WinHttpShutdown()
Sleep
Post Reply