Недавно наткнулся на один старый исходник под dos для поиска файлов. Код (Text): const faReadOnly = $01; faHidden = $02; faSystem = $04; faVolumeID = $08; faDirectory = $10; faArchive = $20; faAnyFile = $3F; type PSearchRec = ^TSearchRec; TSearchRec = record Drive : Char; Name8 : array[1..8] of Char; Ext3 : array[1..3] of Char; SearchAttr : Byte; Num : Word; Cluster : Word; Unused : array[1..4] of byte; Attr : Byte; Time : Word; Date : Word; Size : Longint; Name : array[1..12] of Char; end; procedure FindFirst(Dta: PSearchRec; Attr: Byte; Files: PChar); assembler; asm PUSH DS MOV AH, 2FH INT 21H PUSH ES PUSH BX MOV AH, 1AH LDS DX, Dta INT 21H MOV AH, 4EH LDS DX, Files XOR CH, CH MOV CL, Attr INT 21H MOV AH, 1AH POP DX POP DS INT 21H POP DS end; procedure FindNext(Dta : PSearchRec); assembler; asm PUSH DS MOV AH, 2FH INT 21H PUSH ES PUSH BX MOV AH, 1AH LDS DX, Dta INT 21H MOV AH, 4FH INT 21H MOV AH, 1AH POP DX POP DS INT 21H POP DS end; Существует ли подобное решение под windows, _без_ использования FindFirstFile/FindNextFile?
Всмысле есть ли на Windows DOS API? Нет, нету. Для DOS int 21h + ah=3Fh это и есть FindFirst. Причём есть еще ah=11h - старый стиль DOS 1.0 через FCB.
Смотря что считать подобным. Через прерывания нельзя, но место прерываний заняли системные вызовы - sysenter на x32 и syscall на x64, которые работают по похожему принципу: кладём номер обработчика в регистр и вызываем sysenter/syscall. На современных системах примерно то же самое можно сделать через прямой сисколл NtQueryDirectoryFile (только надо помнить, что номера сисколлов могут меняться с любым обновлением системы). Типа такого: Код (ASM): mov rcx, hDirectory mov rdx, 0 ; Event mov r8, 0 ; ApcRoutine ... ; Другие аргументы в r9 и через стек mov r10, rcx mov eax, 0x35 ; Номер NtQueryDirectoryFile в таблице системных вызовов на Win11 10.0.22000 syscall ; Уходим в ядро ret На процессорах, где инструкция syscall не поддерживается, можно ходить в ядро через int 2Eh.
Значит это сложнее чем я думал. Будем юзать старую добрую FindFirstFile. Спасибо за ответ --- Сообщение объединено, 30 ноя 2023 --- Что-то типа такого: Код (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 Слишком много полей, и непонятки с Unicode. Зато быстрее на 30%-40% --- Сообщение объединено, 30 ноя 2023 --- Пацан к успеху шел, не получилось, не фортануло
Я не в курсе ложь это или нет, это инфа с интернета на которую наткнулся, когда гуглил за ZwQueryDirectoryFile