Локальные сети персональных компьютеров. Работа с сервером Novell NetWare

       

Таблица каталогов файл-сервера


Вся информация о содержимом каталогов файл-сервера находится в таблице каталогов. Таблица каталогов по своему назначению напоминает каталоги MS-DOS: в ней находится информация об именах каталогов и файлов, байты атрибутов, информация о дате создания, идентификатор пользователя, создавшего файл или каталог, информация о правах доступа и т. д.
Для просмотра каталогов в операционной системе MS-DOS имеются соответствующие функции, о чем мы рассказывали в первом томе "Библиотеки системного программиста". Разумеется, программа может просматривать сетевые каталоги с помощью этих функций. Однако если вы воспользуетесь функциями, специально предназначенными для просмотра содержимого каталогов, вы сможете узнать имя пользователя, создавшего каталог или файл, а также получить информацию о правах доступа к каталогу или файлу.
Сетевая оболочка Novell NetWare имеет две разные функции для поиска подкаталогов в каталоге и для поиска файлов в каталоге (MS-DOS получает информацию сразу и о файлах, и о подкаталогах). В этом разделе мы расскажем о поиске каталогов, а файлами займемся позже, в главе "Работа с файлами".
Библиотека NetWare C Interface содержит функцию ScanDirectoryInformation(), предназначенную для просмотра содержимого каталогов. С ее помощью вы можете получить информацию о подкаталогах любого сетевого каталога.
Приведем прототип функции: int ScanDirectoryInformation(BYTE DirectoryHandle, char *SearchDirectoryPath, int *SequenceNumber, char *DirectoryName, BYTE *CreationDateAndTime, long *OwnerObjectID, BYTE *MaximumRightsMask);
С помощью параметров DirectoryHandle и SearchDirectoryPath задается каталог, содержимое которого надо просмотреть. Параметр DirectoryHandle - это индекс в таблице дисков, которую файл-сервер поддерживает для каждой рабочей станции. Когда диск рабочей станции отображается на каталог файл-сервера, создается новый элемент в таблице дисков файл-сервера. Индекс DirectoryHandle однозначно соответствует сетевому каталогу, на который отображается локальный диск рабочей станции.
Вы можете задать в качестве параметра DirectoryHandle нулевое значение, при этом параметр SearchDirectoryPath должен указывать на текстовую строку, содержащую полный путь к исследуемому каталогу. В строке могут использоваться символы "*" и "?", которые трактуются так же, как и в MS-DOS. Например, для поиска всех подкаталогов каталога SYS:USERS вы можете задать 0 в поле DirectoryHandle и строку "SYS:USERS\*" в поле SearchDirectoryPath.
Имя файл-сервера не указывается, так как запрос направляется к предпочтительному, текущему или первичному серверу, в зависимости от того, существует ли предпочтительный сервер или текущий сервер. Если был задан предпочтительный сервер, функция ScanDirectoryInformation() обращается к предпочтительному серверу. Если предпочтительный сервер не был задан и на рабочей станции текущим является диск, отображенный на сетевой каталог, функция ScanDirectoryInformation() обращается к файл-серверу, содержащему этот каталог. Если текущий диск рабочей станции является локальным, функция ScanDirectoryInformation() обращается к первичному серверу.
Параметр SequenceNumber - указатель на слово, которое должно содержать нулевое значение при первом вызове функции ScanDirectoryInformation(). Для получения информации о всех подкаталогах вам придется вызывать эту функцию в цикле, при этом слово, на которое указывает параметр SequenceNumber, будет автоматически увеличиваться самой функцией.
Остальные четыре параметра - указатели на переменные, в которые будут записаны возвращаемые значения.
В область памяти, на которую указывает параметр DirectoryName, после успешного вызова функции будет записано имя обнаруженного подкаталога. Размер этой области памяти должен составлять 16 байт. Вызывая в цикле функцию ScanDirectoryInformation(), программа будет получать в поле, адресуемом параметром DirectoryName, имена найденных подкаталогов.
Параметр CreationDateAndTime указывает на область памяти, размером 4 байта, в которую будет записана информация о дате и времени создания найденного подкаталога. На Рисунок 1 приведен формат этой информации. К номеру года, возвращенному в первом байте, необходимо добавить число 80.



Рисунок 1. Формат даты и времени
Параметр OwnerObjectID - указатель на слово, в котором будет записан идентификатор пользователя, создавшего каталог. По этому идентификатору с помощью функции GetBinderyObjectName() вы легко сможете получить имя пользователя.
Параметр MaximumRightsMask - указатель на байт, в который будет записано значение маски прав доступа, связанное с данным каталогом. Маска используется для определения возможности доступа к каталогу и определяется при создании каталога. Каждый бит маски, установленный в 1, разрешает соответствующий вид доступа:
Номер битаДоступ
0Чтение файлов
1Запись в файлы
2Открытие файлов
3Создание файлов
4Удаление файлов
5Можно создавать подкаталоги и задавать для создаваемых подкаталогов права доступа
6Поиск файлов в каталоге
7Изменение атрибутов файлов

Функция ScanDirectoryInformation() при успешном завершении возвращает нулевое значение, в противном случае - код ошибки:
Код ошибкиЗначение
0x98Заданный сетевой том не существует
0x9BНеправильное значение параметра индекса каталога
0x9CНеправильный путь к каталогу

Для просмотра подкаталогов в заданном каталоге вместо функции ScanDirectoryInformation() можно использовать функцию E2h прерывания INT 21h:
На входе:AH= E2h;
DS:SI= Адрес буфера запроса;
ES:DI Адрес буфера ответа.
На выходе:AL Код ошибки или 0, если операция завершилась без ошибок.

Буфер запроса имеет следующий формат: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 2 BYTE DirectoryHandle; // индекс каталога WORD SequenceNumber; // порядковый номер BYTE PathLength; // длина поля пути BYTE SearchDirectoryPath[PathLength]; // путь поиска };
Приведем формат буфера ответа: struct REPLAY { WORD PacketLength; // размер пакета BYTE DirectoryName[16]; // имя найденного каталога BYTE CreationDate[2]; // дата создания каталога BYTE CreationTime[2]; // время создания каталога long OwnerObjectID; // идентификатор пользователя, // создавшего каталог BYTE MaximumRightsMask; // маска прав доступа BYTE Reserved; // зарезервировано WORD SubDirNumber; // номер подкаталога в // каталоге };
В процессе просмотра содержимого каталога программа должна вызывать эту функцию в цикле, задавая каждый раз (кроме первого) значение поля SequenceNumber в буфере запроса равным значению SubDirNumber, полученному в буфере ответа после предыдущего вызова функции. При первом вызове функции значение поля SequenceNumber должно быть равно нулю. Учтите, что поля SubDirNumber и SequenceNumber имеют "перевернутый" формат, т. е. младший байт поля записан по старшему адресу.
Если при вызове функции был найден подкаталог, соответствующий образцу, заданному в поле SearchDirectoryPath, регистр AL будет содержать нулевое значение.

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