В этом разделе мы расскажем вам об использовании некоторых, самых интересных, на наш взгляд, функций сетевой оболочки 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.
Приведем программу FSCAN (листинг 17), которая выводит список файлов, расположенных в каталоге, путь к которому задается в качестве параметра при запуске программы. Для каждого найденного в каталоге файла программа выводит имя файла, его размер, байт атрибутов и байт расширенных атрибутов, а также имя пользователя, создавшего файл.
// =================================================== // Листинг 17. Просмотр списка файлов в каталоге // Файл fscan\fscan.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., 1993\n"); // Проверяем наличие сетевой оболочки 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("Список файлов в каталоге %s\n", 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] == '\0') break; // Выводим имя файла printf("%-12s", FileName); // Выводим размер файла printf("\t%ld", FileSize); // Выводим байт атрибутов и байт расширенных атрибутов printf("\t%02.2X %02.2X\t", 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 |
= |
Выполняемая функция: |
|
DS:DX |
= |
Адрес буфера, содержащего путь к файлу; |
|
CL |
= |
Новое значение расширенного атрибута. |
|
На выходе: |
AL |
= |
0, если операция завершилась без ошибок,
или |
CL |
= |
Если при вызове функции регистр AL
содержал значение 00h, в регистр CL будет записано
значение расширенного атрибута указанного
файла. |
В программе SETEATTR (листинг 18) мы продемонстрируем использование функции SetExtendedFileAttributes() для изменения байта расширенного атрибута файла, путь к которому указывается в качестве параметра при запуске программы.
// =================================================== // Листинг 18. Изменение байта расширенных атрибутов // Файл seteattr\seteattr.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., 1993\n"); // Проверяем наличие сетевой оболочки 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:users\my.dat T"); return; } // Параметры должны быть заданы заглавными буквами strupr(argv[1]); strupr(argv[2]); // Определяем значение байта расширенных атрибутов NewExtendedFileattributes = 0x00; for(int i = 0; argv[2][i] != '\0' ; 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.2X\n", 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; // сколько байт копировать };
Программа FCOPY (листинг 19) демонстрирует использование функции FileServerFileCopy(). При запуске этой программе необходимо в качестве параметров указать пути к входному и выходному файлам.
// ============================================================= // Листинг 19. Копирование файлов, расположенных на файл-сервере // Файл fcopy\fcopy.cpp // // (C) A. Frolov, 1993 // ============================================================= #include <stdlib.h> #include <stdio.h> #include <string.h> #include <fcntl.h> #include <io.h> #include <sys\stat.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., 1993\n"); // Проверяем наличие сетевой оболочки 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:\users\my.dat f:\us\my.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.2X\n", ccode); // Закрываем файлы close(FromHandle); close(ToHandle); }
Для удаления файлов из сетевых каталогов можно использовать функцию EraseFiles():
int EraseFiles(BYTE DirectoryHandle, char *FilePath, BYTE SearchAttributes);
Эта функция удаляет файл, заданный параметрами DirectoryHandle и FilePath, если его атрибуты соответствуют указанным при помощи параметра SearchAttributes. Последнее означает, что, если вы собираетесь стирать нормальные, скрытые и системные файлы, для параметра SearchAttributes необходимо задать значение 06h.
Функция возвращает 0 при успешном завершении или код ошибки:
Код ошибки |
Значение |
0x98 |
Указанный сетевой том не существует |
0x9B |
Индекс файла указан неправильно |
0x9C |
Путь к файлу указан неправильно |
0xFF |
Файл не найден |
Программа FERASE (листинг 20) демонстрирует использование функции EraseFiles(). При запуске программе в качестве параметра необходимо передать путь к удаляемому файлу.
// =================================================== // Листинг 20. Удаление файлов // Файл ferase\ferase.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., 1993\n"); // Проверяем наличие сетевой оболочки 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:users\my.dat"); return; } // Параметр должен быть задан заглавными буквами strupr(argv[1]); ccode = EraseFiles(0, argv[1], 6); if(!ccode) printf("Файл %s удален\n", argv[1]); else printf("Ошибка %02.2X\n", ccode); }