Once again, I want a “like” button for Tim’s response.
Jake Oshins
Windows Kernel Team
This message offers no warranties and confers no rights.
“Tim Roberts” wrote in message news:xxxxx@ntdev…
lorddoskias wrote:
I have a question, which arised entirely from theoretical interest.
Something which I didn’t know (and I have not done either) was the fact
that the buffer type of IO when utilizng IOCTL cannot actually perform a
deep copy of a structure.
Of course. There is no possible way I/O manager could do a deep copy.
It copies the bytes – however many bytes were specified in the I/O
call. I/O manager doesn’t know what those bytes represent. It doesn’t
know which bytes are addresses, and even if it could determine that
something was an address, it couldn’t know how many bytes to copy.
Does that mean that even if you use buffered
i/o between um<=>km you still have to utilize the
ProbeForRead/ProbeForWrite etc. apis when you are likely to manipulate
values which are stored by reference in the passed structure, because,
in essence, you just get a pointer to this value (in the copied
structure) but the actual backing memory might go in any moment if UM
was to fiddle with it?
Absolutely, yes. This is why it is bad practice to pass pointers inside
a buffer like that. (The Kernel Streaming ioctls do this, but they are
already marked as METHOD_NEITHER, which is an alias for “here be dragons”.)
What are some rules of thumb when you are present with such a situation?
- Don’t do it.
Many such abominations can be cleaned up by using METHOD_IN_DIRECT and
METHOD_OUT_DIRECT instead. Pass the meta information in the first
buffer, and pass the pointer as the second buffer. Then, I/O manager
does the locking for you.
–
Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.