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/


Handling IOCTL_KS_READ_STREAM in KMDF filter driver

OSR_Community_UserOSR_Community_User Member Posts: 110,217
Inspired by the following article - http://www.osronline.com/article.cfm?article=446 - I decided to try it out and write a simple filter driver for IMAGE class devices (webcams).

I have succesfully created and installed a simple filter driver that passes through all requests and prints out some information to DbgView.

Then, I have experimented with blocking IOCTL_KS_READ_STREAM control code - simply marked it as completed with WdfRequestComplete(request, STATUS_UNSUCCESSFUL).

Then, I planned to modify the requested picture (e.g. fill it with green color) and finally complications arose.
IOCTL_KS_READ_STREAM: Queue 0x0000057FE4E51758, Request 0x0000057FE4F2FCD8 OutputBufferLength 128 InputBufferLength 0 IoControlCode 3096599

From the debug output I see that I should supply something to the OutputBuffer.
However, the documenation says about InputBuffer - "The application places a pointer to an array of KSSTREAM_HEADER structures in the InBuffer parameter. Each describes a packet of data to be read." (http://msdn.microsoft.com/en-us/library/windows/hardware/ff560827(v=vs.85).aspx)

Also, I couldn't get neither the output nor the input one with WdfRequestRetrieveOutputBuffer routine. I receive an error - STATUS_INVALID_DEVICE_REQUEST. I'm pretty sure that it means "something about neither buffered nor direct I/O" - but I cannot get what should I do with that.

Another article (http://msdn.microsoft.com/en-us/library/windows/hardware/ff565432(v=vs.85).aspx) says something about "checking the validity of the user buffer's address range and check whether the appropriate read or write access is permitted, using the ProbeForRead and ProbeForWrite support routines."

I'm not sure if I'm on the right way. What should I do to get access to data buffer in order to modify it? I hope Tim R. could give me a clue..

Thanks a lot,
Anton

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 14,661
    [email protected] wrote:
    > Inspired by the following article - http://www.osronline.com/article.cfm?article=446 - I decided to try it out and write a simple filter driver for IMAGE class devices (webcams).

    You have embarked on a dangerous and obstacle-filled journey. The exact
    ioctl interface to kernel streaming drivers is not documented, and it
    doesn't follow the rules used by other ioctls.


    > Then, I planned to modify the requested picture (e.g. fill it with green color) and finally complications arose.
    > IOCTL_KS_READ_STREAM: Queue 0x0000057FE4E51758, Request 0x0000057FE4F2FCD8 OutputBufferLength 128 InputBufferLength 0 IoControlCode 3096599
    >
    > From the debug output I see that I should supply something to the OutputBuffer.
    > However, the documenation says about InputBuffer - "The application places a pointer to an array of KSSTREAM_HEADER structures in the InBuffer parameter. Each describes a packet of data to be read." (http://msdn.microsoft.com/en-us/library/windows/hardware/ff560827(v=vs.85).aspx)
    >
    > Also, I couldn't get neither the output nor the input one with WdfRequestRetrieveOutputBuffer routine. I receive an error - STATUS_INVALID_DEVICE_REQUEST. I'm pretty sure that it means "something about neither buffered nor direct I/O" - but I cannot get what should I do with that.

    Yes. All of the KS ioctls use "neither" buffering, which means there
    are no rules. The ioctls contain raw user-mode pointers. Making things
    even more exciting, there is a filter driver called "ksthunk" that
    partially processes the ioctl and does some of the mappings.

    The documentation for IOCTL_KS_READ_STREAM says that the KSSTREAM_HEADER
    "array" goes in the input buffer. There are three problems with that
    statement. First, it's false. The KSSTREAM_HEADER goes in the output
    buffer. Second, it's never an array. There's always exactly one. A
    custom KS application might send more, but essentially 100% of video
    streaming happens through one of the two proxies (DShow's ksproxy or
    Media Foundation's devproxy), and they both send exactly one. Third,
    for a video stream, you actually get a KSSTREAM_HEADER followed by a
    KS_FRAME_INFO. That's why it's 128 bytes, when a KSSTREAM_HEADER is
    only 56 bytes.

    The UserBuffer in the IRP points to the kernel address of the
    KSSTREAM_HEADER. The Type3InputBuffer and SystemBuffer fields are not
    used. Up through Win 7, ksthunk helpfully maps the actual frame buffer
    (KSSTREAM_HEADER.Data) in the MdlAddress field, but in Win 8 it no
    longer does that.

    What that means is that you *must* use an EvtInCallerContext callback to
    pre-process the IRP. The IRP and the header both can contain user-mode
    addresses which you have to handle. You will have to manipulate the IRP
    fields directly. In your callback, IF the MdlAddress exists, that's
    your frame buffer. Otherwise, use
    WdfRequestRetrieveUnsafeUserOutputBuffer to get the KSSTREAM_HEADER,
    fetch the user-mode address from that, and use
    WdfRequestProbeAndLockUserBufferForWrite to map it. You will have to
    save this information in a context structure for later use.

    After you modify the frame buffer, you'll set KSSTREAM_HEADER.DataUsed,
    and complete the request using the size of the original request's output
    buffer (that is, sizeof(KSSTREAM_HEADER)+sizeof(KS_FRAME_INFO)). In
    addition, for Windows 8 you'll need to set
    KS_FRAME_INFO.FrameCompletionNumber to an incrementing value.
    Otherwise, KS throws your frames away.

    IOCTL_KS_PROPERTY is handled in an entirely different and even more
    bizarre manner.

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

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

  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    >> You have embarked on a dangerous and obstacle-filled journey.
    Yes, I have already realized this myself..

    Thanks for your quick response Tim. Just wanted to leave here a message that I will postpone this task for a while.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

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 16-20 October 2023 Live, Online
Developing Minifilters 13-17 November 2023 Live, Online
Internals & Software Drivers 4-8 Dec 2023 Live, Online
Writing WDF Drivers 10-14 July 2023 Live, Online