Beispiel #1
0
/**********************************************************************
 *	    DOSVM_Int25Handler
 *
 * Handler for int 25h (absolute disk read).
 */
void WINAPI DOSVM_Int25Handler( CONTEXT *context )
{
    WCHAR drivespec[] = {'A', ':', '\\', 0};
    BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, context->SegDs, context->Ebx );
    DWORD begin;
    DWORD length;

	//!!
	WORD *stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
	WORD eip = *stack;
	WORD cs = *++stack;
	context->Esp += 4;
	PUSH_WORD16(context, (WORD)context->EFlags);
	PUSH_WORD16(context, cs);
	PUSH_WORD16(context, eip);
	drivespec[0] += AL_reg( context );

    if (GetDriveTypeW( drivespec ) == DRIVE_NO_ROOT_DIR || 
        GetDriveTypeW( drivespec ) == DRIVE_UNKNOWN)
    {
        SET_CFLAG( context );
        SET_AX( context, 0x0201 ); /* unknown unit */
        return;
    }

    if (CX_reg( context ) == 0xffff)
    {
        begin   = *(DWORD *)dataptr;
        length  = *(WORD *)(dataptr + 4);
        dataptr = (BYTE *)CTX_SEG_OFF_TO_LIN( context,
                                              *(WORD *)(dataptr + 8), 
                                              *(DWORD *)(dataptr + 6) );
    }
    else
    {
        begin  = DX_reg( context );
        length = CX_reg( context );
    }

    DOSVM_RawRead( AL_reg( context ), begin, length, dataptr, TRUE );
    RESET_CFLAG( context );
}
Beispiel #2
0
/**********************************************************************
 *         DOSVM_HardwareInterruptRM
 *
 * Emulate call to interrupt handler in real mode.
 *
 * Either calls directly builtin handler or pushes interrupt frame to 
 * stack and changes instruction pointer to interrupt handler.
 */
void DOSVM_HardwareInterruptRM( CONTEXT86 *context, BYTE intnum ) 
{
     FARPROC16 handler = DOSVM_GetRMHandler( intnum );

     /* check if the call goes to an unhooked interrupt */
     if (SELECTOROF(handler) == 0xf000) 
     {
         /* if so, call it directly */
         TRACE( "builtin interrupt %02x has been invoked "
                "(through vector %02x)\n", 
                OFFSETOF(handler)/DOSVM_STUB_RM, intnum );
         DOSVM_CallBuiltinHandler( context, OFFSETOF(handler)/DOSVM_STUB_RM );
     }
     else 
     {
         /* the interrupt is hooked, simulate interrupt in DOS space */ 
         WORD  flag  = LOWORD( context->EFlags );

         TRACE( "invoking hooked interrupt %02x at %04x:%04x\n", 
                intnum, SELECTOROF(handler), OFFSETOF(handler) );

         /* Copy virtual interrupt flag to pushed interrupt flag. */
         if (context->EFlags & VIF_MASK)
             flag |= IF_MASK;
         else 
             flag &= ~IF_MASK;

         PUSH_WORD16( context, flag );
         PUSH_WORD16( context, context->SegCs );
         PUSH_WORD16( context, LOWORD( context->Eip ));
         
         context->SegCs = SELECTOROF( handler );
         context->Eip   = OFFSETOF( handler );

         /* Clear virtual interrupt flag and trap flag. */
         context->EFlags &= ~(VIF_MASK | TF_MASK);
     }
}
Beispiel #3
0
/**********************************************************************
 *         DOSVM_HardwareInterruptPM
 *
 * Emulate call to interrupt handler in 16-bit or 32-bit protected mode.
 *
 * Pushes interrupt frame to stack and changes instruction 
 * pointer to interrupt handler.
 */
void DOSVM_HardwareInterruptPM( CONTEXT86 *context, BYTE intnum ) 
{
    if(DOSVM_IsDos32())
    {
        FARPROC48 addr = DOSVM_GetPMHandler48( intnum );
        
        if (addr.selector == DOSVM_dpmi_segments->int48_sel)
        {
            TRACE( "builtin interrupt %02lx has been invoked "
                   "(through vector %02x)\n", 
                   addr.offset / DOSVM_STUB_PM48, intnum );

            if (intnum == 0x25 || intnum == 0x26)
                DOSVM_PushFlags( context, TRUE, FALSE );
            else if (DOSVM_IsIRQ(intnum))
                DOSVM_PrepareIRQ( context, TRUE );

            DOSVM_BuildCallFrame( context,
                                  DOSVM_IntProcRelay,
                                  DOSVM_GetBuiltinHandler(
                                      addr.offset/DOSVM_STUB_PM48 ) );
        }
        else
        {
            DWORD *stack;
            
            TRACE( "invoking hooked interrupt %02x at %04x:%08lx\n",
                   intnum, addr.selector, addr.offset );
            
            if (DOSVM_IsIRQ(intnum))
                DOSVM_PrepareIRQ( context, FALSE );

            /* Push the flags and return address on the stack */
            stack = CTX_SEG_OFF_TO_LIN(context, context->SegSs, context->Esp);
            *(--stack) = context->EFlags;
            *(--stack) = context->SegCs;
            *(--stack) = context->Eip;
            context->Esp += -12;

            /* Jump to the interrupt handler */
            context->SegCs  = addr.selector;
            context->Eip = addr.offset;
        }
    }
    else
    {
        FARPROC16 addr = DOSVM_GetPMHandler16( intnum );

        if (SELECTOROF(addr) == DOSVM_dpmi_segments->int16_sel)
        {
            TRACE( "builtin interrupt %02x has been invoked "
                   "(through vector %02x)\n", 
                   OFFSETOF(addr)/DOSVM_STUB_PM16, intnum );

            if (intnum == 0x25 || intnum == 0x26)
                DOSVM_PushFlags( context, FALSE, FALSE );
            else if (DOSVM_IsIRQ(intnum))
                DOSVM_PrepareIRQ( context, TRUE );

            DOSVM_BuildCallFrame( context, 
                                  DOSVM_IntProcRelay,
                                  DOSVM_GetBuiltinHandler(
                                      OFFSETOF(addr)/DOSVM_STUB_PM16 ) );
        }
        else
        {
            TRACE( "invoking hooked interrupt %02x at %04x:%04x\n", 
                   intnum, SELECTOROF(addr), OFFSETOF(addr) );

            if (DOSVM_IsIRQ(intnum))
                DOSVM_PrepareIRQ( context, FALSE );

            /* Push the flags and return address on the stack */
            PUSH_WORD16( context, LOWORD(context->EFlags) );
            PUSH_WORD16( context, context->SegCs );
            PUSH_WORD16( context, LOWORD(context->Eip) );

            /* Jump to the interrupt handler */
            context->SegCs =  HIWORD(addr);
            context->Eip = LOWORD(addr);
        }
    }
}