IPXLIB.C ComentadaProfessor Adjunto do Departamento de Engenharia Informática do ISEP /*********** Funções IPX da shell Novell *************/ /* OS COMENTARIOS AINDA NAO ESTAO COMPLETOS */ /*****************************************************/ /* Estas funções foram implementadas no DEI em 1994/95, para suporte das aulas práticas de Sistemas de Computação II, onde eram desenvolvidas pequenas aplicações em Turbo C 2.0, para as utilizar basta incluir o ficheiro IPXLIB.C: #include "path\ipxlib.c" */ #if !defined(__IPX_DEF_) /* verificar se este ficheiro ja foi incluido */ #define __IPX_DEF_ #include <dos.h> #include <mem.h> /* tipos de socket */ #define TEMP_SOCKET_TYPE 0x00 /* socket temporario (válido até a aplicação terminar) */ #define PERM_SOCKET_TYPE 0xFF /* socket permanente (usado para implementar programas TSR) */ #define DYNAMIC_SOCKET 0x0000 /* numero de porta para atribuição dinâmica */ typedef unsigned char BYTE; /* definição de alguns identificadores de tipo */ typedef unsigned int WORD; typedef unsigned long LONG; typedef struct { BYTE net[4], node[6], socket[2];} IPXaddress; /* endereço IPX completo */ typedef struct /* a estrutura do cabeçalho de um datagrama IPX */ { WORD checkSum, length; /* o checksum não é actualmente usado */ BYTE tranportControl, type; /* */ IPXaddress destination, source; /* endereços de destino e origem */ } IPXheader; #define IPXpacket IPXheader /* para manter as aplicações antigas que usavam este identificador*/ typedef struct { WORD address[2], size; } ECBfragment; typedef struct { WORD link[2]; BYTE far *ESRaddress; BYTE inUseFlag, compCode; BYTE ECBsocket[2]; BYTE IPXworkSpace[4], driverWorkSpace[12], immediateAddress[6]; WORD fragCount; ECBfragment fragDesc[2]; } ECB; BYTE IPXinit(BYTE exitFlag) /* verificar se o driver IPX está instalado */ { union REGS out,in; in.x.ax=0x7A00; int86(0x2F,&in,&out); if(exitFlag && !out.h.al) {puts("\nIPX not Installed -> exiting...");exit(1);} return(out.h.al); } BYTE IPXopenSocket(void *socket, BYTE type) /* abrir um socket */ { /* o socket (número de porta) é passado como apontador */ BYTE *sock=(BYTE *)socket; /* o que permite que esta função defina uma porta livre */ union REGS out,in; /* nesse caso a variável usada como parâmetro deve conter */ in.x.bx=0; /* o valor DYNAMIC_SOCKET e a função encarrega-se de */ in.h.dl=sock[1]; /* encontrar uma porta livre. O número dessa porta é então */ in.h.dh=sock[0]; /* colocado na variavel */ in.h.al=type; /* o parâmetro type deverá ter o valor TEMP_SOCKET_TYPE */ int86(0x7A,&in,&out); /* ou PERM_SOCKET_TYPE */ sock[1]=out.h.dl; sock[0]=out.h.dh; return(out.h.al); } void IPXcloseSocket(WORD socket) { BYTE *sock=(BYTE *)&socket; union REGS out,in; in.x.bx=1; in.h.dl=sock[1]; in.h.dh=sock[0]; int86(0x7A,&in,&out); } BYTE IPXgetLocalTarget(IPXaddress *fullAddress, BYTE *imedAddress, WORD *transpTime) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=2; in.x.si=(WORD)fullAddress; in.x.di=(WORD)imedAddress; int86x(0x7A,&in,&out,&seg); *transpTime=out.x.cx; return(out.h.al); } void IPXsendPacket(ECB *ecb) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=3; in.x.si=(WORD)ecb; int86x(0x7A,&in,&out,&seg); } #define IPXdoSendPacket(ecb) IPXsendPacket(&ecb);while(ecb.inUseFlag) IPXrelinquishControl() void IPXlistenForPacket(ECB *ecb) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=4; in.x.si=(WORD)ecb; int86x(0x7A,&in,&out,&seg); } void IPXsheduleIPXevent(WORD timeUnits, ECB *ecb) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=5; in.x.si=(WORD)ecb; in.x.ax=timeUnits; int86x(0x7A,&in,&out,&seg); } BYTE IPXcancelEvent(ECB *ecb) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=6; in.x.si=(WORD)ecb; int86x(0x7A,&in,&out,&seg); return(out.h.al); } BYTE IPXsheduleSpecialEvent(WORD timeUnits, ECB *ecb) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=7; in.x.si=(WORD)ecb; in.x.ax=timeUnits; int86x(0x7A,&in,&out,&seg); return(out.h.al); } WORD IPXgetIntervalMarker(void) { union REGS in,out; in.x.bx=8; int86(0x7A,&in,&out); return(out.x.ax); } void IPXgetInternetworkAddress(BYTE *address) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=9; in.x.si=(WORD)address; int86x(0x7A,&in,&out,&seg); } void IPXrelinquishControl(void) { union REGS in,out; in.x.bx=10; int86(0x7A,&in,&out); } void IPXdisconnectFromTarget(BYTE *address) { union REGS out,in; struct SREGS seg; segread(&seg); seg.es=seg.ds; in.x.bx=11; in.x.si=(WORD)address; int86x(0x7A,&in,&out,&seg); } void IPXgetProcAddress(void (*proc)(),void *address) { WORD *addr=(WORD *)address; struct SREGS seg; segread(&seg); seg.es=seg.ds; addr[0]=(WORD)proc; addr[1]=(WORD)seg.cs; } void IPXgetDataAddress(void *data,void *address) { WORD *addr=(WORD *)address; struct SREGS seg; segread(&seg); seg.es=seg.ds; addr[0]=(WORD)data; addr[1]=(WORD)seg.ds; } /******************** Funções Auxiliares ***********************/ void swapWORD(WORD *data) { BYTE aux, *bp=(BYTE *)data; aux=bp[0];bp[0]=bp[1];bp[1]=aux; } WORD getSwappedWORD(WORD data) { BYTE *arg=(BYTE *)&data, res[2]; res[0]=arg[1];res[1]=arg[0]; return(*((WORD *)res)); } #define IPXgetDataSize(ipxh) (getSwappedWORD(ipxh.length)-30) /******************* ECB & IPX header setup ********************/ void IPXsetUpSend(ECB *ecb, IPXheader *ipx, BYTE *toNet, BYTE *toNode, WORD toSocket, WORD socket, void *buffer, WORD buffSize, void (*esr)()) { WORD ttime; BYTE *sock=(BYTE *)&socket; BYTE *toSock=(BYTE *)&toSocket; if(esr) IPXgetProcAddress(esr,&ecb->ESRaddress); else memset(&ecb->ESRaddress,0,4); ipx->destination.socket[0]=toSock[1]; ipx->destination.socket[1]=toSock[0]; ecb->inUseFlag=0; ecb->ECBsocket[0]=sock[1]; ecb->ECBsocket[1]=sock[0]; ecb->fragCount=2; IPXgetDataAddress(ipx,ecb->fragDesc[0].address); ecb->fragDesc[0].size=30; IPXgetDataAddress(buffer,ecb->fragDesc[1].address); ecb->fragDesc[1].size=buffSize; ipx->type=0; movmem(toNet,ipx->destination.net,4); movmem(toNode,ipx->destination.node,6); IPXgetLocalTarget(&ipx->destination,ecb->immediateAddress, &ttime); } /*** Prepara a emissão em broadcast na rede corrente [00:00:00:00] ***/ void IPXsetUpSendBroadcast(ECB *ecb, IPXheader *ipx, WORD toSocket, WORD socket, void *buffer, WORD buffSize, void (*esr)()) { BYTE *sock=(BYTE *)&socket; BYTE *toSock=(BYTE *)&toSocket; if(esr) IPXgetProcAddress(esr,&ecb->ESRaddress); else memset(&ecb->ESRaddress,0,4); ecb->ECBsocket[0]=sock[1]; ecb->ECBsocket[1]=sock[0]; ipx->destination.socket[0]=toSock[1]; ipx->destination.socket[1]=toSock[0]; ecb->inUseFlag=0; ecb->fragCount=2; IPXgetDataAddress(ipx,ecb->fragDesc[0].address); ecb->fragDesc[0].size=30; IPXgetDataAddress(buffer,ecb->fragDesc[1].address); ecb->fragDesc[1].size=buffSize; ipx->type=0; memset(ecb->immediateAddress,0xFF,6); memset(ipx->destination.net,0,4); memset(ipx->destination.node,0xFF,6); } void IPXsetUpReceive(ECB *ecb, IPXheader *ipx, WORD socket, void *buffer, WORD buffSize, void (*esr)()) { BYTE *sock=(BYTE *)&socket; if(esr) IPXgetProcAddress(esr,&ecb->ESRaddress); else memset(&ecb->ESRaddress,0,4); ecb->inUseFlag=0; ecb->ECBsocket[0]=sock[1]; ecb->ECBsocket[1]=sock[0]; ecb->fragCount=2; IPXgetDataAddress(ipx,(WORD *)ecb->fragDesc[0].address); ecb->fragDesc[0].size=30; IPXgetDataAddress(buffer,(WORD *)ecb->fragDesc[1].address); ecb->fragDesc[1].size=buffSize; } #endif |