예제 #1
0
TEST_F(RingBuf, RingBufRW2_1)
{
    RingBuf_t   ringbuf;
    uint8_t     wbuf[3];
    uint8_t     rbuf[3];
    size_t      sz;

    for (int i = 0; i < 3; i++) {
        RingBufAlloc(&ringbuf, 3);
        ringbuf.wpos = i;        //ずらす
        ringbuf.rpos = (ringbuf.wpos + 1) % 3;
        memset(ringbuf.buf, 0xdd, 3);
        ringbuf.empty = false;

        //1回ずつ書いて、1回ずつ読む

        //書ける
        wbuf[0] = 0x12;
        sz = 1;
        RingBufWrite(&ringbuf, wbuf, &sz);
        ASSERT_EQ(1UL, sz);

        //書けない
        wbuf[0] = 0x78;
        sz = 1;
        RingBufWrite(&ringbuf, wbuf, &sz);
        ASSERT_EQ(0UL, sz);

        //読める
        sz = 1;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(1UL, sz);
        ASSERT_EQ(0xdd, rbuf[0]);

        //読める
        sz = 1;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(1UL, sz);
        ASSERT_EQ(0xdd, rbuf[0]);

        //読める
        sz = 1;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(1UL, sz);
        ASSERT_EQ(0x12, rbuf[0]);

        //読めない
        sz = 1;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(0UL, sz);

        RingBufFree(&ringbuf);
    }
}
예제 #2
0
TEST_F(RingBuf, RingBufRW1_2)
{
    RingBuf_t   ringbuf;
    uint8_t     wbuf[3];
    uint8_t     rbuf[5];
    size_t      sz;

    for (int i = 0; i < 3; i++) {
        RingBufAlloc(&ringbuf, 3);
        ringbuf.rpos = ringbuf.wpos = i;        //ずらす

        //2回で書いて、1回で読む

        //書ける
        wbuf[0] = 0x12;
        wbuf[1] = 0x34;
        sz = 2;
        RingBufWrite(&ringbuf, wbuf, &sz);
        ASSERT_EQ(2UL, sz);

        //書ける
        wbuf[0] = 0x56;
        wbuf[1] = 0x78;
        sz = 2;
        RingBufWrite(&ringbuf, wbuf, &sz);
        ASSERT_EQ(1UL, sz);

        //書けない
        wbuf[0] = 0x78;
        sz = 1;
        RingBufWrite(&ringbuf, wbuf, &sz);
        ASSERT_EQ(0UL, sz);

        //読める
        sz = 5;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(3UL, sz);
        ASSERT_EQ(0x12, rbuf[0]);
        ASSERT_EQ(0x34, rbuf[1]);
        ASSERT_EQ(0x56, rbuf[2]);

        //読めない
        sz = 1;
        RingBufRead(&ringbuf, rbuf, &sz);
        ASSERT_EQ(0UL, sz);

        RingBufFree(&ringbuf);
    }
}
예제 #3
0
TEST_F(RingBuf2, RingBufWrite5)
{
    //空きがない
    //      +---+
    //     2|   |
    //   RW1|   |
    //     0|   |
    //      +---+
    RingBuf2::mBuf.rpos = 1;
    RingBuf2::mBuf.wpos = 1;
    RingBuf2::mBuf.empty = false;

    const uint8_t DATA[] = { 6, 7 };
    size_t sz = sizeof(DATA);

    RingBufWrite(&RingBuf2::mBuf, DATA, &sz);

    ASSERT_EQ(1, RingBuf2::mBuf.rpos);
    ASSERT_EQ(1, RingBuf2::mBuf.wpos);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[0]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[1]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[2]);
    ASSERT_FALSE(RingBuf2::mBuf.empty);
    ASSERT_EQ(0UL, sz);
}
//*****************************************************************************
//
// The interrupt-context handler for touch screen events from the touch screen
// driver.  This function merely bundles up the event parameters and posts
// them to a message queue.  In the context of the main loop, they will be
// read from the queue and handled using TSMainHandler().
//
//*****************************************************************************
int32_t
TSHandler(uint32_t ui32Message, int32_t i32X, int32_t i32Y)
{
    tScribbleMessage sMsg;

    //
    // Build the message that we will write to the queue.
    //
    sMsg.ui32Msg = ui32Message;
    sMsg.i32X = i32X;
    sMsg.i32Y = i32Y;

    //
    // Make sure the queue isn't full. If it is, we just ignore this message.
    //
    if(!RingBufFull(&g_sMsgQueue))
    {
        RingBufWrite(&g_sMsgQueue, (uint8_t *)&sMsg, sizeof(tScribbleMessage));
    }

    //
    // Tell the touch handler that everything is fine.
    //
    return(1);
}
예제 #5
0
TEST_F(RingBuf2, RingBufWrite7)
{
    //空き上がは1つで、下に1つ
    //      +---+
    //    W2|   |
    //    R1|   |
    //     0|   |
    //      +---+
    RingBuf2::mBuf.rpos = 1;
    RingBuf2::mBuf.wpos = 2;
    RingBuf2::mBuf.empty = false;

    //下エリアの空きが足りない
    const uint8_t DATA[] = { 5, 6, 7 };
    size_t sz = sizeof(DATA);

    RingBufWrite(&RingBuf2::mBuf, DATA, &sz);

    ASSERT_EQ(1, RingBuf2::mBuf.rpos);
    ASSERT_EQ(1, RingBuf2::mBuf.wpos);
    ASSERT_EQ(6, RingBuf2::mBuf.buf[0]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[1]);
    ASSERT_EQ(5, RingBuf2::mBuf.buf[2]);
    ASSERT_FALSE(RingBuf2::mBuf.empty);
    ASSERT_EQ(2UL, sz);
}
예제 #6
0
TEST_F(RingBuf2, RingBufWrite4)
{
    //空き上がは2つで、下に空きがない
    //      +---+
    //     2|   |
    //    W1|   |
    //    R0|   |
    //      +---+
    RingBuf2::mBuf.rpos = 0;
    RingBuf2::mBuf.wpos = 1;
    RingBuf2::mBuf.empty = false;

    const uint8_t DATA[] = { 4, 5 };
    size_t sz = sizeof(DATA);

    RingBufWrite(&RingBuf2::mBuf, DATA, &sz);

    ASSERT_EQ(0, RingBuf2::mBuf.rpos);
    ASSERT_EQ(0, RingBuf2::mBuf.wpos);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[0]);
    ASSERT_EQ(4, RingBuf2::mBuf.buf[1]);
    ASSERT_EQ(5, RingBuf2::mBuf.buf[2]);
    ASSERT_FALSE(RingBuf2::mBuf.empty);
    ASSERT_EQ(2UL, sz);
}
예제 #7
0
파일: getkey.cpp 프로젝트: ftnapps/pkg-sbbs
void sbbs_t::ungetkey(char ch)
{
#if 0	/* this way breaks ansi_getxy() */
	RingBufWrite(&inbuf,(uchar*)&ch,sizeof(uchar));
#else
	keybuf[keybuftop++]=ch;   
	if(keybuftop==KEY_BUFSIZE)   
		keybuftop=0; 
#endif
}
예제 #8
0
//*****************************************************************************
//
// Puts a UART message on the line to the RNP.
//
// \param pui8Msg pointer to the data that will be put on the bus. Must be
// already formated with SOF, length and checksum by the caller.
//
// \param ui16Length the number of bytes that are to be put out the UART.
//
// This function copies the message to the ring buffer and then starts a
// transmission process. Application must assure that transmitter is not busy.
//
//*****************************************************************************
void
RemoTIUARTPutMsg(uint8_t* pui8Msg, uint_fast16_t ui16Length)
{
    bool bIntState;

    //
    // Capture the current state of the master interrupt enable.
    //
    bIntState = IntMasterDisable();

    //
    // Store the message in the ringbuffer for transmission.
    //
    RingBufWrite(&g_rbRemoTITxRingBuf, pui8Msg, ui16Length);

    //
    // If the UART transmit is idle prime the transmitter with first byte and.
    // enable transmit interrupts.
    //
    if(!g_bTxBusy)
    {
        //
        // Enable the TX interrupts and start the transmission of the first
        // byte.
        //
        UARTIntEnable(g_ui32UARTBase, UART_INT_TX);
        UARTCharPutNonBlocking(g_ui32UARTBase,
                               RingBufReadOne(&g_rbRemoTITxRingBuf));

        //
        // Set the Transmit busy flag.
        //
        g_bTxBusy = true;
    }

    //
    // Restore the master interrupt enable to its previous state.
    //
    if(!bIntState)
    {
        IntMasterEnable();
    }

    //
    // Finished.
    //
}
예제 #9
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt29::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
	vm_t* vm = find_vm(hVM);

	if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
		return(FALSE); // Tells VMM that interrupt was not handled
	}

    if(!RingBufFree(&vm->out)) {
        DBTRACEx(0,"!Int29 OUTPUT BUFFER OVERFLOW, hVM", hVM);
        vm->overrun=true;
        return(FALSE);
    }
	DBTRACEx(1,"Int29 OUTPUT", _clientAL);

    BYTE ch=_clientAL;
    RingBufWrite(&vm->out,&ch,1);
    vm->overrun=false;

	return(FALSE);
}
예제 #10
0
TEST_F(RingBuf2, RingBufWrite1)
{
    //最小
    //      +---+
    //     2|   |
    //     1|   |
    //   RW0|   |
    //      +---+
    const uint8_t DATA[] = { 1, };
    size_t sz = sizeof(DATA);

    RingBufWrite(&RingBuf2::mBuf, DATA, &sz);

    ASSERT_EQ(0, RingBuf2::mBuf.rpos);
    ASSERT_EQ(1, RingBuf2::mBuf.wpos);
    ASSERT_EQ(1, RingBuf2::mBuf.buf[0]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[1]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[2]);
    ASSERT_FALSE(RingBuf2::mBuf.empty);
    ASSERT_EQ(1UL, sz);
}
예제 #11
0
TEST_F(RingBuf2, RingBufWrite0)
{
    //最小-1
    //      +---+
    //     2|   |
    //     1|   |
    //   RW0|   |
    //      +---+
    const uint8_t DATA[] = { 1, };
    size_t sz = 0;

    RingBufWrite(&RingBuf2::mBuf, DATA, &sz);

    ASSERT_EQ(0, RingBuf2::mBuf.rpos);
    ASSERT_EQ(0, RingBuf2::mBuf.wpos);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[0]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[1]);
    ASSERT_EQ(0xcc, RingBuf2::mBuf.buf[2]);
    ASSERT_TRUE(RingBuf2::mBuf.empty);
    ASSERT_EQ(0UL, sz);
}
예제 #12
0
void _cdecl input_thread(void* arg)
{
	char	buf[LINEAR_RX_BUFLEN];
	int		count;

	lprintf(LOG_DEBUG,"input_thread: started");
	while(1) {
		count=RingBufFree(&rdbuf);
		if(count<1) {
			lprintf(LOG_WARNING,"input_thread: input buffer full!");
			YIELD();
			continue;
		}
		if(count>sizeof(buf))
			count=sizeof(buf);
		if(!ReadFile(rdslot,buf,count,&count,NULL)) {
			if(GetLastError()==ERROR_HANDLE_EOF) {	/* closed by VDD_CLOSE */
				lprintf(LOG_INFO,"input_thread: ReadFile returned EOF");
				break;
			}
			lprintf(LOG_ERR,"!input_thread: ReadFile Error %d (size=%d)"
				,GetLastError(),count);
			continue;
		}
		if(count==0) {
			lprintf(LOG_ERR,"!input_thread: ReadFile read 0");
			continue;
		}
		RingBufWrite(&rdbuf,buf,count);

		if(virtualize_uart) {
			/* Set the "Data ready" bit in the LSR */
			uart_lsr_reg |= UART_LSR_DATA_READY;

			assert_interrupt(UART_IER_RX_DATA); /* assert rx data interrupt */
		}
	}
	lprintf(LOG_DEBUG,"input_thread: terminated");
}
예제 #13
0
파일: sexyz.c 프로젝트: ftnapps/pkg-sbbs
int send_byte(void* unused, uchar ch, unsigned timeout)
{
	uchar		buf[2] = { TELNET_IAC, TELNET_IAC };
	unsigned	len=1;
	DWORD		result;

	if(telnet && ch==TELNET_IAC)	/* escape IAC char */
		len=2;
	else
		buf[0]=ch;

	if(RingBufFree(&outbuf)<len) {
		fprintf(statfp,"FLOW");
		flows++;
		result=WaitForEvent(outbuf_empty,timeout*1000);
		fprintf(statfp,"\b\b\b\b    \b\b\b\b");
		if(result!=WAIT_OBJECT_0) {
			fprintf(statfp
				,"\n!TIMEOUT (%d) waiting for output buffer to flush (%u seconds, %u bytes)\n"
				,result, timeout, RingBufFull(&outbuf));
			newline=TRUE;
			if(RingBufFree(&outbuf)<len)
				return(-1);
		}
	}

	RingBufWrite(&outbuf,buf,len);
#if !defined(RINGBUF_EVENT)
	ResetEvent(outbuf_empty);
#endif

#if 0
	if(debug_tx)
		lprintf(LOG_DEBUG,"TX: %s",chr(ch));
#endif
	return(0);
}
예제 #14
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt10::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
	BYTE 	ch;
    DWORD   avail;
	vm_t*	vm = find_vm(hVM);

	if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
		return(FALSE); // Tells VMM that interrupt was not handled
	}

	avail=RingBufFree(&vm->out);

 	switch(_clientAH) {
		case 0x02: // Set Cursor Position
			DBTRACE(1,"Int10 func 2 - Set cursor position");
			break;
    	case 0x09:	// Write char and attr at cursor
			DBTRACE(1,"Int10 func 9 - Write char and attr at curosr");
        case 0x10:	// Write char at cursor
#if 0
			DBTRACE(1,"Int10 func 9 - Write char at curosr");			
            if(!avail) {
                DBTRACEx(0,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
                vm->overrun=true;
				break;
            }
            ch=_clientAL;
            RingBufWrite(&vm->out,&ch,1);
            vm->overrun=false;
			
#endif
			break;
	}

    return(FALSE);
}
예제 #15
0
void sbbs_t::telnet_gate(char* destaddr, ulong mode, char* client_user_name, char* server_user_name, char* term_type)
{
	char*	p;
	uchar	buf[512];
	int		i;
	int		rd;
	uint	attempts;
	ulong	l;
	bool	gotline;
	ushort	port;
	ulong	ip_addr;
	ulong	save_console;
	SOCKET	remote_socket;
	SOCKADDR_IN	addr;

	if(mode&TG_RLOGIN)
		port=513;
	else
		port=IPPORT_TELNET;

	p=strchr(destaddr,':');
	if(p!=NULL) {
		*p=0;
		port=atoi(p+1);
	}

	ip_addr=resolve_ip(destaddr);
	if(ip_addr==INADDR_NONE) {
		lprintf(LOG_NOTICE,"!TELGATE Failed to resolve address: %s",destaddr);
		bprintf("!Failed to resolve address: %s\r\n",destaddr);
		return;
	}

    if((remote_socket = open_socket(SOCK_STREAM, client.protocol)) == INVALID_SOCKET) {
		errormsg(WHERE,ERR_OPEN,"socket",0);
		return;
	}

	memset(&addr,0,sizeof(addr));
	addr.sin_addr.s_addr = htonl(startup->telnet_interface);
	addr.sin_family = AF_INET;

	if((i=bind(remote_socket, (struct sockaddr *) &addr, sizeof (addr)))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) binding to socket %d",i, ERROR_VALUE, remote_socket);
		bprintf("!ERROR %d (%d) binding to socket\r\n",i, ERROR_VALUE);
		close_socket(remote_socket);
		return;
	}

	memset(&addr,0,sizeof(addr));
	addr.sin_addr.s_addr = ip_addr;
	addr.sin_family = AF_INET;
	addr.sin_port   = htons(port);

	if((i=connect(remote_socket, (struct sockaddr *)&addr, sizeof(addr)))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) connecting to server: %s"
			,i,ERROR_VALUE, destaddr);
		bprintf("!ERROR %d (%d) connecting to server: %s\r\n"
			,i,ERROR_VALUE, destaddr);
		close_socket(remote_socket);
		return;
	}

	l=1;

	if((i = ioctlsocket(remote_socket, FIONBIO, &l))!=0) {
		lprintf(LOG_NOTICE,"!TELGATE ERROR %d (%d) disabling socket blocking"
			,i, ERROR_VALUE);
		close_socket(remote_socket);
		return;
	}

	lprintf(LOG_INFO,"Node %d %s gate to %s port %u on socket %d"
		,cfg.node_num
		,mode&TG_RLOGIN ? "RLogin" : "Telnet"
		,destaddr,port,remote_socket);

	if(!(mode&TG_CTRLKEYS))
		console|=CON_RAW_IN;

	if(mode&TG_RLOGIN) {
		p=(char*)buf;
		*(p++)=0;
		p+=sprintf(p,"%s",client_user_name==NULL ? useron.alias : client_user_name);
		p++;	// Add NULL
		p+=sprintf(p,"%s",server_user_name==NULL ? useron.name : server_user_name);
		p++;	// Add NULL
		if(term_type!=NULL)
			p+=sprintf(p,"%s",term_type);
		else
			p+=sprintf(p,"%s/%u",terminal, cur_rate);
		p++;	// Add NULL
		l=p-(char*)buf;
		sendsocket(remote_socket,(char*)buf,l);
		mode|=TG_NOLF;	/* Send LF (to remote host) when Telnet client sends CRLF (when not in binary mode) */
	}

	/* This is required for gating to Unix telnetd */
	if(mode&TG_NOTERMTYPE)
		request_telnet_opt(TELNET_DONT,TELNET_TERM_TYPE, 3000);	// Re-negotiation of terminal type

	/* Text/NVT mode by default */
	request_telnet_opt(TELNET_DONT,TELNET_BINARY_TX, 3000);

	if(!(telnet_mode&TELNET_MODE_OFF) && (mode&TG_PASSTHRU))
		telnet_mode|=TELNET_MODE_GATE;	// Pass-through telnet commands

	while(online) {
		if(!(mode&TG_NOCHKTIME))
			gettimeleft();
		rd=RingBufRead(&inbuf,buf,sizeof(buf));
		if(rd) {
#if 0
			if(memchr(buf,TELNET_IAC,rd)) {
				char dump[2048];
				dump[0];
				p=dump;
				for(int i=0;i<rd;i++)
					p+=sprintf(p,"%u ",buf[i]);
				lprintf(LOG_DEBUG,"Node %d Telnet cmd from client: %s", cfg.node_num, dump);
			}
#endif
			if(telnet_remote_option[TELNET_BINARY_TX]!=TELNET_WILL) {
				if(*buf==0x1d) { // ^]
					save_console=console;
					console&=~CON_RAW_IN;	// Allow Ctrl-U/Ctrl-P
					CRLF;
					while(online) {
						SYNC;
						mnemonics("\1n\r\n\1h\1bTelnet Gate: \1y~D\1wisconnect, "
							"\1y~E\1wcho toggle, \1y~L\1wist Users, \1y~P\1wrivate message, "
							"\1y~Q\1wuit: ");
						switch(getkeys("DELPQ",0)) {
							case 'D':
								closesocket(remote_socket);
								break;
							case 'E':
								mode^=TG_ECHO;
								bprintf(text[EchoIsNow]
									,mode&TG_ECHO
									? text[ON]:text[OFF]);
								continue;
							case 'L':
								whos_online(true);
								continue;
							case 'P':
								nodemsg();
								continue;
						}
						break;
					}
					attr(LIGHTGRAY);
					console=save_console;
				}
				else if(*buf<' ' && (mode&TG_CTRLKEYS))
					handle_ctrlkey(*buf, K_NONE);
				gotline=false;
				if((mode&TG_LINEMODE) && buf[0]!='\r') {
					ungetkey(buf[0]);
					l=K_CHAT;
					if(!(mode&TG_ECHO))
						l|=K_NOECHO;
					rd=getstr((char*)buf,sizeof(buf)-1,l);
					if(!rd)
						continue;
					strcat((char*)buf,crlf);
					rd+=2;
					gotline=true;
				}
				if((mode&TG_CRLF) && buf[rd-1]=='\r')
					buf[rd++]='\n';
				else if((mode&TG_NOLF) && buf[rd-1]=='\n')
					rd--;
				if(!gotline && (mode&TG_ECHO) && rd) {
					RingBufWrite(&outbuf,buf,rd);
				}
			} /* Not Telnet Binary mode */
			if(rd > 0) {
				for(attempts=0;attempts<60 && online; attempts++) /* added retry loop here, Jan-20-2003 */
				{
					if((i=sendsocket(remote_socket,(char*)buf,rd))>=0)
						break;
					if(ERROR_VALUE!=EWOULDBLOCK)
						break;
					mswait(500);
				} 
				if(i<0) {
					lprintf(LOG_NOTICE,"!TELGATE ERROR %d sending on socket %d",ERROR_VALUE,remote_socket);
					break;
				}
			}
		}
		rd=recv(remote_socket,(char*)buf,sizeof(buf),0);
		if(rd<0) {
			if(ERROR_VALUE==EWOULDBLOCK) {
				if(mode&TG_NODESYNC) {
					SYNC;
				} else {
					// Check if the node has been interrupted
					getnodedat(cfg.node_num,&thisnode,0);
					if(thisnode.misc&NODE_INTR)
						break;
				}
				YIELD();
				continue;
			}
			lprintf(LOG_NOTICE,"!TELGATE ERROR %d receiving on socket %d",ERROR_VALUE,remote_socket);
			break;
		}
		if(!rd) {
			lprintf(LOG_INFO,"Node %d Telnet gate disconnected",cfg.node_num);
			break;
		}
#if 0
		if(memchr(buf,TELNET_IAC,rd)) {
			char dump[2048];
			dump[0];
			p=dump;
			for(int i=0;i<rd;i++)
				p+=sprintf(p,"%u ",buf[i]);
			lprintf(LOG_DEBUG,"Node %d Telnet cmd from server: %s", cfg.node_num, dump);
		}
#endif
		RingBufWrite(&outbuf,buf,rd);
	}
	console&=~CON_RAW_IN;
	telnet_mode&=~TELNET_MODE_GATE;

	/* Disable Telnet Terminal Echo */
	request_telnet_opt(TELNET_WILL,TELNET_ECHO);

	close_socket(remote_socket);

	lprintf(LOG_INFO,"Node %d Telnet gate to %s finished",cfg.node_num,destaddr);
}
예제 #16
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt21::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
	BYTE	ch;
	BYTE*	buffer;
	WORD	buflen;
	vm_t*	vm = find_vm(hVM);

	if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
#if 0
		if(vm && !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
			DBTRACEx(0,"Int21 on unsupported VM", hVM);
		}
#endif
		return(FALSE); // Tells VMM that interrupt was not handled
	}
	DBTRACEx(1,"Int21 function", _clientAH);

	DWORD avail = RingBufFree(&vm->out);

    switch(_clientAH) {
    	case 0x01:
            DBTRACE(0,"!Int21 Char input WITH echo");
            break;
        case 0x06:	// Direct console I/O
			DBTRACEx(0,"DOS DIRECT CONSOLE IO, DL", _clientDL);
			if(_clientDL==0xff)  {
				avail=RingBufFull(&vm->in);
				if(avail) {
					DBTRACEd(0,"avail",avail);
		            RingBufRead(&vm->in, &ch, 1);
					_clientFlags&=~(1<<6);	// clear zero flag
					_clientAX=ch;
					return(TRUE);
				}
				break;
			}
			// fall-through
    	case 0x02:	// Character output
			DBTRACEx(1,"Int21 function", _clientAH);
            if(!avail) {
                DBTRACEx(0,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
                vm->overrun=true;
				break;
            }
            ch=_clientDL;
            RingBufWrite(&vm->out,&ch,1);
            vm->overrun=false;
			break;
		case 0x09:	// Display string
			DBTRACE(0,"!Int21 func 09 - DISPLAY STRING");
			break;
		case 0x0A:	// Buffered keyboard input
			DBTRACE(0,"Int21 Func 0A - Buffered Keyboard Input");
			/* Need to get a string from the user, echo, and copy to DS:DX */
			/* byte 0 = max length, byte 1 = actual read (minus CR) */
			break;
        case 0x40:	// Write file or device
			if(_clientBX!=1 && _clientBX!=2) {	// !stdout and !stderr
            	DBTRACEd(1,"!Int21 write to unsupported device", _clientBX);
				break;
            }
			DBTRACEdd(1,"Int21 write file", _clientBX, _clientCX);
            buffer = (BYTE*)MAPFLAT(CRS.Client_DS, CWRS.Client_DX);
            buflen = _clientCX;
            if(avail<buflen) {
                DBTRACEd(0,"!OUTPUT BUFFER OVERFLOW, avail", avail);
                vm->overrun=true;
                if(!avail)
					break;
                buflen=avail;
            }
            RingBufWrite(&vm->out,buffer,buflen);
            vm->overrun=false;
            break;
    }

	return(FALSE);	// Tells VMM that interrupt was not handled
}
예제 #17
0
BOOL SBBSExecInt14::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
	BYTE*	buffer;
	BYTE	ch;
	WORD	buflen;
    WORD	rd,wr;
    WORD	avail;
	vm_t*	vm = find_vm(hVM);

	if(vm==NULL || vm->mode!=SBBSEXEC_MODE_FOSSIL) {
		return(FALSE); // Tells VMM that interrupt was not handled
	}


	DBTRACEx(4,"Int14 func",_clientAH);

	switch(_clientAH) {
		case 0x00:	/* Initialize/Set baud rate */
        	DBTRACE(0,"Int14 init");
			_clientAX=PortStatus(vm);
			break;
		case 0x01: /* write char to com port */
        	if(RingBufFree(&vm->out)<2) {
            	DBTRACEx(1,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
            	vm->output_sem=Create_Semaphore(0);
                Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
                Destroy_Semaphore(vm->output_sem);
                vm->output_sem=NULL;
                if(!vm->online) {
                	DBTRACE(0,"!USER HUNG UP");
                	return(true);
                }
            }
			ch=_clientAL;
			RingBufWrite(&vm->out,&ch,1);
#if 0	/* Now done in SBBS.DLL/XTRN.CPP */
			if(ch==0xff) { /* escape TELNET IAC */
				RingBufWrite(&vm->out,&ch,1);
				DBTRACE(1,"Escaped IAC in output stream");
			}
#endif
			vm->overrun=false;
			_clientAX=PortStatus(vm);
			break;
		case 0x02: /* read char from com port */
			if(!RingBufFull(&vm->in)) {
            	DBTRACEx(0,"Waiting on input semaphore, hVM", hVM);
            	vm->input_sem=Create_Semaphore(0);
                Wait_Semaphore(vm->input_sem,BLOCK_THREAD_IDLE);
                Destroy_Semaphore(vm->input_sem);
                vm->input_sem=NULL;
#if 0
				_clientAH=0x80;	/* timed-out */
				return(TRUE);
#endif
			}
			RingBufRead(&vm->in,&ch,1);
			_clientAH=0;
			_clientAL=ch;
			break;
		case 0x03:	/* request status */
			_clientAX=PortStatus(vm);
			break;
		case 0x04:	/* initialize */
			DBTRACE(0,"Int14 func 4 init");
			_clientAX=0x1954;	/* magic number = success */
			_clientBH=5;		/* FOSSIL rev */
			_clientBL=0x1B;		/* maximum FOSSIL func supported */
			break;
        case 0x08:	// flush output buffer
            DBTRACE(0,"Int14 FLUSH OUTPUT BUFFER");
            vm->output_sem=Create_Semaphore(0);
            Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
            Destroy_Semaphore(vm->output_sem);
            vm->output_sem=NULL;
			break;
        case 0x09:	// purge output buffer
        	DBTRACE(0,"Int14 PURGE OUTPUT BUFFER");
        	RingBufReInit(&vm->out);
            break;
        case 0x0A:	// purge input buffer
        	DBTRACE(0,"Int14 PURGE INPUT BUFFER");
        	RingBufReInit(&vm->in);
            break;
		case 0x0B: /* write char to com port, no wait */
        	if(RingBufFree(&vm->out)<2) {
            	_clientAX=0; // char was not accepted
                break;
            }
			ch=_clientAL;
			RingBufWrite(&vm->out,&ch,1);
#if 0	/* Now done in SBBS.DLL/XTRN.CPP */
			if(ch==0xff) { /* escape TELNET IAC */
				RingBufWrite(&vm->out,&ch,1);
				DBTRACE(1,"Escaped IAC in output stream");
			}
#endif
			_clientAX=1; // char was accepted
			break;
        case 0x0C:	// non-destructive read-ahead
			if(!RingBufFull(&vm->in)) {
				_clientAX=0xffff;	// no char available
				break;
			}
			RingBufPeek(&vm->in,&ch,1);
			_clientAH=0;
			_clientAL=ch;
			break;
		case 0x13:	/* write to display */
			dprintf("%c",_clientAL);
			break;
        case 0x18:	/* read bock */
        	rd=_clientCX;
            avail=RingBufFull(&vm->in);
            if(rd>avail)
            	rd=avail;
            if(rd) {
	            buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
                rd = RingBufRead(&vm->in, buffer, rd);
            }
            _clientAX = rd;
            break;
        case 0x19:	/* write block */
			wr=_clientCX;
            avail=RingBufFree(&vm->out);
            if(wr>avail)
            	wr=avail;
            if(wr) {
	            buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
                wr = RingBufWrite(&vm->out, buffer, wr);
            }
            _clientAX = wr;
            break;
#if 1
        case 0x1B:	// driver info
        {
        	DBTRACE(1,"Int14 driver info");
            struct {
                WORD    info_size;
                BYTE	curr_fossil;
                BYTE	curr_rev;
                DWORD	id_string;
                WORD	inbuf_size;
                WORD	inbuf_free;
                WORD	outbuf_size;
                WORD	outbuf_free;
                BYTE	screen_width;
                BYTE	screen_height;
                BYTE	baud_rate;
            } info={ sizeof(info), 5, 1, 0
            		,RINGBUF_SIZE_IN-1, RingBufFree(&vm->in)
                    ,RINGBUF_SIZE_OUT-1, RingBufFree(&vm->out)
                    ,80,25
                    ,1 // 38400
                    };
//			Map_Lin_To_VM_Addr
			buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
            wr=sizeof(info);
            if(wr>_clientCX)
            	wr=_clientCX;
            memcpy(buffer, &info, wr);
        	_clientAX=wr;
            break;
		}
#endif
		default:
			DBTRACEx(0,"!UNHANDLED INTERRUPT 14h function",_clientAH);
			break;
	}
	return(TRUE);	// Tells VMM that interrupt was handled
}
예제 #18
0
파일: str.cpp 프로젝트: ftnapps/pkg-sbbs
bool sbbs_t::spy(uint i /* node_num */)
{
	char	ch;
	char	ansi_seq[32];
	int		ansi_len;
	int		in;

	if(!i || i>MAX_NODES) {
		bprintf("Invalid node number: %d\r\n",i);
		return(false);
	}
	if(i==cfg.node_num) {
		bprintf("Can't spy on yourself.\r\n");
		return(false);
	}
	if(spy_socket[i-1]!=INVALID_SOCKET) {
		bprintf("Node %d already being spied (%lx)\r\n",i,spy_socket[i-1]);
		return(false);
	}
	bprintf("*** Synchronet Remote Spy on Node %d: Ctrl-C to Abort ***"
		"\r\n\r\n",i);
	spy_socket[i-1]=client_socket;
	ansi_len=0;
	while(online 
		&& client_socket!=INVALID_SOCKET 
		&& spy_socket[i-1]!=INVALID_SOCKET 
		&& !msgabort()) {
		in=incom(1000);
		if(in==NOINP) {
			gettimeleft();
			continue;
		}
		ch=in;
		if(ch==ESC) {
			if(!ansi_len) {
				ansi_seq[ansi_len++]=ch;
				continue;
			}
			ansi_len=0;
		}
		if(ansi_len && ansi_len<(int)sizeof(ansi_seq)-2) {
			if(ansi_len==1) {
				if(ch=='[') {
					ansi_seq[ansi_len++]=ch;
					continue;
				}
				ansi_len=0;
			}
			if(ch=='R') { /* throw-away cursor position report */
				ansi_len=0;
				continue;
			}
			ansi_seq[ansi_len++]=ch;
			if(isalpha(ch)) {
				RingBufWrite(node_inbuf[i-1],(uchar*)ansi_seq,ansi_len);
				ansi_len=0;
			}
			continue;
		}
		if(ch<' ') {
			lncntr=0;						/* defeat pause */
			spy_socket[i-1]=INVALID_SOCKET;	/* disable spy output */
			ch=handle_ctrlkey(ch,K_NONE);
			spy_socket[i-1]=client_socket;	/* enable spy output */
			if(ch==0)
				continue;
		}
		if(node_inbuf[i-1]!=NULL) 
			RingBufWrite(node_inbuf[i-1],(uchar*)&ch,1);
	}
	spy_socket[i-1]=INVALID_SOCKET;
	return(true);
}
예제 #19
0
DWORD SBBSExec::OnW32DeviceIoControl(PIOCTLPARAMS pIOCTL)
{
	DWORD	rd;
	DWORD	wr;
	DWORD	avail;
	vm_t*	vm;

//	DBTRACEd(0,"SBBSEXEC ioctl"
		//,pIOCTL->dioc_IOCtlCode);

	switch(pIOCTL->dioc_IOCtlCode) {
		case DIOC_OPEN:
			DBTRACEd(0,"IOCTL: OPEN",Get_System_Time());
			break;

		case DIOC_CLOSEHANDLE:
			DBTRACEd(0,"IOCTL: CLOSE",Get_System_Time());
			break;

		case SBBSEXEC_IOCTL_START:
			DBTRACEd(0,"IOCTL: START",Get_System_Time());
			DBTRACEx(0,"Current Thread Handle",Get_Cur_Thread_Handle());
			if(start.event) {
				DBTRACE(0,"Exec already started!");
				return(SBBSEXEC_ERROR_INUSE);
			}
			if (pIOCTL->dioc_InBuf==NULL 
				|| pIOCTL->dioc_cbInBuf!=sizeof(start)) {
				return(SBBSEXEC_ERROR_INBUF);
			}
			start=*(sbbsexec_start_t*)pIOCTL->dioc_InBuf;
			break;

		case SBBSEXEC_IOCTL_COMPLETE:
			DBTRACEd(0,"IOCTL: COMPLETE",Get_System_Time());
			if(start.event || new_vm==NULL) {
				DBTRACE(0,"!VM never created");
				start.event=0;
				return(SBBSEXEC_ERROR_INUSE);
			}
			if(pIOCTL->dioc_OutBuf==NULL
				|| pIOCTL->dioc_cbOutBuf<sizeof(VMHANDLE)) {
				DBTRACE(0,"!Invalid OUTBUF");
				return(SBBSEXEC_ERROR_OUTBUF);
			}
			*(VMHANDLE*)pIOCTL->dioc_OutBuf=new_vm->handle;
			DBTRACEx(0,"CREATED VM HANDLE", new_vm->handle);
			new_vm=NULL;

			if(pIOCTL->dioc_bytesret!=NULL)
				*pIOCTL->dioc_bytesret = sizeof(VMHANDLE);
			break;
		case SBBSEXEC_IOCTL_READ:

			if (pIOCTL->dioc_InBuf==NULL
				|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
				DBTRACE(0,"!INVALID INBUF");
				return(SBBSEXEC_ERROR_INBUF);
			}

			if (pIOCTL->dioc_OutBuf==NULL || pIOCTL->dioc_cbOutBuf==0) {
				DBTRACE(0,"!INVALID OUTBUF");
				return(SBBSEXEC_ERROR_OUTBUF);
			}

			vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
			if(vm==NULL) {
				DBTRACE(0,"!NO VM LIST");
				return(SBBSEXEC_ERROR_INDATA);
			}

			rd = RingBufFull(&vm->out);

			if(rd>pIOCTL->dioc_cbOutBuf) {
				DBTRACEdd(0,"Reducing read size"
                	,rd, pIOCTL->dioc_cbOutBuf);
				rd=pIOCTL->dioc_cbOutBuf;
			}

			RingBufRead(&vm->out, (BYTE*)pIOCTL->dioc_OutBuf, rd);

			if(pIOCTL->dioc_bytesret!=NULL)
				*pIOCTL->dioc_bytesret = rd;

            if(vm->output_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->output_sem);

            if(rd>1) {
            	DBTRACEd(1,"IOCTL_READ bytes", rd);
            }
			break;

		case SBBSEXEC_IOCTL_WRITE:

			if (pIOCTL->dioc_InBuf==NULL
				|| pIOCTL->dioc_cbInBuf<sizeof(VMHANDLE)+1) {
				DBTRACE(0,"!INVALID INBUF");
				return(SBBSEXEC_ERROR_INBUF);
			}

			if (pIOCTL->dioc_OutBuf==NULL
				|| pIOCTL->dioc_cbOutBuf!=sizeof(DWORD)) {
				DBTRACE(0,"!INVALID OUTBUF");
				return(SBBSEXEC_ERROR_OUTBUF);
			}

			vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
			if(vm==NULL) {
				DBTRACE(0,"!NO VM LIST");
				return(SBBSEXEC_ERROR_INDATA);
			}

			wr = pIOCTL->dioc_cbInBuf-sizeof(VMHANDLE);

			avail = RingBufFree(&vm->in);

			if(wr>avail) {
				DBTRACEdd(0,"Reducing write size", wr, avail);
				wr=avail;
			}

			RingBufWrite(&vm->in, (BYTE*)pIOCTL->dioc_InBuf+sizeof(VMHANDLE), wr);

			*(DWORD *)pIOCTL->dioc_OutBuf = wr;

			if(pIOCTL->dioc_bytesret!=NULL)
				*pIOCTL->dioc_bytesret = sizeof(DWORD);

            if(vm->input_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->input_sem);

			// Wake up the VDM (improves keyboard response - dramatically!)
			Wake_Up_VM(vm->handle);
			break;

		case SBBSEXEC_IOCTL_DISCONNECT:
			DBTRACEd(0,"IOCTL: DISCONNECT",Get_System_Time());

			if (pIOCTL->dioc_InBuf==NULL
				|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
				DBTRACE(0,"!INVALID INBUF");
				return(SBBSEXEC_ERROR_INBUF);
			}

			vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
			if(vm==NULL) {
				DBTRACE(0,"!NO VM LIST");
				return(SBBSEXEC_ERROR_INDATA);
			}

			vm->online=false;

            if(vm->input_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->input_sem);
            if(vm->output_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->output_sem);
			break;

		case SBBSEXEC_IOCTL_STOP:
			DBTRACEd(0,"IOCTL: STOP",Get_System_Time());

			if (pIOCTL->dioc_InBuf==NULL
				|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
				DBTRACE(0,"!INVALID INBUF");
				return(SBBSEXEC_ERROR_INBUF);
			}

			vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
			if(vm==NULL) {
				DBTRACE(0,"!NO VM LIST");
				return(SBBSEXEC_ERROR_INDATA);
			}

			DBTRACEx(0,"CLOSING VM HANDLE", vm->handle);
			vm->handle=NULL;	// Mark as available
			RingBufDispose(&vm->in);
			RingBufDispose(&vm->out);
            if(vm->input_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->input_sem);
            if(vm->output_sem!=NULL) // Wake up int14 handler
            	Signal_Semaphore(vm->output_sem);

			vm->input_sem=NULL;
			vm->output_sem=NULL;

			break;

		default:
			DBTRACEdx(0,"!UNKNOWN IOCTL"
				,pIOCTL->dioc_IOCtlCode,pIOCTL->dioc_IOCtlCode);
			return(SBBSEXEC_ERROR_IOCTL);

	}
	return (0);	// DEVIOCTL_NOERROR);
}
예제 #20
0
void __fastcall TSpyForm::FormKeyPress(TObject *Sender, char &Key)
{
    if(KeyboardActive->Checked && inbuf!=NULL && *inbuf!=NULL)
        RingBufWrite(*inbuf,&Key,1);

}