当前位置:网站首页>Driver and application communication
Driver and application communication
2022-07-03 15:27:00 【Yulong_】
Preface
This article is about Windows Communication between driver and application program under operating system , To put it simply, send data to each other .
Text
In the application , Can pass CreateFile To turn on the device , And then through DeviceIoControl To send or receive data to the driver ; The driver needs to pass Create a control device object , and Create symbolic links , adopt Distribution function To process application data , In a word, it's over by following this process , It's still relatively simple , Go straight to the code , You can leave a message if you are not clear .
Be careful :
About whether symbolic links and device objects are created successfully , It can be provided by Microsoft winobj Tools to view
【WinObj - Windows Sysinternals | Microsoft Docs】
Driver registration 、 Loading can be used KmdManager Tool complete .
example
Application code (main.cpp):
#include <iostream>
#include <Windows.h>
#define DEVICE_NAME L"\\\\.\\MsgCenterKernal"
// Read device
#define READ_CTL_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_READ_ACCESS)
// Write device
#define WRITE_CTL_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_WRITE_ACCESS)
DWORD WriteDevice(HANDLE hDevice, char *szBuff, DWORD dwLen)
{
DWORD dwWrite = 0;
DeviceIoControl(hDevice, WRITE_CTL_CODE, szBuff, dwLen, NULL, 0, &dwWrite, NULL);
return dwWrite;
}
DWORD ReadDevice(HANDLE hDevice, char *szBuff, DWORD dwLen)
{
DWORD dwRead = 0;
DeviceIoControl(hDevice, READ_CTL_CODE, NULL, 0, szBuff, dwLen, &dwRead, NULL);
return dwRead;
}
int main()
{
HANDLE hDevice = CreateFile(DEVICE_NAME, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("open Device error!\n");
return 0;
}
do
{
char szData[100] = "Hello Driver,I am App!";
char szCache[1024];
system("pause");
//DeviceIoControl read write
DWORD dwWriteNumber = WriteDevice(hDevice, szData, strlen(szData)+1);
printf("DeviceIoControl Write:%s,size:%d\n",szData,dwWriteNumber);
system("pause");
memset(szCache, 0, sizeof(szCache));
DWORD dwReadNumber = ReadDevice(hDevice, szCache, sizeof(szCache) - 1);
printf("DeviceIoControl Read:%s,size:%d\n", szCache, dwReadNumber);
system("pause");
} while (FALSE);
CloseHandle(hDevice);
return 0;
}Driver code (Driver.c):
#include <ntddk.h>
#define DEVICE_NAME L"\\Device\\MsgCenterKernal"
#define SYMBOLIC_LINK_NAME L"\\??\\MsgCenterKernal"
// Read device
#define READ_CTL_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_BUFFERED,FILE_READ_ACCESS)
// Write device
#define WRITE_CTL_CODE CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_BUFFERED,FILE_WRITE_ACCESS)
// Global variables
// Equipment control object
PDEVICE_OBJECT g_pControlDeviceObj = NULL;
void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("Driver Unload...\n");
UNICODE_STRING strSymbolicLinkName;
RtlInitUnicodeString(&strSymbolicLinkName, SYMBOLIC_LINK_NAME);
IoDeleteSymbolicLink(&strSymbolicLinkName);
if (pDriverObject->DeviceObject)
{
IoDeleteDevice(pDriverObject->DeviceObject);
g_pControlDeviceObj = NULL;
}
}
NTSTATUS OnMsgDispatch(PDEVICE_OBJECT pDeviceObject, IRP* pIrp)
{
NTSTATUS nStatus = STATUS_SUCCESS;
ULONG lRetLen = 0;
// Request the current stack space
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
// Determine whether it is sent to the control device object
if (pDeviceObject == g_pControlDeviceObj)
{
do
{
// Determine the type of request
// Both opening and closing return success
if (stack->MajorFunction == IRP_MJ_CREATE || stack->MajorFunction == IRP_MJ_CLOSE)
{
break;
}
// Handle DeviceIoControl
if (stack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
// according to IoControlCode To deal with
ULONG ioControlCode = stack->Parameters.DeviceIoControl.IoControlCode;
// data
PVOID pBuffer = pIrp->AssociatedIrp.SystemBuffer;
// Enter the data size of the kernel
ULONG lInLen = stack->Parameters.DeviceIoControl.InputBufferLength;
// The size of the data output by the kernel
ULONG lOutLen = stack->Parameters.DeviceIoControl.OutputBufferLength;
switch (ioControlCode)
{
case WRITE_CTL_CODE:
{
// Read the data sent to the kernel
if (pBuffer != NULL && lInLen > 0)
{
// Generally, it is necessary to judge the size of the input data , If the length exceeds, an error will be returned ! There is no relevant treatment here
DbgPrint("App write to Driver size:%d,data:%s", lInLen, pBuffer);
// Update the data size processed by the kernel
lRetLen = lInLen;
}
break;
}
case READ_CTL_CODE:
{
// The kernel is sent to the application layer
DbgPrint("app want to read from driver size:%d", lOutLen);
const char*pData = "Hello App,I am Driver";
int len = strlen(pData) + 1;
memcpy(pBuffer, pData, len);
// Update the data size processed by the kernel
lRetLen = len;
break;
}
default:
{
// Request not accepted , All returns are illegal
nStatus = STATUS_INVALID_PARAMETER;
break;
}
}
break;
}
// The rest will return parameter errors
nStatus = STATUS_INVALID_PARAMETER;
} while (FALSE);
}
// End request
pIrp->IoStatus.Information = lRetLen;
pIrp->IoStatus.Status = nStatus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return nStatus;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
NTSTATUS nStatus = STATUS_UNSUCCESSFUL;
DbgPrint("Driver Entry...\n");
do
{
UNICODE_STRING strDeviceName, strSymbolLinkName;
RtlInitUnicodeString(&strDeviceName, DEVICE_NAME);
RtlInitUnicodeString(&strSymbolLinkName, SYMBOLIC_LINK_NAME);
// Or replace with IoCreateDeviceSecure
nStatus = IoCreateDevice(pDriverObject, 0, &strDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &g_pControlDeviceObj);
if (!NT_SUCCESS(nStatus))
{
DbgPrint("Create Device Object Error:%x\n",nStatus);
break;
}
g_pControlDeviceObj->Flags |= DO_BUFFERED_IO;
// Create symbolic links
nStatus = IoCreateSymbolicLink(&strSymbolLinkName, &strDeviceName);
if (!NT_SUCCESS(nStatus))
{
DbgPrint("Create SymbolicLink Error:%x\n", nStatus);
IoDeleteDevice(g_pControlDeviceObj);
g_pControlDeviceObj = NULL;
break;
}
// Set unified distribution function
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; ++i)
{
pDriverObject->MajorFunction[i] = OnMsgDispatch;
}
pDriverObject->DriverUnload = DriverUnload;
} while (FALSE);
return nStatus;
}
边栏推荐
- What are the composite types of Blackhorse Clickhouse, an OLAP database recognized in the industry
- C语言刷题~Leetcode与牛客网简单题
- 运维体系的构建
- Redis single thread problem forced sorting layman literacy
- Markdown file titles are all reduced by one level
- 视觉上位系统设计开发(halcon-winform)-1.流程节点设计
- Using notepad++ to build an arbitrary language development environment
- qt使用QZxing生成二维码
- 函数栈帧的创建和销毁
- 秒杀系统3-商品列表和商品详情
猜你喜欢
随机推荐
官网MapReduce实例代码详细批注
秒殺系統3-商品列錶和商品詳情
Win10 enterprise 2016 long term service activation tutorial
软件逆向破解入门系列(1)—xdbg32/64的常见配置及功能窗口
Custom annotation
Kubernetes 进阶训练营 Pod基础
Popular understanding of linear regression (I)
do{}while()的妙用
Visual upper system design and development (Halcon WinForm) -6 Nodes and grids
Digital image processing -- popular Canny edge detection
Matplotlib drawing label cannot display Chinese problems
Jvm-05-object, direct memory, string constant pool
秒杀系统3-商品列表和商品详情
需要知道的字符串函数
视觉上位系统设计开发(halcon-winform)-4.通信管理
socket. IO build distributed web push server
《微服务设计》读书笔记(上)
[combinatorics] combinatorial identities (recursive combinatorial identities | sum of variable terms | simple combinatorial identities and | sum of variable terms | staggered sums of combinatorial ide
【日常训练】395. 至少有 K 个重复字符的最长子串
Stress test WebService with JMeter









