WinAPI для работы с файлами

Тема в разделе "WASM.ARTICLES", создана пользователем Mikl___, 9 ноя 2024 в 05:00.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792

    CopyFile

    Функция копирует файл в новое место.
    Код (C):
    1. CopyFile
    2.     LPCTSTR lpExistingFileName, //Указатель на файл, который надо копировать
    3.     LPCTSTR lpNewFileName, // Указатель на имя файла, куда надо копировать
    4.     BOOL bFailIfExists // Что делать если файл уже существует
    Первый и второй параметр содержат полные имена к файлам.
    Третий параметр указывает, что нужно делать, если файл уже существует. Если он равен TRUE — произойдет ошибка, если FALSE — существующий файл будет перезаписан. Если всё нормально — функция вернет ненулевое значение

    CreateDirectory

    Функция создает новую директорию.
    Код (C):
    1. CreateDirectory
    2.     LPCTSTR lpPathName, //Указатель на строку содержащую путь к новой директории
    3.     LPSECURITY_ATTRIBUTES lpSecurityAttributes // Указатель на атрибуты
    Поле lpSecurityDescriptor структуры SECURITY_ATTRIBUTES задает дескриптор безопасности для нового каталога. Если lpSecurityAttributes имеет значение NULL, каталог получает дескриптор безопасности по умолчанию. Списки управления доступом в дескрипторе безопасности по умолчанию для каталога наследуются от его родительского каталога.
    Если всё нормально — функция вернет ненулевое значение

    CreateDirectoryEx

    Расширенная функция для создания новой директории. При создании используется указанный шаблон.
    Код (C):
    1. CreateDirectoryEx
    2.     LPCTSTR lpTemplateDirectory, /* Путь к каталогу, используемому в качестве шаблона
    3. при создании нового каталога */
    4.     LPCTSTR lpPathName, // Указатель на строку содержащую путь к новому каталогу
    5.     LPSECURITY_ATTRIBUTES lpSecurityAttributes // Указатель на атрибуты
    Поле lpSecurityDescriptor структуры SECURITY_ATTRIBUTES задает дескриптор безопасности для нового каталога. Если lpSecurityAttributes имеет значение NULL, каталог получает дескриптор безопасности по умолчанию. Списки управления доступом (ACL) в дескрипторе безопасности по умолчанию для каталога наследуются от его родительского каталога. Целевая файловая система должна поддерживать безопасность файлов и каталогов, чтобы этот параметр действовал.
    Если всё нормально — функция вернет ненулевое значение.

    CreateFile

    Функция создаёт указатель на новое устройство типа:
    • Файл
    • Канал
    • mailslot (почтовый канал)
    • Коммуникационный ресурс (например, COM порт)
    • Дисковые устройства
    • Консоли
    • Директории (открывает их)
    Функция умеет открывать и создавать новые файлы и устройства ввода/вывода, открывать существующие файлы или каталоги, а также обнулять длину существующего файла.
    Код (C):
    1. CreateFile
    2.     LPCTSTR lpFileName, // Указатель на имя файла (устройства)
    3.     DWORD dwDesiredAccess, //Параметры доступа
    4.     DWORD dwShareMode, //Разделяемый доступ
    5.     LPSECURITY_ATTRIBUTES lpSecurityAttributes, //безопасность
    6.     DWORD dwCreationDistribution, // параметры создания
    7.     DWORD dwFlagsAndAttributes, // Атрибуты файла
    8.     HANDLE hTemplateFile // Файл шаблона
    Рассмотрим подробно все параметры:
    • lpFileName — Указатель на строку содержащую имя создаваемого файла или устройства
    • dwDesiredAccess— тип доступа. Принимает одно или сразу несколько значений:
      dwDesiredAccesshex
      0
      00000000​
      запрос. Функция не даст реального доступа к файлу, а выполнится как тест возможности создания или открытия файла (устройства).
      GENERIC_ALL
      10000000​
      GENERIC_EXECUTE
      20000000​
      GENERIC_WRITE
      40000000​
      получить доступ к записи
      GENERIC_READ
      80000000​
      получить доступ к чтению
    • dwShareMode — флаги, указывающие на то, как создаваемый (открываемый) объект должен разделять доступ между процессами. Это значит, как будет делится доступ к файлу с другими программами если они тоже попытаются открыть этот файл. Параметр может принимать значения (можно использовать одно или сразу несколько):
      dwShareModehexbin
      0
      0​
      000Совместное использование файла запрещено. Запрещает другим процессам открывать файл или устройство, если они запрашивают доступ на удаление, чтение или запись.
      FILE_SHARE_READ
      1​
      001другим процессам разрешается только читать файл. Другие приложения могут открывать файл с помощью функции CreateFile для чтения
      FILE_SHARE_WRITE
      2​
      010другим процессам разрешается только писать в файл
      FILE_SHARE_DELETE
      4​
      100другим процессам разрешается доступ к файлу (устройству) только если требуется доступ на удаление.
    • lpSecurityAttributes — указатель на структуру типа SECURITY_ATTRIBUTES. Через параметр lpSecurityAttributes необходимо передать указатель на дескриптор защиты или значение NULL, если этот дескриптор не используется
      Код (ASM):
      1. SECURITY_ATTRIBUTES struct
      2.     nLength              DWORD ?
      3.     lpSecurityDescriptor DWORD ?
      4.     bInheritHandle       DWORD ?
      5. SECURITY_ATTRIBUTES ends
    • dwCreationDistribution — описывает, что делать с файлом если он уже существует или его ещё нет. Параметр может принимать только одно из следующих значений (комбинация не допускается):
      dwCreationDistributionФайла с таким именем нетФайл с таким именем существует
      CREATE_NEW1создается новый файлсообщение об ошибке
      CREATE_ALWAYS2создается новый файлесли файл существует, то он будет перезаписан (обнулен)
      OPEN_EXISTING3сообщение об ошибкеоткрывается существующий файл (устройство)
      OPEN_ALWAYS4создается новый файлоткрывается существующий файл (устройство)
      TRUNCATE_EXISTING5сообщение об ошибкеоткрывается файл и его размер обрезается до нуля. Параметр dwDesiredAccess должен содержать GENERIC_WRITE
    • dwFlagsAndAttributes — атрибуты создаваемого файла. Параметр может принимать комбинацию из значений:
      dwFlagsAndAttributeshexОписание
      FILE_ATTRIBUTE_READONLY
      1​
      только для чтения
      FILE_ATTRIBUTE_HIDDEN
      2​
      Скрытый файл
      FILE_ATTRIBUTE_SYSTEM
      4​
      Файл — часть операционной системы
      FILE_ATTRIBUTE_
      8​
      FILE_ATTRIBUTE_DIRECTORY
      10​
      С файлами с таким атрибутом операционная система обращается особым образом, считая его каталогом, т. е. рассматривает его как список файлов, состоящий из записей по 32 байта (длина файла кратна 32). Обычный файл стандартными методами не может быть преобразован в каталог, как и каталог не может быть преобразован к файлу. Для создания каталога используется функция CreateDirectory
      FILE_ATTRIBUTE_ARCHIVE
      20​
      Файл был архивирован (выгружен). Таким атрибутом отмечались файлы, над которыми не произведена операция BACKUP или XCOPY. Для целей программирования данный атрибут эквивалентен нулевому значению атрибута
      FILE_ATTRIBUTE_DEVICE
      40​
      Пока зарезервирован
      FILE_ATTRIBUTE_NORMAL
      80​
      Остальные перечисленные в этом списка атрибуты не установлены
      FILE_ATTRIBUTE_TEMPORARY
      100​
      временный файл предназначен для временного хранения данных. После закрытия файла система должна его удалить. Система хранит большую часть такого файла в памяти
      FILE_ATTRIBUTE_SPARSE_FILE
      200​
      Данный атрибут позволяет использовать так называемые распределенные (или разреженные) файлы. Логическая длина таких файлов может много превышать реально занимаемое дисковое пространство
      FILE_ATTRIBUTE_REPARSE_POINT
      400​
      Атрибут предполагается использовать для расширения функциональности файловой системы. Reparse points — так называемые точки повторной обработки, позволяющие осуществлять на базе файловой системы NTFS технологию иерархического хранения данных (Hierarchical Storage Management). Данная технология позволяет значительно расширить рамки дискового пространства за счет удаленных хранилищ, работа с которыми производится автоматически
      FILE_ATTRIBUTE_COMPRESSED
      800​
      Файл, имеющий этот атрибут, динамически сжимается при записи и восстанавливается при чтении. Если этот атрибут имеет каталог, то для всех расположенных в нем файлов и каталогов также выполняется динамическое сжатие данных
      FILE_ATTRIBUTE_OFFLINE
      1000​
      Данные файла не доступны в настоящий момент, возможно, находятся на устройстве, в этот момент отключенном
      FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
      2000​
      Файл не может быть проиндексирован службой индексации Windows
      FILE_ATTRIBUTE_ENCRYPTED
      4000​
      Зашифрованный файл
      FILE_ATTRIBUTE_
      8000​
      FILE_ATTRIBUTE_VIRTUAL
      10000​
      В дополнение к перечисленным выше атрибутам, через параметр dwFlagsAndAttributes можно передать любую логическую комбинацию флагов из перечисленных ниже
      dwFlagsAndAttributeshexОписание
      SECURITY_ANONYMOUS
      00000​
      анонимный доступ
      SECURITY_IDENTIFICATION
      10000​
      идентификационный доступ
      SECURITY_IMPERSONATION
      20000​
      персональный доступ
      SECURITY_DELEGATION
      30000​
      коллективный доступ
      SECURITY_CONTEXT_TRACKING
      40000​
      динамический режим доступа
      SECURITY_EFFECTIVE_ONLY
      80000​
      ограничение групп и привилегий
      SECURITY_SQOS_PRESENT
      100000​
      SECURITY_VALID_SQOS_FLAGS
      1F0000​
      FILE_FLAG_SESSION_AWARE
      800000​
      Файл или устройство открывается с помощью осведомленности о сеансе. Если этот флаг не указан, то для каждого сеанса (например, устройства с использованием перенаправления USB RemoteFX) невозможно открыть процессами, выполняемыми в сеансе 0. Этот флаг не действует для вызывающих абонентов в сеансе 0.
      FILE_FLAG_POSIX_SEMANTICS
      1000000​
      доступ осуществляется в POSIX стандарте. Доступ к файлу будет выполняться в соответствии со спецификацией POSIX
      FILE_FLAG_BACKUP_SEMANTICS
      2000000​
      Backup файл, файл резервного копирования. Файл будет использован для выполнения операции выгрузки или восстановления. При этом выполняется проверка прав доступа
      FILE_FLAG_DELETE_ON_CLOSE
      4000000​
      операционная система должна удалить файл, когда все указатели на файл будут закрыты. Файл будет удален сразу после того как приложение закроет его идентификатор. Этот флаг удобно использовать для временных файлов
      FILE_FLAG_SEQUENTIAL_SCAN
      8000000​
      доступ к файлу может быть последовательный от начала до конца. Указывает, что к файлу будет выполняться последовательный до-ступ от начала файла к его концу. Флаг предназначен для оптимизации кэширования
      FILE_FLAG_RANDOM_ACCESS
      10000000​
      случайный доступ. Используется для оптимизации кэша. Указывает, что к файлу будет выполняться произвольный доступ. Флаг предназначен для оптимизации кэширования
      FILE_FLAG_NO_BUFFERING20000000нельзя использовать буферы или кэш. Отмена промежуточной буферизации или кэширования. При использовании этого флага необходимо выполнять чтение и запись порциями, кратными размеру сектора (обычно 512 байт)
      FILE_FLAG_OVERLAPPED40000000Выполнение чтения и записи асинхронно. Во время асинхронного чтения или записи приложение может продолжать обработку данных
      FILE_FLAG_WRITE_THROUGH80000000возможность записи в файл через кэш. Отмена промежуточного кэширования данных для уменьшения вероятности потери данных при аварии
    • hTemplateFile — файл шаблона. hTemplateFile предназначен для доступа к файлу шаблона с расширенными атрибутами для создаваемого файла
    Если функция выполнилась без проблем, то она возвращает указатель на открытое (созданное) устройства. Через этот указатель получают доступ к файлу.
    Если произошла ошибка — функция вернет INVALID_HANDLE_VALUE = -1

    DeleteFile

    Функция удаления существующего файла
    Код (C):
    1. DeleteFile
    2.     LPCTSTR lpFileName // Указатель на имя файла, предназначенного для удаления
    Если всё нормально — функция вернет ненулевое значение (TRUE)

    RemoveDirectory

    Удаляет существующий пустой каталог
    Код (C):
    1. RemoveDirectory
    2.       LPCSTR lpPathName /* Путь к удаляемой папке. Этот путь должен указывать
    3. пустой каталог, вызывающий процесс должен иметь доступ к каталогу удаления */
    Если функция выполняется успешно, возвращается ненулевое значение (TRUE)

    FindFirstFile

    Функция запускает поиск файла в указанной директории.
    Код (C):
    1. FindFirstFile
    2.     LPCTSTR lpFileName, // Строка содержащая путь для поиска файлов.
    3.     LPWIN32_FIND_DATA lpFindFileData // Информация о файле
    Рассмотрим оба параметра подробнее:
    • lpFileName — указатель на строку содержащую путь для поиска файла
      Строка может указывать на конкретный файл типа "c:\filename.txt" или может хранить шаблон "c:\*.txt" Если указан шаблон, то это даёт возможность перечислить все файлы удовлетворяющие шаблону.
    • lpFindFileData — указатель на структуру WIN32_FIND_DATA, в которую будет записана информация о найденном файле
      Рассмотрим структуру WIN32_FIND_DATA немного подробнее:
      Код (ASM):
      1. WIN32_FIND_DATA struct
      2.     dwFileAttributes    DWORD ?; Атрибуты файла
      3.     ftCreationTime      FILETIME <>; Время создания
      4.     ftLastAccessTime    <>; Время последнего доступа
      5.     ftLastWriteTime     <>; Время последней записи в файл
      6.     nFileSizeHigh       DWORD ?; Верхний байт размера файла
      7.     nFileSizeLow        DWORD ?; Нижний байт размера файла
      8.     dwReserved0         DWORD ?; Зарезервировано
      9.     dwReserved1         DWORD ?; Зарезервировано
      10.     cFileName           BYTE MAX_PATH dup(?); Имя файла
      11.     cAlternateFileName  BYTE 14 dup(?);Имя файла для отображения в DOS (8:3)
      12. 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):
    1. FindNextFile
    2.         HANDLE hFindFile, /* Дескриптор поиска, возвращенный предыдущим вызовом
    3. функции FindFirstFile или FindFirstFileEx */
    4.     LPWIN32_FIND_DATAA lpFindFileData // Информация о файле
    Второй параметр такой же, как и у FindFirstFile. Первый параметр — указатель на файл из предыдущего поиска. Он нужен, чтобы функция FindNextFile знала на каком файле остановился поиск и какой надо найти следующим. Если всё нормально, то функция вернет параметр lpFindFileData, который содержит сведения о следующем найденном файле или каталоге. Если функция завершается сбоем, возвращаемое значение равно нулю, а содержимое lpFindFileData является неопределенным.

    FindClose

    Функция закрывает дескриптор поиска файлов, открытый функцией FindFirstFile.
    Код (C):
    1. FindClose
    2.     HANDLE hFindFile // дескриптор поиска файлов
    Если всё нормально, функция вернет ненулевое значение.

    GetCurrentDirectory

    Функция позволяет узнать текущую директорию, с которой в данный момент работает программа.
    Код (C):
    1. GetCurrentDirectory
    2.     DWORD nBufferLength, // Размер буфера, в котором будет храниться путь
    3.     LPTSTR lpBuffer // Сам буфер
    Если произошла ошибка — функция вернет 0. Если всё нормально — программа вернет длину lpBuffer в котором хранится путь к текущей директории.

    SetCurrentDirectory

    Функция SetCurrentDirectory устанавливает указанную директорию, как текущую.
    Код (C):
    1. SetCurrentDirectory
    2.    LPCTSTR lpPathName /* Путь к новому текущему каталогу. Может указывать
    3. относительный или полный путь */
    Если произошла ошибка — функция вернет 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, сразу после закрывания файл будет удален. Это удобно при работе с временными файлами
     
    MaKsIm, mantissa и k3rnl нравится это.
  2. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Открывает диалог для выбора файлов и дирректорий.
    SHGetPathFromIDList гораздо удобнее чем GetOpenFileName.

    Здесь не совсем ассемблер:
    Код (ASM):
    1. function OpenFile(Title: string): string;
    2. var
    3.   lpItemID: PItemIDList;
    4.   BrowseInfo: TBrowseInfo;
    5.   DisplayName: array[0..2048] of Char;
    6.   TempPath: array[0..2048] of Char;
    7. begin
    8.   Result := '';
    9.   FillChar( BrowseInfo, SizeOf( TBrowseInfo ), #0 );
    10.   BrowseInfo.pszDisplayName := @DisplayName;
    11.   BrowseInfo.lpszTitle := PChar( Title );
    12.   BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS or BIF_BROWSEINCLUDEFILES;
    13.   lpItemID := SHBrowseForFolder( BrowseInfo );
    14.   if lpItemId <> nil then
    15.   begin
    16.     SHGetPathFromIDList( lpItemID, TempPath );
    17.     Result := TempPath;
    18.     GlobalFreePtr( lpItemID );
    19.   end;
    20. end; //OpenFile
    Приблизительный перевод:
    Код (ASM):
    1. .386
    2. .model flat, stdcall
    3.  
    4. includelib kernel32.lib
    5. includelib shell32.lib
    6.  
    7. .data
    8. BIF_RETURNONLYFSDIRS equ 00000001h
    9. BIF_BROWSEINCLUDEFILES equ 00110000h
    10.  
    11. TBrowseInfo struct
    12.     hwndOwner          dd ?
    13.     pIDLRoot           dd ?
    14.     pszDisplayName     dd ?
    15.     lpszTitle          dd ?
    16.     ulFlags            dd ?
    17.     lpfn               dd ?
    18.     lParam             dd ?
    19.     iImage             dd ?
    20. TBrowseInfo ends
    21.  
    22. PItemIDList typedef ptr TBrowseInfo
    23.  
    24. DisplayName db 2049 dup(?)
    25. TempPath    db 2049 dup(?)
    26.  
    27. .code
    28. OpenFile proc Title:DWORD
    29.     push ebp
    30.     mov ebp, esp
    31.     sub esp, sizeof TBrowseInfo
    32.  
    33.     ; Очистка структуры TBrowseInfo
    34.     lea eax, [ebp - sizeof TBrowseInfo]
    35.     xor ecx, ecx
    36.     mov edx, sizeof TBrowseInfo
    37.     rep stosb
    38.  
    39.     ; Заполнение структуры TBrowseInfo
    40.     lea eax, [ebp - sizeof TBrowseInfo]
    41.     mov dword ptr [eax + TBrowseInfo.pszDisplayName], offset DisplayName
    42.     mov dword ptr [eax + TBrowseInfo.lpszTitle], Title
    43.     mov dword ptr [eax + TBrowseInfo.ulFlags], BIF_RETURNONLYFSDIRS or BIF_BROWSEINCLUDEFILES
    44.  
    45.     ; Вызов функции SHBrowseForFolder
    46.     push eax
    47.     call SHBrowseForFolder
    48.     add esp, 4
    49.  
    50.     cmp eax, 0
    51.     je @done
    52.  
    53.     ; Вызов функции SHGetPathFromIDList
    54.     push eax
    55.     lea eax, [ebp - sizeof TBrowseInfo]
    56.     push offset TempPath
    57.     call SHGetPathFromIDList
    58.     add esp, 12
    59.  
    60.     ; Копирование результата в строку возврата
    61.     lea eax, [ebp - sizeof TBrowseInfo]
    62.     mov ecx, 2049
    63.     mov esi, offset TempPath
    64.     mov edi, eax
    65.     rep movsb
    66.  
    67.     ; Освобождение памяти
    68.     push eax
    69.     call GlobalFree
    70.     add esp, 4
    71.  
    72. @done:
    73.     leave
    74.     ret
    75. OpenFile endp
    76.  
    77. end
     
    Mikl___ и MaKsIm нравится это.
  3. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792

    ReadFile и WriteFile

    С помощью функций ReadFile и WriteFile приложение может выполнять чтение из файла и запись в файл.
    Код (C):
    1. ReadFile
    2.   HANDLE  hFile,  // дескриптор файла
    3.   LPVOID  lpBuffer,  // адрес буфера для данных
    4.   DWORD  nNumberOfBytesToRead, // количество байт, которые необходимо прочесть в буфер
    5.   LPDWORD lpNumberOfBytesRead,  /* адрес слова, в которое будет записано
    6. количество прочитанных байт */
    7.   LPOVERLAPPED lpOverlapped // адрес структуры типа OVERLAPPED
    8.  
    9. WriteFile
    10.   HANDLE  hFile,  // идентификатор файла
    11.   LPVOID  lpBuffer,  // адрес записываемого блока данных
    12.   DWORD  nNumberOfBytesToWrite, // количество байт, которые необходимо записать
    13.   LPDWORD lpNumberOfBytesWrite,  /* адрес слова, в котором будет сохранено
    14. количество записанных байт */
    15.   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):
    1. FlushFileBuffers
    2.     HANDLE hFile // Дескриптор открытого файла
    Так как ввод и вывод данных на диск в Windows буферизуется, запись данных на диск может быть отложен до тех пор, пока система не освободится от выполнения текущей работы. С помощью функции FlushFileBuffers можно принудительно заставить операционную систему записать на диск все изменения для файла, дескриптор которого передается функции FlushFileBuffers через единственный параметр hFile. В случае успешного завершения функция возвращает не нулевое значение (TRUE), при ошибке — FALSE. Код ошибки можно получить при помощи функции GetLastError. При закрытии файла функцией CloseHandle содержимое всех буферов, связанных с этим файлом, записывается на диск автоматически. Используйте функцию FlushFileBuffers только в том случае, если запись содержимого буферов нужно выполнить до закрытия файла.

    SetFilePointer

    С помощью функции SetFilePointer приложение может выполнять прямой доступ к файлу, перемещая указатель текущей позиции, связанный с файлом. Сразу после открывания файла этот указатель устанавливается в начало файла. Затем он передвигается функциями ReadFile и WriteFile на количество прочитанных или записанных байт, соответственно.
    Функция SetFilePointer позволяет выполнить установку текущей позиции:
    Код (C):
    1. SetFilePointer
    2.   HANDLE hFile  // Дескриптор открытого файла
    3.   LONG  lDistanceToMove, /* количество байт, на которое будет передвинута
    4. текущая позиция */
    5.   PLONG  lpDistanceToMoveHigh, /* адрес старшего слова, содержащего
    6. расстояние для перемещения позиции */
    7.   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):
    1. SetEndOfFile
    2.    HANDLE hFile // Дескриптор файла для расширения или усечения
    Для изменения длины файла вам достаточно установить текущую позицию в нужное место с помощью функции SetFilePointer, а затем вызвать функцию SetEndOfFile.

    LockFile и UnlockFile

    Так как операционная система Windows является мультизадачной и допускает одновременную работу многих процессов, возможно возникновение ситуаций, в которых несколько задач попытаются выполнять запись или чтение для одних и тех же файлов. Например, два процесса могут попытаться изменить одни и те же записи файла базы данных, при этом третий процесс будет в то же самое время выполнять выборку этой записи.
    Если функции CreateFile указать режимы совместного использования файла FILE_SHARE_READ или FILE_SHARE_WRITE, несколько процессов смогут одновременно открыть файлы и выполнять операции чтения и записи, соответственно. Если же эти режимы не указаны, совместное использование файлов будет невозможно. Первый же процесс, открывший файл, заблокирует возможность работы с этим файлом для других процессов.
    В ряде случаев необходимо обеспечить возможность одновременной работы нескольких процессов с одним и тем же файлом. В этом случае при необходимости процессы могут блокировать доступ к отдельным фрагментам файлов для других процессов. Например, процесс, изменяющий запись в базе данных, перед выполнением изменения может заблокировать участок файла, содержащий эту запись, и затем после выполнения записи разблокировать его. Другие процессы не смогут выполнить запись или чтение для заблокированных участков файла.
    Блокировка участка файла выполняется функцией LockFile:
    Код (C):
    1. LockFile
    2.   HANDLE hFile, // Дескриптор файла
    3.   DWORD  dwFileOffsetLow,  // младшее двойное слово смещения области
    4.   DWORD  dwFileOffsetHigh, // старшее двойное слово смещения области
    5.   DWORD  nNumberOfBytesToLockLow,  // младшее двойное слово длины области
    6.   DWORD  nNumberOfBytesToLockHigh // старшее двойное слово длины области
    Параметр hFile задает дескриптор файла, для которого выполняется блокировка области.
    Смещение блокируемой области (64-разрядное) задается при помощи параметров dwFileOffsetLow (младшее двойное слово) и dwFileOffsetHigh (старшее двойное слово).
    Размер области в байтах задается параметрами nNumberOfBytesToLockLow (младшее двойное слово) и nNumberOfBytesToLockHigh (старшее двойное слово). Если в файле блокируется несколько областей, они не должны перекрывать друг друга.
    В случае успешного завершения функция LockFile возвращает значение TRUE, при ошибке — FALSE. Код ошибки получают при помощи функции GetLastError.
    После использования заблокированной области, а также перед завершением своей работы процессы должны разблокировать все заблокированные ранее области, вызвав для этого функцию UnlockFile:
    Код (C):
    1. UnlockFile
    2.   HANDLE hFile, // дескриптор файла
    3.   DWORD  dwFileOffsetLow,  // младшее слово смещения области
    4.   DWORD  dwFileOffsetHigh, // старшее слово смещения области
    5.   DWORD  nNumberOfBytesToUnlockLow,  // младшее слово длины области
    6.   DWORD  nNumberOfBytesToUnlockHigh // старшее слово длины области
    В программном интерфейсе операционной системы Windows есть еще две функции, предназначенные для блокирования и разблокирования областей файлов. Это функции LockFileEx и UnlockFileEx. Главное отличие функции LockFileEx от функции LockFile заключается в том, что она может выполнять частичную блокировку файла, например, только блокировку от записи. В этом случае другие процессы могут выполнять чтение заблокированной области

    GetFileSize

    Функция возвращает размер указанного файла в байтах.
    Код (C):
    1. GetFileSize
    2.   HANDLE  hFile //Дескриптор файла
    3.   LPDWORD lpFileSizeHigh/* Указатель на переменную, в которой возвращается
    4. двойное слово старшей части размера файла. Этот параметр может иметь
    5. значение 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):
    1. GetFileSizeEx
    2.   HANDLE  hFile,/* Дескриптор файла. Дескриптор должен быть создан
    3. с правом доступа FILE_READ_ATTRIBUTES или эквивалентным, либо
    4. вызывающий объект должен иметь достаточные разрешения на каталог,
    5. содержащий файл */
    6.   PLARGE_INTEGER lpFileSize/* Указатель на структуру LARGE_INTEGER,
    7. которая получает размер файла в байтах */
    Смену атрибута можно осуществить функцией SetFileAttributes, получить значение атрибута функцией GetFileAttributes. Значение атрибутов FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_DEVICE, FILE_ATTRIBUTE_DIRECTORY, FILE_ATTRIBUTE_ENCRYPTED, FILE_ATTRIBUTE_SPARSE_FILE, FILE_ATTRIBUTE_REPARSE_POINT можно установить только при помощи функции DeviceIoControl

    SetFileAttributes

    Задает атрибуты для файла или каталога
    Код (C):
    1. SetFileAttributes
    2.      LPCSTR lpFileName, //Имя файла, атрибуты которого необходимо задать
    3.      DWORD  dwFileAttributes //Атрибуты файла, которые необходимо задать для файла
    Если функция выполняется успешно, возвращается ненулевое значение. Атрибутами файла может быть комбинация из флагов
    dwFileAttributeshex
    FILE_ATTRIBUTE_READONLY
    1​
    Файл, доступный только для чтения. Приложения могут читать файл, но не могут записывать в него или удалять его. Этот атрибут не учитывается в каталогах.
    FILE_ATTRIBUTE_HIDDEN
    2​
    Файл или каталог скрыты. Он не включается в обычный список каталогов
    FILE_ATTRIBUTE_SYSTEM
    4​
    Файл или каталог, часть или который используется исключительно операционной системой.
    8​
    FILE_ATTRIBUTE_DIRECTORY
    10​
    FILE_ATTRIBUTE_ARCHIVE
    20​
    Файл или каталог, который является архивным файлом или каталогом. Приложения обычно используют этот атрибут для пометки файлов для резервного копирования или удаления
    FILE_ATTRIBUTE_DEVICE
    40​
    FILE_ATTRIBUTE_NORMAL
    80​
    Файл, для которых не заданы другие атрибуты. Этот атрибут действителен только при использовании отдельно.
    FILE_ATTRIBUTE_TEMPORARY
    100​
    Файл, используемый для временного хранения. Если доступно достаточно памяти кэша, файловые системы избегают записи данных обратно в хранилище, так как обычно приложение удаляет временный файл после закрытия дескриптора. В этом сценарии система может полностью избежать записи данных. В противном случае данные записываются после закрытия дескриптора.
    FILE_ATTRIBUTE_OFFLINE
    1000​
    Данные файла доступны не сразу. Этот атрибут указывает, что данные файла физически перемещаются в автономное хранилище. Этот атрибут используется удаленным хранилищем, которое является программным обеспечением для управления иерархическим хранилищем. Приложения не должны произвольно изменять этот атрибут.
    FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
    2000​
    Файл или каталог не должны индексироваться службой индексирования содержимого

    GetFileAttributes

    Извлекает атрибуты файловой системы для указанного файла или каталога.
    Код (C):
    1. GetFileAttributes
    2.       LPCSTR lpFileName//Имя файла или каталога
    Если функция выполняется успешно, возвращаемое значение содержит атрибуты указанного файла или каталога. Если функция завершается сбоем, возвращаемое значение INVALID_FILE_ATTRIBUTES = -1.
     
    MaKsIm, Research и k3rnl нравится это.
  4. vitokop

    vitokop Member

    Публикаций:
    0
    Регистрация:
    20 май 2006
    Сообщения:
    48
    nFileSizeHigh

    Старшее двойное слово (DWORD) значения размера файла, в байтах. Это значение равняется нулю, если размер файла не больше, чем определяет его MAXDWORD.
    Размер файла равен
    (nFileSizeHigh * (MAXDWORD+1)) + (nFileSizeHigh

    nFileSizeLow

    Младшее двойное слово (DWORD) значения размера файла, в байтах.
    const MAXDWORD = DWord($FFFFFFFF);

    Размер файла равен (nFileSizeHigh << 32) + (nFileSizeHigh => 64 бита
    --- Сообщение объединено, 10 ноя 2024 в 19:02 ---
    Извините, ошибочка
    (nFileSizeHigh => nFileSizeHigh
     
    Mikl___ нравится это.
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792

    SHFileOperation

    Копирует, перемещает, переименовывает или удаляет объект файловой системы
    Код (C):
    1. SHFileOperation
    2.           LPSHFILEOPSTRUCTA lpFileOp /*Указатель на структуру SHFILEOPSTRUCT,
    3. содержащую сведения, необходимые этой функции для выполнения указанной
    4. операции. Этот параметр должен содержать допустимое значение, не равное  NULL*/
    Возвращает ноль (FALSE) в случае успешного выполнения; в противном случае ненулевое значение (TRUE)
    Код (ASM):
    1. SHFILEOPSTRUCTA struct
    2.    hwnd                  dq ?
    3.    wFunc                 dd ?,?
    4.    pFrom                 dq ?
    5.    pTo                   dq ?
    6.    fFlags                dw ?,?
    7.    fAnyOperationsAborted dd ?
    8.    hNameMappings         dq ?
    9.    lpszProgressTitle     dq ?
    10. 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, в расположение, указанное в pTo
    FO_COPY2Копируются файлы, указанные в элементе pFrom, в расположение, указанное в элементе pTo
    FO_DELETE3Удаляются файлы, указанные в pFrom
    FO_RENAME4Переименуются файл, указанный в pFrom. Флаг нельзя использовать для переименования нескольких файлов за один вызов функции. Вместо этого используйте FO_MOVE
    Флаги, управляющие операцией файла. Этот элемент может использовать сочетание следующих флагов.
    fFlagshexЗначение
    FOF_MULTIDESTFILES
    1​
    Элемент pTo указывает несколько целевых файлов (один для каждого исходного файла в pFrom), а не один каталог, в котором должны быть отложены все исходные файлы
    FOF_CONFIRMMOUSE
    2​
    Не используется
    FOF_SILENT
    4​
    Не отображать диалоговое окно хода выполнения
    FOF_RENAMEONCOLLISION
    8​
    Присвоить файлу новое имя в операции перемещения, копирования или переименования, если файл с целевым именем уже существует
    FOF_NOCONFIRMATION
    10​
    Ответьте "Да" на все для любого отображаемого диалогового окна
    FOF_WANTMAPPINGHANDLE
    20​
    Если FOF_RENAMEONCOLLISION указан и все файлы были переименованы, назначьте объект сопоставления имен, содержащий старые и новые имена элементу hNameMappings. Этот объект должен быть освобожден с помощью SHFreeNameMappings, если он больше не нужен
    FOF_ALLOWUNDO
    40​
    При возможности сохраните сведения об отмене. До Windows Vista операции можно отменить только из того же процесса, который выполнял исходную операцию. В Системах Windows Vista и более поздних версий область действия отмены — это сеанс пользователя. Любой процесс, выполняемый в сеансе пользователя, может отменить другую операцию. Состояние отмены хранится в процессе Explorer.exe и до тех пор, пока этот процесс выполняется, он может координировать функции отмены. Если параметр исходного файла не содержит полный путь и имена файлов, этот флаг игнорируется.
    FOF_FILESONLY
    80​
    Выполните операцию только в файлах (а не в папках), если указано имя файла подстановочного знака (.)
    FOF_SIMPLEPROGRESS
    100​
    Отображать диалоговое окно хода выполнения, но не отображает отдельные имена файлов, так как они работают
    FOF_NOCONFIRMMKDIR
    200​
    Не спрашивать у пользователя подтверждение о создании нового каталога, если операция требует создания
    FOF_NOERRORUI
    400​
    Не отображать диалоговое окно пользователю, если возникает ошибка
    FOF_NO_UI
    614​
    Выполнять операцию автоматически, не показывая пользовательский интерфейс
    FOF_NOCOPYSECURITYATTRIBS
    800​
    Не копировать атрибуты безопасности файла. Целевой файл получает атрибуты безопасности новой папки
    FOF_NORECURSION
    1000​
    Выполнять операцию только в локальном каталоге. Не действовать рекурсивно в подкаталогах, что является поведением по умолчанию
    FOF_NO_CONNECTED_ELEMENTS
    2000​
    Не перемещайте подключенные файлы как группу. Перемещайте только указанные файлы
    FOF_WANTNUKEWARNING
    4000​
    Отправьте предупреждение, если файл окончательно уничтожается во время операции удаления, а не перезапускается. Этот флаг частично переопределяет FOF_NOCONFIRMATION
    FOF_NORECURSEREPARSE
    8000​
    Не используется
    Коды ошибок, предшествующих Win32, больше не поддерживаются и не определяются в общедоступном файле заголовка. Необходимо определить их самостоятельно или сравнивать с возвращаемым числовым значением
    Код ошибкиhexЗначение
    DE_SAMEFILE
    71​
    Исходный и целевой файлы являются одинаковыми
    DE_MANYSRC1DEST
    72​
    В исходном буфере было указано несколько путей к файлам, но только один путь к целевому файлу.
    DE_DIFFDIR
    73​
    Операция переименования была указана, но конечный путь — это другой каталог. Вместо этого используйте операцию перемещения
    DE_ROOTDIR
    74​
    Источником является корневой каталог, который нельзя переместить или переименовать.
    DE_OPCANCELLED
    75​
    Операция была отменена пользователем или автоматически отменена, если соответствующие флаги были предоставлены SHFileOperation
    DE_DESTSUBTREE
    76​
    Назначение является поддеревом источника
    DE_ACCESSDENIEDSRC
    78​
    Параметры безопасности запрещают доступ к источнику
    DE_PATHTOODEEP
    79​
    Исходный или целевой путь превысил или превысит MAX_PATH
    DE_MANYDEST
    7A​
    Операция включала несколько конечных путей, что может завершиться ошибкой в случае операции перемещения
    DE_INVALIDFILES
    7C​
    Недопустимый путь в источнике или назначении
    DE_DESTSAMETREE
    7D​
    Источник и назначение имеют одну и ту же родительскую папку.
    DE_FLDDESTISFILE
    7E​
    Конечный путь — это существующий файл
    DE_FILEDESTISFLD
    80​
    Конечный путь — это существующая папка
    DE_FILENAMETOOLONG
    81​
    Имя файла превышает MAX_PATH
    DE_DEST_IS_CDROM
    82​
    Назначение — компакт-диск, доступный только для чтения, возможно, не отформатирован
    DE_DEST_IS_DVD
    83​
    Назначение — DVD-диск, доступный только для чтения, возможно, не отформатирован
    DE_DEST_IS_CDRECORD
    84​
    Место назначения — записываемый компакт-диск, возможно, неформатированные
    DE_FILE_TOO_LARGE
    85​
    Файл, участвующий в операции, слишком велик для целевого носителя или файловой системы
    DE_SRC_IS_CDROM
    86​
    Источником является компакт-диск, доступный только для чтения, возможно, не отформатирован
    DE_SRC_IS_DVD
    87​
    Источником является DVD-диск, доступный только для чтения, возможно, не отформатирован
    DE_SRC_IS_CDRECORD
    88​
    Источником является записываемый компакт-диск, возможно, не форматируемый
    DE_ERROR_MAX
    B7​
    MAX_PATH превышено во время операции
    402​
    Произошла неизвестная ошибка. Обычно это происходит из-за недопустимого пути в источнике или назначении. Эта ошибка не возникает в Windows Vista и более поздних версиях.
    ERRORONDEST
    10000​
    В месте назначения произошла неуказанная ошибка
    DE_ROOTDIR+ERRORONDEST
    10074​
    Назначение является корневым каталогом и не может быть переименовано

    Удаление каталога через SHFileOperation

    Удаление каталога через оболочку Windows рекомендуется, если вы хотите удалить непустые каталоги или если вам нужна обратная связь в стиле проводника (например, диалоги хода выполнения с летающими файлами). Самый быстрый способ сделать это — создать SHFILEOPSTRUCT, инициализировать его и вызвать SHFileOperation, таким образом:
    Код (ASM):
    1. .data
    2. file_op SHFILEOPSTRUCT <NULL, FO_DELETE, dir, "", \
    3.  FOF_NOCONFIRMATION or  FOF_NOERRORUI or  FOF_SILENT,  false, 0, "">
    4. .code
    5.      . . .
    6.      invoke SHFileOperation,&file_op

    Файловые операции средствами SHFileOperation

    удаление файлов
    Код (Delphi):
    1.  
    2. SetCurrentDirectory( PChar( 'C:\' ) );
    3.   From := 'Test1.tst' + #0 + 'Test2.tst' + #0 + #0;
    4.   with SHFileOpStruct do
    5.   begin
    6.     Wnd := Handle;
    7.     wFunc := FO_DELETE;
    8.     pFrom := @From;
    9.     pTo := nil;
    10.     fFlags := 0;
    11.     fAnyOperationsAborted := False;
    12.     hNameMappings := nil;
    13.     lpszProgressTitle := nil;
    14.   end;
    15.   SHFileOperation(SHFileOpStruct);
    ни один из флагов не установлен. Если вы хотите не просто удалить файлы, а переместить их в корзину, должен быть установлен флаг FOF_ALLOWUNDO функция, удаляющая файлы, переданные ей в списке Names. Параметр ToRecycle определяет, будут ли файлы перемещены в корзину или удалены. Функция возвращает 0, если операция выполнена успешно, и ненулевое значение, если руки у кого-то растут не из того места, и этот кто-то всунул функции имена несуществующих файлов.
    Код (Delphi):
    1. CreateBuffer( Names, Src );
    2.   with SHFileOpStruct do
    3.   begin
    4.     Wnd := Handle;
    5.     wFunc := FO_DELETE;
    6.     pFrom := Pointer( Src );
    7.     pTo := nil;
    8.     fFlags := 0;
    9.     if ToRecycle then
    10.       fFlags := FOF_ALLOWUNDO;
    11.     fAnyOperationsAborted := False;
    12.     hNameMappings := nil;
    13.     lpszProgressTitle := nil;
    14.   end;
    15. SHFileOperation(SHFileOpStruct);
    Перемещаем файлы указанные в списке Src в директорию Dest. Параметр Move определяет, будут ли файлы перемещаться или копироваться. Параметр AutoRename указывает, переименовывать ли файлы в случае конфликта имен.
    Код (Delphi):
    1. with SHFileOpStruct do
    2.   begin
    3.     Wnd := Handle;
    4.     wFunc := FO_COPY;
    5.     if Move then wFunc := FO_MOVE;
    6.     pFrom := Pointer( SrcBuf );
    7.     pTo := PChar( Dest );
    8.     fFlags := 0;
    9.     if AutoRename then
    10.       fFlags := FOF_RENAMEONCOLLISION;
    11.     fAnyOperationsAborted := False;
    12.     hNameMappings := nil;
    13.     lpszProgressTitle := nil;
    14.   end;
    15. SHFileOperation(SHFileOpStruct);
    переименование
    Код (Delphi):
    1. with
    2. SHFileOpStruct do
    3.   begin
    4.     Wnd := Handle;
    5.     wFunc := FO_RENAME;
    6.     pFrom := PChar( Src );
    7.     pTo := PChar( New );
    8.     fFlags := 0;
    9.     if AutoRename then
    10.       fFlags := FOF_RENAMEONCOLLISION;
    11.     fAnyOperationsAborted := False;
    12.     hNameMappings := nil;
    13.     lpszProgressTitle := nil;
    14.   end;
    15. SHFileOperation(SHFileOpStruct);
     
    Последнее редактирование: 12 ноя 2024 в 14:34
  6. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.792

    Помещаем файл в корзину

    По мотивам ManHunter'a Программное удаление файла в Корзину
    Код (ASM):
    1. ; GUI #
    2. include win64a.inc
    3. SHFILEOPSTRUCT struct
    4. hwnd dq ?
    5. wFunc dd ?,?
    6. pFrom dq ?
    7. pTo dq ?
    8. fFlags dw ?,?
    9. fAnyOperationsAborted dd ?
    10. hNameMappings dq ?
    11. lpszProgressTitle dq ?
    12. SHFILEOPSTRUCT ends
    13. FO_DELETE = 3
    14. FOF_ALLOWUNDO = 40h
    15. FOF_NOCONFIRMATION = 10h
    16. FOF_SILENT = 4
    17. .code
    18. WinMain proc
    19. local hFile:qword
    20. local bytecount:dword
    21.         ; Создать тестовый файл
    22.         mov qword ptr[rsp+30h],NULL
    23.         mov qword ptr[rsp+28h],FILE_ATTRIBUTE_ARCHIVE
    24.         mov qword ptr[rsp+20h],CREATE_NEW
    25.         invoke  CreateFile,&fname,GENERIC_WRITE,NULL,NULL
    26.         mov hFile,rax
    27.         mov qword ptr[rsp+20h],NULL
    28.         invoke  WriteFile,hFile,&fdata,sizeof fdata,&bytecount
    29.         invoke  CloseHandle,hFile
    30.         ; Удалить файл
    31.         mov     fos.hwnd,HWND_DESKTOP
    32.         mov     fos.wFunc,FO_DELETE
    33.         movr fos.pFrom,fname
    34.         mov     fos.fFlags,FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT
    35.         invoke  SHFileOperation,&fos
    36. ;завершение программы
    37.         invoke RtlExitUserProcess,0
    38. WinMain endp
    39. .data
    40. fname db 'test3.txt',0,0
    41. fdata db 'KittyKat'
    42. fos   SHFILEOPSTRUCT <>
    43. end
    Продолжение следует...
     
    Последнее редактирование: 12 ноя 2024 в 14:35
  7. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Рекурсивный поиск:
    Код (Delphi):
    1. function PathAppend(path, str: string): string;
    2. begin
    3.   if path[Length(path)] <> '\' then path := path + '\';
    4.   result := path + str;
    5. end; //PathAppend
    Код (Delphi):
    1. procedure ScanDirEx(s: string; var Files: TStrings);
    2. var
    3.   Dir, FileName: string;
    4.   SearchRec: TSearchRec;
    5. begin
    6.   Dir := s;
    7.   if Dir[length(Dir)] <> '\' then Dir := Dir + '\';
    8.   if FindFirst(PathAppend(Dir, '*.*'), faAnyFile, SearchRec) = 0 then
    9.   repeat
    10.     FileName := PathAppend(Dir, SearchRec.name);
    11.     if (SearchRec.name = '.') or (SearchRec.name = '..') then Continue;
    12.     if (SearchRec.Attr and faDirectory) <> 0 then
    13.     begin
    14.       Files.Add(FileName);
    15.       ScanDirEx(FileName, Files);
    16.     end
    17.     else
    18.     begin
    19.       if FileExists(FileName) then
    20.       begin  
    21.         Files.Add(FileName);
    22.       end;
    23.     end;
    24.   until FindNext(SearchRec) <> 0;
    25.   FindClose(SearchRec);
    26. end; //ScanDirEx
    Является ли файлом или директорией, 2 способа:
    Код (Delphi):
    1. function IsDir(s: string): Boolean;
    2. var
    3.   searchResult: TSearchRec;
    4. begin
    5.   FindFirst(s, faAnyFile, searchResult);
    6.   Result := searchResult.Attr = faDirectory;
    7.   FindClose(searchResult);
    8. end; //IsDir
    9.  
    10. function IsDirEx(s: string): Boolean;
    11. var
    12.   Code: Integer;
    13. begin
    14.   Code := GetFileAttributes(PChar(s));
    15.   Result := Code and FILE_ATTRIBUTE_DIRECTORY <> 0;
    16. end; //IsDirEx
    Свободен ли файл:
    Код (Delphi):
    1. function IsFileInUse(const AFileName: string): Boolean;
    2. var
    3.   HFileRes: THandle;
    4. begin
    5.   HFileRes := CreateFile(PChar(AFileName), GENERIC_READ or GENERIC_WRITE,
    6.     0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    7.   Result := (HFileRes = INVALID_HANDLE_VALUE);
    8.   if not Result then CloseHandle(HFileRes);
    9. end; //IsFileInUse
    Еще часто приходится использовать: ExtractFilePath, ExtractFileName, ExtractFileExt
     
    Mikl___ нравится это.
  8. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    Ничего не имею против этого кода и он даже в Lazarus реализован кроссплатформенно. Но вот антивирусы на именно эту процедуру почему то будут реагировать как на малварь. Хотя передавать столько лишних параметров в рекурсии не стоит т.к. не известна глубина каталогов. Лучше добавить туда еще директиву register.

    А вот на вариант этой же процедуры через FindFirstFile/FindNextFile/CloseHandle - не реагируют
     
  9. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Код (Delphi):
    1. function StrRScan(const Str: PChar; Chr: Char): PChar; assembler;
    2. asm
    3.         PUSH    EDI
    4.         MOV     EDI,Str
    5.         MOV     ECX,0FFFFFFFFH
    6.         XOR     AL,AL
    7.         REPNE   SCASB
    8.         NOT     ECX
    9.         STD
    10.         DEC     EDI
    11.         MOV     AL,Chr
    12.         REPNE   SCASB
    13.         MOV     EAX,0
    14.         JNE     @@1
    15.         MOV     EAX,EDI
    16.         INC     EAX
    17. @@1:    CLD
    18.         POP     EDI
    19. end;
    20.  
    21. function GoDelimiterLast(Str: PChar; Delimiters: PChar): PChar;
    22. var
    23.     P, F : PChar;
    24. begin
    25.   P := Str;
    26.   Result := P + StrLen(Str);
    27.   while Delimiters^ <> #0 do
    28.   begin
    29.     F := StrRScan(P, Delimiters^);
    30.     if F <> nil then
    31.     if (Result^ = #0) or (Integer(F) > Integer(Result)) then
    32.        Result := F;
    33.     Inc(Delimiters);
    34.   end;
    35. end;
    36.  
    37. function ExtractFileExt(const Path : String) : String;
    38. var
    39. P: PChar;
    40. begin
    41. P := GoDelimiterLast(PChar(Path), '.');
    42. Result := P;
    43. end;
    44.  
    45. function ExtractFileName(const Path : String) : String;
    46. var
    47. P: PChar;
    48. begin
    49. P := GoDelimiterLast(PChar(Path), ':\');
    50.   if P^ = #0
    51.    then Result := Path
    52.    else Result := P + 1;
    53. end;
    54.  
    55. function Copy(Dest, Source: PChar; MaxLen: Cardinal): PChar; assembler;
    56. asm
    57.         PUSH    EDI
    58.         PUSH    ESI
    59.         PUSH    EBX
    60.         MOV     ESI,EAX
    61.         MOV     EDI,EDX
    62.         MOV     EBX,ECX
    63.         XOR     AL,AL
    64.         TEST    ECX,ECX
    65.         JZ      @@1
    66.         REPNE   SCASB
    67.         JNE     @@1
    68.         INC     ECX
    69. @@1:    SUB     EBX,ECX
    70.         MOV     EDI,ESI
    71.         MOV     ESI,EDX
    72.         MOV     EDX,EDI
    73.         MOV     ECX,EBX
    74.         SHR     ECX,2
    75.         REP     MOVSD
    76.         MOV     ECX,EBX
    77.         AND     ECX,3
    78.         REP     MOVSB
    79.         STOSB
    80.         MOV     EAX,EDX
    81.         POP     EBX
    82.         POP     ESI
    83.         POP     EDI
    84. end;
    85.  
    86. function ExtractFilePath(const Path : String) : String;
    87. var
    88. P, P0: PChar;
    89. begin
    90. P0 := PChar(Path);
    91. P := GoDelimiterLast(P0, ':\');
    92.   if P^ = #0
    93.    then Result := ''
    94.    else Result := Copy(Path, 1, P - P0 + 1);
    95. end;
     
    Mikl___ нравится это.
  10. MaKsIm

    MaKsIm Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    94
    Так вы каждый вызов будете класть в стек дополнительно два параметра (на х86). А вот под Linux на её фс еще и кольцевые ссылки надо обрабатывать (как я и сказал этот код может работать кроссплатформенно).
     
  11. Ahimov

    Ahimov New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    11
    IsFileInUse - а если файла нет?

    Может нэйтив RtlDoesFileExists ?
     
  12. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Ahimov, тогда сначала надо использовать функцию FileExists(), перед вызовом IsFileInUse
     
  13. Ahimov

    Ahimov New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    11
    Research

    Это дельфовый функционал.
     
  14. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Код (Delphi):
    1. function IsFileExists(const filename: string): Boolean;
    2. var
    3.   fileAttr: DWORD;
    4. begin
    5.   fileAttr := GetFileAttributes(PChar(filename));
    6.   Result := fileAttr <> INVALID_FILE_ATTRIBUTES;
    7. end;
     
    Последнее редактирование: 12 ноя 2024 в 11:02
  15. Ahimov

    Ahimov New Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    11
    Нужны дополнительны проверки, как тут. Открывать файл не желательно, да и доступ к нему может быть расшарен.
     
  16. Research

    Research Active Member

    Публикаций:
    1
    Регистрация:
    6 янв 2024
    Сообщения:
    133
    Ahimov, так напиши на нэйтиве со всеми проверками, в чем проблема? Рекурсивный поиск тоже переведи, чтобы быстрее все было