Программирование для Windows NT (том 2)

Функция GetDiskInfo


Функция GetDiskInfo вызывается обработчиком сообщения WM_CREATE при создании главного окна приложения. Она получает и сохраняет информацию о всех логических дисках, имеющихся в системе.

Из предыдущего тома “Библиотеки системного программиста” вы знаете, что с помощью функции GetLogicalDriveStrings можно получить список имен всех логических дисковых устройств. Через второй параметр этой функции необходимо передать адрес блока памяти, в который будет записан указанный выше список, а через первый - размер этого блока.

Однако заранее приложение не знает, сколько логических дисков имеется в системе и, соответственно, не знает, сколько места потребуется ему для сохранения списка логических устройств. Поэтому вначале мы вызываем функцию GetLogicalDriveStrings, передав ей значение 0 в качестве первого параметра и значение NULL - в качестве второго:

dwDriveStringsSpace = GetLogicalDriveStrings(0, NULL);

В результате функция GetLogicalDriveStrings возвращает размер блока памяти, необходимый для записи всех имен логических дисков.

На следующем шаге наше приложение получает блок памяти необходимого размера, вызывая для этого функцию malloc. Адрес полученного блока и его размер затем передаются функции GetLogicalDriveStrings, которая в этом случае заполняет блок необходимой информацией:

GetLogicalDriveStrings(dwDriveStringsSpace,

  lpLogicalDriveStrings);

Если в компьютере имеются, например, логические диски A:, C: и D:, в блок памяти с адресом lpLogicalDriveStrings будут записаны следующие три строки:

A:\<0>

C:\<0>

D:\<0><0>

В конце каждой строки записывается байт с нулевым значением, а в конце последней строки - два нулевых байта.



Получив список имен устройств, наше приложение подсчитывает количество устройств. Для этого оно с помощью функции strchr сканирует список в цикле до тех пор, пока не будет найден его конец, подсчитывая количество проходов в глобальной переменной nNumDirves:

nNumDirves = 0;

for(lpTemp = lpLogicalDriveStrings; *lpTemp != 0;


  nNumDirves++)

{

  lpTemp = strchr(lpTemp, 0) + 1;

}

Определив таким образом общее количество логических дисков, приложение заказывает память для массива структур типа DISKINFO, в котором будут хранится параметры логических дисков:

pdi = malloc(nNumDirves * sizeof(DISKINFO));

Заполнение массива структур DISKINFO выполняется в цикле.

Для каждого диска прежде всего выполняется копирование имени диска из соответствующей строки списка, полученного ранее при помощи функции GetLogicalDriveStrings.

Далее приложение определяет тип диска, вызывая для этого функцию GetDriveType (в локальной переменной lpTemp хранится имя диска):

(pdi + i)->nDriveType = GetDriveType(lpTemp);

Заполнение полей структуры DISKINFO выполняется по-разному в зависимости от типа диска.

Если устройство со сменным носителем данных, то в поле iImage, предназначенное для хранения номера пиктограммы диска, записывается нулевое значение. Именно под этим номером мы занесли пиктограмму диска со сменным носителем в список пиктограмм для органа управления List View.

В поле szVolumeName мы записываем строку <Unknown>, так как определение фактических параметров устройств со сменным носителем выполняется при обработке извещения NM_DBLCLK. Аналогичным образом заполняются и остальные поля структуры.

Заполнение структуры DISKINFO для устройств чтения CD-ROM выполняется точно так же, как и устройств со сменным носителем данных, за исключением того что в поле номера пиктограммы iImage записывается значение 2. Это номер пиктограммы с изображением накопителя CD-ROM в списке пиктограмм органа управления List View.

Если текущим устройством, для которого мы определяем параметры, является диск с несменным носителем данных, функция GetDiskInfo получает большинство этих параметров при помощи функции GetVolumeInformation, как это показано ниже:

GetVolumeInformation(lpTemp, (pdi + i)->szVolumeName, 30,

  &((pdi + i)->dwVolumeSerialNumber),

  &((pdi + i)->dwMaxFileNameLength),

  &((pdi + i)->dwFileSystemFlags),



(pdi + i)->szFileSystemName, 10);

Для определения общего объема диска и объема свободного пространства дополнительно вызывается функция GetDiskFreeSpace:

GetDiskFreeSpace(lpTemp, &dwSectors, &dwBytes, &dwFreeClusters,

  &dwClusters);

Значения, полученные от этой функции, обрабатываются следующим образом:

(pdi + i)->dwFreeSpace  = dwSectors * dwBytes*dwFreeClusters;

(pdi + i)->dwTotalSpace = dwSectors * dwBytes*dwClusters;

Объем свободного пространства в байтах записывается в поле dwFreeSpace. Он вычисляется как произведение сделующих величин: количества свободных кластеров на диске dwFreeClusters, количество секторов в одном кластере dwSectors и количества байт в одном сеткоре dwBytes.

Общий объем диска записывается в поле dwTotalSpace и подсчитывается аналогично, за исключением того что вместо количества свобдных кластеров используется общее количество кластеров на диске dwClusters.

В поле iImage записывается значение 1. Это номер пиктограммы с изображением диска с несменным носителем данных.

Получение и заполнение информации об удаленных (сетевых) дисковых устройствах выполняется аналогично, однако в поле iImage записывается значение 3.

Если тип устройства не поддается классификации, наше приложение получает информацию о его параметрах, а в поле iImage записывает значение 1.


Содержание раздела