Skip to content
Snippets Groups Projects
Commit e2a88765 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Remove the last remnants of Win9x/Me support

Allow "FOSSIL Only" as a configuration option for external programs in SCFG. This is a much easier method of disabling the virtual UART support in the Virtual UART/FOSSIL device driver (if/when necessary) than editing the sbbsexec.ini file (which is still supported).
parent c75f5aa3
No related branches found
No related tags found
No related merge requests found
/* dosxtrn.c */
/* Synchronet External DOS Program Launcher (16-bit MSVC 1.52c project) */
/* $Id: dosxtrn.c,v 1.25 2020/04/15 08:22:33 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
......@@ -42,7 +38,6 @@
#include <dos.h> /* _dos_set/getvect() */
#include <windows.h> /* BOOL, etc. */
#include "vdd_func.h"
#include "execvxd.h"
#include "isvbop.h" /* ddk\inc */
#include "fossdefs.h"
#include "../git_branch.h"
......@@ -65,7 +60,6 @@ static void truncsp(char *str)
}
short vdd=0;
BYTE node_num=0;
int mode=0;
char id_string[128];
#ifdef DEBUG_INT_CALLS
ulong int14calls=0;
......@@ -137,48 +131,6 @@ static int vdd_op(BYTE op)
return(retval);
}
union REGS inregs;
struct SREGS sregs;
BOOL inside_int14=FALSE;
/* This function is only necessary for naughty programs that call the vector
directly instead of issuing an interrupt
*/
void interrupt win95int14(
unsigned _es, unsigned _ds,
unsigned _di, unsigned _si,
unsigned _bp, unsigned _sp,
unsigned _bx, unsigned _dx,
unsigned _cx, unsigned _ax,
unsigned flags )
{
union REGS outregs;
/* prevent recursion, just incase the VXD isn't handling int14h */
if(inside_int14)
return;
inside_int14=TRUE;
inregs.x.ax=_ax;
inregs.x.bx=_bx;
inregs.x.cx=_cx;
inregs.x.dx=_dx;
inregs.x.si=_si;
inregs.x.di=_di;
inregs.x.cflag=flags;
sregs.es=_es;
sregs.ds=_ds;
int86x(0x14,&inregs,&outregs,&sregs);
/* FOSSIL driver only touches these AX and BX */
_ax= outregs.x.ax;
_bx= outregs.x.bx;
inside_int14=FALSE;
}
void vdd_getstatus(vdd_status_t* status)
{
......@@ -500,8 +452,8 @@ int main(int argc, char **argv)
char* envvar[MAX_ENVVARS];
char* arg[MAX_ARGS];
int i,c,d,envnum=0;
int mode = SBBSEXEC_MODE_UNSPECIFIED;
FILE* fp;
BOOL NT=FALSE;
BOOL x64=FALSE;
BOOL success=FALSE;
WORD buf_seg;
......@@ -513,7 +465,7 @@ int main(int argc, char **argv)
,"%s - Copyright %s Rob Swindell\n"
,id_string, __DATE__+7);
fprintf(stderr
,"usage: dosxtrn <path/dosxtrn.env> [NT|95|x64] [node_num] [mode]\n");
,"usage: dosxtrn <path/dosxtrn.env> [NT|x64] [node_num] [mode]\n");
return(1);
}
......@@ -524,16 +476,17 @@ int main(int argc, char **argv)
DllName=dll;
if(argc>2) {
if(strcmp(argv[2],"NT") == 0)
NT=TRUE;
else if(strcmp(argv[2],"x64") == 0)
NT=TRUE, x64=TRUE;
if(strcmp(argv[2],"x64") == 0)
x64=TRUE;
}
if(argc>3)
node_num=atoi(argv[3]);
if(argc>4)
mode=atoi(argv[4]);
if(mode == SBBSEXEC_MODE_UNSPECIFIED)
mode = SBBSEXEC_MODE_DEFAULT;
if((fp=fopen(argv[1],"r"))==NULL) {
fprintf(stderr,"!Error opening %s\n",argv[1]);
return(2);
......@@ -574,8 +527,6 @@ int main(int argc, char **argv)
((BYTE*)int14stub)[7] = FOSSIL_SIGNATURE>>8; /* FOSSIL sig (MSB) */
((BYTE*)int14stub)[8] = FOSSIL_FUNC_HIGHEST; /* FOSSIL highest func supported */
if(NT) { /* Windows NT/2000 */
for(i=0;i<2;i++) {
/* Register VDD */
......@@ -621,6 +572,8 @@ int main(int argc, char **argv)
sprintf(str,"%s, rev %u %s/%s, %s %s mode=%u", __FILE__, DOSXTRN_REVISION, GIT_BRANCH, GIT_HASH, __DATE__, __TIME__, mode);
vdd_str(VDD_DEBUG_OUTPUT, str);
if(mode & SBBSEXEC_MODE_UART)
vdd_op(VDD_VIRTUALIZE_UART);
i=vdd_op(VDD_OPEN);
if(i) {
fprintf(stderr,"!VDD_OPEN ERROR: %d\n",i);
......@@ -630,7 +583,7 @@ int main(int argc, char **argv)
oldint16=_dos_getvect(0x16);
oldint21=_dos_getvect(0x21);
oldint29=_dos_getvect(0x29);
if(mode==SBBSEXEC_MODE_FOSSIL) {
if(mode & SBBSEXEC_MODE_FOSSIL) {
*(WORD*)((BYTE*)int14stub+1) = (WORD)winNTint14 - (WORD)&int14stub - 3; /* jmp offset */
_dos_setvect(0x14,(void(interrupt *)())int14stub);
}
......@@ -639,11 +592,6 @@ int main(int argc, char **argv)
_dos_setvect(0x16,winNTint16);
if(mode&SBBSEXEC_MODE_DOS_OUT)
_dos_setvect(0x29,winNTint29);
}
else if(mode==SBBSEXEC_MODE_FOSSIL) { /* Windows 95/98/Millennium */
*(WORD*)((BYTE*)int14stub+1) = (WORD)win95int14 - (WORD)&int14stub - 3; /* jmp offset */
_dos_setvect(0x14,(void(interrupt *)())int14stub);
}
_heapmin();
i=_spawnvp(_P_WAIT, arg[0], arg);
......@@ -659,7 +607,6 @@ int main(int argc, char **argv)
/* Restore original ISRs */
_dos_setvect(0x14,oldint14);
if(NT) {
vdd_op(VDD_CLOSE);
_dos_setvect(0x16,oldint16);
......@@ -698,7 +645,5 @@ int main(int argc, char **argv)
_asm mov ax, vdd;
UnRegisterModule();
}
return(i);
}
/* execvxd.h */
/* Synchronet FOSSIL driver (VxD) for Windows 9x API */
/* $Id: execvxd.h,v 1.1.1.1 2000/10/10 11:26:23 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#define SBBSEXEC_VXD "sbbsexec.vxd"
#define SBBSEXEC_IOCTL_START 0x8001
#define SBBSEXEC_IOCTL_COMPLETE 0x8002
#define SBBSEXEC_IOCTL_READ 0x8003
#define SBBSEXEC_IOCTL_WRITE 0x8004
#define SBBSEXEC_IOCTL_DISCONNECT 0x8005
#define SBBSEXEC_IOCTL_STOP 0x8006
#define SBBSEXEC_MODE_FOSSIL (0)
#define SBBSEXEC_MODE_DOS_IN (1<<0)
#define SBBSEXEC_MODE_DOS_OUT (1<<1)
#define SBBSEXEC_MODE_UART (1<<2)
enum {
SBBSEXEC_ERROR_INUSE=1
,SBBSEXEC_ERROR_INBUF
,SBBSEXEC_ERROR_INDATA
,SBBSEXEC_ERROR_IOCTL
,SBBSEXEC_ERROR_OUTBUF
};
typedef struct {
DWORD mode;
HANDLE event;
} sbbsexec_start_t;
extern HANDLE exec_mutex;
@echo off
xcopy sbbsexec.vxd c:\sbbs\exec
/* DEBUGOUT.H */
/* $Id: debugout.h,v 1.1.1.1 2000/10/10 11:27:22 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#ifndef _DEBUGOUT_H_
#define _DEBUGOUT_H_
#ifndef DEBUG_VAR // Pre-define to use different/dynamic debug enable var
#define DEBUG_VAR 0x1
#endif
#ifndef DEVICENAME // Pre-define to display devicename on output
#define DEVICENAME "DBTRACE"
#endif
#ifndef DBTRACEDPF // Pre-define if using other printf type function
#define DBTRACEDPF dprintf
#endif
#ifndef DBTFILEOFF // Pre-define if __FILE__ offset required != 2
#define DBTFILEOFF 2
#endif
#ifndef TEXT // Windows Unicode support
#define TEXT(x) x
#endif
#ifndef DBTRACENL // Pre-define if \n required
#define DBTRACENL TEXT("")
#endif
#if !defined(DBG) && !defined(DEBUG)
#define DBTRACE(b,s); { /* DBTRACE */ }
#define DBTRACEd(b,s,d); { /* DBTRACE */ }
#define DBTRACEs(b,s,t); { /* DBTRACE */ }
#define DBTRACEx(b,s,x); { /* DBTRACE */ }
#define DBTRACEdd(b,s,x,y); { /* DBTRACE */ }
#define DBTRACEds(b,s,x,y); { /* DBTRACE */ }
#define DBTRACEsd(b,s,x,y); { /* DBTRACE */ }
#define DBTRACEdx(b,s,x,y); { /* DBTRACE */ }
#define DBTRACExd(b,s,x,y); { /* DBTRACE */ }
#define DBTRACExx(b,s,x,y); { /* DBTRACE */ }
#define DBTRACEsx(b,s,x,y); { /* DBTRACE */ }
#define DBTRACExs(b,s,x,y); { /* DBTRACE */ }
#define DBTRACEss(b,s,x,y); { /* DBTRACE */ }
#define DBTRACExxd(b,s,x,y,z); { /* DBTRACE */ }
#define DBTRACEddx(b,s,x,y,z); { /* DBTRACE */ }
#define DBTRACEdds(b,s,x,y,z); { /* DBTRACE */ }
#define DBTRACExdd(b,s,x,y,z); { /* DBTRACE */ }
#define DBTRACExxx(b,s,x,y,z); { /* DBTRACE */ }
#define DBTRACExsx(b,s,x,y,z); { /* DBTRACE */ }
#else /* DBG or DEBUG */
#define DBTRACE(b,s); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s) \
,DBTRACENL); } }
#define DBTRACEd(b,s,d); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ") \
TEXT("%d%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),d \
,DBTRACENL); } }
#define DBTRACEs(b,s,t); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%s%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),t \
,DBTRACENL); } }
#define DBTRACEx(b,s,x); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%02X%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x \
,DBTRACENL); } }
#define DBTRACEdd(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%d %d%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACEds(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%d %s%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACEsd(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%s %d%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACEdx(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%d %X%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACExd(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %d%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACExx(b,s,x,y); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %X%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,y \
,DBTRACENL); } }
#define DBTRACEsx(b,s,t,x); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%s %X%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),t,x \
,DBTRACENL); } }
#define DBTRACExs(b,s,x,t); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %s%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,t \
,DBTRACENL); } }
#define DBTRACEss(b,s,x,t); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%s %s%s") \
,DEVICENAME,TEXT(__FILE__+DBTFILEOFF) \
,__LINE__,TEXT(s),x,t \
,DBTRACENL); } }
#define DBTRACEddx(b,s,x,y,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%d %d %X%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,y,z \
,DBTRACENL); } }
#define DBTRACEdds(b,s,x,y,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%d %d %s%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,y,z \
,DBTRACENL); } }
#define DBTRACExdd(b,s,x,y,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %d %d%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,y,z \
,DBTRACENL); } }
#define DBTRACExxd(b,s,x,y,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %X %d%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,y,z \
,DBTRACENL); } }
#define DBTRACExxx(b,s,x,y,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %X %X%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,y,z \
,DBTRACENL); } }
#define DBTRACExsx(b,s,x,t,z); { if(DEBUG_VAR&(1<<b)) { \
DBTRACEDPF(TEXT("%-8s (%-12.12s %4d): %s: ")\
TEXT("%X %s %X%s") \
,DEVICENAME \
,TEXT(__FILE__+DBTFILEOFF),__LINE__ \
,TEXT(s),x,t,z \
,DBTRACENL); } }
#endif
#endif // Don't add anything after this line
# makefile for SBBSEXEC.VXD
DEVICENAME = SBBSEXEC
FRAMEWORK = CPP
XFLAGS = -I..
OBJECTS = sbbsexec.obj ringbuf.obj
SOURCEINCPATH = ..
DEBUG = 0
DYNAMIC = 1
!include $(VTOOLSD)\include\vtoolsd.mak
!include $(VTOOLSD)\include\vxdtarg.mak
sbbsexec.obj: sbbsexec.cpp makefile
ringbuf.obj: ..\ringbuf.c ..\ringbuf.h
// SBBSEXEC.cpp - SBBSEXEC.VXD main module
/* Synchronet Windows 9X FOSSIL driver (requires VtoolsD C++ framework) */
/* $Id: sbbsexec.cpp,v 1.3 2018/07/24 01:11:52 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#define DEVICE_MAIN
#include "sbbsexec.h"
#include "debugout.h"
#include "..\ringbuf.h"
#define RINGBUF_SIZE_IN 10000
#define RINGBUF_SIZE_OUT 10000
#undef DEVICENAME
#define DEVICENAME "SBBSEXEC" // For debug output
#include LOCKED_CODE_SEGMENT
#include LOCKED_DATA_SEGMENT
#define MAX_VM 250
typedef struct {
VMHANDLE handle;
SEMHANDLE input_sem;
SEMHANDLE output_sem;
DWORD mode;
BOOL online;
BOOL overrun;
RingBuf in;
RingBuf out;
} vm_t;
vm_t vm[MAX_VM];
Declare_Virtual_Device(SBBSExec)
//////////////////////////////////////////////////////////////////////////
#include LOCKED_CODE_SEGMENT
#include LOCKED_DATA_SEGMENT
vm_t* new_vm;
sbbsexec_start_t start;
vm_t* find_vm(VMHANDLE hVM)
{
int i;
for(i=0;i<MAX_VM;i++)
if(vm[i].handle==hVM)
return(&vm[i]);
#if 0
if(hVM!=Get_Sys_VM_Handle()) {
DBTRACEx(0,"!VM NOT FOUND",hVM);
}
#endif
return(NULL);
}
BOOL SBBSExec::OnSysDynamicDeviceInit()
{
DBTRACE(0,"OnSysDynamicDeviceInit");
return(OnDeviceInit(NULL,NULL));
}
BOOL SBBSExec::OnDeviceInit(VMHANDLE hSysVM, PCHAR pszCmdTail)
{
DBTRACE(0,"SBBSExec::OnDeviceInit");
pInt10 = NULL; // BIOS I/O
pInt14 = NULL; // FOSSIL
pInt16 = NULL; // Keyboard input
pInt21 = NULL; // DOS I/O
pInt29 = NULL; // Direct console I/O (PKZIP/UNZIP)
memset(&start,0,sizeof(start));
#if 1
if ( (pInt21 = new SBBSExecInt21()) == NULL) {
DBTRACE(0,"!Failed to create int 21 handler");
UnhookInts();
return(FALSE);
}
if ( !pInt21->hook()) {
DBTRACE(0,"!Failed to hook int 21");
UnhookInts();
return(FALSE);
}
if ( (pInt29 = new SBBSExecInt29()) == NULL) {
DBTRACE(0,"!Failed to create int 29 handler");
UnhookInts();
return(FALSE);
}
if ( !pInt29->hook()) {
DBTRACE(0,"!Failed to hook int 29");
UnhookInts();
return(FALSE);
}
if ( (pInt16 = new SBBSExecInt16()) == NULL) {
DBTRACE(0,"!Failed to create int 16 handler");
UnhookInts();
return(FALSE);
}
if ( !pInt16->hook()) {
DBTRACE(0,"!Failed to hook int 16");
UnhookInts();
return(FALSE);
}
if ( (pInt14 = new SBBSExecInt14()) == NULL) {
DBTRACE(0,"!Failed to create int 14 handler");
UnhookInts();
return(FALSE);
}
if ( !pInt14->hook()) {
DBTRACE(0,"!Failed to hook int 14");
UnhookInts();
return(FALSE);
}
if ( (pInt10 = new SBBSExecInt10()) == NULL) {
DBTRACE(0,"!Failed to create int 10 handler");
UnhookInts();
return(FALSE);
}
if ( !pInt10->hook()) {
DBTRACE(0,"!Failed to hook int 10");
UnhookInts();
return(FALSE);
}
#endif
return TRUE;
}
//****************************************************************************
//****************************************************************************
VOID SBBSExec::OnSystemExit(VMHANDLE hSysVM)
{
DBTRACE(0,"OnSystemExit");
OnSysDynamicDeviceExit();
}
void SBBSExec::UnhookInts()
{
if(pInt10!=NULL) {
pInt10->unhook();
delete pInt10;
pInt10=NULL;
}
if(pInt14!=NULL) {
pInt14->unhook();
delete pInt14;
pInt14=NULL;
}
if(pInt16!=NULL) {
pInt16->unhook();
delete pInt16;
pInt16=NULL;
}
if(pInt21!=NULL) {
pInt21->unhook();
delete pInt21;
pInt21=NULL;
}
if(pInt29!=NULL) {
pInt29->unhook();
delete pInt29;
pInt29=NULL;
}
}
//****************************************************************************
// Handle control message SYS_DYNAMIC_DEVICE_EXIT
//****************************************************************************
BOOL SBBSExec::OnSysDynamicDeviceExit()
{
DBTRACE(0,"OnSysDynamicDeviceExit");
UnhookInts();
return(TRUE);
}
//////////////////////////////////////////////////////////////////////////
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExec::OnCreateVM(VMHANDLE hVM)
{
DBTRACExd(0,"CreateVM, handle, time",hVM,Get_System_Time());
DBTRACEx(0,"Current Thread Handle",Get_Cur_Thread_Handle());
if(start.event) {
new_vm=find_vm(NULL);
if(new_vm==NULL) {
DBTRACE(0,"!NO AVAILABLE VM structures");
return(FALSE);
}
new_vm->handle=hVM;
new_vm->mode=start.mode;
new_vm->online = true;
new_vm->overrun = false;
new_vm->input_sem = NULL;
new_vm->output_sem = NULL;
if(RingBufInit(&new_vm->in, RINGBUF_SIZE_IN)!=0
|| RingBufInit(&new_vm->out, RINGBUF_SIZE_OUT)!=0) {
DBTRACE(0,"!FAILED to create I/O buffers");
return(FALSE);
}
if(!VWIN32_SetWin32Event(start.event)) {
DBTRACEx(0,"!FAILED TO SET EVENT handle", start.event);
return(FALSE);
}
if(!VWIN32_CloseVxDHandle(start.event)) {
DBTRACEx(0,"!FAILED TO CLOSE EVENT handle", start.event);
return(FALSE);
}
start.event=0;
}
return(TRUE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SBBSExecInt29::SBBSExecInt29() : VPreChainV86Int(0x29)
{
DBTRACE(0,"SBBSExecInt29 constructor");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt29::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
vm_t* vm = find_vm(hVM);
if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
return(FALSE); // Tells VMM that interrupt was not handled
}
if(!RingBufFree(&vm->out)) {
DBTRACEx(0,"!Int29 OUTPUT BUFFER OVERFLOW, hVM", hVM);
vm->overrun=true;
return(FALSE);
}
DBTRACEx(1,"Int29 OUTPUT", _clientAL);
BYTE ch=_clientAL;
RingBufWrite(&vm->out,&ch,1);
vm->overrun=false;
return(FALSE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SBBSExecInt21::SBBSExecInt21() : VPreChainV86Int(0x21)
{
DBTRACE(0,"SBBSExecInt21 constructor");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt21::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
BYTE ch;
BYTE* buffer;
WORD buflen;
vm_t* vm = find_vm(hVM);
if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
#if 0
if(vm && !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
DBTRACEx(0,"Int21 on unsupported VM", hVM);
}
#endif
return(FALSE); // Tells VMM that interrupt was not handled
}
DBTRACEx(1,"Int21 function", _clientAH);
DWORD avail = RingBufFree(&vm->out);
switch(_clientAH) {
case 0x01:
DBTRACE(0,"!Int21 Char input WITH echo");
break;
case 0x06: // Direct console I/O
DBTRACEx(0,"DOS DIRECT CONSOLE IO, DL", _clientDL);
if(_clientDL==0xff) {
avail=RingBufFull(&vm->in);
if(avail) {
DBTRACEd(0,"avail",avail);
RingBufRead(&vm->in, &ch, 1);
_clientFlags&=~(1<<6); // clear zero flag
_clientAX=ch;
return(TRUE);
}
break;
}
// fall-through
case 0x02: // Character output
DBTRACEx(1,"Int21 function", _clientAH);
if(!avail) {
DBTRACEx(0,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
vm->overrun=true;
break;
}
ch=_clientDL;
RingBufWrite(&vm->out,&ch,1);
vm->overrun=false;
break;
case 0x09: // Display string
DBTRACE(0,"!Int21 func 09 - DISPLAY STRING");
break;
case 0x0A: // Buffered keyboard input
DBTRACE(0,"Int21 Func 0A - Buffered Keyboard Input");
/* Need to get a string from the user, echo, and copy to DS:DX */
/* byte 0 = max length, byte 1 = actual read (minus CR) */
break;
case 0x40: // Write file or device
if(_clientBX!=1 && _clientBX!=2) { // !stdout and !stderr
DBTRACEd(1,"!Int21 write to unsupported device", _clientBX);
break;
}
DBTRACEdd(1,"Int21 write file", _clientBX, _clientCX);
buffer = (BYTE*)MAPFLAT(CRS.Client_DS, CWRS.Client_DX);
buflen = _clientCX;
if(avail<buflen) {
DBTRACEd(0,"!OUTPUT BUFFER OVERFLOW, avail", avail);
vm->overrun=true;
if(!avail)
break;
buflen=avail;
}
RingBufWrite(&vm->out,buffer,buflen);
vm->overrun=false;
break;
}
return(FALSE); // Tells VMM that interrupt was not handled
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SBBSExecInt16::SBBSExecInt16() : VPreChainV86Int(0x16)
{
DBTRACE(0,"SBBSExecInt16 constructor");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt16::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
BYTE ch;
DWORD avail;
vm_t* vm = find_vm(hVM);
if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_IN)) {
return(FALSE); // Tells VMM that interrupt was not handled
}
// DBTRACExx(0,"Int16 (hVM, AX)", hVM, _clientAX);
avail=RingBufFull(&vm->in);
switch(_clientAH) {
case 0x00: // Read char from keyboard
case 0x10: // Read char from enhanced keyboard
if(avail) {
RingBufRead(&vm->in, &ch, 1);
_clientAX=ch;
return(TRUE);
}
break;
case 0x01: // Get keyboard status
case 0x11: // Get enhanced keyboard status
if(avail) {
RingBufPeek(&vm->in, &ch, 1);
_clientFlags&=~(1<<6); // clear zero flag
_clientAX=ch;
return(TRUE);
}
break;
default:
DBTRACEx(0,"!UNHANDLED INT16 function", _clientAH);
break;
}
return(FALSE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SBBSExecInt14::SBBSExecInt14() : VPreChainV86Int(0x14)
{
DBTRACE(0,"SBBSExecInt14 constructor");
}
WORD PortStatus(vm_t* vm)
{
WORD status=0x0008; // AL bit 3 (change in DCD) always set
if(vm->online) // carrier detect
status|=0x0080; // DCD
if(RingBufFull(&vm->in)) // receive data ready
status|=0x0100; // RDA
if(vm->overrun) // overrun error detected
status|=0x0200; // OVRN
if(RingBufFree(&vm->out)> // room available in output buffer
RINGBUF_SIZE_OUT/2)
status|=0x2000; // THRE
if(!RingBufFull(&vm->out)) // output buffer is empty
status|=0x4000; // TSRE
return(status);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* fossil_id="Synchronet SBBSEXEC.VXD Fossil";
BOOL SBBSExecInt14::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
BYTE* buffer;
BYTE ch;
WORD buflen;
WORD rd,wr;
WORD avail;
vm_t* vm = find_vm(hVM);
if(vm==NULL || vm->mode!=SBBSEXEC_MODE_FOSSIL) {
return(FALSE); // Tells VMM that interrupt was not handled
}
DBTRACEx(4,"Int14 func",_clientAH);
switch(_clientAH) {
case 0x00: /* Initialize/Set baud rate */
DBTRACE(0,"Int14 init");
_clientAX=PortStatus(vm);
break;
case 0x01: /* write char to com port */
if(RingBufFree(&vm->out)<2) {
DBTRACEx(1,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
vm->output_sem=Create_Semaphore(0);
Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
Destroy_Semaphore(vm->output_sem);
vm->output_sem=NULL;
if(!vm->online) {
DBTRACE(0,"!USER HUNG UP");
return(true);
}
}
ch=_clientAL;
RingBufWrite(&vm->out,&ch,1);
#if 0 /* Now done in SBBS.DLL/XTRN.CPP */
if(ch==0xff) { /* escape TELNET IAC */
RingBufWrite(&vm->out,&ch,1);
DBTRACE(1,"Escaped IAC in output stream");
}
#endif
vm->overrun=false;
_clientAX=PortStatus(vm);
break;
case 0x02: /* read char from com port */
if(!RingBufFull(&vm->in)) {
DBTRACEx(0,"Waiting on input semaphore, hVM", hVM);
vm->input_sem=Create_Semaphore(0);
Wait_Semaphore(vm->input_sem,BLOCK_THREAD_IDLE);
Destroy_Semaphore(vm->input_sem);
vm->input_sem=NULL;
#if 0
_clientAH=0x80; /* timed-out */
return(TRUE);
#endif
}
RingBufRead(&vm->in,&ch,1);
_clientAH=0;
_clientAL=ch;
break;
case 0x03: /* request status */
_clientAX=PortStatus(vm);
break;
case 0x04: /* initialize */
DBTRACE(0,"Int14 func 4 init");
_clientAX=0x1954; /* magic number = success */
_clientBH=5; /* FOSSIL rev */
_clientBL=0x1B; /* maximum FOSSIL func supported */
break;
case 0x08: // flush output buffer
DBTRACE(0,"Int14 FLUSH OUTPUT BUFFER");
vm->output_sem=Create_Semaphore(0);
Wait_Semaphore(vm->output_sem,BLOCK_THREAD_IDLE);
Destroy_Semaphore(vm->output_sem);
vm->output_sem=NULL;
break;
case 0x09: // purge output buffer
DBTRACE(0,"Int14 PURGE OUTPUT BUFFER");
RingBufReInit(&vm->out);
break;
case 0x0A: // purge input buffer
DBTRACE(0,"Int14 PURGE INPUT BUFFER");
RingBufReInit(&vm->in);
break;
case 0x0B: /* write char to com port, no wait */
if(RingBufFree(&vm->out)<2) {
_clientAX=0; // char was not accepted
break;
}
ch=_clientAL;
RingBufWrite(&vm->out,&ch,1);
#if 0 /* Now done in SBBS.DLL/XTRN.CPP */
if(ch==0xff) { /* escape TELNET IAC */
RingBufWrite(&vm->out,&ch,1);
DBTRACE(1,"Escaped IAC in output stream");
}
#endif
_clientAX=1; // char was accepted
break;
case 0x0C: // non-destructive read-ahead
if(!RingBufFull(&vm->in)) {
_clientAX=0xffff; // no char available
break;
}
RingBufPeek(&vm->in,&ch,1);
_clientAH=0;
_clientAL=ch;
break;
case 0x13: /* write to display */
dprintf("%c",_clientAL);
break;
case 0x18: /* read bock */
rd=_clientCX;
avail=RingBufFull(&vm->in);
if(rd>avail)
rd=avail;
if(rd) {
buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
rd = RingBufRead(&vm->in, buffer, rd);
}
_clientAX = rd;
break;
case 0x19: /* write block */
wr=_clientCX;
avail=RingBufFree(&vm->out);
if(wr>avail)
wr=avail;
if(wr) {
buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
wr = RingBufWrite(&vm->out, buffer, wr);
}
_clientAX = wr;
break;
#if 1
case 0x1B: // driver info
{
DBTRACE(1,"Int14 driver info");
struct {
WORD info_size;
BYTE curr_fossil;
BYTE curr_rev;
DWORD id_string;
WORD inbuf_size;
WORD inbuf_free;
WORD outbuf_size;
WORD outbuf_free;
BYTE screen_width;
BYTE screen_height;
BYTE baud_rate;
} info={ sizeof(info), 5, 1, 0
,RINGBUF_SIZE_IN-1, RingBufFree(&vm->in)
,RINGBUF_SIZE_OUT-1, RingBufFree(&vm->out)
,80,25
,1 // 38400
};
// Map_Lin_To_VM_Addr
buffer = (BYTE*)MAPFLAT(CRS.Client_ES, CWRS.Client_DI);
wr=sizeof(info);
if(wr>_clientCX)
wr=_clientCX;
memcpy(buffer, &info, wr);
_clientAX=wr;
break;
}
#endif
default:
DBTRACEx(0,"!UNHANDLED INTERRUPT 14h function",_clientAH);
break;
}
return(TRUE); // Tells VMM that interrupt was handled
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SBBSExecInt10::SBBSExecInt10() : VPreChainV86Int(0x10)
{
DBTRACE(0,"SBBSExecInt10 constructor");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BOOL SBBSExecInt10::handler(VMHANDLE hVM, CLIENT_STRUCT* pRegs, DWORD intno)
{
BYTE ch;
DWORD avail;
vm_t* vm = find_vm(hVM);
if(vm==NULL || !(vm->mode&SBBSEXEC_MODE_DOS_OUT)) {
return(FALSE); // Tells VMM that interrupt was not handled
}
avail=RingBufFree(&vm->out);
switch(_clientAH) {
case 0x02: // Set Cursor Position
DBTRACE(1,"Int10 func 2 - Set cursor position");
break;
case 0x09: // Write char and attr at cursor
DBTRACE(1,"Int10 func 9 - Write char and attr at curosr");
case 0x10: // Write char at cursor
#if 0
DBTRACE(1,"Int10 func 9 - Write char at curosr");
if(!avail) {
DBTRACEx(0,"!OUTPUT BUFFER OVERFLOW, hVM", hVM);
vm->overrun=true;
break;
}
ch=_clientAL;
RingBufWrite(&vm->out,&ch,1);
vm->overrun=false;
#endif
break;
}
return(FALSE);
}
DWORD SBBSExec::OnW32DeviceIoControl(PIOCTLPARAMS pIOCTL)
{
DWORD rd;
DWORD wr;
DWORD avail;
vm_t* vm;
// DBTRACEd(0,"SBBSEXEC ioctl"
//,pIOCTL->dioc_IOCtlCode);
switch(pIOCTL->dioc_IOCtlCode) {
case DIOC_OPEN:
DBTRACEd(0,"IOCTL: OPEN",Get_System_Time());
break;
case DIOC_CLOSEHANDLE:
DBTRACEd(0,"IOCTL: CLOSE",Get_System_Time());
break;
case SBBSEXEC_IOCTL_START:
DBTRACEd(0,"IOCTL: START",Get_System_Time());
DBTRACEx(0,"Current Thread Handle",Get_Cur_Thread_Handle());
if(start.event) {
DBTRACE(0,"Exec already started!");
return(SBBSEXEC_ERROR_INUSE);
}
if (pIOCTL->dioc_InBuf==NULL
|| pIOCTL->dioc_cbInBuf!=sizeof(start)) {
return(SBBSEXEC_ERROR_INBUF);
}
start=*(sbbsexec_start_t*)pIOCTL->dioc_InBuf;
break;
case SBBSEXEC_IOCTL_COMPLETE:
DBTRACEd(0,"IOCTL: COMPLETE",Get_System_Time());
if(start.event || new_vm==NULL) {
DBTRACE(0,"!VM never created");
start.event=0;
return(SBBSEXEC_ERROR_INUSE);
}
if(pIOCTL->dioc_OutBuf==NULL
|| pIOCTL->dioc_cbOutBuf<sizeof(VMHANDLE)) {
DBTRACE(0,"!Invalid OUTBUF");
return(SBBSEXEC_ERROR_OUTBUF);
}
*(VMHANDLE*)pIOCTL->dioc_OutBuf=new_vm->handle;
DBTRACEx(0,"CREATED VM HANDLE", new_vm->handle);
new_vm=NULL;
if(pIOCTL->dioc_bytesret!=NULL)
*pIOCTL->dioc_bytesret = sizeof(VMHANDLE);
break;
case SBBSEXEC_IOCTL_READ:
if (pIOCTL->dioc_InBuf==NULL
|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
DBTRACE(0,"!INVALID INBUF");
return(SBBSEXEC_ERROR_INBUF);
}
if (pIOCTL->dioc_OutBuf==NULL || pIOCTL->dioc_cbOutBuf==0) {
DBTRACE(0,"!INVALID OUTBUF");
return(SBBSEXEC_ERROR_OUTBUF);
}
vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
if(vm==NULL) {
DBTRACE(0,"!NO VM LIST");
return(SBBSEXEC_ERROR_INDATA);
}
rd = RingBufFull(&vm->out);
if(rd>pIOCTL->dioc_cbOutBuf) {
DBTRACEdd(0,"Reducing read size"
,rd, pIOCTL->dioc_cbOutBuf);
rd=pIOCTL->dioc_cbOutBuf;
}
RingBufRead(&vm->out, (BYTE*)pIOCTL->dioc_OutBuf, rd);
if(pIOCTL->dioc_bytesret!=NULL)
*pIOCTL->dioc_bytesret = rd;
if(vm->output_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->output_sem);
if(rd>1) {
DBTRACEd(1,"IOCTL_READ bytes", rd);
}
break;
case SBBSEXEC_IOCTL_WRITE:
if (pIOCTL->dioc_InBuf==NULL
|| pIOCTL->dioc_cbInBuf<sizeof(VMHANDLE)+1) {
DBTRACE(0,"!INVALID INBUF");
return(SBBSEXEC_ERROR_INBUF);
}
if (pIOCTL->dioc_OutBuf==NULL
|| pIOCTL->dioc_cbOutBuf!=sizeof(DWORD)) {
DBTRACE(0,"!INVALID OUTBUF");
return(SBBSEXEC_ERROR_OUTBUF);
}
vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
if(vm==NULL) {
DBTRACE(0,"!NO VM LIST");
return(SBBSEXEC_ERROR_INDATA);
}
wr = pIOCTL->dioc_cbInBuf-sizeof(VMHANDLE);
avail = RingBufFree(&vm->in);
if(wr>avail) {
DBTRACEdd(0,"Reducing write size", wr, avail);
wr=avail;
}
RingBufWrite(&vm->in, (BYTE*)pIOCTL->dioc_InBuf+sizeof(VMHANDLE), wr);
*(DWORD *)pIOCTL->dioc_OutBuf = wr;
if(pIOCTL->dioc_bytesret!=NULL)
*pIOCTL->dioc_bytesret = sizeof(DWORD);
if(vm->input_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->input_sem);
// Wake up the VDM (improves keyboard response - dramatically!)
Wake_Up_VM(vm->handle);
break;
case SBBSEXEC_IOCTL_DISCONNECT:
DBTRACEd(0,"IOCTL: DISCONNECT",Get_System_Time());
if (pIOCTL->dioc_InBuf==NULL
|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
DBTRACE(0,"!INVALID INBUF");
return(SBBSEXEC_ERROR_INBUF);
}
vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
if(vm==NULL) {
DBTRACE(0,"!NO VM LIST");
return(SBBSEXEC_ERROR_INDATA);
}
vm->online=false;
if(vm->input_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->input_sem);
if(vm->output_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->output_sem);
break;
case SBBSEXEC_IOCTL_STOP:
DBTRACEd(0,"IOCTL: STOP",Get_System_Time());
if (pIOCTL->dioc_InBuf==NULL
|| pIOCTL->dioc_cbInBuf!=sizeof(VMHANDLE)) {
DBTRACE(0,"!INVALID INBUF");
return(SBBSEXEC_ERROR_INBUF);
}
vm = find_vm(*(VMHANDLE*)pIOCTL->dioc_InBuf);
if(vm==NULL) {
DBTRACE(0,"!NO VM LIST");
return(SBBSEXEC_ERROR_INDATA);
}
DBTRACEx(0,"CLOSING VM HANDLE", vm->handle);
vm->handle=NULL; // Mark as available
RingBufDispose(&vm->in);
RingBufDispose(&vm->out);
if(vm->input_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->input_sem);
if(vm->output_sem!=NULL) // Wake up int14 handler
Signal_Semaphore(vm->output_sem);
vm->input_sem=NULL;
vm->output_sem=NULL;
break;
default:
DBTRACEdx(0,"!UNKNOWN IOCTL"
,pIOCTL->dioc_IOCtlCode,pIOCTL->dioc_IOCtlCode);
return(SBBSEXEC_ERROR_IOCTL);
}
return (0); // DEVIOCTL_NOERROR);
}
// sbbsexec.h - include file for SBBSEXEC
/* Synchronet Windows 9X FOSSIL driver (requires VtoolsD C++ framework) */
/* $Id: sbbsexec.h,v 1.2 2001/05/02 01:58:31 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* Anonymous FTP access to the most recent released source is available at *
* ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
* *
* Anonymous CVS access to the development source and modification history *
* is available at cvs.synchro.net:/cvsroot/sbbs, example: *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login *
* (just hit return, no password is necessary) *
* cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* You are encouraged to submit any modifications (preferably in Unix diff *
* format) via e-mail to mods@synchro.net *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
////////////////////////////////////////////////////////////////////////
// Basic defintions for VToolsD framework
#include <vtoolscp.h>
#define DEVICE_CLASS SBBSExec
#define SBBSExec_DeviceID UNDEFINED_DEVICE_ID
#define SBBSExec_Major 1
#define SBBSExec_Minor 1
#define SBBSExec_Init_Order UNDEFINED_INIT_ORDER
#include "..\execvxd.h" // sbbsexec_start_t definition
#include "..\ringbuf.h" // RingBuf/RingBuffer
////////////////////////////////////////////////////////////////////////
class SBBSExec : public VDevice
{
public:
virtual BOOL OnDeviceInit(VMHANDLE hSysVM, PCHAR pszCmdTail);
virtual BOOL OnSysDynamicDeviceInit();
virtual void OnSystemExit(VMHANDLE hSysVM);
virtual BOOL OnSysDynamicDeviceExit();
virtual BOOL OnCreateVM(VMHANDLE hVM);
virtual DWORD OnW32DeviceIoControl(PIOCTLPARAMS pIOCTL);
void UnhookInts(void);
// Variables
class SBBSExecInt29* pInt29;
class SBBSExecInt21* pInt21;
class SBBSExecInt16* pInt16;
class SBBSExecInt14* pInt14;
class SBBSExecInt10* pInt10;
};
class SBBSExecInt29 : public VPreChainV86Int
{
public:
SBBSExecInt29();
virtual BOOL handler(VMHANDLE, CLIENT_STRUCT*, DWORD);
};
class SBBSExecInt21 : public VPreChainV86Int
{
public:
SBBSExecInt21();
virtual BOOL handler(VMHANDLE, CLIENT_STRUCT*, DWORD);
};
class SBBSExecInt16 : public VPreChainV86Int
{
public:
SBBSExecInt16();
virtual BOOL handler(VMHANDLE, CLIENT_STRUCT*, DWORD);
};
class SBBSExecInt14 : public VPreChainV86Int
{
public:
SBBSExecInt14();
virtual BOOL handler(VMHANDLE, CLIENT_STRUCT*, DWORD);
};
class SBBSExecInt10 : public VPreChainV86Int
{
public:
SBBSExecInt10();
virtual BOOL handler(VMHANDLE, CLIENT_STRUCT*, DWORD);
};
CompanyName = "Company Name"
FileDescription = "VxD File Description"
FileVersion = "Version 1.00"
InternalName = "DEVNAME"
LegalCopyright = "Copyright \251 1995, Company Name. "
OriginalFilename = "device.vxd"
ProductName = "Product Name"
ProductVersion = "Version 1.00"
Translation = 0x409, 0x4E4
......@@ -395,12 +395,10 @@ typedef enum { /* Values for xtrn_t.event */
#define SAVECOLUMNS (1<<22) /* Save/share current terminal width */
#define XTRN_UTF8 (1<<23) /* External program supports UTF-8 */
#define XTRN_TEMP_DIR (1<<24) /* Place drop files in temp dir */
#define XTRN_UART (1<<25) /* Disable the int14h/FOSSIL driver */
#define XTRN_UART (1<<25) /* Enable the virtual UART driver */
#define XTRN_FOSSIL (1<<26) /* Enable the int14h/FOSSIL driver */
#define XTRN_CONIO (1<<31) /* Intercept Windows Console I/O (Drwy) */
/* Bits in cfg.xtrn_misc */
#define XTRN_NO_MUTEX (1<<0) /* Do not use exec_mutex for FOSSIL VXD */
/* Bits in user.qwk */
#define QWK_FILES (1L<<0) /* Include new files list */
#define QWK_EMAIL (1L<<1) /* Include unread e-mail */
......@@ -812,6 +810,7 @@ enum { /* readmail and delmailidx which types */
#define EX_NOECHO XTRN_NOECHO /* Don't echo stdin to stdout */
#define EX_STDIO (EX_STDIN|EX_STDOUT)
#define EX_UART XTRN_UART
#define EX_FOSSIL XTRN_FOSSIL
#define EX_NOLOG (1<<30) /* Don't log intercepted stdio */
#define EX_CONIO (1<<31) /* Intercept Windows console I/O (doorway) */
#define EX_UNSPECIFIED -1
......
......@@ -68,7 +68,7 @@ BYTE uart_divisor_latch_msb = 0x00;
int log_level = LOG_WARNING;
#endif
BOOL virtualize_uart=TRUE;
BOOL virtualize_uart=FALSE;
double yield_interval=1.0;
BOOL hangup_supported=TRUE;
HANDLE hangup_event=NULL;
......@@ -799,6 +799,10 @@ __declspec(dllexport) void __cdecl VDDDispatch(void)
hangup();
break;
case VDD_VIRTUALIZE_UART:
virtualize_uart = TRUE;
break;
default:
lprintf(LOG_ERR,"!UNKNOWN VDD_OP: %d",getBL());
break;
......
......@@ -880,7 +880,7 @@ const char* io_method(uint32_t mode)
static char str[128];
sprintf(str,"%s%s%s"
,mode & XTRN_UART ? "UART"
,mode & XTRN_UART ? "UART" : (mode & XTRN_FOSSIL) ? "FOSSIL"
: (mode & XTRN_STDIO ? "Standard"
: mode & XTRN_CONIO ? "Console": (mode & XTRN_NATIVE ? "Socket" : "FOSSIL or UART"))
,(mode & (XTRN_STDIO|WWIVCOLOR)) == (XTRN_STDIO|WWIVCOLOR) ? ", WWIV Color" : ""
......@@ -892,13 +892,16 @@ void choose_io_method(uint32_t* misc)
{
int k;
switch((*misc) & (XTRN_STDIO|XTRN_UART)) {
switch((*misc) & (XTRN_STDIO|XTRN_UART|XTRN_FOSSIL)) {
case XTRN_STDIO:
k=0;
break;
case XTRN_UART:
k=2;
break;
case XTRN_FOSSIL:
k=3;
break;
default:
k=1;
break;
......@@ -952,15 +955,16 @@ void choose_io_method(uint32_t* misc)
" This setting is not applied when invoking Baja or JavaScript modules.\n"
;
strcpy(opt[1], "FOSSIL or UART");
strcpy(opt[2], "UART");
opt[3][0] = '\0';
strcpy(opt[2], "UART Only");
strcpy(opt[3], "FOSSIL Only");
opt[4][0] = '\0';
}
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"I/O Method"
,opt)) {
case 0: /* Standard I/O */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != XTRN_STDIO) {
if(((*misc) & (XTRN_STDIO|XTRN_UART|XTRN_FOSSIL)) != XTRN_STDIO) {
(*misc) |=XTRN_STDIO;
(*misc) &=~XTRN_UART;
(*misc) &=~XTRN_UART|XTRN_FOSSIL;
uifc.changes = TRUE;
}
k=((*misc) & WWIVCOLOR) ? 0:1;
......@@ -999,16 +1003,23 @@ void choose_io_method(uint32_t* misc)
uifc.changes=TRUE;
}
break;
case 1: /* FOSSIL or Socket */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != 0) {
(*misc) &= ~(XTRN_UART|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
case 1: /* FOSSIL or UART or Socket */
if(((*misc) & (XTRN_STDIO|XTRN_UART|XTRN_FOSSIL)) != 0) {
(*misc) &= ~(XTRN_UART|XTRN_FOSSIL|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
case 2: /* UART */
if(((*misc) & (XTRN_STDIO|XTRN_UART)) != XTRN_UART) {
if(((*misc) & (XTRN_STDIO|XTRN_UART|XTRN_FOSSIL)) != XTRN_UART) {
(*misc) |= XTRN_UART;
(*misc) &= ~(XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
(*misc) &= ~(XTRN_FOSSIL|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
case 3: /* FOSSIL */
if(((*misc) & (XTRN_STDIO|XTRN_UART|XTRN_FOSSIL)) != XTRN_FOSSIL) {
(*misc) |= XTRN_FOSSIL;
(*misc) &= ~(XTRN_UART|XTRN_STDIO|WWIVCOLOR|XTRN_NOECHO);
uifc.changes=TRUE;
}
break;
......
/* VDD_FUNC.H */
/* Synchronet WinNT VDD FOSSIL constant/type definitions */
/* $Id: vdd_func.h,v 1.10 2018/07/24 01:11:08 rswindell Exp $ */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
......@@ -56,6 +52,7 @@ enum {
,VDD_LOAD_INI_SECTION =16
,VDD_DEBUG_OUTPUT =17
,VDD_HANGUP =18
,VDD_VIRTUALIZE_UART =19
};
typedef struct {
......@@ -65,3 +62,10 @@ typedef struct {
DWORD outbuf_size;
DWORD outbuf_full;
} vdd_status_t;
#define SBBSEXEC_MODE_UNSPECIFIED 0
#define SBBSEXEC_MODE_DOS_IN (1<<0)
#define SBBSEXEC_MODE_DOS_OUT (1<<1)
#define SBBSEXEC_MODE_UART (1<<2)
#define SBBSEXEC_MODE_FOSSIL (1<<3)
#define SBBSEXEC_MODE_DEFAULT (SBBSEXEC_MODE_UART | SBBSEXEC_MODE_FOSSIL)
......@@ -261,7 +261,7 @@ static bool native_executable(scfg_t* cfg, const char* cmdline, long mode)
#ifdef _WIN32
#include "execvxd.h" /* DOSXTRN.EXE API */
#include "vdd_func.h" /* DOSXTRN.EXE API */
extern SOCKET node_socket[];
......@@ -292,7 +292,6 @@ static void add_env_var(str_list_t* list, const char* var, const char* val)
/* Clean-up resources while preserving current LastError value */
#define XTRN_CLEANUP \
last_error=GetLastError(); \
if(vxd!=INVALID_HANDLE_VALUE) CloseHandle(vxd); \
if(rdslot!=INVALID_HANDLE_VALUE) CloseHandle(rdslot); \
if(wrslot!=INVALID_HANDLE_VALUE) CloseHandle(wrslot); \
if(start_event!=NULL) CloseHandle(start_event); \
......@@ -327,7 +326,6 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
BOOL processTerminated=false;
uint i;
time_t hungup=0;
HANDLE vxd=INVALID_HANDLE_VALUE;
HANDLE rdslot=INVALID_HANDLE_VALUE;
HANDLE wrslot=INVALID_HANDLE_VALUE;
HANDLE start_event=NULL;
......@@ -478,15 +476,15 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
SAFEPRINTF2(fullcmdline, "%sDOSXTRN.EXE %s", cfg.exec_dir, path);
if(!(mode&EX_OFFLINE)) {
i = SBBSEXEC_MODE_UNSPECIFIED;
if(mode & EX_UART)
i=SBBSEXEC_MODE_UART;
else {
i=SBBSEXEC_MODE_FOSSIL;
i |= SBBSEXEC_MODE_UART;
if(mode & EX_FOSSIL)
i |= SBBSEXEC_MODE_FOSSIL;
if(mode & EX_STDIN)
i |= SBBSEXEC_MODE_DOS_IN;
if(mode & EX_STDOUT)
i |= SBBSEXEC_MODE_DOS_OUT;
}
BOOL x64 = FALSE;
IsWow64Process(GetCurrentProcess(), &x64);
sprintf(str," %s %u %u"
......@@ -646,7 +644,7 @@ int sbbs_t::external(const char* cmdline, long mode, const char* startup_dir)
while(!(mode&EX_BG)) {
if(mode&EX_CHKTIME)
gettimeleft();
if(!online && !(mode&EX_OFFLINE)) { // Tell VXD/VDD and external that user hung-up
if(!online && !(mode&EX_OFFLINE)) { // Tell VDD and external that user hung-up
if(was_online) {
logline(LOG_NOTICE,"X!","hung-up in external program");
hungup=time(NULL);
......
......@@ -1587,6 +1587,8 @@ bool sbbs_t::exec_xtrn(uint xtrnnum)
mode|=EX_CONIO;
else if(cfg.xtrn[xtrnnum]->misc&XTRN_UART)
mode|=EX_UART;
else if(cfg.xtrn[xtrnnum]->misc&XTRN_FOSSIL)
mode|=EX_FOSSIL;
mode|=(cfg.xtrn[xtrnnum]->misc&(XTRN_CHKTIME|XTRN_NATIVE|XTRN_NOECHO|WWIVCOLOR));
if(cfg.xtrn[xtrnnum]->misc&MODUSERDAT) { /* Delete MODUSER.DAT */
SAFEPRINTF(str,"%sMODUSER.DAT",dropdir); /* if for some weird */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment