当前位置:网站首页>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;
}
边栏推荐
- [cloud native training camp] module VIII kubernetes life cycle management and service discovery
- 使用AUR下载并安装常用程序
- Visual upper system design and development (Halcon WinForm) -6 Nodes and grids
- Wechat payment -jsapi: code implementation (payment asynchronous callback, Chinese parameter solution)
- qt使用QZxing生成二维码
- Digital image processing -- popular Canny edge detection
- Srs4.0+obs studio+vlc3 (environment construction and basic use demonstration)
- Baidu AI Cloud helps Shizuishan upgrade the smart health care model of "Internet + elderly care services"
- Unity功能——Unity离线文档下载及使用
- QT use qzxing to generate QR code
猜你喜欢
![[cloud native training camp] module VIII kubernetes life cycle management and service discovery](/img/87/92638402820b32a15383f19f6f8b91.png)
[cloud native training camp] module VIII kubernetes life cycle management and service discovery

秒杀系统2-Redis解决分布式Session问题

Unity function - unity offline document download and use

北京共有产权房出租新规实施的租赁案例

Detailed pointer advanced 1

基础SQL教程

Construction of operation and maintenance system

Jvm-06-execution engine

Creation and destruction of function stack frames

Jvm-09 byte code introduction
随机推荐
Detailed comments on MapReduce instance code on the official website
解决pushgateway数据多次推送会覆盖的问题
Popular understanding of random forest
【云原生训练营】模块八 Kubernetes 生命周期管理和服务发现
Backtracking method to solve batch job scheduling problem
Srs4.0+obs studio+vlc3 (environment construction and basic use demonstration)
Visual upper system design and development (Halcon WinForm) -1 Process node design
PyTorch crop images differentiablly
Relationship between truncated random distribution and original distribution
Second kill system 3 - list of items and item details
Kubernetes带你从头到尾捋一遍
Baidu AI Cloud helps Shizuishan upgrade the smart health care model of "Internet + elderly care services"
Mysql报错:[ERROR] mysqld: File ‘./mysql-bin.010228‘ not found (Errcode: 2 “No such file or directory“)
CString的GetBuffer和ReleaseBuffer使用说明
Using multipleoutputs to output multiple files in MapReduce
使用Tengine解决负载均衡的Session问题
Kubernetes will show you from beginning to end
Subclass hides the function with the same name of the parent class
子类隐藏父类的同名函数
Unity function - unity offline document download and use