阅读:1889回复:7
怎样让我的vxd驱动被系统动态加载?
我写了一个驱动是关于键盘的,在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,也就是"系靳找不到指定的 |
|
沙发#
发布于: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); |
|
|
板凳#
发布于:2004-03-31 18:56
你说的这种方法,在相关书籍里面好像没有介绍过呀!
按照你的做法,我的驱动应该需要响应请求VXDLDR_APIFUNC_LOADDEVICE,是吗? 响应请求的操作就是加载驱动,也就是syskb_Device_Init,是吗? :( |
|
地板#
发布于:2004-03-31 19:40
你说的这种方法,在相关书籍里面好像没有介绍过呀! 你没有仔细看: VXDLDR是系统提供的一个VxD,由它来加载你的VxD。当然,你的VxD必须正确处理SYS_DYNAMIC_Device_Init。 |
|
|
地下室#
发布于:2004-04-01 10:27
在编译的过程中发现VXDLDR_APIFUNC_LOADDEVICE没有定义,请问在那里可以找到定义?谢谢
|
|
5楼#
发布于:2004-04-01 12:21
在编译的过程中发现VXDLDR_APIFUNC_LOADDEVICE没有定义,请问在那里可以找到定义?谢谢 搜一下就知道啦! VXDLDR.H |
|
|
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; } 代码太长,还麻烦你指点指点!! |
|
7楼#
发布于:2004-04-02 19:45
为何没有人回答我的问题,我只好自己顶一下啦
|
|