Well it depends what you really want to do, but how I approach these things
is put all the non dynamic part in the beginning and then let the dynamic
part at the end something like this:
typedef my_struct
{
//
// fixed part
//
ULONG size;
ULONG someFlags;
ULONG anotherMember;
BOOLEAN shouldDoWhatever;
ULONG someNameLength;
ULONG otherDataLength;
ULONG dynamicLen; // optional I guess in this case
//
//dynamic part now
//
CHAR Data[1]
}
Assuming you have this and you want to send to your driver a
“someNameLength” worth of a file name + some extra stuff that your driver
knows how to handle ( in this case the otherDataLength tells you how much)
you declare something like
my_struct *DataToSend = allocate(sizeof(my_struct) + fileNameLength +
extraDataLen);
should the allocation succeed you now fill the non dynamic members first:
DataToSend->size = sizeof(my_struct) + fileNameLength + extraDataLen;
…
DataToSend->someNameLength = filename->Length;
etc…
and now the dynamic part:
first let’s say you copy the name, you already know the length it is
specified in the "someNameLength’ member
RtlCopyMemory(&(DataToSend->Data[0]), myFileName->Buffer, nameLength);
and if you have some other data to send add that as well after the name
PVOID otherDataPointerOffset = (PVOID)((char*)(&DataToSend->Data[0]) +
nameLength);
RtlCopyMemory(otherDataPointerOffset, DataBuffer, DataLength );
And now you call DeviceIoControl and have as the input buffer your
“DataToSend” pointer and as size the one you actually allocated in this
case: “sizeof(my_struct) + fileNameLength + extraDataLen”
In the driver you just “unpack”/ deserialze this struct, knowing that the
first someNameLength bytes starting drom Data[0] is the name you need, and
the next otherDataLength bytes are the extra data you want to send.
There are other ways I don’t know if this is really the best fit for you
but this way there are no pointers involved in the driver.
Good luck,
Gabriel
On Wed, Oct 14, 2015 at 8:20 AM, wrote:
> Thank you for your replies.
>
> xxxxx@gmail.com wrote:
> > The fact that you think the DeviceIoControl will “know” that the “UINT32*
> > content” is as big as the UINT32 contentSize is a wrong assumption. Those
> > are just 2 members in a struct.
> > What you send down to the driver is only that structure ( which btw I
> would
> > not send that way ).
> …
> > So again make sure you handle those user-mode pointers right when you are
> > in kernel, or just send data there differently not like this, redesign
> the
> > structure I would say, but nevertheless the size you are telling
> > deviceIoControl is wrong, it will try to probe beyond the actual size,
> > beyond by sizeof(UINT32) * ( contentSize + 1 ) what you really have
> there,
> > hence your issue.
>
> I got the problem and solved it. I’am a newbie and I don’t know how to
> redesign the structure to send dynamic content to kernel-driver. Can you
> give me some instruction about it?
>
> xxxxx@probo.com wrote:
> > As a general rule, never, never, never include pointers in ioctl
> > buffers. If you need to pass a descriptor and a buffer, put the
> > descriptor in the first ioctl buffer and the buffer in the second.
>
> I understand this, and try to redesign my application. But what about the
> situation, when I have more then one descriptor?
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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
>
–
Bercea. G.