Функции ядра Windows


В отличие способов управления памятью, где для простых приложений рекомендуется использовать библиотечные функции C/C++, для работы с файлами лучше всего использовать не функции библиотек C/C++, функции интерфейса Win32 API.

· Применение функций Win32 API дает два огромных плюса - скорость дискового обмена данными и переносимость программ на другие платформы.

CreateFile

Функция создаёт указатель на новое устройство типа:

  • Файл
  • Канал
  • mailslot (почтовый канал)
  • коммуникационный ресурс (например COM порт)
  • дисковые устройства
  • консоли
  • директории (открывает их)

Функция умеет открывать и создавать новые устройства (файлы).

 

объявлена в winbase.h.

Объявление:

HANDLE CreateFile(

LPCTSTR lpFileName, // Указатель на имя файла (устройства)

DWORD dwDesiredAccess, //Параметры доступа

DWORD dwShareMode, //Разделяемый доступ

LPSECURITY_ATTRIBUTES lpSecurityAttributes, //безопасность

DWORD dwCreationDistribution,// Описание

DWORD dwFlagsAndAttributes, // Атрибуты файла

HANDLE hTemplateFile // Файл шаблона

);

Теперь рассмотрим подробно все параметры:

  • lpFileName - Указатель на строку содержащую имя создаваемого файла или устройства.
  • dwDesiredAccess - тип доступа. Может принимать значения (можно использовать одно или сразу несколько):
    • 0 - запрос. Функция не даст реального доступа к файлу, а выполнится как тест возможности создания или открытия файла (устройства).
    • GENERIC_READ - получить доступ к чтению
    • GENERIC_WRITE - получить доступ к записи
  • dwShareMode - флаги, указывающие на то, как создаваемый (открываемый) объект должен разделять доступ между процессами. Это значит, как будет делится доступ к файлу с другими программами если они тоже попытаются открыть этот файл. Параметр может принимать значения (можно использовать одно или сразу несколько):
    • FILE_SHARE_DELETE - другим процессам разрешается доступ к файла (устройству) только если требуется доступ на удаление (поддерживается только в Windows NT).
    • FILE_SHARE_READ - другим процессам разрешается только читать файл
    • FILE_SHARE_WRITE - другим процессам разрешается только писать в файл
  • lpSecurityAttributes - указатель на структуру типа SECURITY_ATTRIBUTES.
  • dwCreationDistribution - описывает, что делать с файлом если он уже существует или его ещё нет. Параметр может принимать только одно из следующих значений (комбинация не допускается):
    • CREATE_NEW - создать новый файл. Если он уже существует, то произойдёт ошибка
    • CREATE_ALWAYS - если файл существует, то он будет перезаписан (обнулён).
    • OPEN_EXISTING - открыть существующий файл (устройство). Если файла нет, то произойдёт ошибка.
    • OPEN_ALWAYS - если файла нет, то он будет создан как при использовании CREATE_NEW.
    • TRUNCATE_EXISTING - открыть файл и обрезать его размер до нуля. Параметр dwDesiredAccess должен содержать GENERIC_WRITE. Если файла нет, то произойдёт ошибка.
  • dwFlagsAndAttributes - атрибуты создаваемого файла. Параметр может принимать комбинацию из значений:
    • FILE_ATTRIBUTE_NORMAL
      • FILE_ATTRIBUTE_ARCHIVE - архивный
      • FILE_ATTRIBUTE_COMPRESSED - сжатый
      • FILE_ATTRIBUTE_HIDDEN - скрытый
      • FILE_ATTRIBUTE_NORMAL - нормальный
      • FILE_ATTRIBUTE_OFFLINE - данные файла недоступны
      • FILE_ATTRIBUTE_READONLY - только для чтения
      • FILE_ATTRIBUTE_SYSTEM - системный
      • FILE_ATTRIBUTE_TEMPORARY - временный
    • FILE_FLAG_WRITE_THROUGH - возможность записи в файл через кэш.
    • FILE_FLAG_NO_BUFFERING - нельзя использовать буферы или кэш
    • FILE_FLAG_RANDOM_ACCESS - случайный доступ. Используется для оптимизации кэша
    • FILE_FLAG_SEQUENTIAL_SCAN - доступ к файлу может быть последовательный от начала до конца
    • FILE_FLAG_DELETE_ON_CLOSE - операционная система должна удалить файл, когда все указатели на файл будут закрыты
    • FILE_FLAG_BACKUP_SEMANTICS - Backup файл, т.е. файл резервного копирования.
    • FILE_FLAG_POSIX_SEMANTICS - доступ осуществляется в POSIX стандарте.
    • SECURITY_SQOS_PRESENT
      • SECURITY_ANONYMOUS - анонимный доступ
      • SECURITY_IDENTIFICATION - идентификационный доступ
      • SECURITY_IMPERSONATION - персональный доступ
      • SECURITY_DELEGATION - коллективный доступ
      • SECURITY_CONTEXT_TRACKING - динамический режим доступа
      • SECURITY_EFFECTIVE_ONLY - ограничение групп и привилегий
  • hTemplateFile - файл шаблона

 

 

Структура SECURITY_ATTRIBUTES содержит дескриптор безопасности для объекта и определяет, будет ли возвращаемый дескриптор наследуемым.

  • typedef struct _SECURITY_ATTRIBUTES { // sa
  • DWORD nLength;
  • LPVOID lpSecurityDescriptor;
  • BOOL bInheritHandle;
  • } SECURITY_ATTRIBUTES;

Security Descriptor - Эти объекты содержат информацию о безопасности, соотнесенную с тем или иным защищенным объектом. Физически этот объект представляет собой структуру SECURITY_DESCRIPTOR, описанную в файле Windows.h:

typedef struct _SECURITY_DESCRIPTOR { BYTE Revision; BYTE Sbz1; SECURITY_DESCRIPTOR_CONTROL Control; PSID Owner; PSID Group; PACL Sacl; PACL Dacl;} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;

Структура SECURITY_DESCRIPTOR используется для доступа к информации о безопасности объектов. Но изменять поля непосредственно в данной структуре невозможно. Для этого необходимо использовать специальные функции (например, SetSecurityDescriptorOwner(…)). Кроме того, Win32 API предоставляет интерфейс для создания и инициализации описателя SD для новых объектов.

Если функция выполнилась без проблем, то она возвращает указатель на открытое (созданное) устройства.

Если произошла ошибка, то функция вернёт INVALID_HANDLE_VALUE.

DeleteFile

Функция удаления существующего файла

объявлена в winbase.h.

Объявление:

BOOL DeleteFile(

LPCTSTR lpFileName // Указатель на строку с полным именем файла

);

CopyFile

Функция копирует файл в новое место.

объявлена в winbase.h

BOOL CopyFile(

LPCTSTR lpExistingFileName, // Указатель на файл, который надо копировать

LPCTSTR lpNewFileName, // Указатель на имя файла, куда надо копировать

BOOL bFailIfExists // Что делать если файл уже существует.

);

MoveFile

Переместить существующий файл на новое место.

объявлена в winbase.h. .

Объявление:

BOOL MoveFile(

LPCTSTR lpExistingFileName, // Полный путь к исходному файлу

LPCTSTR lpNewFileName // Полный путь к новому месту

);

Если все нормально, то функция возвращает TRUE.

SetEndOfFile

Функция делает текущую позицию файла концом файла. Если нам нужно сократить размер файла, то мы вызовем эту функцию, установим курсор в необходимую позицию и вызовем эту функцию.

объявлена в winbase.h. .

Объявление:

BOOL SetEndOfFile(

HANDLE hFile // Указатель на открытый файл

);

Если всё ОК, то функция вернёт TRUE.

SetFileAttributes

Функция позволяет устанавливать на файл атрибуты.

 

объявлена в winbase.h. .

Объявление:

BOOL SetFileAttributes(

LPCTSTR lpFileName, // Путь к файлу

DWORD dwFileAttributes // Будущие атрибуты файла

);

С первым параметром всё ясно. Это просто путь к файлу. А вот второй параметр это атрибуты. Они могут быть в виде сочетания следующих флагов:

 

  • FILE_ATTRIBUTE_ARCHIVE - атрибут архивного файла.
  • FILE_ATTRIBUTE_HIDDEN - атрибут спрятанного файла.
  • FILE_ATTRIBUTE_NORMAL - атрибут нормального файла.
  • FILE_ATTRIBUTE_OFFLINE - указывает на то, что данные файла не доступны и находятся на отключённом устройстве
  • FILE_ATTRIBUTE_READONLY - атрибут файла только для чтения.
  • FILE_ATTRIBUTE_SYSTEM - атрибут системного файла.
  • FILE_ATTRIBUTE_TEMPORARY - атрибут временного файла.

Если всё ОК, то функция вернёт TRUE.

SetFilePointer

Функция устанавливает позицию в файле.

объявлена в winbase.h. .

Объявление:

DWORD SetFilePointer(

HANDLE hFile, // Указатель на открытый файл

LONG lDistanceToMove, // количество байт, на которые надо передвинуться

PLONG lpDistanceToMoveHigh, // Второй байт, указывающий количество байт

DWORD dwMoveMethod //Откуда нужно начинать двигаться

);

Первый параметр - указатель на открытый файл. Второй и третий параметры определяют количество байт, на которые надо передвинуться. Последний параметр - это флаг определяющий откуда надо начинать двигаться:

 

  • FILE_BEGIN - Передвинуться от начала файла вперёд.
  • FILE_CURRENT - Передвинуться начиная от текущей позиции вперёд.
  • FILE_END - Передвинуться от конца файла к началу.

Если всё ОК, то функция вернёт младший байт установленной позиции.

Если мы хотим узнать текущую позицию файла, то мы можем, вызвть функцию с такими параметрами: SetFilePointer(h,0,0, FILE_CURRENT). Этим мы заставляем передвинуться на 0 байтов от текущей позиции. Передвижения не произойдёт, но функция вернёт новую позицию файла, то есть текущую.

FindFirstFile

Функция запускает поиск файла в указанной директории.

объявлена в winbase.h.

Объявление:

HANDLE FindFirstFile(

LPCTSTR lpFileName, // Строка содержащая путь для поиска файлов.

LPWIN32_FIND_DATA lpFindFileData // Информация о файле

);

Здесь стоит посмотреть на оба параметра подробнее:

  • lpFileName - строка содержащая путь для поиска файла. Эта строка может указывать на конкретный файл типа 'c:\filename.txt' или может хранить шаблон 'c:*.txt'. Если указывается шаблон, то это даёт возможность перечислить все файлы удовлетворяющие шаблону.
  • lpFindFileData - структура WIN32_FIND_DATA, в которую будет записана информация о найденном файле.

Рассмотрим структуру WIN32_FIND_DATA немного подробнее:

typedef struct _WIN32_FIND_DATA {

DWORD dwFileAttributes; // Атрибуты файла

FILETIME ftCreationTime; // Время создания

FILETIME ftLastAccessTime; //Время последнего доступа

FILETIME ftLastWriteTime; //Время последней записи в файл

DWORD nFileSizeHigh; //Верхний байт размера файла

DWORD nFileSizeLow; //Нижний байт размера файла

DWORD dwReserved0; //Зарезервировано

DWORD dwReserved1; //Зарезервировано

TCHAR cFileName[ MAX_PATH ]; //Имя файла

TCHAR cAlternateFileName[ 14 ]; //Имя файла для отображения в DOS (8:3)

} WIN32_FIND_DATA;

 

Атрибутами файла может быть комбинация из флагов:

  • FILE_ATTRIBUTE_ARCHIVE - архивный
  • FILE_ATTRIBUTE_COMPRESSED - сжатый
  • FILE_ATTRIBUTE_HIDDEN - скрытый
  • FILE_ATTRIBUTE_NORMAL - нормальный
  • FILE_ATTRIBUTE_OFFLINE - данные файла недоступны
  • FILE_ATTRIBUTE_READONLY - только для чтения
  • FILE_ATTRIBUTE_SYSTEM - системный
  • FILE_ATTRIBUTE_TEMPORARY - временный

Размер файла разложен на два байта. Чтоб получить полный размер файла нужно выполнить действие (FInfo.nFileSizeHigh * MAXDWORD) + FInfo.nFileSizeLow. Это не самый эффективный (эффективнее сдвигать), но самый понятный способ.

Функция возвращает указатель на найденный файл, если нет, то возврат будет типа ERROR_NO_MORE_FILES.

ПРИМЕР:

#include "windows.h"

#include <stdio.h>

 

Int

main(int argc, char *argv[])

{

WIN32_FIND_DATA FindFileData;

HANDLE hFind;

 

printf ("Target file is %s.\n", argv[1]);

 

hFind = FindFirstFile(argv[1], &FindFileData);

 

if (hFind == INVALID_HANDLE_VALUE)

{

printf ("Invalid File Handle. GetLastError reports %d\n",

GetLastError ());

return (0);

}

Else

{

printf ("The first file found is %s\n", FindFileData.cFileName);

FindClose(hFind);

return (1);

}

}

 

 

FindNextFile

Функция продолжает поиск начатый с помощью FindFirstFile.

объявлена в winbase.h.

Объявление:

BOOL FindNextFile(

HANDLE hFindFile, // Указатель на файл из предыдущего поиска

LPWIN32_FIND_DATA lpFindFileData // Информация о файле

);

Со вторым параметром всё ясно, он такой же, как и у FindFirstFile. А вот первый - это указатель на файл из предыдущего поиска. Он нужен, чтобы функция FindNextFile знала на каком файле мы остановили поиск и какой файл надо найти следующим.

FindClose

Функция завершает поиск файлов.

объявлена в winbase.h.

Объявление:

BOOL FindClose(

HANDLE hFindFile // Указатель на последний найденный файл

);

Пример

WIN32_FIND_DATA FindFileData;
HANDLE hFind;

FindFileData.dwFileAttributes=FILE_ATTRIBUTE_NORMAL;
hFind=FindFirstFile("C:\\*.*",&FindFileData);
if (hFind!=INVALID_HANDLE_VALUE){
do{
MessageBox(NULL,FindFileData.cFileName,"",MB_ICONINFORMATION);
while (FindNextFile(hFind,&FindFileData));
FindClose(hFind);
}

 

Пример.Извлечение всех нескрытых файлов ненулевого размера из директории и ее поддиректорий:

 

WIN32_FIND_DATA fd; HANDLE handle;
string strSpec = strPath + "\\*.*";
handle = FindFirstFile(strSpec.c_str(), &fd);
if(handle == INVALID_HANDLE_VALUE)
return;
do {
strSpec = fd.cFileName;
if(strSpec != "." && strSpec != "..")
{
if( !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) )
{
strSpec = strPath + "\\" + strSpec;
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// Выполнение операций с найденными

// strSpec, strFiles


}
else {
if(fd.nFileSizeLow != 0 || fd.nFileSizeHigh != 0) {
strFiles+= strSpec + "\n";
}
}
}
}
} while(FindNextFile(handle, &fd));
FindClose(handle);

 

GetFileSize

Функция возвращает размер файла.

 

объявлена в winbase.h. .

Объявление:

DWORD GetFileSize(

HANDLE hFile, // Указатель на файл

LPDWORD lpFileSizeHigh // Здесь вернут старший байт размера файла

);

В параметре lpFileSizeHigh возвращается только верхние два байта. Нижние два байта вернёт сама функция.

Если всё ОК, то функция возвращает младшие два байта размера файла, иначе возвращает 0xFFFFFFFF.

GetFileType

Функция возвращает тип файла.

 

объявлена в winbase.h. .

Объявление:

DWORD GetFileType(

HANDLE hFile, // Указатель на файл

);

Функция возвращает тип файла. Если всё ОК, то результатом будет:

  • FILE_TYPE_UNKNOWN - тип файла не определён
  • FILE_TYPE_DISK - простой дисковый файл
  • FILE_TYPE_CHAR - консольный файл или LPT-устройство
  • FILE_TYPE_PIPE - именованный или анонимный канал.

ReadFile

Функция читает из файла блок данных начиная с текущей позиции. После прочтения блока, позиция переносится в конец прочитанного блока.

 

объявлена в winbase.h. .

Объявление:

BOOL ReadFile(

HANDLE hFile, // Указатель на открытый файл

LPVOID lpBuffer, // Указатель на буфер, куда поместится прочитанный блок

DWORD nNumberOfBytesToRead, // количество прочитанных байтов

LPDWORD lpNumberOfBytesRead,// указатель на число прочитанных данных

LPOVERLAPPED lpOverlapped // указатель на структуру OVERLAPPED

);

Если всё ОК, то функция вернёт TRUE.

lpOverlapped

[in] Указатель на структуру OVERLAPPED. Эта структура требуется тогда, если параметр hFile создавался с флагом FILE_FLAG_OVERLAPPED.

Если hFile был открыт с флагом FILE_FLAG_OVERLAPPED, у параметра lpOverlapped не должно быть значения ПУСТО (NULL). Он должен указать на структуру OVERLAPPED. Если hFile создавался с флагом FILE_FLAG_OVERLAPPED, а lpOverlapped имеет значение ПУСТО (NULL), функция может неправильно сообщить о завершении операций чтения.

Если hFile был открыт с флагом FILE_FLAG_OVERLAPPED, а lpOverlapped имеет значение не ПУСТО (NULL), операция чтения начинается при смещении, заданном в структуре OVERLAPPED, и ReadFile может возвратить значение прежде, чем операция чтения будет закончена. В этом случае, ReadFile возвращает значение ЛОЖЬ (FALSE), а функция GetLastError возвращает значение ERROR_IO_PENDING. Это дает возможность вызывающему процессу продолжиться, в то время как операция чтения заканчивается. Событие, определяемое в структуре OVERLAPPED устанавливается в сигнальное состояние после завершения операции чтения. Вызывающая программа должна корректировать местоположение указателя позиции в файле после завершения работы.

Функция ReadFile сбрасывает событие, указанное членом hEvent структуры OVERLAPPED в несигнальное состояние, когда она начинает операцию ввода-вывода (I/O). Поэтому, нет необходимости для вызывающей программы, чтобы делать так.

Если hFile не открывался с флагом FILE_FLAG_OVERLAPPED, а lpOverlapped - значение ПУСТО (NULL), операции чтения начинается в текущей позиции файла и ReadFile не возвращает значения до тех пор, пока операция не будет закончена. Система модернизирует указатель позиции в файле после завершения работы.

Если hFile не открывался с FILE_FLAG_OVERLAPPED, а lpOverlapped - не ПУСТО (NULL), операция чтения стартует при смещении, указанном в структуре OVERLAPPED. ReadFile не возвращает значение до тех пор, пока операция чтения не завершилась. Система модернизирует позицию указателя в файле после завершения работы.

Структура OVERLAPPED содержит информацию, используемую в асинхронном (или перекрывающем) вводе и выводе данных (I/O).

Синтаксис typedef struct _OVERLAPPED { ULONG_PTR Internal; ULONG_PTR InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent;

} OVERLAPPED;

Члены структуры

Internal

Зарезервирован для использования операционной системой. Этот член структуры, который определяет системно-зависимое состояние, правильный тогда, когда функция GetOverlappedResult возвращает значение ERROR_IO_PENDING без установки дополнительной информации об ошибке.

InternalHigh

Зарезервирован для использования операционной системой. Этот член структуры, который устанавливает длину переданных данных, правильный тогда, когда функция GetOverlappedResult возвращений значение ИСТИНА (TRUE).

Offset

Местоположение файла, в котором начинается передача. Позиция файла - это смещение байта от начала файла. Вызывающий процесс должен установить этот член структуры перед вызовом функции WriteFile или ReadFile.

Этот член структуры используется только тогда, когда устройство - файл. В противном случае, этот член структуры должен быть нуль.

OffsetHigh

Старшее слово позиции файла, в который начинается передача.

Этот член структуры используется только тогда, когда устройство - файл. В противном случае, этот член структуры должен быть нуль.

hEvent

Дескриптор события, которые должно быть установлено в сигнальное состояние, когда операция завершилась. Вызывающий процесс должен установить в этом члене структуры или нуль, или допустимый дескриптор события перед вызовом любых перекрывающих функций. Чтобы создать объект события, используйте функцию CreateEvent. Эта функция возвращает дескриптор, который может быть использован, чтобы синхронизировать одновременные запросы ввода - вывода (I/O) к устройству.

Функции типа ReadFile и WriteFile устанавливают этот дескриптор в несигнальное состояние прежде, чем они начинают операцию ввода-вывода (I/O). Когда операция завершается, дескриптор устанавливается в сигнальное состояние. В этом случае дескриптор файла может быть проверен с помощью ожидающих функции Wait..

Для проверки завершения операции чтения\записи может использоваться функция GetOverlappedResult. Эта функция обычно используется для проверки результата выполнения асинхронной файловой операции:

 

BOOL GetOverlappedResult(

HANDLE hFile, // идентификатор файла

LPOVERLAPPED lpOverlapped, // адрес структуры OVERLAPPED

LPDWORD lpNumberOfBytesTransferred, // адрес счетчика байт

BOOL bWait); // флаг ожидания

 

Через параметры hFile и lpOverlapped передются, соответственно, идентификатор файла, для которого выполнялась асинхронная операция, и адрес адрес структуры OVERLAPPED, подготовленной перед выполнением операции.

В переменную, адрес которой передается функции через параметр lpNumberOfBytesTransferred, записывается количество действительно прочитанных или записанных байт данных.

Параметр bWait может принимать значения TRUE или FALSE. В первом случае функция GetOverlappedResult будет дожидаться завершения выполнения операции. Если же значение параметра bWait равно FALSE, то если при вызове функции операция еще не завершилась, функция GetOverlappedResult вернет значение FALSE (признак ошибки).

При нормальном завершении (без ошибок) функция GetOverlappedResult возвращает значение TRUE.

Функции типа GetOverlappedResult и функции ожидания сбрасывают автосброс событий в несигнальное состояние. Поэтому, если Вы используете автосброс события, ваше приложение может зависнуть, если Вы ожидаете операцию завершения, чтобы затем вызвать функцию GetOverlappedResult.

Вы можете использовать макрос HasOverlappedIoCompleted, чтобы выяснить, завершилась ли асинхронная операция ввода-вывода (I/O). Вы можете использовать функцию CancelIo, чтобы отменить асинхронную операцию ввода-вывода (I/O).

Стандартная ошибка состоит в том, чтобы многократно использовать структуру OVERLAPPED прежде, чем завершилась предыдущая асинхронная операция. Вам следует использовать отдельную структуру для каждого запроса. Вам следует также создавать объект события для каждого потока, который обрабатывает данные. Если Вы храните дескрипторы событий в массиве, Вы можете легко выждать все события, о которых будет сообщено, используя функцию WaitForMultipleObjects.

CreateFile("my.txt",
GENERIC_READ, //открываем только для чтения
FILE_SHARE_READ, // при этом другим тоже можно открывать на чтение
0,
OPEN_EXISTING, // открыть если файл существует
FILE_FLAG_RANDOM_ACCESS, // произвольный доступ

NULL);

SetFilePointer(0x3C, // устанавливаем смещение0, // старшая часть не нужна
FILE_BEGIN); // с начала файла
ReadFile(h, // что читать
&b, // куда читать - адрес переменной
size, // скока вешать в граммах
&bytesRead, // скока прочиталось на самом деле
0); // OVERLAPPED нам не нужен

Функция ReadFileEx

Функция ReadFileEx читает данные из файла асинхронно. Она предназначена исключительно для асинхронных операций, в отличие от функции ReadFile, которая предназначена и для синхронных, и для асинхронных операций. ReadFileEx позволяет приложению в ходе операции чтения файла исполнять другую работу.

Функция ReadFileEx сообщает о своем состоянии завершения работы асинхронно, вызывая заданную процедуру завершения тогда, когда чтение заканчивается или отменяется, а вызывающий поток находится в готовом к действию режиме ожидания.

Синтаксис

BOOL ReadFileEx(

HANDLE hFile, // дескриптор файла

LPVOID lpBuffer, // буфер данных

DWORD nNumberOfBytesToRead, // число читаемых байтов

LPOVERLAPPED lpOverlapped,



Дата добавления: 2017-01-26; просмотров: 1896;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.051 сек.