// ===================================================
// Листинг 5. Include-файл для программы SLIST.CPP
//
// Файл slist!\sap.hpp
//
// (C) A. Frolov, 1993
// ===================================================

// Максимальное количество серверов, для которых
// выполняется опрос

#define MAX_SERVERS         8

// Типы сервиса SAP

#define GENERAL_SERVICE     1
#define NEAREST_SERVICE     3
#define NOT_SUPPORTED	    1

// Короткоживущий сокет

#define SHORT_LIVED         0x00

// Сокет для SAP-протокола

#define SAP_SOCKET          0x452

// Тип пакета SAP

#define SAP_PACKET_TYPE	    2

// Определения используемых типов данных

#define BYTE  unsigned char
#define WORD  unsigned short

// Сетевой адрес

typedef struct IPXAddress {
	BYTE	network[4];
	BYTE	node[6];
	WORD	socket;
} IPXAddress;

// Заголовок IPX-пакета

typedef struct IPXHeader {
	 WORD	      checkSum;
	 WORD	      length;
	 BYTE	      transportControl;
	 BYTE	      packetType;
	 IPXAddress	destination;
	 IPXAddress	source;
} IPXHeader;

// Заголовок SAP-пакета

typedef struct SAPHeader {
		 WORD	       checksum;
		 WORD	       length;
		 BYTE	       transportControl;
		 BYTE	       packetType;
		 IPXAddress  destination;
		 IPXAddress  source;
		 WORD	       SAPPacketType;
		 WORD	       serverType;
		 BYTE	       serverName[48];
		 IPXAddress  serverAddress;
		 WORD	       interveningNetworks;
} SAPHeader;

// Пакет для посылки SAP-запроса

typedef struct SAPQueryPacket {
		 WORD	       checksum;
		 WORD	       length;
		 BYTE	       transportControl;
		 BYTE	       packetType;
		 IPXAddress  destination;
		 IPXAddress  source;
		 WORD	       queryType;
		 WORD	       serverType;
} SAPQueryPacket;

// Структуры для описания блока ECB

typedef struct ECBFragment {
			void    far *address;
			WORD    size;
} ECBFragment;

typedef struct ECB {
		void 	      far *linkAddress;
		void 	      (far *ESRAddress)();
		BYTE 	      inUseFlag;
		BYTE 	      completionCode;
		WORD 	      socketNumber;
		BYTE 	      IPXWorkspace[4];
		BYTE 	      driverWorkspace[12];
		BYTE 	      immediateAddress[6];
		WORD 	      fragmentCount;
		ECBFragment	fragmentDescriptor[2];
} ECB;

// SAP-пакет

typedef struct {
		 IPXHeader    Header;
		 WORD	    ResponseType;
		 WORD	    ServerType;
		 BYTE	    ServerName[48];
		 BYTE	    Network[4];
		 BYTE	    Node[6];
		 WORD	    Socket;
		 WORD	    InterveningNetworks;
} SAP;

// Структура для передачи SAP-пакета

typedef struct {
		 ECB		 theECB;
		 SAPQueryPacket	 SAPq;
} SEND_PACKET;

// Структура для приема SAP-пакета

typedef struct {
		 ECB   theECB;
		 SAP   SB;
} RECEIVE_PACKET;

// Информация о файл-сервере

typedef struct  {
	 char    serverName[48];
	 BYTE    netwareVersion;
	 BYTE    netwareSubVersion;
	 WORD    maxConnectionsSupported;
	 WORD    connectionsInUse;
	 WORD    maxVolumesSupported;
	 BYTE    revisionLevel;
	 BYTE    SFTLevel;
	 BYTE    TTSLevel;
	 WORD    peakConnectionsUsed;
	 BYTE    accountingVersion;
	 BYTE    VAPversion;
	 BYTE    queingVersion;
	 BYTE    printServerVersion;
	 BYTE    virtualConsoleVersion;
	 BYTE    securityRestrictionLevel;
	 BYTE    internetBridgeSupport;
 } FILE_SERV_INFO;

// Описания функций библиотеки NetWare C Interface

extern "C" int IPXInitialize(void);
extern "C" int IPXOpenSocket(WORD *, BYTE);
extern "C" int IPXListenForPacket(ECB *);
extern "C" int IPXCancelEvent(ECB *);
extern "C" int IPXCloseSocket(WORD);
extern "C" WORD IntSwap(WORD);
extern "C" void IPXGetInternetworkAddress(BYTE *);
extern "C" void IPXSendPacket(ECB *);
extern "C" void IPXRelinquishControl(void);
extern "C" IPXGetLocalTarget(BYTE *, BYTE *, int*);
extern "C" WORD IPXGetIntervalMarker(void);
extern "C" long LongSwap(long);
extern "C" int AttachToFileServer(char *, WORD *);
extern "C" int SetPrimaryConnectionID(int);
extern "C" int GetServerInformation(int, FILE_SERV_INFO *);
extern "C" WORD GetPreferredConnectionID(void);
extern "C" WORD GetPrimaryConnectionID(void);
extern "C" WORD GetDefaultConnectionID(void);
extern "C" int SetPreferredConnectionID(WORD);
extern "C" int GetConnectionID(char *, WORD *);
extern "C" void DetachFromFileServer(WORD);
extern "C" int GetNetWareShellVersion(BYTE *,BYTE *, BYTE *);
extern "C" int IsConnectionIDInUse(WORD);
extern "C" int GetNetworkSerialNumber(long *, int*);

// Класс SLIST

class SLIST {
private:

	WORD	QueryType;     // тип запроса
	WORD	SrcSocket;     // сокет

// Массив для приема SAP-пакетов

	RECEIVE_PACKET	 Query[MAX_SERVERS];

// Передаваемый SAP-пакет

	SEND_PACKET   SendPacket;

// Таблицы имен файл-серверов, серийных
// номеров и номеров приложений

	char ServerName[MAX_SERVERS][48];
	long SerialNumber[MAX_SERVERS];
	int  ApplicationNumber[MAX_SERVERS];

// Таблица информации о файл-серверах

	FILE_SERV_INFO ServerInfo[MAX_SERVERS];

// Таблица номеров каналов файл-серверов

	WORD	ConnID[MAX_SERVERS];

// Функции для приема и передачи SAP-пакетов

	void	ReceiveSAPPacket(RECEIVE_PACKET	 *Query);
	void 	SendSAPPacket(void);

// Функции для получения имен файл-серверов и
// другой информации о файл-серверах

	void  GetServersName(void);
	void  GetServersInfo(void);

public:

	int errno;              // код ошибки
	WORD PreferredConnID;   // предпочтительный сервер
	WORD PrimaryConnID;     // первичный сервер
	WORD DefaultConnID;     // сервер по умолчанию

	BYTE MajorVersion;      // верхний номер версии
	BYTE MinorVersion;      // нижний номер версии
	BYTE Revision;          // номер изменений

	SLIST(int);  // конструктор
	~SLIST();    // деструктор

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

	void  PrintServersName(void);

// Проверка ошибок

	int Error(void) { return errno; }
};
