Как реализовать поиск файла по всему жёсткому диску?

Тема в разделе "WASM.ASSEMBLER", создана пользователем MrMiXeR, 28 июл 2008.

  1. MrMiXeR

    MrMiXeR New Member

    Публикаций:
    0
    Регистрация:
    27 июн 2008
    Сообщения:
    97
    собственно сабж, подскажите как на MASM такое сделать
     
  2. Com[e]r

    Com[e]r Com[e]r

    Публикаций:
    0
    Регистрация:
    20 апр 2007
    Сообщения:
    2.624
    Адрес:
    ого..
    в бегиннерс.
    если же на апи, то алгоритм следующий:
    proc Ftest dir:lol: WORD
    lstrcat etc...
    invoke FindFirstFileA()
    cmp eax,ERROR_*
    jz _not_gsom
    mov I,eax
    _gsom:
    if(directory) invoke Ftest,<...>.cfilename
    if(that_file) ...
    invoke FindNextFileA,I,...
    cmp eax,ERROR_NO_MORE_FILES
    jnz _gsom
    _not_gsom:
    invoke CloseHandle,I
    output etc...
    ret
    endp Ftest
     
  3. MrMiXeR

    MrMiXeR New Member

    Публикаций:
    0
    Регистрация:
    27 июн 2008
    Сообщения:
    97
    то есть как я понимаю, эта функция вызывает себя же если деректория? И за счёт этого организуется перебор всех директорий?
     
  4. MrMiXeR

    MrMiXeR New Member

    Публикаций:
    0
    Регистрация:
    27 июн 2008
    Сообщения:
    97
    Допустим, что на C:\ у нас есть папки 1, 2 и 3 при этом в папке 1 есть подпапки 11, 12, 13 etc. я так понимаю если пойдёт перебор по твоему методу и при этом переменная типа WIN32_FIND_DATA одна, папку 1 прога просмотрит всю, но до папки 2 не доберётся. Быть может я не прав?
     
  5. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    одна для каждого конкретного вызова процедуры.
    Сколько будет вызовов, столько и переменных будет. Т.к. локальная переменная выделяется на стеке при вызове процедуры
     
  6. MrMiXeR

    MrMiXeR New Member

    Публикаций:
    0
    Регистрация:
    27 июн 2008
    Сообщения:
    97
    Блииин ))))) Теперь допетрил! :) Я создавал глобальную переменную )))) хм... интересно, а как же мне создать локальную переменную с типом структуры? :|
    на Local FileData WIN32_FIND_DATA <> ругаеццо однако
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    LOCAL wfd : WIN32_FIND_DATA
     
  8. MrMiXeR

    MrMiXeR New Member

    Публикаций:
    0
    Регистрация:
    27 июн 2008
    Сообщения:
    97
    FindMagicFiles proc uses ebx edx ecx esi edi DirPath:dword
    local FileAttrib: WIN32_FIND_DATA
    local FindedFileHandle:dword

    invoke FindFirstFile, DirPath, addr FileAttrib
    mov FindedFileHandle, eax
    .while eax != 0
    .if FileAttrib.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY
    invoke lstrlen, DirPath
    mov edi, DirPath
    lea edi, dword ptr ds:[edi + eax - 3]
    lea esi, dword ptr ds:[FileAttrib.cFileName]
    invoke lstrlen, esi
    mov ecx, eax
    inc ecx
    rep movsb
    mov ebx, eax
    dec edi
    invoke lstrcat, edi, offset FindMask
    invoke FindMagicFiles, DirPath
    .endif
    push eax
    invoke FindNextFile, FindedFileHandle, addr FileAttrib
    .endw
    ret
    FindMagicFiles Endp

    вот так выглядит процедура, первую папку находит, когда вызываю её же для дочерних папок FindFirstFile отказывается возвращать имя дочерней папки
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Когда найдена директория, нужно проверить имя: если имя '.' или '..' нужно пропустить эти директории (текущая и родительская). Для остальных папок нужно вызывать функцию снова
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Это писалось давно, наверняка неоптимально, но работает, посмотри что и как

    Код (Text):
    1. ReadTheFile_1  proc StartAddr:DWORD
    2. LOCAL    FindData       :WIN32_FIND_DATA;
    3.  
    4. LOCAL    hFind          :DWORD
    5. LOCAL    szBuff[260]    :BYTE
    6. LOCAL    szBuffRest[260]:BYTE
    7. LOCAL Lft               :FILETIME
    8. LOCAL time              :SYSTEMTIME
    9.    
    10.    
    11.     mov eax,Break  ;глобальная переменная-флаг (останов поиска)
    12.     test eax,eax
    13.     jz @F
    14.     ret
    15.     @@:
    16.     invoke lstrcpy, addr szBuff,StartAddr               ;копируем в буфер входную строку
    17.     invoke lstrcat, addr szBuff, addr szAll
    18.     ;invoke MessageBox,NULL,addr szBuff,StartAddr,MB_OK
    19.     invoke FindFirstFile, addr szBuff, addr FindData
    20.         .if eax != INVALID_HANDLE_VALUE
    21.             mov hFind, eax
    22.             .while eax != 0
    23.                 .if byte ptr FindData.cFileName != '.'
    24.                     push edi
    25.                     ;--------------------- store File name ----
    26.                     mov edi,[hFirstMem]
    27.                     add edi,CurrMemAddr
    28.                     invoke MemCopy,addr FindData.cFileName,edi,128
    29.                     add edi,128
    30.                     ;--------------------- store File size ----
    31.                     mov edx, FindData.nFileSizeLow
    32.                     .if edx==0
    33.                         invoke lstrcpy,addr szBuff,addr szDir
    34.                     .else
    35.                         invoke BaseAscii, edx, addr szBuff, 0, 10, 0, 0, 1
    36.                     .endif
    37.                     invoke MemCopy,addr szBuff,edi,11
    38.                     add edi,11
    39.                     ;--------------------- store File time ----
    40.                     invoke FileTimeToLocalFileTime, addr FindData.ftLastWriteTime, addr Lft
    41.                     invoke FileTimeToSystemTime, addr Lft, addr time
    42.                     invoke fmtime, time.SYSTEMTIME
    43.                     invoke MemCopy,addr cdt.dmo,edi,21
    44.                     add edi,21
    45.                     ;--------------------- store File attributes ----
    46.                     invoke lstrcpy,addr szArc,addr szFill
    47.                     mov eax, offset szArc
    48.                     .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
    49.                         mov byte ptr[eax], 'r'
    50.                     .endif
    51.                     .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
    52.                         mov byte ptr[eax+1], 'a'
    53.                     .endif
    54.                     .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
    55.                         mov byte ptr[eax+2], 'h'
    56.                     .endif
    57.                     .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
    58.                         mov byte ptr[eax+3], 's'
    59.                     .endif
    60.                     invoke MemCopy,addr szArc,edi,5
    61.                     add edi,5
    62.                     ;----------------------- store Folder name -----
    63.                     invoke MemCopy,StartAddr,edi,256
    64.                     add CurrMemAddr,422
    65.                     pop edi
    66.  
    67.                     mov eax,Cnt
    68.                     .if eax<50 ;&& eax!=0
    69.                         invoke SendMessage,hList,LVM_SETITEMCOUNT,Cnt,LVSICF_NOINVALIDATEALL
    70.                     .endif
    71.                     inc Cnt
    72.                 .endif
    73.                 invoke FindNextFile, hFind, addr FindData
    74.             .endw
    75.             invoke FindClose, hFind
    76.         .endif
    77.      
    78. ; ;------------------------------  Поиск в подпапках ---------------------------------    
    79.       ;invoke MessageBox,NULL, StartAddr, addr szAsterix, MB_OK
    80.       invoke lstrcpy, addr szBuff,StartAddr             ;копируем в буфер входную строку
    81.       invoke lstrcat, addr szBuff, addr szAsterix;;
    82.      
    83.        
    84.       invoke FindFirstFile, addr szBuff, addr FindData
    85.       .if eax != INVALID_HANDLE_VALUE
    86.           mov hFind, eax
    87.          .while eax != 0
    88.             .if byte ptr FindData.cFileName != '.'
    89.                .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
    90.                     invoke lstrcpy,addr szBuffRest, StartAddr
    91.                     invoke lstrcat,addr szBuffRest,addr FindData.cFileName
    92.                     invoke lstrcat,addr szBuffRest,addr szSlashB
    93.                     invoke ReadTheFile_1,addr szBuffRest  
    94.                     ;dec recur
    95.                     inc FolderCount
    96.                     mov eax,FolderCount
    97.                     test eax,32
    98.                     jz @F
    99.                     Call Progress
    100.                     @@:
    101.                .endif
    102.             .endif
    103.             invoke FindNextFile,hFind,addr FindData
    104.          .endw
    105.          invoke FindClose, hFind
    106.       .endif
    107.  
    108. @@:
    109.    
    110.      ret
    111. ReadTheFile_1  endp
     
  11. ovejto

    ovejto New Member

    Публикаций:
    0
    Регистрация:
    21 июл 2008
    Сообщения:
    6
    Я бы добавила такое (ведь надо найти по всех дисках):
    Кстати, обрати внимание на максимальную длинну в MAX_PATH символов. Можно попробовать использовать unicode строку, там лимит в 32K-1 но с ней больше проблем :dntknw:

    GetLogicalDriveStrings - выдаст все имена дисков как массив чаров
    и убрать все не локальные диски через вызов GetDriveType

    все тут:
    http://msdn.microsoft.com/en-us/library/aa364975(VS.85).aspx - GetLogicalDriveStrings
    http://msdn.microsoft.com/en-us/library/aa364939(VS.85).aspx - GetDriveType
    http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx - FindFirstFile