最简单的NT驱动
一、源码
//HelloDDK.h
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#include <ntddk.h>
#ifdef __cplusplus
}
#endif
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")
#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA codeseg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName;
UNICODE_STRING ustrSymbolicLinkName;
}DEVICE_EXTENSION, *PDEVICE_EXTENSION;
typedef struct _MYDATANOTE
{
ULONG uNum;
LIST_ENTRY ListEntry;
}MYDATANOTE, *PMYDATANOTE;
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS CreateDevice2(IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDefaultDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp);
VOID Dump1(PDRIVER_OBJECT pDriverObject);
VOID TestListEntry();
VOID TestRtl();
//HelloDDK.cpp
#include "HelloDDK.h"
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
NTSTATUS status;
KdPrint(("DriverEntry:Enter\n"));
KdPrint(("driver object:0X%08X\n", pDriverObject));
KdPrint(("regiter path:%wZ\n", pRegistryPath));
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDefaultDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDefaultDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDefaultDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDefaultDispatchRoutine;
status = CreateDevice(pDriverObject);
status = CreateDevice2(pDriverObject);
Dump1(pDriverObject);
TestListEntry();
TestRtl();
KdPrint(("DriverEntry:Leave\n"));
return status;
}
#pragma INITCODE
VOID TestRtl()
{
KdPrint(("-----------TestRtl------------\n"));
PCHAR pDest;
PCHAR pSrc;
pDest = (PCHAR)ExAllocatePool(PagedPool, 5);
RtlZeroMemory(pDest, 5);
pSrc = "123456789";
RtlCopyMemory(pDest, pSrc, 4);
KdPrint(("pdest=[%s]\n", pDest));
ExFreePool(pDest);
KdPrint(("TestRtl:leave\n"));
}
#pragma INITCODE
VOID Dump1(PDRIVER_OBJECT pDriverObject)
{
ULONG i;
PDEVICE_OBJECT pdo = pDriverObject->DeviceObject;
KdPrint(("---------------the device dump----------------\n"));
i = 0;
while(pdo)
{
i++;
KdPrint(("the %d device\n", i));
KdPrint(("device object:0X%08X\n", pdo));
KdPrint(("device's driver:0X%08X\n", pdo->DriverObject));
KdPrint(("attach device:0X%08X\n", pdo->AttachedDevice));
KdPrint(("stacksieze:%d\n", pdo->SectorSize));
pdo = pdo->NextDevice;
}
}
#pragma INITCODE
VOID TestListEntry()
{
ULONG i;
LIST_ENTRY ListHead;
PMYDATANOTE pData;
PLIST_ENTRY pEntry;
KdPrint(("---------------list_entry----------------\n"));
InitializeListHead(&ListHead);
//插入
for(i = 0; i < 3; i++)
{
pData = (PMYDATANOTE)ExAllocatePool(PagedPool, sizeof(MYDATANOTE));
pData->uNum = i;
InsertTailList(&ListHead, &pData->ListEntry);
}
//遍历
for(pEntry = ListHead.Flink; pEntry->Flink != ListHead.Flink; pEntry = pEntry->Flink)
{
pData = CONTAINING_RECORD(pEntry, MYDATANOTE, ListEntry);
KdPrint(("%d\n", pData->uNum));
}
//删除
pEntry = ListHead.Flink;
while(!IsListEmpty(&ListHead))
{
pEntry = RemoveTailList(&ListHead);
pData = CONTAINING_RECORD(pEntry, MYDATANOTE, ListEntry);
KdPrint(("the %d note removed\n", pData->uNum));
ExFreePool(pData);
}
}
#pragma INITCODE
NTSTATUS CreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pdev;
UNICODE_STRING devname;
UNICODE_STRING linkname;
RtlInitUnicodeString(&devname, L"\\Device\\MyHelloDDK");
status = IoCreateDevice(pDriverObject,
sizeof(DEVICE_EXTENSION),
&devname,
FILE_DEVICE_UNKNOWN,
0,
false,
&pdev);
if(!NT_SUCCESS(status))
{
return status;
}
pdev->Flags |= DO_BUFFERED_IO;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pdev->DeviceExtension;
pdx->pDevice = pdev;
pdx->ustrDeviceName = devname;
RtlInitUnicodeString(&linkname, L"\\??\\HelloDDK");
pdx->ustrSymbolicLinkName = linkname;
status = IoCreateSymbolicLink(&linkname, &devname);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pdev);
return status;
}
return status;
}
#pragma INITCODE
NTSTATUS CreateDevice2(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pdev;
UNICODE_STRING devname;
UNICODE_STRING linkname;
RtlInitUnicodeString(&devname, L"\\Device\\MyHelloDDK2");
status = IoCreateDevice(pDriverObject,
sizeof(DEVICE_EXTENSION),
&devname,
FILE_DEVICE_UNKNOWN,
0,
false,
&pdev);
if(!NT_SUCCESS(status))
{
return status;
}
pdev->Flags |= DO_BUFFERED_IO;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pdev->DeviceExtension;
pdx->pDevice = pdev;
pdx->ustrDeviceName = devname;
RtlInitUnicodeString(&linkname, L"\\??\\HelloDDK2");
pdx->ustrSymbolicLinkName = linkname;
status = IoCreateSymbolicLink(&linkname, &devname);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pdev);
return status;
}
return status;
}
#pragma PAGEDCODE
VOID HelloDDKUnload(IN PDRIVER_OBJECT pDriverObject)
{
KdPrint(("HelloDDKUnload:enter\n"));
PDEVICE_OBJECT pNext = pDriverObject->DeviceObject;
while(pNext)
{
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pNext->DeviceExtension;
pNext = pNext->NextDevice;
IoDeleteSymbolicLink(&pdx->ustrSymbolicLinkName);
IoDeleteDevice(pdx->pDevice);
}
KdPrint(("HelloDDKUnload:leave\n"));
}
#pragma PAGEDCODE
NTSTATUS HelloDDKDefaultDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
{
KdPrint(("HelloDDKDefaultDispatchRoutine:enter\n"));
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
KdPrint(("HelloDDKDefaultDispatchRoutine:leave\n"));
return STATUS_SUCCESS;
}