Untitled
4. РАБОТА С ФАЙЛАМИ
4.1. Атрибуты файлов
4.2. Поиск файлов
4.3. Изменение атрибутов
4.4. Копирование файлов
4.5. Удаление файлов
В этом разделе мы расскажем вам об использовании некоторых, самых
интересных, на наш взгляд, функций сетевой оболочки Novell NetWare,
предназначенных для работы с файлами.
Практически все обычные операции с файлами, такие, как запись,
чтение, перезапись по месту, удаление и т. п., можно выполнять
с использованием обычных функций MS-DOS, подробно рассмотренных
нами ранее в первом томе "Библиотеки системного программиста".
Однако для выполнения некоторых операций с файлами, расположенными
на файл-сервере, вам не обойтись без специальных функций сетевой
оболочки. К таким операциям можно отнести, например, просмотр
и изменение байта атрибутов и байта расширенных атрибутов файла,
копирование файлов с диска файл-сервера на диск файл-сервера без
вовлечения в эту операцию рабочей станции и т. д.
По сравнению с файлами MS-DOS файлы, расположенные на файл-сервере
Novell NetWare, имеют больше атрибутов. В этом разделе мы рассмотрим
эти атрибуты.
В отличие от MS-DOS файловая система Novell NetWare для хранения
атрибутов файлов использует не один, а два байта. Первый байт
называется байтом атрибутов (File Attributes Byte), второй - байтом
расширенных атрибутов (Extended File Attributes Byte).
Приведем назначение отдельных битов байта атрибутов:
Бит | Назначение |
0 | Read Only: файл можно читать, но нельзя в него писать. Этот файл нельзя также удалять или переименовывать
|
1 | Hidden: скрытый файл, не появляется в списке файлов при поиске в каталоге обычными средствами
|
2 | System: системный файл, не появляется в списке файлов при поиске в каталоге обычными средствами
|
3 | Execute Only: файл может быть загружен только для выполнения. Этот файл нельзя читать или перезаписывать. В операционной системе Novell NetWare не существует средств для сброса бита Execute Only; поэтому, если вы установите этот бит, вы навсегда потеряете доступ к файлу на чтение и запись
|
4 | Subdirectory: данный элемент оглавления каталога описывает не файл, а подкаталог
|
5 | Archive: этот бит установлен, если после выполнения операции выгрузки файла сам файл был изменен
|
6 | Зарезервировано |
7 | Shareable: к данному файлу разрешен одновременный доступ со стороны нескольких пользователей, расположенных на разных рабочих станциях
|
Обратим ваше внимание на бит Execute Only. Если вы установите
этот бит, вызвав соответствующую функцию или воспользовавшись
утилитами Novell NetWare, никто (даже супервизор) не будет иметь
доступа на чтение к этому файлу. Такая возможность полезна для
защиты программ от несанкционированного копирования и дезассемблирования,
однако этот способ обладает рядом недостатков.
Во-первых, вы не можете установить бит Execute Only у оверлеев,
так как перед запуском их надо загрузить в память, а такая операция
запрещена для "только выполняемых" файлов. Файлы, содержащие
программы для Microsoft Windows, также нельзя отмечать как Execute
Only из-за того, что они содержат ресурсы, подгружаемые после
запуска программы.
Во-вторых, никто не помешает злоумышленнику поймать вашу программу
в памяти уже после ее запуска. Для этого он может воспользоваться,
например, резидентными отладчиками, такими, как AFD или Turbo
Debugger. Так что не переоценивайте защиту при помощи атрибута
Execute Only.
Если вы случайно установили бит Execute Only для файла, содержащего
данные, можете смело удалять этот файл - вам никогда не удастся
сбросить бит Execute Only и прочитать содержимое файла.
Байт расширенных атрибутов имеет следующий формат:
Бит | Назначение |
0, 1, 2 | Search Mode: биты 0, 1 и 2 задают режим поиска программного файла при запуске программы на выполнение. Мы не будем рассматривать эти биты для сокращения объема книги, подробности о режимах поиска и дисках поиска вы можете узнать из руководства по библиотеке NetWare C Interface
|
3 | Зарезервировано |
4 | Transaction Bit: при работе с файлом используется обработка транзакций. Файл, у которого установлен этот бит, не может быть удален или переименован
|
5 | Index: для файла размером больше 2 Мбайт для более быстрого доступа организуется индекс по таблице FAT. Этот бит не используется в Novell NetWare версии 3.11
|
6 | Зарезервировано |
7 | Зарезервировано |
Для поиска файлов в каталоге вы можете воспользоваться функцией
_ScanFileInformation() (в документации по библиотеке Netware C
Interface эта функция называется ScanFileInformation(), однако
в самой библиотеке нет функции с этим названием, зато есть функция
_ScanFileInformation(), которая делает то же самое). Приведем
прототип функции:
int _ScanFileInformation(BYTE DirectoryHandle,
char *FilePath, BYTE SearchAttributes, int *SequenceNumber,
char *FileName, BYTE *FileAttributes,
BYTE *ExtendedFileAttributes, long *FileSize,
char *CreationDate, char *LastAccessDate,
char *LastUpdateDateAndTime, char *LastArchiveDateAndTime,
long *FileOwnerID);
Параметр DirectoryHandle при вызове функции может содержать индекс
просматриваемого каталога или ноль. В последнем случае путь к
просматриваемому каталогу должен быть задан через параметр FilePath
в виде текстовой строки, закрытой двоичным нулем.
Параметр SearchAttributes определяет, какие типы файлов нужно
найти. Этот параметр может принимать следующие значения:
Параметр | Значение |
0 | Обычные файлы |
2 | Обычные и скрытые файлы |
4 | Обычные и системные файлы
|
6 | Обычные, скрытые и системные файлы
|
Параметр SequenceNumber при первом вызове функции должен указывать
на переменную, которая имеет значение 0xFFFF. Когда программа
будет просматривать содержимое каталога, вызывая функцию в цикле,
содержимое этой переменной будет изменяться автоматически.
Параметр FileName должен указывать на буфер размером 15 байт,
в который будет записано имя найденного файла.
Атрибуты и расширенные атрибуты будут записаны в байты памяти,
которые необходимо указать при помощи параметров FileAttributes
и ExtendedFileAttributes.
Размер найденного файла будет записан в переменную, заданную при
помощи параметра FileSize.
Сведения о дате создания файла и дате последнего доступа к файлу
будут записаны в буферы размером 2 байта, заданные соответственно
параметрами CreationDate и LastAccessDate.
Дата и время последнего обновления содержимого файла будут записаны
в буфер размером 4 байта, заданный параметром LastUpdateDateAndTime,
а дата и время выгрузки - в аналогичный буфер, заданный параметром
LastArchiveDateAndTime.
Идентификатор пользователя, создавшего файл, будет записан в переменную
типа long, адрес которой задается параметром FileOwnerID. По этому
идентификатору с помощью функции GetBinderyObjectName() можно
получить имя пользователя.
Функция поиска файлов _ScanFileInformation() возвращает 0 при
успешном завершении или код ошибки:
Код ошибки | Значение |
0x89 | У программы нет прав для поиска файлов
|
0xFF | Файл не найден |
Для поиска файлов в каталоге можно использовать функцию E3h
прерывания INT 21h:
На входе: | AH | =
| E3h; |
| DS:SI | = |
Адрес буфера запроса; |
| ES:DI | = |
Адрес буфера ответа; |
На выходе: | AL | =
| Код ошибки или 0, если операция завершилась без ошибок.
|
Буфер запроса имеет следующий формат:
struct REQUEST {
WORD PacketLength; // размер пакета запроса
BYTE Function; // должно быть равно 15
WORD SequenceNumber; // номер для просмотра
BYTE DirectoryHandle; // индекс каталога
BYTE SearchAttributes; // тип файлов для поиска
BYTE PathLength; // длина поля пути
BYTE DirectoryPath[PathLength]; // путь к каталогу
};
Буфер ответа имеет следующий формат:
struct REPLAY {
WORD PacketLength; // размер пакета
WORD SequenceNumber; // номер для просмотра
BYTE FileName[15]; // имя файла
BYTE FileAttributes; // атрибуты файла
BYTE ExtendedFileAttributes; // расширенные
// атрибуты файла
long FileSize; // размер файла в байтах
BYTE CreationDate[2]; // дата создания
BYTE LastAccessDate[2]; // дата последнего доступа
BYTE LastUpdateDateAndTime[4]; // дата и время
// обновления
BYTE LastArchiveDateAndTime[4]; // дата и время
// выгрузки
BYTE Reserved[60]; // зарезервировано
};
При вызове этой функции в цикле в первый раз в поле SequenceNumber
буфера запроса необходимо записать значение 0xFFFF. При последующих
вызовах необходимо уменьшать на единицу значение, полученное в
поле SequenceNumber буфера ответа и записывать его в поле SequenceNumber
буфера запроса. Следует учитывать, что байты в поле SequenceNumber
записаны в обратном порядке, поэтому перед уменьшением необходимо
переставить байты. Это можно сделать при помощи функции IntSwap()
из библиотеки NetWare C Interface.
4.2.1. Программа FSCAN
Приведем программу FSCAN (листинг 17), которая выводит список
файлов, расположенных в каталоге, путь к которому задается в качестве
параметра при запуске программы. Для каждого найденного в каталоге
файла программа выводит имя файла, его размер, байт атрибутов
и байт расширенных атрибутов, а также имя пользователя, создавшего
файл.
// ===================================================
// Листинг 17. Просмотр списка файлов в каталоге
// Файл fscanfscan.cpp
//
// (C) A. Frolov, 1993
// ===================================================
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define BYTE unsigned char
#define WORD unsigned int
extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int _ScanFileInformation(BYTE, char *, BYTE, int *,
char *, BYTE *, BYTE *, long *,
char *, char *, char *, char *, long *);
extern "C" int GetBinderyObjectName(long, char *, WORD *);
void main(int argc, char *argv[]) {
char MajorVersion=0;
char MinorVersion=0;
char Revision=0;
int SequenceNumber;
char FileName[16];
BYTE FileAttributes;
BYTE ExtendedFileAttributes;
long FileSize;
BYTE CreationDate[2];
BYTE LastAccessDate[2];
BYTE LastUpdateDateAndTime[4];
BYTE LastArchiveDateAndTime[4];
long FileOwnerID;
int ccode;
char ObjectName[48];
WORD ObjectType;
printf("n*FSCAN* (C) Frolov A., 1993n");
// Проверяем наличие сетевой оболочки
asm push si
GetNetWareShellVersion(&MajorVersion,
&MinorVersion, &Revision);
asm pop si
if(MajorVersion == 0) {
printf("nОболочка NetWare не загруженаn");
return;
}
// В качестве аргумента необходимо задать
// путь к просматриваемому каталогу в виде SYS:USERS*
if(argc < 2) {
printf("Укажите путь к каталогу, "
"например: dirscan sys:users\*n");
return;
}
printf("Список файлов в каталоге %sn", argv[1]);
printf("--------------------------------------------"
"-------------n");
printf("Имя tРазмерtАтрибутыtВладелецn");
printf("--------------------------------------------"
"-------------n");
// Путь должен быть задан заглавными буквами
strupr(argv[1]);
// Цикл просмотра каталога
for(SequenceNumber = 0xFFFF;;) {
// Получаем информацию о содержимом каталога
ccode = _ScanFileInformation(0, argv[1], 6,
&SequenceNumber, FileName, &FileAttributes,
&ExtendedFileAttributes, &FileSize,
CreationDate, LastAccessDate, LastUpdateDateAndTime,
LastArchiveDateAndTime, &FileOwnerID);
// Если были ошибки, завершаем цикл
if(ccode) break;
if(FileName[0] == ' ') break;
// Выводим имя файла
printf("%-12s", FileName);
// Выводим размер файла
printf("t%ld", FileSize);
// Выводим байт атрибутов и байт расширенных атрибутов
printf("t%02.2X %02.2Xt", FileAttributes,
ExtendedFileAttributes);
// Если для каталога определен владелец,
// получаем и выводим имя владельца
if(FileOwnerID) {
GetBinderyObjectName(FileOwnerID,
ObjectName, &ObjectType);
printf("t%-12s n", ObjectName);
}
else
printf("t <Нет сведений о владельце> n");
}
}
Приведем фрагменты выдачи программы FSCAN при просмотре файлов
из каталога SYS:SYSTEM файл-сервера Novell NetWare версии 3.11:
*FSCAN* (C) Frolov A., 1993
Список файлов в каталоге sys:system*
---------------------------------------------------------
Имя Размер Атрибуты Владелец
---------------------------------------------------------
SYS$LOG.ERR 10852 20 00 SYSPRG
README.BTR 6689 00 00 SUPERVISOR
***************
CLIB.NLM 232842 81 00 SYSPRG
3C503.LAN 11856 81 00 SYSPRG
PS2MFM.DSK 8759 81 00 SYSPRG
INSTALL.NLM 160613 81 00 SYSPRG
NE2000.LAN 11636 81 00 SYSPRG
***************
BCONNLM.HLP 1583 81 00 SYSPRG
BROUTER.NLM 15884 81 00 SYSPRG
BTRIEVE.NLM 64616 01 00 SYSPRG
NET$OBJ.SYS 2560 26 10 FROLOV
BTRIEVE.TRN 4096 00 00 SYSPRG
PRODUCTS.DAT 5120 00 00 SYSPRG
AUTOEXEC.NCF 203 00 00 SYSPRG
MODEM.CFG 46 00 00 FROLOV
IBM$EMS.HLP 84047 00 00 FROLOV
IBM$DRV.OVL 2144 00 00 FROLOV
IBM$EMS.OVL 405 00 00 FROLOV
VIR.DAT 29934 20 00 FROLOV
NET$PROP.SYS 8364 26 10 FROLOV
NET$VAL.SYS 33654 26 10 FROLOV
NETSHLD.NLM 246146 20 00 FROLOV
VIR$CFG.DAT 838 20 00 SYSPRG
VIR$LOG.DAT 3146 20 00 SYSPRG
Файлы с атрибутами 00h и 20h - обычные файлы. Файлы с атрибутами
26h - скрытые и системные. Файл BTRIEVE.NLM имеет байт атрибутов
01, этот файл можно только читать. Файлы с атрибутом 81 - только
читаемые файлы, к которым возможен одновременный доступ со стороны
нескольких пользователей.
В приведенном выше списке есть файлы, у которых установлен бит
Transaction Bit. Для этих файлов включен механизм обработки транзакций,
гарантирующий сохранность содержимого файла при аварии в электропитающей
сети или по другим аналогичным причинам.
Для изменения атрибутов файлов, а также другой информации, такой,
как время создания файла и идентификатор владельца, можно воспользоваться
функцией SetFileInformation():
int SetFileInformation(BYTE DirectoryHandle,
char *FilePath, BYTE SearchAttributes,
BYTE FileAttributes,
BYTE ExtendedFileAttributes,
char *CreationDate, char *LastAccessDate,
char *LastUpdateDateAndTime,
char *LastArchiveDateAndTime,
long *FileOwnerID);
Параметры этой функции имеют такое же назначение, что и параметры
функции _ScanFileInformation(): с помощью параметров DirectoryHandle
и FilePath вы должны указать путь к файлу, остальные параметры
задают новые значения для атрибутов файла и другой информации,
имеющей отношение к файлу.
Функция SetFileInformation() возвращает 0 при успешном завершении
или код ошибки.
Для изменения атрибутов файлов и другой информации о файлах можно
использовать функцию E3h прерывания INT 21h:
На входе: | AH | =
| E3h; |
| DS:SI | = |
Адрес буфера запроса; |
| ES:DI | = |
Адрес буфера ответа. |
На выходе: | AL | =
| Код ошибки или 0, если операция завершилась без ошибок.
|
Буфер запроса имеет следующий формат:
struct REQUEST {
WORD PacketLength; // размер пакета запроса
BYTE Function; // должно быть равно 16
BYTE FileAttributes; // атрибуты файла
BYTE ExtendedFileAttributes; // расширенные
// атрибуты файла
long Reserved; // зарезервировано
BYTE CreationDate[2]; // дата создания
BYTE LastAccessDate[2]; // дата последнего доступа
BYTE LastUpdateDateAndTime[4]; // дата и время
// обновления
BYTE LastArchiveDateAndTime[4]; // дата и время выгрузки
BYTE Reserved[60]; // зарезервировано
BYTE DirectoryHandle; // индекс каталога
BYTE SearchAttributes; // тип файлов для поиска
BYTE PathLength; // длина поля пути
BYTE DirectoryPath[PathLength]; // путь к каталогу
};
Для изменения байта расширенных атрибутов удобно использовать
функцию SetExtendedFileAttributes():
int SetExtendedFileAttributes(char *FilePath,
BYTE *NewExtendedFileattributes);
Параметр FilePath задает путь к файлу, а параметр NewExtendedFileattributes
- новое значение для байта расширенных атрибутов.
Функция возвращает 0 при успешном завершении или код ошибки:
Код ошибки | Значение |
0xFE | У программы нет прав для изменения атрибута
|
0xFF | Файл не найден |
Для того чтобы узнать байт расширенного атрибута файла, используйте
функцию GetExtendedFileAttributes():
int GetExtendedFileAttributes(char *FilePath,
BYTE *ExtendedFileattributes);
Параметр FilePath задает путь к файлу, параметр ExtendedFileattributes
определяет адрес байта памяти, в который будет записано значение
байта расширенных атрибутов файла.
Функция возвращает 0 при успешном завершении или код ошибки:
Код ошибки | Значение |
0xFE | У программы нет прав для просмотра каталога
|
0xFF | Файл не найден |
Для получения и изменения расширенных атрибутов файла и можно
использовать функцию B6h прерывания INT 21h:
На входе: | AH | =
| B6h; |
| AL | = |
Выполняемая функция:
00h - получить байт расширенного атрибута;
01h - изменить байт расширенного атрибута;
|
| DS:DX | = |
Адрес буфера, содержащего путь к файлу; |
| CL | = |
Новое значение расширенного атрибута. |
На выходе: | AL | =
| 0, если операция завершилась без ошибок, или
код ошибки:
FCh - нет прав для выполнения функции;
FFh - файл не найден;
|
| CL | = |
Если при вызове функции регистр AL содержал значение 00h, в регистр CL будет записано значение расширенного атрибута указанного файла.
|
4.3.1. Программа SETEATTR
В программе SETEATTR (листинг 18) мы продемонстрируем использование
функции SetExtendedFileAttributes() для изменения байта расширенного
атрибута файла, путь к которому указывается в качестве параметра
при запуске программы.
// ===================================================
// Листинг 18. Изменение байта расширенных атрибутов
// Файл seteattrseteattr.cpp
//
// (C) A. Frolov, 1993
// ===================================================
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#define BYTE unsigned char
#define WORD unsigned int
extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int SetExtendedFileAttributes(char*, BYTE);
void main(int argc, char *argv[]) {
char MajorVersion=0;
char MinorVersion=0;
char Revision=0;
BYTE NewExtendedFileattributes;
int ccode;
printf("n*SETEATTR* (C) Frolov A., 1993n");
// Проверяем наличие сетевой оболочки
asm push si
GetNetWareShellVersion(&MajorVersion,
&MinorVersion, &Revision);
asm pop si
if(MajorVersion == 0) {
printf("nОболочка NetWare не загруженаn");
return;
}
// Необходимо задать путь к каталогу, удаляемые
// и добавляемые права доступа
if(argc < 3) {
printf("Укажите путь к каталогу и "
"устанавливаемый бит (T или I), "
"nнапример: seteattr sys:usersmy.dat T");
return;
}
// Параметры должны быть заданы заглавными буквами
strupr(argv[1]);
strupr(argv[2]);
// Определяем значение байта расширенных атрибутов
NewExtendedFileattributes = 0x00;
for(int i = 0; argv[2][i] != ' ' ; i++) {
switch(argv[2][i]) {
case 'T':
NewExtendedFileattributes |= 0x10; break;
case 'I':
NewExtendedFileattributes |= 0x20; break;
case '-':
NewExtendedFileattributes = 0; break;
default:
printf("Ошибка в параметрахn");
return;
}
}
// Изменяем байт расширенных атрибутов
ccode = SetExtendedFileAttributes(argv[1],
NewExtendedFileattributes);
if(!ccode)
printf("Байт расширенных атрибутов измененn");
else
printf("Ошибка %02.2Xn", ccode);
}
Ваша программа может копировать файлы либо с локального диска
на локальный, либо с локального на сетевой, либо с сетевого на
сетевой. Если файл копируется из одного сетевого каталога в другой
сетевой каталог, причем эти каталоги расположены на одном файл-сервере,
для копирования имеет смысл использовать специальную функцию FileServerFileCopy().
В этом случае процесс копирования будет выполняться непосредственно
на файл-сервере, без передачи файла по сети.
Приведем прототип функции FileServerFileCopy():
int FileServerFileCopy(int FromHandle, int ToHandle,
long SourceFileOffset, long DestinationFileOffset,
long NumberOfBytesToCopy, long *BytesCopied);
Параметры FromHandle и ToHandle указывают индексы файлов, участвующих
в процессе копирования. Данные копируются из файла, задаваемого
параметром FromHandle в файл, задаваемый параметром ToHandle.
Индексы файлов должны быть получены при помощи вызова функции
MS-DOS с кодом 3Dh (открыть файл). Если файла, в который будут
копироваться данные, нет на диске, его необходимо создать и открыть
при помощи функции MS-DOS с кодом 3Ch. В программе, составленной
на языке Си, вы можете использовать для открытия и создания файлов
функцию open(), входящую в стандартную библиотеку транслятора.
Параметры SourceFileOffset и DestinationFileOffset задают смещение
в исходном и выходном файлах. Если вы копируете файл в новый,
эти параметры должны иметь нулевое значение.
Параметр NumberOfBytesToCopy задает количество копируемых байт.
Если вам надо скопировать весь файл, его длину можно узнать по
индексу файла при помощи функции filelength() из стандартной библиотеки
транслятора.
Параметр BytesCopied - указатель на переменную, в которую будет
записано количество действительно скопированных байт.
Функция возвращает 0 при успешном завершении или код ошибки:
Код ошибки | Значение |
0x83 | Ошибка ввода/вывода на сетевом диске
|
0x96 | Мало оперативной памяти на файл-сервере
|
Для копирования файлов можно использовать функцию F3h прерывания
INT 21h:
На входе: | AH | =
| F3h; |
| ES:DI | = |
Адрес буфера запроса. |
На выходе: | AL |
| Код ошибки или 0, если операция завершилась без ошибок;
|
| DX,CX | = |
Количество скопированный байт. Старший байт находится в регистре DX, младший - в регистре CX.
|
Буфер запроса имеет следующий формат:
struct REQUEST {
WORD FromHandle; // индекс входного файла
WORD ToHandle; // индекс выходного файла
long SourceFileOffset; // смещение входного файла
long DestinationFileOffset; // смещение выходного файла
long NumberOfBytesToCopy; // сколько байт копировать
};
4.4.1. Программа FCOPY
Программа FCOPY (листинг 19) демонстрирует использование функции
FileServerFileCopy(). При запуске этой программе необходимо в
качестве параметров указать пути к входному и выходному файлам.
// =============================================================
// Листинг 19. Копирование файлов, расположенных на файл-сервере
// Файл fcopyfcopy.cpp
//
// (C) A. Frolov, 1993
// =============================================================
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <sysstat.h>
extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int FileServerFileCopy(int, int, long, long, long, long*);
void main(int argc, char *argv[]) {
char MajorVersion=0;
char MinorVersion=0;
char Revision=0;
int FromHandle;
int ToHandle;
long BytesCopied;
int ccode;
printf("n*FCOPY* (C) Frolov A., 1993n");
// Проверяем наличие сетевой оболочки
asm push si
GetNetWareShellVersion(&MajorVersion,
&MinorVersion, &Revision);
asm pop si
if(MajorVersion == 0) {
printf("nОболочка NetWare не загруженаn");
return;
}
// Необходимо задать путь к каталогу, удаляемые
// и добавляемые права доступа
if(argc < 3) {
printf("Укажите пути к копируемым файлам, "
"nнапример: fcopy f:usersmy.dat f:usmy.dat");
return;
}
// Параметры должны быть заданы заглавными буквами
strupr(argv[1]);
strupr(argv[2]);
// Открываем входной файл в двоичном режиме для чтения
if ((FromHandle = open(argv[1], O_RDONLY | O_BINARY)) == -1)
{
printf("Не могу открыть исходный файлn");
return;
}
// Открываем выходной файл в двоичном режиме для чтения
// и записи, разрешаем создание файла, если его еще нет,
// разрешаем запись в файл
if ((ToHandle = open(argv[2],
O_CREAT | O_RDWR | O_BINARY, S_IWRITE)) == -1) {
printf("Не могу открыть выходной файлn");
return;
}
// Копируем файл, длину файла определяем при помощи
// функции filelength()
ccode = FileServerFileCopy(FromHandle, ToHandle,
0, 0, filelength(FromHandle), &BytesCopied);
if(!ccode)
printf("Файл скопированn");
else
printf("Ошибка %02.2Xn", ccode);
// Закрываем файлы
close(FromHandle);
close(ToHandle);
}
Для удаления файлов из сетевых каталогов можно использовать функцию
EraseFiles():
int EraseFiles(BYTE DirectoryHandle,
char *FilePath, BYTE SearchAttributes);
Эта функция удаляет файл, заданный параметрами DirectoryHandle
и FilePath, если его атрибуты соответствуют указанным при помощи
параметра SearchAttributes. Последнее означает, что, если вы собираетесь
стирать нормальные, скрытые и системные файлы, для параметра SearchAttributes
необходимо задать значение 06h.
Функция возвращает 0 при успешном завершении или код ошибки:
Код ошибки | Значение |
0x98 | Указанный сетевой том не существует
|
0x9B | Индекс файла указан неправильно
|
0x9C | Путь к файлу указан неправильно
|
0xFF | Файл не найден |
4.5.1. Программа FERASE
Программа FERASE (листинг 20) демонстрирует использование функции
EraseFiles(). При запуске программе в качестве параметра необходимо
передать путь к удаляемому файлу.
// ===================================================
// Листинг 20. Удаление файлов
// Файл feraseferase.cpp
//
// (C) A. Frolov, 1993
// ===================================================
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BYTE unsigned char
#define WORD unsigned int
extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int EraseFiles(BYTE, char*, BYTE);
void main(int argc, char *argv[]) {
char MajorVersion=0;
char MinorVersion=0;
char Revision=0;
int ccode;
printf("n*FERASE* (C) Frolov A., 1993n");
// Проверяем наличие сетевой оболочки
asm push si
GetNetWareShellVersion(&MajorVersion,
&MinorVersion, &Revision);
asm pop si
if(MajorVersion == 0) {
printf("nОболочка NetWare не загруженаn");
return;
}
// Необходимо задать путь к каталогу, удаляемые
// и добавляемые права доступа
if(argc < 2) {
printf("Укажите путь к удаляемому файлу,"
"nнапример: ferase sys:usersmy.dat");
return;
}
// Параметр должен быть задан заглавными буквами
strupr(argv[1]);
ccode = EraseFiles(0, argv[1], 6);
if(!ccode)
printf("Файл %s удаленn", argv[1]);
else
printf("Ошибка %02.2Xn", ccode);
}
|