|
|
1.1 root 1: /* sbbsexec.c */
2:
3: /* Synchronet Windows NT/2000 VDD for FOSSIL and DOS I/O Interrupts */
4:
1.1.1.2 ! root 5: /* $Id: sbbsexec.c,v 1.13 2003/05/09 10:26:37 rswindell Exp $ */
1.1 root 6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
1.1.1.2 ! root 11: * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #include <windows.h>
39: #include <stdio.h>
40: #include <vddsvc.h>
41: #include "vdd_func.h"
42: #include "ringbuf.h"
43:
1.1.1.2 ! root 44: #define RINGBUF_SIZE_IN 10000
! 45: #define DEFAULT_MAX_MSG_SIZE 4000
1.1 root 46:
47: __declspec(dllexport) void __cdecl VDDDispatch(void)
48: {
49: char str[512];
50: char buf[5000];
51: DWORD count;
1.1.1.2 ! root 52: DWORD msgs;
1.1 root 53: int retval;
54: int node_num;
55: BYTE* p;
56: vdd_status_t* status;
1.1.1.2 ! root 57: static DWORD writes;
! 58: static DWORD bytes_written;
! 59: static DWORD reads;
! 60: static DWORD bytes_read;
1.1 root 61: static DWORD inbuf_poll;
62: static DWORD online_poll;
63: static DWORD status_poll;
1.1.1.2 ! root 64: static DWORD yields;
! 65: static HANDLE hungup_event=NULL;
1.1 root 66: static HANDLE rdslot=INVALID_HANDLE_VALUE;
67: static HANDLE wrslot=INVALID_HANDLE_VALUE;
68: static RingBuf rdbuf;
1.1.1.2 ! root 69: #if defined(_DEBUG)
! 70: static FILE* fp=NULL;
! 71: #endif
1.1 root 72:
1.1.1.2 ! root 73: retval=0;
1.1 root 74: node_num=getBH();
75:
76: switch(getBL()) {
77:
78: case VDD_OPEN:
1.1.1.2 ! root 79: #if defined(_DEBUG)
1.1 root 80: sprintf(str,"sbbsexec%d.log",node_num);
81: fp=fopen(str,"wb");
1.1.1.2 ! root 82: #endif
1.1 root 83:
84: sprintf(str,"\\\\.\\mailslot\\sbbsexec\\wr%d",node_num);
85: rdslot=CreateMailslot(str
86: ,sizeof(buf) // Max message size (0=any)
87: ,MAILSLOT_WAIT_FOREVER // Read timeout
88: ,NULL);
89: if(rdslot==INVALID_HANDLE_VALUE) {
1.1.1.2 ! root 90: #if defined(_DEBUG)
1.1 root 91: if(fp!=NULL)
92: fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
93: ,GetLastError(),str);
1.1.1.2 ! root 94: #endif
1.1 root 95: retval=1;
96: break;
97: }
98:
99: sprintf(str,"\\\\.\\mailslot\\sbbsexec\\rd%d",node_num);
100: wrslot=CreateFile(str
101: ,GENERIC_WRITE
102: ,FILE_SHARE_READ
103: ,NULL
104: ,OPEN_EXISTING
105: ,FILE_ATTRIBUTE_NORMAL
106: ,(HANDLE) NULL);
107: if(wrslot==INVALID_HANDLE_VALUE) {
1.1.1.2 ! root 108: #if defined(_DEBUG)
1.1 root 109: if(fp!=NULL)
110: fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
111: ,GetLastError(),str);
1.1.1.2 ! root 112: #endif
1.1 root 113: retval=2;
114: break;
115: }
116:
117: if(RingBufInit(&rdbuf, RINGBUF_SIZE_IN)!=0) {
118: retval=3;
119: break;
120: }
121:
122: sprintf(str,"sbbsexec_hungup%d",node_num);
123: hungup_event=OpenEvent(
124: EVENT_ALL_ACCESS, // access flag
125: FALSE, // inherit flag
126: str); // pointer to event-object name
127: if(hungup_event==NULL) {
1.1.1.2 ! root 128: #if defined(_DEBUG)
1.1 root 129: if(fp!=NULL)
130: fprintf(fp,"!VDD_OPEN: Error %d opening %s\r\n"
131: ,GetLastError(),str);
1.1.1.2 ! root 132: #endif
1.1 root 133: retval=4;
134: break;
135: }
136:
137: status_poll=0;
138: inbuf_poll=0;
139: online_poll=0;
1.1.1.2 ! root 140: yields=0;
1.1 root 141:
142: retval=0;
143: break;
144:
145: case VDD_CLOSE:
1.1.1.2 ! root 146: #if defined(_DEBUG)
1.1 root 147: if(fp!=NULL) {
1.1.1.2 ! root 148: fprintf(fp,"VDD_CLOSE: rdbuf=%u "
! 149: "status_poll=%u inbuf_poll=%u online_poll=%u yields=%u\r\n"
! 150: ,RingBufFull(&rdbuf),status_poll,inbuf_poll,online_poll,yields);
! 151: fprintf(fp," read=%u bytes (in %u calls)\r\n",bytes_read,reads);
! 152: fprintf(fp," wrote=%u bytes (in %u calls)\r\n",bytes_written,writes);
1.1 root 153: fclose(fp);
154: }
1.1.1.2 ! root 155: #endif
1.1 root 156: CloseHandle(rdslot);
157: CloseHandle(wrslot);
1.1.1.2 ! root 158: if(hungup_event!=NULL)
! 159: CloseHandle(hungup_event);
1.1 root 160: RingBufDispose(&rdbuf);
161: status_poll=0;
162: retval=0;
163:
164: break;
165:
166: case VDD_READ:
167: count = getCX();
1.1.1.2 ! root 168: #if defined(_DEBUG)
1.1 root 169: if(count != 1 && fp!=NULL)
170: fprintf(fp,"VDD_READ of %d\r\n",count);
1.1.1.2 ! root 171: #endif
1.1 root 172: p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
173: ,count,FALSE);
174: if(RingBufFull(&rdbuf)) {
175: retval=RingBufRead(&rdbuf,p,count);
1.1.1.2 ! root 176: #if defined(_DEBUG)
1.1 root 177: if(retval==0 && fp!=NULL)
178: fprintf(fp,"!VDD_READ: RingBufRead read 0\r\n");
1.1.1.2 ! root 179: #endif
! 180: reads++;
! 181: bytes_read+=retval;
1.1 root 182: break;
183: }
184: if(!ReadFile(rdslot,buf,sizeof(buf),&retval,NULL)) {
1.1.1.2 ! root 185: #if defined(_DEBUG)
1.1 root 186: if(fp!=NULL)
187: fprintf(fp,"!VDD_READ: ReadFile Error %d (size=%d)\r\n"
188: ,GetLastError(),retval);
1.1.1.2 ! root 189: #endif
1.1 root 190: retval=0;
191: break;
192: }
193: if(retval==0) {
1.1.1.2 ! root 194: #if defined(_DEBUG)
1.1 root 195: if(fp!=NULL)
196: fprintf(fp,"!VDD_READ: ReadFile read 0\r\n");
1.1.1.2 ! root 197: #endif
1.1 root 198: break;
199: }
200: RingBufWrite(&rdbuf,buf,retval);
201: retval=RingBufRead(&rdbuf,p,count);
1.1.1.2 ! root 202: #if defined(_DEBUG)
1.1 root 203: if(retval==0 && fp!=NULL)
204: fprintf(fp,"!VDD_READ: RingBufRead read 0 after write\r\n");
1.1.1.2 ! root 205: #endif
! 206: reads++;
! 207: bytes_read+=retval;
1.1 root 208: break;
209:
210: case VDD_PEEK:
211: count = getCX();
1.1.1.2 ! root 212: #if defined(_DEBUG)
1.1 root 213: if(count != 1 && fp!=NULL)
214: fprintf(fp,"VDD_PEEK of %d\r\n",count);
1.1.1.2 ! root 215: #endif
1.1 root 216:
217: p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
218: ,count,FALSE);
219: if(RingBufFull(&rdbuf)) {
220: retval=RingBufPeek(&rdbuf,p,count);
221: break;
222: }
223: if(!ReadFile(rdslot,buf,sizeof(buf),&retval,NULL)) {
1.1.1.2 ! root 224: #if defined(_DEBUG)
1.1 root 225: if(fp!=NULL)
226: fprintf(fp,"!VDD_PEEK: ReadFile Error %d\r\n"
227: ,GetLastError());
1.1.1.2 ! root 228: #endif
1.1 root 229: retval=0;
230: break;
231: }
232: if(retval==0) {
1.1.1.2 ! root 233: #if defined(_DEBUG)
1.1 root 234: if(fp!=NULL)
235: fprintf(fp,"!VDD_PEEK: ReadFile read 0\r\n");
1.1.1.2 ! root 236: #endif
1.1 root 237: break;
238: }
239: RingBufWrite(&rdbuf,buf,retval);
240: retval=RingBufPeek(&rdbuf,p,count);
241: break;
242:
243: case VDD_WRITE:
244: count = getCX();
1.1.1.2 ! root 245: #if defined(_DEBUG)
1.1 root 246: if(count != 1 && fp!=NULL)
247: fprintf(fp,"VDD_WRITE of %d\r\n",count);
1.1.1.2 ! root 248: #endif
1.1 root 249: p = (BYTE*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
250: ,count,FALSE);
251: // if(fp!=NULL)
252: // fwrite(p,count,1,fp);
253: if(!WriteFile(wrslot,p,count,&retval,NULL)) {
1.1.1.2 ! root 254: #if defined(_DEBUG)
1.1 root 255: if(fp!=NULL)
256: fprintf(fp,"!VDD_WRITE: WriteFile Error %d (size=%d)\r\n"
257: ,GetLastError(),retval);
1.1.1.2 ! root 258: #endif
1.1 root 259: retval=0;
1.1.1.2 ! root 260: } else {
! 261: writes++;
! 262: bytes_written+=retval;
1.1 root 263: }
264: break;
265:
266: case VDD_STATUS:
267:
268: status_poll++;
269: count = getCX();
270: if(count != sizeof(vdd_status_t)) {
1.1.1.2 ! root 271: #if defined(_DEBUG)
1.1 root 272: if(fp!=NULL)
273: fprintf(fp,"!VDD_STATUS: wrong size (%d!=%d)\r\n",count,sizeof(vdd_status_t));
1.1.1.2 ! root 274: #endif
1.1 root 275: retval=sizeof(vdd_status_t);
276: break;
277: }
278: status = (vdd_status_t*) GetVDMPointer((ULONG)((getES() << 16)|getDI())
279: ,count,FALSE);
280:
281: /* INBUF FULL/SIZE */
282: if(!GetMailslotInfo(
283: rdslot, // mailslot handle
284: &status->inbuf_size, // address of maximum message size
285: &status->inbuf_full, // address of size of next message
1.1.1.2 ! root 286: &msgs, // address of number of messages
1.1 root 287: NULL // address of read time-out
288: )) {
289: status->inbuf_full=0;
1.1.1.2 ! root 290: status->inbuf_size=DEFAULT_MAX_MSG_SIZE;
1.1 root 291: }
292: if(status->inbuf_full==MAILSLOT_NO_MESSAGE)
293: status->inbuf_full=0;
1.1.1.2 ! root 294: status->inbuf_full*=msgs;
1.1 root 295: status->inbuf_full+=RingBufFull(&rdbuf);
296:
297:
1.1.1.2 ! root 298: /* OUTBUF FULL/SIZE */
1.1 root 299: if(!GetMailslotInfo(
300: wrslot, // mailslot handle
301: &status->outbuf_size, // address of maximum message size
302: &status->outbuf_full, // address of size of next message
1.1.1.2 ! root 303: &msgs, // address of number of messages
1.1 root 304: NULL // address of read time-out
305: )) {
306: status->outbuf_full=0;
1.1.1.2 ! root 307: status->outbuf_size=DEFAULT_MAX_MSG_SIZE;
1.1 root 308: }
309: if(status->outbuf_full==MAILSLOT_NO_MESSAGE)
310: status->outbuf_full=0;
1.1.1.2 ! root 311: status->outbuf_full*=msgs;
1.1 root 312:
313: /* ONLINE */
314: if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
315: status->online=0;
316: else
317: status->online=1;
318:
319: retval=0; /* success */
320: break;
321:
322:
323: case VDD_INBUF_PURGE:
1.1.1.2 ! root 324: #if defined(_DEBUG)
1.1 root 325: if(fp!=NULL)
326: fprintf(fp,"!VDD_INBUF_PURGE: NOT IMPLEMENTED\r\n");
1.1.1.2 ! root 327: #endif
1.1 root 328: retval=0;
329: break;
330:
331: case VDD_OUTBUF_PURGE:
1.1.1.2 ! root 332: #if defined(_DEBUG)
1.1 root 333: if(fp!=NULL)
334: fprintf(fp,"!VDD_OUTBUF_PURGE: NOT IMPLEMENTED\r\n");
1.1.1.2 ! root 335: #endif
1.1 root 336: retval=0;
337: break;
338:
339: case VDD_INBUF_FULL:
340: if(!GetMailslotInfo(
341: rdslot, // mailslot handle
342: NULL, // address of maximum message size
343: &retval, // address of size of next message
1.1.1.2 ! root 344: &msgs, // address of number of messages
1.1 root 345: NULL // address of read time-out
346: ))
347: retval=0;
348: if(retval==MAILSLOT_NO_MESSAGE)
349: retval=0;
1.1.1.2 ! root 350: retval*=msgs;
1.1 root 351: retval+=RingBufFull(&rdbuf);
352: inbuf_poll++;
353: break;
354:
355: case VDD_INBUF_SIZE:
356: if(!GetMailslotInfo(
357: rdslot, // mailslot handle
358: &retval, // address of maximum message size
359: NULL, // address of size of next message
360: NULL, // address of number of messages
361: NULL // address of read time-out
362: ))
1.1.1.2 ! root 363: retval=DEFAULT_MAX_MSG_SIZE;
1.1 root 364: break;
365:
366: case VDD_OUTBUF_FULL:
367: if(!GetMailslotInfo(
368: wrslot, // mailslot handle
369: NULL, // address of maximum message size
370: &retval, // address of size of next message
1.1.1.2 ! root 371: &msgs, // address of number of messages
1.1 root 372: NULL // address of read time-out
373: ))
374: retval=0;
375: if(retval==MAILSLOT_NO_MESSAGE)
376: retval=0;
1.1.1.2 ! root 377: retval*=msgs;
1.1 root 378: break;
379:
380: case VDD_OUTBUF_SIZE:
381: if(!GetMailslotInfo(
382: wrslot, // mailslot handle
383: &retval, // address of maximum message size
384: NULL, // address of size of next message
385: NULL, // address of number of messages
386: NULL // address of read time-out
387: ))
1.1.1.2 ! root 388: retval=DEFAULT_MAX_MSG_SIZE;
1.1 root 389: break;
390:
391: case VDD_ONLINE:
392: if(WaitForSingleObject(hungup_event,0)==WAIT_OBJECT_0)
393: retval=0;
394: else
395: retval=1;
396: online_poll++;
397: break;
1.1.1.2 ! root 398:
! 399: case VDD_YIELD:
! 400: Sleep(1);
! 401: yields++;
! 402: break;
! 403:
1.1 root 404: default:
1.1.1.2 ! root 405: #if defined(_DEBUG)
1.1 root 406: if(fp!=NULL)
407: fprintf(fp,"!UNKNOWN VDD_OP: %d\r\n",getBL());
1.1.1.2 ! root 408: #endif
1.1 root 409: break;
410: }
411: setAX((WORD)retval);
412: }
413:
414: __declspec(dllexport) BOOL __cdecl VDDInitialize(IN PVOID DllHandle, IN ULONG Reason,
415: IN PCONTEXT Context OPTIONAL)
416: {
417: return TRUE;
418: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.