Программирование на C++ глазами хакера

         

Запуск библиотеки


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

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

int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData );

Первый параметр (wVersionRequested) — это запрашиваемая версия библиотеки. Младший байт указываемого числа определяет основной номер версии, а старший байт — дополнительный номер. Чтобы легче было работать с этим параметром, я советую использовать макрос MAKEWORD(i, j), где i — это старший байт, a j — младший.

Второй параметр функции WSAStartup — это указатель на структуру WSADATA, в которой после выполнения функции будет находиться информация о библиотеке.

Если загрузка прошла успешно, то результат будет нулевым, иначе — произошла ошибка.

Посмотрите пример использования функции WSAStartup для загрузки библиотеки WinSock 2.0:

WSADATA wsaData;

int err = WSAStartup(MAKEWORD(2, 0), wsaData); if (err != 0) { // Tell the user that WinSock not loaded // ( Сказать пользователю, что библиотека не загружена ) return; }

Обратите внимание, что сразу после попытки загрузить библиотеку идет проверка возвращенного значения. Если функция отработала правильно, то она должна вернуть нулевое значение. Приведу основные коды ошибок:

WSASYSNOTREADY — основная сетевая подсистема не готова к сетевому соединению;

WSAVERNOTSUPPORTED — запрашиваемая версия библиотеки не поддерживается;

WSAEPROCLIM — превышен предел поддерживаемых ОС задач;

WSAEFAULT — неправильный указатель на структуру WSAData.

Структура WSADATA выглядит следующим образом:

typedef struct WSAData { WORD wVersion; WORD wHighVersion; char szDescription[WSADESCRIPTION_LEN+l]; char szSystemStatus[WSASYS_STATOS_LEN+l]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo; } WSADATA, FAR * LPWSADATA;




Разберем каждый параметр в отдельности:

wVersion — версия загруженной библиотеки WinSock;

wHighVersion — последняя версия;

szDescription — текстовое описание, которое заполняется не всеми версиями;

szSystemStatus — текстовое описание состояния, которое заполняется не всеми версиями;

iMaxSockets — максимальное количество открываемых соединений. Эта информация не соответствует действительности, потому что максимальное число зависит только от доступных ресурсов. Параметр остался только для совместимости с первоначальной спецификацией;

iMaxUdpDg — максимальный размер дейтаграммы (пакета). Информация не соответствует действительности, потому что размер зависит от протокола;

lpVendorInfо — информация о производителе.

Давайте рассмотрим небольшой пример, с помощью которого будет загружаться библиотека WinSock из структуры WSAData . Создайте новый проект MFC Application. В Мастере создания приложений, в разделе Application Type выберите Dialog based, а в разделе Advanced Features — Windows sockets. Это уже знакомый вам тип приложения.

Откройте в редакторе ресурсов диалоговое окно и оформите, как на 4.11. На форме должно быть 4 поля Edit Control для вывода информации о загруженной библиотеке и кнопка Get WinSock Info, по нажатию которой будут загружаться данные.

Для каждого поля вводятся переменные:

номер версии — mVersion;

последняя версия — mHighVersion;

описание — mDescription;

состояние — mSystemStatus.

Создайте обработчик события для кнопки Get WinSock Info и напишите в нем код из листинга 4.11.



4.11. Окно будущей программы WinSockInfo

Листинг 4.11. Получение информации о WinSock
void CWinSockInfoDlg::OnBnClickedButton1() { // TODO: Add your control notification handler code here WSADATA wsaData;

int err = WSAStartup(MAKEWORD(2, 0), wsaData); if (err != 0) { // Tell the user that WinSock not loaded return; }

char mText[255]; mVersion.SetWindowText(itoa(wsaData.wVersion, mText, 10)); mHighVersion.SetWindowText(itoa(wsaData.wHighVersion, mText, 10)); if (wsaData.szDescription) mDescription.SetWindowText(wsaData.szDescription); if (wsaData.szSystemStatus) mSystemStatus.SetWindowText(wsaData.szSystemStatus); }



В самом начале запускается WinSock (код, который я уже приводил). После этого полученная информация просто выводится в поля на форме диалога.



4.12. Результат работы программы WinSockInfo

На 4.12 вы можете увидеть результат работы программы на моем компьютере.

Примечание
Исходный код примера, описанного в этом разделе, вы можете найти на компакт - диске в каталоге \Demo\Chapter4\WinSockInfo.
В приведенном примере есть один недостаток — не выгружается библиотека. для освобождения библиотеки используется функция WSACleanup:

int WSACleanup(void);

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


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