Виртуальный диск

altМногие из нас, в студенческие годы любили эксперементировать с реестром и командной строкой в университете/техникуме/институте и т.д. Сколько команд было испробовано, сколько компов было замучено, не пересчесть. К таким западлостроителям (несколько странновато звучит - прим. ред.) отношу себя и я. У меня в закромах много разных "полезных" и не очень команд, вот с одной из них я хочу Вас познакомить.

За что я люблю Windows NT, так это за то, что данная ОС предлагает пользователю столько разнообразных фич, что глаза разбегаются, без варианта быть вновь возвращенными наместо. К примеру одна из них, это создание виртуальных дисков. За данное действие отвечает команда "Subst", которая устанавливает соответствие пути в файловой системе заданному диску. Вызванная без параметров, команда subst выводит имена виртуальных дисков, созданных предыдущими вызовами команды.

Синтаксис:


subst [диск1: [диск2:]путь]

Параметры:

"диск1": Задает диск, которому будет поставлен в соответствие заданный путь
"диск2": Задает физический диск, на который ссылается заданный путь (если не совпадает с текущим диском).
"путь" - Задает путь, который ставится в соответствие диску.

Ключи:

"/d" - Удаляет виртуальный диск.
"/?" - Отображает справку в командной строке.

Пример:

subst I: C:\temp

После выполнения данной команды у Вас появится новое устройство (диск) с меткой "I", который будет иметь содержимое "C:\temp", если же данный путь существует, то команда выполниться и теперь зайдя в "Мой компьютер" вы можете лицезреть новый виртуальный диск.

Знать команды это конечно хорошо, а порой и полезно, но мы не будем каждый раз вводить команду, чтобы создать новое устройство, а также не будем писать сценарий или reg-файл. Для реализации наших "темных замыслов" создадим программу которая сама создаст для нас виртуальный диск или диски (вообщем по желанию). Наверное уже созрела идея как это реализовать программно? Я знаю лишь два способа: первый - использовать функцию ShellExecute, которая будет доступна если подключить модуль "ShellAPI". Пример использования:

shellExecute(0,nil,'subst','I:\ C:\temp',nil,sw_show); - создание диска "I"
shellExecute(0,nil,'subst','I: /d',nil,sw_show); - удаление
Использовать ее мы не будем, хотя она того стоит - позволяет запускать файлы с ключами (о ней читайте в другой раз). Второй способ более приемлен, т.к. для создания виртуальных дисков существует специальная функция...

Основная функция, с которой нам предстоит познакомиться, носит название "DefineDosDevice". Она (функция) позволит определить/переопределить или удалить имя устройства, т.е. мы имеем возможность создать виртуальный диск. Если говорить "книжным" языком, то устройство МС-DOS загружается как символическая ссылка на обьект в пространстве имен в 32х битной версии Windows. Код, который преобразовывает путь МС-DOS на соответствующий путь в 32х битной версии Windows использует эти символические ссылки для отображения карты устройств МС-DOS и обозначения накопителей. Функция DefineDosDevice обеспечивает механизм, посредством чего приложение Win32 может модифицировать символические связи , чтобы изменить карту устройств МС-DOS и пространство имен. Если после этого интерес к данной теме не пропал, то давайте разберем основные параметры функции:

function DefineDosDevice(
dwFlags: DWORD;
lpDeviceName,
lpTargetPath: PChar
): boolean;
Параметры:

"dwFlags": чтобы контролировать создаваемое устройство (определять/переопределять или удалять) можно применять флаги, некоторые могут использоваться совместно:

"0" - определить устройство.
"DDD_RAW_TARGET_PATH" - этот флаг не преобразовывает строку "lpTargetPath" из пути МС-DOS в пути для 32х битной версиии Windows, а оставляет как есть.
"DDD_REMOVE_DEFINITION" - этот флаг удаляет определение(описание) для устройства. Для того, чтобы узнать какое определение удалить, функция проходит список определителей для устройства и ищет сопоставление "lpTargetPath" префиксу каждого определителя связанного с этим устройством. Если "lpTargetPath" = nil , функция удалит первое переопределенное устройство.
"DDD_EXACT_MATCH_ON_REMOVE" - Если этот флаг установлен вместе с DDD_REMOVE_DEFINITION, то функция будет использовать точное сопоставление, чтобы выяснить какой определитель удалить. Используйте этот флаг для страховки от того, чтобы не удаляли что-то, что вы не определяли.
"DDD_NO_BROADCAST_SYSTEM" - ??.

"lpDeviceName": данный параметр содержит имя устройства, служащий точкой монтирования для виртуальных устройств, который переопределяет описатель для установки, изменения или удаления.

"lpTargetPath": этот параметр определяет путь к устройству или же путь к папке, последнее актуально для виртуального устройства.

Задолго до написания статьи, мне попался один исходник, который как раз подойдет для нашей темы и поэтому я не стал изобретать велосипед, а использовал именно его. Жаль, что автора кода я не знаю и поэтому не могу поблагодарить его. Итак, опишу в двух словах порядок действий. В нашей функции CreateDevice, есть два параметра, первый проверять не будем (ниже объясню зачем так сделал), второй параметр проверяем на наличие существования директории, если нет такого, то виртуальный диск будет создан, но уже без содержимого; далее пробуем создать виртуальный диск, если не получается, то диск не будет создан. Хочу заметить, если вы хотите удалить созданный вами ранее виртуальный диск, то в функция "DefineDosDevice" примет вид: DefineDosDevice(DDD_REMOVE_DEFINITION, PChar(name_dev), PChar(path_dev)). Трудностей быть не должно, код прост до безобразия.

Листинг 1.

function CreateDevice(name_dev, dev_path: String):integer;
begin
Result:=0;
//если данная директория не существует, то
if not(DirectoryExists(dev_path)) then
begin
//источник содержимого для устройства отсутствует
Result:=2;
Exit;
end;
if not(DefineDosDevice(0, PChar(name_dev), PChar(path_dev))) then
begin
//ошибка определения устройства
Result:=4;
Exit;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if CreateDevice('I:','G:\about')=0 then
ShowMessage('Создание виртуального устройства прошло удачно!')
else
ShowMessage(SysErrorMessage(GetLastError));
end;
Ну, если все же, не получилось создать виртуальный диск, то попробуем хоть вывести строку сообщения об ошибке и здесь на помощь прийдет функция "SysErrorMessage(GetLastError)", которая преобразует код последней ошибки в строку. Если разобрались, то идем дальше, чтобы каждый раз не прописывать метку нового создаваемого устройства, есть еще одна интересная функция (хотя их несколько), которая позволит нам найти все незадействованные метки. Функция "Getdrivetype" имеет один параметр, в который нужно подставлять имя метки - от "A" до "Z". Выполненная функция возвращает одно из 7 возможных значений, которое определяет тип накопителя:

0(DRIVE_UNKNOWN) - неизвестный накопитель;
1(DRIVE_NO_ROOT_DIR) - незадействованная метка;
2(DRIVE_REMOVABLE) - извлекаемый накопитель (флеш-карта);
3(DRIVE_FIXED) - фиксированный диск (жесткий диск);
4(DRIVE_REMOTE) - удаленный накопитель(сетевой диск)
5(DRIVE_CDROM) - СD-ROM;
6(DRIVE_RAMDISK) - накопитель является виртуальным RAM-диском;

Листинг 2.

function drive():string;
var
i:cardinal;
begin
for i:=ord('C') to ord('Z') do
case Getdrivetype(pchar(chr(i)+':\')) of
1: begin
//вовращаемое функцией значение
result:=chr(i);
//остановить цикл
break;
end;
end;
end;
После выполнения функции "drive" получим первую свободную метку, что с ней делать, думаю, догадаешься сам. На этом стоит закруглиться, теперь при желании можно использовать таймер, который через промежутки времени будет создавать виртуальные диски, опять же результат зависит от вашей фантазии, мое дело - лишь познакомить вас с программированием на Дельфи

Понравилась статья? Поделиться с друзьями:
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: