Изучение системных функций Windows API 32

В данном задании рассматриваются основные функции Win32API с примерами реализации в среде DELPHI. Изучите приведенные примеры, составьте соответствующие программы. Попробуйте перевести данные примеры в среду Visual C++ (или в среду Borland С++ Builder, но учтите при этом, что в данной среде есть ряд ошибок, связанных с реализацией системных функций).

Функции для управления файловой системой

В Win32 API существует стандартная функция GetLogicalDrives, которая возвращает 32-битное значение, каждый бит которого указывает, существует ли данное логическое устройство или нет. Но возиться с битами — занятие неблагодарное. Поэтому: лучше всего создать функцию, которая позволяет узнать, существует ли указанное логическое устройство. Назовем ее DriveExists и приведем два варианта ее реализации - один, использующий операцию «сдвиг влево», чтобы определить, установлен бит или нет. Во втором варианте используется стандартная процедура IN языка Object Pascal, реализованного в Borland Delphi.

Функция DriveExists

Более короткий вариант, для определения установлен определенный бит

или нет, используется операция «сдвиг влево»

Параметр Drive -от 0 до 25

/////////////////////////////////////////////////////////////////////

function DriveExlsts(Drive : Byte) : Boolean;

begin

Result := Boolean(GetLogicalDrives AND(1 SHL Drive))

end;

/////////////////////////////////////////////////////////////////////

Функция DriveExists

Вариант, в котором используются возможности языка Object Pascal

Параметр Drive -от 0 до 25

function DriveExists(Drive : Byte) : Boolean;

var LogDrives : set of 0. .25;

begin

Integer (LogDrives):=GetLogicalDrives;

Result := Drive IN LogDrives;

end;

 

Чтобы определить, какое из 26 возможных логических устройств существует, следует вызывать функцию DriveExists в цикле. Ниже показано, как заполнить содержимое списка именами существующих логических устройств:

procedure TForm1.FormCreate(Sender: TObject);

var D : Byte;

begin

For D := 0 to 25 do {Для всех устройств}

If DriveExists(D) Then {Если существует)

Begin

ListBox1.Items.Add(Chr(D+$41)); (Добавить в список)

End;

end;

Можно заметить, что в данном примере мы до какой-то степени повторили функциональность стандартного компонента DriveComboBox, входящего в комплект библиотеки VCL Delphi. Да, этот компонент удобен для того, чтобы получить список всех доступных логических устройств и выдать одно из них. Но что делать, если вам необходимо совершить какие-то действия над всеми устройствами, например, найти файл? В этом случае необходимо построить список доступных логических устройств, воспользовавшись функцией DriveExists.

 

Заметим, что для того, чтобы получить имя выбранного устройства в списке ListBoxl, в приведенном выше примере, в обработчике события OnClick необходимо выполнить следующее преобразование:

procedure TForml.LlstBox1Click(Sender: TObject):

var Drive: Byte;

begin

with ListBox1 do

Drive:= Ord(Items[ItemIndex][1])-$41;

end;

Cледующая функция, которую мы рассмотрим — это функция GеtDriveType. Она используется для определения типа устройства — накопитель на гибких дисках, накопитель на жестких дисках, привод СD ROM и т.п.

Пример ее использования показан ниже:

Функция CheckDriveType возврацает строчное описание типа логического устройства. Параметр Drive -от 0 до 25

/////////////////////////////////////////////////////////////////

function CheckDriveType(Drive : Byte) : String;

var DriveLetter : Char;

DriveType: UInt;

begin

DriveLetter:= Char(Drive + $41);

DriveType:= GetDriveType(Pchar(DriveLetter + ':\'));

Case DriveType of

0 : Result:= ‘?’;

1 : Result:= 'Path does not exists';

Drive_Removeable: Result:= ‘Removeable’;

Drive_Fixed: Result:=’Fixed’;

Drive_Remote: Result:=’Remote’;

Drive_CDROM: Result:=’CD-ROM’;

Drive_RamDisk: Result:=’RamDisk’;

Else

Result:= ‘Unknown’;

End;

End;

 

Отметим, что в качестве параметра стандартной функции GetDriveType указывается не номер логического диска, а название корневого каталога. Например, чтобы определить тип логического устройства 0 (устройства с именем «А»), необходимо вызвать функцию GetDriveType со следующим параметром:

GetDriveType('A:\')

Функция возвращает следующие значения для логических устройств: 

Значение

Тип устройства

0

Тип устройства не может быть определен.

1

Указанный корневой каталог не существует

DRIVE_REMOVABLE

Дисковод со сменным носителем

DRIVE_FIXED

Дисковод с несменным носителем

DRIVE_REMOTE

Удаленное (сетевое) устройство

DRIVE_CDROM

Привод CD-ROM

DRIVE_RAMDISK

Диск, созданный в памяти (RAM-диск)

В Win32 API существует функция GetVolumeInformation, которая помимо всего прочего позволяет определить тип файловой системы для данного устройства. Давайте посмотрим на эту функцию более внимательно. Информацию, возвращаемую данной функцией, можно разделить на несколько типов:

имя тома;

серийный номер тома;

максимальная длина имени файла для данной файловой системы;

характеристики файловой системы;

имя файловой системы.

Ниже мы приведем функции, возвращающие некоторые из перечисленных типов информации:

Функция GetFileSysName возвращает имя файловой системы для указанного устройства. Параметр Drive - от 0 до 25

////////////////////////////////////////////////////////////////

function GetFileSysName(Drive: Byte): String;

var DriveLetter: Char;

NoMatter: Integer;

FileSysName: Array[0..MAX_PATH] of Char;

Begin

DriveLetter:= Char(Drive+$41);

GetVolumeInformation(Pchar(DriveLetter+’:\’),nil, 0, nil, NoMatter,

Nomatter, FileSysName, SizeOf(FileSysname));

Result:= FileSysName;

End;

 

Какие могут быть имена файловой системы? Это могут быть: File Allocation Table (FAT), High Perfomance File System (HPFS), NT File System (NTFS) или CD-ROM File System (CDFS).

//////////////////////////////////////////////////////////////////

 

Функция GetVolumeName возвраoаtт имя тома для указанного устройства. Параметр Drive - от 0 до 25

Function CetVolumeName(Drive : Byte) : String;

var

DriveLetter : Char;

NoMatter : Integer;

VolumeName : Array[0..MAX_PATH] of Char;

Begin

DriveLetter:=Char(Drive + $41);

GetVolumeInformation(PChar(DriveLetter +":\'), VolumeHame,

SizeOf(VolumName), nil, NoMatter, NoMatter, nil, 0);

 

Имя тома, возвращаемое этой функцией — это метка тома жесткого или гибкого диска, устанавливаемая командой Label. Метку тома можно установить или изменить в панели Properties, которая становится доступной, если в папке My Computer выбрать иконку, соответствующую данному логическому устройству, нажать правую кнопку мыши и выбрать команду Properties.

//////////////////////////////////////////////////////////

 

Функция GetVolumeFlags возвращает характеристики файловой системы. Параметр Drive – от 0 до 25.

Var

DriveLetter: Char;

NoMatter: Integer;

FileSysFlags: Integer;

Begin

DriveLetter:= Char(Drive+$41);

GetVolumeInformation(Pchar(DriveLetter + ‘:\’),nil, 0, nil, FileSysFlags,

NoMatter, Nil, 0);

Result:= FileSysFlags;

End;

О каких характеристиках файловой системы идет речь? Возможные значения флагов приведены в следующей таблице:

Значение

Описание

FS_CASE_IS_PHESERVED

При записи файла на диск сохраняется регистр букв в его имени

FS_CASE_SENSITIVE1

Поддерживается поиск файлов с учетом регистра букв

FS_UNICODE_STORED_ON_DISK

Поддерживается сохранение имен файлов в Unicode

 

FS_PERSISTENT_ACLS

Поддерживаются списки контроля доступа (ACL). Только для NTFS.

FS_FILE_COMPRESSION

Поддерживается сжатие файлов на уровне системы

FS_VOL_IS_COMPRESSED

Устройство представляет собой сжатый диск

 

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

GetSystemDirectory, GetWindowsDirectory, GetTempPath.

Функция GetSysternDirectoly возвращает маршрут к каталогу SYSTEM, например, C:\WINDOWS\SYSTEM, а функция GetWindowsDirectory — маршрут к корневому каталогу Windows, например, C:\WINDOWS. Функция GetTempPath возвращает маршрут к временному каталогу Windows, например C:\WINDOWS\TEMP. Заметим, что в отличие or подобных функций - GetSystemDirectory и GetWundowsDirectory, порядок параметров у этой функции обратный – сначала идет размер буфера, затем указатель на буфер, в который помещается маршрут к временному каталогу.

Говоря о функциях для управления файловой системой, следует вспомнить еще одну функцию — GctDiskFreeSpace. Она позволяет узнать информацию о свободном месте на диске — числе свободных кластеров, секторов, а также о размере кластера и сектора. Как и в случае других файловых функций, имя диска задается именем корневого каталога. Пример использования функции GetDiskFreeSpace показан ниже:

 

Пример использования функции GetDiskFreeSpace. По нажатию кнопки отображается информация для диска С:. Помимо непосредственной информации, возвращаемой функцией GetDiskFreeSpace, подсчитывается полный объем диска и объем свободного пространства на нем.

procedure Tform1.Button1Click(Sender: TObject);

Type

TDiskInfo = Record

SectorsPerCluster : DWORD; {Число секторов в кластере}

BytesPerSector : DWORD; {Число байт в секторе}

FreeClusters : DWORD; {Число свободных кластеров}

NumClusters : DWORD; {Общее число кластеров}

BytesTotal : DWORD; {Полный объем диска в байтах}

BytesFree : DWORD; {Объем свободного пространства в байтах}

end;

var DiskInfo : TDiskInfo;

begin

With DiskInfo do

begin

{получить информацип для диска С: }

GetDiskFreeSpacв(‘c:\’,SectorsPerCluster,BytesPerSector,

FreeClusters, NumClusters):

{подсчитать полный объем диска в байтах}

BytesTotal:= NumClusters*SectorsPerCluster*BytesPerSeetor;

{подсчитать объем свободного пространства в байтах}

BytesFree:= FreeCIusters*SectorsPerCluster*BytesPerSector;

Label1.Caption:= Format(‘Sectors/Clueter : %d', [SectorsPerCluster]);

Label2.Caption:= Format(‘Bytes/Sector : %d', [BytesPerSector]);

Label3.Caption:= Format(‘ Free Clusters : %d', [FreeClusters]);

Label4.Caption:= Format(‘ Total Clusters : %d', [NumClusters]);

Label5.Caption:= Format(‘Total bytes : %d', [BytesTotal]);

Label6.Caption:= Format(‘Free bytes : %d', [BytesFree]);

end;

end;

Функции, возвращающие информацию о вычислительной системе

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

Начнем с функции GctSystemInfo, которая позволяет узнать тип процессора, установленного в системе, и ряд других, связанных с этим характеристик.

Тип процессора

Для определения типа процессора в Win32 API можно воспользоваться функцией GetSystemInfo. Эта функция заполняет структуру TSystemInfo, переданную ей в качестве параметра, информацией о системе. К такой информации относятся:

Архитектура процессора (поле wProcessorArchitecture).

Размер страницы (поле dwPageSize).

Минимальный адрес для приложения (поле lpMinimumApplicationAddress).

Максимальный адрес для приложения (поле

lpMaximumApplicationAddress).

Маска активного процессора (поле dwActiveProcessorMask).

Число процессоров (поле dwNumberOfProcessors).

Тип процессора (поле dwProcessorType).

Размер выделяемого блока (поле dwAUocationGranularity).

Данные о процессоре (поля wProcessorLevel и wProcessorRevision).

 

Ниже показано, как определить тип процессора, установленного в системе:

Var

SI: TSystemInfo;

GetSystemInfo(SI);

Case SI. dwProcessorType of

386: Label2. Caption := 'Intel 386';

486: Label2. Caption := 'Intel 486';

586: Label2.Caption := 'Intel 586';

end;

Несколько слов о других полях структуры TSystemInfo.

Содержимое поля wProcessorArchitecture позволяет определить архитектуру процессора. Возможные значения:

PROCESSOR_ARCHITECTURE_INTEL

(Windows 95 и Windows NT)

PROCESSOR_ARCHITECTURE_MIPS

(только Windows NT)

PROCESSOR_ARCHITECTURE_ALPHA

(только Windows NT)

PROCESSOR_ARCHITECTURE_PPC

(только Windows NT)

PROCESSOR_ARCHITECTURE_UNKNOWN

(только Windows NT)

 

Содержимое поля lpMinimumApplicationAddress позволяет узнать минимальный адрес памяти, доступный для приложения, а содержимое поля lpMaximumApplicationAddress — максимальный адрес. Маска активного процессора (поле dwActiveProcessorMask) указывает на процессор, который активен в данный момент (бит 0 — процессор 0, бит 31 — процессор 31). Общее число процессоров в системе содержится в поле dwNumberOfProcessors. Поле dwAllocationGranularity содержит размер выделяемого блока памяти (страницы). Для платформы Intel это значение равно 64 Кбайт. Содержимое полей wProcessorLevel и wProcessorRevision позволяет узнать более детальную информацию о процессоре, например, номер ревизии.

Версия Windows.

Версию Windows можно определить с помощью функции GetVersionEx. Эта функция использует структуру TOSVersionInfo, которая содержит номер версии (поля dwMagorVersion и dwMinorVersion — 4.0 для коммерческой версии Windows 95), служебный номер (dwBuildNumber, 950 для коммерческой версии Windows 95) и идентификатор платформы (dwPlatformID). Перед вызовом функции GetVersionEx следует занести в поле dwOSVersionInfoSize размер структуры TOSVersionInfo. Пример использования функции GetVersionEx показан ниже:

var

OSVerInfo : TOSVerslonInfo;

WinVer : String;

Build : String;

OSVerInfo. dwOSVerslonInfoSIze := SlzeOf(OSVerlnfo);

GetVerslonEx(OSVerInfo);

{Платформа}

Case OSVerInfo. dwPlatformID of

VER_PLATFORM_WIH32S : Label2 .Caption := 'Windows 3.x';

VER_PLATFORM_WIH32_WIUDOWS : Label2. Caption := 'Windows 95';

VER_PLATFORM_WIN32_NT : Label2.Caption := 'Windows NT';

End;

With OSVerInfo do

Begin

{Версия }

WinVer := Format('%d.%d', [dwMajorVersion, dwMinorVersion]);

{Служебный номер}

Build := Format(' %d', [LoWord(dwBuildNumber)]);

End;

 

Примечание. Для того чтобы определить тип Windows NT — Windows NT Workstation или Windows NT Server, следует обратиться к регистратору и узнать значение параметра:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ProductOptlons

 

Значение WINNT соответствует Windows NT Workstation, SERVERNT - Windows NT Server (3.5 и выше), LANMANNT — Windows NT Advanced Server версии 3.1.

 

Память

Обычно к системным характеристикам относят и память — общий объем памяти, объем доступной памяти, объем виртуальной памяти и т.п. Для этих целей можно использoвaть функцию GlobalMemoryStatus.

Эта функция заполияет структуру TMemoiyStatus информацией об объеме памяти, установленной в системе и связанных с этим характеристиками. Перед использованием этой функции следует занести в поле dwLength размер структуры TMemoryStatus. Назначение полей этой структуры приведено в таблице.

dwLength

Содержит размер структуры TmemoryStatus

dwMemoryLoad

Содержит число от 0 до 100, указывающее использование. памяти. Число 100 указывает на то, что память используется полностью.

dwTotalPhys

Содержит общий объем

физической памяти в байтах

dwAvailPhys

Содержит объем доступной физической памяти в байтах.

dwTotalPageFile

Содержит максимальное число байт, которые могут содержаться в страничном файле, располагаемом на диске

dwAvailPageFile

Содержит число свободных байт в страничном файле

dwTotaVirtual

Содержит число байт в виртуальном адресном пространстве, принадлежащем данному процессу

dwAvailVirtual

Содержит число байт в виртуальном адресном пространстве, доступных процессу

Вернемся к структуре TMemoryStatus. Поле dwMemoryLoad позволяет оценить занятость памяти. Подробных описаний того, каким образом высчитывается этот коэффициент не найдено, при запуске одних и тех же задач получались различные значения. Общий объем физической памяти в байтах определяется через значение поля dwTotalPhys. Под физической памятью понимается память, которая реально установлена на компьютере. Например, если установлено 16 Мбайт, то вы получите меньшее число, так как учитываются «дыры» в пространстве между 640 Кбайт и 1 Мбайт. Объем физической памяти, доступной для выделения, определяется через значение поля dwAvailPhys. Два следующих поля — dwTolalPageFile и dwAvailPageFile показывают, соответственно, общий размер страничного файла и число свободных байт в нем. Помимо страничной и физической памяти Win32 предоставляет возможность использовать виртуальную память — собственно, она и составляет общее адресное пространство, доступное для адресации. Обычно первые 4 Мбайт недоступны для прикладных программ (задается параметром ImageBase компоновщика), а адресное пространство составляет 2 Гбайт — это адресное пространство, доступное данному процессу. Напомню, что старшие 2 Гбайт доступны всем приложениям, а общий объем виртуального адресного пространства равен 4 Гбайт. Таким образом, число байт в виртуальном адресном пространстве для данного процесса будет равно 2 Гбайт — 4 Мбайт. Разница между dwTotalVirtual и dwAvailVirtual позволяет узнать, сколько памяти зарезервировано под данный процесс.

 

Примечание. Поле lpMinimumApplicationAddress структуры TSystemInfo, заполняемой функцией GetSystemInfo позволяет узнать минимальный адрес памяти, доступной приложению. Сумма этого значения и TMemoryStatus. dwTotalVirtual дает общий объем виртуального адресного пространства.

Рассмотрим еще несколько системных функций.

Функция GetComputerName позволяет узнать имя компьютера, а функция GetUserName – имя пользователя. Для определения типа клавиатуры используется функция GetKeyboardType, которая возвращает тип клавиатуры, ее подтип (например, Nokia 9140) и число функциональных клавиш.

Функция SystemParametersInfo позволяет узнать и изменить множество характеристик системы. Отметим, что параметры SPI_GETXXX возвращают характеристики системы, а параметры SPI_SETXXX позволяют их изменить. Ряд параметров, возвращающих характеристики системы, приведен в следующей таблице.

Параметр

Описание

SPI_GETANIMATION

Только для Windows 95. Возвращает информацию о анимированных иконках (структура TAnimationInfo) ,

SPI_GETBEEP

Позволяет узнать, выдается ли предупреждающий сигнал или нет

SPI_GETBORDER

Позволяет узнать ширину рамки окна :

SPI_GETDEFAULTINPUTLANG

Только для Windows 95. Позволяет узнать язык клавиатуры по умолчанию

SPI_GETDRAGFULLWINDOWS

Только для Windows 95 Позволяет узнать, возможно ли перетаскивание полного окна

SPI_GETFASTTASKSWITCH

Позволяет узнать, поддерживается ли быстрое переключение задач

SPI_GETGRIDGRANULARITY

Позволяет узнать шаг расположения объектов в рабочей области

SPI_ GETICONMETRICS

Только для Windows 95. Позволяет узнать метрики для иконок (структуре TIconMetrics)

SPI_GETICONTITLELOGFONT

Позволяет узнать шрифт, которым выводятся подписи к иконкам (структура TLogFont)

SPI_GETICONTITLEWRAP

Позволяет узнать, располагаются подписи к иконкам в одной строке или в нескольких

SPI_GETKEYBOADPREF

Только для Windows 95. Позволяет узнать, пользуется ли пользователь клавиатурой вместо мыши или нет

SPI_GETMENUDROPALIGNMENT

Позволяет определить тип выравнивания локальных меню влево или вправо

SPI_GETMINIMZE

Только для Windows 95. Возвращает размер минимизированных окон (структура TminimizedMetrics)

SPI_GETNONCLIENTMETRICS

Только для Windows 95. Возвращает размер неклиентской области окна (структура TnonCLientMetrics)

SPI_GETSCREENSAVEACTIVE

Позволяет определить, активизирован «хранитель экрана» или нет

SPI_GETWORKAREA

Только для Windows 95. Возвращает размер рабочей области

SPI_LANGDRIVER

Только для Windows 95. Позволяет определить языковый драйвер

И последняя функция, которую мы рассмотрим в данном разделе — функция GetSystemMetrics, которая возвращает системные метрики — горизонтальный и вертикальный размер элементов среды (меню, элементов окон, диалоговых панелей и т.д.), тип загрузки Windows 95, число кнопок мыши и т.п. Отметим, что несмотря на то, что в Win32 наметился определенный прогресс в сторону облегчения получения информации о системе, получение ряда характеристик не совсем очевидно. Например, многие параметры системы можно узнать только через обращение к соответствующим элементам регистратора (registry). Это тема следующего задания.

 

Hosted by uCoz