CopyFileФункция копирует файл в новое место. Код (C): CopyFile LPCTSTR lpExistingFileName, //Указатель на файл, который надо копировать LPCTSTR lpNewFileName, // Указатель на имя файла, куда надо копировать BOOL bFailIfExists // Что делать если файл уже существует Первый и второй параметр содержат полные имена к файлам. Третий параметр указывает, что нужно делать, если файл уже существует. Если он равен TRUE — произойдет ошибка, если FALSE — существующий файл будет перезаписан. Если всё нормально — функция вернет ненулевое значениеCreateDirectoryФункция создает новую директорию. Код (C): CreateDirectory LPCTSTR lpPathName, //Указатель на строку содержащую путь к новой директории LPSECURITY_ATTRIBUTES lpSecurityAttributes // Указатель на атрибуты Поле lpSecurityDescriptor структуры SECURITY_ATTRIBUTES задает дескриптор безопасности для нового каталога. Если lpSecurityAttributes имеет значение NULL, каталог получает дескриптор безопасности по умолчанию. Списки управления доступом в дескрипторе безопасности по умолчанию для каталога наследуются от его родительского каталога. Если всё нормально — функция вернет ненулевое значение CreateDirectoryExРасширенная функция для создания новой директории. При создании используется указанный шаблон. Код (C): CreateDirectoryEx LPCTSTR lpTemplateDirectory, /* Путь к каталогу, используемому в качестве шаблона при создании нового каталога */ LPCTSTR lpPathName, // Указатель на строку содержащую путь к новому каталогу LPSECURITY_ATTRIBUTES lpSecurityAttributes // Указатель на атрибуты Поле lpSecurityDescriptor структуры SECURITY_ATTRIBUTES задает дескриптор безопасности для нового каталога. Если lpSecurityAttributes имеет значение NULL, каталог получает дескриптор безопасности по умолчанию. Списки управления доступом (ACL) в дескрипторе безопасности по умолчанию для каталога наследуются от его родительского каталога. Целевая файловая система должна поддерживать безопасность файлов и каталогов, чтобы этот параметр действовал. Если всё нормально — функция вернет ненулевое значение. CreateFileФункция создаёт указатель на новое устройство типа: Файл Канал mailslot (почтовый канал) Коммуникационный ресурс (например, COM порт) Дисковые устройства Консоли Директории (открывает их) Функция умеет открывать и создавать новые файлы и устройства ввода/вывода, открывать существующие файлы или каталоги, а также обнулять длину существующего файла. Код (C): CreateFile LPCTSTR lpFileName, // Указатель на имя файла (устройства) DWORD dwDesiredAccess, //Параметры доступа DWORD dwShareMode, //Разделяемый доступ LPSECURITY_ATTRIBUTES lpSecurityAttributes, //безопасность DWORD dwCreationDistribution, // параметры создания DWORD dwFlagsAndAttributes, // Атрибуты файла HANDLE hTemplateFile // Файл шаблона Рассмотрим подробно все параметры: lpFileName — Указатель на строку содержащую имя создаваемого файла или устройства dwDesiredAccess— тип доступа. Принимает одно или сразу несколько значений: dwDesiredAccesshex000000000запрос. Функция не даст реального доступа к файлу, а выполнится как тест возможности создания или открытия файла (устройства).GENERIC_ALL10000000GENERIC_EXECUTE20000000GENERIC_WRITE40000000получить доступ к записиGENERIC_READ80000000получить доступ к чтению dwShareMode — флаги, указывающие на то, как создаваемый (открываемый) объект должен разделять доступ между процессами. Это значит, как будет делится доступ к файлу с другими программами если они тоже попытаются открыть этот файл. Параметр может принимать значения (можно использовать одно или сразу несколько): dwShareModehexbin00000Совместное использование файла запрещено. Запрещает другим процессам открывать файл или устройство, если они запрашивают доступ на удаление, чтение или запись.FILE_SHARE_READ1001другим процессам разрешается только читать файл. Другие приложения могут открывать файл с помощью функции CreateFile для чтенияFILE_SHARE_WRITE2010другим процессам разрешается только писать в файлFILE_SHARE_DELETE4100другим процессам разрешается доступ к файлу (устройству) только если требуется доступ на удаление. lpSecurityAttributes — указатель на структуру типа SECURITY_ATTRIBUTES. Через параметр lpSecurityAttributes необходимо передать указатель на дескриптор защиты или значение NULL, если этот дескриптор не используется Код (ASM): SECURITY_ATTRIBUTES struct nLength DWORD ? lpSecurityDescriptor DWORD ? bInheritHandle DWORD ? SECURITY_ATTRIBUTES ends dwCreationDistribution — описывает, что делать с файлом если он уже существует или его ещё нет. Параметр может принимать только одно из следующих значений (комбинация не допускается): dwCreationDistributionФайла с таким именем нетФайл с таким именем существуетCREATE_NEW1создается новый файлсообщение об ошибкеCREATE_ALWAYS2создается новый файлесли файл существует, то он будет перезаписан (обнулен)OPEN_EXISTING3сообщение об ошибкеоткрывается существующий файл (устройство)OPEN_ALWAYS4создается новый файлоткрывается существующий файл (устройство)TRUNCATE_EXISTING5сообщение об ошибкеоткрывается файл и его размер обрезается до нуля. Параметр dwDesiredAccess должен содержать GENERIC_WRITE dwFlagsAndAttributes — атрибуты создаваемого файла. Параметр может принимать комбинацию из значений: dwFlagsAndAttributeshexОписаниеFILE_ATTRIBUTE_READONLY1только для чтенияFILE_ATTRIBUTE_HIDDEN2Скрытый файлFILE_ATTRIBUTE_SYSTEM4Файл — часть операционной системыFILE_ATTRIBUTE_8FILE_ATTRIBUTE_DIRECTORY10С файлами с таким атрибутом операционная система обращается особым образом, считая его каталогом, т. е. рассматривает его как список файлов, состоящий из записей по 32 байта (длина файла кратна 32). Обычный файл стандартными методами не может быть преобразован в каталог, как и каталог не может быть преобразован к файлу. Для создания каталога используется функция CreateDirectoryFILE_ATTRIBUTE_ARCHIVE20Файл был архивирован (выгружен). Таким атрибутом отмечались файлы, над которыми не произведена операция BACKUP или XCOPY. Для целей программирования данный атрибут эквивалентен нулевому значению атрибутаFILE_ATTRIBUTE_DEVICE40Пока зарезервированFILE_ATTRIBUTE_NORMAL80Остальные перечисленные в этом списка атрибуты не установленыFILE_ATTRIBUTE_TEMPORARY100временный файл предназначен для временного хранения данных. После закрытия файла система должна его удалить. Система хранит большую часть такого файла в памятиFILE_ATTRIBUTE_SPARSE_FILE200Данный атрибут позволяет использовать так называемые распределенные (или разреженные) файлы. Логическая длина таких файлов может много превышать реально занимаемое дисковое пространствоFILE_ATTRIBUTE_REPARSE_POINT400Атрибут предполагается использовать для расширения функциональности файловой системы. Reparse points — так называемые точки повторной обработки, позволяющие осуществлять на базе файловой системы NTFS технологию иерархического хранения данных (Hierarchical Storage Management). Данная технология позволяет значительно расширить рамки дискового пространства за счет удаленных хранилищ, работа с которыми производится автоматическиFILE_ATTRIBUTE_COMPRESSED800Файл, имеющий этот атрибут, динамически сжимается при записи и восстанавливается при чтении. Если этот атрибут имеет каталог, то для всех расположенных в нем файлов и каталогов также выполняется динамическое сжатие данныхFILE_ATTRIBUTE_OFFLINE1000Данные файла не доступны в настоящий момент, возможно, находятся на устройстве, в этот момент отключенномFILE_ATTRIBUTE_NOT_CONTENT_INDEXED2000Файл не может быть проиндексирован службой индексации WindowsFILE_ATTRIBUTE_ENCRYPTED4000Зашифрованный файлFILE_ATTRIBUTE_8000FILE_ATTRIBUTE_VIRTUAL10000В дополнение к перечисленным выше атрибутам, через параметр dwFlagsAndAttributes можно передать любую логическую комбинацию флагов из перечисленных ниже dwFlagsAndAttributeshexОписаниеSECURITY_ANONYMOUS00000анонимный доступSECURITY_IDENTIFICATION10000идентификационный доступSECURITY_IMPERSONATION20000персональный доступSECURITY_DELEGATION30000коллективный доступSECURITY_CONTEXT_TRACKING40000динамический режим доступаSECURITY_EFFECTIVE_ONLY80000ограничение групп и привилегийSECURITY_SQOS_PRESENT100000SECURITY_VALID_SQOS_FLAGS1F0000FILE_FLAG_SESSION_AWARE800000Файл или устройство открывается с помощью осведомленности о сеансе. Если этот флаг не указан, то для каждого сеанса (например, устройства с использованием перенаправления USB RemoteFX) невозможно открыть процессами, выполняемыми в сеансе 0. Этот флаг не действует для вызывающих абонентов в сеансе 0.FILE_FLAG_POSIX_SEMANTICS1000000доступ осуществляется в POSIX стандарте. Доступ к файлу будет выполняться в соответствии со спецификацией POSIXFILE_FLAG_BACKUP_SEMANTICS2000000Backup файл, файл резервного копирования. Файл будет использован для выполнения операции выгрузки или восстановления. При этом выполняется проверка прав доступаFILE_FLAG_DELETE_ON_CLOSE4000000операционная система должна удалить файл, когда все указатели на файл будут закрыты. Файл будет удален сразу после того как приложение закроет его идентификатор. Этот флаг удобно использовать для временных файловFILE_FLAG_SEQUENTIAL_SCAN8000000доступ к файлу может быть последовательный от начала до конца. Указывает, что к файлу будет выполняться последовательный до-ступ от начала файла к его концу. Флаг предназначен для оптимизации кэшированияFILE_FLAG_RANDOM_ACCESS10000000случайный доступ. Используется для оптимизации кэша. Указывает, что к файлу будет выполняться произвольный доступ. Флаг предназначен для оптимизации кэшированияFILE_FLAG_NO_BUFFERING20000000нельзя использовать буферы или кэш. Отмена промежуточной буферизации или кэширования. При использовании этого флага необходимо выполнять чтение и запись порциями, кратными размеру сектора (обычно 512 байт)FILE_FLAG_OVERLAPPED40000000Выполнение чтения и записи асинхронно. Во время асинхронного чтения или записи приложение может продолжать обработку данныхFILE_FLAG_WRITE_THROUGH80000000возможность записи в файл через кэш. Отмена промежуточного кэширования данных для уменьшения вероятности потери данных при аварии hTemplateFile — файл шаблона. hTemplateFile предназначен для доступа к файлу шаблона с расширенными атрибутами для создаваемого файла Если функция выполнилась без проблем, то она возвращает указатель на открытое (созданное) устройства. Через этот указатель получают доступ к файлу. Если произошла ошибка — функция вернет INVALID_HANDLE_VALUE = -1DeleteFileФункция удаления существующего файла Код (C): DeleteFile LPCTSTR lpFileName // Указатель на имя файла, предназначенного для удаления Если всё нормально — функция вернет ненулевое значение (TRUE) RemoveDirectoryУдаляет существующий пустой каталог Код (C): RemoveDirectory LPCSTR lpPathName /* Путь к удаляемой папке. Этот путь должен указывать пустой каталог, вызывающий процесс должен иметь доступ к каталогу удаления */ Если функция выполняется успешно, возвращается ненулевое значение (TRUE) FindFirstFileФункция запускает поиск файла в указанной директории. Код (C): FindFirstFile LPCTSTR lpFileName, // Строка содержащая путь для поиска файлов. LPWIN32_FIND_DATA lpFindFileData // Информация о файле Рассмотрим оба параметра подробнее: lpFileName — указатель на строку содержащую путь для поиска файла Строка может указывать на конкретный файл типа "c:\filename.txt" или может хранить шаблон "c:\*.txt" Если указан шаблон, то это даёт возможность перечислить все файлы удовлетворяющие шаблону. lpFindFileData — указатель на структуру WIN32_FIND_DATA, в которую будет записана информация о найденном файле Рассмотрим структуру WIN32_FIND_DATA немного подробнее: Код (ASM): WIN32_FIND_DATA struct dwFileAttributes DWORD ?; Атрибуты файла ftCreationTime FILETIME <>; Время создания ftLastAccessTime <>; Время последнего доступа ftLastWriteTime <>; Время последней записи в файл nFileSizeHigh DWORD ?; Верхний байт размера файла nFileSizeLow DWORD ?; Нижний байт размера файла dwReserved0 DWORD ?; Зарезервировано dwReserved1 DWORD ?; Зарезервировано cFileName BYTE MAX_PATH dup(?); Имя файла cAlternateFileName BYTE 14 dup(?);Имя файла для отображения в DOS (8:3) WIN32_FIND_DATA ends Атрибутами файла может быть комбинация из флагов: FILE_ATTRIBUTE_READONLY = 1 — только для чтения FILE_ATTRIBUTE_HIDDEN = 2 — скрытый FILE_ATTRIBUTE_SYSTEM = 4 — системный FILE_ATTRIBUTE_ARCHIVE = 20h — архивный FILE_ATTRIBUTE_NORMAL = 80h — нормальный FILE_ATTRIBUTE_TEMPORARY = 100h — временный FILE_ATTRIBUTE_COMPRESSED = 800h — сжатый FILE_ATTRIBUTE_OFFLINE = 1000h — данные файла недоступны Размер файла разложен на две части. Чтоб получить полный размер файла нужно: (nFileSizeHigh shl 32) + nFileSizeLowФункция возвращает дескриптор поиска, используемый при последующем вызове FindNextFile или FindClose, а параметр lpFindFileData содержит сведения о первом найденном файле или каталоге. Если нет, то возвращаемое значение будет INVALID_HANDLE_VALUE а содержимое lpFindFileData не определено.FindNextFileФункция продолжает поиск, начатый с помощью FindFirstFile. Код (C): FindNextFile HANDLE hFindFile, /* Дескриптор поиска, возвращенный предыдущим вызовом функции FindFirstFile или FindFirstFileEx */ LPWIN32_FIND_DATAA lpFindFileData // Информация о файле Второй параметр такой же, как и у FindFirstFile. Первый параметр — указатель на файл из предыдущего поиска. Он нужен, чтобы функция FindNextFile знала на каком файле остановился поиск и какой надо найти следующим. Если всё нормально, то функция вернет параметр lpFindFileData, который содержит сведения о следующем найденном файле или каталоге. Если функция завершается сбоем, возвращаемое значение равно нулю, а содержимое lpFindFileData является неопределенным.FindCloseФункция закрывает дескриптор поиска файлов, открытый функцией FindFirstFile. Код (C): FindClose HANDLE hFindFile // дескриптор поиска файлов Если всё нормально, функция вернет ненулевое значение.GetCurrentDirectoryФункция позволяет узнать текущую директорию, с которой в данный момент работает программа. Код (C): GetCurrentDirectory DWORD nBufferLength, // Размер буфера, в котором будет храниться путь LPTSTR lpBuffer // Сам буфер Если произошла ошибка — функция вернет 0. Если всё нормально — программа вернет длину lpBuffer в котором хранится путь к текущей директории.SetCurrentDirectoryФункция SetCurrentDirectory устанавливает указанную директорию, как текущую. Код (C): SetCurrentDirectory LPCTSTR lpPathName /* Путь к новому текущему каталогу. Может указывать относительный или полный путь */ Если произошла ошибка — функция вернет 0. Если всё нормально, то она вернет не ноль.CloseHandleФункция CloseHandle позволяет закрыть дескриптор объекта. Единственный параметр — дескриптор открытого объекта. CloseHandle закрывает дескриптор для следующих объектов: Маркер доступа (Access token) Устройство связи (Communications device) Консольный ввод/вывод (Console input/output) Буфер экрана консоли (Console screen buffer) Событие (Event) Файл Отображение файла (File mapping) I/O completion port Задание (Job) Mailslot Уведомление о ресурсе памяти Мьютекс Именованный канал Канал (pipe) Процесс Семафор Нить (Thread) Транзакция Таймер для ожидания Если при создании или открытии функции CreateFile указали флаг FILE_FLAG_DELETE_ON_CLOSE, сразу после закрывания файл будет удален. Это удобно при работе с временными файлами
Открывает диалог для выбора файлов и дирректорий. SHGetPathFromIDList гораздо удобнее чем GetOpenFileName. Здесь не совсем ассемблер: Код (ASM): function OpenFile(Title: string): string; var lpItemID: PItemIDList; BrowseInfo: TBrowseInfo; DisplayName: array[0..2048] of Char; TempPath: array[0..2048] of Char; begin Result := ''; FillChar( BrowseInfo, SizeOf( TBrowseInfo ), #0 ); BrowseInfo.pszDisplayName := @DisplayName; BrowseInfo.lpszTitle := PChar( Title ); BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS or BIF_BROWSEINCLUDEFILES; lpItemID := SHBrowseForFolder( BrowseInfo ); if lpItemId <> nil then begin SHGetPathFromIDList( lpItemID, TempPath ); Result := TempPath; GlobalFreePtr( lpItemID ); end; end; //OpenFile Приблизительный перевод: Код (ASM): .386 .model flat, stdcall includelib kernel32.lib includelib shell32.lib .data BIF_RETURNONLYFSDIRS equ 00000001h BIF_BROWSEINCLUDEFILES equ 00110000h TBrowseInfo struct hwndOwner dd ? pIDLRoot dd ? pszDisplayName dd ? lpszTitle dd ? ulFlags dd ? lpfn dd ? lParam dd ? iImage dd ? TBrowseInfo ends PItemIDList typedef ptr TBrowseInfo DisplayName db 2049 dup(?) TempPath db 2049 dup(?) .code OpenFile proc Title:DWORD push ebp mov ebp, esp sub esp, sizeof TBrowseInfo ; Очистка структуры TBrowseInfo lea eax, [ebp - sizeof TBrowseInfo] xor ecx, ecx mov edx, sizeof TBrowseInfo rep stosb ; Заполнение структуры TBrowseInfo lea eax, [ebp - sizeof TBrowseInfo] mov dword ptr [eax + TBrowseInfo.pszDisplayName], offset DisplayName mov dword ptr [eax + TBrowseInfo.lpszTitle], Title mov dword ptr [eax + TBrowseInfo.ulFlags], BIF_RETURNONLYFSDIRS or BIF_BROWSEINCLUDEFILES ; Вызов функции SHBrowseForFolder push eax call SHBrowseForFolder add esp, 4 cmp eax, 0 je @done ; Вызов функции SHGetPathFromIDList push eax lea eax, [ebp - sizeof TBrowseInfo] push offset TempPath call SHGetPathFromIDList add esp, 12 ; Копирование результата в строку возврата lea eax, [ebp - sizeof TBrowseInfo] mov ecx, 2049 mov esi, offset TempPath mov edi, eax rep movsb ; Освобождение памяти push eax call GlobalFree add esp, 4 @done: leave ret OpenFile endp end
ReadFile и WriteFileС помощью функций ReadFile и WriteFile приложение может выполнять чтение из файла и запись в файл. Код (C): ReadFile HANDLE hFile, // дескриптор файла LPVOID lpBuffer, // адрес буфера для данных DWORD nNumberOfBytesToRead, // количество байт, которые необходимо прочесть в буфер LPDWORD lpNumberOfBytesRead, /* адрес слова, в которое будет записано количество прочитанных байт */ LPOVERLAPPED lpOverlapped // адрес структуры типа OVERLAPPED WriteFile HANDLE hFile, // идентификатор файла LPVOID lpBuffer, // адрес записываемого блока данных DWORD nNumberOfBytesToWrite, // количество байт, которые необходимо записать LPDWORD lpNumberOfBytesWrite, /* адрес слова, в котором будет сохранено количество записанных байт */ LPOVERLAPPED lpOverlapped // адрес структуры типа OVERLAPPED Через параметр hFile этим функциям необходимо передать дескриптор файла, полученный от функции CreateFile. Параметр lpBuffer содержит адрес буфера, в котором будут сохранены прочитанные данные или из которого будет выполняться запись данных. Параметр nNumberOfBytesToRead используется для функции ReadFile и задает количество байт данных, которые должны быть прочитаны в буфер lpBuffer. Параметр nNumberOfBytesToWrite задает функции WriteFile размер блока данных, имеющего адрес lpBuffer, который должен быть записан в файл. В процессе чтения возможно возникновение ошибки или достижение конца файла, количество прочитанных или записанный байт может отличаться от значений, заданных параметрами nNumberOfBytesToRead и nNumberOfBytesToWrite. Функции ReadFile и WriteFile записывают количество действительно прочитанных или записанных байт в двойное слово с адресом, соответственно, lpNumberOfBytesRead и lpNumberOfBytesWrite. Параметр lpOverlapped используется в функциях ReadFile и WriteFile для организации асинхронного режима чтения и записи. Если запись выполняется синхронно, в качестве этого параметра следует указать значение NULL. Для использования асинхронного режима файл должен быть открыт функцией CreateFile с использованием флага FILE_FLAG_OVERLAPPED. Если указан этот флаг, параметр lpOverlapped не может иметь значение NULL. Он обязательно должен содержать адрес подготовленной структуры типа OVERLAPPED. Если функции ReadFile и WriteFile были выполнены успешно, они возвращают ненулевое значение (TRUE). При возникновении ошибки возвращается значение FALSE. В последнем случае можно получить код ошибки, вызвав функцию GetLastError. В процессе чтения может быть достигнут конец файла. При этом количество действительно прочитанных байт (записывается по адресу lpNumberOfBytesRead) будет равно нулю. В случае достижения конца файла при чтении ошибка не возникает, поэтому функция ReadFile вернет значение TRUE.FlushFileBuffers Код (C): FlushFileBuffers HANDLE hFile // Дескриптор открытого файла Так как ввод и вывод данных на диск в Windows буферизуется, запись данных на диск может быть отложен до тех пор, пока система не освободится от выполнения текущей работы. С помощью функции FlushFileBuffers можно принудительно заставить операционную систему записать на диск все изменения для файла, дескриптор которого передается функции FlushFileBuffers через единственный параметр hFile. В случае успешного завершения функция возвращает не нулевое значение (TRUE), при ошибке — FALSE. Код ошибки можно получить при помощи функции GetLastError. При закрытии файла функцией CloseHandle содержимое всех буферов, связанных с этим файлом, записывается на диск автоматически. Используйте функцию FlushFileBuffers только в том случае, если запись содержимого буферов нужно выполнить до закрытия файла.SetFilePointerС помощью функции SetFilePointer приложение может выполнять прямой доступ к файлу, перемещая указатель текущей позиции, связанный с файлом. Сразу после открывания файла этот указатель устанавливается в начало файла. Затем он передвигается функциями ReadFile и WriteFile на количество прочитанных или записанных байт, соответственно. Функция SetFilePointer позволяет выполнить установку текущей позиции: Код (C): SetFilePointer HANDLE hFile // Дескриптор открытого файла LONG lDistanceToMove, /* количество байт, на которое будет передвинута текущая позиция */ PLONG lpDistanceToMoveHigh, /* адрес старшего слова, содержащего расстояние для перемещения позиции */ DWORD dwMoveMethod // способ перемещения позиции Через параметр hFile передают этой функции дескриптор файла, для которого выполняется изменение текущей позиции. Параметр lDistanceToMove, определяющий дистанцию, на которую будет передвинута текущая позиция, может принимать как положительные, так и отрицательные 32-разрядные значения. В первом случае текущая позиция переместится по направлению к концу файла, во втором - к началу файла. Если вы работаете с файлами, размер которых не превышает 232 байта (4,3 Гбайта), для параметра lpDistanceToMoveHigh можно указать значение NULL. В том случае, когда ваш файл очень большой (до 16 Тбайт), для указания смещения может потребоваться 64-разрядное значение. Для того чтобы указать очень большое смещение, вы должны записать старшую 32-разрядную часть этого 64-разрядного значения в переменную, передать функции SetFilePointer адрес этой переменной через параметр lpDistanceToMoveHigh. Младшую часть 64-разрядного смещения следует передавать, как и раньше, через параметр lDistanceToMove. Параметр dwMoveMethod определяет способ изменения текущей позиции и может принимать одно из перечисленных ниже значений: dwMoveMethodСмещение отсчитывается отСмещения трактуется какFILE_BEGIN0начала файлабеззнаковая величинаFILE_CURRENT1текущей позиции в файлекак положительные, так и отрицательные значенияFILE_END2конца файлакак отрицательная величина В случае успешного завершения функция SetFilePointer возвращает младшее слово новой 64-разрядной позиции в файле. Старшее слово при этом записывается по адресу, заданному параметром lpDistanceToMoveHigh. При ошибке функция возвращает значение -1 При этом в слово по адресу lpDistanceToMoveHigh записывается значение NULL. Код ошибки вы можете получить при помощи функции GetLastError. SetEndOfFileПри необходимости изменить длину файла (уменьшить или увеличить), вы можете воспользоваться функцией SetEndOfFile. Эта функция устанавливает новую длину файла в соответствии с текущей позицией: Код (C): SetEndOfFile HANDLE hFile // Дескриптор файла для расширения или усечения Для изменения длины файла вам достаточно установить текущую позицию в нужное место с помощью функции SetFilePointer, а затем вызвать функцию SetEndOfFile. LockFile и UnlockFileТак как операционная система Windows является мультизадачной и допускает одновременную работу многих процессов, возможно возникновение ситуаций, в которых несколько задач попытаются выполнять запись или чтение для одних и тех же файлов. Например, два процесса могут попытаться изменить одни и те же записи файла базы данных, при этом третий процесс будет в то же самое время выполнять выборку этой записи. Если функции CreateFile указать режимы совместного использования файла FILE_SHARE_READ или FILE_SHARE_WRITE, несколько процессов смогут одновременно открыть файлы и выполнять операции чтения и записи, соответственно. Если же эти режимы не указаны, совместное использование файлов будет невозможно. Первый же процесс, открывший файл, заблокирует возможность работы с этим файлом для других процессов. В ряде случаев необходимо обеспечить возможность одновременной работы нескольких процессов с одним и тем же файлом. В этом случае при необходимости процессы могут блокировать доступ к отдельным фрагментам файлов для других процессов. Например, процесс, изменяющий запись в базе данных, перед выполнением изменения может заблокировать участок файла, содержащий эту запись, и затем после выполнения записи разблокировать его. Другие процессы не смогут выполнить запись или чтение для заблокированных участков файла. Блокировка участка файла выполняется функцией LockFile: Код (C): LockFile HANDLE hFile, // Дескриптор файла DWORD dwFileOffsetLow, // младшее двойное слово смещения области DWORD dwFileOffsetHigh, // старшее двойное слово смещения области DWORD nNumberOfBytesToLockLow, // младшее двойное слово длины области DWORD nNumberOfBytesToLockHigh // старшее двойное слово длины области Параметр hFile задает дескриптор файла, для которого выполняется блокировка области. Смещение блокируемой области (64-разрядное) задается при помощи параметров dwFileOffsetLow (младшее двойное слово) и dwFileOffsetHigh (старшее двойное слово). Размер области в байтах задается параметрами nNumberOfBytesToLockLow (младшее двойное слово) и nNumberOfBytesToLockHigh (старшее двойное слово). Если в файле блокируется несколько областей, они не должны перекрывать друг друга. В случае успешного завершения функция LockFile возвращает значение TRUE, при ошибке — FALSE. Код ошибки получают при помощи функции GetLastError. После использования заблокированной области, а также перед завершением своей работы процессы должны разблокировать все заблокированные ранее области, вызвав для этого функцию UnlockFile: Код (C): UnlockFile HANDLE hFile, // дескриптор файла DWORD dwFileOffsetLow, // младшее слово смещения области DWORD dwFileOffsetHigh, // старшее слово смещения области DWORD nNumberOfBytesToUnlockLow, // младшее слово длины области DWORD nNumberOfBytesToUnlockHigh // старшее слово длины области В программном интерфейсе операционной системы Windows есть еще две функции, предназначенные для блокирования и разблокирования областей файлов. Это функции LockFileEx и UnlockFileEx. Главное отличие функции LockFileEx от функции LockFile заключается в том, что она может выполнять частичную блокировку файла, например, только блокировку от записи. В этом случае другие процессы могут выполнять чтение заблокированной областиGetFileSizeФункция возвращает размер указанного файла в байтах. Код (C): GetFileSize HANDLE hFile //Дескриптор файла LPDWORD lpFileSizeHigh/* Указатель на переменную, в которой возвращается двойное слово старшей части размера файла. Этот параметр может иметь значение NULL, если приложению не требуется двойное слово старшей части размера */ Если функция выполнена успешно, возвращаемое значение является двойным словом нижнего порядка размера файла, а если значение lpFileSizeHigh не равно NULL, функция помещает двойное слово высокого порядка размера файла в переменную, на которую указывает этот параметр. Если функция завершается сбоем и lpFileSizeHigh имеет значение NULL, возвращаемое значение будет INVALID_FILE_SIZE. Дополнительные сведения об ошибке можно получить, вызвав GetLastError. Если lpFileSizeHigh имеет значение NULL, результаты, возвращаемые для больших файлов, являются неоднозначными, и вы не сможете определить фактический размер файла. Вместо этого рекомендуется использовать GetFileSizeEx. Параметры: hFile — дескриптор файла, чей размер должен быть получен. Дескриптор должен быть создан с правом доступа GENERIC_READ или GENERIC_WRITE lpFileSizeHigh — указатель на переменную где старшее слово размер файла. Этот параметр может быть 0 если приложению не требуется старшее слово Возвращаемые значения: если функция добивается успеха, то возвращаемое значение — двойное слово с размером файла. Если lpFileSizeHigh равен NULL то функция устанавливает расширенное двойное слово в переменную указанную параметром с размером файла. Если функция терпит неудачу и lpFileSizeHigh равен NULL, то возвращаемое значение — INVALID_FILE_SIZE. Чтобы получить расширенную информацию об ошибке, вызовите функцию GetLastError. Если функция терпит неудачу и lpFileSizeHigh не 0 — возвращаемое значение — INVALID_FILE_SIZE и GetLastError возвращает код ошибки.GetFileSizeEx Код (C): GetFileSizeEx HANDLE hFile,/* Дескриптор файла. Дескриптор должен быть создан с правом доступа FILE_READ_ATTRIBUTES или эквивалентным, либо вызывающий объект должен иметь достаточные разрешения на каталог, содержащий файл */ PLARGE_INTEGER lpFileSize/* Указатель на структуру LARGE_INTEGER, которая получает размер файла в байтах */ Смену атрибута можно осуществить функцией SetFileAttributes, получить значение атрибута функцией GetFileAttributes. Значение атрибутов FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_DEVICE, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_ENCRYPTED, FILE_ATTRIBUTE_SPARSE_FILE, FILE_ATTRIBUTE_REPARSE_POINT можно установить только при помощи функции DeviceIoControlSetFileAttributesЗадает атрибуты для файла или каталога Код (C): SetFileAttributes LPCSTR lpFileName, //Имя файла, атрибуты которого необходимо задать DWORD dwFileAttributes //Атрибуты файла, которые необходимо задать для файла Если функция выполняется успешно, возвращается ненулевое значение. Атрибутами файла может быть комбинация из флагов dwFileAttributeshexFILE_ATTRIBUTE_READONLY1Файл, доступный только для чтения. Приложения могут читать файл, но не могут записывать в него или удалять его. Этот атрибут не учитывается в каталогах.FILE_ATTRIBUTE_HIDDEN2Файл или каталог скрыты. Он не включается в обычный список каталоговFILE_ATTRIBUTE_SYSTEM4Файл или каталог, часть или который используется исключительно операционной системой.8FILE_ATTRIBUTE_DIRECTORY10FILE_ATTRIBUTE_ARCHIVE20Файл или каталог, который является архивным файлом или каталогом. Приложения обычно используют этот атрибут для пометки файлов для резервного копирования или удаленияFILE_ATTRIBUTE_DEVICE40FILE_ATTRIBUTE_NORMAL80Файл, для которых не заданы другие атрибуты. Этот атрибут действителен только при использовании отдельно.FILE_ATTRIBUTE_TEMPORARY100Файл, используемый для временного хранения. Если доступно достаточно памяти кэша, файловые системы избегают записи данных обратно в хранилище, так как обычно приложение удаляет временный файл после закрытия дескриптора. В этом сценарии система может полностью избежать записи данных. В противном случае данные записываются после закрытия дескриптора.FILE_ATTRIBUTE_OFFLINE1000Данные файла доступны не сразу. Этот атрибут указывает, что данные файла физически перемещаются в автономное хранилище. Этот атрибут используется удаленным хранилищем, которое является программным обеспечением для управления иерархическим хранилищем. Приложения не должны произвольно изменять этот атрибут.FILE_ATTRIBUTE_NOT_CONTENT_INDEXED2000Файл или каталог не должны индексироваться службой индексирования содержимогоGetFileAttributesИзвлекает атрибуты файловой системы для указанного файла или каталога. Код (C): GetFileAttributes LPCSTR lpFileName//Имя файла или каталога Если функция выполняется успешно, возвращаемое значение содержит атрибуты указанного файла или каталога. Если функция завершается сбоем, возвращаемое значение INVALID_FILE_ATTRIBUTES = -1.
nFileSizeHigh Старшее двойное слово (DWORD) значения размера файла, в байтах. Это значение равняется нулю, если размер файла не больше, чем определяет его MAXDWORD. Размер файла равен (nFileSizeHigh * (MAXDWORD+1)) + (nFileSizeHigh nFileSizeLow Младшее двойное слово (DWORD) значения размера файла, в байтах. const MAXDWORD = DWord($FFFFFFFF); Размер файла равен (nFileSizeHigh << 32) + (nFileSizeHigh => 64 бита --- Сообщение объединено, 10 ноя 2024 в 19:02 --- Извините, ошибочка (nFileSizeHigh => nFileSizeHigh
SHFileOperationКопирует, перемещает, переименовывает или удаляет объект файловой системы Код (C): SHFileOperation LPSHFILEOPSTRUCTA lpFileOp /*Указатель на структуру SHFILEOPSTRUCT, содержащую сведения, необходимые этой функции для выполнения указанной операции. Этот параметр должен содержать допустимое значение, не равное NULL*/ Возвращает ноль (FALSE) в случае успешного выполнения; в противном случае ненулевое значение (TRUE) Код (ASM): SHFILEOPSTRUCTA struct hwnd dq ? wFunc dd ?,? pFrom dq ? pTo dq ? fFlags dw ?,? fAnyOperationsAborted dd ? hNameMappings dq ? lpszProgressTitle dq ? SHFILEOPSTRUCTA ends hwnd QWORD — Дескриптор окна в диалоговом окне для отображения сведений о состоянии операции файла wFunc DWORD — Значение, указывающее, какая операция выполняется pFrom QWORD — Указатель на одно или несколько исходных имен файлов. Эти имена должны быть полными путями, чтобы предотвратить непредвиденные результаты. Стандартные DOS подстановочные знаки, такие как "*", разрешены только в позиции имени файла. Использование подстановочного знака в другом месте строки приведет к непредсказуемым результатам. Хотя этот элемент объявлен как одна строка, завершающаяся значением NULL, фактически это буфер, который может содержать несколько имен файлов с разделителями NULL. Каждое имя файла завершается одним символом NULL. Последнее имя файла завершается двойным символом NULL ("\0\0") для указания конца буфера pTo QWORD — Указатель на целевой файл или имя каталога. Этот параметр должен иметь значение NULL, если он не используется. Подстановочные знаки не допускаются. Их использование приведет к непредсказуемым результатам. Как и pFrom, элемент pTo также является строкой с двойным значением NULL и обрабатывается точно так же fFlags WORD — Флаги, управляющие операцией файла fAnyOperationsAborted DWORD — Когда функция возвращается, этот элемент содержит TRUE, если все операции с файлами прерваны, прежде чем они были завершены в противном случае FALSE. Операция может быть прервана пользователем с помощью пользовательского интерфейса или она может быть прервана системой, если были заданы флаги FOF_NOERRORUI или FOF_NOCONFIRMATION hNameMappings QWORD — Когда функция возвращается, этот элемент содержит дескриптор объекта сопоставления имен, который содержит старые и новые имена переименованных файлов. Этот элемент используется только в том случае, если элемент fFlags включает флаг FOF_WANTMAPPINGHANDLE lpszProgressTitle QWORD — Указатель на заголовок диалогового окна хода выполнения. Это строка, завершающаяся значением NULL. Этот элемент используется только в том случае, если fFlags включает флаг FOF_SIMPLEPROGRESS Значение, указывающее, какая операция выполняется. Одно из следующих значений: wFuncЗначениеFO_MOVE1Перемещаются файлы, указанные в pFrom, в расположение, указанное в pToFO_COPY2Копируются файлы, указанные в элементе pFrom, в расположение, указанное в элементе pToFO_DELETE3Удаляются файлы, указанные в pFromFO_RENAME4Переименуются файл, указанный в pFrom. Флаг нельзя использовать для переименования нескольких файлов за один вызов функции. Вместо этого используйте FO_MOVEФлаги, управляющие операцией файла. Этот элемент может использовать сочетание следующих флагов. fFlagshexЗначениеFOF_MULTIDESTFILES1Элемент pTo указывает несколько целевых файлов (один для каждого исходного файла в pFrom), а не один каталог, в котором должны быть отложены все исходные файлыFOF_CONFIRMMOUSE2Не используетсяFOF_SILENT4Не отображать диалоговое окно хода выполненияFOF_RENAMEONCOLLISION8Присвоить файлу новое имя в операции перемещения, копирования или переименования, если файл с целевым именем уже существуетFOF_NOCONFIRMATION10Ответьте "Да" на все для любого отображаемого диалогового окнаFOF_WANTMAPPINGHANDLE20Если FOF_RENAMEONCOLLISION указан и все файлы были переименованы, назначьте объект сопоставления имен, содержащий старые и новые имена элементу hNameMappings. Этот объект должен быть освобожден с помощью SHFreeNameMappings, если он больше не нуженFOF_ALLOWUNDO40При возможности сохраните сведения об отмене. До Windows Vista операции можно отменить только из того же процесса, который выполнял исходную операцию. В Системах Windows Vista и более поздних версий область действия отмены — это сеанс пользователя. Любой процесс, выполняемый в сеансе пользователя, может отменить другую операцию. Состояние отмены хранится в процессе Explorer.exe и до тех пор, пока этот процесс выполняется, он может координировать функции отмены. Если параметр исходного файла не содержит полный путь и имена файлов, этот флаг игнорируется.FOF_FILESONLY80Выполните операцию только в файлах (а не в папках), если указано имя файла подстановочного знака (.)FOF_SIMPLEPROGRESS100Отображать диалоговое окно хода выполнения, но не отображает отдельные имена файлов, так как они работаютFOF_NOCONFIRMMKDIR200Не спрашивать у пользователя подтверждение о создании нового каталога, если операция требует созданияFOF_NOERRORUI400Не отображать диалоговое окно пользователю, если возникает ошибкаFOF_NO_UI614Выполнять операцию автоматически, не показывая пользовательский интерфейсFOF_NOCOPYSECURITYATTRIBS800Не копировать атрибуты безопасности файла. Целевой файл получает атрибуты безопасности новой папкиFOF_NORECURSION1000Выполнять операцию только в локальном каталоге. Не действовать рекурсивно в подкаталогах, что является поведением по умолчаниюFOF_NO_CONNECTED_ELEMENTS2000Не перемещайте подключенные файлы как группу. Перемещайте только указанные файлыFOF_WANTNUKEWARNING4000Отправьте предупреждение, если файл окончательно уничтожается во время операции удаления, а не перезапускается. Этот флаг частично переопределяет FOF_NOCONFIRMATIONFOF_NORECURSEREPARSE8000Не используетсяКоды ошибок, предшествующих Win32, больше не поддерживаются и не определяются в общедоступном файле заголовка. Необходимо определить их самостоятельно или сравнивать с возвращаемым числовым значением Код ошибкиhexЗначениеDE_SAMEFILE71Исходный и целевой файлы являются одинаковымиDE_MANYSRC1DEST72В исходном буфере было указано несколько путей к файлам, но только один путь к целевому файлу.DE_DIFFDIR73Операция переименования была указана, но конечный путь — это другой каталог. Вместо этого используйте операцию перемещенияDE_ROOTDIR74Источником является корневой каталог, который нельзя переместить или переименовать.DE_OPCANCELLED75Операция была отменена пользователем или автоматически отменена, если соответствующие флаги были предоставлены SHFileOperationDE_DESTSUBTREE76Назначение является поддеревом источникаDE_ACCESSDENIEDSRC78Параметры безопасности запрещают доступ к источникуDE_PATHTOODEEP79Исходный или целевой путь превысил или превысит MAX_PATHDE_MANYDEST7AОперация включала несколько конечных путей, что может завершиться ошибкой в случае операции перемещенияDE_INVALIDFILES7CНедопустимый путь в источнике или назначенииDE_DESTSAMETREE7DИсточник и назначение имеют одну и ту же родительскую папку.DE_FLDDESTISFILE7EКонечный путь — это существующий файлDE_FILEDESTISFLD80Конечный путь — это существующая папкаDE_FILENAMETOOLONG81Имя файла превышает MAX_PATHDE_DEST_IS_CDROM82Назначение — компакт-диск, доступный только для чтения, возможно, не отформатированDE_DEST_IS_DVD83Назначение — DVD-диск, доступный только для чтения, возможно, не отформатированDE_DEST_IS_CDRECORD84Место назначения — записываемый компакт-диск, возможно, неформатированныеDE_FILE_TOO_LARGE85Файл, участвующий в операции, слишком велик для целевого носителя или файловой системыDE_SRC_IS_CDROM86Источником является компакт-диск, доступный только для чтения, возможно, не отформатированDE_SRC_IS_DVD87Источником является DVD-диск, доступный только для чтения, возможно, не отформатированDE_SRC_IS_CDRECORD88Источником является записываемый компакт-диск, возможно, не форматируемыйDE_ERROR_MAXB7MAX_PATH превышено во время операции402Произошла неизвестная ошибка. Обычно это происходит из-за недопустимого пути в источнике или назначении. Эта ошибка не возникает в Windows Vista и более поздних версиях.ERRORONDEST10000В месте назначения произошла неуказанная ошибкаDE_ROOTDIR+ERRORONDEST10074Назначение является корневым каталогом и не может быть переименованоУдаление каталога через SHFileOperationУдаление каталога через оболочку Windows рекомендуется, если вы хотите удалить непустые каталоги или если вам нужна обратная связь в стиле проводника (например, диалоги хода выполнения с летающими файлами). Самый быстрый способ сделать это — создать SHFILEOPSTRUCT, инициализировать его и вызвать SHFileOperation, таким образом: Код (ASM): .data file_op SHFILEOPSTRUCT <NULL, FO_DELETE, dir, "", \ FOF_NOCONFIRMATION or FOF_NOERRORUI or FOF_SILENT, false, 0, ""> .code . . . invoke SHFileOperation,&file_op Файловые операции средствами SHFileOperationудаление файлов Код (Delphi): SetCurrentDirectory( PChar( 'C:\' ) ); From := 'Test1.tst' + #0 + 'Test2.tst' + #0 + #0; with SHFileOpStruct do begin Wnd := Handle; wFunc := FO_DELETE; pFrom := @From; pTo := nil; fFlags := 0; fAnyOperationsAborted := False; hNameMappings := nil; lpszProgressTitle := nil; end; SHFileOperation(SHFileOpStruct); ни один из флагов не установлен. Если вы хотите не просто удалить файлы, а переместить их в корзину, должен быть установлен флаг FOF_ALLOWUNDO функция, удаляющая файлы, переданные ей в списке Names. Параметр ToRecycle определяет, будут ли файлы перемещены в корзину или удалены. Функция возвращает 0, если операция выполнена успешно, и ненулевое значение, если руки у кого-то растут не из того места, и этот кто-то всунул функции имена несуществующих файлов. Код (Delphi): CreateBuffer( Names, Src ); with SHFileOpStruct do begin Wnd := Handle; wFunc := FO_DELETE; pFrom := Pointer( Src ); pTo := nil; fFlags := 0; if ToRecycle then fFlags := FOF_ALLOWUNDO; fAnyOperationsAborted := False; hNameMappings := nil; lpszProgressTitle := nil; end; SHFileOperation(SHFileOpStruct); Перемещаем файлы указанные в списке Src в директорию Dest. Параметр Move определяет, будут ли файлы перемещаться или копироваться. Параметр AutoRename указывает, переименовывать ли файлы в случае конфликта имен. Код (Delphi): with SHFileOpStruct do begin Wnd := Handle; wFunc := FO_COPY; if Move then wFunc := FO_MOVE; pFrom := Pointer( SrcBuf ); pTo := PChar( Dest ); fFlags := 0; if AutoRename then fFlags := FOF_RENAMEONCOLLISION; fAnyOperationsAborted := False; hNameMappings := nil; lpszProgressTitle := nil; end; SHFileOperation(SHFileOpStruct); переименование Код (Delphi): with SHFileOpStruct do begin Wnd := Handle; wFunc := FO_RENAME; pFrom := PChar( Src ); pTo := PChar( New ); fFlags := 0; if AutoRename then fFlags := FOF_RENAMEONCOLLISION; fAnyOperationsAborted := False; hNameMappings := nil; lpszProgressTitle := nil; end; SHFileOperation(SHFileOpStruct);
Помещаем файл в корзинуПо мотивам ManHunter'a Программное удаление файла в Корзину Код (ASM): ; GUI # include win64a.inc SHFILEOPSTRUCT struct hwnd dq ? wFunc dd ?,? pFrom dq ? pTo dq ? fFlags dw ?,? fAnyOperationsAborted dd ? hNameMappings dq ? lpszProgressTitle dq ? SHFILEOPSTRUCT ends FO_DELETE = 3 FOF_ALLOWUNDO = 40h FOF_NOCONFIRMATION = 10h FOF_SILENT = 4 .code WinMain proc local hFile:qword local bytecount:dword ; Создать тестовый файл mov qword ptr[rsp+30h],NULL mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE mov qword ptr[rsp+20h],CREATE_NEW invoke CreateFile,&fname,GENERIC_WRITE,NULL,NULL mov hFile,rax mov qword ptr[rsp+20h],NULL invoke WriteFile,hFile,&fdata,sizeof fdata,&bytecount invoke CloseHandle,hFile ; Удалить файл mov fos.hwnd,HWND_DESKTOP mov fos.wFunc,FO_DELETE movr fos.pFrom,fname mov fos.fFlags,FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT invoke SHFileOperation,&fos ;завершение программы invoke RtlExitUserProcess,0 WinMain endp .data fname db 'test3.txt',0,0 fdata db 'KittyKat' fos SHFILEOPSTRUCT <> end Продолжение следует...
Рекурсивный поиск: Код (Delphi): function PathAppend(path, str: string): string; begin if path[Length(path)] <> '\' then path := path + '\'; result := path + str; end; //PathAppend Код (Delphi): procedure ScanDirEx(s: string; var Files: TStrings); var Dir, FileName: string; SearchRec: TSearchRec; begin Dir := s; if Dir[length(Dir)] <> '\' then Dir := Dir + '\'; if FindFirst(PathAppend(Dir, '*.*'), faAnyFile, SearchRec) = 0 then repeat FileName := PathAppend(Dir, SearchRec.name); if (SearchRec.name = '.') or (SearchRec.name = '..') then Continue; if (SearchRec.Attr and faDirectory) <> 0 then begin Files.Add(FileName); ScanDirEx(FileName, Files); end else begin if FileExists(FileName) then begin Files.Add(FileName); end; end; until FindNext(SearchRec) <> 0; FindClose(SearchRec); end; //ScanDirEx Является ли файлом или директорией, 2 способа: Код (Delphi): function IsDir(s: string): Boolean; var searchResult: TSearchRec; begin FindFirst(s, faAnyFile, searchResult); Result := searchResult.Attr = faDirectory; FindClose(searchResult); end; //IsDir function IsDirEx(s: string): Boolean; var Code: Integer; begin Code := GetFileAttributes(PChar(s)); Result := Code and FILE_ATTRIBUTE_DIRECTORY <> 0; end; //IsDirEx Свободен ли файл: Код (Delphi): function IsFileInUse(const AFileName: string): Boolean; var HFileRes: THandle; begin HFileRes := CreateFile(PChar(AFileName), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); Result := (HFileRes = INVALID_HANDLE_VALUE); if not Result then CloseHandle(HFileRes); end; //IsFileInUse Еще часто приходится использовать: ExtractFilePath, ExtractFileName, ExtractFileExt
Ничего не имею против этого кода и он даже в Lazarus реализован кроссплатформенно. Но вот антивирусы на именно эту процедуру почему то будут реагировать как на малварь. Хотя передавать столько лишних параметров в рекурсии не стоит т.к. не известна глубина каталогов. Лучше добавить туда еще директиву register. А вот на вариант этой же процедуры через FindFirstFile/FindNextFile/CloseHandle - не реагируют
Код (Delphi): function StrRScan(const Str: PChar; Chr: Char): PChar; assembler; asm PUSH EDI MOV EDI,Str MOV ECX,0FFFFFFFFH XOR AL,AL REPNE SCASB NOT ECX STD DEC EDI MOV AL,Chr REPNE SCASB MOV EAX,0 JNE @@1 MOV EAX,EDI INC EAX @@1: CLD POP EDI end; function GoDelimiterLast(Str: PChar; Delimiters: PChar): PChar; var P, F : PChar; begin P := Str; Result := P + StrLen(Str); while Delimiters^ <> #0 do begin F := StrRScan(P, Delimiters^); if F <> nil then if (Result^ = #0) or (Integer(F) > Integer(Result)) then Result := F; Inc(Delimiters); end; end; function ExtractFileExt(const Path : String) : String; var P: PChar; begin P := GoDelimiterLast(PChar(Path), '.'); Result := P; end; function ExtractFileName(const Path : String) : String; var P: PChar; begin P := GoDelimiterLast(PChar(Path), ':\'); if P^ = #0 then Result := Path else Result := P + 1; end; function Copy(Dest, Source: PChar; MaxLen: Cardinal): PChar; assembler; asm PUSH EDI PUSH ESI PUSH EBX MOV ESI,EAX MOV EDI,EDX MOV EBX,ECX XOR AL,AL TEST ECX,ECX JZ @@1 REPNE SCASB JNE @@1 INC ECX @@1: SUB EBX,ECX MOV EDI,ESI MOV ESI,EDX MOV EDX,EDI MOV ECX,EBX SHR ECX,2 REP MOVSD MOV ECX,EBX AND ECX,3 REP MOVSB STOSB MOV EAX,EDX POP EBX POP ESI POP EDI end; function ExtractFilePath(const Path : String) : String; var P, P0: PChar; begin P0 := PChar(Path); P := GoDelimiterLast(P0, ':\'); if P^ = #0 then Result := '' else Result := Copy(Path, 1, P - P0 + 1); end;
Так вы каждый вызов будете класть в стек дополнительно два параметра (на х86). А вот под Linux на её фс еще и кольцевые ссылки надо обрабатывать (как я и сказал этот код может работать кроссплатформенно).
Код (Delphi): function IsFileExists(const filename: string): Boolean; var fileAttr: DWORD; begin fileAttr := GetFileAttributes(PChar(filename)); Result := fileAttr <> INVALID_FILE_ATTRIBUTES; end;
Нужны дополнительны проверки, как тут. Открывать файл не желательно, да и доступ к нему может быть расшарен.
Ahimov, так напиши на нэйтиве со всеми проверками, в чем проблема? Рекурсивный поиск тоже переведи, чтобы быстрее все было