⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test.c

📁 灰狐驱动学习笔记系列 参考 windows驱动开发详解和 楚狂人windows驱动编程基础教程
💻 C
字号:
/*

  Test.c
  
  Author: Adly
  Last Updated: 2008-11-16
	
*/

#include <ntddk.h>

#include "Test.h"

//
// A structure representing the instance information associated with
// a particular device
//

typedef struct _DEVICE_EXTENSION
{
	ULONG  StateVariable;
	
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;


//
// Function Declare
//

NTSTATUS
DriverEntry(
	IN PDRIVER_OBJECT		DriverObject,
	IN PUNICODE_STRING		RegistryPath
);

NTSTATUS
TestDispatchCreate(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
);

NTSTATUS
TestDispatchClose(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
);

NTSTATUS
TestDispatchDeviceControl(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
);

VOID
TestUnload(
	IN PDRIVER_OBJECT		DriverObject
);

//////////////////////////////////////////////////////////////////////////
//
// 自定义函数声明
//

NTSTATUS
RegEnumTest();

//////////////////////////////////////////////////////////////////////////

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, TestDispatchCreate)
#pragma alloc_text(PAGE, TestDispatchClose)
#pragma alloc_text(PAGE, TestDispatchDeviceControl)
#pragma alloc_text(PAGE, TestUnload)
#endif // ALLOC_PRAGMA



NTSTATUS
DriverEntry(
	IN PDRIVER_OBJECT		DriverObject,
	IN PUNICODE_STRING		RegistryPath
)
{
	NTSTATUS			Status = STATUS_SUCCESS;    
	UNICODE_STRING		ntDeviceName;
	UNICODE_STRING		dosDeviceName;
	PDEVICE_EXTENSION	deviceExtension;
	PDEVICE_OBJECT		deviceObject = NULL;
	
	
	KdPrint(("[Test] DriverEntry: %wZ\n", RegistryPath));
	
	
	
	RtlInitUnicodeString(&ntDeviceName, TEST_DEVICE_NAME_W);
	
	
	Status = IoCreateDevice(
		DriverObject,
		sizeof(DEVICE_EXTENSION),		// DeviceExtensionSize
		&ntDeviceName,					// DeviceName
		FILE_DEVICE_TEST,	// DeviceType
		0,								// DeviceCharacteristics
		TRUE,							// Exclusive
		&deviceObject					// [OUT]
		);
	
	if(!NT_SUCCESS(Status))
	{
		KdPrint(("[Test] IoCreateDevice Error Code = 0x%X\n", Status));
		
		return Status;
	}
	
	deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;
	
	//
	// Set up synchronization objects, state info,, etc.
	//
	
	//
	// Create a symbolic link that Win32 apps can specify to gain access
	// to this driver/device
	//
	
	RtlInitUnicodeString(&dosDeviceName, TEST_DOS_DEVICE_NAME_W);
	
	Status = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);
	
	if(!NT_SUCCESS(Status))
	{
		KdPrint(("[Test] IoCreateSymbolicLink Error Code = 0x%X\n", Status));
		
		//
		// Delete Object
		//

		IoDeleteDevice(deviceObject);
		
		return Status;
	}
	
	//
	// Create dispatch points for device control, create, close.
	//
	
	DriverObject->MajorFunction[IRP_MJ_CREATE]			= TestDispatchCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE]			= TestDispatchClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]	= TestDispatchDeviceControl;
	DriverObject->DriverUnload							= TestUnload;

	//////////////////////////////////////////////////////////////////////////
	//
	// 自定义函数测试
	//
	RegEnumTest();

	return Status;
}

NTSTATUS
TestDispatchCreate(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
)
{
	NTSTATUS Status = STATUS_SUCCESS;
	
	Irp->IoStatus.Information = 0;
	
	KdPrint(("[Test] IRP_MJ_CREATE\n"));
	
	Irp->IoStatus.Status = Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
	return Status;
}

NTSTATUS
TestDispatchClose(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
)
{
	NTSTATUS Status = STATUS_SUCCESS;
	
	Irp->IoStatus.Information = 0;
	
	KdPrint(("[Test] IRP_MJ_CLOSE\n"));
	
	Irp->IoStatus.Status = Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
	return Status;
}

NTSTATUS
TestDispatchDeviceControl(
	IN PDEVICE_OBJECT		DeviceObject,
	IN PIRP					Irp
)
{
	NTSTATUS			Status = STATUS_SUCCESS;
	PIO_STACK_LOCATION	irpStack;
	PDEVICE_EXTENSION	deviceExtension;
	PVOID				ioBuf;
	ULONG				inBufLength, outBufLength;
	ULONG				ioControlCode;
	
	irpStack = IoGetCurrentIrpStackLocation(Irp);
	deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
	
	Irp->IoStatus.Information = 0;
	
	//
	// Get the pointer to the input/output buffer and it's length
	//
	
	ioBuf = Irp->AssociatedIrp.SystemBuffer;
	inBufLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
	outBufLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
	ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
	// Irp->UserBuffer;		// If METHOD_NEITHER, This is Output Buffer
	
	switch (ioControlCode)
	{
	case IOCTL_TEST_TEST0:
		{
			//
			// Sample IO Control
			//
			KdPrint(("[Test] TEST0 IOCTL: 0x%X", ioControlCode));
			
			break;
		}

	case IOCTL_TEST_TEST1:
		{
			//
			// Sample IO Control
			//
			KdPrint(("[Test] TEST1 IOCTL: 0x%X", ioControlCode));
			
			break;
		}
		
	default:
		{
			Status = STATUS_INVALID_PARAMETER;
			
			KdPrint(("[Test] Unknown IOCTL: 0x%X (%04X,%04X)",
				ioControlCode, DEVICE_TYPE_FROM_CTL_CODE(ioControlCode),
				IoGetFunctionCodeFromCtlCode(ioControlCode)));
			
			break;
		}
	}
	
	
	Irp->IoStatus.Status = Status;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	
	
	return Status;
}

VOID
TestUnload(
	IN PDRIVER_OBJECT		DriverObject
)
{
	UNICODE_STRING dosDeviceName;
	
	//
	// Free any resources
	//
	
	//
	// Delete the symbolic link
	//
	
	RtlInitUnicodeString(&dosDeviceName, TEST_DOS_DEVICE_NAME_W);
	
	IoDeleteSymbolicLink(&dosDeviceName);
	
	//
	// Delete the device object
	//
	
	IoDeleteDevice(DriverObject->DeviceObject);
	
	KdPrint(("[Test] Unloaded"));
}

//////////////////////////////////////////////////////////////////////////
//
// 自定义函数实现
//

NTSTATUS
RegEnumTest()
{
    UNICODE_STRING ustrRegString;
    UNICODE_STRING ustrKeyName;
    HANDLE hRegister;
    ULONG  ulSize, i = 0;
    OBJECT_ATTRIBUTES obj_attrib;
    NTSTATUS status;
    PKEY_FULL_INFORMATION  pfi;
    PKEY_BASIC_INFORMATION pbi;
	
    // 初始化
	RtlInitUnicodeString(&ustrRegString,L"\\Registry\\Machine\\SOFTWARE\\DarkShadow\\Filter");
    InitializeObjectAttributes(&obj_attrib,
							&ustrRegString,
							OBJ_CASE_INSENSITIVE,
							NULL,
							NULL);
	// 打开注册表
    status = ZwOpenKey(&hRegister, KEY_ALL_ACCESS, &obj_attrib);
    if (NT_SUCCESS(status))
    {
        KdPrint(("[Test] ZwOpenKey %wZ Success!", ustrRegString));
    }
    
    // 第一次调用是为了获取需要的长度
    ZwQueryKey(hRegister, KeyFullInformation, NULL, 0, &ulSize);
    pfi = (PKEY_FULL_INFORMATION)ExAllocatePool(PagedPool, ulSize);
	
    // 第二次调用是为了获取数据
    ZwQueryKey(hRegister, KeyFullInformation, pfi, ulSize, &ulSize);
    for (i = 0; i < pfi->SubKeys; i++)
    {
        // 获取第i个子项的长度
        ZwEnumerateKey(hRegister, i, KeyBasicInformation, NULL, 0, &ulSize);
        pbi = (PKEY_BASIC_INFORMATION)ExAllocatePool(PagedPool, ulSize);
		
        // 获取第i个子项的数据
        ZwEnumerateKey(hRegister, i, KeyBasicInformation, pbi, ulSize, &ulSize);
        ustrKeyName.Length = (USHORT)pbi->NameLength;
        ustrKeyName.Buffer = pbi->Name;
        
		KdPrint(("[Test] The %d SubItem Name : %wZ.\n", i, &ustrKeyName));
		
        // 释放内存
        ExFreePool(pbi);
    }

    ExFreePool(pfi);
    ZwClose(hRegister);
	
    return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -