Консультация № 135257
04.05.2008, 09:09
0.00 руб.
0 1 1
Здравствуйте!
Заинтересовался написанием файлового менеджера и возник следующий вопрос:
Обычно под сочетания <ALT+F1> и <ALT+F2> показывают список имеющихся дисковых устройств для последующего выбора.
А вот как можно определить список этих самых доступных букв?
Смотрел функции 0EH, 19H прерывания 21H – но там же получается нужно делать перебор? Т.е., как я понял, делаем какой-то диск текущим, и затем смотрим, получилось ли. Навряд ли это правильно.

И еще позвольте. В книге Зубкова много разных интересных функций по работе с длинными именами файлов, но я там не нашел функцию по переименованию файла (т.е. аналог прежней функции 56H).

Обсуждение

давно
Посетитель
7438
7205
06.05.2008, 15:06
общий
это ответ
Здравствуйте, Бартосик Феликс Михайлович!
Как вариант, список дисков можно получить, пробежав по списку DPB.
Смотри приложение.

-----------
Добавлено 08.05.08:
И еще один вариант, тоже в приложении, используется тот факт,
что ф-я парсинга 29h сообщает о том, если диск не существует.
Работает при удалении/добавлении дисков!
----------

А для работы с длинными именами есть функция ah=71h.
При al=56h (не случайно в AL 56h ... :)) она служит как раз для перемещения/переименования файла
DS:DX -> ASCIZ (long allowed) старого имени файла или директории
ES:DI -> ASCIZ нового имени
Если второе имя без пути, то будет переименование...
Вернет: CF=0, если отработало
CF=1, если ошибка
AX = код ошибки
7100h если функция не поддерживается
Примечание: файл может быть переименован в другой директории, но не на другом диске.


Приложение:
.model tiny, C .code .386 .startup call GetDisks .exit 0 ; Просматриваем блоки Drive Parameter Block (DPB) ; Используем, что для существующих дисков есть и DPB ; Так как структура DPB в разных версиях разная, ; то приходится проверять версию ДОС-а, ; и для меньших 4.00 подправить смещение в команде на 18h... ; Результат - битовая маска в EAX (b0=1 - A, b1=1 - B, b2=1 - C, и т.д.) ; При желании, можно переделать на DX:AX, чтобы остаться в 16-битных регистрах... GetDisks proc uses bx, es, cx, esi mov ah,30h int 21h cmp al, 4 ; 4.00+ - без изменений jae GD_get_list_of_lists mov byte ptr cs:GD_next+3, 18h ; подправим код... GD_get_list_of_lists: mov ah,52h ; получим "список списков" int 21h ; в ES:BX les bx, es:[bx] ; по смещению 0 получим указатель на первый DPB, ; после загрузки ES:BX - указатель на первый DPB mov cx, 32 ; ограничим максимальное число просмотров ; столько, в принципе, никогда не будет, но все же... xor esi, esi ; здесь будем накапливать битовую маску GD_loop: cmp bx, -1 ; у последнего DPB ссылка на последующий равна ffff:ffffh je GD_ret ; достаточно проверить только смещение push cx ; сохраним счетчик цикла mov cl, es:[bx] ; по смещению 0 имеем код диска: 0-A, 1-B, 2-C,... mov eax, 1 shl eax, cl ; сформируем битовую маску pop cx or esi, eax ; и сохраним в ESI GD_next: les bx, es:[bx+19h] ; читаем длинный указатель на следующий DPB loop GD_loop ; зацикливаем GD_ret: mov eax, esi ; результат ret GetDisks endp end ;--------------------------------------------- .model tiny, C .code .386 .startup continue: lea ax, disks ; сюда запишем строку букв дисков call GetDisks, ax lea dx, string mov ah, 9 int 21h mov ah, 0 int 16h cmp al,1bh jne continue .exit 0 ;Для анализа существования диска используем парсинг строки! GetDisks proc pString:word local buffer:byte:4, FCB:byte:26h ; буфера в стеке uses bx, si, di ; сохраним используемые регистры в стеке push-ами mov cx,26 ; максимальное количество дисков A-Z mov bx, pString ; параметр - адрес, куда писать строку дисков lea si,buffer ; буфер, где будем формировать строку ‘<диск>:‘ mov word ptr [si],‘:A‘ ;начнем с ‘A:‘ mov byte ptr [si+2],0 lea di, FCB ; адрес FCB, куда ф-я запишет результат парсинга disk_loop: push si ; сохраним адрес буфера, он портится mov ax, 2901h int 21h pop si cmp al,0ffh ; диск отсутствует? je disk_next ; не сохраняем mov al,[si] ; буква диска mov ah, ‘$‘ ; для вывода на экран по 9 ф-и ; mov ah, 0 ; для нормальной работы лучше так mov word ptr [bx],ax ; сохраним в выходном буфере вместе с завершающим символом inc bx disk_next: inc byte ptr [si] ; увеличим букву диска loop disk_loop ret GetDisks endp .data string db 0dh,0ah disks db 27 dup (0) ;A-Z + 1 end
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа