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

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

unix.superglobalmegacorp.com

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