#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 data_seg("INIT")
#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName; //设备名称
UNICODE_STRING ustrSymLinkName; //符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
// 函数声明
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject);
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp);
#include "Driver.h"
#define MY_REG_SOFTWARE_KEY_NAME L"\\Registry\\Machine\\Software\\Zhangfan"
#pragma INITCODE
VOID CreateRegTest() //创建或打开某注册表项目
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
RtlInitUnicodeString( &RegUnicodeString,MY_REG_SOFTWARE_KEY_NAME);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 初始化objectAttributes
ULONG ulResult;
NTSTATUS ntStatus = ZwCreateKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult);//创建或带开注册表项目
if (NT_SUCCESS(ntStatus))//创建成功
{
if(ulResult==REG_CREATED_NEW_KEY)//判断是被新创建,还是已经被创建
{
KdPrint(("The register item is created\n"));//新创建
}else if(ulResult==REG_OPENED_EXISTING_KEY)//已经创建了
{
KdPrint(("The register item has been created,and now is opened\n"));
}
}
//(2)创建或打开某注册表项目的子项
UNICODE_STRING subRegUnicodeString;
HANDLE hSubRegister;
RtlInitUnicodeString( &subRegUnicodeString, L"SubItem");//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES subObjectAttributes;
InitializeObjectAttributes(&subObjectAttributes,&subRegUnicodeString,OBJ_CASE_INSENSITIVE, hRegister, NULL );//对大小写敏感 初始化subObjectAttributes
ntStatus = ZwCreateKey( &hSubRegister,KEY_ALL_ACCESS,&subObjectAttributes,0,NULL,REG_OPTION_NON_VOLATILE,&ulResult);//创建或带开注册表项目
if (NT_SUCCESS(ntStatus))
{
if(ulResult==REG_CREATED_NEW_KEY)//判断是被新创建,还是已经被创建
{
KdPrint(("The sub register item is created\n"));
}else if(ulResult==REG_OPENED_EXISTING_KEY)
{
KdPrint(("The sub register item has been created,and now is opened\n"));
}
}
//关闭注册表句柄
ZwClose(hRegister);
ZwClose(hSubRegister);
}
#pragma INITCODE
VOID OpenRegTest()
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
//初始化UNICODE_STRING字符串
RtlInitUnicodeString( &RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME);
OBJECT_ATTRIBUTES objectAttributes;
//初始化objectAttributes
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感
//打开注册表
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Open register successfully\n"));
}
ZwClose(hRegister);
}
#pragma INITCODE
VOID DeleteItemRegTest()//删除子项 删除没有子项的项
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
#define MY_REG_SOFTWARE_KEY_NAME1 L"\\Registry\\Machine\\Software\\Zhangfan\\SubItem"
RtlInitUnicodeString( &RegUnicodeString,MY_REG_SOFTWARE_KEY_NAME1);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 初始化objectAttributes
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);//打开注册表
if (NT_SUCCESS(ntStatus))//打开成功 获得句柄
{
KdPrint(("Open register successfully\n"));
}
ntStatus = ZwDeleteKey(hRegister);//删除 SubItem
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Delete the item successfully\n"));
}else if(ntStatus == STATUS_ACCESS_DENIED)
{
KdPrint(("STATUS_ACCESS_DENIED\n"));
}else if(ntStatus == STATUS_INVALID_HANDLE)
{
KdPrint(("STATUS_INVALID_HANDLE\n"));
}else
{
KdPrint(("Maybe the item has sub item to delete\n"));
}
ZwClose(hRegister);
}
#pragma INITCODE
VOID SetRegTest()//设置键值
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
RtlInitUnicodeString( &RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 初始化objectAttributes
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);//打开注册表 L"\\Registry\\Machine\\Software\\Zhangfan"
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Open register successfully\n"));
}
UNICODE_STRING ValueName;
RtlInitUnicodeString( &ValueName, L"REG_DWORD 李赛赛");//初始化ValueName
ULONG ulValue = 1000;
ZwSetValueKey(hRegister,&ValueName,0,REG_DWORD,&ulValue,sizeof(ulValue));//设置REG_DWORD子键 李赛赛 1000
RtlInitUnicodeString(&ValueName, L"REG_SZ 李发起");//初始化ValueName
WCHAR* strValue = L"hello world";
ZwSetValueKey(hRegister,&ValueName,0,REG_SZ,strValue,wcslen(strValue)*2+2);//设置REG_SZ子键 李发起 "hello world"
RtlInitUnicodeString( &ValueName, L"REG_BINARY 邱坤");//初始化ValueName
UCHAR buffer[10];
RtlFillMemory(buffer,sizeof(buffer),0xFF);
ZwSetValueKey(hRegister,&ValueName,0,REG_BINARY,buffer,sizeof(buffer));//设置REG_MULTI_SZ子键 邱坤 二进制0xff
ZwClose(hRegister);//关闭注册表句柄
}
#pragma INITCODE
VOID QueryRegTest()//查询注册表键值
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
RtlInitUnicodeString( &RegUnicodeString,MY_REG_SOFTWARE_KEY_NAME);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 初始化objectAttributes
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);//打开注册表
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Open register successfully\n"));
}
UNICODE_STRING ValueName;
RtlInitUnicodeString( &ValueName, L"REG_DWORD 李赛赛");//初始化ValueName
ULONG ulSize;//读取REG_DWORD子键
ntStatus = ZwQueryValueKey(hRegister,&ValueName,KeyValuePartialInformation ,NULL,0,&ulSize);//查询注册表键值 三种 获取这种数据结构体的长度
if (ntStatus==STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0)
{
ZwClose(hRegister);
KdPrint(("The item is not exist\n"));
return;
}
PKEY_VALUE_PARTIAL_INFORMATION pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ntStatus = ZwQueryValueKey(hRegister,&ValueName,KeyValuePartialInformation ,pvpi,ulSize,&ulSize);//查询注册表键值 三种
if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
KdPrint(("Read regsiter error\n"));
return;
}
//判断是否为REG_DWORD类型
if (pvpi->Type==REG_DWORD && pvpi->DataLength==sizeof(ULONG))
{
PULONG pulValue = (PULONG) pvpi->Data;
KdPrint(("打印数值The value:%d\n",*pulValue));//查询到的数据的值
}
ExFreePool(pvpi);
RtlInitUnicodeString( &ValueName, L"REG_SZ 李发起");//初始化ValueName
ntStatus = ZwQueryValueKey(hRegister,&ValueName,KeyValuePartialInformation ,NULL,0,&ulSize);//读取REG_SZ子键 小的结构体体 先自己查询大小 再申请结构体
if (ntStatus==STATUS_OBJECT_NAME_NOT_FOUND || ulSize==0)
{
ZwClose(hRegister);
KdPrint(("The item is not exist\n"));
return;
}
pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ntStatus = ZwQueryValueKey(hRegister,&ValueName,KeyValuePartialInformation ,pvpi,ulSize,&ulSize);//查询键值
if (!NT_SUCCESS(ntStatus))
{
ZwClose(hRegister);
KdPrint(("Read regsiter error\n"));
return;
}
//判断是否为REG_SZ类型
if (pvpi->Type==REG_SZ)
{
KdPrint(("打印字符串The value:%S\n",pvpi->Data));//打印字符串
}
ZwClose(hRegister);
}
#pragma INITCODE
VOID EnumerateSubItemRegTest()
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
RtlInitUnicodeString( &RegUnicodeString, MY_REG_SOFTWARE_KEY_NAME);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 初始化objectAttributes
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);//打开注册表
if (NT_SUCCESS(ntStatus))
{
KdPrint(("打开注册表成功 Open register successfully\n"));
}
ULONG ulSize;
ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize);//第一次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的长度
PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ZwQueryKey(hRegister,KeyFullInformation,pfi,ulSize,&ulSize);//第二次调用ZwQueryKey为了获取KEY_FULL_INFORMATION数据的数据
for (ULONG i=0;i<pfi->SubKeys;i++)//项的个数
{
ZwEnumerateKey(hRegister,i,KeyBasicInformation,NULL,0,&ulSize);//第一次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的长度 结构体的长度
PKEY_BASIC_INFORMATION pbi =(PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ZwEnumerateKey(hRegister,i,KeyBasicInformation,pbi,ulSize,&ulSize);//第二次调用ZwEnumerateKey为了获取KEY_BASIC_INFORMATION数据的数据
UNICODE_STRING uniKeyName;
uniKeyName.Length = uniKeyName.MaximumLength =(USHORT)pbi->NameLength;
uniKeyName.Buffer = pbi->Name;//名字
KdPrint(("子项:The %d sub item name:%wZ\n",i,&uniKeyName));
ExFreePool(pbi);
}
ExFreePool(pfi);
ZwClose(hRegister);
}
#pragma INITCODE
VOID EnumerateSubValueRegTest()
{
UNICODE_STRING RegUnicodeString;
HANDLE hRegister;
RtlInitUnicodeString( &RegUnicodeString,MY_REG_SOFTWARE_KEY_NAME);//初始化UNICODE_STRING字符串
OBJECT_ATTRIBUTES objectAttributes;
InitializeObjectAttributes(&objectAttributes,&RegUnicodeString,OBJ_CASE_INSENSITIVE,NULL, NULL );//对大小写敏感 //初始化objectAttributes
NTSTATUS ntStatus = ZwOpenKey( &hRegister,KEY_ALL_ACCESS,&objectAttributes);//打开注册表
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Open register successfully\n"));
}
ULONG ulSize;
ZwQueryKey(hRegister,KeyFullInformation,NULL,0,&ulSize);//得到项的结构体的大小 要申请内存
PKEY_FULL_INFORMATION pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ZwQueryKey(hRegister,KeyFullInformation,pfi,ulSize,&ulSize);//得到项的个数
for (ULONG i=0;i<pfi->Values;i++)//项的个数
{
ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,NULL,0,&ulSize);//得到结构体的大小 要申请内存
PKEY_VALUE_BASIC_INFORMATION pvbi =(PKEY_VALUE_BASIC_INFORMATION)ExAllocatePool(PagedPool,ulSize);
ZwEnumerateValueKey(hRegister,i,KeyValueBasicInformation,pvbi,ulSize,&ulSize);
UNICODE_STRING uniKeyName;
uniKeyName.Length = uniKeyName.MaximumLength =(USHORT)pvbi->NameLength;
uniKeyName.Buffer = pvbi->Name;//键的名字
KdPrint(("The %d sub value name:%wZ\n",i,&uniKeyName));
if (pvbi->Type==REG_SZ)
{
KdPrint(("The sub value type:REG_SZ\n"));
}else if (pvbi->Type==REG_MULTI_SZ)
{
KdPrint(("The sub value type:REG_MULTI_SZ\n"));
}else if (pvbi->Type==REG_DWORD)
{
KdPrint(("The sub value type:REG_DWORD\n"));
}else if (pvbi->Type==REG_BINARY)
{
KdPrint(("The sub value type:REG_BINARY\n"));
}
ExFreePool(pvbi);
}
ExFreePool(pfi);
ZwClose(hRegister);
}
#pragma INITCODE
void RtlRegTest()//rtl简单函数 封装
{
//创建子项目
NTSTATUS ntStatus =RtlCreateRegistryKey(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan");//Registry\Machine\System\CurrentControlSet\Services
if (NT_SUCCESS(ntStatus))
{ KdPrint(("Create the item successfully\n"));
}
ntStatus =RtlCheckRegistryKey(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan");//检查某项是否存在
if (NT_SUCCESS(ntStatus))
{ KdPrint(("The item is exist\n"));
}
ULONG value1 = 100;
ntStatus = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES, L"HelloDDK\\Zhangfan", L"DWORD_Value_李赛赛", REG_DWORD, &value1, sizeof(value1)); //写入REG_DWORD的数据
if (NT_SUCCESS(ntStatus))
{ KdPrint(("Write the DWORD value succuessfully\n"));
}
PWCHAR szString = L"Hello DDK";
ntStatus = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan",L"SZ_Value_邱坤",REG_SZ,szString,wcslen(szString)*2+2);
if (NT_SUCCESS(ntStatus))
{KdPrint(("Write the REG_SZ value succuessfully\n"));
}
RTL_QUERY_REGISTRY_TABLE paramTable[2];
RtlZeroMemory(paramTable, sizeof(paramTable));
ULONG defaultData=0;
ULONG uQueryValue;
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = L"DWORD_Value";
paramTable[0].EntryContext = &uQueryValue;
paramTable[0].DefaultType = REG_DWORD;
paramTable[0].DefaultData = &defaultData;
paramTable[0].DefaultLength = sizeof(ULONG);
ntStatus = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan",paramTable,NULL,NULL);//查询REG_DWORD的数据
if (NT_SUCCESS(ntStatus))
{
KdPrint(("Query the item successfully\n"));
KdPrint(("The item is :%d\n",uQueryValue));//查询到的值
}
ntStatus = RtlDeleteRegistryValue(RTL_REGISTRY_SERVICES,L"HelloDDK\\Zhangfan",L"DWORD_Value_李赛赛");//删除子键
if (NT_SUCCESS(ntStatus))
{
KdPrint(("delete the value successfully\n"));
}
KdPrint(("执行完毕"));
}
#pragma INITCODE
VOID RegTest()
{
//CreateRegTest();
// OpenRegTest();
//SetRegTest();
//QueryRegTest();
//EnumerateSubItemRegTest();
//EnumerateSubValueRegTest();
//DeleteItemRegTest();
//RtlRegTest();
}
/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath )
{
NTSTATUS status;
KdPrint(("Enter DriverEntry\n"));
//注册其他驱动调用函数入口
pDriverObject->DriverUnload = HelloDDKUnload;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKDispatchRoutine;
//创建驱动设备对象
status = CreateDevice(pDriverObject);
RegTest();
KdPrint(("DriverEntry end\n"));
return status;
}
/************************************************************************
* 函数名称:CreateDevice
* 功能描述:初始化设备对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
* 返回 值:返回初始化状态
*************************************************************************/
#pragma INITCODE
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt; //创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice");
//创建设备
status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,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 = devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
return STATUS_SUCCESS;
}
/************************************************************************
* 函数名称:HelloDDKUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
pDriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pNextObj;
KdPrint(("Enter DriverUnload\n"));
pNextObj = pDriverObject->DeviceObject;
//while (pNextObj != NULL)
//{
// PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
// pNextObj->DeviceExtension;
// //删除符号链接
// UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
// IoDeleteSymbolicLink(&pLinkName);
// pNextObj = pNextObj->NextDevice;
// IoDeleteDevice( pDevExt->pDevice );
//}
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK");
IoDeleteSymbolicLink(&symLinkName);//删除符号连接
IoDeleteDevice(pDriverObject->DeviceObject);//删除设备
}
/************************************************************************
* 函数名称:HelloDDKDispatchRoutine
* 功能描述:对读IRP进行处理
* 参数列表:
pDevObj:功能设备对象
pIrp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp)
{
KdPrint(("Enter HelloDDKDispatchRoutine\n"));
NTSTATUS status = STATUS_SUCCESS;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0; // bytes xfered
IoCompleteRequest( pIrp, IO_NO_INCREMENT );// 完成IRP
KdPrint(("Leave HelloDDKDispatchRoutine\n"));
return status;
}