现在的位置: 首页 > 综合 > 正文

我的第一个*.SYS

2013年03月31日 ⁄ 综合 ⁄ 共 2259字 ⁄ 字号 评论关闭

很简单的驱动,什么也不做,只是一个文件.

#include <ntddk.h>
#include <ntddndis.h>

int DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegisterString)
{
 return 0;
}

    同许多应用程序一样,WDM驱动程序是PE格式的,但是它却没有WinMain或main这样的入口,取而代之的是DriverEntry:

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,    
    //不同于前面的PDO
                     
IN PUNICODE_STRING RegistryPath)
{
DriverObject- >DriverExtension- >AddDevice =
AddDevice;    // DriverExtension

中存放着驱动程序扩展信息,包括设备所需要的硬件资源等。
DriverObject- >MajorFunction[IRP_MJ_CREATE]
= RequestCreate;
DriverObject- >MajorFunction[IRP_MJ_CLOSE]
= RequestClose;
DriverObject- >MajorFunction[IRP_MJ_DEVICE_CONTROL]
= RequestControl;
DriverObject- >MajorFunction[IRP_MJ_PNP]
= RequestPnp;
    return STATUS_SUCCESS;
}

---- 在DriverEntry驱动程序要向操作系统登记并注册一些消息处理器,而且还要指明是否对驱动程序输入输出的数据进行缓冲,另外还要我们提供一个AddDevice例程来把驱动程序添加到驱动程序堆栈中。其中,IRP_MJ_XXXXX为驱动程序所收到的系统消息,RequestXXXXX为相应的消息处理函数。在客户端程序中,我们一般要采用DeviceIoControl通过自定义的控制码与驱动程序通信(在VxD中大多也采用这种方式)。看看驱动程序所收到的系统消息,我们不难发现当用户调用DeviceIoControl时操作系统就会向驱动程序发出一条IRP_MJ_DEVICE_CONTROL消息,以触发RequestControl消息处理函数。

NTSTATUS RequestControl(IN PDEVICE_OBJECT
DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpStack;
    ULONG ControlCode;
    ULONG InputLength,OutputLength;
    NTSTATUS status;

IrpStack=IoGetCurrentIrpStackLocation(Irp);    
//获取当前IRP所在的I/O堆栈
ControlCode=IrpStack- >Parameters.DeviceIoControl.
IoControlCode;       //取得控制码
InputLength=IrpStack- >Parameters.DeviceIoControl.
InputBufferLength;  //取输入缓冲区大小
OutputLength=IrpStack- >Parameters.DeviceIoControl.
OutputBufferLength;//取输出缓冲区大小
switch(ControlCode)
    {
case HELLOWDM_IOCTL_HELLO:    DbgPrint
("Hello from WDM./n");//向调试器输出字符串
    status=STATUS_SUCCESS;         //置返回值    
                break;
default:        status=STATUS_INVALID_DEVICE_REQUEST;
            //输入的控制码不支持
    }
    return CompleteRequest(Irp, status, 0);
//调用CompleteRequest通知操作系统完成IRP操作
}

---- 在客户端方面,先调用Setupapi.dll中的 SetupDiGetClassDevs并用上面提到的128位 GUID建立Ring-0与Ring-3接口:

---- HDEVINFO info=SetupDiGetClassDevs ((LPGUID)&GUID_HELLOWDM,NULL, //GUID_HELLOWDM 是128位GUID NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); 然后使用SetupDiEnumDeviceInterfaces 对所获得的接口进行枚举以获得接口数据,接着连续两次调用SetupDiGetDeviceInterfaceDetail 获得接口详细信息,其中包括调用CreateFil e所需的一个型为//./0000000000000004# {3d93c5c0-0085-11d1-821e-0080c88327ab} 的字符串,最后调用方法和VxD的调用大体相同这里就不赘述了。不过由于使用了 Setupapi.dll中的API所以还需要使用 SetupDiDestroyDeviceInfoList来释放所申请的资源。

抱歉!评论已关闭.