uses "Console"
uses "iNet"
uses "OS"
printl "Connect to Firefox web site, determine latest Firefox version and download it"
'---Check if computer is connected to internet
if INET_GetState Then
'---Get Firefox web site page
string Firefox_Info_Page = INET_UrlGetString("https://www.mozilla.org/en-US/firefox/new/")
'---Get Firefox available version
string Firefox_Available_Version = grab$(Firefox_Info_Page, "data-latest-firefox=""", """")
'---Get Win64 direct download url
string Firefox_DownLoad_Url_Win64 = grab$(Firefox_Info_Page, "<div id=""other-platforms"">", "</div>")
Firefox_DownLoad_Url_Win64 = grab$(Firefox_DownLoad_Url_Win64, "<li class=""os_win64"">", "</li>")
Firefox_DownLoad_Url_Win64 = grab$(Firefox_DownLoad_Url_Win64, "<a href=""", """")
printl "Firefox available version...:", Firefox_Available_Version
printl "Firefox Download url........:", Firefox_DownLoad_Url_Win64
'---Download
string sLocalFile = APP_SourcePath + "Firefox Setup " + Firefox_Available_Version + ".exe"
'---Initializes an application's use of the WinINet Internet functions.
dword hInternet = INET_Internet_Open("Download Fireforx", %INTERNET_OPEN_TYPE_DIRECT)
IF hInternet = %NULL THEN
printl "INET_Internet_Open error"
waitkey
stop
END IF
long MyContext = 1
long hFile = INET_Internet_OpenUrl(hInternet, Firefox_DownLoad_Url_Win64, "", %INTERNET_FLAG_NO_CACHE_WRITE, MyContext)
IF hFile = %NULL THEN
printl "INET_Internet_OpenUrl error. Check url: " & Firefox_DownLoad_Url_Win64
INET_Internet_CloseHandle hInternet
waitkey
stop
END IF
'---Set a callback for hInternet events. Driver will automatically call MyStatusFunction on status change
long bResult = INET_Internet_SetStatusCallBack(hFile, MyStatusFunction)
'---Query remote server about the size of the file we are going to download
long FileSize = INET_Http_QueryInfo(hFile, %HTTP_QUERY_CONTENT_LENGTH)
printl "Real file size in bytes: " & FileSize
IF FileSize = %NULL THEN
printl "INET_Http_QueryInfo(hInternet, %HTTP_QUERY_CONTENT_LENGTH) error. Check url: " & Firefox_DownLoad_Url_Win64
INET_Internet_CloseHandle hInternet
INET_Internet_CloseHandle hFile
waitkey
stop
END IF
'---Ok we can start a loop for file download. This can be automated in a loop or in a timer function
'---Reads the data in %BufferLen bytes chunks
double T0 = timer
double T1
'---Setup a %BufferLen bytes buffer
long lBufferLen = 500000 '500k
string strBuffer = STRING$(lBufferLen, $SPC)
dword pstrBuffer = STRPTR(strBuffer)
String strData
dword cbBytesRead
DWord TotalBytesRead
long lScreenLine = 8
long lScreenPos = 20
string sSave = Console_SaveScreen(1, 1, 80, 24)
Console_Box(lScreenPos - 1, lScreenLine - 1, 40, 8, 24, 24, "Downloading ...", 26, %Console_BOX_FLAG_3DOFF)
DO
bResult = INET_Internet_ReadFile(hFile, pstrBuffer, len(strBuffer), cbBytesRead)
IF bResult = 0 OR cbBytesRead = 0 THEN EXIT DO
IF cbBytesRead = LEN(strBuffer) THEN
strData &= strBuffer
ELSE
strData &= LEFT$(strBuffer, cbBytesRead)
END IF
TotalBytesRead += cbBytesRead
T1 = Timer
PrintAt "Elapsed seconds : " & LSet$(Format$(T1-T0, "0"), 19) , lScreenPos + 1, lScreenLine + 1, 24
PrintAt "Bytes read so far: " & LSet$(TotalBytesRead, 19) , lScreenPos + 1, lScreenLine + 2, 24
PrintAt "KBytes per second: " & LSet$(Format$((TotalBytesRead / Max(T1-T0, 1))/1024, "0.00"), 19) , lScreenPos + 1, lScreenLine + 3, 24
PrintAt "Estimated seconds: " & LSet$(Format$((FileSize * (T1-T0))/TotalBytesRead, "0"), 19) , lScreenPos + 1, lScreenLine + 4, 24
PrintAt "Seconds to go : " & LSet$(Format$(((FileSize * (T1-T0))/TotalBytesRead)-(T1-T0), "0"), 19) , lScreenPos + 1, lScreenLine + 5, 24
Console_ProgressBar(1, lScreenPos + 1, lScreenLine + 7, 40-1, 27, 1, FileSize, TotalBytesRead)
LOOP
Console_RestoreScreen(1, 1, 80, 24, sSave)
'---Closes all used handles
INET_Internet_CloseHandle hInternet
INET_Internet_CloseHandle hFile
printl "Saving file: " & sLocalFile
Save_File(sLocalFile, strData)
printl "File saved."
printl
printl "Press ESC to end or any other key within 10 secs to execute setup"
'---Ask if execute setup
string sUserReply = WaitKey(10)
if sUserReply <> "[ESC]" and sUserReply <> "[TIMEOUT]" Then
printl "Executing " + sLocalFile
OS_Shell(sLocalFile, %OS_WNDSTYLE_NORMAL, %OS_SHELL_SYNC)
Else
printl "No execution. Execute manually if needed."
end If
Else
printl "! it seems you are not connected to internet." in %CCOLOR_FLIGHTRED
end If
printl "---All done, press a key to end or wait 5 secs---"
WaitKey(5)
'------------------------------------------------------------------
' CallBack function automatically called by Internet driver when
' status change for a specific Internet handle to which a callback
' function has been installed.
' Parameters are mandatory and are defined my Microsoft
' callback template. More info at: http://msdn.microsoft.com/en-us/library/aa385121(VS.85).aspx
'------------------------------------------------------------------
callback function MyStatusFunction( _
byval hInternet as long , _ '---Mandatory in thinBasic and in API
byval dwContext as long , _ '---Mandatory in thinBasic and in API
byval dwInternetStatus as long , _ '---Mandatory in thinBasic and in API
byval lpvStatusInformation as long , _ '---Optional in thinBasic, mandatory in API
byval dwStatusInformationLength as long _ '---Optional in thinBasic, mandatory in API
) as long
'------------------------------------------------------------------
dim BytesReceived as dword at 0
static TotBytes as dword
static MoreStatusLine as long = 20
'printat "Data from " & function_name & " callback" , 1, 17
'printat " Internet handle: " & hInternet & " Internet dwContext: " & dwContext, 1, 18
select case dwInternetStatus
case %INTERNET_STATUS_RECEIVING_RESPONSE
case %INTERNET_STATUS_RESPONSE_RECEIVED
'--- Successfully received a response from the server.
'--- The lpvStatusInformation parameter points to a DWORD value that contains the number, in bytes, received.
setat(BytesReceived, lpvStatusInformation)
TotBytes += BytesReceived
'---ATTENTION: TotalBytes received can differ from total bytes of the file to be downloaded
'printat " Receiving data (" & dwInternetStatus & " " & INET_Internet_StatusGetDescription(dwInternetStatus) & ") TotBytes: " & TotBytes, 1, 19
case else
'---In case of other status, just decode it at the bottom.
'printat " (" & dwInternetStatus & " " & INET_Internet_StatusGetDescription(dwInternetStatus) & ")", 1, MoreStatusLine
incr MoreStatusLine
end select
end function