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
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен