KMDF Framework File Objects and WDM FILE_OBJECT

Hi,

if I have two user mode applications accessing the same file (a Service writing to
a particular file name and a user application reading from the same file name)
does the KMDF Framework manage an independent WDFFILEOBJECT for each thread (each
will have sent an open request) or is there just one?

If there is a per instance WDFFILEOBJECT, is the same true for the underlying WDM
FILE_OBJECT?

The CurrentByteOffset field in the WDM FILE_OBJECT would seem to indicate a WDM
FILE_OBJECT (and therefore an individual WDFFILEOBJECT) instance for each open
instance (or how are multiple readers handled) whereas in the online description
there is mention of IoSetShareAccessvs. IoCheckShareAccess?

What is the most reliable way to determine which user space application “gets
there first” the Create call from a writer or the Create call from a reader (e.g.
the user starts his reader application through scheduled tasks)?

By the “file” in this case is not a file on any storage. The file name is used to
identify access to particular functionality on a PCI Express device (one of four
possibilities).

Thanks for any tips,
Charles

Charles wrote:

if I have two user mode applications accessing the same file (a Service writing to
a particular file name and a user application reading from the same file name)
does the KMDF Framework manage an independent WDFFILEOBJECT for each thread (each
will have sent an open request) or is there just one?

If there is a per instance WDFFILEOBJECT, is the same true for the underlying WDM
FILE_OBJECT?

Each call to CreateFile gets a new FILE_OBJECT, whether they are in the
same process or different processes.

A WDFFILEOBJECT is just a local wrapper around a FILE_OBJECT. There is
always a one-to-one correspondence.

The CurrentByteOffset field in the WDM FILE_OBJECT would seem to indicate a WDM
FILE_OBJECT (and therefore an individual WDFFILEOBJECT) instance for each open
instance (or how are multiple readers handled) whereas in the online description
there is mention of IoSetShareAccess vs. IoCheckShareAccess?

IoSetShareAccess sets whether the file that is associated with this
FILE_OBJECT can be opened in future CreateFile calls. It’s not about
sharing this particular FILE_OBJECT.

What is the most reliable way to determine which user space application “gets
there first” the Create call from a writer or the Create call from a reader (e.g.
the user starts his reader application through scheduled tasks)?

Why do you need to know this? There’s no good way to tell which process
called CreateFile. If you need to identify two different kinds of
access, you can use namespaces (such as “\\.\MyDriver\reader” and
“\\.\MyDriver\writer”), or possibly have a custom ioctl that
identifies the caller, or maybe even use the file permissions.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Am 10.01.2012 19:00, schrieb Tim Roberts:

Why do you need to know this? There’s no good way to tell which process
called CreateFile. If you need to identify two different kinds of
access, you can use namespaces (such as “\\.\MyDriver\reader” and
“\\.\MyDriver\writer”), or possibly have a custom ioctl that
identifies the caller, or maybe even use the file permissions.

Well I don’t really need to know which process executes first, but I do need to
know whether it is a reader or the writer which is called first. The writer
initialises a number of structures and owns a circular buffer in system memory.

Currently, I have four WDFFILEOBJECTS in my device extension (since there are four
‘features’). The spec requires that the writer opens asynchronously (overlapped)
and the readers synchronously. I therefore check the file-names to see if it has
been opened already and the FO_SYNCHRONOUS_IO flag to deduce whether it is a
reader or a writer. Once the four ‘slots’ are occupied no further writers are
accepted.

On one system running XP Embedded, I am seeing sporadic problems which I am trying
to track down. Other test-systems (XP, XP-Embedded) run for weeks on end with
constant PCI Express data transfers and without a single problem. What I notice
from TraceView is that sometimes calls to WdfFileObjectGetFlags return zero even
though I can see from the application SW source code that the file has been opened
with FO_SYNCHRONOUS_IO set. There is not a single OpenFile (or is it FileOpen)
call in the application software without SYNCHRONOUS I/O set. I have checked with
grep. The writer is a service and this has definitely not been restarted. I am not
sure yet whether this is my real problem or just a result of some other problem.

Just wanted to make sure my understanding of WDFFILEOBJECTS and WDM FILE_OBJECTS
was correct.

Charles

You should not be checking for FO_SYNCHRONOUS_IO as an indicator of reader or writer. Instead, your app should open the handle with read or write access and then you can check the current stack location to determine role. The driver should be completely agnostic to the overlapped state of the handle being opened.

In WDM you would do the check this way

If (IoGetCurrentIrpStackLocation(Irp)->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) // or FILE_WRITE_DATA
{

}

d
-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Charles
Sent: Tuesday, January 10, 2012 11:07 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF Framework File Objects and WDM FILE_OBJECT

Am 10.01.2012 19:00, schrieb Tim Roberts:

Why do you need to know this? There’s no good way to tell which
process called CreateFile. If you need to identify two different
kinds of access, you can use namespaces (such as
“\\.\MyDriver\reader” and “\\.\MyDriver\writer”), or possibly
have a custom ioctl that identifies the caller, or maybe even use the file permissions.

Well I don’t really need to know which process executes first, but I do need to know whether it is a reader or the writer which is called first. The writer initialises a number of structures and owns a circular buffer in system memory.

Currently, I have four WDFFILEOBJECTS in my device extension (since there are four ‘features’). The spec requires that the writer opens asynchronously (overlapped) and the readers synchronously. I therefore check the file-names to see if it has been opened already and the FO_SYNCHRONOUS_IO flag to deduce whether it is a reader or a writer. Once the four ‘slots’ are occupied no further writers are accepted.

On one system running XP Embedded, I am seeing sporadic problems which I am trying to track down. Other test-systems (XP, XP-Embedded) run for weeks on end with constant PCI Express data transfers and without a single problem. What I notice from TraceView is that sometimes calls to WdfFileObjectGetFlags return zero even though I can see from the application SW source code that the file has been opened with FO_SYNCHRONOUS_IO set. There is not a single OpenFile (or is it FileOpen) call in the application software without SYNCHRONOUS I/O set. I have checked with grep. The writer is a service and this has definitely not been restarted. I am not sure yet whether this is my real problem or just a result of some other problem.

Just wanted to make sure my understanding of WDFFILEOBJECTS and WDM FILE_OBJECTS was correct.

Charles


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other 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

Am 10.01.2012 20:16, schrieb Doron Holan:

You should not be checking for FO_SYNCHRONOUS_IO as an indicator of reader or writer. Instead, your app should open the handle with read or write access and then you can check the current stack location to determine role. The driver should be completely agnostic to the overlapped state of the handle being opened.

In WDM you would do the check this way

If (IoGetCurrentIrpStackLocation(Irp)->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) // or FILE_WRITE_DATA
{

}

Is there a KMDF way of doing it? e.g. based on calling WdfFileObjectGetFlags() or
WdfFileObjectWdmGetFileObject()->ReadAccess /WriteAccess ?

For the flags, I only see the following settings in wdm.h

#define FO_FILE_OPEN 0x00000001
#define FO_SYNCHRONOUS_IO 0x00000002
#define FO_ALERTABLE_IO 0x00000004
#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FO_WRITE_THROUGH 0x00000010
#define FO_SEQUENTIAL_ONLY 0x00000020
#define FO_CACHE_SUPPORTED 0x00000040
#define FO_NAMED_PIPE 0x00000080
#define FO_STREAM_FILE 0x00000100
#define FO_MAILSLOT 0x00000200
#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400
#define FO_QUEUE_IRP_TO_THREAD FO_GENERATE_AUDIT_ON_CLOSE
#define FO_DIRECT_DEVICE_OPEN 0x00000800
#define FO_FILE_MODIFIED 0x00001000
#define FO_FILE_SIZE_CHANGED 0x00002000
#define FO_CLEANUP_COMPLETE 0x00004000
#define FO_TEMPORARY_FILE 0x00008000
#define FO_DELETE_ON_CLOSE 0x00010000
#define FO_OPENED_CASE_SENSITIVE 0x00020000
#define FO_HANDLE_CREATED 0x00040000
#define FO_FILE_FAST_IO_READ 0x00080000
#define FO_RANDOM_ACCESS 0x00100000
#define FO_FILE_OPEN_CANCELLED 0x00200000
#define FO_VOLUME_OPEN 0x00400000
#define FO_REMOTE_ORIGIN 0x01000000
#define FO_DISALLOW_EXCLUSIVE 0x02000000
#define FO_SKIP_COMPLETION_PORT FO_DISALLOW_EXCLUSIVE
#define FO_SKIP_SET_EVENT 0x04000000
#define FO_SKIP_SET_FAST_IO 0x08000000

Charles

Charles wrote:

Am 10.01.2012 20:16, schrieb Doron Holan:
> …
> In WDM you would do the check this way
>
> If (IoGetCurrentIrpStackLocation(Irp)->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) // or FILE_WRITE_DATA
> {
> …
> }
>
Is there a KMDF way of doing it? e.g. based on calling WdfFileObjectGetFlags() or
WdfFileObjectWdmGetFileObject()->ReadAccess /WriteAccess ?

Doron’s suggestion is not part of the file object. It’s part of the IRP
that you get in IRP_MJ_CREATE. So, in the KMDF EvtDeviceFileCreate
callback, use WdfRequestGetParameters

WDF_REQUEST_PARAMETERS wrp;
WdfRequestGetParameters( Request, &wrp );
if( wrp.Create.SecurityContext->DesiredAccess & FILE_READ_DATA )

You can store that information in your WDFFILEOBJECT context structure
for later use.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Those are file object flags. The flags I am talking about are in the create irp. You check for them in EvtDeviceFileCreate and then if needed, you set some kind of state in the WDFFILEOBJECT context you created or if the WDFFILEOBJECT value is state in and of itself, store the WDFFILEOBJECT in the right field of some other context. The KMDF way is

WDF_REQUEST_PARAMETERS params;
WDF_REQUEST_PARAMETERS_INIT(&params);

WdfRequestGetParameters(request, &params);

If (params.Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA)

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of Charles
Sent: Tuesday, January 10, 2012 11:48 AM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF Framework File Objects and WDM FILE_OBJECT

Am 10.01.2012 20:16, schrieb Doron Holan:

You should not be checking for FO_SYNCHRONOUS_IO as an indicator of reader or writer. Instead, your app should open the handle with read or write access and then you can check the current stack location to determine role. The driver should be completely agnostic to the overlapped state of the handle being opened.

In WDM you would do the check this way

If
(IoGetCurrentIrpStackLocation(Irp)->Parameters.Create.SecurityContext->DesiredAccess & FILE_READ_DATA) // or FILE_WRITE_DATA {

}

Is there a KMDF way of doing it? e.g. based on calling WdfFileObjectGetFlags() or WdfFileObjectWdmGetFileObject()->ReadAccess /WriteAccess ?

For the flags, I only see the following settings in wdm.h

#define FO_FILE_OPEN 0x00000001
#define FO_SYNCHRONOUS_IO 0x00000002
#define FO_ALERTABLE_IO 0x00000004
#define FO_NO_INTERMEDIATE_BUFFERING 0x00000008
#define FO_WRITE_THROUGH 0x00000010
#define FO_SEQUENTIAL_ONLY 0x00000020
#define FO_CACHE_SUPPORTED 0x00000040
#define FO_NAMED_PIPE 0x00000080
#define FO_STREAM_FILE 0x00000100
#define FO_MAILSLOT 0x00000200
#define FO_GENERATE_AUDIT_ON_CLOSE 0x00000400
#define FO_QUEUE_IRP_TO_THREAD FO_GENERATE_AUDIT_ON_CLOSE
#define FO_DIRECT_DEVICE_OPEN 0x00000800
#define FO_FILE_MODIFIED 0x00001000
#define FO_FILE_SIZE_CHANGED 0x00002000
#define FO_CLEANUP_COMPLETE 0x00004000
#define FO_TEMPORARY_FILE 0x00008000
#define FO_DELETE_ON_CLOSE 0x00010000
#define FO_OPENED_CASE_SENSITIVE 0x00020000
#define FO_HANDLE_CREATED 0x00040000
#define FO_FILE_FAST_IO_READ 0x00080000
#define FO_RANDOM_ACCESS 0x00100000
#define FO_FILE_OPEN_CANCELLED 0x00200000
#define FO_VOLUME_OPEN 0x00400000
#define FO_REMOTE_ORIGIN 0x01000000
#define FO_DISALLOW_EXCLUSIVE 0x02000000
#define FO_SKIP_COMPLETION_PORT FO_DISALLOW_EXCLUSIVE
#define FO_SKIP_SET_EVENT 0x04000000
#define FO_SKIP_SET_FAST_IO 0x08000000

Charles


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other 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

Am 10.01.2012 20:55, schrieb Doron Holan:

Those are file object flags. The flags I am talking about are in the create
irp.

OK thanks.

> does the KMDF Framework manage an independent WDFFILEOBJECT for each thread

Yes. Independent copy for each CreateFile call.

If there is a per instance WDFFILEOBJECT, is the same true for the underlying WDM
FILE_OBJECT?

Yes.

The CurrentByteOffset field in the WDM FILE_OBJECT would seem to indicate a WDM
FILE_OBJECT (and therefore an individual WDFFILEOBJECT) instance

CurrentByteOffset is CurrentByteOffset, it is not an instance indicator of any kind.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

And for handles opened as overlapped , CurrentByteOffset is not updated since the OVERLAPPED structure specifies the offset

d

debt from my phone


From: Maxim S. Shatskih
Sent: 1/10/2012 8:11 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] KMDF Framework File Objects and WDM FILE_OBJECT

does the KMDF Framework manage an independent WDFFILEOBJECT for each thread

Yes. Independent copy for each CreateFile call.

If there is a per instance WDFFILEOBJECT, is the same true for the underlying WDM
FILE_OBJECT?

Yes.

The CurrentByteOffset field in the WDM FILE_OBJECT would seem to indicate a WDM
FILE_OBJECT (and therefore an individual WDFFILEOBJECT) instance

CurrentByteOffset is CurrentByteOffset, it is not an instance indicator of any kind.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other 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

On 11-Jan-2012 06:11, Maxim S. Shatskih wrote:

> does the KMDF Framework manage an independent WDFFILEOBJECT for each thread

Yes. Independent copy for each CreateFile call.

This is, by the way, why CreateFile is used even to open existing
files. It always creates a new kernel object, which maps to either new
or existing file.

– pa