Локальные сети персональных компьютеров. Работа с сервером Novell NetWare© Александр Фролов, Григорий ФроловТом 4, М.: Диалог-МИФИ, 1993, 168 стр. 3.1. Таблица томов файл-сервераКаждый файл-сервер хранит информацию о сетевых томах в таблице томов (Volume Table), состоящей из 256 элементов. Номера элементов используются для адресации томов и называются номерами томов (Volume Number). Зная номер тома, программа может получить такие важные характеристики тома, как его объем, размер свободного пространства на томе, максимальное количество каталогов, которое можно создать на томе, количество уже созданных каталогов. Кроме того, программа может определить, является ли данный том файл-сервера съемным. Одна из важных задач - определение имен и номеров томов, смонтированных на файл-сервере. Для определения имен смонтированных томов лучше всего воспользоваться функцией GetVolumeName() из библиотеки NetWare C Interface: int GetVolumeName(int VolumeNumber, char*VolumeName); Первый параметр функции задает номер тома, для которого необходимо получить имя. На сервере Novell NetWare версии 2.2 можно создать 32 тома, версия 3.11 допускает существование 64 томов. Поэтому диапазон возможных значений для первого параметра в зависимости от версии NetWare может быть от 0 до 31 или от 0 до 63. Второй параметр - указатель на буфер размером 16 байт, в который будет записано имя тома. В случае ошибки функция возвращает ненулевое значение. Например, если вы укажете недопустимый номер тома, функция возвратит значение 0x98. Для определения списка смонтированных томов вы можете вызывать эту функцию в цикле, задавая ей номера томов в диапазоне от 0 до 63. Если функция вернет ненулевое значение или если на месте первой буквы имени тома будет двоичное нулевое значение, то это означает, что на данном сервере больше нет смонтированных томов. Можно решить и обратную задачу - по имени тома определить его номер. Для этого предназначена функция GetVolumeNumber(): int GetVolumeNamber(char*VolumeName, int *VolumeNumber); Для тома, имя которого задается первым параметром, функция определяет номер тома и записывает его по адресу, заданному вторым параметром. Если функция вернет ненулевое значение, указанному номеру тома не соответствует никакой том. Для получения справочной информации о томе удобно воспользоваться функцией GetVolumeInfoWithNumber(): int GetVolumeInfoWithNumber(BYTE VolumeNumber, char *VolumeName, WORD *TotalBlocks, WORD *SectorsPerBlock, WORD *AvailableBlocks, WORD *TotalDirectorySlots, WORD *AvailableDirectorySlots, WORD *Removable); Для тома, номер которого задан параметром VolumeNumber, функция возвращает имя, записывая его по адресу, указанному параметром VolumeName, общее количество блоков (параметр TotalBlocks), количество секторов в одном блоке (параметр SectorsPerBlock), количество свободных блоков (параметр AvailableBlocks), количество каталогов, имеющихся на томе (параметр TotalDirectorySlots), количество каталогов, которые можно дополнительно создать на томе (параметр AvailableDirectorySlots), признак того, что том является съемным (параметр Removable). При использовании этой функции следует учесть, что она предоставляет информацию только о тех серверах, к которым пользователь подключен. Если рабочая станция создала канал с сервером, но не подключилась к нему, функция вернет код ошибки 252. Размер сектора составляет 512 байт, что вы можете использовать для подсчета объема тома в килобайтах. Если переменная, адрес которой указан параметром Removable, получила значение 0, это означает, что соответствующий том несъемный. В следующем разделе мы приведем исходный текст программы, которая для текущего сервера (или первичного сервера, если текущий сервер не определен) выводит список смонтированных томов. Для каждого тома программа выводит его объем в килобайтах и размер имеющегося на томе свободного пространства. Информация о томах может быть получена и без использования описанных выше функций библиотеки NetWare C Interface. Для определения соответствия между номером тома и именем тома можно воспользоваться функцией E2h прерывания INT 21h:
Буфер запроса имеет следующий формат: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 6 BYTE VolumeNumber; // номер тома }; В этом буфере вам надо заполнить все поля, указав размер буфера и номер тома, для которого необходимо получить имя. Код функции в поле Function должен иметь значение 6. Приведем формат буфера ответа: struct REPLAY { WORD PacketLength; // размер пакета BYTE VolumeNameLength; // длина имени тома BYTE VolumeName[16]; // имя тома }; Если указанному номеру тома не соответствует ни один том, поле VolumeNameLength будет содержать нулевое значение. Для выполнения обратной операции - получения номера тома по его имени - можно воспользоваться той же функцией E2h прерывания INT 21h. Но формат буферов запроса и ответа будет другой. Формат буфера запроса: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 5 BYTE NameLength; // длина имени тома BYTE VolumeName[16]; // имя тома }; В этом буфере вам надо указать размер буфера, длину имени тома и имя тома, для которого необходимо получить номер имени. Код функции в поле Function должен иметь значение 5. Приведем формат буфера ответа: struct REPLAY { WORD PacketLength; // размер пакета BYTE VolumeNumber; // номер имени тома }; Если том, имя которого указано в буфере запроса, смонтирован, регистр AL после возврата из функции будет равен нулю. Для получения информации о смонтированном томе по номеру тома можно воспользоваться функцией DAh прерывания INT 21h:
Буфер ответа имеет следующий формат: struct REPLAY { WORD SectorsPerBlock; WORD TotalBlocks; WORD AvailableBlocks; WORD TotalDirectorySlots; WORD AvailableDirectorySlots; BYTE VolumeName[16]; WORD Removable; }; Назначение полей этой структуры аналогично назначению параметров функции GetVolumeInfoWithNumber(). 3.1.1. Программа VOLINFOПриведем исходный текст программы, которая выводит список смонтированных томов для текущего сервера. Если текущий диск локальный, программа выходит информацию о первичном сервере. Программа в цикле с помощью функции GetVolumeName() получает имена смонтированных томов. Если первый байт имени тома содержит двоичный ноль, программа выходит из цикла. Для каждого тома программа получает информацию о томе, вызывая функцию GetVolumeInfoWithNumber(). // =================================================== // Листинг 7. Программа для просмотра имен // томов текущего или первичного файл-сервера // Файл volinfo\volinfo.cpp // // (C) A. Frolov, 1993 // =================================================== #include <stdlib.h> #include <stdio.h> #define WORD unsigned int #define BYTE unsigned char extern "C" int GetNetWareShellVersion(char *,char *, char *); extern "C" int GetVolumeName(int, char*); extern "C" int GetVolumeInfoWithNumber(BYTE, char*, WORD*, WORD*, WORD*, WORD*, WORD*, WORD*); void main(void) { char MajorVersion=0; char MinorVersion=0; char Revision=0; char VolumeName[64][16]; int ccode, i; WORD TotalBlocks, SectorsPerBlock, AvailableBlocks; WORD TotalDirectorySlots, AvailableDirectorySlots, Removable; long TotalSectors, AvailableSectors; printf("\n*VOLINFO* (C) Frolov A., 1993\n"); asm push si GetNetWareShellVersion(&MajorVersion, &MinorVersion, &Revision); asm pop si if(MajorVersion == 0) { printf("\nОболочка NetWare не загружена\n"); return; } printf("\nСмонтированные тома:\n" "----------------------------------------------\n"); printf("Имя тома\tВсего Кбайт\tСвободно Кбайт\n"); printf("----------------------------------------------"); // Цикл по томам файл-сервера. for(i=0; i<64; i++) { // Получаем и выводим имя тома ccode = GetVolumeName(i, VolumeName[i]); printf("\n%s\t", VolumeName[i]); // Если ошибка или тома нет, выходим из цикла if(ccode) break; if(!*(VolumeName[i])) break; // Получаем информацию о томе ccode = GetVolumeInfoWithNumber(i, VolumeName[i], &TotalBlocks, &SectorsPerBlock, &AvailableBlocks, &TotalDirectorySlots,&AvailableDirectorySlots, &Removable); if(!ccode) { // Подсчитываем общее количество секторов на томе // и количество свободных секторов TotalSectors = (long)TotalBlocks * SectorsPerBlock; AvailableSectors = (long)AvailableBlocks * SectorsPerBlock; // Выводим размер томов и размер свободного пространства // в килобайтах. Учитываем, что размер сектора // составляет 512 байт. printf("\t%ld\t\t%ld", ((long)TotalSectors * 512L) / 1024L, ((long)AvailableSectors * 512L) / 1024L); } } } Вот что программа VOLINFO вывела на экран, когда мы запустили ее на нашем сервере SYSPRG: *VOLINFO* (C) Frolov A., 1993 Смонтированные тома: ---------------------------------------------- Имя тома Всего Кбайт Свободно Кбайт ---------------------------------------------- SYS 140000 8084 VOL1 178864 13768 VOL2 160000 13372 VOL3 169024 924 |