U5533129@ucsvc.ucs.unimelb.edu.au (CARDIOLOGY, R.M.H.) (08/16/90)
Are there an tricks to linking Turbo C code with Summer '87 Clipper (apart
from compiling in large memory model).
I very much want this piece of code to work, so I can provide decent security
on databases on a network. Is there anything obvious wrong with it?
The program links OK, but falls over under certain conditions (apparantly
when calling the FILE() function, but it's not clear because the problem
goes away if I link in the debugger or put print statements in the code).
(Anyone is welcome to use this code if it can be made to work.)
-------Start of code------
/*
Open read-only databases with Clipper.
Peter Summers - 27/4/90
Sample usage (in a clipper program)
access="**"
call _tryreado
use database
call _testreado with access
if access="RO"
code
else && access="RW"
other code
endif
*/
#include <mem.h>
#include <dos.h>
#define TRAPPEDVECTOR 0x21
#define SPAREVECTOR 0x60
/*
Declaration of the new int 21 routine.
*/
void far interrupt newvector(unsigned BP, unsigned DI, unsigned SI,
unsigned DS, unsigned ES, unsigned DX,
unsigned CX, unsigned BX, unsigned AX,
unsigned IP, unsigned CS, unsigned FLAGS);
/*
Set up the old interrupt on a spare vector and set interrupt 21
to point to the new routine.
*/
void tryreado(void)
{
setvect(SPAREVECTOR,getvect(TRAPPEDVECTOR));
setvect(TRAPPEDVECTOR,newvector);
}
/*
Tests whether an attempt to open a file as read/write has succeeded,
in which case the spare vector will have been set to NULL. Resets
interrupt 21 to its earlier value and returns a string with first
two characters "RW" or "RO". Attempts to write to files opened as
read only will fail, and the clipper program must prevent them.
*/
void testreado(char *access)
{
access[0]='R';
if (getvect(SPAREVECTOR)==NULL)
access[1]='W';
else
{
setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
access[1]='O';
}
}
/*
The new interrupt routine.
*/
static void far interrupt newvector(unsigned BP, unsigned DI, unsigned SI,
unsigned DS, unsigned ES, unsigned DX,
unsigned CX, unsigned BX, unsigned AX,
unsigned IP, unsigned CS, unsigned FLAGS)
{
unsigned oldAX =AX;
/*
Call the old interrupt 21.
*/
_DI = DI;
_SI = SI;
_DS = DS;
_ES = ES;
_DX = DX;
_CX = CX;
_BX = BX;
_AX = AX;
geninterrupt(SPAREVECTOR);
asm pushf
asm pop FLAGS
AX = _AX;
BX = _BX;
CX = _CX;
DX = _DX;
ES = _ES;
DS = _DS;
SI = _SI;
DI = _DI;
/*
If it was an attempt to open a file as read/write, then try again
as read only if the operation failed, or restore the old interrupt
21 if it succeeded.
*/
if ((oldAX & 0xFF03)==0x3D02)
if (FLAGS & 1)
{
/* RW failed, try RO */
_DI = DI;
_SI = SI;
_DS = DS;
_ES = ES;
_DX = DX;
_CX = CX;
_BX = BX;
_AX = 0x3D00;
geninterrupt(SPAREVECTOR);
asm pushf
asm pop FLAGS
AX = _AX;
/* RO failed too, restore vector so the Clipper program can crash
without taking machine down. */
if (FLAGS & 1)
setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
}
else
{
/* RW succeeded, restore the old int 21 routine and set the spare
vector to NULL for testreado to test. */
setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
setvect(SPAREVECTOR,NULL);
}
return;
}