如果一个驱动需要和应用程序通信 name首先要生成一个设备对象
在windows驱动开发体系中 设备对象是非常重要的元素
设备对象和分发函数构成整个内核体系的基本框架 设备对象可以在内核中暴露给应用层 应用层可以像操作文件一样操作它
IoCreateDevice
IoCreateDevice 例程创建设备对象供驱动程序使用。
NTSTATUS IoCreateDevice(
[in] PDRIVER_OBJECT DriverObject,
[in] ULONG DeviceExtensionSize,
[in, optional] PUNICODE_STRING DeviceName,
[in] DEVICE_TYPE DeviceType,
[in] ULONG DeviceCharacteristics,
[in] BOOLEAN Exclusive,
[out] PDEVICE_OBJECT *DeviceObject
);
#define DriverName L"\\DEVICE\\MyDriver"
#define SymbolLink L"\\??\\Alex"
NTSTATUS CreateDevice(PDRIVER_OBJECT DriverObject) {
UNICODE_STRING MyDriver;//驱动名字
PDEVICE_OBJECT MyDevice = NULL;
RtlInitUnicodeString(&MyDriver, DriverName);
NTSTATUS Status = IoCreateDevice(DriverObject,
sizeof(DriverObject->DriverExtension),
&MyDriver,
FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN,
FALSE,
&MyDevice);
if (Status == STATUS_SUCCESS) {
KdPrint(("驱动设备对象创建成功!\n"));
}
else {
KdPrint(("驱动设备对象创建失败"));
}
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SymbolLink);
Status = IoCreateSymbolicLink(&SymbolName, &MyDriver);
if (Status == STATUS_SUCCESS) {
KdPrint(("符号链接名已关联\n"));
}
else {
KdPrint(("符号链接名关联失败"));
IoDeleteDevice(MyDevice);
}
return Status;
}
void DeleteDevice(PDRIVER_OBJECT DriverObject) {
KdPrint(("已进入删除设备例程"));
if (DriverObject->DeviceObject) {
UNICODE_STRING SymbolName;
RtlInitUnicodeString(&SymbolName, SymbolLink);
IoDeleteSymbolicLink(&SymbolName);
KdPrint(("已经删除符号链接名\n"));
IoDeleteDevice(DriverObject->DeviceObject);
KdPrint(("已经删除驱动设备"));
}
KdPrint(("已退出删除设备例程"));
}
#define IO_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x600,METHOD_BUFFERED,FILE_ANY_ACCESS)
NTSTATUS IrpCall(PDEVICE_OBJECT DriverObject, PIRP prip) {
KdPrint(("进入irp派遣例程"));
PIO_STACK_LOCATION IoStack;
IoStack = IoGetCurrentIrpStackLocation(prip);
switch (IoStack->MajorFunction)
{
case IRP_MJ_DEVICE_CONTROL:
{
UINT32 ControlCode = IoStack->Parameters.DeviceIoControl.IoControlCode;
if (ControlCode == IO_TEST) {
KdPrint(("进入ControlCode->IO_TEST"));
break;
}
}
case IRP_MJ_CREATE: {
KdPrint(("3环调用CreateFile\n"));
break;
}
case IRP_MJ_CLOSE: {
KdPrint(("3环调用close"));
break;
}
}
prip->IoStatus.Status = STATUS_SUCCESS;
prip->IoStatus.Information = 4;
IofCompleteRequest(prip, IO_NO_INCREMENT);
KdPrint(("离开pirpcall\n"));
return STATUS_SUCCESS;
}
/// <summary>
/// 驱动停止函数
/// </summary>
/// <param name="DriverObject"></param>
/// <returns></returns>
VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
if (DriverObject != NULL) {
DbgPrint("[%ws]Driver Upload,Driver Object Address:%p", __FUNCTIONW__, DriverObject);
}
DeleteDevice(DriverObject);
return;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
DbgPrint("[%ws] Hello Kernel World\n", __FUNCTIONW__);
if (RegistryPath != NULL) {
DbgPrint("[%ws]Driver REgistPath:%wZ\n", __FUNCTIONW__, RegistryPath);
}
if (DriverObject != NULL) {
DbgPrint("[%ws]Driver Object Address:%p\n", __FUNCTIONW__, RegistryPath);
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IrpCall;
DriverObject->MajorFunction[IRP_MJ_CREATE] = IrpCall;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IrpCall;
CreateDevice(DriverObject);
}
return STATUS_SUCCESS;
}
应用程序代码 这里采用的是mfc
#include<winioctl.h>;
#define IO_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x600,METHOD_BUFFERED,FILE_ANY_ACCESS)
#define SymbolLink L"\\??\\Alex"
static HANDLE DeviceHandle = NULL;
void Cmfcr3Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
DeviceHandle = CreateFileW(SymbolLink,
GENERIC_ALL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (DeviceHandle == INVALID_HANDLE_VALUE) {
::MessageBoxA(NULL, "打开驱动设备失败!", "Error", MB_ICONHAND);
return;
}
}
void Cmfcr3Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CloseHandle(DeviceHandle);
}
void Cmfcr3Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
DWORD ReturnSize;
DeviceIoControl(DeviceHandle,
IO_TEST,
NULL,
0,
NULL,
0,
&ReturnSize,
NULL);
}


需要注意mfc程序 要以管理员权限运行
网友评论