Annotation of sbbs/src/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.23 2006/10/28 03:54:09 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 2006 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: #include "fossdefs.h"
                     48: 
                     49: #define VDD_FILENAME   "sbbsexec.dll"
                     50: 
                     51: /****************************************************************************/
                     52: /* Truncates white-space chars off end of 'str' and terminates at first tab */
                     53: /****************************************************************************/
                     54: static void truncsp(char *str)
                     55: {
                     56:        size_t c;
                     57: 
                     58:        str[strcspn(str,"\t")]=0;
                     59:        c=strlen(str);
                     60:        while(c && (unsigned char)str[c-1]<=' ') c--;
                     61:        str[c]=0;
                     62: }
                     63: short  vdd=0;
                     64: BYTE   node_num=0;
                     65: int            mode=0;
                     66: int            revision;
                     67: char   id_string[128];
                     68: #ifdef DEBUG_INT_CALLS
                     69: ulong  int14calls=0;
                     70: ulong  int16calls=0;
                     71: ulong  int21calls=0;
                     72: ulong  int29calls=0;
                     73: #endif
                     74: 
                     75: void (interrupt *oldint14)();
                     76: void (interrupt *oldint16)();
                     77: void (interrupt *oldint21)();
                     78: void (interrupt *oldint29)();
                     79: 
                     80: 
                     81: static int vdd_buf(BYTE op, int count, WORD buf_seg, WORD buf_off)
                     82: {
                     83:        int retval;
                     84: 
                     85:        _asm {
                     86:                push    bx
                     87:                push    cx
                     88:                push    es
                     89:                push    di
                     90:                mov             ax,     vdd
                     91:                mov             bh,     node_num
                     92:                mov             bl,     op
                     93:                mov             cx,     count
                     94:                mov             es, buf_seg
                     95:                mov             di, buf_off
                     96:        }
                     97:        DispatchCall();
                     98:        _asm {
                     99:                mov             retval, ax
                    100:                pop             di
                    101:                pop             es
                    102:                pop             cx
                    103:                pop             bx
                    104:        }
                    105:        return(retval);
                    106: }
                    107: 
                    108: static int vdd_str(BYTE op, char* str)
                    109: {
                    110:        WORD                    buf_seg;
                    111: 
                    112:        _asm mov buf_seg, ss;
                    113:        return vdd_buf(op, strlen(str), buf_seg, (WORD)str);
                    114: }
                    115: 
                    116: static int vdd_op(BYTE op)
                    117: {
                    118:        int retval;
                    119: 
                    120: #if FALSE      /* disable yield? */
                    121:        if(op==VDD_YIELD)
                    122:                return(0);
                    123: #endif
                    124:        _asm {
                    125:                push    bx
                    126:                mov             ax,     vdd
                    127:                mov             bh,     node_num
                    128:                mov             bl,     op
                    129:        }
                    130:        DispatchCall();
                    131:        _asm {
                    132:                mov             retval, ax
                    133:                pop             bx
                    134:        }
                    135:        return(retval);
                    136: }
                    137: 
                    138: union REGS inregs;
                    139: struct SREGS sregs;
                    140: BOOL inside_int14=FALSE;
                    141: 
                    142: /* This function is only necessary for naughty programs that call the vector
                    143:    directly instead of issuing an interrupt 
                    144: */
                    145: void interrupt win95int14(
                    146:        unsigned _es, unsigned _ds,
                    147:        unsigned _di, unsigned _si,
                    148:        unsigned _bp, unsigned _sp,
                    149:        unsigned _bx, unsigned _dx,
                    150:        unsigned _cx, unsigned _ax,
                    151:     unsigned flags )
                    152: {
                    153:        union REGS outregs;
                    154: 
                    155:        /* prevent recursion, just incase the VXD isn't handling int14h */
                    156:        if(inside_int14)        
                    157:                return;
                    158: 
                    159:        inside_int14=TRUE;
                    160: 
                    161:        inregs.x.ax=_ax;
                    162:        inregs.x.bx=_bx;
                    163:        inregs.x.cx=_cx;
                    164:        inregs.x.dx=_dx;
                    165:        inregs.x.si=_si;
                    166:        inregs.x.di=_di;
                    167:        inregs.x.cflag=flags;
                    168: 
                    169:        sregs.es=_es;
                    170:        sregs.ds=_ds;
                    171: 
                    172:        int86x(0x14,&inregs,&outregs,&sregs);
                    173: 
                    174:        /* FOSSIL driver only touches these AX and BX */
                    175:        _ax= outregs.x.ax;
                    176:        _bx= outregs.x.bx;
                    177: 
                    178:        inside_int14=FALSE;
                    179: }
                    180: 
                    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: #ifdef DEBUG_FOSSIL_CALLS
                    217:        DWORD fossil_calls[0x100];
                    218: #endif
                    219: 
                    220: void interrupt winNTint14(
                    221:        unsigned _es, unsigned _ds,
                    222:        unsigned _di, unsigned _si,
                    223:        unsigned _bp, unsigned _sp,
                    224:        unsigned _bx, unsigned _dx,
                    225:        unsigned _cx, unsigned _ax,
                    226:        )
                    227: {
                    228:        BYTE                    ch;
                    229:        BYTE far*               p;
                    230:        WORD                    buf_seg;
                    231:        int                             wr;
                    232:        vdd_status_t    vdd_status;
                    233:     fossil_info_t info = { 
                    234:                 sizeof(info)
                    235:                ,FOSSIL_REVISION
                    236:                ,revision       /* driver revision */
                    237:                ,0                      /* ID string pointer */ 
                    238:                ,0,0            /* receive buffer size/free (overwritten later) */
                    239:                ,0,0            /* transmit buffer size/free (overwritten later) */
                    240:         ,80,25         /* screen dimensions (cols, rows) */
                    241:                                        /* port settings (i.e. 38400 N-8-1): */
                    242:         ,FOSSIL_BAUD_RATE_38400
                    243:                |FOSSIL_PARITY_NONE
                    244:                |FOSSIL_DATA_BITS_8
                    245:                |FOSSIL_STOP_BITS_1
                    246:        };
                    247: 
                    248: #ifdef DEBUG_INT_CALLS
                    249:        int14calls++;
                    250: #endif
                    251: 
                    252: #ifdef DEBUG_FOSSIL_CALLS
                    253:        fossil_calls[_ax>>8]++;
                    254: #endif
                    255: 
                    256:        switch(_ax>>8) {
                    257:                case FOSSIL_FUNC_SET_RATE:      /* Initialize/Set baud rate */
                    258:                        _ax = PortStatus();
                    259:                        break;
                    260:                case FOSSIL_FUNC_PUT_CHAR: /* write char to com port, with wait */
                    261:                        ch=_ax&0xff;
                    262:                        _asm mov buf_seg, ss;
                    263:                        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    264:                        _ax = PortStatus();
                    265:                        break;
                    266:                case FOSSIL_FUNC_GET_CHAR: /* read char from com port, with wait */
                    267:                        _asm mov buf_seg, ss;
                    268:                        _ax = vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
                    269:                        if(!_ax) {
                    270:                                _ax = 0x8000;   /* timed-out */
                    271:                                vdd_op(VDD_YIELD);
                    272:                        } else {
                    273:                                _ax = ch;
                    274:                        }
                    275:                        break;
                    276:                case FOSSIL_FUNC_GET_STATUS:    /* request status */
                    277:                        _ax=PortStatus();
                    278:                        if(_ax==0x6088)
                    279:                                vdd_op(VDD_MAYBE_YIELD);
                    280:                        break;
                    281:                case FOSSIL_FUNC_INIT:  /* initialize */
                    282:                        _ax=FOSSIL_SIGNATURE;   /* magic number = success */
                    283:                        _bx=FOSSIL_REVISION<<8 | FOSSIL_FUNC_HIGHEST;   /* FOSSIL rev/maximum FOSSIL func supported */
                    284:                        break;
                    285:                case FOSSIL_FUNC_DTR:
                    286:                        if((_ax&0xff)==0)       /* Lower DTR */
                    287:                                vdd_op(VDD_HANGUP);
                    288:                        break;
                    289:         case FOSSIL_FUNC_FLUSH_OUT:    /* flush output buffer  */
                    290:                        break;
                    291:         case FOSSIL_FUNC_PURGE_OUT:    /* purge output buffer  */
                    292:                        vdd_op(VDD_OUTBUF_PURGE);
                    293:                        break;
                    294:         case FOSSIL_FUNC_PURGE_IN:     /* purge input buffer   */
                    295:                        vdd_op(VDD_INBUF_PURGE);
                    296:                        break;
                    297:                case FOSSIL_FUNC_WRITE_CHAR:    /* write char to com port, no wait */
                    298:                if(0 /*RingBufFree(&vm->out)<2 */) {
                    299:                _ax=0; /* char was not accepted */
                    300:                 break;
                    301:             }
                    302:                        ch=_ax&0xff;
                    303:                        _asm mov buf_seg, ss;
                    304:                        _ax = vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    305:                        break;
                    306:         case FOSSIL_FUNC_PEEK: /* non-destructive read-ahead */
                    307:                        vdd_getstatus(&vdd_status);
                    308:                        if(!vdd_status.inbuf_full) {
                    309:                                _ax=0xffff;     /* no char available */
                    310:                                vdd_op(VDD_YIELD);
                    311:                                break;
                    312:                        }
                    313:                        _asm mov buf_seg, ss;
                    314:                        _ax = vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
                    315:                        if(_ax == 0)
                    316:                                vdd_op(VDD_YIELD);
                    317:                        break;
                    318:         case FOSSIL_FUNC_READ_BLOCK:   /* read block, no wait */
                    319:                        vdd_getstatus(&vdd_status);
                    320:                        if(!vdd_status.inbuf_full)
                    321:                                _ax = 0; /* no data available */
                    322:                        else
                    323:                                _ax = vdd_buf(VDD_READ, _cx, _es, _di);
                    324:                        if(_ax == 0)
                    325:                                vdd_op(VDD_YIELD);
                    326:                        break;
                    327:         case FOSSIL_FUNC_WRITE_BLOCK:  /* write block, no wait */
                    328:                        _ax = vdd_buf(VDD_WRITE, _cx, _es, _di);
                    329:                        break;
                    330:         case FOSSIL_FUNC_GET_INFO:     /* driver info */
                    331:                        vdd_getstatus(&vdd_status);
                    332:                        info.inbuf_size=vdd_status.inbuf_size;
                    333:                        info.inbuf_free=info.inbuf_size-vdd_status.inbuf_full;
                    334:                        info.outbuf_size=vdd_status.outbuf_size;
                    335:                        info.outbuf_free=info.outbuf_size-vdd_status.outbuf_full;
                    336:                        info.id_string = id_string;
                    337: 
                    338:                        if(vdd_status.inbuf_full==vdd_status.outbuf_full==0)
                    339:                                vdd_op(VDD_MAYBE_YIELD);
                    340: 
                    341:                        p = _MK_FP(_es,_di);
                    342:             wr=sizeof(info);
                    343:             if(wr>_cx)
                    344:                wr=_cx;
                    345:             _fmemcpy(p, &info, wr);
                    346:                _ax=wr;
                    347:             break;
                    348:        }
                    349: }
                    350: 
                    351: void int14stub(void)
                    352: {
                    353:        /* This function will be overwritten later (during runtime) with FOSSIL signature */
                    354: }
                    355: 
                    356: void interrupt winNTint16(
                    357:        unsigned _es, unsigned _ds,
                    358:        unsigned _di, unsigned _si,
                    359:        unsigned _bp, unsigned _sp,
                    360:        unsigned _bx, unsigned _dx,
                    361:        unsigned _cx, unsigned _ax,
                    362:        unsigned _ip, unsigned _cs,
                    363:     unsigned flags )
                    364: {
                    365:        BYTE                    ch;
                    366:        WORD                    buf_seg;
                    367:        vdd_status_t    status;
                    368: 
                    369: #ifdef DEBUG_INT_CALLS
                    370:        int16calls++;
                    371: #endif
                    372: 
                    373:        vdd_getstatus(&status);
                    374:        switch(_ax>>8) {
                    375:        case 0x00:      /* Read char from keyboard */
                    376:         case 0x10:     /* Read char from enhanced keyboard */
                    377:                        if(status.inbuf_full) {
                    378:                                _asm mov buf_seg, ss;
                    379:                                vdd_buf(VDD_READ, 1, buf_seg, (WORD)&ch);
                    380:                                _ax=ch;
                    381:                                return;
                    382:                        } 
                    383:                        vdd_op(VDD_MAYBE_YIELD);
                    384:                        break;
                    385:        case 0x01:      /* Get keyboard status */
                    386:         case 0x11:     /* Get enhanced keyboard status */
                    387:                        if(status.inbuf_full) {
                    388:                                _asm mov buf_seg, ss;
                    389:                                vdd_buf(VDD_PEEK, 1, buf_seg, (WORD)&ch);
                    390:                 flags&=~(1<<6);        /* clear zero flag */
                    391:                 _ax=ch;
                    392:                                return;
                    393:                        }
                    394:                        vdd_op(VDD_MAYBE_YIELD);
                    395:                break;
                    396:        }
                    397: 
                    398:        _chain_intr(oldint16);          
                    399: }
                    400: 
                    401: #ifdef DEBUG_DOS_CALLS
                    402:        DWORD dos_calls[0x100];
                    403: #endif
                    404: 
                    405: void interrupt winNTint21(
                    406:        unsigned _es, unsigned _ds,
                    407:        unsigned _di, unsigned _si,
                    408:        unsigned _bp, unsigned _sp,
                    409:        unsigned _bx, unsigned _dx,
                    410:        unsigned _cx, unsigned _ax,
                    411:        )
                    412: {
                    413: #ifdef DEBUG_INT_CALLS
                    414:        int21calls++;
                    415: #endif
                    416:        if(_ax>>8 == 0x2c)      /* GET_SYSTEM_TIME */
                    417:                vdd_op(VDD_MAYBE_YIELD);
                    418: #ifdef DEBUG_DOS_CALLS
                    419:        dos_calls[_ax>>8]++;
                    420: #endif
                    421:        _chain_intr(oldint21);
                    422: }
                    423: 
                    424: void interrupt winNTint29(
                    425:        unsigned _es, unsigned _ds,
                    426:        unsigned _di, unsigned _si,
                    427:        unsigned _bp, unsigned _sp,
                    428:        unsigned _bx, unsigned _dx,
                    429:        unsigned _cx, unsigned _ax,
                    430:        )
                    431: {
                    432:        char    ch;
                    433:        WORD    buf_seg;
                    434: #ifdef DEBUG_INT_CALLS
                    435:        int29calls++;
                    436: #endif
                    437: 
                    438:        ch=_ax&0xff;
                    439:        _asm mov buf_seg, ss
                    440:        vdd_buf(VDD_WRITE, 1, buf_seg, (WORD)&ch);
                    441: 
                    442:        _chain_intr(oldint29);
                    443: }
                    444: 
                    445: /****************************************************************************/
                    446: /* Return the filename portion of a full pathname                                                      */
                    447: /****************************************************************************/
                    448: char* getfname(const char* path)
                    449: {
                    450:        const char* fname;
                    451:        const char* bslash;
                    452: 
                    453:        fname=strrchr(path,'/');
                    454:        bslash=strrchr(path,'\\');
                    455:        if(bslash>fname)
                    456:                fname=bslash;
                    457:        if(fname!=NULL) 
                    458:                fname++;
                    459:        else 
                    460:                fname=(char*)path;
                    461:        return((char*)fname);
                    462: }
                    463: 
                    464: char * DllName         =VDD_FILENAME;
                    465: char * InitFunc        ="VDDInitialize";
                    466: char * DispFunc        ="VDDDispatch";
                    467: 
                    468: int main(int argc, char **argv)
                    469: {
                    470:        char    str[128];
                    471:        char    cmdline[128],*p;
                    472:        char    dll[256];
                    473:        char    exec_dir[128];
                    474:        char*   envvar[10];
                    475:        char*   arg[16];
                    476:        int             i,c,d,envnum=0;
                    477:        FILE*   fp;
                    478:        BOOL    NT=FALSE;
                    479:        BOOL    success=FALSE;
                    480:        WORD    buf_seg;
                    481:        WORD    w;
                    482: 
                    483:        sscanf("$Revision: 1.23 $", "%*s 1.%u", &revision);
                    484: 
                    485:        sprintf(id_string,"Synchronet FOSSIL Driver (DOSXTRN) revision %u", revision);
                    486:        if(argc<2) {
                    487:                fprintf(stderr
                    488:                        ,"%s - Copyright %s Rob Swindell\n"
                    489:                        ,id_string, __DATE__+7);
                    490:                fprintf(stderr
                    491:                        ,"usage: dosxtrn <path/dosxtrn.env> [NT|95] [node_num] [mode]\n");
                    492:                return(1);
                    493:        }
                    494: 
                    495:        sprintf(exec_dir,"%.*s",sizeof(exec_dir)-1,argv[0]);
                    496:        p=getfname(exec_dir);
                    497:        *p=0;
                    498:        sprintf(dll,"%s%s",exec_dir,VDD_FILENAME);
                    499:        DllName=dll;
                    500: 
                    501:        if(argc>2 && !strcmp(argv[2],"NT")) 
                    502:                NT=TRUE;
                    503:        if(argc>3)
                    504:                node_num=atoi(argv[3]);
                    505:        if(argc>4)
                    506:                mode=atoi(argv[4]);
                    507: 
                    508:        if((fp=fopen(argv[1],"r"))==NULL) {
                    509:                fprintf(stderr,"!Error opening %s\n",argv[1]);
                    510:                return(2);
                    511:        }
                    512: 
                    513:        fgets(cmdline, sizeof(cmdline), fp);
                    514:        truncsp(cmdline);
                    515: 
                    516:        arg[0]=cmdline; /* point to the beginning of the string */
                    517:        for(c=0,d=1;cmdline[c];c++)     /* Break up command line */
                    518:                if(cmdline[c]==' ') {
                    519:                        cmdline[c]=0;                   /* insert nulls */
                    520:                        arg[d++]=cmdline+c+1;   /* point to the beginning of the next arg */
                    521:                }
                    522:        arg[d]=0;
                    523: 
                    524:        while(!feof(fp)) {
                    525:                if(!fgets(str, sizeof(str), fp))
                    526:                        break;
                    527:                truncsp(str);
                    528:                if((envvar[envnum]=strdup(str))==NULL) {
                    529:                        fprintf(stderr,"!MALLOC ERROR\n");
                    530:                        return(4);
                    531:                }
                    532:                _putenv(envvar[envnum++]);
                    533:        }
                    534:        fclose(fp);
                    535: 
                    536:        /* Save int14 handler */
                    537:        oldint14=_dos_getvect(0x14);
                    538: 
                    539:        /* Overwrite stub function */
                    540:        ((BYTE*)int14stub)[0] = 0xe9;   /* jump (relative) */
                    541:        ((BYTE*)int14stub)[3] = 0x90;   /* NOP */
                    542:        ((BYTE*)int14stub)[4] = 0x90;   /* NOP */
                    543:        ((BYTE*)int14stub)[5] = 0x90;   /* NOP */
                    544:        ((BYTE*)int14stub)[6] = FOSSIL_SIGNATURE&0xff;  /* FOSSIL sig (LSB) */
                    545:        ((BYTE*)int14stub)[7] = FOSSIL_SIGNATURE>>8;    /* FOSSIL sig (MSB) */
                    546:        ((BYTE*)int14stub)[8] = FOSSIL_FUNC_HIGHEST;    /* FOSSIL highest func supported */
                    547: 
                    548:        if(NT) {        /* Windows NT/2000 */
                    549: 
                    550:                for(i=0;i<2;i++) {
                    551: 
                    552:                        /* Register VDD */
                    553:                        _asm {
                    554:                                push    es
                    555:                                push    ds
                    556:                                pop             es
                    557:                                mov     si, DllName             ; ds:si = dll name
                    558:                                mov     di, InitFunc    ; es:di = init routine
                    559:                                mov     bx, DispFunc    ; ds:bx = dispatch routine
                    560: #if 1  /* Vista work-around, apparently doesn't support an InitFunc (RegisterModule fails with AX=1) */
                    561:                                xor             di,di
                    562:                                mov             es,di
                    563: #endif
                    564: 
                    565:                        };
                    566:                        RegisterModule();
                    567:                        _asm {
                    568:                                mov             vdd, ax
                    569:                                jc              err
                    570:                                mov             success, TRUE
                    571:                                err:
                    572:                                pop             es
                    573:                        }
                    574:                        if(success)
                    575:                                break;
                    576:                        DllName=VDD_FILENAME;   /* try again with no path (for Windows Vista) */
                    577:                }
                    578:                if(!success) {
                    579:                        fprintf(stderr,"Error %d loading %s\n",vdd,DllName);
                    580:                        return(-1);
                    581:                }
                    582: 
                    583: #if 0
                    584:                fprintf(stderr,"vdd handle=%d\n",vdd);
                    585:                fprintf(stderr,"mode=%d\n",mode);
                    586: #endif
                    587:                vdd_str(VDD_LOAD_INI_FILE, exec_dir);
                    588: 
                    589:                vdd_str(VDD_LOAD_INI_SECTION, getfname(arg[0]));
                    590: 
                    591:                sprintf(str,"%s, rev %u, %s %s", __FILE__, revision, __DATE__, __TIME__);
                    592:                vdd_str(VDD_DEBUG_OUTPUT, str);
                    593: 
                    594:                i=vdd_op(VDD_OPEN);
                    595:                if(i) {
                    596:                        fprintf(stderr,"!VDD_OPEN ERROR: %d\n",i);
                    597:                        UnRegisterModule();
                    598:                        return(-1);
                    599:                }
                    600:                oldint16=_dos_getvect(0x16);
                    601:                oldint21=_dos_getvect(0x21);
                    602:                oldint29=_dos_getvect(0x29);
                    603:                if(mode==SBBSEXEC_MODE_FOSSIL) {
                    604:                        *(WORD*)((BYTE*)int14stub+1) = (WORD)winNTint14 - (WORD)&int14stub - 3; /* jmp offset */
                    605:                        _dos_setvect(0x14,(void(interrupt *)())int14stub); 
                    606:                }
                    607:                _dos_setvect(0x21,winNTint21); 
                    608:                if(mode&SBBSEXEC_MODE_DOS_IN)
                    609:                        _dos_setvect(0x16,winNTint16); 
                    610:                if(mode&SBBSEXEC_MODE_DOS_OUT) 
                    611:                        _dos_setvect(0x29,winNTint29); 
                    612:        }
                    613:        else if(mode==SBBSEXEC_MODE_FOSSIL)     { /* Windows 95/98/Millennium */
                    614:                *(WORD*)((BYTE*)int14stub+1) = (WORD)win95int14 - (WORD)&int14stub - 3;         /* jmp offset */
                    615:                _dos_setvect(0x14,(void(interrupt *)())int14stub); 
                    616:        }
                    617: 
                    618:        _heapmin();
                    619:        i=_spawnvp(_P_WAIT, arg[0], arg);
                    620: 
                    621:        p=argv[1]+(strlen(argv[1])-3);
                    622:        strcpy(p,"RET");
                    623:        if((fp=fopen(argv[1],"w+"))==NULL) {
                    624:                fprintf(stderr,"!Error opening %s\n",argv[1]);
                    625:                return(3);
                    626:        }
                    627:        fprintf(fp,"%d",i);
                    628: 
                    629:        /* Restore original ISRs */
                    630:        _dos_setvect(0x14,oldint14);
                    631: 
                    632:        if(NT) {
                    633:                vdd_op(VDD_CLOSE);
                    634: 
                    635:                _dos_setvect(0x16,oldint16);
                    636:                _dos_setvect(0x21,oldint21);
                    637:                _dos_setvect(0x29,oldint29);
                    638: 
                    639:                sprintf(str,"%s returned %d", arg[0], i);
                    640:                vdd_str(VDD_DEBUG_OUTPUT, str);
                    641: 
                    642: #ifdef DEBUG_INT_CALLS
                    643:                sprintf(str,"int14h calls: %u", int14calls);    vdd_str(VDD_DEBUG_OUTPUT, str);
                    644:                sprintf(str,"int16h calls: %u", int16calls);    vdd_str(VDD_DEBUG_OUTPUT, str);
                    645:                sprintf(str,"int21h calls: %u", int21calls);    vdd_str(VDD_DEBUG_OUTPUT, str);
                    646:                sprintf(str,"int29h calls: %u", int29calls);    vdd_str(VDD_DEBUG_OUTPUT, str);
                    647: #endif
                    648: #ifdef DEBUG_DOS_CALLS
                    649:                for(i=0;i<0x100;i++) {
                    650:                        if(dos_calls[i]>100) {
                    651:                                sprintf(str,"int21h function %02X calls: %u\n"
                    652:                                        ,i, dos_calls[i]);
                    653:                                vdd_str(VDD_DEBUG_OUTPUT, str);
                    654:                        }
                    655:                }
                    656: #endif
                    657: #ifdef DEBUG_FOSSIL_CALLS
                    658:                for(i=0;i<0x100;i++) {
                    659:                        if(fossil_calls[i]>0) {
                    660:                                sprintf(str,"int14h function %02X calls: %u"
                    661:                                        ,i, fossil_calls[i]);
                    662:                                vdd_str(VDD_DEBUG_OUTPUT, str);                 }
                    663:                }
                    664: #endif
                    665: 
                    666:                /* Unregister VDD */
                    667:                _asm mov ax, vdd;
                    668:                UnRegisterModule();
                    669: 
                    670:        }
                    671: 
                    672:        return(i);
                    673: }

unix.superglobalmegacorp.com

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