Отображение дисков рабочей станции
Для обеспечения возможности работы с файлами, расположенными на дисках файл-сервера, сетевая оболочка выполняет отображение локальных дисков рабочей станции на сетевые каталоги. При этом прикладная программа, запущенная на рабочей станции, может и не заметить, что она работает не с локальным диском, а с удаленным. Разумеется, для обеспечения возможности отображения пользователь должен подключиться к файл-серверу, сообщив ему свое имя и пароль. В предыдущей главе вы научились составлять программы, подключающие пользователя к файл-серверу.
Дополнительно к таблице номеров каналов серверов сетевая оболочка работает еще с тремя таблицами, необходимыми для отображения дисков. Это таблица флагов дисковых устройств (Drive Flag Table), таблица номеров каналов дисковых устройств (Drive Connection ID Table) и таблица индексов дисковых устройств (Drive Handle Table).
Эти таблицы могут отображать 32 дисковых устройства, все они имеют размер 32 байта, по одному байту на одно устройство.
У вас может возникнуть вопрос: почему 32 дисковых устройства, а не 26? Действительно, MS-DOS позволяет вам использовать только 26 дисковых устройств, обозначая их буквами в диапазоне от A до Z. Сетевая оболочка добавляет еще шесть устройств, которые обычно используются в качестве временных логических дисков, отображаемых на сетевые каталоги только на время работы программы. Для обозначения этих дополнительных дисков сетевая оболочка использует следующие символы:
[ | левая квадратная скобка; |
\ | обратный слеш; |
] | правая квадратная скобка; |
^ | символ caret (знак для вставки); |
_ | подчеркивание; |
' | апостроф. |
Таблица флагов дисковых устройств (Drive Flag Table) содержит байты состояния для каждого дискового устройства рабочей станции. Пользуясь этой таблицей, программа может определить, какие диски рабочей станции локальные, а какие отображены на сетевые каталоги. Приведем список возможных значений элементов таблицы флагов:
0 | Диска нет, т. е. этот диск не отображен ни на локальный диск, ни на удаленный сетевой каталог |
01h | Диск постоянно отображен на сетевой каталог |
02h | Диск временно отображен на сетевой каталог (временное отображение действует только во время работы программы; когда программа завершается, отображение автоматически отменяется) |
80h | Локальный диск рабочей станции |
81h | Локальный диск рабочей станции, постоянно отображенный на сетевой каталог |
82h | Локальный диск рабочей станции, временно отображенный на сетевой каталог |
Когда программа обращается к диску, сетевая оболочка просматривает таблицу флагов и определяет, с каким диском надо работать - с отображенным или локальным.
Для того чтобы определить, на каталог какого сервера отображен тот или иной диск, программа может использовать таблицу номеров каналов дисковых устройств (Drive Connection ID Table). В этой таблице для каждого диска указан номер канала, который сетевая оболочка рабочей станции использует для работы с сервером, на чей каталог отображен данный диск. Если диск локальный или его нет совсем, для такого диска в таблице находится нулевое значение. Так как рабочая станция может образовать до 8 каналов, таблица номеров каналов дисковых устройств может содержать значения от 1 до 8 (или 0 для неиспользуемых дисков).
Таблица индексов дисковых устройств (Drive Handle Table) имеет отношение к таблице каталогов, расположенной в файл-сервере. Для каждого канала файл-сервер заводит отдельную таблицу индексов дисковых устройств, в которой содержится информация о томе и каталоге, на который отображается соответствующий диск рабочей станции. Подробнее об этом мы расскажем ниже в разделе "Таблица каталогов файл-сервера".
Вы можете отобразить диск рабочей станции на сетевой каталог при помощи функции AllocPermanentDirectoryHandle(), которая создает новый элемент в таблице индексов каталога, расположенной на файл-сервере. Кроме того, эта функция изменяет содержимое всех таблиц сетевой оболочки, имеющих отношение к отображению дисков рабочей станции.
Приведем прототип функции AllocPermanentDirectoryHandle(): int AllocPermanentDirectoryHandle(BYTE DirectoryHandle, char *DirectoryPath, char DriveLetter, BYTE *NewDirectoryHandle, BYTE *EffectiveRightsMask);
Вы можете указать путь к отображаемому сетевому каталогу либо с помощью индекса каталога через параметр DirectoryHandle, либо через полный путь к каталогу (параметр DirectoryPath), либо используя комбинированный способ. Впрограмме DIRMAP, демонстрирующей применение этой функции (см. ниже), мы указали полный путь к отображаемому каталогу при помощи параметра DirectoryPath, а для параметра DirectoryHandle мы задали нулевое значение.
Параметр DriveLetter задает отображаемый диск. Если этот диск до вызова функции AllocPermanentDirectoryHandle() отображался на другой сетевой каталог или был локальным диском рабочей станции, это никак не скажется на успехе или результате отображения.
Параметр NewDirectoryHandle - указатель на переменную, в которую будет записан индекс, связанный с отображаемым каталогом. Вы можете использовать этот индекс для ссылки на каталог вместо полного имени каталога. Он будет нужен также для отмены отображения диска.
Параметр EffectiveRightsMask - указатель на байт памяти, в который будет записана маска прав доступа пользователя в данном каталоге. Назначение отдельных битов этой маски мы рассмотрим ниже в разделе "Таблица каталогов файл-сервера".
Отображение диска сохраняется до тех пор, пока оно не будет отменено функцией DeallocateDirectoryHandle(): int DeallocateDirectoryHandle(BYTE DirectoryHandle);
Эта функция отменяет отображение диска на каталог, имеющий индекс DirectoryHandle.
Для того чтобы отменить отображение диска, пользуясь его буквенным обозначением, можно воспользоваться функцией GetDirectoryHandle(), возвращающей индекс каталога для диска, заданного своим номером (0 - A, 1 - B и т. д.): DirectoryHandle = GetDirectoryHandle(argv[1][0] - 'A');
Для отображения локального диска на сетевой каталог вместо функции AllocPermanentDirectoryHandle() можно воспользоваться функцией E2h прерывания INT 21h:
На входе: | AH | = | E2h; |
DS:SI | = | Адрес буфера запроса; | |
ES:DI | = | Адрес буфера ответа. | |
На выходе: | AL | = | Код ошибки или 0, если операция завершилась без ошибок. |
Буфер запроса имеет следующий формат: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 18 BYTE DirectoryHandle; // индекс каталога BYTE DriveLetter; // отображаемый диск BYTE PathLength; // длина пути к каталогу BYTE DirectoryPath[PathLength]; // путь к каталогу };
Приведем формат буфера ответа: struct REPLAY { WORD PacketLength; // размер пакета BYTE NewDirectoryHandle; // новый индекс каталога BYTE EffectiveRightsMask ; // маска прав доступа };
Для отмены отображения диска вместо функции DeallocateDirectoryHandle можно использовать функцию E2h прерывания INT 21h, заполнив буфер запроса следующим образом: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 20 BYTE DirectoryHandle; // индекс каталога };
До сих пор мы рассматривали так называемое постоянное отображение дисков на сетевые каталоги. Это отображение сохраняется до тех пор, пока оно не будет отменено вызовом соответствующей функции. Однако вы можете заказать временное отображение, которое будет отменено автоматически после завершения работы программы, создавшей временное отображение.
Временное отображение выполняется функцией AllocTemporaryDirectoryHandle(): int AllocTemporaryDirectoryHandle(BYTE DirectoryHandle, char *DirectoryPath, char DriveLetter, BYTE *NewDirectoryHandle, BYTE *EffectiveRightsMask);
Параметры этой функции полностью аналогичны параметрам функции AllocPermanentDirectoryHandle(). Дополнительно к дискам с именами A - Z вы можете использовать диски, обозначаемые следующими символами: [, \, ], ^, _, '.
Для временного отображения диска на сетевой каталог вы можете воспользоваться функцией E2h прерывания INT 21h. Вам надо заполнить буфер запроса аналогично тому, как это нужно для создания постоянного отображения, но в поле Function необходимо указать значение 19. Формат буфера ответа полностью аналогичен формату, используемому при постоянном отображении.
Для получения адресов таблиц можно воспользоваться функцией EFh прерывания INT 21h:
На входе: | AH | = | EFh; |
AL | = | 0 - получить адрес таблицы индексов дисковых устройств (Drive Handle Table); |
1 - получить адрес таблицы флагов дисковых устройств (Drive Flag Table);
2 - получить адрес таблицы номеров каналов дисковых устройств (Drive Connection ID Table);
3 - получить адрес таблицы номеров каналов
(Connection ID Table);