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

📄 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
);

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

VOID
MyGetTickCount();

VOID
MyGetCurrentTime();

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

#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;

	//////////////////////////////////////////////////////////////////////////
	//
	// 自定义函数测试
	//
	
	// 获得启动毫秒数
	MyGetTickCount();

	// 获得当前时间
	MyGetCurrentTime();

	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"));
}

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

VOID
MyGetTickCount()
{
    LARGE_INTEGER    tick_count;
    ULONG            inc;
	
    inc = KeQueryTimeIncrement();
    KeQueryTickCount(&tick_count);
	
	// 因为1毫秒等于1000000纳秒,而inc的单位是100纳秒
	// 所以除以10000即得到当前毫秒数
    tick_count.QuadPart *= inc;
    tick_count.QuadPart /= 10000;
	
    KdPrint(("[Test] TickCount : %d", tick_count.QuadPart));
}

VOID
MyGetCurrentTime()
{
    LARGE_INTEGER CurrentTime;
    LARGE_INTEGER LocalTime;
    TIME_FIELDS   TimeFiled;
    static WCHAR  Time_String[32] = {0};
	
    // 这里得到的其实是格林威治时间
    KeQuerySystemTime(&CurrentTime);
    // 转换成本地时间
    ExSystemTimeToLocalTime(&CurrentTime, &LocalTime);
    // 把时间转换为容易理解的形式
    RtlTimeToTimeFields(&LocalTime, &TimeFiled);
    
    KdPrint(("[Test] NowTime : %4d-%2d-%2d %2d:%2d:%2d", 
			TimeFiled.Year, TimeFiled.Month, TimeFiled.Day, 
			TimeFiled.Hour, TimeFiled.Minute, TimeFiled.Second));
}

⌨️ 快捷键说明

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