На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Все статьи должны быть оформлены согласно Правил оформления статей.
2. Любые обсуждения должны происходить в специальной теме, обсуждение в любых других темах раздела запрещены.
3. Запрещается писать статьи о создании и распространении вирусов, троянов и других вредоносных программ!
4. За грамотно написанные и правильно оформленные статьи авторы награждаются DigiMoney.

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > FTP-клиент, библиотека (WinInet) , Windows, MASM, Сеть

      FTP–клиент с помощью библиотеки Wininet

      Для использования ftp протокола в качестве посредника для общения
      с ftp сервером, в данной статье я буду использовать функции библиотеки WinInet :)

      Исходник, предназначен, для соединения с ftp сервером, отображения папок и файлов, перемещения по текущим директориям и
      скачивания и заливки файлов.

      Основные функции библиотеки WinInet для общения с ftp сервером, я не буду описывать, а прокомментирую в ниже приведённом коде.
      Только упомяну, что вместо функций FtpPutFile и FtpGetFile, я использовала InternetWriteFile и InternetReadFile – соответственно, для подсчёта и отображения, залитых и скачанных байт.

      Итак, FtpClient:
      ExpandedWrap disabled
         .386
        .model flat,stdcall
        option casemap:none
         
        include \masm32\include\windows.inc
         
        include \masm32\include\user32.inc
        include \masm32\include\kernel32.inc
        include \masm32\include\wininet.inc
         
        includelib \masm32\lib\user32.lib
        includelib \masm32\lib\kernel32.lib
        includelib \masm32\lib\wininet.lib
          
          _T macro p1, p2 ;макрос обработки строк
              local l
                ifb <p2>; Строка без имени
                    .data
                        l   db p1, 0
                    .code
                    exitm   <addr l>
                else    ; Строка с именем
                    .data
                        p1  db p2, 0
                    .code
                    exitm   <addr p1>
                endif
            endm
         
            IDC_Glav        equ 1000 ;окно данных
            IDC_GETHOST     equ 1001 ;host
            IDC_Dir         equ 1002 ;dir
            IDC_User        equ 1003 ;user
            IDC_Pass        equ 1004 ;pass
            IDC_Connect     equ 1005 ;connect
            IDC_Setdir      equ 1006 ;setdir
            IDC_Disconnect  equ 1007 ;disconnect
            IDC_EXIT        equ 1008 ;exit
            IDC_PutFileName        equ 1009 ;putfile
            IDC_GetFilename        equ 1010 ;nameputfile
            SizeGetPutFile         equ 1011 ;statictext для отображени процесса Write/Read - byte
            ObshiySize             equ 1012 ;размер файлов
         
        ;-------------------------------------------------------------------------
                      treadftpfind PROTO ;поток для поиска файлов
            threadprocdownloadfile PROTO ;поток для скачивания файла
                 threadprocputfile PROTO ;поток для заливки файла
            ;оконная процедура
            WndProc            PROTO  :DWORD, :DWORD, : DWORD,:DWORD
            ;процедура поиска директорий и файлов
            FindFTPFiles       PROTO  :DWORD, :DWORD
            ;сообщение в лист бокс
            MESSG              PROTO  :HWND,  :DWORD
            ;обработка клика по строчке в листбоксе
            ListBoxProc        PROTO  :HWND,  :UINT,  :WPARAM, :LPARAM
          
            
           .data
         
        ;-------------------------------------------------------------------------
         
         
         pdwNumberOfBytesWritten dd  0  ;для записи файла
                 ObshiyBuffer    dd  0  ;подсчёта байт при скачивании
              ObshiyBufferPut    dd  0  ;и залвики
         
         wNumberOfBytesToRead dd 0;сколько считали байт
              ReadByteFilePut dd 0
              CountBytesWrite dd 0;сколько записали байт
                     AgetUser db 'FtpClient',0;название клиент-программы
                    hInstance dd 0
          
         ;декрипторы соединений
          hInternet dd 0
          hConnect  dd 0
         ;декрипторы файлов
         FileOpenchtobPut dd 0;хандл файла для чтения и размера с диска
          hInetFileHandle dd 0;хандл файла для скачивания и размера
              FileOpenPut dd 0;созданный файл на сервере для заливки
                    hFile dd 0;для записи на диск  
          hFileConnection dd 0;файл для поиска
         
         FIND_DATA WIN32_FIND_DATA <?>;структура файла
         ;для потоков
         jdownftp               dd 0
         jputfile                     dd 0
         jfindftp                     dd 0
         ;размеры файлов
         lpdwFileSizeHigh dd 0
         lpFileSizeHigh   dd 0
         ;----------------------------------------------------------------------------------
        .data?
         ;----------------------------------------------------------------------------------
                 User db 1024 dup (?);Логин
                 Pass db 1024 dup (?);Пароль
             StrokaIz db 1024 dup (?);Хост
         
        BufferReadPut db 1024 dup (?)
         
         
             BufferFile  db 1024 dup (?)
             NameFilePut db 1024 dup (?)
          BufferDir      db 1024 dup (?)  
          lpfnEditProc    HWND ?  
          hDlg HWND ?
         
        .code
            start:
         
        ;--------------------------------------------------------------------------------
         
                invoke  GetModuleHandle, NULL
                         mov     hInstance, eax
                invoke  DialogBoxParam, hInstance, _T("MAINDIALOG"), 0, addr WndProc, 0
                invoke  ExitProcess, eax
         
        ;--------------------------------------------------------------------------------
         
        WndProc proc hWnd   :DWORD,
                      uMsg   :DWORD,
                      wParam :DWORD,
                      lParam :DWORD
                      
        .if uMsg == WM_INITDIALOG
         
            invoke  SendMessage, hWnd, WM_SETTEXT, NULL, _T("FTP клиент")
                         mov     eax, hWnd
                         mov     hDlg, eax           ; хэндл окна нам еще понадобится :)
                 ; сабклассируем контрол EDIT
                invoke  GetDlgItem, eax, IDC_Glav
                 ; для кликанья в лист боксе ;)
                invoke  SetWindowLong,eax, GWL_WNDPROC, addr ListBoxProc
                         mov      lpfnEditProc, eax   ; сохраняем адрес предыдущей функции
                
         .elseif uMsg==WM_COMMAND
                mov     eax, wParam
                mov     edx, eax;нажатие кнопок
                shr     edx, 16
                
         .if edx == BN_CLICKED
         
         ;---------------------------------------------------------------------------------------  
                
         .if ax == IDC_Connect;подключаемся к серверу и выводи все папки и файлы
              
                invoke   InternetOpen,addr AgetUser,INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
                          mov hInternet, eax
                      ;берём ip, login, pass    
                invoke   GetDlgItemText, [hWnd], IDC_User,   addr User,-1
                invoke   GetDlgItemText, [hWnd], IDC_Pass,   addr Pass,-1  
                invoke   GetDlgItemText, [hWnd], IDC_GETHOST,addr StrokaIz,-1
                      ;заполняем данными для подключенияи вперёд ;)
                invoke   InternetConnect, [hInternet],\;Дескриптор, полученный вызовом предыдущей функции.
                                                addr StrokaIz,\;хост
                                                INTERNET_DEFAULT_FTP_PORT,\; 21
                                                addr User,addr Pass,\;логин , пароль
                                                INTERNET_SERVICE_FTP,\;Тип сервиса
                                                0,\
                                                0
                          mov hConnect, eax;сохраняем дескриптор
                        ;берём директорию из контрола "/"
               invoke  GetDlgItemText, [hWnd],IDC_Dir,addr  BufferDir,-1        
               invoke  FindFTPFiles,[hConnect] ,addr  BufferDir ;ищем все файлы и папки    
                        
             .endif
                
         ;-----------------------------------------------------------------------------------------
         
                  ;смена директории
         .if ax ==  IDC_Setdir;берём название директориииз контрола
              invoke  GetDlgItemText, hWnd,IDC_Dir, addr  BufferDir,-1
              invoke  FindFTPFiles,   [hConnect] ,  addr  BufferDir ;ищем все файлы и папки
             .endif
            
        ;-----------------------------------------------------------------------------------------------  
         
          .if ax == IDC_Disconnect
          
                  invoke InternetCloseHandle, hConnect
                  
          .endif
          
         ;-------------------------------------------------------------------------------------------
         
        ;закачиваем файл на сервер  
           .if ax == IDC_PutFileName
           ;берём название файла
               invoke  GetDlgItemText, hWnd,IDC_GetFilename,addr NameFilePut,-1
               ;спрашиваем этот файл залить, малоли вдруг ошиблись ;)
               invoke MessageBox,[hWnd],offset NameFilePut,_T('Залить файл?'), MB_OKCANCEL
           .if ax == TRUE;если пользователь действительно хочет скачать выбранный файл
               invoke CreateFile,ADDR NameFilePut,\;открываем файл для чтения
                                    GENERIC_READ,\
                                    FILE_SHARE_READ,\
                                    NULL,\
                                    OPEN_ALWAYS,\
                                    0,\
                                    NULL;  
                       mov FileOpenchtobPut, eax;сохраняем хэндл
                       ;узнаём размер файла
               invoke GetFileSize,[FileOpenchtobPut],addr lpFileSizeHigh
                       mov lpFileSizeHigh, eax ;корректный размер
               invoke SetDlgItemInt,[hDlg],ObshiySize,lpFileSizeHigh  ,1              
                       ;создаём файл на сервере с соответствующим названием, для записи                  
               invoke FtpOpenFile,[hConnect],offset NameFilePut,GENERIC_WRITE ,\
                                        FTP_TRANSFER_TYPE_UNKNOWN,\;выбран как бинарь ;)
                                              INTERNET_FLAG_NEED_FILE
                       mov  FileOpenPut , eax;сохраняем дескриптор для заливки файла
                      ;открываем поток для заливки файла, отображения залитых байт и чтобы не тормозило ;)
               invoke CreateThread,0,0, offset threadprocputfile,0,0,offset jputfile
                  
                    
              .else
                
            .endif    
                 .endif
         
        ;-------------------------------------------------------------------------
              
          .if ax == IDC_EXIT;выход
                        invoke InternetCloseHandle,hConnect
                        invoke  SendMessage, hWnd, WM_CLOSE, 0, 0
                 .endif  
             .endif  
         .elseif uMsg == WM_CLOSE
                invoke InternetCloseHandle,hConnect
                invoke  EndDialog,hWnd,0
         
            .else
                mov     eax, FALSE
                ret
            .endif
                mov     eax, TRUE
                ret
         
        WndProc endp
                
         ;------------------------------------------------------------------------------------------------
         
        ;процедура поиска файлов и папок
        FindFTPFiles proc FConnect:DWORD, Dir:DWORD ;хэндл и выбранная директория
                
               invoke  GetDlgItem, hDlg, IDC_Glav
               ;отчищаем листбокс
               invoke  SendMessage, eax, LB_RESETCONTENT, 0, 0
               ;смена директории
               invoke  FtpSetCurrentDirectory, [FConnect],   Dir
               ;поиск всего ;)
              
               invoke  FtpFindFirstFile, [FConnect],_T('*.*'),addr FIND_DATA,INTERNET_FLAG_NEED_FILE , 0
                        mov  hFileConnection ,eax
               ;обнуляем структуру
               invoke  RtlZeroMemory, addr FIND_DATA, SizeOf(WIN32_FIND_DATA)
                        
         .repeat
           ;функции поиска и заполнения данными структуры ВИНДАТ и добавления в листбокс
         
             invoke  MESSG , [hDlg],  addr  (FIND_DATA.cFileName)  
              
             invoke  InternetFindNextFile,[hFileConnection],offset FIND_DATA  
            
          .until eax==FALSE  
            
             invoke InternetCloseHandle,hFileConnection;закрываем поюзанный хэндл :)
            
         ret
         
        FindFTPFiles endp
         
        ;--------------------------------------------------------------------------------------------
         
        ;обработка двойного нажатия клика мыши на строчку в листбоксе
        ListBoxProc  proc   hCtl: HWND, uMsg: UINT, wParam: WPARAM, lParam: LPARAM
            LOCAL IndexItem  :DWORD;номер строки
            mov     eax, wParam
            ;двойной клик по строчке в листбоксе
         .if ( uMsg == WM_LBUTTONDBLCLK )
          ;номер строчки
               invoke  SendMessage,hCtl,LB_GETCURSEL,0,0
                        mov IndexItem, eax
           ;извлекаем текст из кликнутой строчке :))          
               invoke  SendMessage,hCtl,LB_GETTEXT,IndexItem,ADDR BufferDir
              
                 ;обнуляем структуру
               invoke  RtlZeroMemory, addr FIND_DATA, SizeOf(WIN32_FIND_DATA)
                
              
               invoke  FtpFindFirstFile, [hConnect],ADDR BufferDir, offset FIND_DATA,INTERNET_FLAG_RESYNCHRONIZE , 0
                        mov  hFileConnection ,eax
                    
         .if FIND_DATA.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY
          
                  invoke  InternetCloseHandle,hFileConnection
                      ;поток поиска файлов в директории
            invoke  CreateThread,0,0, offset treadftpfind ,0,0,offset jfindftp
                    
                     jmp EXITPROC
                    
                .else
                
         .endif
         ;спрашиваем действительно ли пользователь хочет скачать файл
                 invoke MessageBox,[hCtl], ADDR BufferDir,_T('Скачать файл?'), MB_OKCANCEL
              
         .if ax == TRUE
              
           ;открываем файл на сервере для чтения
                    invoke FtpOpenFile,[hConnect],ADDR BufferDir,GENERIC_READ ,\
                                        FTP_TRANSFER_TYPE_UNKNOWN,\
                                               NULL
                            mov [hInetFileHandle], eax
             ;запрашиваем размер файла с сервера      
                    invoke FtpGetFileSize,[hInetFileHandle]  ,\
                                              offset lpdwFileSizeHigh
                            mov lpdwFileSizeHigh,eax
                            
                    invoke SetDlgItemInt,[hDlg],ObshiySize,  lpdwFileSizeHigh ,1  
             ;создаём файл для записи закачанных байт      
                    invoke CreateFile,ADDR BufferDir,\
                                    GENERIC_WRITE,\
                                    FILE_SHARE_WRITE,\
                                    NULL,\
                                    OPEN_ALWAYS,\
                                    0,\
                                    NULL
                            mov hFile , eax                              
         ;поток скачивания
                    invoke  CreateThread,0,0, offset threadprocdownloadfile ,0,0,offset jdownftp
                  
             .else
          EXITPROC:      
             .endif    
         .endif
            ; нажата любая другая клавиша, вызываем старую функцию контрола
            invoke  CallWindowProc, lpfnEditProc, hCtl, uMsg, wParam, lParam
            ret
         
        ListBoxProc endp
         
        ;--------------------------------------------------------------------------------------------
         
        ;посылка сообщения в лист бокс
         MESSG proc hWnd: HWND, message: DWORD
                invoke  GetDlgItem, hDlg, IDC_Glav
                push    eax
                invoke  SendMessage, eax, LB_ADDSTRING, 0, message
                pop     ecx
                invoke  SendMessage, ecx, LB_SETTOPINDEX, eax, 0
                ret
         MESSG endp
         
        ;----------------------------------------------------------------------------------------------
         
        ;поток входа в папку на ftp и поиска всех файлов и папок в текущей директории
        treadftpfind proc
         
               invoke  SetDlgItemText, [hDlg]  ,IDC_Dir, addr BufferDir;смена названия директории в Edit
               invoke  FindFTPFiles,   [hConnect] , addr  BufferDir  ;ищем все файлы и папки
          
           ret  
         
        treadftpfind endp
         
        ;----------------------------------------------------------------------------------------------
         
         ;поток скачивания файла с ftp - сервера
        threadprocdownloadfile proc
         
        ;обнуляем общий буфер, который играет немаловажную роль для подсчёта скачанных байт :)
                  mov ObshiyBuffer, 0h
        .repeat;цикл закачки с постусловием
         
          invoke InternetReadFile,[hInetFileHandle],\;функция считывает в буфер байтики
           addr BufferFile,\;буфер для чтения
           sizeof BufferFile ,\;размер буфера
           addr wNumberOfBytesToRead;считаных байт
          
           ;считаем сколько всего закачалось из файла в каждый момент времени 1024 буф.
                 mov eax,   ObshiyBuffer;общий буфер в регистр для сложения
                 add eax, CountBytesWrite
                 mov   ObshiyBuffer , eax ;результат в общий буфер
         
           ;выводим в контрол сколько же мы уже скачали
          invoke SetDlgItemInt,[hDlg],SizeGetPutFile,  ObshiyBuffer , 1
         
           ;запись файла на диск; дескриптор созданного файла, буфер, размер буфера, записанных байт
          invoke WriteFile, [hFile],addr BufferFile ,wNumberOfBytesToRead, addr CountBytesWrite , NULL
         
         .until  wNumberOfBytesToRead == 0 ;качаем файл пока не закончится ^ всё равно запишется ноль ;)
          
            ;закрываем дескриптор скачиваемого и сзданного файла
             invoke CloseHandle, hFile
             invoke InternetCloseHandle, hInetFileHandle
            
            ret  
         
        threadprocdownloadfile endp
         
        ;---------------------------------------------------------------------------------------------
         
        ;поток, чтобы положить файл на сервант ;)
        threadprocputfile proc
         mov ObshiyBufferPut, 0h;обнуляем
        ;читаем файл пока не закончится
        .repeat  
         ;функция чтения файла с диска
          invoke ReadFile,[FileOpenchtobPut],\
            addr BufferReadPut,\ ;буфер для данных
                      sizeof  BufferReadPut,\ ;его размер
            addr ReadByteFilePut,\ ;сколько считали
            NULL
          ;считаем сколько считали и поидеи должны отправить ;)
                  mov eax,   ObshiyBufferPut
                  add eax,   ReadByteFilePut
                  mov ObshiyBufferPut , eax
          ;заливаем        
          invoke InternetWriteFile,[FileOpenPut],\;хэндл вернувшийся после гуляния с фун-ей FtpOpenFile
             addr BufferReadPut,\;буфер записывания :)
             ReadByteFilePut,\;размер
             addr pdwNumberOfBytesWritten;сколько положили
         ;выводим так как очень интересно :)
          invoke SetDlgItemInt,[hDlg],SizeGetPutFile,  ObshiyBufferPut  , 1
        ;когда-нибудь да он закончится
         .until ReadByteFilePut==0
          ;закрываем теперь уже не нужные дескрипторы
             invoke  CloseHandle, FileOpenchtobPut
             invoke  InternetCloseHandle, FileOpenPut
            
        ret
         
        threadprocputfile endp
         
        end start
      Диалог:

      ExpandedWrap disabled
        #define IDD_DLG1 MAINDIALOG
        #define IDC_EDT1 1001
        #define IDC_LST1 1000
        #define IDC_STC1 10003
        #define IDC_EDT2 1003
        #define IDC_EDT3 1004
        #define IDC_EDT4 1002
        #define IDC_BTN1 1009
        #define IDC_BTN2 1005
        #define IDC_BTN3 1006
        #define IDC_STC2 10010
        #define IDC_STC3 10011
        #define IDC_STC4 10012
        #define IDC_STC5 10013
        #define IDC_EDT5 1010
        #define IDC_STC6 10014
        #define IDC_STC7 1011
        #define IDC_BTN4 1007
        #define IDC_BTN5 1008
        #define IDC_STC8 1013
        #define IDC_STC9 1012
        IDD_DLG1 DIALOGEX 6,5,397,240
        CAPTION "IDD_DLG"
        FONT 8,"MS Sans Serif",0,0
        STYLE 0x10CF0000
        BEGIN
          CONTROL "127.0.0.1",IDC_EDT1,"Edit",0x50010000,298,12,54,13,0x00000200
          CONTROL "",IDC_LST1,"ListBox",0x50010141,2,1,256,235,0x00000200
          CONTROL "NamePutFile",IDC_STC1,"Static",0x50000000,300,84,54,9
          CONTROL "",IDC_EDT2,"Edit",0x50010000,264,40,54,13,0x00000200
          CONTROL "",IDC_EDT3,"Edit",0x50010000,334,40,54,13,0x00000200
          CONTROL "/",IDC_EDT4,"Edit",0x50010000,300,68,56,13,0x00000200
          CONTROL "PutFile",IDC_BTN1,"Button",0x50010000,300,116,54,13
          CONTROL "Connect",IDC_BTN2,"Button",0x50010000,270,204,54,13
          CONTROL "SetDir",IDC_BTN3,"Button",0x50010000,270,221,54,13
          CONTROL "Host",IDC_STC2,"Static",0x50000000,298,0,54,9
          CONTROL "Login",IDC_STC3,"Static",0x50000000,266,27,54,9
          CONTROL "Pass",IDC_STC4,"Static",0x50000000,336,27,54,9
          CONTROL "Dir",IDC_STC5,"Static",0x50000000,302,55,54,9
          CONTROL "LINK.EXE",IDC_EDT5,"Edit",0x50010000,300,99,54,13,0x00000200
          CONTROL "SizeProc",IDC_STC6,"Static",0x50000000,300,169,54,9
          CONTROL "0",IDC_STC7,"Static",0x50000000,300,182,54,9
          CONTROL "Disconnect",IDC_BTN4,"Button",0x50010000,328,204,54,13
          CONTROL "Exit",IDC_BTN5,"Button",0x50010000,328,221,54,13
          CONTROL "Размер",IDC_STC8,"Static",0x50000000,300,142,54,11
          CONTROL "0",IDC_STC9,"Static",0x50000000,300,156,54,9
        END
      Компилируем:

      ExpandedWrap disabled
        rc.exe Dlg.rc
        E:\masm32\BIN\FTPConnect\ml /c /coff FtpC.asm
        E:\masm32\BIN\FTPConnect\Link /SUBSYSTEM:WINDOWS FtpC.obj Dlg.RES
        pause


      Если вы пожертвуете в фонд проекта возможно я добавлю докачку и скачивание папок. ( шучу ;) )
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0428 ]   [ 16 queries used ]   [ Generated: 19.03.24, 09:36 GMT ]