|
|
3.12a Javascript
/* sbbsexec.c */
/* Synchronet Windows NT/2000 VDD for FOSSIL and DOS I/O Interrupts */
/* $Id: sbbsexec.c,v 1.1.1.2 2018/04/24 16:40:41 root Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* 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. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to [email protected] *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <vddsvc.h>
#include "vdd_func.h"
#include "ringbuf.h"
#define RINGBUF_SIZE_IN 10000
#define DEFAULT_MAX_MSG_SIZE 4000
__declspec(dllexport) void __cdecl VDDDispatch(void)
{
char str[512];
char buf[5000];
DWORD count;
DWORD msgs;
int retval;
int node_num;
BYTE* p;
vdd_status_t* status;
static DWORD writes;
static DWORD bytes_written;
static DWORD reads;
static DWORD bytes_read;
static DWORD inbuf_poll;
static DWORD online_poll;
static DWORD status_poll;
static DWORD yields;
static HANDLE hungup_event=NULL;
static HANDLE rdslot=INVALID_HANDLE_VALUE;
static HANDLE wrslot=INVALID_HANDLE_VALUE;
static RingBuf rdbuf;
#if defined(_DEBUG)
static FILE* fp=NULL;
#endif
retval=0;
node_num=getBH();
switch(getBL()) {
case VDD_OPEN:
#if defined(_DEBUG)
sprintf(str,"sbbsexec%d.log",node_num);
fp=fopen(str,"wb");
#endif
sprintf(str,"\\\\.\\mailslot\\sbbsexec\\wr%d",node_num);
rdslot=CreateMailslot(str
,sizeof(buf) // Max message size (0=any)
,MAILSLOT_WAIT_FOREVER // Read timeout
,NULL);
if(rdslot==INVALID_HANDLE_VALUE) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
,GetLastError(),str);
#endif
retval=1;
break;
}
sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d",node_num);
wrslot=CreateFile(str
,GENERIC_WRITE
,FILE_SHARE_READ
,NULL
,OPEN_EXISTING
,FILE_ATTRIBUTE_NORMAL
,(HANDLE) NULL);
if(wrslot==INVALID_HANDLE_VALUE) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
,GetLastError(),str);
#endif
retval=2;
break;
}
if(RingBufInit(&rdbuf, RINGBUF_SIZE_IN)!=0) {
retval=3;
break;
}
sprintf(str,"sbbsexec_hungup%d",node_num);
hungup_event=OpenEvent(
EVENT_ALL_ACCESS, // access flag
FALSE, // inherit flag
str); // pointer to event-object name
if(hungup_event==NULL) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
,GetLastError(),str);
#endif
retval=4;
break;
}
status_poll=0;
inbuf_poll=0;
online_poll=0;
yields=0;
retval=0;
break;
case VDD_CLOSE:
#if defined(_DEBUG)
if(fp!=NULL) {
fprintf(fp,"VDD_CLOSE: rdbuf=%u "
"status_poll=%u inbuf_poll=%u online_poll=%u yields=%u\r\n"
,RingBufFull(&rdbuf),status_poll,inbuf_poll,online_poll,yields);
fprintf(fp," read=%u bytes (in %u calls)\r\n",bytes_read,reads);
fprintf(fp," wrote=%u bytes (in %u calls)\r\n",bytes_written,writes);
fclose(fp);
}
#endif
CloseHandle(rdslot);
CloseHandle(wrslot);
if(hungup_event!=NULL)
CloseHandle(hungup_event);
RingBufDispose(&rdbuf);
status_poll=0;
retval=0;
break;
case VDD_READ:
count = getCX();
#if defined(_DEBUG)
if(count != 1 && fp!=NULL)
fprintf(fp,"VDD_READ of %d\r\n",count);
#endif
p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
,count,FALSE);
if(RingBufFull(&rdbuf)) {
retval=RingBufRead(&rdbuf,p,count);
#if defined(_DEBUG)
if(retval==0 && fp!=NULL)
fprintf(fp,"!VDD_READ: RingBufRead read 0\r\n");
#endif
reads++;
bytes_read+=retval;
break;
}
if(!ReadFile(rdslot,buf,sizeof(buf),&retval,NULL)) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_READ: ReadFile Error %d (size=%d)\r\n"
,GetLastError(),retval);
#endif
retval=0;
break;
}
if(retval==0) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_READ: ReadFile read 0\r\n");
#endif
break;
}
RingBufWrite(&rdbuf,buf,retval);
retval=RingBufRead(&rdbuf,p,count);
#if defined(_DEBUG)
if(retval==0 && fp!=NULL)
fprintf(fp,"!VDD_READ: RingBufRead read 0 after write\r\n");
#endif
reads++;
bytes_read+=retval;
break;
case VDD_PEEK:
count = getCX();
#if defined(_DEBUG)
if(count != 1 && fp!=NULL)
fprintf(fp,"VDD_PEEK of %d\r\n",count);
#endif
p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
,count,FALSE);
if(RingBufFull(&rdbuf)) {
retval=RingBufPeek(&rdbuf,p,count);
break;
}
if(!ReadFile(rdslot,buf,sizeof(buf),&retval,NULL)) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_PEEK: ReadFile Error %d\r\n"
,GetLastError());
#endif
retval=0;
break;
}
if(retval==0) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_PEEK: ReadFile read 0\r\n");
#endif
break;
}
RingBufWrite(&rdbuf,buf,retval);
retval=RingBufPeek(&rdbuf,p,count);
break;
case VDD_WRITE:
count = getCX();
#if defined(_DEBUG)
if(count != 1 && fp!=NULL)
fprintf(fp,"VDD_WRITE of %d\r\n",count);
#endif
p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
,count,FALSE);
// if(fp!=NULL)
// fwrite(p,count,1,fp);
if(!WriteFile(wrslot,p,count,&retval,NULL)) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_WRITE: WriteFile Error %d (size=%d)\r\n"
,GetLastError(),retval);
#endif
retval=0;
} else {
writes++;
bytes_written+=retval;
}
break;
case VDD_STATUS:
status_poll++;
count = getCX();
if(count != sizeof(vdd_status_t)) {
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_STATUS: wrong size (%d!=%d)\r\n",count,sizeof(vdd_status_t));
#endif
retval=sizeof(vdd_status_t);
break;
}
status = (vdd_status_t*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
,count,FALSE);
/* INBUF FULL/SIZE */
if(!GetMailslotInfo(
rdslot, // mailslot handle
&status->inbuf_size, // address of maximum message size
&status->inbuf_full, // address of size of next message
&msgs, // address of number of messages
NULL // address of read time-out
)) {
status->inbuf_full=0;
status->inbuf_size=DEFAULT_MAX_MSG_SIZE;
}
if(status->inbuf_full==MAILSLOT_NO_MESSAGE)
status->inbuf_full=0;
status->inbuf_full*=msgs;
status->inbuf_full+=RingBufFull(&rdbuf);
/* OUTBUF FULL/SIZE */
if(!GetMailslotInfo(
wrslot, // mailslot handle
&status->outbuf_size, // address of maximum message size
&status->outbuf_full, // address of size of next message
&msgs, // address of number of messages
NULL // address of read time-out
)) {
status->outbuf_full=0;
status->outbuf_size=DEFAULT_MAX_MSG_SIZE;
}
if(status->outbuf_full==MAILSLOT_NO_MESSAGE)
status->outbuf_full=0;
status->outbuf_full*=msgs;
/* ONLINE */
if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
status->online=0;
else
status->online=1;
retval=0; /* success */
break;
case VDD_INBUF_PURGE:
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_INBUF_PURGE: NOT IMPLEMENTED\r\n");
#endif
retval=0;
break;
case VDD_OUTBUF_PURGE:
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED\r\n");
#endif
retval=0;
break;
case VDD_INBUF_FULL:
if(!GetMailslotInfo(
rdslot, // mailslot handle
NULL, // address of maximum message size
&retval, // address of size of next message
&msgs, // address of number of messages
NULL // address of read time-out
))
retval=0;
if(retval==MAILSLOT_NO_MESSAGE)
retval=0;
retval*=msgs;
retval+=RingBufFull(&rdbuf);
inbuf_poll++;
break;
case VDD_INBUF_SIZE:
if(!GetMailslotInfo(
rdslot, // mailslot handle
&retval, // address of maximum message size
NULL, // address of size of next message
NULL, // address of number of messages
NULL // address of read time-out
))
retval=DEFAULT_MAX_MSG_SIZE;
break;
case VDD_OUTBUF_FULL:
if(!GetMailslotInfo(
wrslot, // mailslot handle
NULL, // address of maximum message size
&retval, // address of size of next message
&msgs, // address of number of messages
NULL // address of read time-out
))
retval=0;
if(retval==MAILSLOT_NO_MESSAGE)
retval=0;
retval*=msgs;
break;
case VDD_OUTBUF_SIZE:
if(!GetMailslotInfo(
wrslot, // mailslot handle
&retval, // address of maximum message size
NULL, // address of size of next message
NULL, // address of number of messages
NULL // address of read time-out
))
retval=DEFAULT_MAX_MSG_SIZE;
break;
case VDD_ONLINE:
if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
retval=0;
else
retval=1;
online_poll++;
break;
case VDD_YIELD:
Sleep(1);
yields++;
break;
default:
#if defined(_DEBUG)
if(fp!=NULL)
fprintf(fp,"!UNKNOWN VDD_OP: %d\r\n",getBL());
#endif
break;
}
setAX((WORD)retval);
}
__declspec(dllexport) BOOL __cdecl VDDInitialize(IN PVOID DllHandle, IN ULONG Reason,
IN PCONTEXT Context OPTIONAL)
{
return TRUE;
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.