Файловый ввод-вывод в Win32
В этом разделе будут приведены минимальные сведения, необходимые для выполнения простых операций с файлами. В отличие от MS DOS среда Win32 способна поддерживать несколько файловых систем. Главные требования к этим системам — иерархичность и соблюдение определенных правил присвоения имен каталогам и файлам.
Перечислим функции API Win32, имеющие отношение к работе с файловой системой. Полное их описание можно получить в MSDN.
Функция |
Назначение |
AreFileApisANSI |
Определение набора символов файла — ANSI или OEM |
CancelIo |
Отменить все ждущие обработки операции (I/O) ввода и вывода |
CloseHandle |
Закрыть открытый дескриптор файла |
CopyFile, CopyFileEx CopyProgressRoutine |
Копирование cуществующего файла в новый |
CreateDi rectory, CreateDirectoryEx |
Определенная приложением функция обратного вызова, используемая с функциями CopyFileEx и MoveFileWithProgress. Она вызывается, когда завершается часть операции копирования или пересылки |
CreateFile |
Создать каталог |
DefineDosDevice |
Создать файл или объект специального типа |
DeleteFile |
Определить, переопределить или удалить имена устройства MS DOS |
FindCiose |
Удалить файл |
Fi ndCloseChangeNoti fi cati on |
Закрыть указанный поисковый дескриптор (см. функции FindFirstFile и FindNextFile) |
FindFi rstChangeNoti fication |
Закрыть объект-уведомление об изменении файла |
FindFirstFile, FindFirstFileEx, FindNextFile |
Создать объект-уведомление об изменении файла |
F1ndNextChangeNoti fi cati on |
Поиск файлов |
FlushFileBuffers |
Сброс объекта-уведомления в занятое состояние |
GetBinaryType |
Очистка буфера для указанного файла и запись всех буферизированных данных в файл |
GetCurrentDirectory |
Определить, является ли файл исполняемым, и если это так, то для какой подсистемы — Win32, MS DOS, OS/2, POSIX и т. д. |
GetDiskFreeSpace, GetDiskFreeSpaceEx |
Получить текущий каталог |
GetDriveType |
Информация относительно указанного диска, включая количество свободного пространства на нем |
GetFileAttributes, GetFileAttributesEx |
Определить тип диска — съемный, фиксированный, CD-ROM, электронный или сетевой |
GetFi1elnformati onByHandle |
Получить атрибуты файла или каталога |
GetFi1eSi ze, GetFi1eSi zeEx |
Найти информацию относительно указанного файла |
GetFileType |
Получить размер указанного файла |
GetFullPathName |
Получить тип указанного файла |
GetLogical Drives, GetLogi calDri veStri ngs |
Получить полный путь и имя для указанного файла |
GetLongPathName |
Определить доступные в настоящее время дисководы |
GetShortPathName |
Преобразовать указанный путь к его длинной форме |
GetTempFileName |
Получить псевдоним файла |
GetTempPath |
Создать имя для временного файла |
LockFile, LockFileEx |
Получить путь каталога для временных файлов Блокировка файла |
Далее на примерах конкретных программ разберемся с тем, как использовать в программах на ассемблере наиболее интересные и часто применяемые функции из перечисленных выше для работы с файлами API Win32. В целях экономии места все примеры реализованы в виде консольных приложений. Основное внимание уделено не полноте описания параметров для вызова той или иной функции и результатов ее работы (эту информацию можно найти в справочниках по функциям API), а деталям практической реализации файловых операций в программах на языке ассемблера. Для изучения подробностей работы функций API Win32 необходимо использовать какой-либо отладчик для Windows, напри-MepTD32.EXE.
Обработка ошибок
Прежде чем рассматривать функции API Win32, относящиеся к файловому вводу-выводу, отметим, как можно выяснить причину их ошибочного завершения. Для этого Windows предоставляет функцию GetLastError.
DWORD GetLastError(void):
Для вызова функции GetLastError не нужно передавать никаких параметров. Эту функцию необходимо вызывать сразу после функции API Win32, успешность работы которой мы проверяем.
;.........
push offset info
push hFile
call GetFilelnformationByHandle
call GetLastError ;в регистре ЕАХ возвращается код ошибки
В регистре ЕАХ возвращается код ошибки. Расшифровать его можно с помощью файла Winerror.h, где вместе с кодами ошибок приведены короткие сообщения о причине их возникновения.
Создание, открытие, закрытие и удаление файла
Создание и открытие файла в Win32 производится одной функцией CreateFile. HANDLE CreateFi1eCLPCTSTR ipFileName, DWORD dwDesiredAccess. DWORD dwShareMode. LPSECURITY_ATTRIBUTES ipSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes. HANDLE hTemplateFile):
Параметры данной функции имеют размер двойного слова. Их назначение следующее (параметры описаны в порядке, обратном их записи в стек):
- lpFileName — указатель на ASCIIZ-строку с именем (путем) открываемого
или создаваемого файла;
- dwDesiredAccess — тип доступа к файлу:
- GENERICREAD = 80000000b - доступ по чтению;
- GENERIC_WRITE = 40000000b - доступ по записи;
- GENERIC_READ+GENERIC_WRITE = 0C0000000h - доступ по чтению-записи;
- DwShareMode — режим разделения файлов между разными процессами, данный параметр может принимать значения:
0 — монополизация доступа к файлу;
- FILE_SHARE_READ = 0000000th — другие процессы могут открыть файл, но только по чтению, запись в файл монополизирована процессом, открывшим файл;
FILESHAREWRITE = 00000002b — другие процессы могут открыть файл, но только по записи, чтение в файл монополизировано процессом, открывшим файл;
- FILE_SHARE_READ+FILE_SHARE_WRITE = 00000003b - другие процессы могут
открывать файл по чтению-записи;
- IpSecurityAttributes — указатель на структуру SecurityAttributes (файл winbase.h), определяющую защиту связанного с файлом объекта ядра, при отсутствии защиты заносится NULL;
ш dwCreationDistribution — определяет действия для случаев, когда файл существует или не существует (аналог этого параметра используется при
вызове описанных выше функций MS DOS 6ch и 716ch), данный параметр может принимать значения:
- CREATE_NEW= 1 — создать новый файл, если файл не существует; если файл существует, то функция завершается формированием ошибки;
- CREATE_ALWAYS=2 — создать новый файл, если файл не существует; если он существует, то заместить новым;
- 0PEN_EXISTING=3 — открыть файл, если он существует; если файл не существует, то формируется ошибка;
- 0PEN_ALWAYS=4 — открыть файл при его существовании и создать его если файла нет;
TRUNCATE_EXISTING=5 — открыть файл с усечением его до нулевой длины; если файл не существует, то формируется ошибка;
DwFlagsAndAttributes — флаги и атрибуты; этот параметр используется для задания характеристик создаваемого файла:
- FILE_ATTRIBUTE_READ0NLY=OOOO0OOlh - файл только для чтения;
- FILE_ATTRIBUTE_HIDDEN=00000002h - скрытый файл;
- FILE_ATTRIBUTE_SYSTEM=00000004h - системный файл;
- FILE_ATrRIBUTE_DIRECTORY=OO0000lOh - каталог;
- FILE ATTRIBUTE ARCHIVE=00000020h - архивный ф'айл;
- FILE_ATTRIBUTE_N0RMAL=00000080h - обычный файл для чтения-записи (этот атрибут нельзя комбинировать с другими);
- FILE_ATTRIBUTE_TEMPORARY=0000Ol00h - создается временный файл (преимущество этого файла в том, что система стремится не записывать этот файл на диск, а работать с ним в памяти; этот атрибут выгодно комбинировать с флагом FILE_FLAG_DELETE_ON_CLOSE, тогда после закрытия файла в программе он будет удален, не оставив следов на диске, иначе, как и bMS DOS, программе придется «подчищать» за собой содержимое диска);
- FILE_FLAG_WRITE_THR0UGH=80000000h - не использовать промежуточное кэширование при записи на диск, а все изменения записывать прямо на диск;
- FILE_FLAG_NO_BUFFERING=20000000h - не использовать средства буферизации операционной системы;
- FILE_FLAG_RANDOM_ACCESS=10000000h - прямой доступ к файлу (установка этого флага или флага
- ILE_FLAG_SEQUENTIAL_SCAN позволяет оптимизировать системе процесс кэширования);
- FILE_FLAG_SEQUENTIAL_SCAN=08000000h - последовательный доступ к файлу; 0
- ILE_FLAG_DELETE_0N_CL0SE=04000000h - удалить файл после его закрытия (см. описание атрибута
- ILEATTRIBUTETEMPORARY);
- FILE_FLAG_0VERLAPPED=40000000h - асинхронный доступ к файлу (синхронность означает то, что программа, вызвавшая функцию для доступа к файлу, приостанавливается до тех пор, пока не закончит работу функция ввода-вывода);
- hTemplateFile — параметр используется только при создании нового файла, его значением является дескриптор другого существующего и предварительно открытого файла, а новый файл создается с теми же значениями атрибутов и флагов, что и у файла, дескриптор которого указан в параметре hTemplateFile.
При удачном завершении функция возвращает в регистре ЕАХ дескриптор нового файла. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
Закрытие файла
Закрытие файла производится функцией Cl oseHandl e:
B00L C1oseHandle( HANDLE hObject );
Функция имеет один параметр размером в двойное слово — дескриптор, полученный при открытии файла функцией CreateFile.
При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
Win32 поддерживает несколько функций для часто используемых операций над файлами: копирование, перемещение и переименование файлов.
Копирование файла
Для копирования файлов в Win32 используется функция CopyFile:
B00L CopyFile(LPCTSTR lpExistingFileName. LPCTSTR ipNewFileName. B00L bFailIfExists): Параметрами этой функции являются:
- lpExistingFileName — указатель на ASCIIZ-строку с именем файла-источника;
- lpNewFileName — указатель на ASCIIZ-строку с именем файла-приемника,
который может и не существовать;
- bFailIfExists — параметр, задаваемый равным 0 или 1, в зависимости от условий копирования:
- 0 — при наличии файла он удаляется и создается новый с содержимым
файла-источника;
- 1 — при наличии файла копирование не производится, а функция CopyFile
возвращает ошибку.
При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
;prg07_29.asm - Win32-nporpaMMa консольного приложения для исследования
;работы функции CopyFile API Win32.
;..........................................................
.data
TitleText db 'Копирование файлов в Win32'.О
s_file db "p".O ;имя входного файла
d_file db "pi".0 ;имя выходного файла
.code
mov eax.l
push eax
push offset d_file
push offset s_file
call CopyFileA
cmp eax.O
jz exit .выход в случае неудачи
:.........
Перемещение файла
Для перемещение файла Win32 содержит две функции MoveFile и MoveFi 1 еЕх:
BOOL MoveFile(LPCTSTR lpExistingFileName, LPCTSTR lpNewFileNam):
BOOL MoveFileEx(LPCTSTR TpExistingFileName. LPCTSTR ipNewFileName. DWORD dwFlags):
Параметрами функции MoveFile являются указатели на ASCIIZ-строки с именами файла-источника и файла-приемника. Функция MoveFi 1 еЕх обладает дополнительными свойствами благодаря наличию третьего параметра, который определяет особенности перемещения:
- MOVEFILE REPLACE_EXISTING=00000001h - при существовании целевого файла он замещается содержимым файла-источника;
- MOVEFILE_COPY_AL10WED=00000002h - если не указывать специально, то
- функция MoveFi 1 еЕх не перемещает файлы на другой диск, а если перемещение требуется, необходимо устанавливать этот флаг; .
- MOVEFILE_DELAY_UNTIL_REBOOT=00000004h - (только для Windows NT и выше) файл-источник не удаляется до перезагрузки системы;
- MOVEFILE_WRITE_THROUGH=00000008h — установка флага гарантирует, что возврат из функции не произойдет до фактического перемещения и удаления файла.
Кроме этого, функция MoveFi 1 еЕх допускает указание на месте второго параметра значения NULL, тем самым моделируя вызов функции Del eteFi I e.
При удачном завершении функции MoveFile и MoveFi 1 еЕх возвращают ненулевое значение в регистре ЕАХ. В случае неудачи функции возвращают в регистре ЕАХ значение NULL.
:prg07_30.asm - Win32-nporpaMMa консольного приложения для исследования :работы функции MoveFile(Ex) API Win32.
:
.data
TitleText db 'Перемещение файлов в Win32'.О
s_file db "p",0 ;имя входного файла
d_file db "pi".0 :имя выходного файла
.code
:.........
push offset d_file
push offset s_file
call MoveFileA
cmp eax.O
jz exit :выход в случае неудачи
Переименование файла
Специальной функции для переименования файла нет, так как она и не нужна — перемещение файла в пределах одного каталога по сути и является его переименованием.
Удаление файла
Для удаления файла применяется функция Del eteFi I e:
BOOL DeleteFile(LPCTSTR TpFileName);
У нее единственный параметр — указатель на ASCIIZ-строку с именем (путем) удаляемого файла. Перед удалением файл необходимо закрыть, хотя в некоторых версиях Windows это не является обязательным.
При удачном завершении функция возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
Чтение, запись, позиционирование в файле
Необходимо сразу отметить, что Win32 допускает два режима доступа к файлу — синхронный и асинхронный. Необходимость введения этих двух режимов в архитектуру Win32 вызвано тем, что файловый ввод-вывод относится к наиболее медленным операциям и способен значительно ухудшить впечатление от компьютера с хорошей центральной частью (процессором и материнской платой) и плохой дисковой подсистемой. Поэтому разработчики Win32 уделяют много внимания моделированию файловых операций с использованием памяти компьютера. Это и упомянутые выше временные файлы и гибкая система кэширования вводимых и выводимых данных, а также файлы, отображенные в память, работу с которыми мы рассмотрим в конце данного раздела. Наше дальнейшее изложение будет посвящено организации синхронного ввода-вывода. Для обычных несложных приложений Win32 его вполне достаточно.
Установка текущей файловой позиции
Доступ к содержимому файла может быть произвольным (прямым) и последовательным. Как обычно, функции ввода-вывода работают с файловым указателем. Но необходимо иметь в виду, что файловый указатель связан только с описателем файла. Его значение равно текущему номеру позиции в файле, с которой будет'производиться чтение-запись данных при очередном вызове функции ввода-вывода. В первый момент после открытия значение указателя равно 0, то есть он указывает на начало файла. Функции, производящие чтение-запись в файле, меняют значение файлового указателя на количество прочитанных или записанных байт. При необходимости, а при организаций прямого доступа к файлу без этого не обойтись, значение файлового указателя можно изменять с помощью функции SetFilePointer:
DWORD SetFilePointer( HANDLE hFile, LONG IDistanceToMove. PLONG lpDistanceToMoveHigh. DWORD dwMoveMethod );
Параметры этой функции имеют размер двойного слова и следующее назначение: cmp eax.O
jz exit :если неуспех
eld
mov edi,p_start
mov esi.p_start
mov ecx.FileSize cycl: moval.Odh repne scasb
cmp byte ptr [edi].0ah
jne $-5
inc edi
dec ecx
jeexz exit :весь файл прочитан
mov eax.edi
sub eax.esi :в еах - длина строки для вывода на экран, а в esi - ее адрес ;вывести очередную строку
call WriteConsoleA
cmp eax,0
jz exit :если неуспех
add esi,eax
jmp cycl закрываем файлы exit: :выход из приложения
return: ¦
При небольшой модификации программы можно построчно выводить содержимое любого текстового файла. Для небольших файлов совсем необязательно отслеживать конец каждой строки — можно выводить из буфера сразу весь файл одним вызовом функции WriteConsoleA.
Получение и изменение атрибутов файла
Аналогично группе функций MS DOS для работы с файловой системой файловая подсистема Win32 содержит ряд функций, с помощью которых можно определить характеристики конкретного файла.
Начальные значения атрибутов файла назначаются при создании файла. Впоследствии их можно изменить вызовом функции SetFi I eAttributes.
BOOL SetFileAttributestLPCTSTR ipFileName. DWORD dwFi1eAttributes);
Параметры этой функции означают следующее:
ш ipFileName — указатель на ASCIIZ-строку, содержащую имя файла;
Ш dwFil eAttri butes — двойное слово, определяющее, какие атрибуты файла могут быть установлены.
Планируя использование этой функции, необходимо иметь в виду, что не все возможные атрибуты файлов могут быть установлены с ее помощью. Перечислим те атрибуты, комбинацию которых можно задавать для изменения атрибутов файла, специфицированного параметром lpFileName: FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTENORMAL,
FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_
SYSTEM, FILEATTRIBUTETEMPORARY.
При удачном завершении функция SetFi 1 eAttri butes возвращает ненулевое значение в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
Для получения атрибутов файла используется функция GetFil eAttri butes.
DWORD GetFileAttributes(LPCTSTR lpFileName):
Функция имеет один параметр lpFileName, который является указателем на ASCIIZ-строку, содержащую имя файла.
При удачном завершении функция GetFil eAttri butes возвращает значение в регистре ЕАХ, которое является комбинацией атрибутов файла, специфицированного параметром lpFileName. Выделить эти атрибуты можно, используя логические команды ассемблера или команды обработки битов. В случае неудачи функция возвращает в регистре ЕАХ значение NULL.
В приложениях очень часто требуется определить размер файла. Для этого Win32 содержит отдельную функцию GetFileSize. DWORD GetFileSize( HANDLE hFile, LPDWORD lpFileSizeHigh ): Параметры функции означают следующее:
- hFile — дескриптор файла, размер которого требуется определить;
- lpFileSizeHigh — адрес области памяти, куда помещаются старшие 32 бита значения размера файла, младшие 32 бита возвращаются функцией в регистре ЕАХ.
При удачном завершении функция GetFil eSize возвращает значение младших 32 бит размера файла в регистре ЕАХ. В случае неудачи функция возвращает в регистре ЕАХ значение Offffffffh.
Особого разговора заслуживают возможности получения информации о временных характеристиках файлов. По сравнению с аналогичными средствами MS DOS в Win32 этот вопрос проработан значительно глубже. Хотя если посмотреть номенклатуру и описание функций MS DOS для работы с длинными именами файлов, то видно, что у них уже есть общие идеи, реализованные рассматриваемыми ниже функциями Win32.
Как уже отмечалось выше, в Win32 с файлом связаны три значения времени: время создания, время последнего доступа и время последней модификации. Получить эти значения можно с помощью функции GetFileTime.
BOOL GetFileTime( HANDLE hFile, LPFILETIME ipCreationTime. LPFILETIME ipLastAccessTime,
LPFILETIME ipLastWhteTime);
Перед вызовом данной функции, необходимо открыть файл, о значениях времени которого мы хотим получить информацию. Функции GetFileTime передается дескриптор этого файла и указатели на три экземпляра структуры FILETIME, в которые будут записаны время создания (IpCreationTime), время последнего доступа (lpLastAccessTime) и время последней записи (lpLastWriteTime).
Аналогично функции MS DOS 71a7h Win32 предоставляет две функции для взаимного преобразования DOS-времени файла в 64-битное представление времени:
BOOL FileTimeToDosDateTime(CONST FILETIME *lpFileTime, LPWORD lpFatDate.
LPWORD ipFatTime): BOOL DosDateTimeToFileTimetWORD wFatDate.
WORD wFatTime. LPFILETIME ipFiieTime);
Функция FileTimeToDosDateTime в качестве входного параметра принимает указатель *lpFi1eTime на экземпляр структуры FILETIME. Этот указатель содержит представление времени в виде 64-битного значения. На выходе данная функция формирует два значения в переменных размером в слово, адреса которых указаны параметрами lpFatDate и lpFatTime. Формат этих слов совпадает с форматом соответствующих параметров, которыми манипулирует функция 71a7h.
Функция DosDateTimeToFileTime, наоборот, преобразует время в формате DOS представленное в виде двух слов wFatDate, wFatTime (для времени и даты соответственно), в 64-битное значение 1 pFi I eTime.
Установить время создания, последнего доступа или модификации файлов можно с помощью функции SetFileTime.
BOOL SetFileTime( HANDLE hFile. const FILETIME *lpCreationTime.
const FILETIME *lpLastAccessTime, const FILETIME *lpLastWriteTime ):
В качестве входных параметров функция SetFil eTime принимает указатели на три экземпляра структуры FILETIME и дескриптор файла. Экземпляры структур уже заполнены необходимыми значениями времени. Если какое-либо из значений устанавливать не нужно, то вместо указателя на соответствующую структуру передается NULL. В случае успешного завершения функция возвращает ненулевое значение в регистре ЕАХ.
Из вышеизложенного видно, что для получения различных характеристик файла используются множество различных функций. Работа с ними может утомить кого угодно. Нельзя ли чего-нибудь попроще? Можно. Win32 предоставляет функцию GetFi I elnformationByHandl e:
BOOL GetFileInformationByHandle( HANDLE hFile.
LPBY_HANDLE_FILE_INFORMATION lpFilelnformation );
На вход данной функции передается дескриптор файла, о котором необходимо получить Информацию, и указатель на экземпляр структуры BYHANDLEFI LE_ INFORMATION, который заполняется этой функцией. Как видно из названия полей (см. код ниже), в этой структуре сосредоточена вся информация о файле. Ниже приведен пример кода, использующего данную структуру.
;prg07_32.asm - Win32-nporpaMMa консольного приложения для
Win32 для исследования работы
функции GetFilelnformationByHandle API Win32.
;описание структур
FILETIME struc
DwLowDateTime dd ? ;младшие 32 бита значения времени
DwHighDateTime dd ? :старшие 32 бита значения времени
FILETIME ends
BY_HANDLE_FILE_INFORMATION struc
DwFileAttributes dd 0 атрибуты файла
struc
FtCreationTime_DwLowDateTime dd ? ;младшие 32 бита
значения времени создания файла FtCreationTime_
DwHighDateTiirie dd ? :старшие 32 бита значения времени создания файла
ends
struc
FtLastAccessTime_DwLowDateTime dd ? ;младшие 32 бита значения времени поел,
доступа FtLastAccessTime_DwHighDateTime dd ? :старшие 32 бита значения времени поел, доступа
ends
struc
^¦LastWriteTime_DwLowOateTime dd ? :младшие 32 бита значения времени поел, записи
^¦LastWnteTimeJDwHighDateTime dd ? :старшие 32 бита значения времени поел, записи ends
. .".-rialNumber dd С ;серийный номер тома, на котором находится файл
| nfTleSizeHigh d
d 0 :старшие 32 бита размера файла ¦nFiieSizeLow dd 0
:младшие 32 бита размера файла I nNumberOftinks dd 0 ;
число ссылок на файл | nFilelndexHigh dd 0 ;старшие 32 бита идентификатора файла nFilelndexLow dd 0 ; младшие 32 бита идентификатора файла
ends .data
t info BY_HANDLE_FILE_INFORMATION <> TitleText db 'Получение информации о файле в
Win32',О lpBuf db "p",0 I hFile dd 0 .code
¦-------------------------------------CreateFi 1 e
Нгкрываем файл
push О
push 0 -.атрибуты (они игнорируются)
push OPEN_EXISTING :открыть существующий файл, если его нет - ошибка
push 0 : защита файла не требуется
push FILE_SHARE_READ разрешено совместное использование файла (по чтению)
push GENERIC_READ разрешено чтение из файла
push offset lpBuf
call CreateFileA
emp eax.Offffffffh
je exit :если неуспех
mov hFile.eax :дескриптор файла №
GetFilelnformationByHandle
push offset info
push hFile
call GetFilelnformationByHandle
emp eax.O
jz exit :выход в случае неудачи ¦"^
результат смотрим в отладчике TD32.exe
Результат работы данной программы можно посмотреть и проанализировать в отладчике.
Работа с дисками, каталогами и организация поиска файлов
Win32 располагает большим набором функций для получения информации о структуре файловой системы конкретного компьютера. Часть этих функций раз-вивает идеи работы с файловой подсистемой, появившиеся в последних версиях WAS DOS. Другие функции являются уникальными для платформы Win32. Рас-Рассмотрим наиболее интересные из них.
Программа, предназначенная для исследования файловой системы, прежде всего должна знать, какие логические диски присутствуют в системе. Среди
нескольких функций, выполняющих эту работу, наиболее удобной для процесса обработки является GetLogicalDrivesString.
DWORD GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer);
Данной функции передаются два параметра: lpBuffer — адрес буфера, в который помешаются имена корневых каталогов логических дисков, установленных в системе; nBufferLength — длина буфера, заданного указателем lpBuffer. В качестве возвращаемого значения функция формирует длину буфера, действительно необходимую для размещения строки с именами корневых каталогов логических дисков. Например, при наличии трех логических дисков структура заполненного буфера будет следующей: А:\0В:\0С:\0. Заметьте, что имена корневых каталогов разделены нулевыми байтами. Более эффективно вызывать эту функцию два раза: первый раз с нулевым значением первого параметра, при этом функция вернет потребное количество байт для размещения буфера; второй раз функцию уже можно вызывать, подставив на место первого параметра значение, возвращенное при первом вызове.
:prg07_33.asm - Win32-консольное приложение для Win32 для исследования работы :функции GetLogicalDriveStrings API Win32.
.data
TitleText db 'Получение информации о дисках в Win32',0 '
infojmf db 10 duo (0)
.code
:.......----GetLogi cal Dri veStri ngs................-........
push offset info_buf
push 0
call GetLogicalDriveStringsA
cmp eax.O
jz exit ;выход в случае неудачи
;вызываем функцию второй раз. когда известно количество байт, потребное :для записи списка корневых каталогов
push offset info_buf
push eax
call GetLogicalDriveStringsA
cmp eax.O
jz exit :выход в случае неудачи результат смотрим в отладчике TD32.exe
Недостаток функции GetLogi cal Dri veStri ngs состоит в том, что она работает не во всех версиях Windows. Альтернативным вариантом получения информации о наличии дисков в системе является функция GetLogi cal Drives.
DWORD GetLogicalDrives(VOID);
Эта функция возвращает в регистре ЕАХ битовую маску, в которой установленные биты указывают на существование логического диска: бит 0 — А, бит 1 — В, бит 2 — С... Таким образом, с помощью функции GetLogi cal Drives можно достичь того же самого результата, что и с помощью функции GetLogi cal Dri veStri ngs, но несколько большими трудами.
;prg07_34.asm - Win32-консольное приложение для исследования
;работы функции GetLogicalDrives API Win32.
.data
TitleText db 'Получение информации о дисках в Win32'.0
info_buf db 10 dup (0)
.code
call GetLogicalDrives cmp eax.O
jz exit ;выход в случае неудачи результат смотрим з отладчике TD32.exe
После того как информация о номенклатуре логических дисков в системе получена, можно получить информацию о каждом из них. Для этого используется функция GetVolumelnformation.
BOOL GetVolumeInformation(LPCTSTR ipRootPathName.
LPTSTR lpvolumeNameBuffer. DWORD nVolumeNameSize, LPDWORD ipVolumeSerialNumber, LPDWORD
ipMaximumComponentLength. LPDWORD lpFileSystemFlags.
LPTSTR ipFileSystemNameBuffer. DWORD nFileSystemNameSize);
На вход функции GetVolumelnformation подаются следующие параметры:
- IpRootPathName — указатель на строку с именем корневого каталога диска, информацию о котором необходимо получить (если параметр равен NULL, функция формирует информацию о текущем диске). Формат задания имени корневого каталога диска — имя_диска:\. Это единственный параметр, значение которого нужно задавать, остальные параметры — адреса областей памяти, в которые будут помещены значения, формируемые функцией;
- lpVolumeNameBuffern и nVolumeNameSize — указатель на буфер и размер буфера, в который будет записано имя диска;
- IpVolumeSerial Number — адрес двойного слова, куда будет записан серийный номер. Если информация о серийном номере диска не нужна, то при вызове функции значение этого параметра необходимо сделать равным NULL;
- lpMaximumComponentLength — адрес двойного слова, куда будет записано значение максимальной длины пути, возможное в данной файловой системе;
- lpFileSystemFlags — флаги с дополнительной информацией о файловой системе:
- • FS_CASE_SENSITIVE=FILE_CASE_SENSITIVE_SEARCH
=00000001h - поддержка со стороны файловой системы поиска с сохранением регистра букв;
- • FS_CASE_IS_PRESERVED=FILE_CASE_PRESERVED_NAMES
=00000002h - при записи на диск сохранить регистр букв в имени файла;
- • FS_UNICODE_STORED_ON_DISK=FILE_UNICODE_ON_DISK
=00000004h - файловая система поддерживает хранение имен файлов в Unicode;
- • FSPERSI STENT_ACLS=FI LEPERS I STENT_ACLS
=00000008h - файловая система способна оперировать со списками контроля доступа (ACL) — только для NTFS;
• FS_FILE_COMPRESSION=FILE_FILE_COMPR?SSION
=00000010h — файловая система поддерживает сжатие файлов;
• FS_VOL_IS_COMPRESSED=FILE_VOLUME_IS_COMPRESSED
=00008000h - том, о котором запрашивается информация, был сжат;
a lpFileSystemNameBuffer и nFileSystemNameSize — указатель и размер буфера в который будет записано имя файловой системы. Если TpFiieSystemName-Buffer=NULL, то в эти параметры ничего не записывается.
Изменить метку диска может вызов функции SetVolumeLabel.
BOOL SetVolumeLabel(LPCTSTR IpRootPathName. LPTSTR lpVolumeName):
Параметр IpRootPathName задает адрес строки с именем корневого каталога диска, метку которого меняем. Второй параметр 1 pVol umeNarae — строка с меткой тома. Для удаления метки тома с диска параметр lpVolumeName нужно задать равным NULL.
Получить информацию о свободном дисковом пространстве Информацию о свободном дисковом пространстве, а заодно и о разбиении диска на сектора и кластеры позволяет получить функция GetDiskFreeSpace.
BOOL GetDiskFreeSpaceCLPCTSTR IpRootPathName.
LPDWORD ipSectorsPerCluster, LPDWORD lpBytesPerSector,
LPDWORD ipNumDerOfFreeClusters. " LPDWORD ipTotalNumberOfClusters):
На вход функции нужно подать строку с именем корневого каталога диска, о котором необходимо получить информацию (NULL для текущего диска), и адреса буферов, куда будет помещена следующая информация: общее количество кластеров на диске (1 pTotal NumberOfCl usters), общее количество свободных кластеров (TpNumberOfFreeCI usters), количество байт в секторе (lpBytesPerSector), количество секторов в кластере (IpSectorsPerCluster).
Создание и удаление каталога
Создание каталога выполняет функция CreateDi rectory.
BOOL CreateDi rectory (LPCTSTR lpPathName. LPSECURITYJVTTRIBUTES.IpSecurityAttributes ¦:
Первый параметр этой функции lpPathName — указатель на ASCIIZ-строку с путем, последний элемент которого является именем нового каталога. Параметр ipSecurityAttributes — указатель на экземпляр структуры Security_Attributes.
SECURITY_ATTRIBUTES stoic
nLength dd. 0
lpSecurityDeschptor dd 0
blnheritHandle dd
ends С помощью структуры SecurityAttributes можно ограничить доступ пользователя к каталогу. Параметр IpSecurityAttributes обычно задается равным NULL. Более подробную информацию о параметрах структуры можно получить в MSDN.
Удаление каталога выполняет функция RemoveDi rectory.
BOOL RemoveDirectory(LPCTSTR lpPathName);
единственный параметр этой функции ipPathName — указатель на ASCIIZ-стро-^Вс путем, последний элемент которого является именем удаляемого каталога. ^Удаляемый каталог не должен быть пустым.
Определение и изменение текущего каталога
Аналогично принципам организации файловой системы MS DOS в Win32 также Иуществует понятие текущего каталога, то есть каталога, в котором выполняются ^шеущие операции по работе с файлами. В отличие от MS DOS понятие текуще-^^Италога относится к текущему процессу. При запуске процесса текущим бу-I дет являться каталог, из которого этот процесс был запущен. Определяет текущий налог процесса функция GetCurrentDirectory.
RD GetCurrentDirectory(OWORD nBufferLength, LPTSTR ipBuffer);
it Параметры TpBuffern и BufferLength определяют соответственно адрес и длину I буфера, в который помещается путь с текущим каталогом (строка с завершаю-Нцим нулем). Функция возвращает NULL в случае ошибки и число байтов, необходимо для записи данных в буфер, в случае удачного завершения. Завершающий ^ нуль в возвращаемом функцией числе не учитывается. Если буфер мал, то с помощью возвращаемого значения можно изменить его размер. [ Изменить текущий каталог процесса можно с помощью функции SetCurrent-^Brectory.
¦6001 SetCurrentDi rectory (LPCTSTR IpszPathName): "
j" Параметр IpszPathName — адрес ASCIIZ-строки с путем, последний элемент ко-I торою — новый текущий каталог данного процесса.
[i Платформа Win32 также поддерживает понятие системного и основного ка-^ВДога Windows. Для определения системного каталога существует специальная |; функция GetSystemDi rectory.
[ GetSystemDirectory(LPTSTR ipszBuffer, UINT uSize):
Два параметра этой функции определяют адрес и размер буфера, в который I записывается путь к системному каталогу Windows.
„Для определения основного каталога Windows существует специальная функция
GetWindowsDi rectory.-
UINT GetWindowsDirectorydPTSTR IpBuffer. UINT uSize);
Два параметра этой функции определяют адрес и размер буфера, в которыйзаписывается путь к основному каталогу Windows. Возвращаемое значение количество реально записанных в буфер байтов. Его можно использовать для г корректировки параметра uSize, если он был задан слишком маленьким, и повторного вызова функции GetWindowsDi rectory.
Для демонстрации применения вышеприведенных функций рассмотрим комплексный пример, в ходе которого продемонстрируем порядок вызова и анализа Е возвращаемых значений функциями API Win32 для работы с каталогами. Опре-
делим текущий каталог процесса, создадим новый каталог, сделаем его текущим удалим новый каталог, определим системный каталог и каталог Windows.
:prg07_35.asm - Win32-KOHCo/ibHoe приложение для исследования работы функций ;работы с каталогами API Win32.
.data
TitleText db 'Работа с каталогами в Win32',0
NewOir db "Новый каталог".0
dirjbuf db 50 dup ("?")
size_dir_buf=$-dir_buf
Parent db "..".0
.code
:определив текущий каталог
push offset dirjwf
push size_dir_buf
call GetCurrentDirectoryA
cmp eax.0
jz exit ;выход в случае неудачи :создадим каталог
push 0
push offset NewDir .
call CreateDirectoryA
cmp eax,0
jz exit :выход в случае неудачи ¦.сделаем новый каталог текущий
push offset NewDir
call SetCurrentDirectoryA
cmp eax.0
jz exit ;выход в случае неудачи
;проверим новый текущий каталог
push offset dir_buf
push size_dir_buf
call GetCurrentDirectoryA
cmp eax.0
jz exit .-выход в случае неудачи
;------.....SetCurrentDi rectory-..................-.........
:вернемся в родительский каталог
push offset Parent
call SetCurrentDirectoryA
cmp eax.0
jz exit ;выход в случае неудачи
;проверил новый текущий каталог
push offset dir_buf
push size_dir_buf
call GetCurrentDirectoryA
cmp eax.O
jz exit :выход в случае неудачи :удалим новый текущий каталог
push offset NewDir
call RemoveDirectoryA
cmp eax.O
jz exit ;выход в случае неудачи I определив системный каталог mov eax.size_dir_buf push eax
push offset dir_buf call GetSystemDirectoryA cmp eax.O
jz exit :выход в случае неудачи ¦.определим основной каталог Windows mov eax.size_d1r_buf push eax
push offset dir_buf call GetWindowsDirectoryA cmp eax.O
jz exit -.выход в случае неудачи результат смотрим в отладчике TD32.exe
Среди функций Win32, работающих с текущим каталогом, существует функция GetFuT I PathName, которая по имени файла формирует его полное имя, состоящее из пути от корневого каталога к текущему. Последний элемент этого имени — имя входного файла.
DWORD GetFulIPathNameCLPCTSTR ipFileName. DWORD nBufferLength, LPTSTR ipBuffer.
LPTSTR *lpFilePart): I На входе функция принимает имя файла в виде ASCIIZ-строки. На выходе —
три параметра:
- IpBuffer — адрес буфера, в который помещается полный путь с именем
файла;
- nBufferLength — длина буфера, на который указывает параметр IpBuffer,
в символах;
- lpFilePart — адрес ячейки размером с двойное слово, в которое помещается указатель на позицию внутри буфера, идентифицированную параметром 1 pBuf fег и соответствующую первому символу имени файла после имен всех каталогов.
Самое интересное в этой функции — механизм ее работы. Суть его в том, что
реально функция GetFul I PathName не ищет файл, ка имя которого указывает параметр IpBuffer. Результат своей работы — полный путь — она формирует из двух
компонент: полного пути к текущему каталогу данного процесса и имени файла,
наличие которого на диске функция GetFul I PathName даже не проверяет. Для подобной работы ей даже не нужно обращаться к диску. С аналогичной функцией
' мы уже имели дело, когда рассматривали функции MS DOS для работы с файлами, имеющими длинные имена.
Поиск файлов
При последовательном изучении материала данного раздела читатель кроме знакомства со средствами по работе с файлами операционных систем фирмы Microsoft поневоле должен был оценить процесс эволюции этих средств. Особенно очевиден этот процесс при поиске файлов.
Платформа Win32 предлагает два способа поиска файлов:
- с использованием функции SearchPath;
- с использованием функций FindFirr,tFile, FindNExtFile и структуры WIN32 FIND DATA.
Поиск файлов с помощью функции SearchPath
Функция SearchPath ищет файлы в указанном при ее вызове списке каталогов.
DWORD SearchPathtLPCTSTR lpPath. LPCTSTR ipFileName. LPCTSTR lpExtension, DWORD nBufferiength. LPTSTR ipBuffer, LPTSTR *lpFilePart):
Первый параметр lpPath определяет список каталогов, в которых будет осуществляться поиск файла. Параметры lpFileName и lpExtension указывают на ASCIIZ-строки с именем и расширением искомого файла. Наличие пары этих параметров позволяет задавать имя и расширение файла двумя способами:
- одной ASCIIZ-строкой — на нее указывает параметр lpFileName, при этом параметр ipExtension равен NULL;
- отдельными ASCHZ-строками — в этом случае параметр ipFileName содержит указатель на ASCIIZ-строку с именем файла, а второй парамет lpExtension — содержит указатель на ASCIIZ-строку с расширением файла; строка с расширением должна начинаться с символа . (точка).
Параметр IpBuffer указывает на буфер, куда записывается ASCHZ-строка с полным путем к искомому файлу. Длина этого буфера определяется параметром nBufferLength. Если эта длина слишком мала, то ее можно подкорректировать значением, возвращаемым функцией в регистре ЕАХ. Это значение является личеством символов, действительно необходимых для записи полного имени найденного файла в буфер. Если в ЕАХ возвращается NULL, то это говорит об ошибке вызова функции.
Последний параметр lpFilePart является указателем на символ в буфере, с которого начинается собственно имя файла.
При вызове функции SearchPath параметр lpPath можно задать равным NULL. В этом случае поиск файла будет осуществляться в следующих каталогах (порядок перечисления соответствует порядку просмотра при поиске):
- каталог, из которого запущено приложение;
- текущий каталог;
- системный каталог;
- основной каталог Windows;
- каталоги, перечисленные в переменной окружения PATH.
Поиск файлов с помощью функций FindFirstFile и FindNExtFile Предыдущий способ поиска обладает существенным недостатком — ограниченным числом каталогов диска, подвергающихся просмотру в процессе поиска. По этой причине он не может быть использован для поиска в пределах всего диска. Этот недостаток устраняется при втором способе поиска — с использованием функций FindFirstFile, FindNExtFile и структуры WIN32FINDDATA. Этот способ реализует определенный алгоритм поиска. Вначале вызывается функция FindFirstFile, которая имеет два параметра: lpFileName — указатель на ASCII-строку с именем файла; lpFindFileData — указатель на экземпляр структуры WIN32_FIND_OATA.
HANDLE FindFirstFiletLPCTSTR lpFileName. LPWIN32_FIND_DATA lpFindFileData): Имя файла может содержать символы шаблона * и ?. Кроме того, имя может Вырожать путь, с которого нужно начинать поиск. Выше, при знакомстве с функциями MS DOS для работы файлами, имеющими длинные имена, приводилось Иписание структуры WIN32_FIND_DATA и ее полей.
В случае успеха функция FindFirstFile заполняет поля структуры WIN32_FIND_ DATA и возвращает значение дескриптора внутренней структуры в памяти, который впоследствии может быть использован функциями FindNextFile или FindClose. В случае неудачи функция не изменяет содержимое структуры WIN32_FIND_DATA и возвращает значение
INVALID_HANDLE_VALUE (EAX=-llo=Offffffffh). 1 Проанализировав результаты поиска, программа может продолжить или прекратить его. Для продолжения поиска необходимо вызвать функцию Fi ndNExtFi I e. I BOOL FindNextFile
( HANDLE hFindFile. LPWIN32_FIND_DATA lpFindFileData ):
В качестве параметров используются дескриптор, полученный в регистре ЕАХ в результате поиска функцией FindFirstFile, и указатель на экземпляр структуры WIN32_FIND_DATA. В случае успеха функция FindNextFile возвращает ненулевое значение в регистре ЕАХ и заполняет структуру WIN32FINDDATA. При неудаче —
I ЕАХ = 0.
Для продолжения поиска при неизменных исходных параметрах поиска функ-
ция FindNextFile вызывается циклически.
Для окончания процесса поиска необходимо вызвать функцию FindClose.
BOOL FindCloset HANDLE hFindFile ):
i Функция FindClose имеет один параметр — дескриптор, полученный функци-Нй FindFirstFile в начале поиска. В случае успеха функция FindClose возвращает Е ненулевое значение в регистре ЕАХ, при неудаче — ЕАХ = 0.
Файлы, отображаемые в память
¦Платформа Win32 позволяет организовать работу с содержимым файла как с ^Властью оперативной памяти, без использования операций файлового ввода-Лывода. Этот механизм отображает (проецирует) содержимое файла на область Императивной памяти. Программе передается адрес этой области, после этого ра-Ибота с содержимым файла осуществляется командами работы с памятью.
Для «проецирования» файла необходимо выполнить следующие действия.
- 1. Требуется создать (для несуществующего файла) или открыть (для существующего файла) объект ядра файл. Цель этого шага — сообщить системе, где находится физическое представление файла. Создание или открытие объекта ядра файл производится с помощью функции CreateFile (см. выше). Все параметры этой функции задаются обычным образом. На выходе в случае успеха функция формирует дескриптор (в регистре ЕАХ), в обратном случае - значение INVALID_HANDLE_VALUE (ЕАХ—llo=Offffffffh).
2. Требуется создать объект ядра проекция файла. Цель этого шага — сообщить системе размер проецируемого файла. Для этого используется функция CreateFi I eMappi ng:
HANDLE CreateFileMapping
(HANDLE hFile. LPSECURITY_ATTRIBUTES
ipFileMappingAttributes DWORD flProtect.
DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow. LPCTSTR ipName);
Параметр hFile является дескриптором файла, полученным функцией Create-File. Параметр 1 pFi 1 eMappingAttributes — указатель на экземпляр структуры SECURITYATTRIBUTES, которая служит для установки защиты. Присвойте параметру lpFil eMappi ngAttri butes значение NULL. Параметр flProtect предназначен для установки атрибутов защиты страниц физической памяти в адресном пространстве процесса, на которые отображается файл. Используют один из следующих атрибутов:
PAGE_READONLY=02 — доступ к файлу только по чтению (при использовании этого параметра вызов CreateFile должен был производиться с флагом GENERIC_READ);
€ PAGEREADWRI TE=04 — доступ к файлу только по записи (при использовании этого параметра вызов CreateFile должен был производиться с флагом GENERICREAD | GENERICWRITE);
a PAGE_WRITECOPY=08 — доступ к файлу по чтению-записи с созданием копии данных из файла, при этом исходный файл не изменяется, изменения касаются лишь модифицированных страниц копии в страничном файле (при использовании этого параметра вызов CreateFile должен был производиться с флагом GENERIC_READ или GENERIt_READ|GENERIC_WRITE).
Параметры dwMaximumSizeHigh и dwMaximumSizeLow предназначены для того, чтобы сообщить системе максимальный размер файла в байтах. При этом в dwMaximumSizeLow указываются младшие 32 бита этого значения, а в dwMaximumSizeHigh — старшие 32 бита. Если предполагается размер файла, равный текущей его длине, то следует при вызове функции передать dwMaxi ¦ mumSizeLow=dwMaximumSizeHigh=NULL.
Последний параметр IpName — указатель на ASCIIZ-строку с именем объекта проецируемый файл для обеспечения доступа к нему других процессов. Обычно задают равным NULL.
3. Требуется выполнить проецирование файла на адресное пространство процесса. В этом шаге две цели. Первая цель — сообщить системе порядок отображения (проецирования) файла на адресное пространство процесса — полный или частичный. Вторая цель — получить адрес этого отображения в памяти. Реализация этих целей достигается функцией MapViewOfFile: LPVOID MapViewOfFi1e(HANDLE hFileMappingObject,
DWORD dwDesiredAccess.
- DWORD dwFileOffsetHigh. DWORD dwFileOffsetLow.
DWORD dwNumberOfBytesToMap);
Параметр hFil eMappi ngObject — дескриптор, возвращенный функцией Create-Fi 1 eMapping на предыдущем шаге. Параметр dwDesiredAccess определяет вид доступа к данным:
FILE_MAP_COPY=01 — данные в файле доступны по чтению, хотя отображенные данные доступны по чтению и по записи; операция записи приводит к созданию копии страницы в страничном файле, в которую производится запись, поэтому после первой операции записи теряется соответствие между реальными данными на диске и данными, с кото
рыми работает приложение (при использовании этого значения параметра dwDesiredAccess функция CreateFil eMappi ng должна была быть вызвана с одним из атрибутов: PAGE_READONLY, PAGE_READWRITE или PAGEWRITECOPY);
• FILE_MAP_WRITE=02 — данные в файле доступны по чтению-записи (при использовании этого значения параметра dwDesiredAccess функция CreateFil eMapping должна была быть вызвана с атрибутом PAGE_READWRITE);
ш FILEMAPRE AD=04 — данные в файле доступны по чтению (при использовании этого значения параметра dwDesiredAccess функция CreateFile-Mapping должна была быть вызвана с одним из атрибутов: PAGE_READONLY, PAGE_READWRITE или PAGE_WRITECOPY);
• FILE_MAP_ALL_ACCESS=OOOFO00Oh + OOOOOOOlh + 00000002h +
00000004h + 00000008h + OOOOOOlOh — данные в файле доступны по чтению-записи (при использовании этого значения параметра dwDesiredAccess функция CreateFile-Mapping должна была быть вызвана с атрибутом PAGERE ADWRI ТЕ).
Параметры dwFileOffsetHigh, dwFileOffsetLow и dwNumberOfBytesToMap предназначены для указания позиции в файле, с которой начинать отображение, и количества отображаемых байт (dwNumberOfBytesToMap). Параметр dwFileOffsetHigh — старшие 32 бита этого смещения, а параметр dwFileOffsetLow — младшие 32 бита этого смещения. Таким образом, с файлом можно работать не целиком, а по частям, эффективно используя при этом оперативную память. Заметим, что если задать параметр dwNumberOfBytesToMap равным NULL, то система будет пытаться отобразить содержимое файла с указанной парой dwFileOffsetHigh:dwFileOffsetLow смещения и до конца файла. В случае успеха функция формирует адрес отображения в памяти (регистр ЕАХ), в обратном случае ЕАХ = 0. После получения в ЕАХ адреса начала отображения в памяти приложение может работать с данными файла обычными командами работы с памятью. При необходимости функция MapViewOfFile может быть вызвана повторно с другими параметрами dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow и dwNumberOfBytesToMap. При этом (запомните!) резервируется новый регион в памяти.
После выполнения необходимых действий приложение должно корректно завершить работу с отображением файла.
4. Требуется выполнить разрыв связи данных в файле и соответствующими данными, отображенными на адресное пространство процесса. Это дейст-
I вие выполняет функция UnmapViewOfFile. BOOL UnmapViewOfFile( LPCVOID ipBaseAddress);
Эта функция имеет единственный параметр — IpBaseAddress, который является значением, возвращенным функцией MapViewOfFile. С помощью функции UnmapViewOfFile необходимо разрывать каждое из отображений, созданных последовательностью вызовов MapViewOfFile, сохраняя при этом их соответствия. Также имейте в виду, что если функция MapViewOfFile была вызвана с параметром FILEMAPCOPY, то после вызова UnmapViewOfFile теряются все внесенные в отображенные данные изменения.
5. Далее нужно закрыть объект ядра проекция файла. В принципе, этот и сле-ivmmuu шяг нр яиляютг.я обязательными, так как система в процессе за-
вершения работы приложения освободит все ресурсы. Освобождение
объекта ядра проекция файла производится функцией CloseHandle.
BOOL CloseHandle( HANDLE hObject):
Функции CloseHandle передается единственный параметр hObject — де.
скриптор, полученный как результат вызова функции CreateFileMapping.
6. Требуется закрыть объект ядра файл. Освобождение объекта ядра файл также производится функцией CloseHandle.
BOOL CloseHandle( HANDLE hObject );
Функции CloseHandle передается единственный параметр hObject — дескриптор, полученный как результат вызова функции CreateFile.
Пример программы (prg07_36.asm), демонстрирующей порядок использования файлов, отображаемых в адресное пространство процесса, достаточно велик и по этой причине вынесен на дискету. Работа программы проста и заключается в следующем: необходимо вывести содержимое некоторого файла на экран — в окно консоли. Имя исходного файла вводится с клавиатуры.
|