Abhijit wrote:
Hello,
Consider foll usage of the variable g_pEvent:
//++++++++
In Dispatch Routine: (User mode app init sends this IOCTL)
g_pEvent = ObReferenceObjectByHandle ( hEvent ) ; // hEvent passed by
user mode app
Have some error-handling here, before calling ObReferenceObjectByHandle.
If you don’t serialize IOCTL processing you need to protect that sequence.
Like…
***
pTemp = ObReferenceObjectByHandle(…); // needs to run at PASSIVE_LEVEL
KeAcquireSpinLock(…);
if( (g_pEvent != 0) || (pTemp == 0) )
{
KeReleaseSpinLock(…);
if( pTemp )
ObDereferenceObject( pTemp );
// fail request
}
else
{
g_pEvent = pTemp;
KeReleaseSpinLock(…);
// succeed request
}
***
Inside a thread: (this is always running-unless the driver is exiting)
if ( g_pEvent )
{
KeSetEvent ( g_pEvent , … ) ; // Signal the user mode app
}
Protect the whole if-block with the spinlock.
(You need to pass FALSE as the third parameter for KeSetEvent())
In Dispatch Routine: (User mode app cleanup sends this IOCTL)
if ( g_pEvent )
{
ObDereferenceObject ( g_pEvent ) ;
g_pEvent = NULL ;
}
Rewrite like:
***
KeAcquireSpinLock(…);
if( g_pEvent )
{
pTemp = g_pEvent;
g_pEvent = 0;
}
KeReleaseSpinLock(…);
if( pTemp ) ObDereferenceObject( pTemp );
***
(DDK says you may call ObDereferenceObject() at DISPATCH_LEVEL too,
but since it’s not necessary…)
And make sure g_pEvent uses volatile storage-class!
//--------
Do I need to guard the usage of g_pEvent by a SpinLock ?
I strongly suggest you get some good book on multi-threaded
programming; this question doesn’t really have to do with
driver-programming, it’s rather basic multithreaded programming…
Also you might want to rethink that signal-usermode-app-via-event
approach - from what I remember there was a lengthy discussion
about all the nasty things that can happen in some cases - even
“not-so-special” cases.
(completing IRPs is a simple and effective alternative)
Regards,
Paul Groke