Annotation of sbbs/src/sbbs3/dosxtrn/dosxtrn.c, revision 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.