News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Download a file from the internet

Started by Matthias Merkel, December 17, 2017, 11:00:20 PM

Previous topic - Next topic

aw27

To prevent issues with antivirus (https://virusscan.jotti.org/en-US/filescanjob/kzzy27svtq) I will start programming in pure VB.Net  in 2018 :badgrin:
It produces small executables too.


Imports System.Net

Module Module1
    Public WithEvents client As New WebClient()
    Public stillDownloading As Boolean

    Sub Main()
        stillDownloading = True
        client.DownloadFileAsync(New Uri("http://masm32.com/board/index.php?topic=6771.0"), "test.html")
        While stillDownloading
        End While

        Dim filePath As String = ".\test.html"
        Dim psi As New ProcessStartInfo(filePath)
        psi.WorkingDirectory = IO.Path.GetDirectoryName(filePath)
        Process.Start(psi)
    End Sub

    Private Sub Client_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs) Handles client.DownloadProgressChanged
        Console.WriteLine(String.Format("{0} %", e.ProgressPercentage))
        If e.ProgressPercentage = 100 Then
            Console.WriteLine("Download completed")
            stillDownloading = False
        End If
    End Sub


To be more confident let me check in another site:
https://www.virustotal.com/#/file/283bf0921aaffd360edec353d9698e679e6dfaf12319100c7d2451a42f705899/detection
Damn, CrowdStrike Falcon (never heard about it before) says it is malware with 80% confidence.   :(


jj2007

Quote from: caballero on December 18, 2017, 09:19:13 PM
Wow, it is a quite good example, where are the masm sources?  :biggrin:

Thanks :t

This is a MASM source (it assembles with Masm, right?). If you need more detail, check \Masm32\MasmBasic\MasmBasic.inc and \Masm32\MasmBasic\Res\MbGui.asm

jj2007

Quote from: aw27 on December 18, 2017, 09:27:57 PMI will start programming in pure VB.Net  in 2018 :badgrin:

These are good intentions, José :t

Your code has little problems, though:TmpFile.bas(14) : error BC30002: Tipo 'ProcessStartInfo' non definito
TmpFile.bas(16) : error BC30451: 'Process' non dichiarato

(warning: VB is a Micros**t product!)

aw27

Quote
[quote author=jj2007 link=topic=6771.msg72479#msg72479 date=1513595003]
TmpFile.bas(16) : error BC30451: 'Process' non dichiarato

(warning: VB is a Micros**t product!)
It works here, I was even able to run it, imagine!

aw27

Quote from: jj2007 on December 18, 2017, 09:41:05 PM
This is a MASM source (it assembles with Masm, right?). If you need more detail, check \Masm32\MasmBasic\MasmBasic.inc and \Masm32\MasmBasic\Res\MbGui.asm
It was built with MASM (probably) and it builds with MASM because you had not the time (yet) to build your own HLL compiler. May be in 2018 you can handle that part.

jj2007

Quote from: aw27 on December 18, 2017, 10:49:43 PMIt works here, I was even able to run it, imagine!

After searching a bit for the error messages, I found the culprit:
Imports System.Net ' José's original code
Imports System.Diagnostics ' added by JJ to make it work
...
End Module ' added by JJ to make it work


And voilà, it builds fine, and even starts downloading something :t
Then it gets stuck and hangs at 100% cpu load. Fortunately, it can be killed with Task Manager :icon_mrgreen:

mabdelouahab

with : VB.Net Masm64.Net  :biggrin:

;*************************************************************
OPTION LITERALS:ON
include \masm32\include64\AsmDotNet64.inc
   .includelib kernel32,msvcrt,user32
   .proto ExitProcess,wprintf,printf,MessageBoxA
;*************************************************************
   .import System.Net.WebClient,tWebClient
   .import System.Net.DownloadProgressChangedEventArgs,tDPCEventArgs
   .importSystem.Uri,tUri
   .import System.Diagnostics.ProcessStartInfo,tProcessStartInfo
   .import System.Diagnostics.Process,tProcess
   .import System.IO.Path,tPath
;*************************************************************
.data
   stillDownloading    dd 1
   filePath          dq Of_Bstr(".\test.html")
.code
;*************************************************************
   On_DownloadProgressChanged proc _Sender:QWORD,_e:QWORD
   .LOCAL e,tDPCEventArgs
   LOCAL ProgressPercentage:QWORD
      mov rax,_e
      mov e,rax
      .get ,e.ProgressPercentage
      mov ProgressPercentage,rax
      invoke printf,"\n{%d}",ProgressPercentage
      .if ProgressPercentage == 100
         mov stillDownloading,0
      .endif
      ret
   On_DownloadProgressChanged endp
;*************************************************************
   entry_point proc
      .LOCAL client,tWebClient
      .LOCAL vUri,tUri
      .LOCAL psi,tProcessStartInfo
      .LOCAL Path,tPath
      .LOCAL Process,tProcess
      LOCAL DirectoryName:qword
      .invoke vUri.CreateInstance,"http://masm32.com/board/index.php?topic=6771.0"
      .invoke client.CreateInstance
      .invoke client.DownloadFileAsync,vUri,"test.html"
      .addhandlerEx client.DownloadProgressChanged, addr On_DownloadProgressChanged
   @@:   cmp stillDownloading,1
      je @B
      .invoke psi.CreateInstance,filePath
      .invoke Path.GetDirectoryName,filePath
      mov DirectoryName,rax
      .set psi.WorkingDirectory ,DirectoryName
      .invoke Process.Start_5,psi
      invoke ExitProcess,0
      ret
   entry_point endp
;*************************************************************
end    
;*************************************************************

aw27

Quote
Then it gets stuck and hangs at 100% cpu load. Fortunately, it can be killed with Task Manager :icon_mrgreen:
@JJ
1- Imports System.Diagnostics is a default imported namespace in my VS 2017 installation and I swear that it is the first time I use VB.Net in 2017 and I have not changed anything.

2. If it gets stuck is because you are trying to make a Forms Application and my example is for a Console application.
       While stillDownloading
        End While
will not make a console app get stuck because Client_DownloadProgressChanged comes from a different thread and the download is asynch.

 

jj2007

Quote from: aw27 on December 19, 2017, 02:00:30 AM
Quote
Then it gets stuck and hangs at 100% cpu load. Fortunately, it can be killed with Task Manager :icon_mrgreen:
@JJ
1- Imports System.Diagnostics is a default imported namespace in my VS 2017 installation and I swear that it is the first time I use VB.Net in 2017 and I have not changed anything.

Me swear, too, that I have not changed anything :biggrin:

Quote2. If it gets stuck is because you are trying to make a Forms Application and my example is for a Console application.
       While stillDownloading
        End While
will not make a console app get stuck because Client_DownloadProgressChanged comes from a different thread and the download is asynch.

Console output:
0 %
0 %
100 %
Download completed


Doesn't look like a "Forms Application", whatever that is 8)

Btw that doesn't look like good programming practice. Shouldn't there be at least a Sleep(1) inside?        While stillDownloading
        End While

aw27

Quote
Btw that doesn't look like good programming practice. Shouldn't there be at least a Sleep(1) inside?
Yeah, but I could not remember how to say Sleep in VBNet-ish.  :lol:


jj2007

Quote from: aw27 on December 19, 2017, 04:04:13 AM
Quote
Btw that doesn't look like good programming practice. Shouldn't there be at least a Sleep(1) inside?
Yeah, but I could not remember how to say Sleep in VBNet-ish.  :lol:

The learning curve will be steep, but you are still young, so we are all optimistic :icon14:
Quote from: aw27 on December 18, 2017, 09:27:57 PMI will start programming in pure VB.Net  in 2018 :badgrin:

P.S.: Just tested my download snippet in Win10 home, it builds & works like a charm. Normal user account, it doesn't even warn me - I am always impressed how easy it is to download stuff in Windows. No wonder people catch viruses :badgrin:

aw27

Quote
The learning curve will be steep
Every kid can learn VB Net in a few hours.  :icon14:
I like to know a bit of every programming language, but am not into those that try to do everything for me.
BTW, I found that Sleep is System.Threading.Thread.CurrentThread.Sleep
On the other end you can hang a Forms application with long sleeps. What I use to do in other programming languages is a small sleep followed by an instruction to pump the waiting messages. This is probably doEvents in VB Net.

juozas

#27
A long time I created an example program that Downloads and saves a file from url you input in a dialog it shows. It remembers the last url you downloaded:
.386
.model flat, stdcall  ;32 bit memory model
option casemap :none  ;case sensitive

include \masm32\include\windows.inc

uselib MACRO libname
include \masm32\include\libname.inc
includelib \masm32\lib\libname.lib
endm

uselib kernel32
uselib user32
uselib shlwapi
uselib Comctl32
uselib wininet
uselib masm32

include \masm32\macros\macros.asm

DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
GetTheFile PROTO :DWORD

.const

IDD_MAIN                equ 101
IDC_OK                  equ 1
IDC_CANCEL              equ 2
IDC_FNAME               equ 102
IDI_ICON                equ 101


.data
msgOk db "Download is done!", 0
msgErr db "Download failed", 0
mcap db "Download",0

.data?

FileName db 256 dup (?)

hInstance dd ?
hIcon dd ?
hCfg dd ?
CfgSize dd ?
CfgRead dd ?
CfgWrite dd ?

.code

start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke InitCommonControls
invoke DialogBoxParam,hInstance,IDD_MAIN,NULL,addr DlgProc,NULL
invoke ExitProcess,0

DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_INITDIALOG
;initialization here
invoke LoadIcon, hInstance, IDI_ICON
        mov hIcon, eax
        invoke SendMessage, hWin, WM_SETICON, 1, hIcon
        invoke CreateFile,chr$("DownDlg.cfg"),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
        mov hCfg, eax
        invoke GetFileSize,hCfg,NULL
        mov CfgSize, eax
        invoke ReadFile,hCfg,addr FileName, CfgSize, addr CfgRead, NULL
        invoke CloseHandle, hCfg
        invoke SetDlgItemText, hWin, IDC_FNAME, addr FileName
        invoke GetDlgItem,hWin,IDC_FNAME
      invoke SetFocus,eax
.elseif uMsg==WM_COMMAND
.if wParam==IDC_OK
invoke GetDlgItemText,hWin,IDC_FNAME,addr FileName,sizeof FileName
invoke GetTheFile, addr FileName
.if eax == TRUE
invoke CreateFile,chr$("DownDlg.cfg"),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL
mov hCfg, eax

invoke WriteFile,hCfg,addr FileName,sizeof FileName, addr CfgWrite,NULL
invoke SetEndOfFile,hCfg
invoke CloseHandle,hCfg
invoke MessageBox, hWin, addr msgOk, addr mcap, MB_OK + MB_ICONINFORMATION
invoke SendMessage,hWin,WM_CLOSE,NULL,NULL
.else
    invoke MessageBox, hWin, addr msgErr, addr mcap, MB_OK + MB_ICONSTOP
invoke GetDlgItem,hWin,IDC_FNAME
      invoke SetFocus,eax
.endif
.elseif wParam==IDC_CANCEL
invoke SendMessage,hWin,WM_CLOSE,NULL,NULL
.endif
.elseif uMsg==WM_CLOSE
invoke EndDialog,hWin,0
.endif
xor eax,eax
ret
DlgProc endp

GetTheFile proc fName:DWORD
local buffer[1024]: BYTE
local hSession: DWORD
local hUrl: DWORD
local bufferlen: DWORD

local AppName[127]: BYTE
local FileSave[MAX_PATH]: BYTE

local fhandl: DWORD
local bwrite: DWORD

invoke PathFindFileName, fName
invoke lstrcpy, addr FileSave, eax

invoke GetModuleFileName,  NULL,  addr AppName,  sizeof AppName
invoke InternetOpen,  addr AppName,  INTERNET_OPEN_TYPE_PRECONFIG, NULL,  NULL,  NULL
mov hSession, eax
.if hSession == INVALID_HANDLE_VALUE
    mov eax,  FALSE
    ret
    .endif
invoke InternetOpenUrl, hSession, fName, NULL, NULL, NULL, NULL
mov hUrl, eax
.if hUrl == INVALID_HANDLE_VALUE
    mov eax, FALSE
    ret
.endif

invoke CreateFile,addr FileSave,  GENERIC_READ or GENERIC_WRITE,  FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
mov fhandl, eax
.if fhandl == INVALID_HANDLE_VALUE
mov eax, FALSE
ret
.endif

invoke SetFilePointer,  fhandl, NULL, NULL, FILE_BEGIN
download:
invoke InternetReadFile, hUrl,  addr buffer,sizeof buffer,  addr bufferlen
.if bufferlen != 0
invoke WriteFile,  fhandl,  addr buffer,  bufferlen,  addr bwrite, NULL
jmp download
.endif

invoke CloseHandle,  fhandl
invoke InternetCloseHandle,  hUrl
invoke InternetCloseHandle,  hSession
mov eax, TRUE
ret
GetTheFile endp

end start

It uses resources for dialog definition. Compiled under wine. Full archive attached.
Edit: It hangs if it can't resolve and/or connect to url (at least on wine), it must be full one (with the protocol prefix), it also will overwrite any existing file that's same as in url upon attempting to download it, so please be careful.
Intel Pentium Dual-Core E6300 @ 2.80 GHz / Asus P5G41-M LE (2 GB Ram) / NVIDIA GeForce 210
Ubuntu Linux 22.04 LTS with Wine 7.22
Windows XP on Virtual machine

Сделано в СССР