Программирование на Ассемблере

Обзор функций WINDOWS API для работы с файлами


Файл – это объект операционной системы. Это значит, что ОС создает для каждого файла таблицу, куда заносит информацию о файле, включающую в себя имя файла, его местоположение на диске, текущее положение указателя, режимы открытия и т.д.

Для создания записи о файле используется функция CreateFile:

HANDLE CreateFile(

    LPCTSTR lpFileName,       // Имя файла (с нулевым завершителем)

    DWORD dwDesiredAccess,           // Режим доступа к файлу (read-write)

    DWORD dwShareMode,    // Возможность share

    LPSECURITY_ATTRIBUTES lpSecurityAttributes,           // атрибуты безопасности

    DWORD dwCreationDistribution,  // Режимы создания

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

    HANDLE hTemplateFile    // Дескриптор файла с атрибутами копирования

   );      

Параметр dwDesiredAccess может принимать значения.

GENERIC_READ          Разрешено чтение.



GENERIC_WRITE         Разрешена запись. Может задаваться совместно с первым.

(см. файл WINNT.H)

#define GENERIC_READ                  (0x80000000L)

#define GENERIC_WRITE                 (0x40000000L)

#define GENERIC_EXECUTE          (0x20000000L)

#define GENERIC_ALL                     (0x10000000L)

DwShareMode

-возможность совместного использования. Если параметр равен 0, файл нельзя совместно использовать.

Допустимые значения параметров:

FILE_SHARE_DELETE         Windows NT only: Разрешается только тогда, когда файл удаляется.

FILE_SHARE_READ    Разрешается только для чтения.

FILE_SHARE_WRITE   Разрешается только для записи.

LpSecurityAttributes – указатель на структуру SECURITY_ATTRIBUTES с целью задания возможности наследования файла процессом – потомком. Если параметр равен NULL, дескриптор файла не может наследоваться.

Windows NT: lpSecurityDescriptor определяет дескриптор безопасности для дескриптора. Если он равен NULL, дескриптор получает параметры безопасности, принятые по умолчанию, если файловая система поддерживает такие атрибуты. Для Windows 95 эта структура игнорируется.


Функция ReadFile читает данные из файла.
BOOL ReadFile(
    HANDLE hFile,      // Дескриптор файла
    LPVOID lpBuffer,   // адрес буфера
    DWORD nNumberOfBytesToRead,           // количество читаемых байтов
    LPDWORD lpNumberOfBytesRead,          // адрес количества прочитанных байтов
    LPOVERLAPPED lpOverlapped   // адрес тсруктуры для данных
   );      
 
Если возвращается True, а количество прочитанных байтов равно 0, то это прочитан конец файла.
BOOL WriteFile(
    HANDLE hFile,      // Дескриптор файла
    LPCVOID lpBuffer,            // адрес буфера
    DWORD nNumberOfBytesToWrite,           // количество записанных байтов
    LPDWORD lpNumberOfBytesWritten,       // указатель на количество записанных байтов
    LPOVERLAPPED lpOverlapped   // Указатель на структуру для асинхронного использования файла
   );      
Пример 1. Создать файл для записи и записать туда заданную строку.
Ideal
p586
model              flat
extrn ExitProcess:proc
extrn CreateFileA:proc
extrn    CloseHandle:proc
extrn ReadFile:proc
extrn    WriteFile:proc
extrn CloseHandle:proc
extrn MessageBoxA:proc
include "win.inc"
dataseg
my       db        '  -  25', 0
val       dd        ?
d1        dd        ?
d2        dd        ?
n1        db        'a.txt', 0
n2        db        'b.txt', 0
msg      db        'Error', 0
s1         dd        ?
codeseg
begin:
push 0 0 CREATE_ALWAYS 0 0
push GENERIC_WRITE
push     offset n1
             
call      CreateFileA
cmp         eax, INVALID_HANDLE_VALUE
jne       short m1
push     MB_OK offset msg offset n1 0
call      MessageBoxA
jmp      short m2
m1:
mov     [d1], eax
mov     eax, 0
for1:
mov     bl, [my+eax]
test       bl, bl
je         short break
inc       eax
jmp      for1
break:
push     0 offset s1 eax offset my [d1]
call      WriteFile
test       eax, eax
jne       short m4
push     MB_OK offset msg offset n1 0


call      MessageBoxA
jmp      short m2
m4:
push     [d1]
call      CloseHandle
cmp     eax, INVALID_HANDLE_VALUE
jne       short m3
push     MB_OK offset msg offset n1 0
call      MessageBoxA
jmp      short m2
m3:
m2:
call      ExitProcess
end     begin
Пример 2. Составить функцию для копирования файлов с заданными именами.
Ideal
p586
model              flat
extrn ExitProcess:proc
extrn CreateFileA:proc
extrn CloseHandle:proc
extrn ReadFile:proc
extrn    WriteFile:proc
extrn CloseHandle:proc
extrn MessageBoxA:proc
include "win.inc"
dataseg
my       db        '  -  25', 0
val       dd        ?
n1        db        'io6.exe', 0
n2        db        'proba.txt', 0
msg      db        'Error', 0
s1         dd        ?
codeseg
proc     FileCopy
public  FileCopy
arg       nin:dword, nout:dword
local     buffer:byte:512, d1:dword, d2:dword, count:dword=s
push     ebp
mov     ebp, esp
sub       esp, s
push    eax
push     0 0 OPEN_EXISTING 0 0 GENERIC_READ [nin]
call       CreateFileA
cmp     eax, INVALID_HANDLE_VALUE
jne       short @@m1
push     MB_OK offset msg [nin] 0
call       MessageBoxA
jmp      @@m3
@@m1:
mov     [d1], eax
push     0 0 CREATE_ALWAYS 0 0 GENERIC_WRITE [nout]
call       CreateFileA 
cmp     eax, INVALID_HANDLE_VALUE
jne       short @@m2
push     MB_OK offset msg [nout] 0
call       MessageBoxA
jmp      @@m3
@@m2:
mov     [d2], eax
for1:
push 0
lea        eax, [count]
push     eax 512
lea        eax, [buffer]
push     eax [d1]
call       ReadFile
test      eax, eax
jne       short @@m4
push     MB_OK offset msg [nin] 0
call       MessageBoxA
jmp      short @@m3
@@m4:
mov     eax, [count]
test      eax, eax
je         short break
push     0
lea        eax, [count]
push     eax [count]
lea        eax, [buffer]
push     eax [d2]
call       WriteFile
test      eax, eax
jne       short @@m5
push     MB_OK offset msg [nout] 0
call       MessageBoxA
jmp      short @@m3
@@m5:
mov     eax, [count]
cmp     eax, 512
jb         short break
jmp      for1   
break:
push     [d1]
call       CloseHandle
push     [d2]
call       CloseHandle
@@m3:
pop eax
mov     esp, ebp
pop      ebp
ret        8
endp
begin:
push     offset n2 offset n1
call       FileCopy
call       ExitProcess
end     begin

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