• XSS.stack #1 – первый литературный журнал от юзеров форума

Криво работает поиск файлов

Quake3

TPU unit
Забанен
Регистрация
03.11.2010
Сообщения
4 529
Решения
4
Реакции
5 305
Депозит
0.046
Пожалуйста, обратите внимание, что пользователь заблокирован
Написал рекурсивный поиск файлов. Вроде все работает, но есть некоторые проблемы, а именно - почему-то выводятся имена "..". Хотя я пробовал сравнивать и через lstrcmp, и иначе (;&& byte ptr[fd.cFileName]!="." && word ptr[fd.cFileName]!=".."), все равно не получается.
В чем ошибка?
р.s. Большая просьба помочь именно с этим кодом. Я в курсе, что в интернете очень много примеров рекурсии, мне нужен не результат поиска файлов, а понятие сути рекурсивного поиска.
p.p.s. вероятно, код кривой и унылый, но лучше сделать не получилось.


Код:
.386                      
.model flat, stdcall      
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\wininet.inc
include \masm32\macros\macros.asm
include \masm32\macros\windows.asm
uselib kernel32,masm32

findAll PROTO :dword

.data
fd WIN32_FIND_DATA <>
startDir db "F:\Demod",0;стартовая папка
mask0 db "*",0;маска поиска
buf1 db 256 dup(0)


.code
Start:
push offset startDir
call findAll

invoke ExitProcess,0

findAll PROC p1:dword
local buf[256]:byte;рабочий буфер
local directory[256]:byte;текущая директория
local hFindFile:dword
local directoryRes[256]:byte;резервный буфер

invoke lstrcpy,addr buf,p1;копируем то, на что указывает буфер (т.е. переданную директорию)
invoke lstrcpy,addr directory,addr buf;копируем это еще раз, для передачи в функцию
invoke lstrcpy,addr directoryRes,addr buf;и еще раз, для резерва
invoke lstrcat,addr buf,chr$("\");добавляем слеш
invoke lstrcat,addr buf,offset mask0;добавляем маску
invoke lstrlen,p1;вычисляем длину папки с маской
mov esi,eax
    add esi,sizeof mask0;добавляем длину маски
	mov byte ptr buf[esi],0;добавляем нуллбайт
invoke FindFirstFile,addr buf,offset fd
mov hFindFile,eax
invoke StdOut,addr buf
invoke StdOut,chr$(13,10)
.if eax==INVALID_HANDLE_VALUE; если ошибка
	print "some error with FindFirstFile";уведомляем и выходим
	ret
.endif

.REPEAT
.if fd.dwFileAttributes==FILE_ATTRIBUTE_DIRECTORY
	invoke lstrcmp,addr fd.cFileName,chr$(".")
  test eax,eax
  jz FNDNext
	invoke lstrcmp,addr fd.cFileName,chr$("..")
  test eax,eax
  jz FNDNext
;&& byte ptr[fd.cFileName]!="." && word ptr[fd.cFileName]!="..";если папка 

	invoke lstrcat,addr directory,chr$("\")
	invoke lstrcat,addr directory,offset fd.cFileName;добавляем к текущей папке имя найденной
	lea edx,directory
    push edx;передаем это все в рекурсию
	call findAll
.endif
FNDNext:;сюда переходим для поиска дальше
invoke FindNextFile,hFindFile,offset fd
cmp eax,0;файлы кончились, 
je ende1;идем на выход
invoke StdOut,offset fd.cFileName
invoke StdOut,chr$(13,10)

nvoke RtlZeroMemory,addr buf,sizeof buf;очищаем буфер
invoke lstrcpy,addr directory,addr directoryRes;восстановить из резервной копии
	

.UNTIL eax==0

ende1:
invoke FindClose,hFindFile
ret
findAll ENDP

end Start
 
Код:
cmp	byte ptr [fd.cFileName], '.'
jz	FNDNext

Добавлено в [time]1340036909[/time]
хватит и одной этой проверки. ".." тоже под нее попадает)
 
Код:
invoke FindFirstFile,addr buf,offset fd
mov hFindFile,eax
invoke StdOut,addr buf
invoke StdOut,chr$(13,10)
.if eax==INVALID_HANDLE_VALUE; если ошибка
print "some error with FindFirstFile";уведомляем и выходим
ret
.endif
ошибочная проверка eax, у тебя проверяется результат StdOut вместо FindFirstFile

вообще у тебя как-то неправильно код построен, вывод ".." происходит в этом месте
Код:
invoke FindNextFile,hFindFile,offset fd
cmp eax,0;файлы кончились,
je ende1;идем на выход
invoke StdOut,offset fd.cFileName
invoke StdOut,chr$(13,10)
т.к. тут нету проверки на ".." - сразу вывод в консольку.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Rev0Lt
Спасибо, но в таком случае не будут обрабатываться папки с точкой в имени, верно? Хоть их и мало, но все же.

accwranadm
т.к. тут нету проверки на ".." - сразу вывод в консольку
Да, действительно, что-то я не увидел. Спасибо, буду переделывать.
 
а вобще я бы советовал орентироваться на юникод. везде и всегда)

Добавлено в [time]1340042099[/time]
Спасибо, но в таком случае не будут обрабатываться папки с точкой в имени, верно? Хоть их и мало, но все же.
ну можно чекать следующие байты. всяко быстрее будет
 
юзай юникод и я бы советовал еще динамически выделять память под все пути и структуры в зависимости от их длины ( а не 256, т.к. давно уже пути вылезли за MAX_PATH ) т.к. на дирах с большим количеством вложенных сабдир стек ты забьешь очень быстро и получишь эксепшенс.

по поводу чека файлов на точки можно попробовать сравнивать с word '.\0' и dword '..\0\0' хотя под юникод придется немного переделать.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Честно говоря, с юникодом на WinApi никогда не работал, надо будет попробовать. Хотя в Масме с ним вроде непросто.
. давно уже пути вылезли за MAX_PATH
Но как такое может быть? Смотрю какую-то статью, в ней написано, что стандартные средства (типа проводника виндовс или даже тотал командера) не могут работать с директориями, которые выходят за MAX_PATH.
_http://cirux.ru/featured/windows-max_path-limitation-the-maximum-character-length-of-a-path/ Или автор ошибается?
динамически выделять память
Это как? Вызывать VirtualAlloc вначале функции, а при выходе с функции - VirtualFree?
 
Это как? Вызывать VirtualAlloc вначале функции, а при выходе с функции - VirtualFree?
Примерно так, только не VirtualAlloc т.к. ты попросишь у нее MAX_PATH, а она даст тебе *размер страницы*, обычно 4кб. Тут лучше использовать HeapAlloc/LocalAlloc.
 
Код:
.code
	AllocateHeap  proc arg_0:dword
  assume  fs:nothing
  mov  eax,fs:18h
    push  dword ptr[arg_0]
    	mov  eax,dword ptr[eax+30h]
    push  HEAP_ZERO_MEMORY
    push  dword ptr [eax+18h]
    call  RtlAllocateHeap	
  ret
	AllocateHeap  endp
	
	FreeHeap  proc arg_0:dword
  assume  fs:nothing   
  mov eax,fs:18h
  push  dword ptr[arg_0]
  	mov  eax,dword ptr[eax+30h]
  push  0
  push  dword ptr [eax+18h]
  call  RtlFreeHeap
  ret
	FreeHeap  endp
sizebuff equ 100500
start:
	push  sizebuff;необходимая длина
	call  AllocateHeap;выделяем место в куче
	push  eax  ;аргумент FreeHeap
  xchg edi,eax;edi - указатель на буфер в куче
;действия с выделенным буфером
	call  FreeHeap;освобождение выделенного буфера
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх