Hi all,
I want to make a callback from a driver in the context of device.exe to
an application in userland. Actually, that's a lie, I want to do it
differently but I am getting pushback for other reasons.

My scenario is like this:

Application -> registers callback via stream driver IOCTL
Driver -> allocates buffers and handles reading data from device

..
..


Driver -> Data arrives at driver and is put in a buffer in created in
device.exe context.
Driver -> Driver makes callback to userland application with the data
mapped to application user space.

Application -> processes data and returns

Driver -> handles buffer cleanup and continues in device.exe context


The first problem is mapping the data buffer, MapPtrToProcess is
deprecated and MapCallerPtr would not work as it is not a PSL call and I
want to avoid a buffer copy. The best way I could come up with was
ReadProcessMemory, this is a trusted API though so I may have problems
there too.

Next, how do I make a function call in the context of a different
process space? I could use a thread in the application space that simply
waits for an event and do it that way (like an IST) but I am racking my
brains to figure out another way - does anybody have any ideas?

BTW: This is under CE5.0, to be used on WM5.



Geoff
--

Re: Cross Process Callbacks by Paul

Paul
Fri Jul 21 17:19:45 CDT 2006

If you have the help of a wrapper API in the application space, you can use
synchronization objects, like events, to handle notification of a 'callback'
that it's time to run. Getting data to it is still a problem, but you could
handle that with a point-to-point message queue, shared memory
(memory-mapped file, without the file), etc. The wrapper API, when the
application calls a function, CallMeBackWithData( Callback fcn, DWORD
extraparams ), say, would launch a thread:

thread()
{
event = CreateEvent()

DeviceIoControl( driver, set up callback, event )

WaitForSingleObject( event )

// call the application's specified call-back function, grabbing data
sent by the driver from whereever it belongs
}

Paul T.

"Silver" <thesilverring@hot> wrote in message
news:uBJRZ3QrGHA.2052@TK2MSFTNGP02.phx.gbl...
> Hi all,
> I want to make a callback from a driver in the context of device.exe to an
> application in userland. Actually, that's a lie, I want to do it
> differently but I am getting pushback for other reasons.
>
> My scenario is like this:
>
> Application -> registers callback via stream driver IOCTL
> Driver -> allocates buffers and handles reading data from device
>
> ..
> ..
>
>
> Driver -> Data arrives at driver and is put in a buffer in created in
> device.exe context.
> Driver -> Driver makes callback to userland application with the data
> mapped to application user space.
>
> Application -> processes data and returns
>
> Driver -> handles buffer cleanup and continues in device.exe context
>
>
> The first problem is mapping the data buffer, MapPtrToProcess is
> deprecated and MapCallerPtr would not work as it is not a PSL call and I
> want to avoid a buffer copy. The best way I could come up with was
> ReadProcessMemory, this is a trusted API though so I may have problems
> there too.
>
> Next, how do I make a function call in the context of a different process
> space? I could use a thread in the application space that simply waits for
> an event and do it that way (like an IST) but I am racking my brains to
> figure out another way - does anybody have any ideas?
>
> BTW: This is under CE5.0, to be used on WM5.
>
>
>
> Geoff
> --



Re: Cross Process Callbacks by Steve

Steve
Mon Jul 24 21:42:33 CDT 2006

This is not a workable plan sorry. You can instead create a separate tread
that blocks and waits for the driver. You can bury that in a "wrapper" API
that you define but ultimately they is no supported way to call an arbitrary
function in an application from the driver. Threads and synchronization
created at the application level can do the same thing without all the
security risks and hassles associated with a driver based callback.

--
Steve Maillet
EmbeddedFusion
www.EmbeddedFusion.com
smaillet at EmbeddedFusion dot com



Re: Cross Process Callbacks by Andrew

Andrew
Tue Jul 25 02:59:53 CDT 2006

Steve and Paul are right; you can't do cross process callbacks and you
have to use a synchronisation object and if you absolutely must use
callbacks, create a wrapper DLL that runs in the application process to
handle them.

In the past I have used named events to achieve this. The driver
creates named events during it's initialisation:

/* Now initialise the event system. */
_stprintf(pds->szReadReadyEvent,_T("%s_PMREV_ReadReady"),pds->szName);
pds->hevReadReady = CreateEvent(
NULL, FALSE, FALSE, pds->szReadReadyEvent);
...

The IOCTL interface allows the application layer to get the name of the
event that it is interested in:

/* Get the event name used to notify*/
/* the application of what's up. */
case IOCTL_PMR_GET_EVENT_NAME:
...
switch( ((PPMRGETEVENTNAMEIOCTL)pInBuf)->eventName )
{
case PMREN_READREADY:
memcpy(
((PPMRGETEVENTNAMEIOCTL)pOutBuf)->szName,
pds->szReadReadyEvent,
sizeof(TCHAR)*MAX_EVENTNAME );
break;
...

And in the wrapper library you spawn a thread to activate the callback
that you have installed for the appropriate event.....

DWORD WINAPI callbackThread( PVOID pvParam )
{
PPMR_CALLBACK pPmrCallback = (PPMR_CALLBACK)pvParam;
HANDLE hevCallbackEvent;
PMRGETEVENTNAMEIOCTL ioCtlEvent;
DWORD bytesReturned;
HANDLE hev[2];
BOOL bTerminate = FALSE;
DWORD dwStatus;
....
/* Get the device name from the */
/* device driver. */
ioCtlEvent.eventName = pPmrCallback->eName;
DeviceIoControl(
pPmrCallback->hPmr, /* hDevice */
IOCTL_PMR_GET_EVENT_NAME, /* dwIoControlCode */
&ioCtlEvent, /* lpInBuffer */
sizeof(PMRGETEVENTNAMEIOCTL), /* nInBufferSize */
&ioCtlEvent, /* lpOutBuffer */
sizeof(PMRGETEVENTNAMEIOCTL), /* nOutBufferSize */
&bytesReturned, /* lpBytesReturned */
NULL ); /* lpOverlapped */
....
if( PMR_OK == ioCtlEvent.status )
{
hevCallbackEvent = CreateEvent(
NULL, FALSE, FALSE, ioCtlEvent.szName );
if( hevCallbackEvent != INVALID_HANDLE_VALUE )
{
hev[0] = hevCallbackEvent;
hev[1] = pPmrCallback->hevTerminate;

while( !bTerminate )
{
dwStatus = WaitForMultipleObjects(
2, hev, FALSE, INFINITE );

switch( dwStatus )
{
/* Event from the device driver. */
/* Activate installed callback. */
case ( WAIT_OBJECT_0 + 0 ):
pPmrCallback->cbFn(
pPmrCallback->hPmr,
pPmrCallback->pParam );
break;
/* Terminate event from our owner. */
case ( WAIT_OBJECT_0 + 1 ):
CloseHandle( hevCallbackEvent );
bTerminate = TRUE;
break;
/* These should not occur. */
case WAIT_TIMEOUT:
case WAIT_FAILED:
ASSERT( FALSE );
break;
}
}
....

Hope this helps.
Andrew.