📄 mplpc.c
字号:
/*
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 + -