天天看点

驱动之HelloWorld

许多程序都是以HelloWorld开始的,本文也不例外。

程序以C语言为基础。代码如下:

/*

Name: NTDriver.h

Version: 0.10

Author: dir

Date: 22-09-09 23:42

Description:

*/

#ifndef __NTDRIVER__H__

#define __NTDRIVER__H__

#include <ntddk.h>

// 设备扩展

typedef struct _DEVICE_EXTENSION

{

PDEVICE_OBJECT pDevice;

UNICODE_STRING ustrDeviceName;

UNICODE_STRING ustrSymLinkName;

} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

#define DEVNAME L"//Device//MyDevice"

#define SYMLINKNAME L"//??//HelloWorld"

// 字符缓冲区大小

#define BUFFER_SIZE 256

// 函数声明

NTSTATUS

CreateDevice(IN PDRIVER_OBJECT pDriverObjcet);

VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);

NTSTATUS

HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,

IN PIRP pIrp);

NTSTATUS

DriverEntry(IN PDRIVER_OBJECT pDriverObjcet,

IN PUNICODE_STRING pRegistryPath);

#endif

/*

Name: NTDriver.c

Version: 0.10

Author: dir

Date: 22-09-09 23:42

Description:

*/

#include "NTDriver.h"

// 声明函数在内存中的形式

#ifdef ALLOC_PRAGMA

#pragma alloc_text(ININ, CreateDevice)

#pragma alloc_text(ININ, DriverEntry)

#pragma alloc_text(PAGE, HelloDDKDispatchRoutine)

#pragma alloc_text(PAGE, HelloDDKUnload)

#endif

//

// 函数部分

//

// 创建设备

NTSTATUS

CreateDevice(IN PDRIVER_OBJECT pDriverObjcet)

{

NTSTATUS status;

PDEVICE_OBJECT pDevObj;

PDEVICE_EXTENSION pDevExt;

UNICODE_STRING uDevName;

UNICODE_STRING uSymLinkName;

// 创建设备名

RtlInitUnicodeString(&uDevName, DEVNAME);

// 创建设备

status = IoCreateDevice(pDriverObjcet,sizeof(DEVICE_EXTENSION),

&uDevName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);

if (!NT_SUCCESS(status))

{

return status;

}

// 初始化内存读写方式

pDevObj->Flags |= DO_BUFFERED_IO;

// 将驱动信息记录在扩展设备中

pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

pDevExt->pDevice = pDevObj;

// 将设备名写入扩展设备

pDevExt->ustrDeviceName.MaximumLength = BUFFER_SIZE;

pDevExt->ustrDeviceName.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);

RtlCopyUnicodeString(&pDevExt->ustrDeviceName, &uDevName);

// 创建符号链接

RtlInitUnicodeString(&uSymLinkName, SYMLINKNAME);

IoCreateSymbolicLink(&uSymLinkName, &uDevName);

if (!NT_SUCCESS(status))

{

// 删除设备

IoDeleteDevice(pDevObj);

return status;

}

// 将符号链接写入扩展设备

pDevExt->ustrSymLinkName.MaximumLength = BUFFER_SIZE;

pDevExt->ustrSymLinkName.Buffer = (PWSTR)ExAllocatePool(PagedPool, BUFFER_SIZE);

RtlCopyUnicodeString(&pDevExt->ustrSymLinkName, &uSymLinkName);

return STATUS_SUCCESS;

}

// 卸载设备

VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)

{

PDEVICE_OBJECT pDevObj;

PDEVICE_EXTENSION pDevExt;

KdPrint(("[HelloDDK] Enter HelloDDKUnload/n"));

pDevObj = pDriverObject->DeviceObject;

pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;

// 删除符号链接

IoDeleteSymbolicLink(&pDevExt->ustrSymLinkName);

// 删除设备

IoDeleteDevice(pDevExt->pDevice);

// 释放字符串空间

RtlFreeUnicodeString(&pDevExt->ustrSymLinkName);

RtlFreeUnicodeString(&pDevExt->ustrDeviceName);

KdPrint(("[HelloDDK] Leave HelloDDKUnload/n"));

}

// 消息派遣

NTSTATUS

HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,

IN PIRP pIrp)

{

NTSTATUS status = STATUS_SUCCESS;

KdPrint(("[HelloDDK] Enter HelloDDKDispatchRoutine/n"));

// 完成IRP

pIrp->IoStatus.Status = status;

pIrp->IoStatus.Information = 0;

IoCompleteRequest(pIrp, IO_NO_INCREMENT);

KdPrint(("[HelloDDK] Leave HelloDDKDispatchRoutine/n"));

return status;

}

// 驱动入口

NTSTATUS

DriverEntry(IN PDRIVER_OBJECT pDriverObjcet,

IN PUNICODE_STRING pRegistryPath)

{

NTSTATUS status;

KdPrint(("[HelloDDK] Enter DriverEntry/n"));

// 创建驱动设备对象

status = CreateDevice(pDriverObjcet);

if (!NT_SUCCESS(status))

{

return status;

}

// 注册其它驱动函数入口

pDriverObjcet->DriverUnload = HelloDDKUnload;

pDriverObjcet->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;

pDriverObjcet->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;

pDriverObjcet->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;

pDriverObjcet->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;

KdPrint(("[HelloDDK] Leave DriverEntry/n"));

return status;

}

驱动不像普通的程序一样直接双击就可以运行。而程序的错误可能引起蓝屏(BSOD),所以驱动一般先在虚拟机里调试运行。

通过KMD加载、运行驱动。通过DebugView来查看输出信息。驱动加载后可以用WinObj来查看设备和符号链接。

运行效果图:

驱动之HelloWorld