【转帖】驱动程序和应用程序之间通信(For Win2000 or later version)

用python实现微信、钉钉等软件多开 我发现坛友分享的很多都是通过cmd 去start 多个微信 虽然能实现多开,但不够灵活,比如我上午登录了一个微信,下午在登录就不太好用了 当然也可能是我start的姿势不对。于是我就搜了下单实例原理,自己动手实现了个随用随开的。目前很多软件都限制单实例,大多数软件都是用Mutex来实现的 而这个东西咱们可以用handle去干掉它,并且不影响使用。 钉钉也是一样的步骤 不过Mutex的名字不一样 我测试的钉钉的是: ”\Sessions\1\BaseNamedObjects\{{239B7D43-86D5 阅读详情
 正文
Q:
请问有什么方法实现驱动程序主动和应用程序进行实时通讯,而不用应用程序采用定时查询的方法?
比如驱动有一事件发生需要立即通知应用程序,或驱动程序需要向应用程序读取一些内容.

A:
有一个很容易的方式,在驱动程序和应用程序之间用一个事件。
在应用程序CreateFile的时候,驱动程序IoCreateSynchronizationEvent一个有名的事件,然后应用程序CreateEvent/OpenEvent此有名事件即可。
注意点:
1,不要在驱动初始化的时候创建事件,此时大多不能成功创建;
2,让驱动先创建,那么此后应用程序打开时,只能读(Waitxxxx),不能写(SetEvent/ResetEvent)。反之,如果应用程序先创建,则应用程序和驱动程序都有读写权限;
3,用名字比较理想,注意驱动中名字在/BaseNamedObjects/下,例如应用程序用“xxxEvent”,那么驱动中就是“/BaseNamedObjects/xxxEvent”;
4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。
5,此后,驱动对读请求应立即返回,否则就返回失败。不然将失去用事件通知的意义(不再等待读完成,而是有需要(通知事件)时才会读);
6,应用程序发现有事件,应该在一个循环中读取,直到读取失败,表明没有数据可读;否则会漏掉后续数据,而没有及时读取;

Sample Code:


// Describe the share memory.
typedef struct _PKT_BUFFER
{
PMDL BufferMdl;
PVOID UserBaseAddress;
PVOID KernelBaseAddress;
}PKT_BUFFER, *PPKT_BUFFER;

typedef struct _SHARE_EVENT_CONTEXT
{
WCHAR EventName[128]; // Event name, the only connection btw ring0/ring3
HANDLE Win32EventHandle; // Ring3 copy of the event handle
HANDLE DriverEventHandle; // Ring0 copy of the event handle
PVOID DriverEventObject; // The event object
}SHARE_EVENT_CONTEXT, *PSHARE_EVENT_CONTEXT;


BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size)
{
PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool,
Size,
'MpaM');

if(!PktBuffer->KernelBaseAddress)
return FALSE;

//
// Allocate and initalize an MDL that describes the buffer
//
PktBuffer->BufferMdl = IoAllocateMdl(PktBuffer->KernelBaseAddress,
Size,
FALSE,
FALSE,
NULL);

if(!PktBuffer->BufferMdl)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress =NULL;
return FALSE;
}

MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl);

DEBUGP(DL_INFO, ("CreateShareMemory: KernelBaseAddress = 0x%p/n", PktBuffer->KernelBaseAddress));

return TRUE;
}

VOID DestroyShareMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->BufferMdl)
{
IoFreeMdl(PktBuffer->BufferMdl);
PktBuffer->BufferMdl = NULL;
}

if(PktBuffer->KernelBaseAddress)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress = NULL;
}
}

//This function works in user dispatch code.
BOOLEAN MapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(!PktBuffer->BufferMdl)
return FALSE;

//
// The preferred V5 way to map the buffer into user space
//
PktBuffer->UserBaseAddress =
MmMapLockedPagesSpecifyCache(PktBuffer->BufferMdl, // MDL
UserMode, // Mode
MmCached, // Caching
NULL, // Address
FALSE, // Bugcheck?
NormalPagePriority); // Priority

if(!PktBuffer->UserBaseAddress)
return FALSE;

DEBUGP(DL_INFO, ("MapSharedMemory SUCCESS, UserBaseAddress %p/n", PktBuffer->UserBaseAddress));
return TRUE;
}

VOID UnmapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->UserBaseAddress)
{
MmUnmapLockedPages(PktBuffer->UserBaseAddress, PktBuffer->BufferMdl);
PktBuffer->UserBaseAddress = NULL;
}
}

BOOLEAN CreateShareEvent(PSHARE_EVENT_CONTEXT ShareEvent)
{
UNICODE_STRING UnicodeName;
WCHAR UnicodeBuffer[128] = L"/BaseNamedObjects/";

RtlInitUnicodeString(&UnicodeName, UnicodeBuffer);
UnicodeName.MaximumLength = 128;
RtlAppendUnicodeToString(&UnicodeName, ShareEvent->EventName);

ShareEvent->DriverEventObject = IoCreateSynchronizationEvent(&UnicodeName,
&ShareEvent->DriverEventHandle);

if(ShareEvent->DriverEventObject == NULL)
{
ShareEvent->DriverEventHandle = NULL;
DEBUGP(DL_INFO, ("CreateSynchronizationEvent FAILED Name=%ws/n", UnicodeBuffer));
return FALSE;
}
else
{
KeClearEvent(ShareEvent->DriverEventObject);

DEBUGP(DL_INFO, ("CreateSynchronizationEvent SUCCESS Name=%ws DriverEventObject=%p, DriverEventHandle=%u/n",
UnicodeBuffer,
ShareEvent->DriverEventObject,
ShareEvent->DriverEventHandle));

return TRUE;
}
}

VOID DestroyShareEvents(PSHARE_EVENT_CONTEXT ShareEvent)
{
if(ShareEvent->DriverEventHandle)
{
ZwClose(ShareEvent->DriverEventHandle);
ShareEvent->DriverEventObject = NULL;
ShareEvent->DriverEventHandle = NULL;
}
}
TI CCS安装本质:嵌入式开发环境的系统级重构 Code Composer Studio(CCS)并非普通IDE,而是德州仪器(TI)硬件-软件深度协同的嵌入式开发平台,其核心涵盖编译器链、调试服务器、芯片支持包与SysConfig外设配置工具。理解CCS的本质,需从嵌入式开发环境构建原理出发:它通过统一工具链抽象底层JTAG/SWD协议、管理芯片生命周期适配,并支撑C2000、MSP432、Tiva-C等多架构实时控制开发。技术价值在于保障硬件驱动、外设时钟树、链接脚本与固件烧录的全链路一致性;典型应用场景包括电机FOC控制、工业PLC固件开发及边缘A 阅读详情

相关推荐

VS Code深度集成Claude Code:IDE级AI工作流重构指南

IDE智能扩展已从语法提示进化为开发工作流的底层重构力量。以VS Code为执行平台、Claude大模型为智能体,通过认证网关、上下文引擎、MCP协议栈与权限沙箱四大技术模块,实现代码理解、Git操作、多工具协同等工程能力闭环。其核心价值在于将AI嵌入编辑、调试、提交等真实动作节点,而非孤立调用;技术落地高度依赖VS Code环境健康度(CLI注册、Shell继承、Git配置)与上下文感知精度(@-mention文件定位、Git索引缓存、模糊匹配权重)。适用于Vue/React项目重构、CI/CD辅助、跨语

weixin_30756499的博客 394

驱动程序应用程序之间通信For Win2000 or later version)

作者 Fang 关键字 驱动 应用 通信 原作者姓名 Fang 文章原始出处 根据网上一些资料整理。 正文 Q: 请问有什么方法实现驱动程序主动应用程序进行实时通讯,而不用应用程序采用定时查询的方法? 比如驱动有一事件发生需要立即通知应用程序,或驱动程序需要向应用程序读取一些内容. A: 有一个很容易的方式,在驱动程序应用程序之间用一个事件。 在应用程序CreateFile的时候,驱动程序Io

2015

.NET开发者必读:从Copilot CLI到SDK集成的生产级落地指南

GitHub Copilot 不再只是 IDE 中的代码补全工具,而是一种可编程的 AI 工程能力。其核心演进路径是从命令行接口(CLI)向软件开发工具包(SDK)升级——CLI 适合轻量交互,而 SDK 提供类型安全、生命周期可控、认证可审计、工具可编排的企业级集成能力。在 .NET 生态中,GitHub.Copilot.SDK NuGet 包封装了跨平台进程管理、JSON-RPC 协议、Azure OpenAI BYOK 支持及 IToolPermissionHandler 权限控制等关键机制,使 Co

weixin_30654419的博客 471

同步技术

事件对象 KeInitializeEvent IoCreateNotificationEvent IoCreateSynchronizationEvent VOID KeInitializeEvent(     IN PRKEVENT  Event,     IN EVENT_TYPE  Type,     IN BOOLEAN  State     ); The KeI

cosseen的专栏 794

驱动事件对象

事件对象 驱动程序可以使用一个事件对象挂起当前线程等待直到底下一层驱动程序处理一个等待者驱动程序建立的IRP。 拥有驱动创建的线程的驱动程序,或者在一个同步IO请求的completion例程上等待的驱动派遣例程同样可以使用一个事件对象在他们的线程(或)其他驱动例程之间同步操作。 这一章包含以下主题: 定义使用一个事件对象 标准事件对象 定义使用一个事件对象 任何使用一个事

死胖子的博客 1286

windows之 访问控制模型

当一个线程使用Open*打开一个内核对象时,会发生什么? 有两种可能: 1. 打开成功,拿到句柄 2. 打开失败 这不是废话么?!为啥打开失败呢?有两种可能: 1. 当前线程不具有指定的特权 2.  权限不足(由dwDesiredAccess参数指定权限) 这个时候就引入了今天的主题:令牌(包含特权列表)安全描述符(描述用户权限)。 Token token是什么?对

点点灵犀 2427

Mythos安全大模型:漏洞利用自动化与红蓝队工作流重构

大模型在网络安全领域的应用正从辅助分析迈向自主攻防决策。其核心原理在于将代码理解、二进制逆向与协议解析能力深度耦合,并通过多阶段强化学习对齐‘漏洞链构建’与‘规避检测’等高阶目标。这种技术跃迁不仅提升了渗透测试效率,更重塑了软件供应链的风险评估范式——从单点漏洞识别升级为动态攻击面编排。在工程实践中,Mythos类模型已展现出对CVE复现、Metasploit模块生成及EDR绕过的实操能力,广泛应用于金融、政务与工控系统的红队演练与SOAR驱动的蓝队响应。本文聚焦其技术底座、推理时算力依赖与安全落地边界,揭

weixin_33795093的博客 417

安卓启动流程与期间核心组件工作原理

本文以实际工作中出现的启动相关各种千奇百怪的bug为钩子,讲解了安卓app冷启动过程中核心组件的工作原理,pms -> packageParser/androidmanifest.xml -> context -> ams -> application -> activity -> layoutInflater资源加载过程 -> wms /window/WM -> view与viewgroup绘制原理 -> 渲染阶段。理供解决问题的思路,看业务框架代码能看懂他们改的哪块源码,跟他们扯皮能扯赢

mix39的博客 313

驱动开发(12)内核中的多线程同步对象

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处:在内核模式下创建线程在驱动程序中创建线程的方法是调用 PsCreateSystemThread 内核函数,此函数即可以创建系统线程,也可以创建用户线程。此函数的原型如下:NTSTATUS PsCreateSystemThread( _Out_ PHANDLE

zuishikonghuan的博客 3455

Ring3与Ring0通信方法若干

本人在[(原创)应用程序与驱动通信的若干方式]文章中阐述了,上下层通信的技术实现部分,但没有结合应用,下面的文章就具体应用给大家展示了使用方法,希望能够大家一些启发。               Ring3与Ring0同步是很有用的手段,在此做一个简要的整理,希望对开发这方面程序的朋友有帮助,好了,开始吧。          1 同步的策略          初写驱动的朋友都知道,通过Dev

2214

windows驱动开发7:应用程序驱动程序通信

应用同驱动通信

longkuis的专栏 3087

驱动开发:驱动与应用的通信

驱动程序应用程序通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。先来简单介绍一下。

微软技术分享 7622

转帖驱动程序应用程序之间通信

 驱动程序必须与应用程序进行通信,才能最终达到应用程序控制设备的目的,不然驱动有QIU用。要通信就涉及到3个方面: 1.应用程序驱动程序通信2.驱动程序应用程序通信3.数据传输下面分别讨论1。应用程序驱动程序通信1-1 应用程序实现与驱动通信的过程: ---用CreateFile打开设备,然后用DeviceIoControl驱动通信,包括从驱动读数据写数据2种情况也可以使用ReadF

floweronwarmbed的专栏 1064

驱动程序使用 EVENT 主动应用程序通信

背景 用户层程序使用 DeviceIoControl 将 IOCTL 控制码、输入缓冲区、输出缓冲区传入到内核;内核响应 IRP_MJ_DEVICE_CONTRL 消息,并从 IRP 中获取传入的 IOCTL 控制码、输入缓冲区、输出缓冲区,以此实现数据的交互。 但是,当内核层想主动传递数据到用户层,用户层又怎样才能知道呢?因为只有用户层知道内核层有数据输出的时候,它才会调用 DeviceIoControl 函数去获取数据。所以,本文要介绍的就是基于事件 EVENT 实现的同步框架,可以解决这个的问题。 函

LYSM 2789

Windows驱动开发(三)—— 驱动应用层通信的几种方式

因此,内核线程用户进程的通信可以通过进程间通信的方式实现,例如文件映射、共享内存、管道等方式。是 Windows 中的一种轻量级的进程间通信机制,允许在同一台计算机上的不同进程之间进行高效的消息传递。在Windows系统中,驱动程序想要正常工作,往往离不开用户态进程间的交互。因此,驱动用户态进程的通信就成为了必不可少的手段。是Windows系统内部使用的一种通信机制,微软没有提供任何的公开文档,因此在实际使用中可能存在一定风险。的请求,用户态进程直接通过设备读写的方式与驱动程序通信

qq_38933606的博客 1948

应用程序驱动程序通信

1.符号的说明 2.通信IRP的说明与注册 3.demo的实现。 4.总结一下自己的错误。

Catch me if you can 5128

共享内存

共享内存的步骤 1创建共享内存,并打开 2映射共享内存 3分离共享内存 4控制共享内存,删除 shmget 函数的作用:在内核中创建共享内存 函数的原型:int shmget(key_t  key,int size,intshmflg); 函数的参数:key(键值 IPC——PRIVATE私有的键值)                       size:创建的内存大小    

qq_26654257的博客 323
上一篇: 【转帖】驱动程序与应用程序之间的通信
下一篇: 【转帖】如何建立应用程序和驱动程序间的通信
floweronwarmbed
博客等级 码龄18年 46粉丝 16原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值