webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1766回复:7

怎样让我的vxd驱动被系统动态加载?

楼主#
更多 发布于:2004-03-31 14:41
我写了一个驱动是关于键盘的,在98下面,格式为vxd,我写好了可以被静态加载,自己写了一个inf文件,手动更新系统键盘驱动,可以挂上去,但是我希望它被动态加载,不知道该怎么办?

静态加载我用的代码:
public syskb_Control
syskb_Control PROC NEAR

Control_Dispatch INIT_COMPLETE, syskb_Device_Init
Control_Dispatch W32_DEVICEIOCONTROL,_OnW32Deviceiocontrol,cCall,<esi>
clc
ret

syskb_Control ENDP

如希望它被动态加载,我改动如下代码:

public syskb_Control
syskb_Control PROC NEAR

Control_Dispatch SYS_DYNAMIC_Device_Init, syskb_Device_Init
Control_Dispatch W32_DEVICEIOCONTROL,_OnW32Deviceiocontrol,cCall,<esi>
clc
ret

syskb_Control ENDP

也就是说把INIT_COMPLETE改为SYS_DYNAMIC_Device_Init,但是在改后重新编译,CreateFile返回的错误码为2,也就是"系靳找不到指定的
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
沙发#
发布于:2004-03-31 17:39
首先(VXDLDR是系统提供的一个VxD)
    hLoader = CreateFile(
        "\\\\.\\VXDLDR",
        GENERIC_READ,
        FILE_SHARE_READ,
        0,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

然后发送一个VXDLDR_APIFUNC_LOADDEVICE请求加载你的VxD.
szShortName是你的VxD的名字。

    isDone = DeviceIoControl(
        hLoader,
        VXDLDR_APIFUNC_LOADDEVICE,
        (PVOID)szShortName,
        strlen(szShortName)+1,
        NULL,
        0,
        &nRet,
        NULL);
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-03-31 18:56
你说的这种方法,在相关书籍里面好像没有介绍过呀!
按照你的做法,我的驱动应该需要响应请求VXDLDR_APIFUNC_LOADDEVICE,是吗?
响应请求的操作就是加载驱动,也就是syskb_Device_Init,是吗? :(
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地板#
发布于:2004-03-31 19:40
你说的这种方法,在相关书籍里面好像没有介绍过呀!
按照你的做法,我的驱动应该需要响应请求VXDLDR_APIFUNC_LOADDEVICE,是吗?
响应请求的操作就是加载驱动,也就是syskb_Device_Init,是吗? :(


你没有仔细看:
VXDLDR是系统提供的一个VxD,由它来加载你的VxD。当然,你的VxD必须正确处理SYS_DYNAMIC_Device_Init。
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-01 10:27
在编译的过程中发现VXDLDR_APIFUNC_LOADDEVICE没有定义,请问在那里可以找到定义?谢谢
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
5楼#
发布于:2004-04-01 12:21
在编译的过程中发现VXDLDR_APIFUNC_LOADDEVICE没有定义,请问在那里可以找到定义?谢谢


搜一下就知道啦!
VXDLDR.H
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-02 09:31
我按照你的方法没有得到驱动传回的任何消息,以下是驱动源码,也是从网上下载来自己改的
SYSKBDrv.VXD
.386p
.xlist
include vmm.inc
include vwin32.inc
include vkd.inc
include vmd.inc
include debug.inc
;include SYSKBDrv.inc
.list
SCANESCAPE   equ   0E0h
CAPSLOCK       equ   3Ah

VXD_LOCKED_DATA_SEG

Keyboard_Proc dd 0

SwtchPrnKey dd 1

SwtchEscapeAccent dd 0

LeftShiftState dd 0
RightShiftState dd 0

PrintScreenState dd 0

SectionName db "SYSKBDrv", 0

EscKeyName db "escape", 0
PrnKeyName db "printscreen", 0

ForcePreByte db 0E0h, 0

PreCode db 0

VXD_LOCKED_DATA_ENDS
VXD_LOCKED_CODE_SEG

DECLARE_VIRTUAL_DEVICE SYSKBDrv, \
SYSKBDrv_MAJOR_VERSION, \
SYSKBDrv_MINOR_VERSION,        \
SYSKBDrv_Control,,        \
UNDEFINED_INIT_ORDER

public SYSKBDrv_Control
SYSKBDrv_Control PROC NEAR
        
Control_Dispatch SYS_DYNAMIC_Device_Init, SYSKBDrv_Device_Init
Control_Dispatch W32_DEVICEIOCONTROL,_OnW32Deviceiocontrol,cCall,<esi>
clc
ret

SYSKBDrv_Control ENDP

VXD_LOCKED_CODE_ENDS

VXD_PAGEABLE_CODE_SEG



BeginProc SYSKBDrv, Hook_Proc Keyboard_Proc

; get the scancode

        mov     dl, cl
        and     dl, 7Fh

; Trace_Out "Key: #CL"



checkprecode:
cmp cl, SCANESCAPE
jnz MutiCode
mov PreCode, 1

push    edx
mov     edx,30h
cCALL _Postmessage_Proc,edx,PRESERVE_FLAGS
pop     edx
stc ret



MutiCode:
cmp     PreCode,1
jnz     chain
mov     PreCode,0
jnz     chain
push    edx
mov     edx,18h
cCALL _Postmessage_Proc,edx,PRESERVE_FLAGS
pop     edx
jmp chain
                  

chain:
; Trace_Out "---> #CL"
call Keyboard_Proc
clc ; let the key through
ret

EndProc SYSKBDrv

VXD_PAGEABLE_CODE_ENDS
BeginProc SYSKBDrv_Device_Init

; see if the user wants escape-accent grave switched

xor eax, eax ; default == no switch
mov esi, offset32 SectionName
mov edi, offset32 EscKeyName
VMMCall Get_Profile_Boolean
mov SwtchEscapeAccent, eax

; see if the user wants print-key swapped
xor eax, eax
mov esi, offset32 SectionName
mov edi, offset32 PrnKeyName
VMMCall Get_Profile_Hex_Int
mov SwtchPrnKey, eax

; hook the keyboard

GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input
mov esi, offset32 SYSKBDrv
VMMCall Hook_Device_Service
mov Keyboard_Proc, esi
clc
ret

EndProc SYSKBDrv_Device_Init

VXD_ICODE_ENDS

End

SYSKBDrv.c


#include "c:\98ddk\inc\win98\basedef.h"
#include "c:\98ddk\inc\win98\vmm.h"
#include "c:\98ddk\inc\win98\vpicd.h"
#include "c:\98ddk\inc\win98\debug.h"
#include "c:\98ddk\inc\win98\vwin32.h"

DWORD hWnd;
hWnd=0;
char Flag=0;

BOOL OnW32Deviceiocontrol(PDIOCPARAMETERS p)
{
//DPRINTF1(dbgbuf,"W32DevIoControl code=%x\n", p->dwIoControlCode );

switch (p->dwIoControlCode)
{
case DIOC_GETVERSION:
case DIOC_CLOSEHANDLE: // file closed
return 0;

case 4:
       
       *((DWORD *)(p->lpvOutBuffer))=hWnd;
       p->lpcbBytesReturned=4;
       hWnd=0;
       return 0;


case 5:
       if(Flag) Flag=0;
else Flag=1;
hWnd=0;
return 0;

default:
return -1;
}

}


void Postmessage_Proc(DWORD pf)
{
if (Flag)
{
       
hWnd=pf;//&0x7f;//&0x00000fff;
//(*pf)&=0xfbffff00;
//*pf=0;
}

}

编写测试程序

Test.c

#include "stdafx.h"
#include <conio.h>
#include <windows.h>
#include <winioctl.h>
#define VXDLDR_APIFUNC_LOADDEVICE 1
int main(int argc, char* argv[])
{
DWORD junk,event;
char InBuffer[4];
char p[]="SYSKBDrv";
memset(InBuffer,0,4);
hwd=CreateFile("\\\\.\\VXDLDR", GENERIC_READ,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if (hwd == INVALID_HANDLE_VALUE)
{
printf("\nUnable to open VXDLDR device in main program - error %d\n", GetLastError());
return 1;
}

    DeviceIoControl(hwd,VXDLDR_APIFUNC_LOADDEVICE,(PVOID)p,strlen(p)+1,&event, sizeof(event),&junk,NULL);
printf("Get %d bytes\n",junk);
printf("Event happened: %02x\n", event);
return 0;
}


代码太长,还麻烦你指点指点!!
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-02 19:45
为何没有人回答我的问题,我只好自己顶一下啦
游客

返回顶部