Получение информации о логических дисках, томах и файлах
При работе с файловой системой первым делом, как правило, необходимо определить конфигурацию системы, т.е. какие диски и каких типов установлены на компьютере. Это можно определить при помощи функции GetLogicalDrivers:
DWORD GetLogicalDrives(VOID)
При удачном завершении функция возвращает 32-х битовое значение, каждый бит которого указывает, существует ли соответствующее логическое устройство: бит 0 - диск А, бит 1 - диск B, бит 2 - диск С ….., бит 25 - диск Z. При неудачном завершении функция возвращает ноль.
Для получения информации о томах системы используется функция GetVolumeInformation, которая возвращает информацию, специфичную для файловой системы, связанной с каталогом, указанным первым параметром функции, остальные параметры - указатели на буферы и переменные типа DWORD:
BOOL GetVolumeInformation(
LPCTSTR lpRootPathName,
LPTSTR lpVolumeNameBuffer,
DWORD nVolumeNameSize,
LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength,
LPDWORD lpFileSystemFlags,
LPTSTR lpFileSystemNameBuffer,
DWORD nFileSystemNameSize
);
Первый аргумент - lpRootPathName - является указателем на корневой каталог файловой системы, информацию о которой мы хотим получить. Если этот параметр равен NULL, то используется корневой каталог текущего диска.
Второй и третий аргументы работают в связке. Второй аргумент – lpVolumeNameBuffer -является указателем на буфер, в который будет записано имя диска, а третий - nVolumeNameSize - определяет размер этого буфера в байтах.
В четвертом аргументе - lpVolumeSerialNumber – функция возвращает серийный номер тома.
В пятом аргументе - lpMaximumComponentLength – указывается максимальная длина имени файла вместе с путем, которая допускается в данной файловой системе. Для FAT32 и NTFS данное значение равно 255.
В шестом аргументе - lpFileSystemFlags – функция возвращает двойное слово, в котором может быть записана любая комбинация флагов (табл. 13), дающая дополнительную информацию о файловой системе.
табл. 13 – Назначение битов аргумента lpFileSystemFlags
Флаг | Значение | Назначение |
FS_CASE_SENSITIVE | 0x00000001 | Если этот флаг установлен, то при записи на диск сохраняется регистр букв в имени файла. |
FS_CASE_IS_PRESERVED | 0x00000002 | Если этот флаг установлен, то файловая система поддерживает имена файлов с учетом регистра. |
FS_UNICODE_STORED_ON_DISK | 0x00000004 | Если этот флаг установлен, то файловая система поддерживает хранение на диске имен файлов в Unicode. |
FS_PERSISTENT_ACLS | 0x00000008 | Если этот флаг установлен, то файловая система способна оперировать со списками контроля доступа ACL (только NTFS). |
FS_FILE_COMPRESSION | 0x00000010 | Если этот флаг установлен, то то файловая система поддерживает сжатие томов. |
FS_VOL_IS_COMPRESSED | 0x00008000 | Если этот флаг установлен, то том, о котором запрашивается информация, был сжат. |
Седьмой и восьмой аргументы работают в связке. Седьмой аргумент – lpFileSystemNameBuffer -является указателем на буфер, в который будет записано название файловой системы, а третий - nFileSystemNameSize - определяет размер этого буфера в байтах.
Указатели на возвращаемые значения (lpRootPathName, lpVolumeNameBuffer,lpVolumeSerialNumber и lpFileSystemNameBuffer) должны быть перед вызовом функции инициализированы, например, с помощью процедуры GetMem.
Рекомендуется проверять возвращаемое функцией GetVolumeInformation значение. Если функция возвращает FALSE, следует проверить правильность задания входных параметров.
Для получения информации о типе диска используется функция GetDriveType:
UINT GetDriveType(LPCTSTR lpRootPathName);
В качестве единственного аргумента используется указатель на корневой каталог диска, тип которого необходимо определить. Возвращаемое функцией значение определяет тип диска (табл. 14).
табл. 14 – Типы дисков
Флаг | Значение | Назначение |
DRIVE_UNKNOWN | Тип устройства определить не удалось. | |
DRIVE_NO_ROOT_DIR | Корневого каталога не существует. | |
DRIVE_REMOVABLE | Устройство со сменным носителем (гибкий диск). | |
DRIVE_FIXED | Устройство с несменным носителем (жесткий диск). | |
DRIVE_REMOTE | Удаленное устройство (сетевой диск). | |
DRIVE_CDROM | CDROM. | |
DRIVE_RAMDISK | RAM-диск. |
Функция GetDiskFreeSpace возвращает статистику о дисковом пространстве на указанном томе:
BOOL GetDiskFreeSpace (
LPCTSTR lpRootPathName,
LPDWORD lpSectorsPerCluster,
LPDWORD lpBytesPerSector,
LPDWORD lpNumberOfFreeClusters,
LPDWORD lpTotalNumberOfClusters
);
Первый аргумент - lpRootPathName - является указателем на корневой каталог файловой системы, информацию о которой мы хотим получить. Если этот параметр равен NULL, то используется текущий каталог диска.
Во втором аргументе - lpSectorsPerCluster – функция возвращает число секторов в кластере.
В третьем аргументе - lpBytesPerSector – функция возвращает количество байт в секторе.
В четвертом аргументе - lpNumberOfFreeClusters – функция возвращает количество свободных кластеров на диске.
В пятом аргументе - lpTotalNumberOfClusters – функция возвращает общее количество кластеров на диске.
Выполнение работы
К п.1. После создания нового проекта, можно приступить к разработке приложения, внешний вид основного окна которого приведен на рис. 3.
рис. 3 Внешний вид основного окна приложения
К п.2. После размещения на форме компонента TComboBox, создайте обработчик события OnCreate формы и добавьте туда код для формирования списка о дисках и логических томах, присутствующих в системе:
procedure TForm1.FormCreate(Sender: TObject);
var mask,LogDrives,i: DWORD;
begin
LogDrives:=GetLogicalDrives;
mask:=1;
i:=0;
repeat
if (mask and LogDrives) <> 0
then ComboBox1.AddItem(chr(ord('A')+i)+':'+'\',nil);
i:=i+1;
mask:=mask shl 1;
until mask = 0;
end;
К п.3. Для отображения информации о выбранном в компоненте ComboBox1 диске или логическом томе, вначале разместите на форме компонент StringGrid1.
Для отображения информации о выбранном диске используются возвращаемые параметры функций GetVolumeInformation, GetDiskFreeSpace и GetDriveType. Кроме того, необходимо определить производные параметры такие как: количество занятых кластеров на диске, и количество свободной, занятой и общей памяти подсчитанной в байтах. Поэтому в раздел public класса TForm1 добавьте следующие переменные:
TForm1 = class(TForm)
……………
// компоненты формы
private
{ Private declarations }
public
{ Public declarations }
SectorsPerClaster,BytesPerSector,FreeClasters,Clusters: DWORD;
Free,Busy,All: Int64;
MaxCompLength,FileSystemFlags: DWORD;
RootPathName,VolNameBuf,FileSystemNameBuf: PChar;
VolSerialNumber: PDWORD;
end;
Теперь добавьте в ранее созданный обработчик события OnCreate формы код для вывода названий параметров диска в соответствии с описаниями тех же функций:
procedure TForm1.FormCreate(Sender: TObject);
var mask,LogDrives,i: DWORD;
begin
……………
// определение имеющихся в системе дисков
……………
for i:=0 to high(InfoDrive) do
StringGrid1.Cells[0,i]:=InfoDrive[i]; // массив строк
// параметров
GetMem(VolNameBuf,255);
GetMem(VolSerialNumber,255);
GetMem(FileSystemNameBuf,255);
end;
Здесь же выделяется динамическая память (функция GetMem) для хранения строк имен тома, серийного номера тома и имени файловой системы.
Для обновления информации в таблице параметров после выбора нового диска необходимо создать обработчик события OnChange компонента Combobox1, в котором и будет осуществляться запрос информации о выбранном диске:
procedure TForm1.ComboBox1Select(Sender: TObject);
var sDriveType: string;
BytesPerClaster: Int64;
begin
RootPathName:=PChar(ComboBox1.Items.Strings[ComboBox1.ItemIndex]);
if GetVolumeInformation(RootPathName,VolNameBuf,255,
VolSerialNumber,MaxCompLength,FileSystemFlags,
FileSystemNameBuf,255) then begin
StringGrid1.Cells[1,0]:=RootPathName;
StringGrid1.Cells[1,1]:=VolNameBuf;
StringGrid1.Cells[1,2]:=IntToHex(DWORD(VolSerialNumber^),8);
StringGrid1.Cells[1,3]:=IntToStr(MaxCompLength);
StringGrid1.Cells[1,4]:=IntToHex(FileSystemFlags,8);
StringGrid1.Cells[1,5]:=FileSystemNameBuf;
endж
if GetDiskFreeSpace(RootPathName,SectorsPerClaster,
BytesPerSector,FreeClasters,Clusters) then begin
StringGrid1.Cells[1,6]:=IntToStr(SectorsPerClaster);
StringGrid1.Cells[1,7]:=IntToStr(BytesPerSector);
StringGrid1.Cells[1,8]:=IntToStr(FreeClasters);
StringGrid1.Cells[1,9]:=IntToStr(Clusters-FreeClasters);
StringGrid1.Cells[1,10]:=IntToStr(Clusters);
end
BytesPerClaster:=SectorsPerClaster*BytesPerSector;
All:=BytesPerClaster*Clusters;
Free:=BytesPerClaster*FreeClasters;
Busy:=All-Free;
StringGrid1.Cells[1,11]:=IntToStr(Free);
StringGrid1.Cells[1,12]:=IntToStr(Busy);
StringGrid1.Cells[1,13]:=IntToStr(All);
StringGrid1.Cells[1,14]:=TypeDrive[GetDriveType(RootPathName)];
end;
При выходе из программы необходимо освободить память, выделенную под буферы строк:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
FreeMem(VolNameBuf,255);
FreeMem(VolSerialNumber,255);
FreeMem(FileSystemNameBuf,255);
end;
Контрольные вопросы
1. Файловая система FAT12.
2. Файловая система FAT16.
3. Файловая система FAT32.
4. Файловая система NTFS.
5. Файловая система CDFS.
6. Cредства Win32 API и Delphi для получения информации о логических дисках, томах и файлах;
7. Cредства Win32 API и Delphi для работы с логическими дисками, томами и файлами.
Библиографический список
1. Древс Ю.Г. Организация ЭВМ и вычислительных систем: Учебник для вузов. –М.: Высшая школа. 2006. -501 с.
2.Олифер В.Г., Олифер Н.А. Сетевые операционные системы. Учебник для вузов. 2-е издание. – СПб.: Питер. 2008. 669 с.
3. Буза М.К. Архитектура компьютеров. Минск: Новое знание. 2007. -558 с.
4. Гордеев А.В. Операционные системы: Учебник для вузов. 2-е издание. –СПб.: Питер, 2007. 416 с.
5.Степанов А.Н. Архитектура вычислительных систем и компьютерных сетей. Учебное пособие. С-П. Питер, 2006, 512 с