1.HelloDDK 的入口函数
和普通的应用程序不同,Windows 驱动程序的入口函数不是main 函数,而是一个叫
做DriverEntry 的函数,代码将在下面列出。DriverEntry 函数由内核中的I/O 管理器负责调
用,其函数有两个参数:pDriverObject 和pRegistryPath。其中,pDriverObject 是I/O 管理
器传递进来的驱动对象,pRegistryPath 是一个Unicode 字符串,指向此驱动负责的注册表。
#001 /************************************************************************ #002 * 文件名称:Driver.cpp #003 * 作 者:张帆 #004 * 完成日期:2007-11-1 #005 *************************************************************************/ #006 #007 #include "Driver.h" #008 #009 /************************************************************************ #010 * 函数名称:DriverEntry #011 * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 #012 * 参数列表: #013 pDriverObject:从I/O 管理器中传进来的驱动对象 #014 pRegistryPath:驱动程序在注册表的中的路径 #015 * 返回值:返回初始化驱动状态 #016 *************************************************************************/ #017 #pragma INITCODE #018 extern "C" NTSTATUS DriverEntry ( #019 IN PDRIVER_OBJECT pDriverObject, #020 IN PUNICODE_STRING pRegistryPath ) #021 { #022 NTSTATUS status;
#023 KdPrint(("Enter DriverEntry\n")); #024 #025 //注册其他驱动调用函数入口 #026 pDriverObject->DriverUnload = HelloDDKUnload; #027 pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine; #028 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine; #029 pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine; #030 pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine; #031 #032 //创建驱动设备对象 #033 status = CreateDevice(pDriverObject); #034 #035 KdPrint(("DriverEntry end\n")); #036 return status; #037 }
以退出内存。
代码 18 行,标志DriverEntry 函数的开始。注意此处在函数体的前面用extern "C"修
饰,这样在编译的时候会编译成_DriverEntry@8 的符号。如果不加入此修饰符号,
编译器会自动按照C++的符号名编译,导致错误链接。
代码 23 行,打印一行调试信息。KdPrint 其实是一个宏,在调试版本(Checked 版)
中,会用DbgPrint 代替。而在发行版(Free 版)中,则不执行任何操作,其功能
类似于MFC 中的TRACE 宏。由于驱动程序是运行在Windows 的核心态,没有用
户界面,所以查看调试信息有别于Win32 程序。关于查看调试信息的讲解将在第3
章论述。
代码 26~30 行,驱动程序向Windows 的I/O 管理器注册一些回调函数。回调函数
是由程序员定义的函数,这些函数不是由驱动程序本身负责调用,而是由操作系
统负责调用。程序员将这些函数的入口地址告诉操作系统,操作系统会在适当的
时候调用这些函数。在这个例子中,这几个回调函数基本是自解释型的,读者可
以根据函数名分析出其作用。当驱动被卸载时,调用HelloDDKUnload。当驱动程
序处理创建、关闭和读写相关的IRP 时,调用HelloDDKDispatchRoutine(这里只
是将处理函数简化为一个函数,实际情况要比这个复杂)。
- Int3 嘎兹 嘎兹 嘎兹