首页
社区
课程
招聘
[求助]替换键盘中断服务例程相关,求大神解答
发表于: 2015-7-1 11:53 6877

[求助]替换键盘中断服务例程相关,求大神解答

2015-7-1 11:53
6877
通过修改IRQ1的键盘中断服务例程,走自己的程序处理流程,那么有个问题:
1.如果读取了端口的数据,再跳转回原来原来的中断服务例程,这样是不行的,应该数据已经被自己的程序读取,系统通过状态寄存判断的话,是读取不到数据,也就是系统不会有键盘响应,即使你按了按键

2.但是如果自己通过0xD2命令把数据写回端口,又会触发中断,导致死循环的问题,无解中

所以,请教大家,有没有不要jmp回原来的处理例程,又能让系统继续正常的执行下去(让系统能够正常显示所输入的数据,正常响应各种按键)

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 34
活跃值: (734)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
自己顶一下
2015-7-1 12:05
0
雪    币: 96
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可以维护一个向前看队列 来避免死循环,我设置了个较大的数组来完成这些操作具体如下,不过不怎么严谨。有些代码是多余的,貌似按方向键也会有问题,其他情况基本都正常,不妨试试
#include "reioapic.h"
extern KSPIN_LOCK SpinLock;
extern ULONG KiKeyboardInterrupt;
extern ULONG KEYBOARDINTERRUPT;
extern ULONG IDLEINTERRUPTENTRY;

UCHAR PreCh[LOG_PRE_SIZE] = { 0 };
ULONG CurPos = 0;

ULONG TestRead()
{
        ULONG i = 100;
        CHAR ch;
        while (i--)
        {
                ch = READ_PORT_UCHAR(0x64);
                KeStallExecutionProcessor(50);
                if (!(ch&OUTPUTFULL))
                        break;
        }
        if (i)
                return 1;
        return 0;
}

ULONG TestWrite()
{
        ULONG i = 100;
        CHAR ch;
        while (i--)
        {
                ch = READ_PORT_UCHAR(0x64);
                KeStallExecutionProcessor(50);
                if (!(ch&INPUTFULL))
                        break;
        }
        if (i)
                return 1;
        return 0;
}

BOOLEAN InPreCh(UCHAR CurCh)
{
        ULONG i = 0;
        for (i = 0; i < CurPos; i++)
        if (CurCh == PreCh[i])
                return TRUE;
        return FALSE;
}

VOID MoveInPreCh(UCHAR CurCh)
{
        ULONG i = 0;
        for (i = 0; i < CurPos; i++)
        {
                if (PreCh[i] == 0)
                {
                        PreCh[i] = CurCh;
                        return;
                }
        }

        PreCh[CurPos++] = CurCh;
}

VOID MoveOutPreCh(UCHAR CurCh)
{
        LONG i = 0;
        for (i = 0; i < CurPos; i++)
        if (CurCh == PreCh[i])
        {
                PreCh[i] = 0;
                break;
        }
        for (i = CurPos - 1; i >= 0; i--)
        {
                if (PreCh[i] == 0)
                {
                        --CurPos;
                }
                else
                        break;
        }
}

VOID MyPortFilter()
{
        UCHAR CurCh;
        ULONG res = 0;
        KIRQL CurIrql, OldIrql;
        ULONG ProcessorNo = 0;
        CurIrql = KeGetCurrentIrql();
        if (CurIrql < DISPATCH_LEVEL)
        {
                KeAcquireSpinLock(&SpinLock, &OldIrql);
        }
        else
        {
                KeAcquireSpinLockAtDpcLevel(&SpinLock);
        }
        ProcessorNo = KeGetCurrentProcessorNumber();
        //DbgPrint("processor no:%d\n",ProcessorNo);
        //测试是否可读
        while (!res)
        {
                res = TestRead();
        }
        res = 0;
        CurCh = READ_PORT_UCHAR(0x60);
        if (!InPreCh(CurCh))
        {
                DbgPrint("makecode:%x\n", CurCh);
                MoveInPreCh(CurCh);
                while (!res)
                {
                        res = TestWrite();
                }
                res = 0;
                WRITE_PORT_UCHAR(0x64, 0xd2);
                while (!res)
                {
                        res = TestWrite();
                }
                res = 0;
                WRITE_PORT_UCHAR(0x60, CurCh);
        }
        else
        {
                MoveOutPreCh(CurCh);
        }

        if (CurIrql < DISPATCH_LEVEL)
        {
                KeReleaseSpinLock(&SpinLock, OldIrql);
        }
        else
        {
                KeReleaseSpinLockFromDpcLevel(&SpinLock);
        }
}

_declspec(naked) VOID HookKeyboardInterrupt()
{
        __asm
        {
                pushad
                pushfd
                push fs
                mov bx, 0x30
                mov fs, bx
                push ds
                push es
        }

        MyPortFilter();

        __asm
        {
                pop es
                pop ds
                pop fs
                popfd
                popad
                jmp KiKeyboardInterrupt
        }
}
2015-7-1 12:29
0
雪    币: 34
活跃值: (734)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不知道怎么把键值发给系统,这样就不用写回数据了
2015-7-1 13:43
0
雪    币: 34
活跃值: (734)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
为啥都没有人解答呢
2015-7-1 16:36
0
雪    币: 96
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
建议 仔细看下 按键的发生过程 :http://blog.csdn.net/cosmoslife/article/details/7853459
我的认识也不深,但是基于以上 要发给系统按键 应该是需要中断的  所以还是要涉及到端口写。
要不就是模仿那个按键中断去插的dpc,直接手动完成到ps/2键盘按键队列的维护,然后去插那个dpc最后完成退出中断?
2015-7-1 17:20
0
游客
登录 | 注册 方可回帖
返回
//