Windows для профессионалов

       

Определение версии системы


Весьма часто приложению требуется определять, в какой версии Windows оно выпол няется. Причин тому несколько Например, программа может использовать функции защиты, заложенные в Windows API, но в полной мерс эти функции реализованы лишь в Windows 2000.

Насколько я помню, функция GetVersion есть в API всех версий Windows:

DWORD GetVersion();

С этой простой функцией связана целая история. Сначала ее разработали для 16 разрядной Windows, и она должна была я старшем слове возвращать номер версии MS-DOS, а в младшем — номер версии Windows. Соответственно в каждом слове старший байт сообщал основной номер версии, младший — дополнительный но мер версии

Увы, программист, писавший ее код, слегка ошибся, и получилось так, что номера версии Windows поменялись местами: в старший байт попадал дополнительный но мер, а в младший - основной. Поскольку многие программисты уже начали пользо ваться этой функцией, Microsoft пришлось оставить все, как есть, и изменить доку ментацию с учетом ошибки.

Из-за всей этой неразберихи вокруг GetVersion в Windows API включили новую функцию — GetVersionEx:

BOOL GetVersionEx(POSVERSIONINFO pVersionInformation);

Перед обращением к GetVersionEx профамма должна создать структуру OSVER SIONINFOEX, показанную ниже, и передать ее адрес этой функции

typedef struct {
DWORD dwOSVersionInfoSize;
DWORD dwMajorVersion;
DWORD dwMinorVersion;
DWORD dwBuildNumber;
DWORD dwPlatformId;
TCHAR szCSDVersion[128];
WORD wServicePackMajor;
WORD wServicePackMinor;
WORD wSuiteMask;
BYTE wProductType;
BYTE wReserved;
} OSVERSIONINFOEX, *POSVERSIONINFOEX;

Эта структура — новинка Windows 2000 В остальных версиях Windows использу ется структура OSVERSIONINFO, в которой нет последних пяти элементов, присутству ющих в структуре OSVERSIONINFOEX

Обратите внимание, что каждому компоненту номера версии операционной сис темы соответствует свой элемент структуры это сделано специально — чтобы про граммисты не возились с выборкой данных ш всяких там старших-младших байтов слов (и не путались в них), тeпepь программе гораздо проще сравнивать ожидаемый номер версии операционной системы с действительным Назначение каждою элемен та структуры OSVERSIONTNFOFX описано в таблице 4-2




Элемент Описание
dwOSVersionInfoSjze Размер структуры, перед обращением к функции GetVertsionEx дол жен быть заполнен вызовом sizeof(OSVERSIONINFO) или Sizeof(OSVERSIONINFOEX)
dwMajorVersion Основной номер версии операционной системы
dwMinorVersion Дополнительный номер версии операционной системы
dwBuildNumber Версия сборки данной системы
dwPlatformId Идентификатор платформы, поддерживаемой данной системой, его возможные шачепия VFR_PLATFORM_WIN32s (Win32s), VER_PLATFORM_WIN32_WINDOWS (Windows 95/98), VER_PLATFORM_WIN32_NT (Windows NT или Windows 2000), VER_PLATFORM_WIN32_CEHH (Windows CE)
szCSDVersion Этот элемент содержит текст — дополнительную информацию об установленной операционной системе
wServicePackMajor Основной номер версии последнего установленного пакета исправ лений (service pack)
wServicePackMinor Дополнительный номер версии последнего установленного пакета исправлений
Таблица 4-2. Элементы структуры OSVERSIONINFOEX

Элемент Описание
wSuiteMask Сообщает, какие программные пакеты (suites) доступны в системе;
его возможные значения

VER_SUITE_SMALLBUSINESS,
VER_SUITE_ENTERPRISE,
VER_SUITE_BACKOFFICE,
VER_SUITE_COMMUNICATIONS,
VER_SUITE_TERMINAL,
VER_SUITE_SMALLBUSINESS_RESTRICTED,
VER_SUITE_EMBEDDEDNT,
VER_SUITE_DATACENTER
wProductType Сообщает, какой именно вариант операционной системы установлен; его возможные значения:

VER_NT_WORKSTATION,
VER_NT_SERVER,
VER_NT_DOMAIN_CONTROLLER
wReserved Зарезервирован на будущее
В Windows 2000 появилась новая функция, VerifyVersionInfo, которая сравнивает версию установленной операционной системы с тем, что требует Ваше приложение:

BOOL VerifyVersionInfo(
POSVERSIONINFOEX pVersionInformation;
DWORD dwTypeMask;
DWORDLONG dwlConditionMask);

Чтобы использовать эту функцию, соэдайте структуру OSVERSIONINFOEX, запи шите в се элемент dwOSVersionInfoSize размер структуры, а потом инициализируйте любые другие элементы, важные для Вашей программы, При вызове VerifyVersionInfo параметр dwTypeMask указывает, какие элементы структуры Вы инициализировали.


Этот параметр принимает любые комбинации следующих флагов: VER_MINORVER SION, VER_MAJORVERSION, VER_BUILDNUMBER, VER_PLATFORMID, VER_SERVICEPACK MINOR, VER_SERVICEPACKMAJOR, VER_SUITENAME и VER_PRODUCT_TYPE, Последний параметр, dwlConditionMask, является 64-разрядным значением, которое управляет тем, как именно функция сравнивает информацию о версии системы с нужными Вам дан ными.

Параметр dwlConditionMask устанавливает правила сравнения через сложный на бор битовых комбинаций. Для создания требуемой комбинации используйте макрос VER_SET_CONDITION:

VER_SET_CONDITION(
DWORDLONG dwlConditionMask, ULONG dwTy0eBiLMask, ULONG dwConditionMask);

Первый параметр, dwlConditionMask, идентифицирует переменную, битами кото рой Вы манипулируете. Вы не передаете адрес этой переменной, потому что VER_SET_ CONDITION — макрос, а не функция. Параметр dwTypeBitMask указывает один элемент в структуре OSVERSIONINFOEX, который Вы хотите сравнить со своими данными. (Для сравнения нескольких элементов придется обращаться к VER_SETCONDITION не сколько раз подряд.) Флаги, передаваемые в этом параметре, идентичны передавае мым в параметре dwTypeMask функции VerifyVersionInfo.

Последний параметр макроса VER_SET_CONDITION, dwConditionMask, сообщает, как Вы хотите проводить сравнение. Он принимает одно из следующих значений. VER_EQUAL, VER_GREATER, VER_GREATER_EQUAL, VER_LESS или VER_LESS_EQUAL, Вы можете использовать эти значения в сравнениях по VER_PRODUCT_TYPE. Например, значение VER_NT_WORKSTATION меньше, чем VER_NT_SERVER. Но в сравнениях по VER_SUITENAME вместо этих значений применяется VER_AND (должны быть установ лены все программные пакеты) или VER_OR (должен быть установлен хотя бы один из программных пакетов).

Подготовив набор условий, Вы вызываете VerifyVersionlnfo и получаете ненулевое значение, если система отвечает требованиям Вашего приложения, или 0, если она не удовлетворяет этим требованиям или если Вы неправильно вызвали функцию Чтобы определить, почему VenfyVersionlnfo вернула 0, вызовше GetLastError. Если та вернет ERROR_OLD_WIN_VERSION, значит, Вы правильно вызвали функцию Venfy VersionInfo, но система не соответствует предъявленным требованиям.

Вот как проверить, установлена ли Windows 2000;

// готовим структуру OSVERSIONINFOEX, сообщая, что нам нужна Windows 2000
OSVERSIONINFOEX osver = { 0 };
osver.dwOSVersionInfoSize = sizeof(osver);
osver.dwMdjorVersion = 5;
osver.dwMinorVersion = 0;
osver.dwPlatformId = VER_PLATFORM_WIN32_NT;

// формируем маску условии

DWORDLONG dwlConditionMask = 0;
// всегда инициализируйте это элемент так
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL); VER_SET_CONDITION(dwlConditionMask, VER_PLATFORMID, VER_EQUAL);

// проверяем версию
if (VenfyVersionInfo(&osver, VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID,
dwlConditionMask)) {

// хост-система точно соответствует Windows 2000

} else {
// хост-система не является Windows 2000 }


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