// ===================================================
// Листинг 23. Клиент NETBIOS, вариант с
//           использованием каналов
//
// Файл nbclient.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_CLIENT {

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

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

		NCB AddNameNCB;

public:

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

	char OurName[16];
	unsigned NetworkNameNumber;

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

	NETBIOS_SESSION_CLIENT(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;

// Устанавливаем имя сервера, с которым
// будем создавать канал

		AddNameNCB.SetCallName("NETBIOS Server");

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

		AddNameNCB.SetRtoSto(20,20);

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

		AddNameNCB.WCall();
	}

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

	~NETBIOS_SESSION_CLIENT() {

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

		AddNameNCB.WHangUp();

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

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

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

	int Error(void) {return errno;}

// Функция для передачи по каналу

	void Send(char *ReceiveBuffer, unsigned BufferSize) {

// Устанавливаем адрес и длину буфера

		AddNameNCB.SetBuffer(ReceiveBuffer, BufferSize);

// Передаем данные по каналу с ожиданием

		AddNameNCB.WSend();
	}
};

void main(void) {

// Наш клиент с именем "NETBIOS Client"

	NETBIOS_SESSION_CLIENT Client("NETBIOS Client");

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

	if(Client.Error()) {
		printf("Ошибка %02.2X\n", Client.Error());
		return;
	}
	printf("Инициализация завершена.\n");

// Передаем сообщение серверу по созданному каналу.
// Канал был создан при работе конструктора
// класса NETBIOS_SESSION_CLIENT.

	Client.Send("Привет от клиента NETBIOS!", 512);
}