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

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > Рекурсивный поиск файлов , Windows, Общие вопросы
      Рекурсивный поиск файлов (FASM)


      ExpandedWrap disabled
        ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
        ; Global files search in FASM
        ;      Created by Ct757
        ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
        ;
        ;
        ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ; В данном примере показана рекурсивная реализация
        ; поиска файлов на ассембеле под Windows с помощью
        ; API-функций FindFirstFile + FindNextFile, а так же
        ; показано как можно узнать список присутстующих
        ; в системе дисков с помощью функции GetLogicalDrives
        ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         
         
        format PE GUI 4.0                      ; PE EXE файл
        entry start                        ; Точка входа
         
          include '%fasminc%\win32a.inc'
         
        section '.main' code readable writeable executable     ; Секция кода
                                       ; и данных
         
              buf     rb 500h                      ; Буффер для имени директории
         
              fake1   dd '.',0                     ; Дирекории, которые
              fake2   dd '..',0                    ; НЕ надо сканировать
         
         
          start:                           ; Начало основной
                                       ; Программы
         
              push    1h                       ; SEM_FAILCRITICALERRORS
              call    [SetErrorMode]                   ; Установим error mode
                                       ; что бы в случае обращения
                                       ; к недоступному диску
                                       ; не вываливалось сообщение
         
              call    [GetLogicalDrives]               ; Получаем список дисков,
                                       ; существующих в системе
         
              mov     ecx,25                       ; Будем проверять, начиная с Z:\
         
            .find_drives:
              mov     ebx,1                    ; Нехитрые опрерации в
              shl     ebx,cl                       ; ходе которых мы выясняем
              and     ebx,eax                      ; присутствует диск в
              je      .no_disk                     ; системе или нет
         
        ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        ; На всякий случай, пояснение из MSDN:
        ;
        ; ;---------------------------------;
        ; ;  DWORD GetLogicalDrives(void);  ;
        ; ;---------------------------------;
        ;
        ; Return Values:
        ; --------------
        ;     If the function succeeds, the return value is a bitmask
        ;     representing the currently available disk drives.
        ;     Bit position 0 (the least-significant bit) is drive A,
        ;     bit position 1 is drive B, bit position 2 is drive C, and so on.
        ;
        ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         
              add     cl,65                    ; Если да, то добавим
              mov     byte [buf],cl                ; букву диска в
              sub     cl,65                    ; буффер
         
              mov     dword [buf+1],':\*.'             ; Сформируем строку
              mov     byte [buf+5],'*'                 ; для поиска, вида,
              mov     byte [buf+6],0                   ; например, C:\*.*
         
              push    eax                      ; Сохраняем в стеке
              push    ecx                      ; нужные регистры
         
              call    find_files                   ; Вызываем процедуру поиска
         
              pop     ecx                      ; Восстанавливаем
              pop     eax                      ; регистры
         
            .no_disk:                          ; Если диска нет,
              dec     ecx                      ; то проверяем следующий
              jge     .find_drives                 ; пока ecx>0
         
              push    0                        ; Выходим из
              call    [ExitProcess]                ; программы
         
         
          proc find_files                      ; Рекурсивная процедура
                                       ; поиска файлов
         
            locals                         ; Локальные переменные:
              fd     FINDDATA                      ; структура WIN32_FIND_DATA
              find_h dd ?                      ; и хэндл поиска
            endl
         
              lea    eax,[fd]                      ; Вычисляем и кладем в стек
              push   eax                       ; указатель на стуктуру find data
              push   buf                       ; Указатель на имя директории, где искать
              call   [FindFirstFile]                   ; Ищем
              inc    eax                       ; Если ничего
              je     .exit                     ; не нашли - выходим
              dec    eax                       ; Иначе, сохраним
              mov    [find_h],eax                  ; хэндл поиска
         
            .find_next:
              mov    eax,[fd.dwFileAttributes]             ; Проверяем, нашли
              and    eax,FILE_ATTRIBUTE_DIRECTORY          ; директорию?
              je     .found                    ; Если нет - прыгаем на .found
         
              lea    eax,[fd.cFileName]                ; Проверяем,
              push   eax                       ; вдруг это
              push   fake1                     ; "."
              call   [lstrcmp]                     ;
              test   eax,eax                       ; Если да,
              je     .next                     ; ищем следующий файл
         
              lea    eax,[fd.cFileName]                ; Проверяем,
              push   eax                       ; вдруг это
              push   fake2                     ; ".."
              call   [lstrcmp]                     ;
              test   eax,eax                       ; Если да
              je     .next                     ; ищем следующий файл
         
              push   buf                       ; Вычислим
              call   [lstrlen]                     ; длину строки
              sub    eax,3                     ; вычтем *.*
              push   eax                       ; сохраним полученную длину
         
              mov    byte [buf+eax],0                  ; Если мы всё-таки
              lea    eax,[fd.cFileName]                ; нашли директорию
              push   eax                       ; то прибавляем
              push   buf                       ; её имя к текущей
              call   [lstrcat]                     ; папке
         
              push   buf                       ; Опять вычислим
              call   [lstrlen]                     ; длину получившейся строки
         
              mov    dword [buf+eax],'\*.*'            ; и прибавим
              mov    byte [buf+eax+4],0                ; \*.* для поиска
         
              call   find_files                    ; Вызываем процедуру
                                       ; поиска для найденной
                                       ; директории
         
              pop    eax                       ; Восстановим
              mov    dword [buf+eax-1],'\*.*'              ; имя прежней
              mov    byte [buf+eax+3],0                ; директории
         
              jmp    .next                     ; Ищем следующий файл
         
            .found:
         
              lea    eax,[fd.cFileName]
              push   eax
              call   [lstrlen]
              cmp    dword [fd.cFileName+eax-4],'.txt'         ; Проверим расширение файла
              jne    .next                     ; Если не совпадает ищем дальше
         
              lea    eax,[fd.cFileName]
              push   0                         ;
              push   eax                       ;
              push   eax                       ;
              push   0                         ; Покажем MessageBox с
              call   [MessageBox]                  ; именем найденного файла
         
            .next:
              lea    eax,[fd]                      ; Кладем в стек указатель
              push   eax                       ; на структуру find_data
              push   [find_h]                      ; Хэндл текущего поиска
              call   [FindNextFile]                ; Ищем следующий файл
              test   eax,eax                       ;
              jne    .find_next                    ; Если ничего не нашли,
         
              push   [find_h]                      ; то закрываем
              call   [FindClose]                   ; хэндл поиска
         
            .exit:                         ;
              ret                          ; Выход
          endp
         
        data import                        ; Импорт нужных API-функций
         
          library kernel32,'KERNEL32.DLL',\
              user32,'USER32.DLL'
         
          include '%fasminc%\APIA\kernel32.inc'
          include '%fasminc%\APIA\user32.inc'
         
        end data
      Сообщение отредактировано: Ct757 -
        Рекурсивный поиск файлов (MASM32)


        ExpandedWrap disabled
          ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
          ; Global files search in MASM
          ;      Created by Ct757
          ; -=-=-=-=-=-=-=-=-=-=-=-=-=-
          ;
          ;
          ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ; В данном примере показана рекурсивная реализация
          ; поиска файлов на ассемблере под Windows с помощью
          ; API-функций FindFirstFile + FindNextFile, а так же
          ; показано как можно узнать список присутствующих
          ; в системе дисков с помощью функции GetLogicalDrives
          ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           
          .386
          .model flat, stdcall
           
          option casemap:none
           
          include \masm32\include\windows.inc
          include \masm32\include\kernel32.inc
          include \masm32\include\user32.inc
           
          includelib \masm32\lib\user32.lib
          includelib \masm32\lib\kernel32.lib
           
          .data                                                         ; Секция данных
           
                buf     db 500h dup(?)                                  ; Буффер для имени директории
              
                fake1   db '.',0                                        ; Директории, которые
                fake2   db '..',0                                       ; НЕ надо сканировать
           
          .code                                                         ; Секция кода
           
          find_files proc                                               ; Рекурсивная процедура
                                                                        ; Поиска файлов
           
                push    ebp                                             ; Выделим место в стеке
                mov     ebp,esp                                         ; под хэндл поиска
                sub     esp,144h                                        ; и структуру WIN32_FIND_DATA
           
                lea     eax,[ebp-144h]                                  ; Вычисляем указатель на find_data
                invoke  FindFirstFile,offset buf,eax                    ; Ищем файлы
                inc     eax                                             ; Если ничего
                je      exit                                            ; не нашли - выходим
                dec     eax                                             ; Иначе, сохраним
                mov     dword ptr [ebp-6h],eax                          ; хэндл поиска
           
          find_next:
                mov     eax,dword ptr [ebp-144h]                        ; Проверяем, нашли
                and     eax,FILE_ATTRIBUTE_DIRECTORY                    ; директорию?
                je      found                                           ; Если нет - прыгаем на found
           
                lea     eax,[ebp-118h]                                  ; Вычислим указатель на cFileName
                invoke  lstrcmp,offset fake1,eax                        ; это "."?
                test    eax,eax                                         ; Если да,
                je      next                                            ; ищем дальше
           
                lea     eax,[ebp-118h]                                  ; Вычислим указатель на cFileName
                invoke  lstrcmp,offset fake2,eax                        ; это ".."?
                test    eax,eax                                         ; Если да,
                je      next                                            ; ищем дальше
           
                invoke  lstrlen,offset buf                              ; Вычислим длину строки
                sub     eax,3                                           ; Вычтем *.*
                push    eax                                             ; Сохраним полученную длину
           
                mov     byte ptr [buf+eax],0                            ; Если мы всё-таки нашли
                lea     eax,[ebp-118h]                                  ; директорию, то прибавим
                invoke  lstrcat,offset buf,eax                          ; к её имени cFileName
           
                invoke  lstrlen,offset buf                              ; Вычислим длину строки
           
                mov     dword ptr [buf+eax],'*.*\'                      ; Прибавим \*.*
                mov     byte ptr [buf+eax+4],0                          ; для поиска
           
                call    find_files                                      ; Вызываем процедуру поиска
                                                                        ; для найденной директории
           
                pop     eax                                             ; Восстановим дляну строки
                mov     dword ptr [buf+eax-1],'*.*\'                    ; И восстановим \*.*
                mov     byte ptr [buf+eax+3],0                          ;
           
                jmp     next                                            ; Ищем дальше
           
          found:
                lea     eax,[ebp-118h]                                  ; Вычислим длину
                invoke  lstrlen,eax                                     ; cFileName
                cmp     dword ptr [ebp-118h+eax-4],'txt.'               ; Проыерим расширение файла
                jne     next                                            ; Если не равно ищем дальше
           
                lea     eax,[ebp-118h]                                  ; Если нашли, то что нужно
                invoke  MessageBox,0,eax,eax,0                          ; Покажем MessageBox с именем файла
           
          next:
                lea     eax,[ebp-144h]                                  ; Вычислим указатель на find_data
                invoke  FindNextFile,dword ptr [ebp-6h],eax             ; Ищем следующий файл
                test    eax,eax                                         ;
                jne     find_next                                       ; Если ничего не нашли
           
                invoke  FindClose,dword ptr [ebp-6h]                    ; Закрываем хэндл поиска
           
          exit:
                leave                                                   ; Выходим из
                ret                                                     ; процедуры
          find_files endp
           
          start:
                invoke  SetErrorMode,SEM_FAILCRITICALERRORS             ; Установим error mode
                                                                        ; чтобы в случае обращения
                                                                        ; к недоступному диску
                                                                        ; не вываливалось сообщение
           
                invoke  GetLogicalDrives                                ; Получаем список дисков
                                                                        ; существующих в системе
           
                mov     ecx,25                                          ; Будем проверять, начиная с Z:\
           
          find_drives:
                mov     ebx,1                                           ; Нехитрые операции в
                shl     ebx,cl                                          ; ходе которых мы выясняем
                and     ebx,eax                                         ; присутсвует диск в
                je      no_disk                                         ; системе или нет
           
          ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ; На всякий случай, пояснение из MSDN:
          ;
          ; ;---------------------------------;
          ; ;  DWORD GetLogicalDrives(void);  ;
          ; ;---------------------------------;
          ;
          ; Return Values:
          ; --------------
          ;     If the function succeeds, the return value is a bitmask
          ;     representing the currently available disk drives.
          ;     Bit position 0 (the least-significant bit) is drive A,
          ;     bit position 1 is drive B, bit position 2 is drive C, and so on.
          ;
          ; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
           
                add     cl,65                                           ; Если да, то
                mov     byte ptr buf,cl                                 ; добавим букву
                sub     cl,65                                           ; диска в буффер
           
                mov     dword ptr buf+1,'.*\:'                          ; Сформируем строку
                mov     byte ptr buf+5,'*'                              ; для поиска, вида,
                mov     byte ptr buf+6,0                                ; например, C:\*.*
           
                push    eax                                             ; Сохраняем нужные
                push    ecx                                             ; регистры в стеке
           
                call    find_files                                      ; Вызываем процедуру поиска
           
                pop     ecx                                             ; Восстанавливаем
                pop     eax                                             ; регистры
           
          no_disk:                                                      ; Если диска нет,
                dec     ecx                                             ; то проверяем следующий
                jge     find_drives                                     ; пока ecx>0
           
                invoke  ExitProcess,0                                   ; Выходим из программы
          end start
        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
        0 пользователей:


        Рейтинг@Mail.ru
        [ Script execution time: 0,0308 ]   [ 15 queries used ]   [ Generated: 19.04.24, 08:17 GMT ]