[Kernel-Application communication]

Hello , I am working on sending some data via dma to fpga , my issue is
that i wanted to directly communicate via deviceiocontrol function , i have
almost no experience on this topic , Please any help or info is good .

problem is when i send data i do like this :

DeviceIoControl (hDMADevice, ISTART_TEST_SMUX, DataToSend,
sizeof(TestCmdSMUX), NULL, 0, &bytes, &os))
where DataToSend is pointer to structure i send , with size
= sizeof(TestCmdSMUX).

How can i decode this data in driver itself ? what i did so far is :

case ISTART_TEST_SMUX:
{
TestCmdSMUX * pTC;
if (InputBufferLength >= sizeof(TestCmdSMUX))
{

status = WdfRequestRetrieveInputBuffer(Request, sizeof(TestCmdSMUX),
&pTC, NULL);
if (status == STATUS_SUCCESS)
{
status = SetTestModesmux(pDevExt, pTC );
}
}
}

*DataToSend *is ptr to structure like this :
typedef struct {
int Engine; /**< Engine Number */
unsigned int TestMode; /**< Test Mode - Enable TX, Enable loopback */
unsigned int MinPktSize; /**< Min packet size */
unsigned int MaxPktSize; /**< Max packet size */
UCHAR buffer[1];

} TestCmdSMUX *DataToSend **

*UCHAR buffer[1];* –> this is pointer to first element of my data i want
to send to kernel .

so it isn’t working properly , and i don’t know why ! , few questions i
have here :
1 - is WdfRequestRetrieveInputBuffer right to use ? and can i in this way
use members of pTC structure ?
2 - what is diffrence between *WdfRequestRetrieveInputBuffer *and
*Irp->AssociatedIrp.SystemBuffer
,when to use them?*
3 - how can i actually recieve the array data i am passing with
deviceiocontrol datatosend structure ?
4 - what is type of my IOCode in this usecase , Method_In_Direct OR
MethodBuffered ?
5 - suppose i want to address in driver the 3rd element data of array
passed , how i do that in driver ?

Thanks so much


Mohamed Abdel Rauof.
communication and electronics Engineer Cairo University BSc. 2011.

Hi,

>what is diffrence between *WdfRequestRetrieveInputBuffer *and *Irp->AssociatedIrp.SystemBuffer
,when to use them?*

KMDF driver will use the wdfrequestretreiveinputBuffer and IRP of
associatedIRP uses the wdm method.

Please use the DataToSend stricture of buffer use copytomemory and save the
date and pass it to driver , and check in driver and print the string in
driver side , use METHODbuffer for data , if you use the Method_IN_DIRECT (
for direct memory accessing you were using the DMA , you can use this part).

Please refer the sample C:\WinDDK\7600.16385.1\src\general\amcc5933\sys

Regards,
Prabhakar V

On Thu, Feb 2, 2017 at 6:37 PM, mohamed rauof
wrote:

> Hello , I am working on sending some data via dma to fpga , my issue is
> that i wanted to directly communicate via deviceiocontrol function , i have
> almost no experience on this topic , Please any help or info is good .
>
> problem is when i send data i do like this :
>
> DeviceIoControl (hDMADevice, ISTART_TEST_SMUX, DataToSend,
> sizeof(TestCmdSMUX), NULL, 0, &bytes, &os))
> where DataToSend is pointer to structure i send , with size
> = sizeof(TestCmdSMUX).
>
> How can i decode this data in driver itself ? what i did so far is :
>
> case ISTART_TEST_SMUX:
> {
> TestCmdSMUX * pTC;
> if (InputBufferLength >= sizeof(TestCmdSMUX))
> {
>
> status = WdfRequestRetrieveInputBuffer(Request, sizeof(TestCmdSMUX),
> &pTC, NULL);
> if (status == STATUS_SUCCESS)
> {
> status = SetTestModesmux(pDevExt, pTC );
> }
> }
> }
>
> *DataToSend *is ptr to structure like this :
> typedef struct {
> int Engine; / *< Engine Number /
> unsigned int TestMode; /
< Test Mode - Enable TX, Enable loopback */
> unsigned int MinPktSize; / *< Min packet size /
> unsigned int MaxPktSize; /
< Max packet size */
> UCHAR buffer[1];
>
> } TestCmdSMUX *DataToSend **
>
>
> UCHAR buffer[1]; –> this is pointer to first element of my data i want
> to send to kernel .
>
>
> so it isn’t working properly , and i don’t know why ! , few questions i
> have here :
> 1 - is WdfRequestRetrieveInputBuffer right to use ? and can i in this way
> use members of pTC structure ?
> 2 - what is diffrence between *WdfRequestRetrieveInputBuffer *and Irp->AssociatedIrp.SystemBuffer
> ,when to use them?

> 3 - how can i actually recieve the array data i am passing with
> deviceiocontrol datatosend structure ?
> 4 - what is type of my IOCode in this usecase , Method_In_Direct OR
> MethodBuffered ?
> 5 - suppose i want to address in driver the 3rd element data of array
> passed , how i do that in driver ?
>
> Thanks so much
>
> –
> Mohamed Abdel Rauof.
> communication and electronics Engineer Cairo University BSc. 2011.
> — NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars
> on crash dump analysis, WDF, Windows internals and software drivers!
> Details at To unsubscribe, visit the List Server section of OSR Online at

On Feb 2, 2017, at 5:07 AM, mohamed rauof > wrote:

problem is when i send data i do like this :

DeviceIoControl (hDMADevice, ISTART_TEST_SMUX, DataToSend, sizeof(TestCmdSMUX), NULL, 0, &bytes, &os))
where DataToSend is pointer to structure i send , with size = sizeof(TestCmdSMUX).

But that number is not correct. The data you want to send is much larger than TestCmdSMUX. If you send sizeof(TestCmdSMUX), you will get exactly one byte of your buffer, because that’s what’s specified in the structure.

You have two alternatives. One is to specify the actual length of the data you want to send in the ioctl:

… DataToSend, sizeof(TestCmdSMUX) + bufferLength - 1, …

The other is to split the buffer out of the structure altogether, and send the structure as the first buffer, and the buffer as the second buffer. That would require changing to METHOD_IN_DIRECT.

DataToSend is ptr to structure like this :
typedef struct {
int Engine; / *< Engine Number /
unsigned int TestMode; /
< Test Mode - Enable TX, Enable loopback */
unsigned int MinPktSize; / *< Min packet size /
unsigned int MaxPktSize; /
< Max packet size */
UCHAR buffer[1];

} TestCmdSMUX DataToSend *

UCHAR buffer[1]; –> this is pointer to first element of my data i want to send to kernel .

It is NOT a pointer. It is the address of the first byte of data.

so it isn’t working properly , and i don’t know why ! , few questions i have here :
1 - is WdfRequestRetrieveInputBuffer right to use ? and can i in this way use members of pTC structure ?

Yes and yes.

2 - what is diffrence between WdfRequestRetrieveInputBuffer and Irp->AssociatedIrp.SystemBuffer ,when to use them?

WdfRequestRetrieveInputBuffer will go fetch the right pointer. If Irp->AssociatedIrp.SystemBuffer is the right pointer for the method of this ioctl, that’s what it will use.

3 - how can i actually recieve the array data i am passing with deviceiocontrol datatosend structure ?

The problem is not that you aren’t receiving it. The problem is that you are sending it. You need to tell it exactly how much data to send.

4 - what is type of my IOCode in this usecase , Method_In_Direct OR MethodBuffered ?

If you are only using the first buffer in DeviceIoControl, these two methods are identical. If the buffer you are sending is large (like, bigger than 8k or 12k), then it would make sense to use METHOD_IN_DIRECT and send the data buffer as the second buffer in DeviceIoControl.

5 - suppose i want to address in driver the 3rd element data of array passed , how i do that in driver ?

If you were actually passing the data, it would be pTC->buffer[2].

Tim Roberts, xxxxx@probo.commailto:xxxxx
Providenza & Boekelheide, Inc.</mailto:xxxxx>

Thanks alot for your detailed reply.
Ok , i get your reply but still have few questions.
I send 32 kb data which is large , so you 1-say i shall make it like this :
Deviceiocontrol( …,…,sizof(testcmdmux)+32kb-1,…,…) ?
Or i shall divide it ?
If so , how can i divide this much data ?
I mean data i want to send is 32768 bytes “32kb”.

2-What did you mean by second buffer ?
3- the data i should send are sizeof(my structure)+32kb-1 or
sizeof(mystructure)+ (32kb-1)*sizeof(datatosend->buffer) this one is making
me crazy :slight_smile: ?
4-If you are only using the first buffer in DeviceIoControl, these two
methods are identical. If the buffer you are sending is large (like,
bigger than 8k or 12k), then it would make sense to use METHOD_IN_DIRECT
and send the data buffer as the second buffer in DeviceIoControl.

So you mean i shall for sure use method in direct ? Ok , but i need to
understand second buffer ! , do you mean i shall send deviceiocontrol 2
times here ?

Really appreciate any help here

On Feb 3, 2017 5:40 AM, “Tim Roberts” wrote:

> On Feb 2, 2017, at 5:07 AM, mohamed rauof
> wrote:
>
>
> problem is when i send data i do like this :
>
> DeviceIoControl (hDMADevice, ISTART_TEST_SMUX, DataToSend,
> sizeof(TestCmdSMUX), NULL, 0, &bytes, &os))
> where DataToSend is pointer to structure i send , with size
> = sizeof(TestCmdSMUX).
>
>
> But that number is not correct. The data you want to send is much larger
> than TestCmdSMUX. If you send sizeof(TestCmdSMUX), you will get exactly
> one byte of your buffer, because that’s what’s specified in the structure.
>
> You have two alternatives. One is to specify the actual length of the
> data you want to send in the ioctl:
>
> … DataToSend, sizeof(TestCmdSMUX) + bufferLength - 1, …
>
> The other is to split the buffer out of the structure altogether, and send
> the structure as the first buffer, and the buffer as the second buffer.
> That would require changing to METHOD_IN_DIRECT.
>
>
> *DataToSend *is ptr to structure like this :
> typedef struct {
> int Engine; / *< Engine Number /
> unsigned int TestMode; /
< Test Mode - Enable TX, Enable loopback */
> unsigned int MinPktSize; / *< Min packet size /
> unsigned int MaxPktSize; /
< Max packet size */
> UCHAR buffer[1];
>
> } TestCmdSMUX *DataToSend **
>
>
> UCHAR buffer[1]; –> this is pointer to first element of my data i want
> to send to kernel .
>
>
> It is NOT a pointer. It is the address of the first byte of data.
>
>
>
> so it isn’t working properly , and i don’t know why ! , few questions i
> have here :
> 1 - is WdfRequestRetrieveInputBuffer right to use ? and can i in this way
> use members of pTC structure ?
>
>
> Yes and yes.
>
>
> 2 - what is diffrence between *WdfRequestRetrieveInputBuffer *and Irp->AssociatedIrp.SystemBuffer
> ,when to use them?

>
>
> WdfRequestRetrieveInputBuffer will go fetch the right pointer. If
> Irp->AssociatedIrp.SystemBuffer is the right pointer for the method of
> this ioctl, that’s what it will use.
>
>
> 3 - how can i actually recieve the array data i am passing with
> deviceiocontrol datatosend structure ?
>
>
> The problem is not that you aren’t receiving it. The problem is that you
> are sending it. You need to tell it exactly how much data to send.
>
>
> 4 - what is type of my IOCode in this usecase , Method_In_Direct OR
> MethodBuffered ?
>
>
> If you are only using the first buffer in DeviceIoControl, these two
> methods are identical. If the buffer you are sending is large (like,
> bigger than 8k or 12k), then it would make sense to use METHOD_IN_DIRECT
> and send the data buffer as the second buffer in DeviceIoControl.
>
>
> 5 - suppose i want to address in driver the 3rd element data of array
> passed , how i do that in driver ?
>
>
> If you were actually passing the data, it would be pTC->buffer[2].
> —
> Tim Roberts, xxxxx@probo.com
> Providenza & Boekelheide, Inc.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:> showlists.cfm?list=ntdev>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:>

On Feb 4, 2017, at 8:36 AM, mohamed rauof wrote:
>
> Ok , i get your reply but still have few questions.
> I send 32 kb data which is large , so you 1-say i shall make it like this :
> Deviceiocontrol( …,…,sizof(testcmdmux)+32kb-1,…,…) ?
> Or i shall divide it ?
> If so , how can i divide this much data ?
> I mean data i want to send is 32768 bytes “32kb”.

Remember that, in METHOD_BUFFERED, your buffer is copied into kernel mode. That’s fine for short buffers, but it can cost for larger buffers. With METHOD_IN_DIRECT, the first buffer is copied, but for the second buffer, the physical pages are mapped into kernel memory. That’s more efficient for longer buffers.

For 32kB, I’d probably split it.

> 2-What did you mean by second buffer ?

DeviceIoControl has two buffers. Some people refer to them as “input” and “output”, but that’s not technically accurate.

> 3- the data i should send are sizeof(my structure)+32kb-1 or sizeof(mystructure)+ (32kb-1)*sizeof(datatosend->buffer) this one is making me crazy :slight_smile: ?

Come on. It’s not really that hard, is it? The number has to describe how many bytes you’re sending. Your first two expressions are identical. The third is obviously wrong, as I hope you can see.

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