Annotation of sbbs/sbbs3/dosxtrn/dosxtrn.c, revision 1.1.1.1

1.1       root        1: /* dosxtrn.c */
                      2: 
                      3: /* Synchronet External DOS Program Launcher (16-bit MSVC 1.52c project) */
                      4: 
                      5: /* $Id: dosxtrn.c,v 1.1.1.1 2000/10/10 11:27:07 rswindell Exp $ */
                      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:  *                                                                                                                                                     *
                     11:  * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
                     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 <stdio.h>
                     39: #include <stdlib.h>
                     40: #include <string.h>
                     41: #include <process.h>
                     42: #include <dos.h>                       /* _dos_set/getvect() */
                     43: #include <windows.h>           /* BOOL, etc. */
                     44: #include "vdd_func.h"
                     45: #include "execvxd.h"
                     46: #include "isvbop.h"                    /* ddk\inc */
                     47: 
                     48: /****************************************************************************/
                     49: /* Truncates white-space chars off end of 'str' and terminates at first tab */
                     50: /****************************************************************************/
                     51: static void truncsp(char *str)
                     52: {
                     53:        size_t c;
                     54: 
                     55: str[strcspn(str,"\t")]=0;
                     56: c=strlen(str);
                     57: while(c && (unsigned char)str[c-1]<=' ') c--;
                     58: str[c]=0;
                     59: }
                     60: 
                     61: short  vdd=0;
                     62: BYTE   node_num=0;
                     63: int            mode=0;
                     64: 
                     65: void (interrupt *oldint14)();
                     66: void (interrupt *oldint16)();
                     67: void (interrupt *oldint29)();
                     68: 
                     69: static int vdd_buf(BYTE op, int count, WORD buf_seg, WORD buf_off)
                     70: {
                     71:        int retval;
                     72: 
                     73:        _asm {
                     74:                push    bx
                     75:                push    cx
                     76:                push    es
                     77:                push    di
                     78:                mov             ax,     vdd
                     79:                mov             bh,     node_num
                     80:                mov             bl,     op
                     81:                mov             cx,     count
                     82:                mov             es, buf_seg
                     83:                mov             di, buf_off
                     84:        }
                     85:        DispatchCall();
                     86:        _asm {
                     87:                mov             retval, ax
                     88:                pop             di
                     89:                pop             es
                     90:                pop             cx
                     91:                pop             bx
                     92:        }
                     93:        return(retval);
                     94: }
                     95: 
                     96: static int vdd_op(BYTE op)
                     97: {
                     98:        int retval;
                     99: 
                    100:        _asm {
                    101:                push    bx
                    102:                mov             ax,     vdd
                    103:                mov             bh,     node_num
                    104:                mov             bl,     op
                    105:        }
                    106:        DispatchCall();
                    107:        _asm {
                    108:                mov             retval, ax
                    109:                pop             bx
                    110:        }
                    111:        return(retval);
                    112: }
                    113: 
                    114: char win95int14[]={
                    115:         0xCF   // IRET
                    116:        ,0x90   // NOP
                    117:        ,0x90
                    118:        ,0x90
                    119:        ,0x90
                    120:        ,0x90
                    121:        ,0x54   // FOSSIL sig
                    122:        ,0x19   // FOSSIL sig
                    123:        ,0x1B   // FOSSIL highest func supported
                    124: };
                    125: 
                    126: void vdd_getstatus(vdd_status_t* status)
                    127: {
                    128:        WORD                    buf_seg;
                    129: 
                    130:        _asm mov buf_seg, ss;
                    131:        if(vdd_buf(VDD_STATUS, sizeof(vdd_status_t), buf_seg, (WORD)status)!=0)
                    132:                memset(status,0,sizeof(vdd_status_t));
                    133: }
                    134: 
                    135: #if 1
                    136: 
                    137: WORD PortStatus()
                    138: {
                    139:        WORD                    status=0x0008;                  // AL bit 3 (change in DCD) always set
                    140:        vdd_status_t    vdd_status;
                    141: 
                    142:        vdd_getstatus(&vdd_status);
                    143: 
                    144:        if(vdd_status.online)                   // carrier detect
                    145:                status|=0x0080;                         // DCD
                    146: 
                    147:        if(vdd_status.inbuf_full)               // receive data ready 
                    148:                status|=0x0100;                         // RDA
                    149: 
                    150: //     if(vm->overrun)                                 // overrun error detected
                    151: //             status|=0x0200;                         // OVRN
                    152: 
                    153:        if(vdd_status.outbuf_full
                    154:                <vdd_status.outbuf_size/2)      // room available in output buffer
                    155:                status|=0x2000;                         // THRE
                    156: 
                    157:        if(!vdd_status.outbuf_full)             // output buffer is empty
                    158:                status|=0x4000;                         // TSRE
                    159: 
                    160:        return(status);
                    161: }
                    162: 
                    163: #else
                    164: 
                    165: WORD PortStatus()
                    166: {
                    167:        WORD    status=0x0008;                  // AL bit 3 (change in DCD) always set
                    168:        static  poll;
                    169:        static  online=1;
                    170:        static  outbuf_full;
                    171:        static  outbuf_size;
                    172: 
                    173:        if(!poll)
                    174:                outbuf_size=vdd_op(VDD_OUTBUF_SIZE);
                    175: 
                    176:        if(!(poll%500)) {
                    177:                online=vdd_op(VDD_ONLINE);
                    178:                outbuf_full=vdd_op(VDD_OUTBUF_FULL);
                    179:        }
                    180: 
                    181:        if(online)                                              // carrier detect
                    182:                status|=0x0080;                         // DCD
                    183: 
                    184:        if(vdd_op(VDD_INBUF_FULL))              // receive data ready 
                    185:                status|=0x0100;                         // RDA
                    186: 
                    187: //     if(vm->overrun)                                 // overrun error detected
                    188: //             status|=0x0200;                         // OVRN
                    189: 
                    190:        if(outbuf_full
                    191:                <outbuf_size/2)                         // room available in output buffer
                    192:                status|=0x2000;                         // THRE
                    193: 
                    194:        if(!outbuf_full)                                // output buffer is empty
                    195:                status|=0x4000;                         // TSRE
                    196: 
                    197:        poll++;
                    198: 
                    199:        return(status);
                    200: }
                    201: 
                    202: #endif
                    203: 
                    204: void interrupt winNTint14(
                    205:        unsigned _es, unsigned _ds,
                    206:        unsigned _di, unsigned _si,
                    207:        unsigned _bp, unsigned _sp,
                    208:        unsigned _bx, unsigned _dx,
                    209:        unsigned _cx, unsigned _ax,
                    210:        )
                    211: {
                    212:        BYTE                    ch;
                    213:        BYTE far*               p;
                    214:        WORD                    buf_seg;
                    215:        int                             wr;
                    216:        vdd_status_t    vdd_status;
                    217:     struct {
                    218:         WORD    info_size;
                    219:         BYTE   curr_fossil;
                    220:         BYTE   curr_rev;
                    221:         DWORD  id_string;
                    222:         WORD   inbuf_size;
                    223:         WORD   inbuf_free;
                    224:         WORD   outbuf_size;
                    225:         WORD   outbuf_free;
                    226:         BYTE   screen_width;
                    227:         BYTE   screen_height;
                    228:         BYTE   baud_rate;
                    229:     } info= { sizeof(info), 5, 1, 0
                    230:                                ,0,0
                    231:                                ,0,0
                    232:                        ,80,25
                    233:                        ,1 // 38400
                    234:                        };
                    235: 
                    236:        switch(_ax>>8) {
                    237:                case 0x00:      /* Initialize/Set baud rate */
                    238:                        _ax = PortStatus();
                    239:                        break;
                    240:                case 0x01: /* write char to com port */
                    241:                        ch=_ax&0xff;
                    242:                        _asm mov buf_seg, ss;
                    243:                        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    244:                        _ax = PortStatus();
                    245:                        break;
                    246:                case 0x02: /* read char from com port */
                    247:                        _asm mov buf_seg, ss;
                    248:                        _ax = vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
                    249:                        if(!_ax)
                    250:                                _ax = 0x8000;   /* timed-out */
                    251:                        else
                    252:                                _ax = ch;
                    253:                        break;
                    254:                case 0x03:      /* request status */
                    255:                        _ax=PortStatus();
                    256:                        break;
                    257:                case 0x04:      /* initialize */
                    258:                        _ax=0x1954;     /* magic number = success */
                    259:                        _bx=0x051B;     /* FOSSIL rev/maximum FOSSIL func supported */
                    260:                        break;
                    261:         case 0x08:     /* flush output buffer  */
                    262:                        break;
                    263:         case 0x09:     /* purge output buffer  */
                    264:                        vdd_op(VDD_OUTBUF_PURGE);
                    265:                        break;
                    266:         case 0x0A:     /* purge input buffer   */
                    267:                        vdd_op(VDD_INBUF_PURGE);
                    268:                        break;
                    269:                case 0x0B:      /* write char to com port, no wait */
                    270:                if(0 /*RingBufFree(&vm->out)<2 */) {
                    271:                _ax=0; // char was not accepted
                    272:                 break;
                    273:             }
                    274:                        ch=_ax&0xff;
                    275:                        _asm mov buf_seg, ss;
                    276:                        _ax = vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    277:                        break;
                    278:         case 0x0C:     // non-destructive read-ahead
                    279:                        vdd_getstatus(&vdd_status);
                    280:                        if(!vdd_status.inbuf_full) {
                    281:                                _ax=0xffff;     // no char available
                    282:                                break;
                    283:                        }
                    284:                        _asm mov buf_seg, ss;
                    285:                        _ax = vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
                    286:                        break;
                    287:         case 0x18:     /* read bock */
                    288:             _ax = vdd_buf(VDD_READ, _cx, _es, _di);
                    289:                        break;
                    290:         case 0x19:     /* write block */
                    291:                        _ax = vdd_buf(VDD_WRITE, _cx, _es, _di);
                    292:                        break;
                    293:         case 0x1B:     /* driver info */
                    294:                        vdd_getstatus(&vdd_status);
                    295:                        info.inbuf_size=vdd_status.inbuf_size;
                    296:                        info.inbuf_free=info.inbuf_size-vdd_status.inbuf_full;
                    297:                        info.outbuf_size=vdd_status.outbuf_size;
                    298:                        info.outbuf_free=info.outbuf_size-vdd_status.outbuf_full;
                    299: 
                    300:                        p = _MK_FP(_es,_di);
                    301:             wr=sizeof(info);
                    302:             if(wr>_cx)
                    303:                wr=_cx;
                    304:             _fmemcpy(p, &info, wr);
                    305:                _ax=wr;
                    306:             break;
                    307:        }
                    308: }
                    309: 
                    310: void interrupt winNTint16(
                    311:        unsigned _es, unsigned _ds,
                    312:        unsigned _di, unsigned _si,
                    313:        unsigned _bp, unsigned _sp,
                    314:        unsigned _bx, unsigned _dx,
                    315:        unsigned _cx, unsigned _ax,
                    316:        unsigned _ip, unsigned _cs,
                    317:     unsigned flags )
                    318: {
                    319:        BYTE                    ch;
                    320:        WORD                    buf_seg;
                    321:        vdd_status_t    status;
                    322: 
                    323:        vdd_getstatus(&status);
                    324:        switch(_ax>>8) {
                    325:        case 0x00:      // Read char from keyboard
                    326:         case 0x10:     // Read char from enhanced keyboard
                    327:                        if(status.inbuf_full) {
                    328:                                _asm mov buf_seg, ss;
                    329:                                vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
                    330:                                _ax=ch;
                    331:                                return;
                    332:                        }
                    333:                        break;
                    334:        case 0x01:      // Get keyboard status
                    335:         case 0x11:     // Get enhanced keyboard status
                    336:                        if(status.inbuf_full) {
                    337:                                _asm mov buf_seg, ss;
                    338:                                vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
                    339:                 flags&=~(1<<6);        // clear zero flag
                    340:                 _ax=ch;
                    341:                                return;
                    342:            }
                    343:                break;
                    344:        }
                    345: 
                    346:        _chain_intr(oldint16);          
                    347: }
                    348: 
                    349: void interrupt winNTint29(
                    350:        unsigned _es, unsigned _ds,
                    351:        unsigned _di, unsigned _si,
                    352:        unsigned _bp, unsigned _sp,
                    353:        unsigned _bx, unsigned _dx,
                    354:        unsigned _cx, unsigned _ax,
                    355:        )
                    356: {
                    357:        char    ch;
                    358:        WORD    buf_seg;
                    359: 
                    360:        ch=_ax&0xff;
                    361:        _asm mov buf_seg, ss
                    362:        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    363: 
                    364:        _chain_intr(oldint29);
                    365: }
                    366: 
                    367: char * DllName         ="SBBSEXEC.DLL";
                    368: char * InitFunc        ="VDDInitialize";
                    369: char * DispFunc        ="VDDDispatch";
                    370: 
                    371: int main(int argc, char **argv)
                    372: {
                    373:        char    str[128];
                    374:        char    cmdline[128],*p;
                    375:        char    dll[512];
                    376:        char*   envvar[10];
                    377:        char*   arg[16];
                    378:        int             i,c,d,envnum=0;
                    379:        FILE*   fp;
                    380:        BOOL    NT=FALSE;
                    381:        BOOL    success=FALSE;
                    382:        WORD    seg;
                    383: 
                    384:        if(argc<2) {
                    385:                fprintf(stderr
                    386:                        ,"This program is for the internal use of Synchronet BBS only\n");
                    387:                return(1);
                    388:        }
                    389: #if 1
                    390:        strcpy(dll,argv[0]);
                    391:        p=strrchr(dll,'\\');
                    392:        if(p!=NULL) *(p+1)=0;
                    393:        strcat(dll,"SBBSEXEC.DLL");
                    394:        DllName=dll;
                    395: #endif
                    396: 
                    397:        if(argc>2 && !strcmp(argv[2],"NT")) {
                    398:                NT=TRUE;
                    399:                if(argc>3)
                    400:                        node_num=atoi(argv[3]);
                    401:                if(argc>4)
                    402:                        mode=atoi(argv[4]);
                    403:        }
                    404: 
                    405:        if((fp=fopen(argv[1],"r"))==NULL) {
                    406:                fprintf(stderr,"!Error opening %s\n",argv[1]);
                    407:                return(2);
                    408:        }
                    409: 
                    410:        fgets(cmdline, sizeof(cmdline), fp);
                    411:        truncsp(cmdline);
                    412: 
                    413:        arg[0]=cmdline; /* point to the beginning of the string */
                    414:        for(c=0,d=1;cmdline[c];c++)     /* Break up command line */
                    415:                if(cmdline[c]==' ') {
                    416:                        cmdline[c]=0;                   /* insert nulls */
                    417:                        arg[d++]=cmdline+c+1; } /* point to the beginning of the next arg */
                    418:        arg[d]=0;
                    419: 
                    420:        while(!feof(fp)) {
                    421:                if(!fgets(str, sizeof(str), fp))
                    422:                        break;
                    423:                truncsp(str);
                    424:                envvar[envnum]=malloc(strlen(str)+1);
                    425:                if(envvar[envnum]==NULL) {
                    426:                        fprintf(stderr,"!MALLOC ERROR\n");
                    427:                        return(4);
                    428:                }
                    429:                strcpy(envvar[envnum],str);
                    430:                _putenv(envvar[envnum++]);
                    431:        }
                    432:        fclose(fp);
                    433: 
                    434:        /* Save int14 handler */
                    435:        oldint14=_dos_getvect(0x14);
                    436: 
                    437:        if(NT) {        /* Windows NT/2000 */
                    438: 
                    439:                /* Register VDD */
                    440:                _asm {
                    441:                        push    es
                    442:                        push    ds
                    443:                        pop             es
                    444:                        mov     si, DllName             ; ds:si = dll name
                    445:                    mov     di, InitFunc    ; es:di = init routine
                    446:                        mov     bx, DispFunc    ; ds:bx = dispatch routine
                    447:                };
                    448:                RegisterModule();
                    449:                _asm {
                    450:                        mov             vdd, ax
                    451:                        jc              err
                    452:                        mov             success, TRUE
                    453:                        err:
                    454:                        pop             es
                    455:                }
                    456:                if(!success) {
                    457:                        fprintf(stderr,"Error %d loading %s\n",vdd,DllName);
                    458:                        return(-1);
                    459:                }
                    460: #if 0
                    461:                fprintf(stderr,"vdd handle=%d\n",vdd);
                    462:                fprintf(stderr,"mode=%d\n",mode);
                    463: #endif
                    464: 
                    465:                i=vdd_op(VDD_OPEN);
                    466:                if(i) {
                    467:                        fprintf(stderr,"!VDD_OPEN ERROR: %d\n",i);
                    468:                        UnRegisterModule();
                    469:                        return(-1);
                    470:                }
                    471: 
                    472:                oldint16=_dos_getvect(0x16);
                    473:                oldint29=_dos_getvect(0x29);
                    474:                if(mode==SBBSEXEC_MODE_FOSSIL)
                    475:                        _dos_setvect(0x14,(void(interrupt *)())winNTint14); 
                    476:                if(mode&SBBSEXEC_MODE_DOS_IN)
                    477:                        _dos_setvect(0x16,winNTint16); 
                    478:                if(mode&SBBSEXEC_MODE_DOS_OUT) 
                    479:                        _dos_setvect(0x29,winNTint29); 
                    480:        }
                    481:        else            /* Windows 95/98/Millennium */
                    482:                _dos_setvect(0x14,(void(interrupt *)())win95int14); 
                    483: 
                    484:        _heapmin();
                    485:        i=_spawnvp(_P_WAIT, arg[0], arg);
                    486: 
                    487:        p=argv[1]+(strlen(argv[1])-3);
                    488:        strcpy(p,"RET");
                    489:        if((fp=fopen(argv[1],"w+"))==NULL) {
                    490:                fprintf(stderr,"!Error opening %s\n",argv[1]);
                    491:                return(3);
                    492:        }
                    493:        fprintf(fp,"%d",i);
                    494: 
                    495:        /* Restore original ISRs */
                    496:        _dos_setvect(0x14,oldint14);
                    497: 
                    498:        if(NT) {
                    499:                vdd_op(VDD_CLOSE);
                    500: 
                    501:                _dos_setvect(0x16,oldint16);
                    502:                _dos_setvect(0x29,oldint29);
                    503: 
                    504:                /* Unregister VDD */
                    505:                _asm mov ax, vdd;
                    506:                UnRegisterModule();
                    507:        }
                    508:        return(i);
                    509: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.