Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


[Kernel-Application communication]

OSR_Community_UserOSR_Community_User Member Posts: 110,217
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.

Comments

  • prabhakar_vinayagamprabhakar_vinayagam Member - All Emails Posts: 114
    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
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,450
    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, [email protected]
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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 :) ?
    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, [email protected]
    > Providenza & Boekelheide, Inc.
    >
    >
    > ---
    > NTDEV is sponsored by OSR
    >
    > Visit the list online at: showlists.cfm?list=ntdev>
    >
    > 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 <
    > http://www.osronline.com/page.cfm?name=ListServer&gt;
    >
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,450
    On Feb 4, 2017, at 8:36 AM, mohamed rauof <[email protected]> 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 :) ?

    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, [email protected]
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA