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; }