Ввод/вывод с использованием функций Windows API

Для тех, кто переходит на Delphi не с прежних версий Turbo Pascal, а с С, других языков или начинает освоение с "нуля", более привычными будут стандартные функции работы с файлами Windows. Тем более, что возможности ввода/вывода в них расширены. Каждый файл в этом наборе функций описывается не переменной, а дескриптором (Handle) — 32-разрядной величиной, которая идентифицирует файл в операционной системе.

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

function CreateFile(IpFileName: PChar; dwDesiredAccess, 

dwShareMode: DWORD; IpSecurityAttributes: PSecurityAttributes;

 dwCreationDistribution, dwFlagsAndAttributes: DWORD; 

hTemplateFile: THandle): THandle;

Хоть ее название и начинается с create, но она позволяет не только создавать, но и открывать уже существующие файлы.

Такое огромное количество параметров оправдано, т. к. createFile используется для открытия файлов на диске, устройств, каналов, портов и вообще любых источников ввода/вывода. Назначение параметров описано в табл. 9.2.

Таблица 9.2. Параметры функции CreateFile

Параметр

Описание

IpFileName:pChar

Имя открываемого объекта. Может представлять собой традиционную строку с путем и именем файла, UNC (для открытия объектов в сети, имя порта, драйвера или устройства)

dwDesiredAccess,:DWORD

Способ доступа к объекту. Может быть равен:

  •  GENERIC READ — для чтения; 

  •  GENERIC WRITE — для записи.

Их комбинация позволяет открыть файл для чтения и записи. Параметр 0 применяется, если нужно получить атрибуты файла без его фактического открытия

dwShareMode:DWORD

Режим совместного использования файла: 

  •  0 — совместный доступ запрещен;

  • FILE SHARE READ — для чтения;

  • FILE_SHARE_WRITE -  для записи.

Их комбинация — для полного совместного доступа

IpSecurityAttributes :PSecurityAttributes

Атрибуты защиты файла. В Windows 95/98 не используются (должны быть равны nil). В Windows NT/2000 этот параметр, равный nil, дает объекту атрибуты по умолчанию

dwCreationDistribution: DWORD;

Способ открытия файла:

  •  CREATE NEW — создается новый файл, если таковой уже существует, функция возвращает ошибку ERROR_ALREADY_EXISTS;
  •  CREATE ALWAYS — создается новый файл, если таковой уже существует, он перезаписывается;
  •  OPEN EXISTING— открывает существующий файл, если таковой не найден, функция возвращает ошибку;
  •  OPEN ALWAYS — открывает существующий файл, если таковой не найден, он создается

dwFlagsAndAttributes: DWORD;

Набор атрибутов (скрытый, системный, сжатый) и флагов для открытия объекта. Подробное описание см. в документации по Win32

hTemplateFile: THandle

Файл-шаблон, атрибуты которого используются для открытия. В Windows 95/98 не используется и должен быть равен 0

Функция createFile возвращает дескриптор открытого объекта ввода/вывода. Если открытие невозможно из-за ошибок, возвращается код INVALID_HANDLE_VALUE, а расширенный код ошибки можно узнать, вызвав функцию GetLastError.

Закрывается файл в Win32 функцией closeHandie (не closeFile, a closeHandle! Правда, "легко" запомнить? Что поделать, так их назвали разработчики Win32).

Приведем из большого разнообразия несколько приемов использования функции CreateFile. Часто программисты хотят иметь возможность организовать посекторный доступ к физическим устройствам хранения — например к дискете. Сделать это не так уж сложно, но при этом методы для Windows 98 и Windows 2000 различаются. В Windows 2000 придется открывать устройство ('\\.\A:'), а в Windows 98 — специальный драйвер доступа (обозначается '\\.\vwin32'). И то и другое делается функцией createFile.

 Листинг 9.1  Чтение сектора с дискеты при помощи функции CreateFile 

type

pDIOCRegs = ^TDIOCRegs;

TDIOCRegs = packed record

rEBX,rEDX,rECX,rEAX,rEDI, rESI, rFlags : DWORD;

end;

const VWIN32_DIOC_DOS_IOCTL = 1;

VWIN32_DIOC_DOS_INT13 = 4; //Прерывание 13

SectorSize = 512;

function ReadSector(Head, Track, Sector: Integer; buffer : pointer; 

Floppy: char):Boolean; 

var hDevice : THandle; 

Regs : TDIOCRegs;

 DevName : string; nb : Integer; 

begin

if WIN32PLATFORM <> VER_PLATFORM_WIN32_NT then

 begin {win95/98} hDevice := CreateFile('\\.\vwin32', GENERIC_READ, 0, nil, 0,

FILE_FLAG_DELETE_ON_CLOSE, 0);

if (hDevice = INVALID_HANDLE_VALUE) then

 begin

Result := FALSE;

Exit; end;

regs.rEDX := Head * $100 + Ord(Floppy in ['b', 'B']);

regs.rEAX := $201; // KOH onepam-iM read sector

regs.rEBX := DWORD(buffer); // buffer

regs.rECX := Track * $100 + Sector;

regs.rFlags := $0;

Result := DeviceloControl(hDevice,VWIN32_DIOC_DOS_INT13,

@regs, sizeof(regs), @regs, sizeof(regs), nb, nil) 

and ((regs.rFlags and $1)=0); CloseHandle(hDevice); 

end {win95/98} 

else

begin // Windows NT/2000 

DevName :='\\.\A:';

if Floppy in ['b', 'B'] then DevName[5] := Floppy;

hDevice := CreateFile(pChar(Devname), GENERIC_READ, FILE_SHARE_READ 

or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

if (hDevice = INVALID_HANDLE_VALUE) then 

begin 

Result := FALSE;

Exit;

end;

SetFilePointer(hDevice, (Sector-1)*SectorSize, nil, FILE_BEGIN); // нумерация с 1

Result := ReadFile(hDevice, buffer';, SectorSize, nb, nil) and (nb=SectorSize);

CloseHandle(hDevice);

end; // Windows NT/2000 

end;

Для чтения и записи данных в Win32 используются функции:

function ReadFile(hFile: THandle; var Buffer; nNumberOfBytesToRead: DWORD; var IpNumberOfBytesRead: DWORD; IpOverlapped: POverlapped): BOOL; function WriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD; var IpNumberOfBytesWritten: DWORD; IpOverlapped: POverlapped): BOOL;

Здесь все сходно с BlockRead и Blockwrite: hFile — это дескриптор файла, Buffer — адрес, по которому будут читаться (писаться) данные; третий параметр означает требуемое число читаемых (записываемых) байтов, а четвертый — фактически прочитанное (записанное). Последний параметр — IpOverlapped — обсудим чуть позже.

Функция createFile используется и для доступа к портам ввода/вывода. Часто программисты сталкиваются с задачей: как организовать обмен данными с различными нестандартными устройствами, подключенными к параллельному или последовательному порту? В Turbo Pascal для DOS был очень хороший псевдомассив Ports: пишешь Port[x] := у; и не знаешь проблем. В Win32 прямой доступ к портам запрещен и приходится открывать их как файлы:

...

hCom := CreateFile('COM2', GENERIC_READ or GENERIC_WRITE,

0, NIL, OPEN_EXISTING, FILE_FLAG__OVERLAPPED, 0) ;

 if hCom = INVALID_HANDLE_VALUE then

begin

raise EAbort.CreateFmt('Ошибка открытия порта: %d*,[GetLastError]);

end;

Самое большое отличие от предыдущего примера — в скромном флаге FILE_FLAG_OVERLAPPED. О роли этих изменений- в следующем разделе

 


Знаете ли Вы, что релятивистское объяснение феномену CMB (космическому микроволновому излучению) придумал человек выдающейся фантазии Иосиф Шкловский (помните книжку миллионного тиража "Вселенная, жизнь, разум"?). Он выдвинул совершенно абсурдную идею, заключавшуюся в том, что это есть "реликтовое" излучение, оставшееся после "Большого Взрыва", то есть от момента "рождения" Вселенной. Хотя из простой логики следует, что Вселенная есть всё, а значит, у нее нет ни начала, ни конца... Подробнее читайте в FAQ по эфирной физике.

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution