⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mplpc.c

📁 quake1 dos源代码最新版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
Copyright (C) 1996-1997 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/
#include <go32.h>
#include "mpdosock.h"

//#include "types.h"
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;

//#include "lpc.h"
typedef struct {
	short	version;	// version of LPC requested
	short	sizeOfArgs;	// size of arguments
	short	service;	// service # requested
	char	Data[1];	// data
} LPCData;

typedef struct {
	short	version;		// LPC version
	short	sizeOfReturn;	// return data size
	short	error;			// any error codes
	short	noRet;			// number of returns
	char	Data[1];		// data
} LPCReturn;

//#include "services.h"
#define  MAXSOCKETS  20

// services
#define LPC_SOCKBIND			4
#define LPC_SOCKGETHOSTBYNAME	5
#define LPC_SOCKGETHOSTNAME		6
#define LPC_SOCKGETHOSTBYADDR	7
#define LPC_SOCKCLOSE			8
#define LPC_SOCKSOCKET			9
#define LPC_SOCKRECVFROM		10
#define LPC_SOCKSENDTO			11
#define LPC_SOCKIOCTL			12
#define LPC_SOCKGETSOCKNAME		13
#define LPC_SOCKFLUSH			14
#define LPC_SOCKSETOPT			15
#define LPC_SOCKGETLASTERROR	16
#define LPC_SOCKINETADDR		17

// htons, ntohs, htonl, ntohl implemented locally

// errors
#define LPC_UNRECOGNIZED_SERVICE	-1
#define LPC_NOERROR					0

// structures for support
typedef struct {
	SOCKET	s;
	int		namelen;
	char	name[1];
} BindArgs;

typedef struct {
	SOCKET	s;
	long	cmd;
	char	data[1];
} IoctlArgs;

typedef struct {
	int		retVal;
	int		namelen;
	char	name[1];
} GetSockNameRet;

typedef GetSockNameRet GetHostNameRet;

typedef struct {
	int		retVal;
	int		h_addr_0;	// that's the only important value
} GetHostByNameRet;

typedef struct {
	int		len;
	int		type;
	char	addr[1];
} GetHostByAddrArgs;

typedef struct {
	int		retVal;
	char	h_name[1];	// h_name is the only important value
} GetHostByAddrRet;

typedef struct {
	SOCKET	s;
	int		flags;
} RecvFromArgs;

typedef struct {
	int		retVal;
	int		errCode;
	int		len;	// message len
	struct sockaddr	sockaddr;
	int		sockaddrlen;
	char	Data[1];
} RecvFromRet;

typedef struct {
	SOCKET	s;
	int		flags;
	int		len;
	struct sockaddr	sockaddr;
	int		sockaddrlen;
	char	Data[1];
} SendToArgs;

typedef struct {
	int		retVal;
	int		errCode;
} SendToRet;

typedef struct {
	int	bufflen;
	SOCKET	s;
	int	len;
	int	sockaddrlen;
	struct sockaddr	address;
	char	data[1];
} SocketChannelData;

typedef struct {
   int af;
   int type;
   int protocol;
} SocketArgs;

typedef struct {
   SOCKET s;
   int len;
   int flags;
   int addrlen;
   struct sockaddr addr;
   char data[1];
} WinSockData;

typedef struct {
   SOCKET s;
   int level;
   int optname;
   int optlen;
   char optval[1];
} SetSockOptArgs;

typedef struct {
   SOCKET   sock[MAXSOCKETS];
} SocketMap;

//#include "rtq.h"
#define RTQ_NODE struct rtq_node

RTQ_NODE
{
	RTQ_NODE	*self;		// Ring zero address of this node
	RTQ_NODE	*left;		// Ring zero address of preceding node
	RTQ_NODE	*right;		// Ring zero address of succeding node
	BYTE		*rtqDatum;	// Ring 3 Datum of Buffer (start of preface)
	BYTE		*rtqInsert;	// Ring 3 insertion position
	WORD		rtqLen;		// Length of buffer, excluding preface
	WORD		rtqUpCtr;	// Up Counter of bytes used so far
	WORD		rtqQCtr;	// number of nodes attached
	WORD		padding;	// DWORD alignment
};

#define RTQ_PARAM_MOVENODE struct rtq_param_movenode
RTQ_PARAM_MOVENODE
{
	WORD		rtqFromDQ;
	WORD		rtqToDQ;
};

RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From

//#include "mplib.h"
// give up time slice
void Yield(void);
void MGenWakeupDll(void);

// post a message to win32 side
void PostWindowsMessage(void);

// get # of items on qNo
int MGenGetQueueCtr(int qNo);

// move first node from qFrom to qTo
RTQ_NODE *MGenMoveTo(int qFrom, int qTo);

// get first node from q
RTQ_NODE *MGenGetNode(int q);

// get master node, returning size of RTQ_NODE for size verification
RTQ_NODE *MGenGetMasterNode(unsigned *size);

// move all nodes from qFrom to qTo
RTQ_NODE *MGenFlushNodes(int qFrom, int qTo);

// count number of nodes in queues designated by bitmask
// lowerOrderBits == 0..31, upperOrderBits == 32-63
int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits);

// perform consistency check on chunnel address space
int MGenSanityCheck(void);

#include <stdio.h>
#include <sys/farptr.h>

extern short flat_selector;

#define SOCKET_MAP_QUEUE  41

#define IDLE_QUEUE	44
#define REC_QUEUE	45
#define SEND_QUEUE	46

//  queue sizes
#define FREEQBASE	58
#define FREEQ64		58
#define FREEQ128	59
#define FREEQ256	60
#define FREEQ512	61
#define FREEQ1024	62
#define FREEQ2048	63

#define NFREEQ		6

#define QLIMIT		10

#define PRIVATEQ	50

#define FARPKL(x)  (_farnspeekl((unsigned long) x))
#define FARPKB(x)  (_farnspeekb((unsigned long) x))
#define FARPKS(x)  (_farnspeekw((unsigned long) x))

#define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y))
#define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y))

int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 };

int SocketError = 0;

SocketMap *SockMap;

#define HOSTENT_ALIAS_LIMIT    5
#define HOSTENT_STRLEN_LIMIT   50
#define HOSTENT_ADDR_LIST_LIMIT   5

struct hostent  HostEnt;

char HostEnt_hname[HOSTENT_STRLEN_LIMIT];
char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT];
char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT];
struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT];
struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT];

void
fmemcpyto(void *to, const void *from, int length)
{
   movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length);
}

void
fmemcpyfrom(void *to, const void *from, int length)
{
   movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length);
}

void
fstrcpyto(char *to, const char *from)
{
   while (*from) {
	  FARPOKB(to, *from);
	  to++; from++;
   }
   FARPOKB(to, 0);
}

void
fstrncpyto(char *to, const char *from, int len)
{
   while (*from && len) {
	  FARPOKB(to, *from);
	  to++; from++; len--;
   }
   FARPOKB(to, 0);
}

void
fstrcpyfrom(char *to, const char *from)
{
   while (FARPKB(from)) {
	  *to = FARPKB(from);
	  from++; to++;
   }
   *to = 0;
}

void
fstrncpyfrom(char *to, const char *from, int len)
{
   while (FARPKB(from) && len) {
	  *to =  FARPKB(from);
	  from++; to++; len--;
   }
   *to = 0;
}

void
GetSocketMap(void)
{
   RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE);

   SockMap = (SocketMap *) FARPKL(&n->rtqDatum);
}

void *
GetFreeBufferToQueue(int q, int bufSize)
{
   int i;

   for (i = 0; i < NFREEQ; i++) {
	  if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) {
		 RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q);
		 if (!n)
			continue;
		 FARPOKL(&n->rtqUpCtr, bufSize);
		 return (void *) FARPKL(&n->rtqDatum);
	  }
   }

   return 0;
}

void FreeBufferFromQueue(int q)
{
	int	i;
	RTQ_NODE *n = MGenGetNode(q);

	for (i = 0; i < NFREEQ; i++) {
		if (Qsizes[i] == FARPKS(&n->rtqLen)) {
			MGenMoveTo(q, i+FREEQBASE);
			return;
		}
	}
}

void SetLPCData(LPCData *lpc)
{
	FARPOKL(&(lpc->version), 1);
	FARPOKL(&(lpc->sizeOfArgs), 0);
	FARPOKL(&(lpc->service), 0);
}

int bind(SOCKET s, const struct sockaddr *name, int namelen)
{
	RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
	LPCData  *p;
	LPCReturn *r;
	BindArgs  *bargs;
	int       retVal;

	_farsetsel(flat_selector);
	SocketError = 0;
	p = (LPCData *) FARPKL(&n->rtqDatum);
	SetLPCData(p);
	FARPOKL(&p->service, LPC_SOCKBIND);
	bargs = (BindArgs *) p->Data;
	FARPOKL(&bargs->s, s);
	FARPOKL(&bargs->namelen, namelen);
	fmemcpyto(bargs->name, name, namelen);
	MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
	PostWindowsMessage();

	while ((n = MGenGetNode(REC_QUEUE)) == 0)
		Yield();

	r = (LPCReturn *) FARPKL(&n->rtqDatum);

	if (FARPKS(&r->error) != LPC_NOERROR) {
		return -1;
	}

	retVal = FARPKL(r->Data);

	// get ready for next call
	MGenMoveTo(REC_QUEUE, IDLE_QUEUE);

	return retVal;
}

int closesocket(SOCKET s)
{
	RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
	LPCData  *p;
	LPCReturn *r;
	int       retVal;

	_farsetsel(flat_selector);
	SocketError = 0;
	p = (LPCData *) FARPKL(&n->rtqDatum);
	SetLPCData(p);
	FARPOKL(&p->service, LPC_SOCKCLOSE);
	FARPOKL(p->Data, s);

	MGenMoveTo(IDLE_QUEUE, SEND_QUEUE);
	PostWindowsMessage();

	while ((n = MGenGetNode(REC_QUEUE)) == 0)
		Yield();

	r = (LPCReturn *) FARPKL(&n->rtqDatum);

	if (FARPKS(&r->error) != LPC_NOERROR) {
		return -1;
	}

	retVal = FARPKL(r->Data);

	// get ready for next call
	MGenMoveTo(REC_QUEUE, IDLE_QUEUE);

	return retVal;
}

void ZapHostEnt()
{
	// do nothing
}

void ReconstructHostEnt(struct hostent *s, void *flattened)
{
	struct hostent   *old = (struct hostent *) flattened;
	int i;
	char **ptr;

	s->h_name = HostEnt_hname;
	fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1);
	s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0;

	s->h_aliases = HostEnt_h_aliases;
	ptr = (char **) FARPKL(&old->h_aliases);
	for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) {
		s->h_aliases[i] = HostEnt_names[i];
		// fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1);
		s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0;
	}
	s->h_aliases[i] = 0;

	s->h_addrtype = FARPKS(&old->h_addrtype);
	s->h_length = FARPKS(&old->h_length);

	if (FARPKS(&old->h_length) != sizeof(struct in_addr)) {
		printf("Error!\n");
		exit(0);
	}

	s->h_addr_list = (char **) HostEnt_addr_list;
	ptr = (char **) FARPKL(&old->h_addr_list);
	for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) {
		s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]);
		fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length);
	}
	s->h_addr_list[i] = 0;
}

int getsockname(SOCKET s, struct sockaddr *name, int *namelen)
{
   RTQ_NODE *n = MGenGetNode(IDLE_QUEUE);
   LPCData  *p;
   LPCReturn *r;
   GetSockNameRet  *ret;
   int       retVal;

   SocketError = 0;
   _farsetsel(flat_selector);
   p = (LPCData *) FARPKL(&n->rtqDatum);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -