hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:1549回复:10

送分!DDD编写的WDM驱动如何使用事件对象实现与应用程序的通信?

楼主#
更多 发布于:2003-09-28 22:16
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-28 22:31
更正!不是DDD是DDK!
\"DDK编写的WDM驱动如何使用事件对象实现与应用程序的通信\"
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-09-29 10:56
找一下,论坛里原来有一篇文章的。
助人乃快乐之本 有人给分就更快乐了 :-)
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-09-29 11:00
我原来保存过,这里帖出来。
不过不敢掠他人之美,记得是authru2000帖出来的。


1、先由应用程序创建一个事件,然后通过DEVICEIOCONTOL将该事件的句柄传给驱动,最后再创建一个辅助线程来查询该事件。
如DS中的例子所写:
// testintr.cpp - application for interrupt demo driver
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060 USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <winioctl.h>

#include \"common.h\"

// This is a simple console app that exercises the interrupt demo
// driver.
//
// The test app waits for the driver to notify it that there is
// interrupt data to read. The driver notifies the app by setting
// an event whose handle the app passes to the driver at startup.
// The app simply emits the interrupt data (a count and a timestamp)
// to the console.

TIMESTAMP tsbuf[FIFOSIZE];

HANDLE h, hEvent;

/////////////////////////////////////////////////////////////////
// ServiceThread
//
// This thread is awakened by the driver to tell the app to come
// and get the interrupt records
//
DWORD WINAPI ServiceThread(PVOID hEvent)
{
ULONG nItems, nBytesRead;
PTIMESTAMP pts;

while (TRUE)
{
WaitForSingleObject(hEvent, INFINITE);
printf(\"New event:\\n\");

if (!DeviceIoControl(
h,
IOCTL_GET_TIMESTAMP_DATA,
NULL,
0,
tsbuf,
sizeof(tsbuf),
&nBytesRead,
NULL) )
{
printf(\"DeviceIoControl failed %x\\n\", GetLastError());
exit(1);
}

nItems = nBytesRead/sizeof(TIMESTAMP);

for (pts = tsbuf; nItems; nItems--, pts++)
printf(\"Interrupt time %08x (High=%08x) count %x\\n\",
pts->ts_time,
pts->ts_interrupt_count);

}

return 0;
}

/////////////////////////////////////////////////////////////////
//
// Main
//
void __cdecl main(int ac, char* av[])
{
DWORD Tid;
ULONG error;
ULONG nRet;

// Open the device

h = CreateFile(\"\\\\\\\\.\\\\IntrDemo0\",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL);

if (h == INVALID_HANDLE_VALUE)
{
error=GetLastError();
fprintf(stderr, \"Cannot open device, error %d (0x%x)\\n\", error, error);
exit(1);
}

// Create an event for notification

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

if (! DeviceIoControl(
h,
IOCTL_SET_NOTIFICATION_EVENT,
&hEvent,
sizeof(hEvent),
NULL,
0,
&nRet,
NULL
) )
{
printf(\"Ioctl failed: %x\\n\", GetLastError());
exit(1);
}

// Create the thread that waits for the event

CreateThread(0, 0x1000, ServiceThread, (PVOID)hEvent, 0, &Tid);

printf(\"press return to exit . . .\\n\");

// Look for a key to terminate

while (TRUE)
if (_getche() == 0xd)
break;

CloseHandle(hEvent);
CloseHandle(h);
}

 

2、在驱动中这样处理:
//////////////////////////////////////////////////////////////////
// DeviceControl
//
// The test app uses a DeviceIoControl call for two purposes:
//
// 1. It passes an event handle to the driver. The driver sets
// the event when there is something for the app to do, i.e.,
// when an interrupt occurs, and the app fetches the data.
//
// 2. It fetches the timestamp data for the interrupts.
//
NTSTATUS InterruptDemoDevice:eviceControl(KIrp I)
{
T << I;

I.Information() = 0;

switch (I.IoctlCode())
{//注意这里
case IOCTL_SET_NOTIFICATION_EVENT:
{
HANDLE hEvent = *(HANDLE*)I.IoctlBuffer();

if (m_pEvent)
delete m_pEvent;

m_pEvent = new (NonPagedPool) KEvent(hEvent, OBJECT_TYPE_ALL_ACCESS);

return I.Complete(STATUS_SUCCESS);
}

case IOCTL_GET_TIMESTAMP_DATA:
if (SynchronizeInterrupt(&m_Interrupt, LinkTo(ReadTimeFifo), PIRP(I)) )
return I.Complete(STATUS_SUCCESS);

else
return I.Complete(STATUS_UNSUCCESSFUL);

break;

default:
T << \"Bad Request: \" << I.IoctlCode() << \"\\n\";

return I.Complete(STATUS_INVALID_PARAMETER);
}
}

//////////////////////////////////////////////////////////////////
// Isr
//
// This is the interrupt service routine. Since we always return
// FALSE (to indicate that we did not service the interrupt), there
// is no interaction with the hardware required. The system will
// call the actual floppy interrupt handler. This routine justs
// counts the interrupt (m_InterruptCount), grabs a timestamp,
// and requests queues the DPC object.
//
BOOLEAN InterruptDemoDevice::Isr(void)
{
T << \"In the ISR\\n\";

TIMESTAMP ts;

ts.ts_interrupt_count = ++m_InterruptCount;
KeQueryTickCount(&ts.ts_time);

m_TimeStampFifo.Write(&ts, 1);

m_Dpc.Request();
return FALSE;
}

//////////////////////////////////////////////////////////////////
// Dpc
//
// This the callback associated with the device\'s DPC object. The
// ISR queues the dpc object, resulting in a call to this routine.
// It invokes the synch crit section member function TestAndClearNotifyApp,
// which determines if it is necessary to notify the app of the
// interrupt. The idea is that we only notify the app when there
// is no outstanding interrupt to which the app has not responded.
//
VOID InterruptDemoDevice:pc(PVOID Arg1, PVOID Arg2)
{
BOOLEAN Notify;
BOOLEAN SynchStatus;

if (m_pEvent)
{
SynchStatus = SynchronizeInterrupt(
&m_Interrupt,
LinkTo(TestAndClearNotifyApp),
&Notify
);

if (SynchStatus)
{
T << \"DPC, App notify=\" << ULONG(Notify) << \"\\n\";
if (Notify) //注意这里
m_pEvent->Set();
}
else
T << \"Dpc error synchronizing\\n\";
}
}


 

set前最好先判断一下该事件是否有效,如下所示:
if(IntEvent!= NULL)
IntEvent->Set(IO_NO_INCREMENT,FALSE);
助人乃快乐之本 有人给分就更快乐了 :-)
HONGLIN
驱动牛犊
驱动牛犊
  • 注册日期2002-04-04
  • 最后登录2010-03-17
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望12点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-09-29 16:35
App事件对象是可以传入Drvier的,也就是说App和Driver可以共享你的事件
不再困惑
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-09-29 17:30
我看都没看就给你分了!看清题目!是用DDK来做,不是用DS,DS的我早就搞定了!
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2003-09-29 19:41
我原来保存过,这里帖出来。
不过不敢掠他人之美,记得是authru2000帖出来的。

 

我想你记错了,肯定不是我。我没有用DS写驱动的。 ;)
BTW,如果authru2000说的是我的话。。。 :D
tzhou66
驱动牛犊
驱动牛犊
  • 注册日期2003-10-04
  • 最后登录2009-01-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2003-10-04 05:48
Use DDK, DS. I don\'t understand why this gives pointers
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2003-10-04 17:30
我已经搞定了,麻烦大家了!
edbert
驱动牛犊
驱动牛犊
  • 注册日期2003-04-26
  • 最后登录2012-08-11
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望26点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2003-10-28 10:15
请问APP事件是怎样传入DRIVER的?
hhm
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
10楼#
发布于:2003-10-28 11:05
搞定了也告诉大家,是如何解决的??
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
游客

返回顶部