WinPopdown

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

Автор: Разинков Илья (IPv6)
Опубликовано: 06.11.2002
Версия текста: 1.0

Немного истории
Как это работает

Демонстрационный проект (VC6, MFC)
Исполняемый файл

Немного истории

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

Естественно мысль написать чего нибудь свое так, как хочется просто уже висела в воздухе. Первые попытки найти информацию в инете каким образом это вообще происходит навели на странные мысли что с одной стороны многие пытались, но с другой не у всех получилось. А те, у кого получилось - молчат :(. И чтобы в будущем "ищущие" не попадали в такую же ситуацию, в какую попал я (связанную с дефицитом данных по этой теме), я и выкладываю то что у меня в результате получилось.

Как это работает

В инете было найдено что сервис поддерживает работу сразу по двум каналам - по mailslot и по netbios (точнее через SMB - Service Message Block - надстройка над Netbios).

C mailslot удалось разобраться довольно быстро и здесь я на этом останавливаться не буду – информация есть даже в MSDN, не говоря уже о разных форумах, а вот с технологией отcылки/приема сообщений через Netbios вышла загвоздка. В присутствии специального сервиса "Messenger Service" отсылать сообщение довольно просто (функцией WinApi “ NetMessageBufferSend”), но вот принимать - нет никакой возможности (сообщение принимается исключительно самим сервисом, реакцией которого был показ знакомого наверно многим Message box-а с текстом сообщения). В отсутствии же оного все теряется в тумане. Побившись немного головой "об стену" и ничего не узнав пришлось идти путем изобретателя велосипеда и открывать Америку заново. Поставив на две машины в сети по снифферу и послушав что шлют Messenger servic-ы друг другу формат сообщений удалось расшифровать (благо не такой он сложный). Естественно из этого следует что возможно что-то все-таки упущено, поэтому всем кто скачает и опробует эту программу у себя в сети большая просьба - если не работает, то сообщите пожалуйста где и что не работает (если будет возможность разобраться конечно). Я со своей стороны могу сказать что в нашей доменной сети пересылка сообщений (даже больших, хотя у Messenger Service есть ограничение на максимальный размер сообщений, это где-то около килобайта) между компьютерами c Windows 2000 и Windows NT проблем пока не встречала.

Теперь немного о формате. Формат Netbios-пакета включает в себя заголовок (32 байта), первые 4 байта которого стандартны - 0xFF,'S','M','B', а пятым байтом идет команда которую этот пакет "символизирует". Для отсылки/приема сообщений из заголовка кроме первых 4ех байт ничего больше не используется (заполняется нулями). Кроме заголовка в пакет входит само тело пакета. «Наполнение» этого тела зависит от команды

Команд ОЧЕНЬ много, предназначены они чуть ли не для всего - для передачи файлов/поиска файлов на удаленной машине и т.д. и т.п. За отсылку сообщений же отвечают четыре команды

0xd0Сообщение, помещающееся целиком в один пакет; в этот пакет помещается строка с именем «от кого», строка с именем «кому» и само сообщение (все три строки разделены 0-ым байтом)
0xd5Сообщение, не помещающееся целиком в один пакет, точней начало такого сообщения (информация от кого и кому). В такой пакет помещается лишь «от кого» и «кому»
0xd7Сообщение, не помещающееся целиком в один пакет, кусок сообщения. Пакеты с этой командой шлются до тех пор пока не будет частями переслано все сообщение
0xd6Сообщение, не помещающееся целиком в один пакет, конец сообщения. В пакете собственно ничего нет (сам пакет представляет из себя, кроме заголовка, 5 нулей)

До приема/передачи сообщений также необходимо для начала зарегистрировать сетевое имя. в WinPopDown регистрится имя компьютера. Внутренний сетевой "ник" общающихся машин при регистрации должен обязательно заканчиваться на цифру 3 - это окончание "забито" Microsoftом специально для Messenger Service.

Полная замена сервиса должна по идее делать следующие вещи:

- обрабатывать сообщения, приходящие по mailslot (делается это довольно просто стандартными средствами WinApi работы с mailslot-ами. для отправки/приема сообщений используется слот с именем "messngr");

- регистрировать netbios alias не только по имени компьютера, но еще и по имени активного (залогиненного) пользователя в данный момент, а также по имени домена, в который этот пользователь входит (или по имени рабочей группы если доменной системы нет);

- правильно работать в ситуациях, когда на машине установлено несколько сетевых карт и/или протоколов, поверх которых возможно общение по NetBios

WinPopDown принимает и отправляет сообщения только от сетевого "ника", составленного из имени компьютера (т.к. программа имеет демонстрационный характер, цель поддерживать всё, полагающееся для «Messenger Service» не ставилась). Зато WinPopDown показывает реального отправителя сообщения (который в общем-то может легко не совпадать с тем что передано в самом сообщении; многие специализированные программы позволяют менять поле «от кого»; реальное сетевое имя отправителя так изменить невозможно и вот оно-то и показывается WinPopdown-ом)

Еще одним из ограничений WinPopDown является работа только по одному LAN-адаптеру (LANA), номер которого, если у Вас на машине установлено несколько сетевых карт или активны несколько поддерживающих Netbios протоколов, вы сможете выбрать при запуске программы. LANA – это некоторое число, характеризующее через какую сетевую карту и по какому протоколу более низкого уровня, поддерживающего Netbios, будет работать передача сообщений. Пример: если на компьютере установлено две карты, по каждой из которых можно обмениваться пакетами по Tcp-ip и NetBEUI, то для обмена сообщениями по NetBios будет доступно 4е Lana (каждому такому сочетанию системой будет присвоен определенный номер)– «Первая карта / Tcp-ip», «Первая карта / NetBEUI», «Вторая карта / Tcp-ip», «Вторая карта / NetBEUI». MSDN для Netbios-приложений, которые претендуют на независимость от количества LAN-адаптеров, рекомендуется использовать следующий подход – перенумеровать все адаптеры, затем для серверной части зарегистрировать сетевое имя на каждом адаптере и начать «слушать» сообщения на каждом LANA. Для клиентской части, также рекомендуется отправлять сообщения по каждому LANA, но при установке соединения хотя бы по одному такому каналу, запрос на соединения на других LANA должен быть отменен. Кстати, для старых операционных систем (например DOS, Windows 95) считалось что с точки зрения NetBios существует только один LANA, с номером 0, поэтому это значение в некоторых программах просто жестко прошивалось в коде программы.

ПРЕДУПРЕЖДЕНИЕ

Так как эта программа работает вместо Messenger Service, то перед запуском надо этот сервис остановить. (потом можно запустить его вновь). Дело в том что при старте программа пытается зарегистрировать сетевой ник (про который было сказано выше). И так как это имя должно быть в сети уникальным то при запущенном Messenger Service эта попытка естественно не удастся (ведь тоже самое - регистрацию имени - при запуске делает сервис)

Осталось привести коды ошибок которые могут возникать в процессе работы с Netbios в целом и при отсылке/приеме сообщений в частности. Вот они:

NRC_GOODRET0x00The operation succeeded.
NRC_BUFLEN0x01An illegal buffer length was supplied.
NRC_ILLCMD0x03An illegal command was supplied.
NRC_CMDTMO0x05The command was timed out.
NRC_INCOMP0x06The message was incomplete. The application is to issue another command.
NRC_BADDR0x07The buffer address was illegal.
NRC_SNUMOUT0x08The session number was out of range.
NRC_NORES0x09No resource was available.
NRC_SCLOSED0x0aThe session was closed.
NRC_CMDCAN0x0bThe command was canceled.
NRC_DUPNAME0x0dA duplicate name existed in the local name table.
NRC_NAMTFUL0x0eThe name table was full.
NRC_ACTSES0x0fThe command finished; the name has active sessions and is no longer registered.
NRC_LOCTFUL0x11The local session table was full.
NRC_REMTFUL0x12The remote session table was full. The request to open a session was rejected.
NRC_ILLNN0x13An illegal name number was specified.
NRC_NOCALL0x14The system did not find the name that was called.
NRC_NOWILD0x15Wildcards are not permitted in the ncb_name member.
NRC_INUSE0x16The name was already in use on the remote adapter.
NRC_NAMERR0x17The name was deleted.
NRC_SABORT0x18The session ended abnormally.
NRC_NAMCONF0x19A name conflict was detected.
NRC_IFBUSY0x21The interface was busy.
NRC_TOOMANY0x22Too many commands were outstanding; the application can retry the command later.
NRC_BRIDGE0x23The ncb_lana_num member did not specify a valid network number.
NRC_CANOCCR0x24The command finished while a cancel operation was occurring.
NRC_CANCEL0x26The NCBCANCEL command was not valid; the command was not canceled.
NRC_DUPENV0x30The name was defined by another local process.
NRC_ENVNOTDEF0x34The environment was not defined. A reset command must be issued.
NRC_OSRESNOTAV0x35Operating system resources were exhausted. The application can retry the command later.
NRC_MAXAPPS0x36The maximum number of applications was exceeded.
NRC_NOSAPS0x37No service access points (SAPs) were available for NetBIOS.
NRC_NORESOURCES0x38The requested resources were not available.
NRC_INVADDRESS0x39The NCB address was not valid.
NRC_INVDDID0x3bThe NCB DDID was invalid.
NRC_LOCKFAIL0x3cThe attempt to lock the user area failed.
NRC_OPENERR0x3fAn error occurred during an open operation being performed by the device driver. This error code is not part of the NetBIOS 3.0 specification.
NRC_SYSTEM0x40A system error occurred.

Напоследок - повторюсь. Т.к. все-таки информация наполовину получена эмпирическим путем, то если у вас в различных сетевых условиях будут возникать глюки - сообщите пожалуйста на каких средах они возникают: либо по emailу razinkov@mail.ru, либо сюда, в комментарии к статье


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