file-like interface to "normal" FDO (PCI-Board)

Hi everyone!

My name is Paul Groke, and this is my first mail on this list :slight_smile:

I’m writing a Window 2000/XP driver (WDM) for a custom IO-Board for my
company. The board has (among other stuff) a simple UART and a small
nonvolatile RAM. Now, for the UART and the RAM I’d like to “enable”
the ReadFile and WriteFile Win32 functions, and some others.
Which “part” of the board is being talked to is decided by an addition
the the device-name that I can parse in the IRP_MJ_CREATE - which at
the moment works fine for me.

For the file-like interface on the Win32 side I currently handle:
* IRP_MJ_READ
* IRP_MJ_WRITE
* IRP_MJ_FLUSH_BUFFERS
* IRP_MJ_QUERY_INFORMATION (incomplete)
* IRP_MJ_SET_INFORMATION (just return STATUS_INVALID_PARAMETER)

But there are some things that I don’t really understand/ find
information about:

In general, does it under any circumstances make sense to pass an
IRP_MJ_QUERY_INFORMATION or IRP_MJ_SET_INFORMATION on to the lower
stack device? (It’s a PCI board, so the lower device should probably
be a PDO of the PCI-Bus driver)

* IRP_MJ_READ, IRP_MJ_WRITE:

Do I have to update the file-pointer (FILE_OBJECT::CurrentByteOffset)
and MAY I safely do so. (The DDK states a FILE_OBJECT is to be
considered opaque except for DeviceObject, FsContext, FsContext2 and
FileName) Is it sufficient to check FILE_OBJECT::Flags for
FO_SYNCHRONOUS_IO before updating the fields? And do I need to take
the file pointer from that field as well when FO_SYNCHRONOUS_IO is
set, or is it sufficient to update it after reading/writing?
(The IFS FAQ, Q29 mentiones paging IO, but since it’s not an FSD and
noone will ever do paging on an 8k file…?) The read/write stuff
itself works fine, except for the file-pointer not being updated…

* IRP_MJ_FLUSH_BUFFERS

Works fine at the moment - anything special to be aware of? Does the
system ever send me one of those (except for when FlushFileBuffers()
was called)?

* IRP_MJ_QUERY_INFORMATION & IRP_MJ_SET_INFORMATION

I’d like to be able to support calls to SetFilePointer, GetFileSize,
and maybe SetEndOfFile (SetEndOfFile would only have to “fail
properly” because it’s a “fixed size file”). The more of the other
file- functions I could support without putting too much work in it
the better. (At the moment only GetFileSize works)

So. What kind of request should I handle? At the moment I do
FileStandardInformation for the UART and the RAM. The UART returns 0
for all fields, the RAM returns “1 hardlink, 8kb size, 8kb alloc”. As
mentioned above, at least the 8kb are reported o.k. by GetFileSize.
The WDM.h lists:
FileBasicInformation, FileStandardInformation,
FilePositionInformation and FileEndOfFileInformation

  • should I support all those too? Is there any example-code that I
    could loop up? So far I have found nothing on the web and the DDK
    itself does not say so much about it… :frowning: (WINDDK\2600 that is)
    I’m pretty consused about this, so I’d really appreciate your help
    here.

Paul Groke
R&D
TAB Austria GmbH & CoKG

> In general, does it under any circumstances make sense to pass an

IRP_MJ_QUERY_INFORMATION or IRP_MJ_SET_INFORMATION on to the lower
stack device? (It’s a PCI board, so the lower device should probably
be a PDO of the PCI-Bus driver)

No. You are the functional driver, and you decide how to handle them. They are
usually used by on-disk files only.

* IRP_MJ_READ, IRP_MJ_WRITE:

Do I have to update the file-pointer (FILE_OBJECT::CurrentByteOffset)

Yes, if you want to support the lseek() semantics.

and MAY I safely do so.

Yes, since synchronous file object will have only 1 IO in progress on them (the
mutex which provides this is maintained by IO manager).

(The DDK states a FILE_OBJECT is to be
considered opaque except for DeviceObject, FsContext, FsContext2 and
FileName) Is it sufficient to check FILE_OBJECT::Flags for
FO_SYNCHRONOUS_IO before updating the fields?

Yes.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com