в бегиннерс. если же на апи, то алгоритм следующий: proc Ftest dirWORD 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
то есть как я понимаю, эта функция вызывает себя же если деректория? И за счёт этого организуется перебор всех директорий?
Допустим, что на C:\ у нас есть папки 1, 2 и 3 при этом в папке 1 есть подпапки 11, 12, 13 etc. я так понимаю если пойдёт перебор по твоему методу и при этом переменная типа WIN32_FIND_DATA одна, папку 1 прога просмотрит всю, но до папки 2 не доберётся. Быть может я не прав?
одна для каждого конкретного вызова процедуры. Сколько будет вызовов, столько и переменных будет. Т.к. локальная переменная выделяется на стеке при вызове процедуры
Блииин ))))) Теперь допетрил! Я создавал глобальную переменную )))) хм... интересно, а как же мне создать локальную переменную с типом структуры? :| на Local FileData WIN32_FIND_DATA <> ругаеццо однако
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 отказывается возвращать имя дочерней папки
Когда найдена директория, нужно проверить имя: если имя '.' или '..' нужно пропустить эти директории (текущая и родительская). Для остальных папок нужно вызывать функцию снова
Это писалось давно, наверняка неоптимально, но работает, посмотри что и как Код (Text): ReadTheFile_1 proc StartAddr:DWORD LOCAL FindData :WIN32_FIND_DATA; LOCAL hFind :DWORD LOCAL szBuff[260] :BYTE LOCAL szBuffRest[260]:BYTE LOCAL Lft :FILETIME LOCAL time :SYSTEMTIME mov eax,Break ;глобальная переменная-флаг (останов поиска) test eax,eax jz @F ret @@: invoke lstrcpy, addr szBuff,StartAddr ;копируем в буфер входную строку invoke lstrcat, addr szBuff, addr szAll ;invoke MessageBox,NULL,addr szBuff,StartAddr,MB_OK invoke FindFirstFile, addr szBuff, addr FindData .if eax != INVALID_HANDLE_VALUE mov hFind, eax .while eax != 0 .if byte ptr FindData.cFileName != '.' push edi ;--------------------- store File name ---- mov edi,[hFirstMem] add edi,CurrMemAddr invoke MemCopy,addr FindData.cFileName,edi,128 add edi,128 ;--------------------- store File size ---- mov edx, FindData.nFileSizeLow .if edx==0 invoke lstrcpy,addr szBuff,addr szDir .else invoke BaseAscii, edx, addr szBuff, 0, 10, 0, 0, 1 .endif invoke MemCopy,addr szBuff,edi,11 add edi,11 ;--------------------- store File time ---- invoke FileTimeToLocalFileTime, addr FindData.ftLastWriteTime, addr Lft invoke FileTimeToSystemTime, addr Lft, addr time invoke fmtime, time.SYSTEMTIME invoke MemCopy,addr cdt.dmo,edi,21 add edi,21 ;--------------------- store File attributes ---- invoke lstrcpy,addr szArc,addr szFill mov eax, offset szArc .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) mov byte ptr[eax], 'r' .endif .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) mov byte ptr[eax+1], 'a' .endif .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) mov byte ptr[eax+2], 'h' .endif .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) mov byte ptr[eax+3], 's' .endif invoke MemCopy,addr szArc,edi,5 add edi,5 ;----------------------- store Folder name ----- invoke MemCopy,StartAddr,edi,256 add CurrMemAddr,422 pop edi mov eax,Cnt .if eax<50 ;&& eax!=0 invoke SendMessage,hList,LVM_SETITEMCOUNT,Cnt,LVSICF_NOINVALIDATEALL .endif inc Cnt .endif invoke FindNextFile, hFind, addr FindData .endw invoke FindClose, hFind .endif ; ;------------------------------ Поиск в подпапках --------------------------------- ;invoke MessageBox,NULL, StartAddr, addr szAsterix, MB_OK invoke lstrcpy, addr szBuff,StartAddr ;копируем в буфер входную строку invoke lstrcat, addr szBuff, addr szAsterix;; invoke FindFirstFile, addr szBuff, addr FindData .if eax != INVALID_HANDLE_VALUE mov hFind, eax .while eax != 0 .if byte ptr FindData.cFileName != '.' .if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) invoke lstrcpy,addr szBuffRest, StartAddr invoke lstrcat,addr szBuffRest,addr FindData.cFileName invoke lstrcat,addr szBuffRest,addr szSlashB invoke ReadTheFile_1,addr szBuffRest ;dec recur inc FolderCount mov eax,FolderCount test eax,32 jz @F Call Progress @@: .endif .endif invoke FindNextFile,hFind,addr FindData .endw invoke FindClose, hFind .endif @@: ret ReadTheFile_1 endp
Я бы добавила такое (ведь надо найти по всех дисках): Кстати, обрати внимание на максимальную длинну в MAX_PATH символов. Можно попробовать использовать unicode строку, там лимит в 32K-1 но с ней больше проблем 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