Changjiang的专栏

孤帆远影碧空尽,唯见长江天际流。

赵世平ID:Changjiang
[修改头像]
17664次访问,排名5663(1)好友0人,关注者0
Changjiang的文章
原创 8 篇
翻译 2 篇
转载 0 篇
评论 6 篇
最近评论
wangqinghua1:很有收获,文风简洁
fantasyzzz:老师好,我是今天和您联系请教学习汇编方法的您的学生,我以前一直学习的是8086的汇编语言,不过也可以理解您上面的Win32ASM程序示例的大意,我已经对8086的汇编程序编写有一定的掌握,熟悉汇编的编写方法了,而且我现在还在看8086的教材巩固,我想问的是这个过程是否可以跳过,放下8086的学习,直接学习Win32的汇编。不知道这里请教合适么?谢谢老师。。
royelee:当年也是玩crack的啊?
还是原来用trw2k的时代爽啊。
Changjiang:呵呵,这个BLOG是去年开的,一直没有用,这几天正好有空,放上了一点文章。最近还好么,支持你。
flier:正是应了微软 3.0 那个说法,CLI 一直出到第三版,才算是基本上完成了预先的设想,把从一开始就规划进去的那些坑都填上,也腾出了精力去折腾相对来说更实际一些的 WinFX。等 Enterprise Library 那套东东再成熟一点,针对 Java 阵营的进攻号角才算真正吹向。
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes
文章分类
收藏
    相册
    好友的BLOG
    孟岩的BLOG
    自己的其他BLOG
    Changjiang的另一个BLOG:TBsoft工作室的BLOG
    存档

    翻译 Windows 95虚拟设备驱动程序(VxD)

    新一篇: 浅谈设备驱动程序回调Win32应用程序

    Windows 95虚拟设备驱动程序(VxD

     

     

    2005修订版,翻译自Windows 95 DDK,部分内容根据Windows Me DDK修订或者注释。本文档适用于Windows 9x,包括Windows 9598Me,不适用于Windows NT2000XP及其以后版本)

     

     

    原著:Microsoft

     

    翻译:TBsoft Software Studio1998

     

    修订TBsoft Software Studio2005

     

     

    1 VxD介绍

     

     

    本文介绍VxD的作用。如果Windows 95提供的标准VxD对你的硬件或者软件不能提供100%的兼容支持,你需要为你的硬件或者软件(包括16位和32位软件)创建VxD。如果你想让Windows用户使用你的硬件或者软件的某些新特征,你也可以创建VxD

     

    本文介绍如何写VxD,讲述了创建VxD所需的结构、过程和调用,还给出了创建和测试VxD的步骤。VxD可以是静态的或者动态装载的,下面的内容主要讲述静态VxD,不过关于格式和功能的内容两者都适用。

     

     

    2 什么是VxD

     

     

    VxD是一个管理例如硬件设备或者已安装软件等系统资源的32位可执行程序,使得几个应用程序可以同时使用这些资源。Windows通过使用VxD允许基于Windows的应用程序实现多任务。VxD在与Windows的连接工作中处理中断,并在不影响其它应用程序的执行的情况下为特定的应用程序执行I/O操作。

     

    大多数VxD管理硬件设备,也有一些VxD管理或代替与之相关的软件,例如ROM BIOS例程。VxD可以包含必须在相应设备上执行的设备相关代码,也可以依靠其它软件去执行这些对设备的操作。任何情况下,VxD都会为每一个应用程序保留该设备状态的记录,保证无论何时一个应用程序继续执行该设备均处于正确状态。

     

    一些VxD仅仅管理已安装软件,例如MS-DOS设备驱动程序或者TSR程序,这样的VxD通常包含仿真这些软件或者保护这些软件用于正在运行的应用程序的数据的代码。VxD有时还用于提高已安装软件的性能,Intel兼容CPU执行32位的VxD比执行16位的MS-DOS设备驱动程序或者TSR程序有更高的效率。

     

     

    3 标准VxD

     

     

    Windows包括多种VxD,用于支持公共硬件设备和可安装软件。在某些情况下,可能需要修改VxD以提供新的特征或者支持非标准硬件。

     

    Windows提供许多不准备修改,但能够辅助支持其他VxDVxD。例如:许多VxD使用V86内存管理器(V86MMGR)和虚拟可编程中断控制器设备(VPICD)提供的功能保存V86模式内存和允许硬件中断请求。

     

    要取得开发VxD的帮助,Windows 95设备驱动程序开发工具包(DDK(现在可以直接使用Windows 98 DDK或者Windows Me DDK——译者注)包括了大量可用设备驱动程序的源代码。

     

     

    4 创建VxD

     

     

    你可以通过修改VxD例子程序或者自己手工创建来创建VxD。你可以用汇编语言来写VxD,也可以用高级语言(例如C语言)来写一部分VxD

     

    要创建一个VxD,需要以下步骤:

     

    1、阅读硬件手册中关于描述这种型号硬件VxD的章节。

     

    2、写出所需的控制过程,VxD服务和API函数。

     

    3、建立为VxD标识适当模块名的模块定义文件,并引出需要的设备描述块。

     

    4、汇编连接VxD

     

    5、用调试版Windows 95测试VxD,要获得更多关于调试VxD的信息,请参阅相关资料(可以用Soft-ICE调试——译者注)。

     

    6、为VxD和相关文件建立安装文件(INF文件),通过修改注册信息和向WindowsSYSTEM目录和相关目录拷贝文件来安装VxD

     

    7、建立最终发行软件包。

     

     

    5 你需要怎样开始

     

     

    本文假定你是一位有经验的汇编语言程序员,而且熟悉Intel兼容处理器的指令集和系统结构。在某些特殊情况下,你还应该懂得下列内容:

     

     

    保护模式和虚拟8086(即V86——译者注)模式。

     

    平坦内存模式

     

    中断和异常处理

     

    保护和特权级

     

    段和页式内存管理以及错误处理

     

    输入和输出保护以及错误处理

     

     

    本文也假定你已经熟练了解专门硬件的特征和相应的ROM BIOS例程以及其他可安装软件。

     

     

    6 写一个VxD

     

     

    许多情况下,写一个VxD用来代替一个由Windows 95提供的标准VxD。然而,大多数情况下,写一个VxD是用来支持新硬件设备或者软件的,在这种情况下,通常手工创建一个VxD比修改已经存在的VxD要容易,原因是大多数VxD都是设备相关的。然而,已存在VxD的源代码需要尽可能地仔细分析,原因是它们可能包含通用的格式和结构,以及说明怎样使用VMMVxD服务去实现有用的功能。

     

    写一个VxD需要下列步骤:

     

    1、建立包含VxD各个段,VxD声明,设备控制过程,处理系统控制消息过程的基本部分和API过程的基本部分的VxD框架。

     

    2、加入实模式初始化过程(可选)。

     

    3、完成处理初始化消息的过程。这些过程应该能够初始化控制块,分配全局内存以及安装中断、I/O捕获和页错误回调过程。

     

    4、完成处理不同中断和错误的回调过程。

     

    5、为服务加入服务表定义和声明(可选)。

     

    6、完成API过程(可选)

     

    7、完成处理系统控制消息的过程以建立和删除虚拟机。

     

    在写一个VxD的过程中,你可以安装该VxD并在调试器控制下运行Windows,在该VxD中设置断点监视该VxD管理的中断,这样可以帮助你查明该VxD是否正确工作。

     

     

    6.1 VxD

     

     

    VxD可以包含下面5个段的一些组合:

     

    1VxD_CODE段:保护模式代码段(必须)。该段包含VxD系统控制过程、回调过程、服务和API过程。该段用宏VxD_CODE_SEGVxD_CODE_ENDS定义开始和结束,也可命名为_LTEXT

     

    2VxD_DATA段:保护模式数据段(必须)。该段包括设备描述表、服务表和部分VxD全局数据。该段用宏VxD_DATA_SEGVxD_DATA_ENDS定义开始和结束,也可命名为_LDATA

     

    3VxD_ICODE段:保护模式初始化代码段(可选)。该段一般包括只在VxD初始化过程中使用的过程和服务,VMMInit_Complete消息发生后丢弃此段。该段用宏VxD_ICODE_SEGVxD_ICODE_ENDS定义开始和结束,也可命名为_ITEXT

     

    4VxD_IDATA段:保护模式初始化数据段(可选)。该段一般包括初始化过程和服务使用的数据,VMMInit_Complete消息发生后丢弃此段。该段用宏VxD_IDATA_SEGVxD_IDATA_ENDS定义开始和结束,也可命名为_IDATA

     

    5VxD_REAL_INIT段:实模式初始化段(可选)。该段包含实模式初始化过程和数据,VMM在装载VxD其它部分之前调用此过程,过程返回后丢弃此段,该段用宏VxD_REAL_INIT_SEGVxD_REAL_INIT_ENDS定义开始和结束,也可命名为_RTEXT

     

    除实模式初始化段以外,所有代码和数据段均为32位平坦内存模式的保护模式段,这就是说定义在保护模式段中的过程和数据均为32位的偏移量。当VMM装载VxD时,按照VxD在内存中的实际位置修正所有的偏移量。因此,在保护模式段中使用普通OFFSET命令(伪操作,下同——译者注)处应该使用OFFSET32宏,OFFSET32宏定义的偏移量为连接器确定了正确的偏移量修正信息。

     

    VxD不能改变CSDSESSS段寄存器,VxD能够使用FSGS段寄存器。

     

     

    6.2 保护模式指令

     

     

    VxD的源程序文件必须以.386p命令开始,以通知汇编器允许保护模式指令。虽然VxD工作在0特权级,但也不应该用保护模式指令去修改CPU的运行,例如修改全局描述符或中断描述符以及修改任务状态段或寄存器,这样做可能会对Windows运行有不利影响。唯一的例外情况是当该VxD为虚拟数学协处理器设备驱动程序(VMCPD),允许修改CR0寄存器中的80387位。

     

     

    6.3 包含(Include)文件

     

     

    包含文件定义了VxD需要的宏、结构、符号和服务表,用于声明段和过程以及使用VMM和其它VxD服务。下面是每个包含文件包含的公共服务定义、宏和符号定义列表:

     

    1VMM.INC:包含所有的VMM服务以及所需的宏和符号,例如Declare_Virtual_DeviceVMMCall

     

    2DEBUG.INC:包含在调试终端上输出信息和执行各种数据检查的宏。这些宏的功能由定义了调试符号的VxD在汇编时该文件生成的代码实现。

     

    3VPICD.INC:包含为虚拟可编程中断控制器设备(VPICD)定义的所有服务、宏和符号。VPICD处理所有的中断,所以许多VxD需要VPICD服务。

     

    4SHELL.INC:包含虚拟外壳设备提供的公共服务的定义。虚拟外壳设备提供对例如MessageBox这样的Windows函数的调用,可以让VxD显示对话框。

     

     

    6.4 VxD声明

     

     

    每一个VxD都要声明一个名称、一个版本号、一个初始化顺序和一个设备控制过程,许多虚拟设备驱动程序还声明一个设备标识和一些API过程。VxD一般使用Declare_Virtual_Device宏来实现这些声明,例如:

     

    Declare_Virtual_Device VSAMPLED, 4, 0, VSAMPLED_Control, \

     

           VSAMPLED_Device_ID, VSAMPLED_Init_Order, \

     

           VSAMPLED_V86_API_Handler, \

     

           VSAMPLED_PM_API_Handler

     

    本例声明了一个VxD实例——VSAMPLED V4.0,在对应的源文件必须定义名字为VSAMPLED_Control的设备控制过程。符号VSAMPLED_Device_IDVSAMPLED_Init_Order说明非标准VxD的标识和初始化顺序,该VxD支持V86模式和保护模式API过程。

     

    VMM用宏定义的信息来初始化VxD并发送系统控制消息给VxD,并且允许MS-DOS应用程序、设备驱动程序和TSR调用VxD。为了使VMM存取这些信息,相应的宏建立一个设备描述块(DDB)并将其保存在保护模式数据段中(DDB的格式与VxD_Desc_Block结构相同),宏为DDB建立了一个必须在VxD连接时被显式引出的标号。在上例中,DDB的名称是VSAMPLED_DDB

     

     

    6.5 VxD标识(ID

     

     

    一个VxD提供一个VxD标识,以区别于其它VxDVMM动态连接例程使用VxD标识为合适的VxD连接服务调用,如果VxD提供服务或者提供V86模式和保护模式API过程以及其它需要唯一标识的情况,VxD就必须有唯一标识。虽然标准VxD使用预定义VxD标识(符号定义在VMM.INC文件中),支持新设备和新软件接口的VxD还是必须全部有新标识。为了防止与其他新VxD冲突,Microsoft通过请求和注册标识来保证没有其它厂商使用自己的VxD的标识,Microsoft保留001FFH之间的所有VxD标识自己使用。不提供服务或者API过程,或者不需要唯一标识的VxD应该使用Undefined_Device_ID符号来定义VxD标识。

     

     

    6.6 初始化顺序

     

     

    每一个VxD都有一个用于指定VMM应该何时初始化该VxD的初始化顺序值,VMM按照该值从小到大的顺序初始化虚拟机(应该是VxD——译者注)。如果两个或者两个以上的VxD有相同的值,VMM会按照SYSTEM.INI文件中出现的顺序来初始化,但指定顺序是没有保证的。

     

    对于需要调用其它VxD服务或者需要在其它VxD之前拦截中断的VxD,初始化顺序是很重要的。如果一个VxD需要在标准VxD之前或者之后初始化,它的初始化顺序值应该通过在标准VxD预定义的初始化顺序符号(在VMM.INC文件中定义)上加上或者减去一个小数值来创建。

     

    如果一个VxD不需要初始化顺序值,应该使用Undefined_Init_Order符号代替初始化顺序值。

     

     

    6.7 设备控制过程

     

     

    每一个VxD都有一个设备控制过程,VMM通过调用此过程给VxD发送VxD系统控制消息。系统控制消息指导VxD完成动作,例如自身初始化或者通知VxD虚拟机的变化(例如创建虚拟机)等。大多数VxD通过使用Begin_Control_DispatchControl_DispatchEnd_Control_Dispatch宏来定义设备控制过程,例如:

     

    Begin_Control_Dispatch VSAMPLED

     

           Control_Dispatch Sys_Critical_Init, VSAMPLED_Crit_Init

     

           Control_Dispatch Device_Init, VSAMPLED_Device_Init

     

           Control_Dispatch Sys_Critical_Exit, VSAMPLED_Crit_Exit

     

    End_Control_Dispatch VSAMPLED

     

    上例中,宏创建了一个名字为VSAMPLED_Control的设备控制过程,并生成了检查Sys_Critical_InitDevice_InitSys_Critical_Exit消息的指令。当这些消息发送到该过程时,该过程通过控制相应的过程(例如VSAMPLED_Crit_Init)来处理消息,这些消息处理过程必须在VxD中定义。

     

     

    7 系统控制消息

     

     

    VMM发送系统控制消息给VxD,以通知VxD影响系统和虚拟机的变化。大多数VxD需要跟踪虚拟机的创建和状态,所以无论何时创建、初始化或者终止虚拟机,VMM都会发送消息给VxDVMM也会在执行焦点移动到一个虚拟机或者从一个虚拟机移走时,以及虚拟外壳设备需要给用户显示一个消息框时发送消息给VxD

     

    下面是公共消息和VxD应该怎样处理这些消息的方法列表:

     

    Begin_Message_Mode消息:当虚拟外壳设备需要给用户显示一个消息框但不能使用系统虚拟机和Windows函数时VxD收到此消息。虚拟键盘、鼠标和显示设备保存当前状态,允许任何消息模式服务并为消息模式处理初始化相应设备。

     

    Create_VM消息:这是当一个新的虚拟机被创建时VxD收到的第一条消息。VxD应该初始化与虚拟机有关的数据,特别是控制块。

     

    Debug_Query消息:VxDWDEB386调试器收到此消息。VxD可以显示调试列表和从调试终端读取用户命令。

     

    Destroy_VM消息:这是VxD收到的第三条虚拟机终止消息。Simulate_IntExec_Int服务对获得此消息的虚拟机不再有效。

     

    Device_Init消息:这是VxD收到的第二条消息。允许中断,大多数VxD分配和拷贝初始状态到系统虚拟机控制块中的设备指定部分,安装中断回调函数和I/O保护异常以及指定实例数据。这时,Simulate_IntExec_Int服务变得有效。

     

    End_Message_Mode消息:当虚拟外壳设备不再需要显示消息框时VxD收到此消息。虚拟键盘、鼠标和显示器设备恢复获得此消息的虚拟机以前保存的状态,禁止任何消息模式服务。

     

    Init_Complete消息:这是VxD收到的第三条消息,也是最后一条与系统初始化有关的消息。虽然大多数VxD都不处理此消息,但使用V86内存的VxD应该在此消息返回前定位和申请内存。当VxD返回此消息后(应该是VxD从此消息返回后——译者注)VMM丢弃VxD的初始化代码和数据段。

     

    Query_Destory消息:当虚拟外壳设备需要决定是否可以删除虚拟机时VxD收到此消息。VxD可以通过设置进位标志(CF——译者注)返回以阻止虚拟机被删除,在这种情况下VxD应该使用SHELL_Message服务来通知用户问题。

     

    Reboot_Processor消息:当用户试图重新启动计算机时VxD收到此消息。可以重新启动计算机的VxD,例如键盘设备应该完成该工作。

     

    Set_Device_Focus消息:当执行焦点从一个虚拟机移动到另一个虚拟机时VxD收到此消息。VxD恢复硬件设备到与虚拟机有关的状态。如果VxD使用I/O捕获管理没有执行焦点时的虚拟机,VxD应该尽可能地移走太多的I/O捕获,使虚拟机运行尽可能地快一些。

     

    Sys_Critical_Exit消息:这是VxD收到的最后一条消息。禁止中断,Simualte_IntExec_Int服务不再有效。VxD应该复位与之相关的硬件设备,保证能够无问题地返回到实模式。

     

    Sys_Critical_Init消息:这是VxD收到的第一条消息。中断仍然不被允许,所以VxD应该尽可能快地完成任务。大多数VxD完成下列任务:

     

    安装和初始化需要支持来自设备的硬件中断和来自VMM或者其它VxD的软件中断的任何函数,为设备提供需要单独使用V86模式内存页的申请,例如虚拟显示设备申请显示内存。

     

    初始化VxD服务需要的任何数据,这通常包括读取SYSTEM.INI文件中的设置。当处理此消息时,Simualte_IntExec_Int服务必须不被使用。

     

    Sys_VM_Init消息:在Init_Complete消息之后VxD收到此消息。VxD应该初始化系统虚拟机的硬件和软件状态。如果VxD设置进位标志返回,VMM终止所有进程并退出Windows

     

    Sys_VM_Terminate消息:这是VxD收到的第一条系统虚拟机终止消息。VxD可以开始为虚拟机终止做准备。Simulate_IntExec_Int服务有效,系统虚拟机总是最后一个被终止的虚拟机。

     

    System_Exit消息:这是当系统终止时VxD收到的第一条消息。VMM在发送Sys_VM_Terminate消息之后发送此消息,允许中断,但Simualte_IntExec_Int服务不再有效。如果此消息来自一个致命错误的结果,VxD可以通过修改系统虚拟机的内存以恢复系统状态,使得Windows能够终止而不死机。

     

    VM_Critical_Init消息:这是当一个新的VxD应该是虚拟机——译者注)被创建时VxD收到的第二条消息。VxD可以通过设置进位标志返回以阻止虚拟机被建立。禁止中断,Simualte_IntExec_Int服务不再有效。

     

    VM_Init消息:这是当一个新的VxD应该是虚拟机——译者注)被创建时VxD收到的第三条消息。VxD应该初始化虚拟机的硬件和软件状态,例如虚拟显示设备执行INT 10H功能设置初始显示模式。

     

    VM_Not_Execute消息:这是VxD收到的第二条虚拟机终止消息(如果虚拟机已经被虚拟外壳设备删除,这是收到的第一条消息)。VxD可以通过检查EDX寄存器中的标志来查明终止原因。Simulate_IntExec_Int服务对获得此消息的虚拟机不再有效。

     

    VM_Resume消息:当虚拟机的执行被恢复时VxD收到此消息,例如切换到前台时。VxD应该锁定任何资源和为虚拟机重新开始准备内部结构。如果VxD设置进位标志返回,VMM不恢复执行虚拟机。

     

    VM_Suspend消息:当虚拟机已经被挂起时VxD收到此消息,例如切换到后台时。VxD应该解锁任何与虚拟机有关的资源。

     

    VM_Terminate消息:这是VxD收到的第一条虚拟机终止消息。VxD可以开始准备虚拟机的终止。Simulate_IntExec_Int服务有效。

     

     

    8 VxD初始化

     

     

    VMM初始化一个VxD时做下列工作:

     

    1、装载实模式初始化段并调用实模式初始化过程。该过程可以完成阻止装载VxD,阻止启动Windows,指定设备实例数据和在内存中选择页面给设备专用的工作。

     

    2、装载VxD其它段到32位平坦内存模式的保护模式内存,并丢弃实模式初始化段。

     

    3、发送Sys_Critical_Init消息到设备控制过程。禁止硬件中断,所以VxD应该尽可能地用较少的时间完成自身初始化。

     

    4、发送Device_Init消息到设备控制过程。允许硬件中断,所以必须准备让VxD管理来自设备的中断。

     

    5、发送Init_Complete消息到设备控制过程。

     

    6、丢弃初始化代码和数据段,释放其它被使用的内存。VxD不能在处理完Init_Complete消息以后试图存取这些段中的过程和数据。

     

    在初始化过程中的任何时刻,VxD都可以设置进位标志返回到VMM以阻止装载VxD。部分VMM服务,例如初始化信息服务只在初始化过程中有效。

     

     

    9 实模式初始化

     

     

    任何静态设备驱动程序都可以提供实模式初始化过程以在Windows切换到保护模式之前执行初始化任务。VMM装载VxD时调用该过程,该过程检查有关的Windows环境,包括注册表和初始化文件中的有关设置以判断是否应该装载该VxD。该过程也可以给Windows返回信息以为每个虚拟机的实例指定物理内存页保留给设备专用和数据项地址。要获得关于实模式初始化的更多信息,请参阅相关资料。

     

     

    10 VxD服务

     

     

    VxD可以提供服务功能(函数或过程——译者注)给VMM和其它VxD使用。这些服务让其它VxD可以直接访问该VxD的特征,允许测试和修改该VxD的功能和能力。

     

    VxD不能和Windows DLL一样引出函数,代之的是VMM通过INT 20H提供到VxD服务的动态链接,该中断处理过程使用服务编号判断支持服务的VxD,该中断处理过程也使用服务编号查询在VxD服务表中的服务地址。

     

    下面的内容讲述怎样在VxD中定义服务,声明VxD服务表以及从一个VxD向另一个VxD中引入服务。

     

     

    10.1 定义服务

     

     

    VxD使用BeginProcEndProc宏以及ServiceAsync_Service选项定义服务。宏标记服务过程代码的开始和结束,选项标识该过程是一个服务。下面的实例给出了VSAMPLED_Get_Version服务的定义:

     

    BeginProc VSAMPLED_Get_Version, Service

     

           mov ax, 030Ah

     

           clc

     

           ret

     

    EndProc VSAMPLED_Get_Version

     

    Async_Service选项标识该服务可以被异步调用,也就是说在处理中断的过程中调用。异步服务必须是可重入的,而且不能调用VMM和不是异步服务的VxD服务。

     

    VMM和标准VxD对服务使用两种调用约定:基于寄存器的调用约定和基于32C语言的调用约定。这两种调用约定有不同的服务名格式,参数传递和返回值方法以及寄存器保护。

     

    对于基于寄存器的服务,服务名不应该以下划线(_)开头,所有的参数通过寄存器传递,结果也通过寄存器返回,服务保护所有不显式用于返回值的寄存器。

     

    对于基于C语言的服务,服务名必须以下划线(_)开头,所有的参数通过堆栈中的32位值传递,结果(如果存在)通过EAX寄存器(32位值)或者EAXEDX寄存器(64位值)返回,服务保护EBXESFSGS寄存器以及ESIEDI寄存器,只有标志寄存器和EAXECXEDX寄存器被修改。

     

     

    10.2 声明服务

     

     

    VxD使用Begin_Service_TableEnd_Service_Table宏声明服务。宏标记包含服务名和可选的包含服务的段名的列表的开始和结束。声明必须建立在进行VxD定义的文件中(也就是说在包含Declare_Virtual_Device宏的文件中),而且必须先进行设备指定符号的定义。下面的实例给出了一个实例VxD——VSAMPLED的服务表声明: