Subversion Repositories Kolibri OS

Rev

Rev 6977 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                                 ;;
  3. ;; Copyright (C) KolibriOS team 2014-2017. All rights reserved.    ;;
  4. ;; Distributed under terms of the GNU General Public License       ;;
  5. ;;                                                                 ;;
  6. ;;  downloader.asm - HTTP client for KolibriOS                     ;;
  7. ;;                                                                 ;;
  8. ;;      hidnplayr@kolibrios.org                                    ;;
  9. ;;                                                                 ;;
  10. ;;          GNU GENERAL PUBLIC LICENSE                             ;;
  11. ;;             Version 2, June 1991                                ;;
  12. ;;                                                                 ;;
  13. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  14.  
  15. URLMAXLEN       = 65535
  16.  
  17. __DEBUG__       = 1
  18. __DEBUG_LEVEL__ = 1
  19.  
  20.  
  21. format binary as ""
  22. use32
  23.         org     0x0
  24.  
  25.         db      'MENUET01'      ; header
  26.         dd      0x01            ; header version
  27.         dd      START           ; entry point
  28.         dd      IM_END          ; image size
  29.         dd      I_END+0x1000    ; required memory
  30.         dd      I_END+0x1000    ; esp
  31.         dd      url
  32.         dd      0x0             ; I_Path
  33.  
  34.  
  35. include '../../macros.inc'
  36. include '../../proc32.inc'
  37. include '../../dll.inc'
  38. include '../../debug-fdo.inc'
  39. include '../../develop/libraries/box_lib/trunk/box_lib.mac'
  40. include '../../develop/libraries/http/http.inc'
  41.  
  42. virtual at 0
  43.         http_msg http_msg
  44. end virtual
  45.  
  46.  
  47. START:
  48.         mcall   68, 11                  ; init heap so we can allocate memory dynamically
  49.  
  50. ; load libraries
  51.         stdcall dll.Load, @IMPORT
  52.         test    eax, eax
  53.         jnz     mainloop.exit
  54.  
  55. ; wanted events
  56.         mcall   40, EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + EVM_MOUSE_FILTER
  57.  
  58. ; prepare filename buffers
  59.         mov     edi, fname_buf
  60.         mov     esi, download_file_path
  61.   @@:
  62.         lodsb
  63.         stosb
  64.         test    al, al
  65.         jnz     @r
  66.  
  67. ; Initialise OpenDialog
  68.         invoke  OpenDialog_Init, OpenDialog_data
  69.  
  70. ; If user provided parameters, start download right away!
  71.         cmp     byte[url], 0
  72.         jne     display_url_and_download
  73.  
  74.         mov     [OpenDialog_data.draw_window], draw_window
  75.  
  76. redraw:
  77.         call    draw_window
  78.  
  79. mainloop:
  80.         mcall   10      ; wait here for event
  81.         cmp     eax, EV_REDRAW
  82.         je      redraw
  83.         cmp     eax, EV_KEY
  84.         je      .key
  85.         cmp     eax, EV_BUTTON
  86.         je      .button
  87.         cmp     eax, EV_MOUSE
  88.         je      .mouse
  89.         jmp     mainloop
  90.  
  91.   .key:
  92.         mcall   2       ; read key
  93.         invoke  edit_box_key, edit1
  94.         cmp     ax, 13 shl 8
  95.         je      download
  96.         jmp     mainloop
  97.  
  98.   .button:
  99.         mcall   17      ; get id
  100.         cmp     ah, 1   ; button id=1 ?
  101.         je      .exit
  102.  
  103.         cmp     [btn_text], sz_download
  104.         je      download
  105.  
  106.         cmp     [btn_text], sz_open
  107.         je      open_file
  108.  
  109.   .exit:
  110.         mcall   -1      ; exit
  111.  
  112.   .mouse:
  113.         invoke  edit_box_mouse, edit1
  114.         jmp     mainloop
  115.  
  116.  
  117. open_file:
  118.         mcall   70, fileopen
  119.         jmp     mainloop
  120.  
  121. display_url_and_download:
  122.         xor     al, al
  123.         mov     ecx, 4096
  124.         mov     edi, url
  125.         repne scasb
  126.         sub     edi, url+1
  127.         mov     [edit1.size], edi
  128.  
  129. download:
  130. ; Extract the filename from URL
  131.         mov     edi, url
  132.         xor     al, al
  133.         mov     ecx, URLMAXLEN
  134.         repne scasb
  135.         mov     esi, edi
  136.         dec     esi
  137.         dec     esi
  138.         std
  139.   .loop:
  140.         lodsb
  141.         cmp     al, '/'
  142.         je      .done
  143.         test    al, al
  144.         jnz     .loop
  145.   .done:
  146.         cld
  147.         mov     ecx, edi
  148.         sub     ecx, esi
  149.         inc     esi
  150.         inc     esi
  151.         mov     edi, filename_area
  152.         rep movsb
  153.  
  154. ; invoke OpenDialog
  155.         invoke  OpenDialog_Start, OpenDialog_data
  156.         mcall   40, EVM_REDRAW + EVM_BUTTON + EVM_STACK
  157.         call    draw_window
  158.  
  159. ; Create the local file
  160.         mov     [fileinfo], 2           ; create/write to file
  161.         xor     eax, eax
  162.         mov     [fileinfo.offset], eax
  163.         mov     [fileinfo.offset+4], eax
  164.         mov     [fileinfo.size], eax
  165.         mcall   70, fileinfo
  166.         test    eax, eax
  167.         jnz     create_error
  168.  
  169. ; Start the download
  170.         invoke  HTTP_get, url, 0, FLAG_STREAM or FLAG_REUSE_BUFFER, 0
  171.         test    eax, eax
  172.         jz      get_error
  173.  
  174.         mov     [identifier], eax
  175.         mov     [offset], 0
  176.         mov     [btn_text], sz_cancel
  177.         mov     [status], sz_downloading
  178.         or      [edit1.flags], ed_figure_only
  179.         and     [edit1.flags], not ed_focus
  180.         push    [sc.work]
  181.         pop     [edit1.color]
  182.         call    draw_window
  183.  
  184.         jmp     download_loop
  185.  
  186. get_error:
  187.         mov     [btn_text], sz_exit
  188.         mov     [status], sz_err_http
  189.         jmp     redraw
  190.  
  191. create_error:
  192.         mov     [btn_text], sz_exit
  193.         mov     [status], sz_err_create
  194.         jmp     redraw
  195.  
  196. download_loop:
  197.         mcall   10
  198.         cmp     eax, EV_REDRAW
  199.         je      .redraw
  200.         cmp     eax, EV_BUTTON
  201.         je      .button
  202.  
  203.         invoke  HTTP_receive, [identifier]
  204.         test    eax, eax
  205.         jz      got_data
  206.         jmp     download_loop
  207.  
  208.   .redraw:
  209.         call    draw_window
  210.         jmp     download_loop
  211.  
  212.   .button:
  213.         jmp     http_free
  214.  
  215. got_data:
  216.         mov     ebp, [identifier]
  217.         test    [ebp + http_msg.flags], 0xffff0000      ; error?
  218.         jnz     http_error
  219.  
  220.         cmp     [fileinfo], 3                           ; Did we write before?
  221.         je      .write
  222.  
  223.         test    [ebp + http_msg.flags], FLAG_CONTENT_LENGTH
  224.         jz      .first_write
  225.  
  226.         mov     eax, [ebp + http_msg.content_length]
  227.         mov     [pb.max], eax
  228.  
  229.         DEBUGF  1, "new file size=%u\n", eax
  230.         mov     [fileinfo], 4                           ; set end of file
  231.         mov     [fileinfo.offset], eax                  ; new file size
  232.         mcall   70, fileinfo
  233.         test    eax, eax
  234.         jnz     write_error
  235.  
  236.  
  237.   .first_write:
  238.         mov     [fileinfo], 3                           ; write to existing file
  239.   .write:
  240.         mov     ecx, [ebp + http_msg.content_received]
  241.         sub     ecx, [offset]
  242.         jz      .no_data                                ; more then 0 data bytes?
  243.  
  244.         mov     [fileinfo.size], ecx
  245.         mov     eax, [ebp + http_msg.content_ptr]
  246.         mov     [fileinfo.buffer], eax
  247.         mov     ebx, [offset]
  248.         mov     [fileinfo.offset], ebx
  249.         DEBUGF  1, "Writing to disk: size=%u offset=%u\n", ecx, ebx
  250.         mcall   70, fileinfo
  251.         test    eax, eax                                ; check error code
  252.         jnz     write_error
  253.         cmp     ebx, ecx                                ; check if all bytes were written to disk
  254.         jne     write_error
  255.  
  256.         mov     eax, [ebp + http_msg.content_received]
  257.         mov     [offset], eax
  258.         mov     [pb.value], eax
  259.  
  260.         invoke  progressbar_draw, pb
  261.  
  262.   .no_data:
  263.         test    [ebp + http_msg.flags], FLAG_GOT_ALL_DATA
  264.         jz      download_loop
  265.  
  266. ; Download completed successfully
  267.         mov     [status], sz_complete
  268.         mov     [pb.progress_color], 0x0000c800         ; green
  269.         mov     [btn_text], sz_open
  270.         jmp     http_free
  271.  
  272. write_error:
  273.         mov     [status], sz_err_full
  274.         mov     [pb.progress_color], 0x00c80000         ; red
  275.         mov     [btn_text], sz_exit
  276.         jmp     http_free
  277.  
  278. http_error:
  279.         mov     [status], sz_err_http
  280.         mov     [pb.progress_color], 0x00c80000         ; red
  281.         mov     [btn_text], sz_exit
  282. ;        jmp     http_free
  283.  
  284. http_free:
  285.         mcall   40, EVM_REDRAW + EVM_BUTTON
  286.         push    [ebp + http_msg.content_received]
  287.         pop     [pb.value]
  288.  
  289.         mov     ecx, [ebp + http_msg.content_ptr]
  290.         test    ecx, ecx
  291.         jz      @f
  292.         mcall   68, 13                                  ; free the buffer
  293.   @@:
  294.         invoke  HTTP_free, [identifier]                 ; free headers and connection
  295.         jmp     redraw
  296.  
  297. draw_window:
  298.         mcall   12, 1   ; start window draw
  299.  
  300. ; get system colors
  301.         mcall   48, 3, sc, 40
  302.  
  303. ; draw window
  304.         mov     edx, [sc.work]
  305.         or      edx, 0x34000000
  306.         mcall   0, <50, 420>, <350, 120>, , 0, title
  307.  
  308. ; draw button
  309.         mcall   8, <320,75>, <50,24>, 22, [sc.work_button]
  310.  
  311. ; draw button text
  312.         mov     ecx, [sc.work_button_text]
  313.         or      ecx, 90000000h
  314.         mcall   4, <325,56>, , [btn_text]
  315.  
  316. ; draw status text
  317.         mov     ecx, [sc.work_text]
  318.         or      ecx, 90000000h
  319.         mcall   4, <10,70>, , [status]
  320.  
  321. ; draw editbox
  322.         edit_boxes_set_sys_color edit1, editboxes_end, sc
  323.         invoke  edit_box_draw, edit1
  324.  
  325.         cmp     [identifier], 0
  326.         je     @f
  327. ; draw progressbar
  328.         invoke  progressbar_draw, pb
  329.   @@:
  330.         mcall   12, 2   ; end window draw
  331.  
  332. dont_draw:
  333.         ret
  334.  
  335. ;---------------------------------------------------------------------
  336. ; Data area
  337. ;-----------------------------------------------------------------------------
  338. align   4
  339. @IMPORT:
  340.  
  341. library lib_http,       'http.obj', \
  342.         box_lib,        'box_lib.obj', \
  343.         proc_lib,       'proc_lib.obj'
  344.  
  345. import  lib_http, \
  346.         HTTP_get,       'get', \
  347.         HTTP_receive,   'receive', \
  348.         HTTP_free,      'free'
  349.  
  350. import  box_lib, \
  351.         edit_box_draw,    'edit_box', \
  352.         edit_box_key,     'edit_box_key', \
  353.         edit_box_mouse,   'edit_box_mouse', \
  354.         progressbar_draw, 'progressbar_draw', \
  355.         progressbar_prog, 'progressbar_progress'
  356.  
  357. import  proc_lib, \
  358.         OpenDialog_Init,  'OpenDialog_init', \
  359.         OpenDialog_Start, 'OpenDialog_start'
  360.  
  361.  
  362. fileinfo        dd 2
  363.   .offset       dd 0, 0
  364.   .size         dd 0
  365.   .buffer       dd 0
  366.                 db 0
  367.                 dd fname_buf
  368.  
  369. fileopen        dd 7
  370.                 dd 0                    ; flags
  371.                 dd fname_buf            ; parameters
  372.                 dd 0                    ; reserved
  373.                 dd 0                    ; reserved
  374.                 db "/sys/@open", 0      ; path
  375.  
  376. edit1           edit_box 400, 5, 10, 0xffffff, 0x0000ff, 0x0080ff, 0x000000, 0x90000000, URLMAXLEN, url, mouse_dd, ed_focus+ed_always_focus, 0, 0
  377. editboxes_end:
  378.  
  379. identifier      dd 0
  380. btn_text        dd sz_download
  381. status          dd sz_null
  382. sz_download     db 'Download', 0
  383. sz_cancel       db ' Cancel ', 0
  384. sz_open         db '  Open  ', 0
  385. sz_exit         db '  Exit  ', 0
  386.  
  387. sz_null         db 0
  388. sz_downloading  db 'Downloading..', 0
  389. sz_complete     db 'Download completed', 0
  390. sz_err_create   db 'Could not create the local file!', 0
  391. sz_err_full     db 'Disk full!', 0
  392. sz_err_http     db 'HTTP error!', 0
  393. title           db 'HTTP Downloader', 0
  394.  
  395. OpenDialog_data:
  396. .type                   dd 1    ; Save
  397. .procinfo               dd procinfo
  398. .com_area_name          dd communication_area_name
  399. .com_area               dd 0
  400. .opendir_path           dd temp_dir_path
  401. .dir_default_path       dd communication_area_default_path
  402. .start_path             dd open_dialog_path
  403. .draw_window            dd dont_draw
  404. .status                 dd 0
  405. .openfile_patch         dd fname_buf
  406. .filename_area          dd filename_area
  407. .filter_area            dd filter
  408. .x:
  409. .x_size                 dw 420  ; Window X size
  410. .x_start                dw 200  ; Window X position
  411. .y:
  412. .y_size                 dw 320  ; Window y size
  413. .y_start                dw 140  ; Window Y position
  414.  
  415. communication_area_name         db 'FFFFFFFF_open_dialog',0
  416. open_dialog_path                db '/sys/File Managers/opendial',0
  417. communication_area_default_path db '/sys',0
  418.  
  419. filter:
  420. dd      0
  421. db      0
  422.  
  423. pb:
  424. .value          dd 0
  425. .left           dd 5
  426. .top            dd 45
  427. .width          dd 300
  428. .height         dd 16
  429. .style          dd 1
  430. .min            dd 0
  431. .max            dd 0
  432. .back_color     dd 0xefefef
  433. .progress_color dd 0xc8c8c8
  434. .frame_color    dd 0x94aece
  435. .frame_color2   dd 0xffffff
  436.  
  437. include_debug_strings
  438.  
  439. download_file_path db '/tmp0/1/', 0
  440.  
  441. IM_END:
  442.  
  443. url             rb URLMAXLEN
  444. sc              system_colors
  445. offset          dd ?
  446. mouse_dd        dd ?
  447.  
  448. filename_area   rb 256
  449. temp_dir_path   rb 4096
  450. procinfo        rb 1024
  451. fname_buf       rb 4096
  452. text_work_area  rb 1024
  453.  
  454. I_END: