Вот более и менее оптимизированный вариант: Код (Text): .data szSlesh db "\",0,0,0 szLink db "\??\C:\",0 .code align 4 ZwSearch proc uses esi lpPath:dword,lpPathLen:dword local hFind:HANDLE local iosb:IO_STATUS_BLOCK invoke ZwOpenFile,addr hFind,100001h,lpPath,addr iosb,7,21h .if eax == 0 && iosb.Information == 1 invoke GlobalAlloc,40h,260 mov esi,eax lea ecx,iosb xor eax,eax invoke ZwQueryDirectoryFile,hFind,eax,eax,eax,ecx,esi,260,1,1,eax,1 .while eax != 80000006h or eax,eax jnz @F lea eax,[esi+040h] ;FileName mov ecx,dword ptr [esi+03Ch] ;FileNameLength mov byte ptr [eax+ecx],0 cmp word ptr [eax],'.' jz s_next cmp word ptr [eax+2],'.' jz s_next mov ebx,lpPath mov ebx,dword ptr [ebx+000000008h] ;ObjectName mov edi,dword ptr [ebx+4] ;Buffer mov ecx,lpPathLen mov byte ptr [edi+ecx],0 add edi,ecx push esi push ecx lea esi,[esi+040h] rep movsb pop ecx pop esi test dword ptr [esi+38h],10h ;FileAttributes jz s_file add ecx,dword ptr [esi+03Ch] ;FileNameLength mov edi,dword ptr [ebx+4] ;Buffer add edi,ecx push esi push ecx mov esi,offset szSlesh rep movsb pop ecx pop esi add ecx,2 mov word ptr [ebx],cx ;Length pusha lea eax,[esi+040h] ;FileName invoke MessageBoxW,0,eax,dword ptr [ebx+4],0 popa invoke ZwSearch,lpPath,ecx jmp s_next s_file: pusha lea eax,[esi+040h] ;FileName invoke MessageBoxW,0,eax,dword ptr [ebx+4],0 popa s_next: lea ecx,iosb xor eax,eax invoke ZwQueryDirectoryFile,hFind,eax,eax,eax,ecx,esi,260,1,1,eax,eax .endw @@: invoke GlobalFree,esi invoke ZwClose,hFind .endif ret ZwSearch endp start proc local as:ANSI_STRING local us:UNICODE_STRING local oa:OBJECT_ATTRIBUTES invoke lstrlen,offset szLink mov as._Length,ax mov as.MaximumLength,ax mov eax,offset szLink mov as.Buffer,eax invoke RtlAnsiStringToUnicodeString,addr us,addr as,1 invoke RtlInitUnicodeString,addr us,us.Buffer xor eax,eax lea ecx,oa mov dword ptr [ecx],000000018h and dword ptr [ecx+000000004h],eax mov dword ptr [ecx+00000000Ch],00000240h and dword ptr [ecx+000000010h],eax lea ebx,us mov dword ptr [ecx+000000008h],ebx and dword ptr [ecx+000000014h],eax movzx ecx,us._Length invoke ZwSearch,addr oa,ecx invoke ExitProcess,0 start endp
когдато писал функцию удаления директории и ничего не стоит переписать этот код под поиск файлов (тут правда на делфях, но смысл понять думаю можно) Код (Text): function DeleteDirectory(DirName: PUNICODE_STRING): NTSTATUS; var Status: NTSTATUS; DirFile: HANDLE; Size: ULONG; ObjAttr: OBJECT_ATTRIBUTES; IoStatus: IO_STATUS_BLOCK; FileName: UNICODE_STRING; Buf: PWCHAR; FileDirInfo: PFILE_DIRECTORY_INFORMATION; begin InitializeObjectAttributes (@ObjAttr, DirName, OBJ_CASE_INSENSITIVE, 0, nil); Status := NtCreateFile(@DirFile, FILE_LIST_DIRECTORY, @ObjAttr, @IoStatus, nil, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_DELETE + FILE_SHARE_WRITE + FILE_SHARE_READ, FILE_OPEN, FILE_DIRECTORY_FILE, nil, 0); if Status = STATUS_SUCCESS then begin Size := SizeOf(FILE_DIRECTORY_INFORMATION) + 256; FileDirInfo := VirtualAlloc(nil, Size, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); Status := NtQueryDirectoryFile(DirFile, 0, nil, nil, @IoStatus, FileDirInfo, Size, FileDirectoryInformation, true, nil, true); while Status <> STATUS_NO_MORE_FILES do begin if not cmpwclen(FileDirInfo^.FileName, '.', FileDirInfo^.FileNameLength) then if not cmpwclen(FileDirInfo^.FileName, '..', FileDirInfo^.FileNameLength) then begin Buf := VirtualAlloc(nil, DirName^.Length + FileDirInfo^.FileNameLength + 2, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); CopyMemory(Buf, DirName^.Buffer, DirName^.Length); PWCHAR(ULONG(Buf) + DirName^.Length)^ := '\'; CopyMemory(PVOID(ULONG(Buf) + 2 + DirName^.Length), @FileDirInfo^.FileName, FileDirInfo^.FileNameLength); RtlInitUnicodeString(@FileName, Buf); if (FileDirInfo^.FileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0 then DeleteDirectory(@FileName) else DeleteFile(@FileName, FILE_NON_DIRECTORY_FILE); VirtualFree(Buf, 0, MEM_RELEASE) end; VirtualFree(FileDirInfo, 0, MEM_RELEASE); FileDirInfo := VirtualAlloc(nil, Size, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE); Status := NtQueryDirectoryFile(DirFile, 0, nil, nil, @IoStatus, FileDirInfo, Size, FileDirectoryInformation, true, nil, false) end; VirtualFree(FileDirInfo, 0, MEM_RELEASE); NtClose(DirFile); Status := DeleteFile(DirName, FILE_DIRECTORY_FILE) end; Result := Status end;
Куда тебе на натив с последним вопросом, ты с разделом попутал -> Beginners, вначале с Win32 разберись.
функция сравнения строк, например такая: Код (Text): function cmpwclen(Str1: PWideChar; Str2: PWideChar; Len: integer): boolean; var i:integer; begin Result := true; for i:=0 to (len div 2)-1 do if str1[i]<>str2[i] then Result := false end; зы: можно и другие использовать
Использую код товарища Flasher'а, но есть проблема: вроде как работает рекурсивно и должно искать во всех подпапках - ан нет, в некоторых ищет, а в некоторых нет. Как будто это зависит от фазы луны. Как я понял - иногда вылетает ZwOpenFile c кодом ошибки С0000033h. Код: Код (Text): .386 .model flat, stdcall option casemap: none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\masm32.inc include \masm32\include\user32.inc includelib \masm32\lib\masm32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\user32.lib includelib \masm32\lib\w2k\ntdll.lib IO_STATUS_BLOCK STRUCT ; sizeof = 08h Status SDWORD ? ; 0000h NTSTATUS Information DWORD ? ; 0004h IO_STATUS_BLOCK ENDS UNICODE_STRING STRUCT _Length WORD ? ; len of string in bytes (not chars) MaximumLength WORD ? ; len of Buffer in bytes (not chars) Buffer PWSTR ? ; pointer to string UNICODE_STRING ENDS _STRING STRUCT _Length WORD ? MaximumLength WORD ? Buffer DWORD ? ; PCHAR _STRING ENDS ANSI_STRING equ <_STRING> PUNICODE_STRING typedef PTR UNICODE_STRING OBJECT_ATTRIBUTES STRUCT ; sizeof = 18h _Length DWORD ? ; original name Length RootDirectory HANDLE ? ObjectName PUNICODE_STRING ? Attributes DWORD ? SecurityDescriptor PVOID ? ; Points to type SECURITY_DESCRIPTOR SecurityQualityOfService PVOID ? ; Points to type SECURITY_QUALITY_OF_SERVICE OBJECT_ATTRIBUTES ENDS ZwOpenFile proto stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD ZwQueryDirectoryFile proto stdcall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD ZwClose proto stdcall :DWORD RtlAnsiStringToUnicodeString proto stdcall :DWORD, :DWORD, :DWORD RtlInitUnicodeString proto stdcall :DWORD, :DWORD .data szSlesh db "\",0,0,0 szLink db "\??\G:\",0 COUNTER dd 0 .code align 4 ZwSearch proc uses esi lpPath:dword,lpPathLen:dword local hFind:HANDLE local iosb:IO_STATUS_BLOCK invoke ZwOpenFile,addr hFind,100001h,lpPath,addr iosb,7,21h .if eax == 0 && iosb.Information == 1 invoke GlobalAlloc,40h,260 mov esi,eax lea ecx,iosb xor eax,eax invoke ZwQueryDirectoryFile,hFind,eax,eax,eax,ecx,esi,260,1,1,eax,1 .while eax != 80000006h or eax,eax jnz @F lea eax,[esi+040h] ;FileName mov ecx,dword ptr [esi+03Ch] ;FileNameLength mov byte ptr [eax+ecx],0 cmp word ptr [eax],'.' jz s_next cmp word ptr [eax+2],'.' jz s_next mov ebx,lpPath mov ebx,dword ptr [ebx+000000008h] ;ObjectName mov edi,dword ptr [ebx+4] ;Buffer mov ecx,lpPathLen mov byte ptr [edi+ecx],0 add edi,ecx push esi push ecx lea esi,[esi+040h] rep movsb pop ecx pop esi test dword ptr [esi+38h],10h ;FileAttributes jz s_file add ecx,dword ptr [esi+03Ch] ;FileNameLength mov edi,dword ptr [ebx+4] ;Buffer add edi,ecx push esi push ecx mov esi,offset szSlesh rep movsb pop ecx pop esi add ecx,2 mov word ptr [ebx],cx ;Length ; Это ПАПКА ;pusha ;lea eax,[esi+040h] ;FileName ;invoke MessageBoxW,0,eax,dword ptr [ebx+4],0 ;popa invoke ZwSearch,lpPath,ecx jmp s_next s_file: ; ЭТО ФАЙЛ ;pusha ;lea eax,[esi+040h] ;FileName ;invoke MessageBoxW,0,eax,dword ptr [ebx+4],0 ;popa inc dword ptr [COUNTER] s_next: lea ecx,iosb xor eax,eax invoke ZwQueryDirectoryFile,hFind,eax,eax,eax,ecx,esi,260,1,1,eax,eax .endw @@: invoke GlobalFree,esi invoke ZwClose,hFind .endif ret ZwSearch endp StartSearch proc local as:ANSI_STRING local us:UNICODE_STRING local oa:OBJECT_ATTRIBUTES invoke lstrlen,offset szLink mov as._Length,ax mov as.MaximumLength,ax mov eax,offset szLink mov as.Buffer,eax invoke RtlAnsiStringToUnicodeString,addr us,addr as,1 invoke RtlInitUnicodeString,addr us,us.Buffer xor eax,eax lea ecx,oa mov dword ptr [ecx],000000018h and dword ptr [ecx+000000004h],eax mov dword ptr [ecx+00000000Ch],00000240h and dword ptr [ecx+000000010h],eax lea ebx,us mov dword ptr [ecx+000000008h],ebx and dword ptr [ecx+000000014h],eax movzx ecx,us._Length invoke ZwSearch,addr oa,ecx ret StartSearch endp start: call StartSearch invoke ExitProcess,0 end start