📄 novdos.c
字号:
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: DOS NetWare IPX link core.
*
****************************************************************************/
#include <stddef.h>
#include <string.h>
#include <ctype.h>
#include <i86.h>
#include "nitipx.h"
#include "tinyio.h"
#include "packet.h"
#include "trptypes.h"
#include "trperr.h"
#include "ipxstuff.h"
#ifdef DEBUG
void putstring( char far *str )
{
unsigned bytes;
extern unsigned _dos_write( int handle, void __far *buffer, unsigned count, unsigned *bytes );
while( *str ) {
_dos_write( 1, str, 1, &bytes );
++str;
}
}
static char hexbuff[80];
char * hex( unsigned long num )
{
char *p;
p = &hexbuff[79];
*p = 0;
if( num == 0 ) {
*--p = '0';
return( p );
}
while( num != 0 ) {
*--p = "0123456789abcdef"[ num & 15 ];
num >>= 4;
}
return( p );
}
void puthex( unsigned long x )
{
putstring( hex( x ) );
}
void put1( unsigned char *c )
{
if( *c < 0x10 ) putstring( "0" );
puthex( *c );
}
void put2( unsigned char *c )
{
put1( c );
put1( c+1 );
}
void put4( unsigned char *c )
{
put2( c );
put2( c+2 );
}
void put6( unsigned char *c )
{
put4( c );
put2( c+4 );
}
void putnetaddr( SPXHeader *l ) {
putstring( " source" );
putstring( " net " );
put4( l->source.network.a );
putstring( " node " );
put6( l->source.node.a );
putstring( " socket " );
puthex( l->source.socket );
putstring( "\r\ndestination" );
putstring( " net " );
put4( l->destination.network.a );
putstring( " node " );
put6( l->destination.node.a );
putstring( " socket " );
puthex( l->destination.socket );
putstring( "\r\n" );
}
void putconnstatus( WORD conn )
{
CSB stat;
putstring( "Connection " );
puthex( conn );
putstring( " status " );
if( _SPXGetConnectionStatus( conn, &stat ) != 0 ) {
putstring( "unknown" );
} else {
puthex( stat.connectionStatus );
putstring( " id src " );
puthex( stat.sourceConnectionID );
putstring( " id dst " );
puthex( stat.destinationConnectionID );
}
putstring( "\r\n" );
}
#else
#define putnetaddr( x )
#define puthex( x )
#define putstring( x )
#define putnetaddr( x )
#define putconnstatus( x )
#endif
#define NUM_REC_BUFFS 5
SPXHeader SendHead;
SPXHeader RecHead[NUM_REC_BUFFS];
SPXHeader ConnHead;
ECB SendECB;
ECB ConnECB;
ECB RecECB[NUM_REC_BUFFS];
char Buffer[NUM_REC_BUFFS][MAX_DATA_SIZE];
WORD Connection;
WORD IPXSocket;
WORD SPXSocket;
WORD PartnerSPXSocket;
char Listening;
SIP SAPHead;
ECB SAPECB;
IPXHeader ServHead;
ECB ServECB;
IPXHeader RespHead;
ECB RespECB;
char ServDummy;
typedef void (far *ESRAddr)();
#ifdef __WINDOWS__
#define ESRFUNC __export __far __pascal
DWORD IPXTaskID;
typedef int (WINAPI *NOVWINAPI)();
NOVWINAPI IPXFuncs[ IPX_MAX_FUNCS ];
extern void SetLinkName( char* );
#else
#define ESRFUNC
#endif
ESRAddr SAPBroadESRAddr;
ESRAddr SAPWaitESRAddr;
ESRAddr ServRespESRAddr;
static void IpxWait( void )
{
//*******************************************************************
// NOTE: This call is absolutely necessary. The DOS call some
// how clears out a condition in IPX where IPXRelinquishControl
// won't return.
//*******************************************************************
extern void clock(void);
#pragma aux clock = \
0xb4 0x2c /* mov ah,02ch */ \
0xcd 0x21 /* int 21h */ \
modify [ cx dx ];
clock();
_IPXRelinquishControl();
}
#define WaitOn( ecb ) while( (ecb).inUseFlag ) IpxWait()
static void Delay( unsigned timeout )
{
unsigned start;
start = _IPXGetIntervalMarker();
for( ;; ) {
_IPXRelinquishControl();
if( (_IPXGetIntervalMarker() - start) >= timeout ) break;
}
}
static char WaitTimeout( ECB *ecb, unsigned timeout, int can )
{
unsigned start;
start = _IPXGetIntervalMarker();
for( ;; ) {
_IPXRelinquishControl();
if( ecb->inUseFlag == 0 ) {
return( ecb->completionCode == 0 );
}
if( (_IPXGetIntervalMarker() - start) >= timeout ) {
if( can ) _IPXCancelEvent( ecb );
return( 0 );
}
}
}
static void PostAListen( int i )
{
_INITECB( RecECB[i], RecHead[i], 2, SPX );
RecECB[i].fragmentDescriptor[1].address = &Buffer[i];
RecECB[i].fragmentDescriptor[1].size = sizeof( Buffer[i] );
_SPXListenForSequencedPacket( &RecECB[i] );
}
static unsigned DoRemoteGet( char *rec, unsigned len )
{
int i;
unsigned recvd;
unsigned got;
int p;
len = len;
recvd = 0;
for( ;; ) {
i = NUM_REC_BUFFS-1;
p = -1;
for( ;; ) {
if( i < 0 ) {
if( p != -1 ) break;
_IPXRelinquishControl();
i = NUM_REC_BUFFS-1;
}
if( !RecECB[i].inUseFlag ) {
if( p == -1
|| LOWER_SEQ( RecHead[i].sequenceNumber, RecHead[p].sequenceNumber ) ) {
p = i;
}
}
--i;
}
got = _SWAPINT( RecHead[p].length ) - sizeof( RecHead[p] );
_fmemcpy( rec, Buffer[p], got );
recvd += got;
PostAListen( p );
if( got != MAX_DATA_SIZE ) break;
rec = (unsigned_8 *)rec + got;
}
return( recvd );
}
static unsigned DoRemotePut( char *snd, unsigned len )
{
_INITECB( SendECB, SendHead, 2, SPX );
SendHead.connectControl |= 0x10;
SendHead.length = _SWAPINT( sizeof( SendHead ) + len );
SendECB.fragmentDescriptor[1].address = snd;
SendECB.fragmentDescriptor[1].size = len;
_SPXSendSequencedPacket( Connection, &SendECB );
WaitOn( SendECB );
return( len );
}
unsigned RemoteGet( char *rec, unsigned len )
{
return( DoRemoteGet( rec, len ) );
}
unsigned RemotePut( char *snd, unsigned len )
{
while( len >= MAX_DATA_SIZE ) {
if( DoRemotePut( snd, MAX_DATA_SIZE ) == REQUEST_FAILED ) {
return( REQUEST_FAILED );
}
snd = (unsigned_8 *)snd + MAX_DATA_SIZE;
len -= MAX_DATA_SIZE;
}
if( DoRemotePut( snd, len ) == REQUEST_FAILED ) {
return( REQUEST_FAILED );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -