Функция SetFilePointer возвращает новое значение указателя файла. В том случае, когда 32 разрядов для этого мало, старшие тридцать два разряда записываются по адресу lpDistanceToMoveHigh.
DWORD dwMoveMethod);
PLONG lpDistanceToMoveHigh,
LONG IDistanceToMove,
DWORD SetFilePointer(HANDLE hFile,
1) hFile – хэндл того файла, в котором перемещается указатель.
2) IDistanceToMove – это число символов, на которое необходимо передвинуть указатель файла. Так как тип этого аргумента LONG, то невозможно переместить указатель файла больше, чем на 2*32 байта. Если необходимо передвинуть указатель более чем на 2*32 байта, то в этом случае необходимо воспользоваться третьим аргументом функции, через который можно передать указатель на буфер, содержащий старшие тридцать два разряда требуемого значения.
3) PLONG lpDistanceToMoveHigh – указатель на буфер со старшими 32-мя байтами расстояния для перемещения указателя.
Таким образом, при определении нового значения указателя файла используется следующая формула:
НЗУ=СЗУ+ IDistanceToMove+ * lpDistanceToMoveHigh,
Где НЗУ – новое значение указателя;
СЗУ – старое значение указателя;
4) dwMoveMethod определяет точку отсчёта для перемещения указателя файла. Возможные значения этого аргумента следующие:
Функция при успешном завершении возвращает новое значение указателя. Но возможны ещё два случая. Во-первых функция может вернуть значение 0хffffffff, при этом слово, на которое указывает третий аргумент может быть нулевым. Это означает, что при работе функции произошла ошибка. Во-вторых функция может вернуть значение 0хffffffff, при этом слово на которое указывает третий аргумент может быть не равно нулю. В этом случае для того, чтобы определить произошла ли ошибка, необходимо вызвать функцию GetLastError(). Если эта функция вернёт значение, отличное от NO_ERROR, то это будет являться сообщением об ошибке.
Ввод:
АН = 40h
ВХ = идентификатор
СХ = число байт
DS:DX = адрес буфера с данными
Вывод:
CF = 0 и АХ = число записанных байт, если не произошла ошибка
CF = 1 и АХ = 05h, если доступ запрещен, 06h, если неправильный идентификатор
Если при записи в файл указать СХ = 0, файл будет обрезан по текущему значению указателя. При записи в файл на самом деле происходит запись в буфер DOS, данные из которого сбрасываются на диск при закрытии файла или если их количество превышает размер сектора диска. Для немедленного сброса буфера можно использовать функцию 68h (функция fflush в С).
Пример для DOS 13.2. Прямой доступ к файлу. Модифицируем созданный ранее файл в примере 13.1 MYFILE.txt, содержащий строку “Файл номер 1”, в которой следует заменить 1 на 2а.
; В сегменте команд
; Откроем файл
mov AH,3Dh ;Функция открытия файла
mov AL,2 ;Доступ для чтения-записи
mov DX,offset fname ;Адрес имени файла
int 21h
mov handle,AX ;Сохраним дескриптор
;Установим указатель на байт номер 11
mov AH,42h ;Функция установки указателя
mov AL,0 ;Режим - от начала файла
mov BX,handle ;Дескриптор
mov CX, 0 ;Старшая половина указателя
mov DX, 11 ;Младшая половина указателя
int 21h
;Модифицируем файл
mov AH,40h ;Функция записи
mov BX,handle ;Дескриптор
mov CX,2 ;Число записываемых байтов
mov DX,offset mod ;Отсюда выводить
int 21h
;В сегменте данных
mod db '2a' ;Буфер вывода
handle dw 0 ;Ячейка для дескриптора
fname db 'MYFILE.txt', 0 ;Имя файла в формате ASCIIZ
При модификации будет произведена как замена последнего байта файла, так и увеличения длины файла на 1 байт.
Если необходимо задать положение указателя от конца файла, то для этого в параметрах функции 42h следует указать режим 02, а в регистровую пару CX:DX поместить число -1 (так как мы хотим сместиться на 1 байт влево от конца файла); 32- разрядное число -1 имеет машинное представление FFFFFFFFh. Поэтому строки заполнения регистров СХ и DX будут выглядеть следующим образом: