Delphi - объектно-ориентированный язык программирования, разработанный компанией Borland в 1995 году. Он основан на языке программирования Pascal, но имеет более расширенные возможности и добавлены новые функции.
Delphi является интегрированной средой разработки (IDE), которая позволяет разрабатывать программное обеспечение для различных платформ, включая Windows, macOS, Android и iOS. Delphi достигает многоплатформенности с помощью...
Данный совет содержит исходный код модуля, который может помочь Вам получить, установить и удалить метку тома гибкого или жесткого диска. Код получения метки тома содержит функцию Delphi FindFirst, код для установки и удаления метки тома использует вызов DOS-прерывания 21h и функции 16h и 13h соответственно. Поскольку функция 16h не поддерживается Windows, она должна вызываться через DPMI-прерывание 31h, функцию 300h.
{ *** НАЧАЛО КОДА МОДУЛЯ VOLLABEL *** } unitVolLabel; interface
uses
Classes, SysUtils, WinProcs; type
EInterruptError = class
(Exception); EDPMIError = class
(EInterruptError); Str11 = string
[11]; procedure
SetVolumeLabel(NewLabel: Str11; Drive: Char); function
GetVolumeLabel(Drive: Char): Str11; procedure
DeleteVolumeLabel(Drv: Char); implementation
type
PRealModeRegs = ^TRealModeRegs; TRealModeRegs = record
case
Integer of
0: ( EDI, ESI, EBP, EXX, EBX, EDX, ECX, EAX: Longint; Flags, ES, DS, FS, GS, IP, CS, SP, SS: Word); 1: ( DI, DIH, SI, SIH, BP, BPH, XX, XXH: Word; case
Integer of
0: ( BX, BXH, DX, DXH, CX, CXH, AX, AXH: Word); 1: ( BL, BH, BLH, BHH, DL, DH, DLH, DHH, CL, CH, CLH, CHH, AL, AH, ALH, AHH: Byte)); end
; PExtendedFCB = ^TExtendedFCB; TExtendedFCB = record
ExtendedFCBflag: Byte; Reserved1: array
[1..5] of
Byte; Attr: Byte; DriveID: Byte; FileName: array
[1..8] of
Char; FileExt: array
[1..3] of
Char; CurrentBlockNum: Word; RecordSize: Word; FileSize: LongInt; PackedDate: Word; PackedTime: Word; Reserved2: array
[1..8] of
Byte; CurrentRecNum: Byte; RandomRecNum: LongInt; end
; procedure
RealModeInt(Int: Byte; var
Regs: TRealModeRegs);
{ процедура работает с прерыванием 31h, функцией 0300h для иммитации } { прерывания режима реального времени для защищенного режима. } varErrorFlag: Boolean; begin
asm
mov ErrorFlag, 0
{ успешное завершение } mov ax, 0300h { функция 300h } mov bl, Int { прерывание режима реального времени, которое необходимо выполнить } mov bh, 0 { требуется } mov cx, 0 { помещаем слово в стек для копирования, принимаем ноль } les di, Regs { es:di = Regs } int 31h { DPMI-прерывание 31h } jnc @@End{ адрес перехода установлен в error } @@Error: mov ErrorFlag, 1 { возвращаем false в error } @@End
: end
; if
ErrorFlag then
raise
EDPMIError.Create('Неудача при выполнении DPMI-прерывания'); end
; function
DriveLetterToNumber(DriveLet: Char): Byte;
{ функция преобразования символа буквы диска в цифровой эквивалент. } beginif
DriveLet in
['a'..'z'] then
DriveLet := Chr(Ord(DriveLet) - 32); if
not
(DriveLet in
['A'..'Z']) then
raise
EConvertError.CreateFmt('Не могу преобразовать %s в числовой эквивалент диска', [DriveLet]); Result := Ord(DriveLet) - 64; end
; procedure
PadVolumeLabel(var
Name: Str11);
{ процедура заполнения метки тома диска строкой с пробелами } vari: integer; begin
for
i := Length(Name) + 1 to
11 do
Name := Name + ' '; end
; function
GetVolumeLabel(Drive: Char): Str11;
{ функция возвращает метку тома диска } varSR: TSearchRec; DriveLetter: Char; SearchString: string
[7]; P: Byte; begin
SearchString := Drive + ':*.*';
{ ищем метку тома } ifFindFirst(SearchString, faVolumeID, SR) = 0 then
begin
P := Pos('.', SR.Name); if
P > 0 then
begin
{ если у него есть точка... } Result := ' '; { пространство между именами } Move(SR.Name[1], Result[1], P - 1); { и расширениями } Move(SR.Name[P + 1], Result[9], 3); end
else
begin
Result := SR.Name;
{ в противном случае обходимся без пробелов } PadVolumeLabel(Result); end; end
else
Result := ''; end
; procedure
DeleteVolumeLabel(Drv: Char);
{ процедура удаления метки тома с данного диска } varCurName: Str11; FCB: TExtendedFCB; ErrorFlag: WordBool; begin
ErrorFlag := False
; CurName := GetVolumeLabel(Drv);
{ получение текущей метки тома } FillChar(FCB, SizeOf(FCB), 0); { инициализируем FCB нулями } withFCB do
begin
ExtendedFCBflag := $FF;
{ всегда } Attr := faVolumeID; { Аттрибут Volume ID } DriveID := DriveLetterToNumber(Drv); { Номер диска } Move(CurName[1], FileName, 8); { необходимо ввести метку тома } Move(CurName[9], FileExt, 3); end; asm
push ds
{ сохраняем ds } mov ax, ss { помещаем сегмент FCB (ss) в ds } mov ds, ax lea dx, FCB { помещаем смещение FCB в dx } mov ax, 1300h { функция 13h } Call DOS3Call { вызываем int 21h } pop ds { восстанавливаем ds } cmp al, 00h { проверка на успешность выполнения } je @@End@@Error:
{ устанавливаем флаг ошибки } mov ErrorFlag, 1 @@End: end
; if
ErrorFlag then
raise
EInterruptError.Create('Не могу удалить имя тома'); end
; procedure
SetVolumeLabel(NewLabel: Str11; Drive: Char);
{ процедура присваивания метки тома диска. Имейте в виду, что } { данная процедура удаляет текущую метку перед установкой новой. } { Это необходимое требование для функции установки метки. } varRegs: TRealModeRegs; FCB: PExtendedFCB; Buf: Longint; begin
PadVolumeLabel(NewLabel); if
GetVolumeLabel(Drive) <> '' then
{ если имеем метку... } DeleteVolumeLabel(Drive); { удаляем метку } Buf := GlobalDOSAlloc(SizeOf(PExtendedFCB)); { распределяем реальный буфер } FCB := Ptr(LoWord(Buf), 0); FillChar(FCB^, SizeOf(FCB), 0); { инициализируем FCB нулями } with
FCB^ do
begin
ExtendedFCBflag := $FF;
{ требуется } Attr := faVolumeID; { Аттрибут Volume ID } DriveID := DriveLetterToNumber(Drive); { Номер диска } Move(NewLabel[1], FileName, 8); { устанавливаем новую метку } Move(NewLabel[9], FileExt, 3); end; FillChar(Regs, SizeOf(Regs), 0); with
Regs do
begin
{ Сегмент FCB } ds := HiWord(Buf); { отступ = ноль } dx := 0; ax := $1600; { Функция 16h } end
; RealModeInt($21, Regs);
{ создаем файл } if(Regs.al <> 0) then
{ проверка на успешность выполнения } raise
EInterruptError.Create('Не могу создать метку тома'); end
; end
.
{ *** КОНЕЦ КОДА МОДУЛЯ VOLLABEL *** }