Define STD_ERROR_HANDLE (DWORD)-12.

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

#define INVALID_HANDLE_VALUE (HANDLE)-1.

Возвращаемые значения функций ReadFile и WriteFile имеют тип BOOL и представляют собой логические значения правильности выполнения функции. Если это значение FALSE, то произошла ошибка. Код этой ошибки можно получить с помощью вспомогательной функции MS Windows, которая называется GetLastError. Эта функция не имеет аргументов и возвращает в качестве собственного значения код ошибки, который можно в дальнейшем анализировать.

Использование описанных выше системных функций иллюстрируется следующим примером:

#include <windows.h>

#include <wincon.h>

#include <stdio.h>

void main()

{char buffer[100]="It was readed ";

int len;

DWORD actlen;

HANDLE hstdin,hstdout;

BOOL rc;

len=strlen(buffer);

hstdout=GetStdHandle(STD_OUTPUT_HANDLE);

if(hstdout==INVALID_HANDLE_VALUE)ExitProcess(0);

hstdin=GetStdHandle(STD_INPUT_HANDLE);

if(hstdin==INVALID_HANDLE_VALUE)ExitProcess(0);

rc=ReadFile(hstdin,buffer+len,80,&actlen,NULL);

if(!rc)ExitProcess(0);

actlen+=len;

WriteFile(hstdout,buffer,actlen,&actlen,0);

getchar();

ExitProcess(0);

}

 

Задание на лабораторную работу:

1. изучить системные функции стандартного ввода-вывода MS Windows.

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

 

 

Лабораторная работа № 2

БАЗОВЫЕ СРЕДСТВА ИСПОЛЬЗОВАНИЯ ФАЙЛОВОЙ СИСТЕМЫ

 

Для полноценного использования файловой системы необходимо иметь средства для работы с любым файлом, указанным внутри программы. Для выполнения чтения из файла или записи в него требуется значение хэндла, связанного с этим файлом. Хэндл файла может быть получен в ОС Windows системной функцией CreateFile. Работа с файлом завершается системной функцией CloseHandle.

Функция CreateFile предназначена и для собственно создания и, в частности, для открытия уже существующего файла. Заметим, что в MS Windows имеется два варианта функции создания и открытия файла, отличающихся последней дополнительной буквой А или W. Первый вариант отвечает использованию кодирования символов по стандарту ANSI, а второй – по стандарту UNICODE. Второй вариант задействует не один, а два байта на каждый символ. На данный момент будем использовать более консервативный вариант ANSI.

Функция CreateFile имеет 7 аргументов, первым из которых является имя открываемого файла, вторым – код желаемого доступа к файлу, третьим – код режима разделяемого использования файла, далее следует адрес атрибутов защиты файла (мы не будем использовать эти довольно не простые возможности и этот аргумент всегда будем полагать равным NULL, т.е. сообщать ОС об отсутствии информации о защите файла). Пятый аргумент задает поведение ОС при открытии файла (диспозицию), шестой – атрибуты файла, а последний имеет специальный характер и рассматриваться нами не будет (значение этого аргумента будем указывать как NULL). При удачном выполнении операции функция CreateFile возвращает значение хэндла файла, а при ошибке выдает вместо него значение, задаваемое символической константой INVALID_HANDLE_VALUE. На языке Си прототип функции CreateFileA записывается в виде

HANDLE CreateFile(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAttributes, HANDLE hTemplateFile);

где lpFileName задает указатель на имя файла, dwDesiredAccess – код желаемого доступа, dwShareMode – код режима разделения работы с файлом, lpSecurityAttributes – указатель на атрибут защиты файла, dwCreationDisposition – код действия над файлом во время выполнения данной функции, dwFlagsAttributes – флаги атрибутов, hTemplateFile – хэндл файла шаблона с расширенными атрибутами.

Параметр dwFlagsAttributes задает атрибут открываемого файла. В этом атрибуте используются отдельные биты. Обычный (нормальный) файл имеет атрибут, равный 0, файл, доступный только для чтения – атрибут 1, скрытый файл – атрибут, равный 2, системный файл – атрибут, равный 4. Чаще всего в качестве этого параметра можно использовать символическую константу FILE_ATTRIBUTE_NORMAL. Для кодирования доступа к открываемому файлу служат две символические константы GENERIC_READ и GENERIC_WRITE, задающих соответственно разрешение на чтение и запись в файл. Они могут использоваться совместно, путем объединения (операцией логического ИЛИ) в одном параметре dwDesiredAccess , или раздельно. Совместное использование файлов задается символическим константами FILE_SHARE_READ и FILE_SHARE_WRITE, которые также при необходимости можно комбинировать в одном параметре. Для задания действий с файлом служат символические константы CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXISTING, которые нельзя комбинировать в одном параметре dwCreationDisposition , а следует использовать порознь. Константа CREATE_NEW приводит к тому, что если заданный файл уже существует, то функция возвращает ошибку. Константа CREATE_ALWAYS требует создания файла всегда, даже взамен существующего, при этом содержимое старого файла теряется. Константа OPEN_EXISTING требует открывать только существующий файл, если при этом файл с указанным именем не существует, то функция возвращает ошибку. Константа OPEN_ALWAYS приводит к тому, что существующий файл открывается, а если файл не существует, то он создается. Константа TRUNCATE_EXISTING приводит к следующим действиям: если файл существует, то он открывается, после чего длина файла устанавливается равной нулю, содержимое файла при этом теряется; если же файл не существовал, то функция возвращает ошибку.

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

BOOL CloseHandle(HANDLE hObject),

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

Пример использования рассмотренных функций иллюстрирует следующий пример:

#include <windows.h>

#include <wincon.h>

#include <stdio.h>

#define METHOD 0

void main()

{char buffer[100]="1234567890It was readed";

int len;

DWORD cb,cbwl;

HANDLE hstout,fhandle;

char fname[]="myresult.txt";

BOOL rc;

len=strlen(buffer);

hstout=GetStdHandle(STD_OUTPUT_HANDLE);

if(hstout==INVALID_HANDLE_VALUE)ExitProcess(0);

fhandle=CreateFile(fname, GENERIC_READ, FILE_SHARE_READ,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);

if(fhandle==NULL)ExitProcess(0);

rc=SetFilePointer(fhandle,10,0,METHOD);

if(rc==NULL)ExitProcess(0);

rc=ReadFile(fhandle,buffer,80,&cb,NULL);

if(!rc)ExitProcess(0);

cb+=len;

WriteFile(hstout,buffer,cb,&cbwl,NULL);

CloseHandle(fhandle);

getchar();

ExitProcess(0);

}

Следующей по значимости для работы с файлами является функция позиционирования SetFilePointer, имеющая на языке Си следующий прототип

DWORD WINAPI SetFilePointer(HANDLE hFile, LONG ib, PLONG lpDistanceToMoveHigh, DWORD metod);

Где hFile – хэндл позиционируемого файла, ib – количество байтов, на которое будет перемещена текущая позиция относительно точки отсчета (младшие 32 бита), metod – метод отсчета смещения в файле, lpDistanceToMoveHigh – адрес старшего слова размещения числа байтов, на которые требуется переместить текущую позицию в файле (при использовании файлов меньше 4 Гбайт этот параметр не используется – задается как NULL). Результирующая позиция после перемещения выдается функцией в качестве значения типа DWORD. При ошибке функция возвращает значение –1. Метод отсчета задается символическими константами FILE_BEGIN, FILE_CURRENT, FILE_END, которые определены в заголовочном файле.

Следующий пример иллюстрирует использование позиционирования файла

#include <windows.h>

#include <wincon.h>

#include <stdio.h>

#define METHOD 0

void main()

{char buffer[100]="1234567890It was readed";

int len;

DWORD cb,cbwl;

HANDLE hstout,fhandle;

char fname[]="myresult.txt";

BOOL rc;

len=strlen(buffer);

hstout=GetStdHandle(STD_OUTPUT_HANDLE);

if(hstout==INVALID_HANDLE_VALUE)ExitProcess(0);

fhandle=CreateFile(fname, GENERIC_READ, FILE_SHARE_READ,0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);

if(fhandle==NULL)ExitProcess(0);

rc=SetFilePointer(fhandle,10,0,METHOD);

if(rc==NULL)ExitProcess(0);

rc=ReadFile(fhandle,buffer,80,&cb,NULL);

if(!rc)ExitProcess(0);

cb+=len;

WriteFile(hstout,buffer,cb,&cbwl,NULL);

CloseHandle(fhandle);

getchar();

ExitProcess(0);

}

Задание на лабораторную работу:

1. изучить системные функции ввода-вывода и позиционирования в файлах MS Windows.

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

 

Лабораторная работа № 3