// ===================================================
// Листинг 22. Сервер NETBIOS, вариант с
//           использованием каналов
//
// Файл nbserver.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <conio.h>
#include <mem.h>
#include <string.h>
#include "netbios.hpp"

// Класс серверов NETBIOS

class NETBIOS_SESSION_SERVER {

	unsigned errno;
	void interrupt ( *int5C)(...);

public:

// Здесь хранится имя сервера
// и номер этого имени

	char OurName[16];
	unsigned NetworkNameNumber;

// Блок NCB, который будет использован при добавлении
// имени

	NCB AddNameNCB;

// Конструктор, проверяет наличие NETBIOS
// и добавляет имя

	NETBIOS_SESSION_SERVER(char *Name) {

// Проверяем длину имени имя

		if(strlen(Name) > 15) {
			errno = 0xff;
			return;
		}
		strcpy(OurName, Name);

// Проверяем наличие интерфейса NETBIOS

		int5C = getvect(0x5c);
		errno = 0;
		if(FP_SEG(int5C) == 0x0000 || FP_SEG(int5C) == 0xF000) {
			errno=0xff;
			return;
		}

// Добавляем имя

		AddNameNCB.WAddName(OurName);

// Запоминаем полученный номер имени

		NetworkNameNumber = AddNameNCB.GetNetworkNameNumber();
		errno = AddNameNCB.Error();
		if(errno) return;

// Устанавливаем "*" в поле CallName, это означает,
// что сервер будет обрабатывать запросы на создание
// канала от любого имени

		AddNameNCB.SetCallName("*");

// Устанавливаем время тайм-аута для команд
// приема и передачи данных по каналу

		AddNameNCB.SetRtoSto(20,20);

// Создаем канал с принимающей стороны

		AddNameNCB.WListen();
	}

// Деструктор, удаляет канал и имя.

	~NETBIOS_SESSION_SERVER() {

// Удаление канала

		AddNameNCB.WHangUp();

// Удаление имени

		AddNameNCB.WDeleteName(OurName);
		errno = AddNameNCB.Error();
	}

// Функция для проверки кода ошибки

	int Error(void) {return errno;}

// Функция для приема данных по каналу

	void Receive(char *ReceiveBuffer, unsigned BufferSize) {

// Записываем в NCB адрес и длину буфера

		AddNameNCB.SetBuffer(ReceiveBuffer, BufferSize);

// Выполняем прием датаграммы с ожиданием

		AddNameNCB.WReceive();

	}
};

void main(void) {

// Наш сервер с именем "NETBIOS Server"

	NETBIOS_SESSION_SERVER Server("NETBIOS Server");
	char ReceiveBuffer[512];

// Проверяем, были ли ошибки на этапе
// инициализации сервера.

	if(Server.Error()) {
		printf("Ошибка %02.2X\n", Server.Error());
		return;
	}
	printf("Инициализация завершена.\n");
	printf("Ожидаем сообщение от клиента.\n");

// Принимаем сообщение от клиента по каналу,
// который был создан конструктором
// класса NETBIOS_SESSION_SERVER

	Server.Receive(ReceiveBuffer, 512);
	printf("Принято: >%s<\n",ReceiveBuffer);
}