⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dos2udip.c

📁 gdb是linux下的一个远程调试环境.能让你很方便地调试linux下的代码.
💻 C
📖 第 1 页 / 共 3 页
字号:
    return NULL;    }static RealUDIVecRecPtr IPCFar * FindIntVect(){    RealUDIVecRecPtr IPCFar * VecP;    union rec recognizer;    InitRecognizer( &recognizer );    /* Try and find a vector that matches the passed in recognizer */    for (VecP =  (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x60*4));	 VecP <= (RealUDIVecRecPtr IPCFar *)(REALPTR_TO_FARCPTR(0x66*4));	 VecP++) {	if ((*VecP != REALNULL) && ((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(*VecP))->recognizer.l == recognizer.l)	    	return VecP;    }         return NULL;}static void SetupEnvironment(void){#ifndef DOS386		/* if not DOS386, nothing to do except set up the		   pointer to TIPVecRec		   */        pTIPVecRec = &TIPVecRec;#else		/* setup code for DOS386 */FARPTR  dummyfp;REALPTR dummyrp;ULONG   dummyint;REALPTR IPCFar *p;REALPTR ptr_dos_ext_psp;int     err;int	i;	/**************************************************************	 * There are some initialization things that we might as well do before	 * we do the realcopy down below.  Here we do some initialization	 * of TIPVecRec and the code_selector and data_selector and call_prot	 * routine address that are then used by the real mode code.	 ****************************************************************/	_dx_rmlink_get(&call_prot, &dummyrp, &dummyint, &dummyfp);	code_selector = GetCS();	data_selector = GetDS();	for (i=0; i<4; i++)	    segregblock[i] = data_selector;		/******************************************************	 * Map first 1 meg of physical memory into our ds: address space	 * This is 256 4K pages starting at physical address 0.	 * The pointer conventional_memory is its mapped offset in our data space	 * If this mapping cannot be done (because we are running under DPMI 0.90)	 * then we will have to access dos memory using far pointers and do some	 * copies of data down in the d386 routines.	 ********************************************************/ 	err = _dx_map_phys(data_selector, (ULONG) 0, (ULONG) 256, (ULONG *)&conventional_memory);	if (err) 	    conventional_memory = NULL;#ifdef DEBUG        if (err) 	    printf("TIP: Unable to map conventional memory %d\n", err);	else 	    printf("TIP: Successfully mapped conventional memory\n");#endif        if (!conventional_memory) {	   /* mapping conventional memory did not work */	   /* need to set up stacks to switch to at UDI call time */	    create_stack(0, 64000);	    create_stack(1, 10000);	    stack_table[2] =  0;	/* end of list */	  }        /* do a realcopy to copy all the things that must be reachable	   * from real mode into a real mode segment.  For simplicity,	   * we just always assume that REALBREAK might not work.	   * This is only used at TIP INIT time and the performance impact is negligent.	   */         err = realcopy(0,    		  /* real mode stuff was linked first */                        end_real,         /* where the real mode stuff ends */			&real_basep,			&prot_basep,			&rmem_adrp);        if (err) {	        printf("\nTIP: realcopy call failed;\n");                printf(  "     Probable cause: insufficient free conventional memory.\n");                do_exit(1);        }        /* The prot_basep that was returned above must now be used	   to access from protected mode the data elements that were	   copied above.  In particular, we create a pointer to the	   copied TIPVecRec and use that.	 */        pTIPVecRec = (struct UDIVecRec IPCFar *) (prot_basep + (ULONG) &TIPVecRec);         	/**************************************************************	 * The real_basep that was returned from realcopy must be used as	 * the code segment pointer of all the real mode routines.	 * and so must be patched into TIPVecRec.	 * real_basep is returned by realcopy such that the offset parts	 * (as assembled in in the module dostip.asm) can remain unchanged.	 * So we just need to patch the real_basep seg into each of those pointers	 ***************************************************************/	for (p = (REALPTR IPCFar *)&pTIPVecRec->exeName;	     p<= (REALPTR IPCFar *)&pTIPVecRec->UDITransMode; p++) {		RP_SET(*p, RP_OFF(*p), RP_SEG(real_basep)); 	}	/*****************************************************	   Store our PSP (real segment) away for later termination	   and also the dos extender's PSP (our parent).  We get this by 	   building a real pointer with seg = our_tsr_psp, ofst = 0x16,	   and then derefencing that	*****************************************************/	our_tsr_psp = GetPSP();	RP_SET(ptr_dos_ext_psp, 0x16, our_tsr_psp);	dos_ext_psp = *((USHORT _far *)(REALPTR_TO_FARCPTR(ptr_dos_ext_psp)));#endif	/* end of DOS386 setup code */}static unsigned int ComputeTSRSize(void *topofstack){#ifndef DOS386	/* Real mode program, compute program size */	/* Huge pointers force compiler to do segment arithmetic for us. */static char _huge *tsrstack;static char _huge *tsrbottom;    /* Initialize stack and bottom of program. */    tsrstack = (char huge *)topofstack;    FP_SEG( tsrbottom ) = _psp;    FP_OFF( tsrbottom ) = 0;    /* Program size is:     *	   top of stack     *	 - bottom of program (converted to paragraphs) (using huge math)     *	 + one extra paragraph     */    return((unsigned int) (((tsrstack - tsrbottom) >> 4) + 1));#else	/*********************	 In DOS386 mode, the TSR size consists of the real memory that	 is used by the Pharlap DOS extender and the small amount of real memory	 used by UDI.  The number 6400 seems to be a good guess for now.	 This might have to be adjusted with newer versions of Dos extender, etc.	 I wonder if there is some way to compute this number accurately.         **********************/	return(6400);	/* our best guess for now */#endif}main(int argc, char *argv[]){    unsigned tsrsize;    get_tip_name(argc, argv);	/* get name from argv or whereever */#ifdef TSRDEBUG    {    int i;    printf( "Invoked with %d arguments\n", argc );    for (i = 0; i < argc; i++)	printf( "%s ", argv[i] );    printf( "\n" );    }#endif    InitRecognizer(&TIPVecRec.recognizer );    SetupEnvironment();		/* do some setup specific to DOS or DOS386 */    /* See if the interrupt vector has already been selected for us */    if ((UDIVecP = FindIntVect()) == NULL) {	if ((UDIVecP = AllocateIntVect()) == NULL)	    return -1;	/* No interrupt vectors available */	}    else {	/* Interrupt vector already allocated */	pTIPVecRec->Next = *UDIVecP;		/* always store a real ptr there */	((struct UDIVecRec IPCFar *) REALPTR_TO_FARCPTR(pTIPVecRec->Next))->Prev = FARCPTR_TO_REALPTR(pTIPVecRec);	}    *UDIVecP = FARCPTR_TO_REALPTR(pTIPVecRec);    tsrsize = ComputeTSRSize(&argv);	/* pass it pointer to argv (top of stack) */    /* We are now ready to support DFEs. If we wish to debug back-ends,       though, we are probably running CodeView with the TIP right now       and don't want to really TSR because CV will shut down at that       point. Instead, let's spawn a new DOS shell from which we can       start a DFE (after setting a breakpoint in the TIP somewhere).    */#ifdef TSRDEBUG    system( getenv( "COMSPEC" ) );#else    do_dos_keep(0, tsrsize);#endif    return 0;}#define GET_PSP_DOS2	0x51#define GET_PSP_DOS3	0x62#define SET_PSP 	0x50static unsigned short GetPSP( void ){    union REGS regs;    if (_osmajor == 2)	return 0;#ifdef DOS386    regs.h.ah = GET_PSP_DOS2;	/* Phar Lap requires we use this to get real segment */#else    regs.h.ah = GET_PSP_DOS3;#endif    intdos( &regs, &regs );    return regs.x.bx;}static void SetPSP( unsigned short PSPSegment ){    union REGS regs;    regs.h.ah = SET_PSP;    regs.x.bx = PSPSegment;    intdos( &regs, &regs );}#ifdef DOS386/*============================ DOS386 glue routines ====================================*//**************************************************************** * In DPMI Compatibility mode, when we get to this point, the only * thing that is on the stack is the saved far stack pointer (which actually * points back to the real mode stack).   Remember in pmstub in dostip.asm, * we switched stack pointers so that SS = DS for C level requirements. * * The INCOMING_PARAMS macro defines a packed structure which expresses what the * real mode stack really looks like when we get to each dos386 glue routine.  * The STACK_PAD is all the extra stuff that was on the stack because of the switching * from real to protected mode, etc. * The packed structure can be used to express where things really are on the stack * because the DFE's MSC compiler will push things differently from the hc386 compiler. ********************************************************************/typedef _packed struct {	FARPTR  ret_to_dosext;	USHORT	zero_word;	USHORT  saved_di;	USHORT  saved_si;	USHORT  saved_bp;	USHORT  saved_ds;	ULONG	ret_to_dfe;} STACK_PAD;/* The following macro defines the packed structure for the incoming parameters * including the STACK_PAD stuff noted above.  It is used by those few d386_ * routines that do not need converted pointers to avoid non-use warnings */#define INCOMING_PARAMS_NO_PTR(params)  \	_packed struct {		\	    STACK_PAD padding;        	\	    params			\	} _far *in  = rm_stk_ptr; 	\/* The following macro defines the packed structure for the incoming parameters * (see above) and also defines a local structure for storing the converted local * pointers.  Most d386_ routines use this macro. */#define INCOMING_PARAMS(params)   	\	INCOMING_PARAMS_NO_PTR(params) 	\	struct {			\	    params			\	    int dummy;     /* to avoid warnings and for local count */          \	} local ;    /* local structure for holding converted pointers */  \	int  stackspace = stacksize;    \/************************************************************** * The following macros handle the creation of near C pointers from real pointers * so that the real UDI routines can be called with near C pointers. * Different macros are called for IN pointers vs. OUT pointers and * for PREPROCESSING (before the real UDI call) and POSTPROCESSING (cleanup * after returning from the real UDI call). * * If conventional_memory has been mapped, the following happens *	PREPROCESS (IN or OUT ptr) sets local.var pointer to the mapped pointer *				   nothing to copy so count is ignored *	POSTPROCESS		   nothing to do  * * If conventional_memory has not been mapped, then *	PREPROCESS (IN ptr) 	   does alloca of count to get local pointer *				   copies data into local allocated area *	PREPROCESS (OUT ptr) 	   does alloca of count to get local pointer *				   no copy of data yet. *	POSTPROCESS (OUT ptr)	   copies data from local allocated area back to real mem *  * Note that a few UDI routines have pointers that are both IN and OUT */	/* the following is used in a couple of places in the macros */#define ALLOC_LOCAL(var, count) \	if ((stackspace -= count) <= 500) return(UDIErrorIPCLimitation); \	local.var = alloca(count); #define INPTR_PREPROCESS_COUNT(var,count)  \    if (conventional_memory) { \	local.var = REALPTR_TO_NEARCPTR(in->var); \    } \    else { \	local.dummy = count;	/* avoid double evaluation if count is expression */   \	ALLOC_LOCAL(var, local.dummy); \	movedata(SS_DOSMEM, LINEARIZE(in->var), data_selector, (unsigned int) local.var, local.dummy); \    } #define INPTR_PREPROCESS(var) INPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))#define OUTPTR_PREPROCESS_COUNT(var,count)  \    if (conventional_memory)  \	local.var = REALPTR_TO_NEARCPTR(in->var); \    else { \	ALLOC_LOCAL(var,count); \    }#define OUTPTR_PREPROCESS(var) OUTPTR_PREPROCESS_COUNT(var, sizeof(*(in->var)))#define OUTPTR_POSTPROCESS_COUNT(var,count)  \    if (!conventional_memory) {\	movedata(data_selector, (unsigned int)local.var, SS_DOSMEM, LINEARIZE(in->var), count); \    }#define OUTPTR_POSTPROCESS(var) OUTPTR_POSTPROCESS_COUNT(var, sizeof(*(in->var)))/* The following routine computes the length of a string that * is pointed to by a real pointer.  This is only needed when * we cannot map real mode memory at the end of the DS. */int realptr_strlen(REALPTR rp) {char _far *farp;char _far *start;    farp = (char _far *) REALPTR_TO_FARCPTR(rp);   /* need to use a far c ptr */    start = farp;    while (*farp++);       /* advance until a 0 located */    return(FP_OFF(farp) - FP_OFF(start));}/*========================  Glue Routines ============================================*/UDIError d386_UDIConnect (void _far * rm_stk_ptr, int stacksize){ INCOMING_PARAMS(  char		*Configuration;		/* In  */  UDISessionId	*Session;		/* Out */  DOSTerm           *TermStruct; 	/* In - not seen in UDIP */)UDIError err;    INPTR_PREPROCESS_COUNT(Configuration, realptr_strlen((REALPTR)(in->Configuration))+1);    OUTPTR_PREPROCESS(Session);     err = UDICConnect(	   /* for UDIConnect, special case, call UDICConnect in dos2udip.c */	local.Configuration,	local.Session,	REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)    );    OUTPTR_POSTPROCESS(Session);    return(err);}UDIError d386_UDIDisconnect (void _far * rm_stk_ptr, int stacksize){INCOMING_PARAMS(  UDISessionId	Session;		/* In */  UDIBool	Terminate;  DOSTerm           *TermStruct; 		/* In - not seen in UDIP */)UDIError err;    local.dummy = 0;                    /* avoids warning */    err = UDICDisconnect(		/* need to call UDICDisconnect */	in->Session,	in->Terminate,	REALPTR_TO_FARCPTR((REALPTR)in->TermStruct)    );    return(err);		}UDIError d386_UDISetCurrentConnection  (void _far * rm_stk_ptr, int stacksize){INCOMING_PARAMS_NO_PTR(  UDISessionId	Session;		/* In */)	return(UDISetCurrentConnection(in->Session));}UDIError d386_UDICapabilities  (void _far * rm_stk_ptr, int stacksize){INCOMING_PARAMS(  UDIUInt32	*TIPId;			/* Out */  UDIUInt32	*TargetId;		/* Out */  UDIUInt32	DFEId;			/* In */  UDIUInt32	DFE;			/* In */  UDIUInt32	*TIP;			/* Out */  UDIUInt32	*DFEIPCId;		/* Out */  UDIUInt32	*TIPIPCId;		/* Out */  char		*TIPString;		/* Out */)UDIError err;    OUTPTR_PREPROCESS(TIPId);    OUTPTR_PREPROCESS(TargetId);    OUTPTR_PREPROCESS(TIP);    OUTPTR_PREPROCESS(DFEIPCId);    OUTPTR_PREPROCESS(TIPIPCId);    OUTPTR_PREPROCESS_COUNT(TIPString, 100);   /* max TIP string? */    err = UDICCapabilities(		/* another special case call UDICapabilities */	local.TIPId,	local.TargetId,	in->DFEId,	in->DFE,	local.TIP,	local.DFEIPCId,	local.TIPIPCId,	local.TIPString    );    OUTPTR_POSTPROCESS(TIPId);    OUTPTR_POSTPROCESS(TargetId);    OUTPTR_POSTPROCESS(TIP);    OUTPTR_POSTPROCESS(DFEIPCId);    OUTPTR_POSTPROCESS(TIPIPCId);    OUTPTR_POSTPROCESS_COUNT(TIPString, strlen(local.TIPString)+1);    return(err);}UDIError d386_UDIGetErrorMsg  (void _far * rm_stk_ptr, int stacksize){INCOMING_PARAMS(  UDIError	ErrorCode;		/* In */  UDISizeT	MsgSize;		/* In */  char		*Msg;			/* Out */  UDISizeT	*CountDone;		/* Out */)UDIError err;    OUTPTR_PREPROCESS_COUNT(Msg, in->MsgSize);    OUTPTR_PREPROCESS(CountDone);        err = UDIGetErrorMsg(	in->ErrorCode,	in->MsgSize,	local.Msg,		/* pointers made local */	local.CountDone    );    OUTPTR_POSTPROCESS_COUNT(Msg, *(local.CountDone)+1);    OUTPTR_POSTPROCESS(CountDone);    return(err);}UDIError d386_UDIGetTargetConfig (void _far * rm_stk_ptr, int stacksize)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -