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