Программирование для Windows NT (том 2)

       

Установка соединения с каналом со стороны клиента


Для создания канала клиентский процесс может воспользоваться функцией CreateFile. Как вы помните, эта функция предназначена для работы с файлами, однако с ее помощью можно также открыть канал, указав его имя вместо имени файла. Забегая вперед, скажем, что функция CreateFile позволяет открывать не только файлы или каналы Pipe, но и другие системные ресурсы, например, устройства и каналы Mailslot.

Функция CreateFile была нами описана в предыдущем томе “Библиотеки системного программиста”, однако для удобства мы повторим прототип этой функции и ее краткое описание:

Итак, прототип функции CreateFile:

HANDLE CreateFile(

  LPCTSTR lpFileName,     // адрес строки имени файла

  DWORD  dwDesiredAccess, // режим доступа

  DWORD  dwShareMode, // режим совместного использования файла

  LPSECURITY_ATTRIBUTES lpSecurityAttributes, // дескриптор

                                              // защиты

  DWORD  dwCreationDistribution, // параметры создания

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

  HANDLE hTemplateFile);  // идентификатор файла с атрибутами

Раньше при работе с файлами через параметр lpFileName вы передавали этой функции адрес строки, содержащей имя файла, который вы собираетесь создать или открыть. Строка должна быть закрыта двоичным нулем. Если функция CreateFile работает с каналом Pipe, параметр lpFileName определяет имя канала.

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



Константа

Описание

0

Доступ запрещен, однако приложение может определять атрибуты файла, канала или устройства, открываемого при помощи функции CreateFile

GENERIC_READ

Разрешен доступ на чтение из файла или канала Pipe

GENERIC_WRITE

Разрешен доступ на запись в файл или канал Pipe

Тип доступа, указанный при помощи параметра dwDesiredAccess, не должен противоречить типу доступа для канала, заданного при его создании функцией CreateNamedPipe.


С помощью параметра dwShareMode задаются режимы совместного использования открываемого или создаваемого файла. Для этого параметра вы можете указать комбинацию следующих констант:

Константа

Описание

0

Совместное использование файла запрещено

FILE_SHARE_READ

Другие приложения могут открывать файл с помощью функции CreateFile для чтения

FILE_SHARE_WRITE

Аналогично предыдущему, но на запись

Через параметр lpSecurityAttributes необходимо передать указатель на дескриптор защиты или значение NULL, если этот дескриптор не используется. В наших приложениях мы не работаем с дескриптором защиты.

Параметр dwCreationDistribution определяет действия, выполняемые функцией CreateFile, если приложение пытается создать файл, который уже существует. Для этого параметра вы можете указать одну из следующих констант:

Константа

Описание

CREATE_NEW

Если создаваемый файл уже существует, функция CreateFile возвращает код ошибки

CREATE_ALWAYS

Существующий файл перезаписывается, при этом содержимое старого файла теряется

OPEN_EXISTING

Открывается существующий файл. Если файл с указанным именем не существует, функция CreateFile возвращает код ошибки

OPEN_ALWAYS

Если указанный файл существует, он открывается. Если файл не существует, он будет создан

TRUNCATE_EXISTING

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

Параметр dwFlagsAndAttributes задает атрибуты и флаги для файла.

При этом можно использовать любые логические комбинации следующих атрибутов (кроме атрибута FILE_ATTRIBUTE_NORMAL, который можно использовать только отдельно):

Атрибут

Описание

FILE_ATTRIBUTE_ARCHIVE

Файл был архивирован (выгружен)

FILE_ATTRIBUTE_COMPRESSED

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

FILE_ATTRIBUTE_NORMAL

Остальные перечисленные в этом списка атрибуты не установлены

FILE_ATTRIBUTE_HIDDEN

Скрытый файл

FILE_ATTRIBUTE_READONLY

Файл можно только читать

FILE_ATTRIBUTE_SYSTEM

Файл является частью операционной системы

<


В дополнение к перечисленным выше атрибутам, через параметр dwFlagsAndAttributes вы можете передать любую логическую комбинацию флагов, перечисленных ниже:

Флаг

Описание

FILE_FLAG_WRITE_THROUGH

Отмена промежуточного кэширования данных для уменьшения вероятности потери данных при аварии

FILE_FLAG_NO_BUFFERING

Отмена промежуточной буферизации или кэширования. При использовании этого флага необходимо выполнять чтение и запись порциями, кратными размеру сектора (обычно 512 байт)

FILE_FLAG_OVERLAPPED

Асинхронное выполнение чтения и записи. Во время асинхронного чтения или записи приложение может продолжать обработку данных

FILE_FLAG_RANDOM_ACCESS

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

FILE_FLAG_SEQUENTIAL_SCAN

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

FILE_FLAG_DELETE_ON_CLOSE

Файл будет удален сразу после того как приложение закроет его идентификтор. Этот флаг удобно использовать для временных файлов

FILE_FLAG_BACKUP_SEMANTICS

Файл будет использован для выполнения операции выгрузки или восстановления. При этом выполняется проверка прав доступа

FILE_FLAG_POSIX_SEMANTICS

Доступ к файлу будет выполняться в соответствии со спецификацией POSIX

И, наконец, последний параметр hTemplateFile предназначен для доступа к файлу шаблона с расширенными атрибутами создаваемого файла.

В случае успешного завершения функция CreateFile возвращает идентификатор созданного или открытого файла (или каталога), а при работе с каналом Pipe - идентификатор реализации канала.

При ошибке возвращается значение INVALID_HANDLE_VALUE (а не NULL, как можно было бы предположить). Код ошибки можно определить при помощи функции GetLastError.

В том случае, если файл уже существует и были указаны константы CREATE_ALWAYS или OPEN_ALWAYS, функция CreateFile не возвращает код ошибки. В то же время в этой ситуации функция GetLastError возвращает значение ERROR_ALREADY_EXISTS.

Приведем фрагмент исходного текста клиентского приложения, открывающего канал с именем $MyPipe$ при помощи функции CreateFile:

char   szPipeName[256];

HANDLE hNamedPipe;

strcpy(szPipeName, "\\\\.\\pipe\\$MyPipe$");

hNamedPipe = CreateFile(

    szPipeName, GENERIC_READ | GENERIC_WRITE,

    0, NULL, OPEN_EXISTING, 0, NULL);

Здесь канал открывается как для записи, так и для чтения.


Содержание раздела