可以是可以,但是还是不太好,因为这方面的资料太少了,你会做不下去的。如果你以前没有用过C开发VXD的话,我建议你还是用C吧!!转贴一篇文章。用 Delphi 编写 VxD 设备驱动程序(转)(sundyl 转贴)  
出处:http://www.chinaasp.com/columns/delphi/article1472.asp正文:用 Delphi 编写 VxD 设备驱动程序(转)关键词:Delphi控件杂项作者:Emil Biserov([email protected])(Russion) 
英语翻译:Vitaly Zayko([email protected]
中文翻译改编:Riceball([email protected]) 前言 
  用 Delphi 3.0 编写 VxD 设备驱动程序,在Delphi 3 下编译通过,Delphi 2 下没有测试,Delphi 4 建立的 Object 文件 M$ Linker 5.12.8181 不能识别,这里使用的汇编器是M$的Macro Assembler ver. 6.11d ,联结器是M$ Incremental Linker ver. 5.12.8181 ,它们来自 Windows 98DDK(http://www.microsoft.com/ddk/ddk98.htm)。 介绍 
  Windows 存在有两种类型的 VxD 设备驱动程序: 
    1、静态(Static) VxD ,装入操作系统并永久的存在于内存中; 
    2、动态(Dynamic) VxD,当需要时才调入内存,用完后关闭VxD即可释放内存。 
  Inprise Delphi 有能力建立任何一种类型的 VxD 设备驱动程序,下面我们将介绍如何建立动态 VxD。 
  当 Win32 应用程序打开一个 VxD “虚拟”设备时,VWIN32 使用 LoadDevice 将 VxD 装入内存,并建立消息W32_DEVICEIOCONTROL ,发向 VxD。 
  也就是说,VxD 至少应该响应以下两个系统信息和编写以下的一个函数: 
    SYS_DYNAMIC_DEVICE_INIT 
    SYS_DYNAMIC_DEVICE_EXIT 
    W32_DEVICEIOCONTROL 函数. 
  消息 SYS_DYNAMIC_DEVICE_INIT 在尝试装入 VxD 时发送到 VxD ,消息 SYS_DYNAMIC_DEVICE_EXIT 在尝试动态交换时发送到 VxD ,消息的处理者在成功处理后,应该在寄存器 AX 中返回 VXD_SUCCESS 标志。   W32_DEVICEIOCONTROL 的 dwService 参数有以下的值: 
    DIOC_OPEN 当 VxD 通过 CreateFile() 函数尝试打开操作时发送(在 SYS_DYNAMIC_DEVICE_INIT 消息后),如果成功返回 NO_ERROR (0);  
    DIOC_CLOSEHANDLE 当 VxD 通过 CloseHandle() 函数尝试关闭操作时发送(在 SYS_DYNAMIC_DEVICE_EXIT 前) 
    所有其它的值 > 0 意味着不同的函数调用(由 dwIoControlCode 给出),当 VxD 被 DeviceIoControl 函数调用时。 启动模块(vxdmain.asm) 
... 
extrn SysDynamicDeviceInit :PROC 
extrn SysDynamicDeviceExit :PROC 
extrn W32DeviceIoControl  :PROC 
... 
                        PUBLIC  DELPHIIO_DDB 
            Public  @@HandleFinally 
            Public  @initialization 
... 
Control_0    proc 
    cmp    eax, SYS_DYNAMIC_DEVICE_INIT 
    jnz    short chkSysDynExit 
    call    SysDynamicDeviceInit 
    cmp    eax, 1 
    retn    
;------------- chkSysDynExit: 
    cmp    eax, SYS_DYNAMIC_DEVICE_EXIT 
    jnz    short chkDevIOCtl 
    call    SysDynamicDeviceExit 
    cmp    eax, 1 
    retn    
;------------- 
chkDevIOCtl: 
    cmp    eax, W32_DEVICEIOCONTROL 
    jnz    short loc_ret 
    push    esi 
    push    edx 
    push    ebx 
    push    ecx 
    call    W32DeviceIoControl 
    cmp    eax, 1 
    retn    
;------------- 
loc_ret: 
    clc    
    retn    Control_0    endp @@HandleFinally: 
@initialization: 
            ret _LTEXT  ends 
                        END   Delphi 会为单元的 initialization/finalization 建立代码调用外部过程 HandleFinaly 和 initialization ,即使 initialization/finalization 在单元中不存在。因此我们在汇编的启动文件中建立空的外部过程入口。 主 Delphi 程序单元(vxdProcs.pas)  
... 
procedure ShellMessage(Handle, Flags : integer; const Message, Caption : PChar;  
  Callback, ReferenceData : pointer); stdcall; assembler; 
asm 
  mov    ebx, Handle        // virtual machine handle 
  mov    eax, Flags        // message box flags 
  mov    ecx, Message        // address of message text 
  mov    edi, Caption        // address of caption text 
  mov    esi, Callback        // address of callback 
  mov    edx, ReferenceData        // reference data for callback   int    20H            // VxDCall 
  dd    170004h            // Shell_Message 
end; function SysDynamicDeviceInit : INTEGER; 
begin 
  ShellMessage(0, $10, Copyright, 'SysDynInit: Hello from Delphi VxD !!!', nil, nil); 
  Result := VXD_SUCCESS; 
end; function SysDynamicDeviceExit : INTEGER; 
begin 
  ShellMessage(0, $10, Copyright, 'SysDynDevExit: Bye from Delphi VxD !!!', nil, nil); 
  Result := VXD_SUCCESS; 
end; function W32DeviceIoControl(dwService : INTEGER; 
                            dwDDB : INTEGER; 
                            hDevice : INTEGER; 
                            lpDIOCParms : pointer) : INTEGER; 
begin 
  ShellMessage(0, $10, Copyright, 'W32DevIOCtl', nil, nil);   if (dwService = DIOC_OPEN) then 
  begin 
      Result := NO_ERROR; 
  end 
  else if (dwService = DIOC_CLOSEHANDLE) then 
  begin 
      Result := VXD_SUCCESS; 
  end 
  else if (dwService > MAX_PASVXD_W32_API) then 
  begin 
      Result := ERROR_NOT_SUPPORTED; 
  end 
    else 
  begin 
      Result := VXD_SUCCESS;  
  end; 
end; 
... 
[译者:好了,简单的 VxD 设备驱动程序编写完毕了。你可以将它当作一个写 VxD 设备驱动程序的模板。] 附一:Make.bat 
D:\VISUAL~1\98DDK\BIN\Win98\ml -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 vxdmain.asm 
call dcc3.bat -J vxdprocs.pas 
D:\VISUAL~1\98DDK\BIN\link /DEF:vxddef.def /VXD vxdmain.obj vxdprocs /OUT:delphiio.vxd 附二: 
现在让我们来编写对该 VxD 的测试程序,两个按钮:一个打开 VxD;一个关闭 VxD。 const 
VxDName = '\\.\DELPHIIO.VXD'; ... function TVxDTestForm.OpenVxDDriver: boolean; 
begin 
HVxDHandle := CreateFile(VxDName,0,0,nil,0,FILE_FLAG_DELETE_ON_CLOSE,0); 
Result := HVxDHandle <> INVALID_HANDLE_VALUE; 
end; procedure TVxDTestForm.CloseVxDDriver; 
begin 
if HVxDHandle <> INVALID_HANDLE_VALUE then begin 
  CloseHandle(HVxDHandle); 
  HVxDHandle := INVALID_HANDLE_VALUE; 
end; 
end 
 
 

解决方案 »

  1.   

    我从一些资料上看过,好像是能写。其实Delphi中也可以用汇编的。
    理论上,Windows上的程序Delphi都能写。当然了Delphi的效率确实比VC稍差。
    我对底层程序没有兴趣,所以,你别问我该怎么写,我不会。另:提问题最好在工作日,工作时间提。那时人气比较旺。
      

  2.   

    ... 
    extrn SysDynamicDeviceInit :PROC 
    extrn SysDynamicDeviceExit :PROC 
    extrn W32DeviceIoControl  :PROC 
    ... 
                            PUBLIC  DELPHIIO_DDB 
                Public  @@HandleFinally 
                Public  @initialization 
    ... 
    Control_0    proc 
        cmp    eax, SYS_DYNAMIC_DEVICE_INIT 
        jnz    short chkSysDynExit 
        call    SysDynamicDeviceInit 
        cmp    eax, 1 
        retn    
    ;------------- chkSysDynExit: 
        cmp    eax, SYS_DYNAMIC_DEVICE_EXIT 
        jnz    short chkDevIOCtl 
        call    SysDynamicDeviceExit 
        cmp    eax, 1 
        retn    
    ;------------- 
    chkDevIOCtl: 
        cmp    eax, W32_DEVICEIOCONTROL 
        jnz    short loc_ret 
        push    esi 
        push    edx 
        push    ebx 
        push    ecx 
        call    W32DeviceIoControl 
        cmp    eax, 1 
        retn    
    ;------------- 
    loc_ret: 
        clc    
        retn    Control_0    endp @@HandleFinally: 
    @initialization: 
                ret _LTEXT  ends 
                            END 
    //***************************
    前面的这一段是什么意思?省略号省略的是:"asm.......end;" 吗??
      

  3.   

    好像不行,微软不授权delphi,但delphi可通过底层实现
      

  4.   

    用Vtoolsd啊!!你不会C语言吗?不用汇编也可以开发Vxd的啊!!Vtoolsd中有很多好的例子!!
      

  5.   

    我是用vtoolsd,而且写vxd的工具我都有了。VTOOLSD只产生框架,用什么来编译?vc++?ddk?编译都不成功。步骤不对吧。指个引吧
      

  6.   

    据我所知,微软禁止其他公司的产品直接写出VXD,就好像WPS要另存为DOC(word),在法律意义上是不容许的。Delphi好像要用什么东西Link一下才行,我也不记得时什么了,网上找找吧!
      

  7.   

    大家看看吧。gezehua(键客)的答案才是真正有建议性的答案!!!!!
      

  8.   

    你先买一本书来看看或者上我告诉你的那个网站,上面有针对使用Vtoolsd的教学。简单的说就是这样的,先用 VC建立一个简单工程,不是MFC的, 名字要和Vtoolsd生成的框架名称相同,例如:
      Vtoolsd生成了以下
      appytime.c
      appytime.h
      appytime.mak
      三个文件,那么你就最好生成名字为appytime的工程。然后制定它的mak文件为appytime.mak。指定它编译生成的文件为appytime.vxd,这样你再把上面的三个文件考到工程文件的目录下,把这三个文件用Addfile(右击生成的工程项)加入到工程中,这样你就可以看到该工程的结构了,然后就可以加入自己的代码并且编译了。
      

  9.   

    为什么Vtoolsd只能装一次?卸了之后,重装就装不上了?
      

  10.   

    听说你要锁键盘,为什么不能用程序呢?
    用程序来封锁键盘,你可以连ctrl+alt+del都封锁啊!!所有的键都不能用,除了用鼠标结束你的程序之外,用什么来结束呢?如果你连鼠标也锁住不就行了!!Vxd也是要加载的呀!!别人如果查到你那个Vxd,一样可以从注册表里把它去掉,再重启就就没有了,动态加载的VXD也是需要一个程序来调用的。 你是怎么协载的?
      

  11.   

    我另外有程序是禁止修改注册表的。这个程序是进驻‘explorer.exe’进程的。她是一个客户机监控程序,在任务栏有图标,有菜单,可用密码退出。进入windows时禁止ctrl+alt+del只是想确保我的这个程序的运行。我的程序运行后,就解开。你可以连ctrl+alt+del封锁吗? 
      

  12.   

    我的VXD打算静态加载。它的任务只是让人在进入windows时,用ctrl+alt+del妨碍我的主程序运行
      

  13.   

    不用Ctrl+Alt+Del也可以结束你主程序,这样的工具一大堆,比如RunIt,只需要点鼠标就可以结束你的程序了。如果你只是想让别人在Ctrl+Alt+Dle弹出的任务列表中结束不掉你的程序,隐藏进程不就可以了。屏蔽系统键:
    var 
      tempint:Integer;
    begin
      SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,@tempint,0);
    end;恢复
    var
      tempint:Integer;
    begin
      SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,@tempint,0);
    end; 
      

  14.   

    第一:我的程序只针对一般的计算机使用者;他们是不可以安装其他东西的。所以,使用高级方法
        (使用工具)可以不予考虑第二:你的方法完全不起作用;原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完
    全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还
    没有执行到,就根本不起作用。如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)
    不知可行否?)。请多指教。。
      

  15.   

    第一:我的程序只针对一般的计算机使用者;他们是不可以安装其他东西的。所以,使用高级方法
        (使用工具)可以不予考虑第二:你的方法完全不起作用;原因:在进入windows时,一般的程序是要先加载后,才执行过程的。也就是说在你的程序还不完
    全加载时,按下ctrl+alt+del,你的程序是完全暴露的,你的所有的隐藏程序过程和锁键盘过程还
    没有执行到,就根本不起作用。如果使用vxd,它可以在注册表里注册,由系统来加载,不使用进程的形式,ctrl+alt+del也就不起作用了。在vxd中放入我们的过程,vxd在加载时执行就行了。(后面一段,只是我个人认为)
    不知可行否?)。请多指教。。
      

  16.   

    你好像还没有转过弯来,等会儿我给你做一个程序(不用VXD),看你怎样只用Ctrl+Alt+Del的方式结束它。把你的Email给我。
      

  17.   

    我试了,你说的第二种情况是对的。你不能用“另外有程序是禁止修改注册表的。这个程序是进驻‘explorer.exe’进程的。她是一个客户机监控程序,在任务栏有图标,有菜单,可用密码退出。”这个程序来禁止系统键吗?
      

  18.   

    不是,是用来禁止打开regedit的,还有其他的功能,如服务请求。
      

  19.   

    已进入青色桌面(无图标),你就无断按ctrl+alt+del , 然后又取消,反复作,就一定能看到
    你要关程序了。只要她是进程,就一定能被关掉(用这种方法)
      

  20.   

    [email protected]  
    [email protected]
      

  21.   

    你如果使用VXD并不好,有很多麻烦的地方,第一,你必须监视你的程序是否被调用,一旦被调用那么就必须封锁键盘,当你的程序完成隐藏后,要通知VXD,告诉他可以不再封锁键盘了。第二,你要处理用户的注销问题。因为他如果注销的话,那么你的程序就会重新启动。这时你的VXD要重复上述过程。注:VXD调用API函数比较麻烦。
      

  22.   

    TO summernightrain(夏夜雨)
    这也是没办法中的办法,只能从根本上去解决问题,只有vxd不属于进程。难作,也是必须要作的,不可回避。我是知道,这个是不可回避的。我问这么多只有两个目的,那就是
    第一:除了vxd外,有没有第二种方法。
    第二:如不得已而用vxd的话,有没有作vxd得捷径,因为我对vc++不熟,既学vc++,又学vxd,达到目的的周期太长。如果,delphi能作,就勉强用一用。起码不用重新去学一门语言。当然,如果能得到你的建议(或帮助)最好。在此,我谢谢你的建议。。
      

  23.   

    回答:
      1,可否考虑用钩子来处理,写一个Explorer要调用的钩子,然后再这个Dll中调用你要启动的程序,然后进行封锁键盘。
      2,如果要学VXD的话,只开发键盘方面的,基本可以不需要C++,会C就可以了。VC++你只需要学习如何用它来编译你的 C版本的VXD就可以了。不知道你看了Vtoolsd的例子没有,它里面有两部分的例子分别是C和C++的(当然不是一样的)。我以前用它来做的硬盘隐藏就是用C编的。关于什么时候该用C什么时候该用C++,我可以说在开发VXD的时候大部分情况都是你想用什么就用什么!
      

  24.   

    To:summernightrain(夏夜雨) 
    你的东东太多,我也一下糊涂了。
    用Dephi做Vxd的也看过一些,差不多很烦。调用也麻烦。
      

  25.   

    To:summernightrain(夏夜雨) 
    "Explorer要调用的钩子",这句话的意思不就是用Explorer来调用自己的dll吗?怎么用Explorer来调用自己的dll?Explorer能调用吗?我真有点不可思议。怎么做?你能给我讲一讲。