FilterGetMessage Bug?!

When i wait in a few threads parallel synchronously with FilterGetMessage and a single FltSendMessage occurs in kernel, every FilterGetMessage get’s signaled with the same message.

Is this behavior a bug?

Check if all gets completed with an error. This is the only way I see for multiple gets to complete by one send. If they were all successful, there were multiple FltSendMessage calls.

Scott [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.de
Sent: Tuesday, September 18, 2012 11:52 AM
To: Windows File Systems Devs Interest List
Subject: [ntfsd] FilterGetMessage Bug?!

When i wait in a few threads parallel synchronously with FilterGetMessage and a single FltSendMessage occurs in kernel, every FilterGetMessage get’s signaled with the same message.

Is this behavior a bug?


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

Following situation:

I’ve started 20 Threads in user mode all waiting with FilterGetMessage(), at any time i start sending FltSendMessages - the buffer is filled with an value which is thread safely incremented before every send ( using mutexes ).
The first 10 FilterGetMessages() receive the correct number 0-9… the second ten also have S_OK as return value but some random value stored in buffer… The outstanding FltSendMessages are timeouting AFTER all FilterGetMessages have returned S_OK!

The buffer in kernel is successfully filled with values 10-19.
How is this behavior explained?

My guess is that something in the implementation of Filter Manager is not thread safe. FltSendMessages are called in IRP_MJ_CREATE callback. Race Conditions could occur.

Sorry for the third message in row but i forgot to mention a last point.
If i call 20 FltSendMessages in a for-loop. All FilterGetMessage buffers are filled with values 0-19.

FltSendMessage will complete a Get if it the message was too large to fit or if it couldn’t pin the buffer. It will then wait for a larger Get until timeout.

Does this repro on Win7/Win8? Are you using overlapped FilterGetMessage?

Scott [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@hotmail.de
Sent: Tuesday, September 25, 2012 12:28 AM
To: Windows File Systems Devs Interest List
Subject: RE:[ntfsd] FilterGetMessage Bug?!

Sorry for the third message in row but i forgot to mention a last point.
If i call 20 FltSendMessages in a for-loop. All FilterGetMessage buffers are filled with values 0-19.


NTFSD is sponsored by OSR

For our schedule of debugging and file system seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I am testing on Windows 7 64-bit. Code snippets ( not 100% copy ) are:

typedef struct
{
FILTER_MESSAGE_HEADER header;
ULONG msg;
}MY_MSG;

DWORD WINAPI worker( LPARAM par )
{
MY_MSG my_msg;
HRESULT res = FilterGetMessage( port, &my_msg, sizeof( FILTER_MESSAGE_HEADER) + sizeof( ULONG), NULL)
if( res == S_OK ){ printf( “%d\n”, my_msg.msg ); }
return 0;
}

void main()
{
FilterConnect…
for( i… 20){ CreateThread(…, worker…, ) // some error handling code
}


Filter

ULONG msg = -1;
… PreCreateCallback()
{
ULONG nr = 0;
MutexLock();
msg++;
nr = msg;
MutexUnlock();
FltSendMessage( filter, port, &msg, sizeof( ULONG ), NULL, NULL, 3 sek in -100ns );
}

Additionally the buffer in kernel is allocated with ExAllocatePoolWithTag… sizeof (ULONG ) and the content is set to nr.

The user mode notifies the filter, when all threads being started over a FilterSendMessage. Then the filter starts to send messages in PreCreate. (until 20 were send).

In UM there is also a logging if FilterGetMessage failed!

Would FilterGetMessage not return an error code, when the buffer is too small?
Again all FilterGetMessage calls succeed with S_OK.

it is not msg in FltSendMessage but a correctly initialized buffer ( just wrote the snippet out of my mind right now).

Thanks for reporting this issue.

Since the port handle provided by FilterConnectionCommunicationPort is an asynchronous handle, synchronous calls to FilterGetMessage must be serialized. If not the results are unpredictable. This is just how the IO subsystem works.

Arguably either FilterGetMessage should handle this under the covers or there should be an option to get a synchronous handle from FilterConnectCommunicationPort.

Options to work around the issue are to call FilterGetMessage asynchronously or to serialize the synchronous calls to FilterGetMessage.

Scott [MSFT]
This posting is provided “AS IS” with no warranties, and confers no rights.

Just for interest. Never heard about synchronous and asynchronous handles? Is there a doc for this subject?

Or is the first one simply protected with mutexes or something like this.
Still wondering why not every FilterGetMessage call creates internally an event which can be signalled. The Filter Manager could hold two queues. One with user mode buffer address, sizes, and the event. And one with FltSendMessage buffer address / sizes.
When an FltSendMessage occurs the first entry of the um queue is popped worked and signalled.

Thanks for the fast support.

The “synchronous” nature of handles is a user mode concept, not a KM concept. If a UM handle wants synchronous behavior the FO_SYNCHRONOUS_IO bit will be set in the file object, and the create call will specify the FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT option bits.

Note: an FSD or filter is not required to honor those bits. They are honored by the I/O Manager. The I/O interface has always been primarily asynchronous. The synchronous bits and options are “hints” to components so they can process things more efficiently.

Tony
OSR