Virtual KMDF and IPC to application in userland

Hi,

I have written a virtual serial driver using UMDF. as I suspected I am
having to write this application in kernal mode to get around the mscomm
issue.

My user mode driver handled the various requested and communicated to a user
mode application using named pipes. The user mode application has a GUI and
does lots of wounderous processing including IP communications. I want to
keep the user mode application doing all the complicated bits (TCP/IP ect)
and have the drivers as a simple as possible.

From my initial research I can see that named pipes do not seem to be very
popular in kernal mode. I was looking for a function I use quite a lot in
my user mode driver (PeekNamedPipe).

  1. does anyone know the function for peeking a named pipe in kernal mode?

  2. Can anyone give suggestions on how to make a virtual serial driver talk
    to a user mode application other than the one that thinks its accessing the
    com port.

  3. Does anyone know a work around for the MSCOMM / Pending read request
    problem when using UMDF?

Thanks in advance

Alex

Pipe’s are undocumented in the kernel. The samples that claim to show
how to use them have a disturbing habit of crashing the system. If you
want this project to ever be used don’t consider pipes.

The typical way to do the communication is by an inverted call see
http://www.osronline.com/article.cfm?id=94 these are easy to do in KMDF.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Alex Brown” wrote in message
news:xxxxx@ntdev:

> Hi,
>
> I have written a virtual serial driver using UMDF. as I suspected I am
> having to write this application in kernal mode to get around the mscomm
> issue.
>
> My user mode driver handled the various requested and communicated to a user
> mode application using named pipes. The user mode application has a GUI and
> does lots of wounderous processing including IP communications. I want to
> keep the user mode application doing all the complicated bits (TCP/IP ect)
> and have the drivers as a simple as possible.
>
> From my initial research I can see that named pipes do not seem to be very
> popular in kernal mode. I was looking for a function I use quite a lot in
> my user mode driver (PeekNamedPipe).
>
> 1) does anyone know the function for peeking a named pipe in kernal mode?
>
> 2) Can anyone give suggestions on how to make a virtual serial driver talk
> to a user mode application other than the one that thinks its accessing the
> com port.
>
> 3) Does anyone know a work around for the MSCOMM / Pending read request
> problem when using UMDF?
>
> Thanks in advance
>
> Alex

Thanks,

Another v.useful push in the right direction.

Still keen to see if anyone has found a solution for mscomm but i’m not
holding my breath

On 3 September 2010 16:24, Don Burn wrote:

> Pipe’s are undocumented in the kernel. The samples that claim to show how
> to use them have a disturbing habit of crashing the system. If you want
> this project to ever be used don’t consider pipes.
>
> The typical way to do the communication is by an inverted call see
> http://www.osronline.com/article.cfm?id=94 these are easy to do in KMDF.
>
>
> Don Burn (MVP, Windows DKD)
> Windows Filesystem and Driver Consulting
> Website: http://www.windrvr.com
> Blog: http://msmvps.com/blogs/WinDrvr
>
>
>
>
> “Alex Brown” wrote in message news:xxxxx@ntdev:
>
>
> Hi,
>>
>> I have written a virtual serial driver using UMDF. as I suspected I am
>> having to write this application in kernal mode to get around the mscomm
>> issue.
>>
>> My user mode driver handled the various requested and communicated to a
>> user
>> mode application using named pipes. The user mode application has a GUI
>> and
>> does lots of wounderous processing including IP communications. I want to
>> keep the user mode application doing all the complicated bits (TCP/IP ect)
>> and have the drivers as a simple as possible.
>>
>> From my initial research I can see that named pipes do not seem to be very
>> popular in kernal mode. I was looking for a function I use quite a lot in
>> my user mode driver (PeekNamedPipe).
>>
>> 1) does anyone know the function for peeking a named pipe in kernal mode?
>>
>> 2) Can anyone give suggestions on how to make a virtual serial driver talk
>> to a user mode application other than the one that thinks its accessing
>> the
>> com port.
>>
>> 3) Does anyone know a work around for the MSCOMM / Pending read request
>> problem when using UMDF?
>>
>> Thanks in advance
>>
>> Alex
>>
>
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Been here on this list since its inception, and in all the iterations that
named pipes have been brought to the fore, averaging 24 times a year, or at
least twice a month, the number of times I have seen pipes advocated can be
counted on one meta-tarsal of one pinky.

To agree with Don, use the inverted call.

Gary G. Little

H (952) 223-1349

C (952) 454-4629

xxxxx@comcast.net

From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Alex Brown
Sent: Friday, September 03, 2010 10:45 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland

Thanks,

Another v.useful push in the right direction.

Still keen to see if anyone has found a solution for mscomm but i’m not
holding my breath

On 3 September 2010 16:24, Don Burn wrote:

Pipe’s are undocumented in the kernel. The samples that claim to show how
to use them have a disturbing habit of crashing the system. If you want
this project to ever be used don’t consider pipes.

The typical way to do the communication is by an inverted call see
http://www.osronline.com/article.cfm?id=94 these are easy to do in KMDF.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Alex Brown” wrote in message news:xxxxx@ntdev:

Hi,

I have written a virtual serial driver using UMDF. as I suspected I am
having to write this application in kernal mode to get around the mscomm
issue.

My user mode driver handled the various requested and communicated to a user
mode application using named pipes. The user mode application has a GUI and
does lots of wounderous processing including IP communications. I want to
keep the user mode application doing all the complicated bits (TCP/IP ect)
and have the drivers as a simple as possible.

From my initial research I can see that named pipes do not seem to be very
popular in kernal mode. I was looking for a function I use quite a lot in
my user mode driver (PeekNamedPipe).

1) does anyone know the function for peeking a named pipe in kernal mode?

2) Can anyone give suggestions on how to make a virtual serial driver talk
to a user mode application other than the one that thinks its accessing the
com port.

3) Does anyone know a work around for the MSCOMM / Pending read request
problem when using UMDF?

Thanks in advance

Alex


NTDEV is sponsored by OSR

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

— NTDEV is sponsored by OSR 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

Alex Brown wrote:

  1. Can anyone give suggestions on how to make a virtual
    serial driver talk to a user mode application other than the
    one that thinks its accessing the com port.

Well, you have a few options here.

  1. Raw PDO

  2. Control device

  3. Enumerate the virtual serial device from a root-enumerated bus driver, and open the bus driver’s FDO to feed it data.

  4. As a corollary to #3, you can toss your virtual serial driver, and just usbser.sys. Then you just need to write the bus driver (which you might find hard to believe, but this will be much easier), and have the contract on its child PDO’s be CDC ACM URB’s. Then you get all the serial functionality for free, and an easy path to feed it data as well.

  1. Does anyone know a work around for the MSCOMM /
    Pending read request problem when using UMDF?

I don’t think it’s solvable in UMDF, primarily because you would need to complete the incoming read IRP directly in the kernel driver’s dispatch routine. For this to work, the UMDF reflector would have to call directly into some userspace callback right from kernel mode. While we all get a good laugh when the Wipro folks post this kind of code, I think it’s a non-starter.

Thanks All.

I’m drawing the following conclusions:

  • Named pipes wont work
  • use inverted call
  • write a virtual bus driver and use usbser.sys

I have used usbser.sys to talk to real hardware in the past and have had
some strange behaviour at times. I’ll See how it goes.

Thanks

On 4 September 2010 16:38, wrote:

> Alex Brown wrote:
>
> > 2) Can anyone give suggestions on how to make a virtual
> > serial driver talk to a user mode application other than the
> > one that thinks its accessing the com port.
>
> Well, you have a few options here.
>
> 1) Raw PDO
>
> 2) Control device
>
> 3) Enumerate the virtual serial device from a root-enumerated bus driver,
> and open the bus driver’s FDO to feed it data.
>
> 4) As a corollary to #3, you can toss your virtual serial driver, and just
> usbser.sys. Then you just need to write the bus driver (which you might
> find hard to believe, but this will be much easier), and have the contract
> on its child PDO’s be CDC ACM URB’s. Then you get all the serial
> functionality for free, and an easy path to feed it data as well.
>
> > 3) Does anyone know a work around for the MSCOMM /
> > Pending read request problem when using UMDF?
>
> I don’t think it’s solvable in UMDF, primarily because you would need to
> complete the incoming read IRP directly in the kernel driver’s dispatch
> routine. For this to work, the UMDF reflector would have to call directly
> into some userspace callback right from kernel mode. While we all get a
> good laugh when the Wipro folks post this kind of code, I think it’s a
> non-starter.
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Alex Brown wrote:

I have used usbser.sys to talk to real hardware in the past
and have had some strange behaviour at times.

What was the strange behaviour?

Oh, there was two things:

  1. usbser does not support removal of a device very well. I was not using
    any filter drivers. This is not a problem in this applications

  2. we had some issues with data being sent up the USB pipe too quickly. Our
    embedded device was producing data quicker than what would normally happen
    at a set baud rate and the software (notably mscomm) would fall over.

I have the potential to run into point 2. in some cases it helps because
things run quicker than they are supposed to, this = happy sales dpt. I have
a way of dealing with it though.

While I have your attention, can you point me towards any examples of Fake
USB bus drivers. not something I have written before

Alex

On 6 September 2010 16:34, wrote:

> Alex Brown wrote:
>
> > I have used usbser.sys to talk to real hardware in the past
> > and have had some strange behaviour at times.
>
> What was the strange behaviour?
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Ok, I’m going to put this out there.

I have taken Chri’s advice and written a bus driver using Toaster as a
guide. I have got the driver to create a PDO. I have an INF that installs
usbser.sys on that device.

to my supprise (sarcasm) usbser.sys failed to load (Error code 10)

There is one part of Chris’s post I am a little confused over:

and have the contract on its child PDO’s be CDC ACM URB’s.

I cannot for the life of me work out how to define this “Contract”

A push in the right direction would be fantastic

On 6 September 2010 17:04, Alex Brown wrote:

> Oh, there was two things:
>
> 1) usbser does not support removal of a device very well. I was not using
> any filter drivers. This is not a problem in this applications
>
> 2) we had some issues with data being sent up the USB pipe too quickly. Our
> embedded device was producing data quicker than what would normally happen
> at a set baud rate and the software (notably mscomm) would fall over.
>
> I have the potential to run into point 2. in some cases it helps because
> things run quicker than they are supposed to, this = happy sales dpt. I have
> a way of dealing with it though.
>
> While I have your attention, can you point me towards any examples of Fake
> USB bus drivers. not something I have written before
>
> Alex
>
>
> On 6 September 2010 16:34, wrote:
>
>> Alex Brown wrote:
>>
>> > I have used usbser.sys to talk to real hardware in the past
>> > and have had some strange behaviour at times.
>>
>> What was the strange behaviour?
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> 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
>>
>
>

You need to implement the accepting end of URB processing, ie process incoming urb requests in the pdo and complete them appropriately. Note that usbser is not a full fledged COM port implemention. Rather it is just enough to implement a modem and nothig more.

d

dent from a phpne with no keynoard


From: Alex Brown
Sent: September 07, 2010 7:10 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland

Ok, I’m going to put this out there.

I have taken Chri’s advice and written a bus driver using Toaster as a guide. I have got the driver to create a PDO. I have an INF that installs usbser.sys on that device.

to my supprise (sarcasm) usbser.sys failed to load (Error code 10)

There is one part of Chris’s post I am a little confused over:

and have the contract on its child PDO’s be CDC ACM URB’s.

I cannot for the life of me work out how to define this “Contract”

A push in the right direction would be fantastic

On 6 September 2010 17:04, Alex Brown > wrote:
Oh, there was two things:

1) usbser does not support removal of a device very well. I was not using any filter drivers. This is not a problem in this applications

2) we had some issues with data being sent up the USB pipe too quickly. Our embedded device was producing data quicker than what would normally happen at a set baud rate and the software (notably mscomm) would fall over.

I have the potential to run into point 2. in some cases it helps because things run quicker than they are supposed to, this = happy sales dpt. I have a way of dealing with it though.

While I have your attention, can you point me towards any examples of Fake USB bus drivers. not something I have written before

Alex

On 6 September 2010 16:34, > wrote:
Alex Brown wrote:

> I have used usbser.sys to talk to real hardware in the past
> and have had some strange behaviour at times.

What was the strange behaviour?


NTDEV is sponsored by OSR

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

— NTDEV is sponsored by OSR 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

Right,

the problem I have at the moment is getting my PDO to respond to any
requests what so ever.

I am implementing the Read, write and IOControl events but none of the fire.

Alex

On 7 September 2010 15:49, Doron Holan wrote:

> You need to implement the accepting end of URB processing, ie process
> incoming urb requests in the pdo and complete them appropriately. Note that
> usbser is not a full fledged COM port implemention. Rather it is just enough
> to implement a modem and nothig more.
>
> d
>
> dent from a phpne with no keynoard
>
> ------------------------------
> From: Alex Brown
> Sent: September 07, 2010 7:10 AM
> To: Windows System Software Devs Interest List
>
> Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland
>
> Ok, I’m going to put this out there.
>
> I have taken Chri’s advice and written a bus driver using Toaster as a
> guide. I have got the driver to create a PDO. I have an INF that installs
> usbser.sys on that device.
>
> to my supprise (sarcasm) usbser.sys failed to load (Error code 10)
>
> There is one part of Chris’s post I am a little confused over:
>
> and have the contract on its child PDO’s be CDC ACM URB’s.
>
> I cannot for the life of me work out how to define this “Contract”
>
> A push in the right direction would be fantastic
>
> On 6 September 2010 17:04, Alex Brown wrote:
>
>> Oh, there was two things:
>>
>> 1) usbser does not support removal of a device very well. I was not
>> using any filter drivers. This is not a problem in this applications
>>
>> 2) we had some issues with data being sent up the USB pipe too quickly.
>> Our embedded device was producing data quicker than what would normally
>> happen at a set baud rate and the software (notably mscomm) would fall over.
>>
>> I have the potential to run into point 2. in some cases it helps because
>> things run quicker than they are supposed to, this = happy sales dpt. I have
>> a way of dealing with it though.
>>
>> While I have your attention, can you point me towards any examples of
>> Fake USB bus drivers. not something I have written before
>>
>> Alex
>>
>>
>> On 6 September 2010 16:34, wrote:
>>
>>> Alex Brown wrote:
>>>
>>> > I have used usbser.sys to talk to real hardware in the past
>>> > and have had some strange behaviour at times.
>>>
>>> What was the strange behaviour?
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> 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
>>>
>>
>>
> — NTDEV is sponsored by OSR 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
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Alex Brown wrote:

  1. usbser does not support removal of a device very well. I
    was not using any filter drivers. This is not a problem in this
    applications

What sort of “support” were you looking for? If you register for device notifications, that’s your indication to close your handle when the device goes away. Once you do that, the driver will unload. I’ve never had a problem here.

  1. we had some issues with data being sent up the USB pipe
    too quickly. Our embedded device was producing data quicker
    than what would normally happen at a set baud rate and the
    software (notably mscomm) would fall over.

usbser will send your baud rate requests down the wire (with SET_LINE_CODING or whatever it is), but it doesn’t throttle the rate of data sent or received.

Alex Brown wrote:

the problem I have at the moment is getting my PDO to respond
to any requests what so ever.

I am implementing the Read, write and IOControl events but none
of the[m] fire.

Right: you’re actually going to want to watch for *internal* IOCTL requests, namely of the kind seen here:

http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx

The vast majority of them will be submit URB internal IOCTLs, which are documented here:

http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx

You should expect to respond to these sorts of requests:

  1. Get device descriptor

  2. Get config descriptor (first 9 bytes, then the whole thing). Your config descriptor should appear as a CDC ACM device as specified in usbcdc11.pdf.

  3. Set config (passing back your choice of pipe handle values, etc.)

  4. URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)

  5. URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving actual data, both asynchronous notifications i.e. DSR and the actual port data itself)

… and so on

I guess this is a little more complicated than I first thought/remembered, but I still think it will be easier than writing your own serial driver, the serial driver semantics are extremely complicated and very hard to get totally right (especially if you are dealing with esoteric user-mode code like mscomm32.ocx).

Your other alternative is to start with the KMDF serial sample and rip out all the hardware-based lower edge code and replace it with interaction to a raw PDO or control device. However, you would still have to go through all the complexity of defining a contract between usermode and the raw PDO to indicate and receive port data and asynchronous notifications. In my opinion it’s easier to integrate this into essentially a blank slate (your bus driver) rather than placing it into two dozen different spots in a driver that you did not write.

Also, usbser and the WDK serial driver do not behave exactly the same and have different semantics in various situations so if you are dealing with existing code that was using usbser, starting from serial may be painful.

I’m not fining it as bad as I initally thought I would Chris.

Its knowing things like you need to look for *internal* IOCTLS. I am happy
with the approch I am taking.

The applications connecting to the COM port will be expecting it to be a
modem so I think its the right choice.

Just for interest, the two things we found before with usbser:

  1. we got over this detachment problem in the end.

  2. The issue we saw was caused by usbser not throttling. So mscomm.osx
    (groan) thought we where connected at 9600 baud. our application send
    64bytes in every read. this lead to vb6 and mscomm falling over. We switched
    to a .net com port that could handle a full 2Mbp/s when connected at 9600.

We also throttled the data back at the embedded device end :slight_smile:

On 7 September 2010 16:37, wrote:

> Alex Brown wrote:
>
> > the problem I have at the moment is getting my PDO to respond
> > to any requests what so ever.
> >
> > I am implementing the Read, write and IOControl events but none
> > of the[m] fire.
>
> Right: you’re actually going to want to watch for internal IOCTL
> requests, namely of the kind seen here:
>
> http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx
>
> The vast majority of them will be submit URB internal IOCTLs, which are
> documented here:
>
> http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx
>
> You should expect to respond to these sorts of requests:
>
> 1) Get device descriptor
>
> 2) Get config descriptor (first 9 bytes, then the whole thing). Your
> config descriptor should appear as a CDC ACM device as specified in
> usbcdc11.pdf.
>
> 3) Set config (passing back your choice of pipe handle values, etc.)
>
> 4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)
>
> 5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving
> actual data, both asynchronous notifications i.e. DSR and the actual port
> data itself)
>
> … and so on
>
> I guess this is a little more complicated than I first thought/remembered,
> but I still think it will be easier than writing your own serial driver, the
> serial driver semantics are extremely complicated and very hard to get
> totally right (especially if you are dealing with esoteric user-mode code
> like mscomm32.ocx).
>
> Your other alternative is to start with the KMDF serial sample and rip out
> all the hardware-based lower edge code and replace it with interaction to a
> raw PDO or control device. However, you would still have to go through all
> the complexity of defining a contract between usermode and the raw PDO to
> indicate and receive port data and asynchronous notifications. In my
> opinion it’s easier to integrate this into essentially a blank slate (your
> bus driver) rather than placing it into two dozen different spots in a
> driver that you did not write.
>
> Also, usbser and the WDK serial driver do not behave exactly the same and
> have different semantics in various situations so if you are dealing with
> existing code that was using usbser, starting from serial may be painful.
>
> —
> NTDEV is sponsored by OSR
>
> 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
>

Hi Again,

I need a little more guidance. so far I have managed to respond the the
various URB requests and get to the stage where I’m getting bulk transfers.

so far the Bulk OUT is working OK. I can read the buffer the child driver
has sent and can get the text out using kdPrint (I know this
is dangerous and its not staying, it was just a test)

what has stumped me is the IN. I have tried a number of approaches when
handling this one

Approach 1:

  • Request comes in
  • Look to see if data is available
  • if data is available send, else complete the request
    with .TransferBufferLength=0;

This caused the system to hit 100% CPU usage, hard to tell what was
happening but I am assuming USBSER.sys (the child driver)
was continually sending IN requests

Approach 2:

  • Request comes in
  • If no data is available forward the request to a manual queue
  • when data is available grab the request, copy data to .TransfereBuffer,
    set .TransferBufferLength and complete the request

The problem I get with this approach is I get a bug check (0c0000008F,
0xC0000005) Access Violation when i’m trying to read or write to the urb.
The urb has been pulled from the requests parameters.

Approach 3:

  • When an in request comes in poll to see if data has arrived.

It did not suppose me that this locked the CPU to 100% and didn’t work. I
couldnt find a way of putting the thread to sleep (sorry about
the terminology, I’m used to .net) so other threads could use the cpu.

At the moment the data to be sent on an IN request is being generated by the
driver. its a bit dumb at the moment, just trying to sent OK
when I see a on the OUT transaction.

Any help is appreciated

On 7 September 2010 16:46, Alex Brown wrote:

> I’m not fining it as bad as I initally thought I would Chris.
>
> Its knowing things like you need to look for internal IOCTLS. I am happy
> with the approch I am taking.
>
> The applications connecting to the COM port will be expecting it to be a
> modem so I think its the right choice.
>
> Just for interest, the two things we found before with usbser:
>
> 1) we got over this detachment problem in the end.
>
> 2) The issue we saw was caused by usbser not throttling. So mscomm.osx
> (groan) thought we where connected at 9600 baud. our application send
> 64bytes in every read. this lead to vb6 and mscomm falling over. We switched
> to a .net com port that could handle a full 2Mbp/s when connected at 9600.
>
> We also throttled the data back at the embedded device end :slight_smile:
>
> On 7 September 2010 16:37, wrote:
>
>> Alex Brown wrote:
>>
>> > the problem I have at the moment is getting my PDO to respond
>> > to any requests what so ever.
>> >
>> > I am implementing the Read, write and IOControl events but none
>> > of the[m] fire.
>>
>> Right: you’re actually going to want to watch for internal IOCTL
>> requests, namely of the kind seen here:
>>
>> http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx
>>
>> The vast majority of them will be submit URB internal IOCTLs, which are
>> documented here:
>>
>> http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx
>>
>> You should expect to respond to these sorts of requests:
>>
>> 1) Get device descriptor
>>
>> 2) Get config descriptor (first 9 bytes, then the whole thing). Your
>> config descriptor should appear as a CDC ACM device as specified in
>> usbcdc11.pdf.
>>
>> 3) Set config (passing back your choice of pipe handle values, etc.)
>>
>> 4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)
>>
>> 5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving
>> actual data, both asynchronous notifications i.e. DSR and the actual port
>> data itself)
>>
>> … and so on
>>
>> I guess this is a little more complicated than I first thought/remembered,
>> but I still think it will be easier than writing your own serial driver, the
>> serial driver semantics are extremely complicated and very hard to get
>> totally right (especially if you are dealing with esoteric user-mode code
>> like mscomm32.ocx).
>>
>> Your other alternative is to start with the KMDF serial sample and rip out
>> all the hardware-based lower edge code and replace it with interaction to a
>> raw PDO or control device. However, you would still have to go through all
>> the complexity of defining a contract between usermode and the raw PDO to
>> indicate and receive port data and asynchronous notifications. In my
>> opinion it’s easier to integrate this into essentially a blank slate (your
>> bus driver) rather than placing it into two dozen different spots in a
>> driver that you did not write.
>>
>> Also, usbser and the WDK serial driver do not behave exactly the same and
>> have different semantics in various situations so if you are dealing with
>> existing code that was using usbser, starting from serial may be painful.
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> 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
>>
>
>

Approach 2 is the way to go, but it looks like you haven’t got it right.

Do check to insure that the user memory involved in reading IN data is persistent until the read completes.

If you are using an OVERLAPPED structure, don’t allocate it on the stack. Don’t have your read buffer on the stack.

Take a look at some of the WDK documentation and samples that perform asynchronous I/O.

Good luck,

Thomas F. Divine

From: Alex Brown
Sent: Friday, September 10, 2010 7:18 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland

Hi Again,

I need a little more guidance. so far I have managed to respond the the various URB requests and get to the stage where I’m getting bulk transfers.

so far the Bulk OUT is working OK. I can read the buffer the child driver has sent and can get the text out using kdPrint (I know this is dangerous and its not staying, it was just a test)

what has stumped me is the IN. I have tried a number of approaches when handling this one

Approach 1:
a… Request comes in
b… Look to see if data is available
c… if data is available send, else complete the request with .TransferBufferLength=0;
This caused the system to hit 100% CPU usage, hard to tell what was happening but I am assuming USBSER.sys (the child driver) was continually sending IN requests

Approach 2:
a… Request comes in
b… If no data is available forward the request to a manual queue
c… when data is available grab the request, copy data to .TransfereBuffer, set .TransferBufferLength and complete the request
The problem I get with this approach is I get a bug check (0c0000008F, 0xC0000005) Access Violation when i’m trying to read or write to the urb. The urb has been pulled from the requests parameters.

Approach 3:
a… When an in request comes in poll to see if data has arrived.
It did not suppose me that this locked the CPU to 100% and didn’t work. I couldnt find a way of putting the thread to sleep (sorry about the terminology, I’m used to .net) so other threads could use the cpu.

At the moment the data to be sent on an IN request is being generated by the driver. its a bit dumb at the moment, just trying to sent OK when I see a on the OUT transaction.

Any help is appreciated

On 7 September 2010 16:46, Alex Brown wrote:

I’m not fining it as bad as I initally thought I would Chris.

Its knowing things like you need to look for internal IOCTLS. I am happy with the approch I am taking.

The applications connecting to the COM port will be expecting it to be a modem so I think its the right choice.

Just for interest, the two things we found before with usbser:

1) we got over this detachment problem in the end.

2) The issue we saw was caused by usbser not throttling. So mscomm.osx (groan) thought we where connected at 9600 baud. our application send 64bytes in every read. this lead to vb6 and mscomm falling over. We switched to a .net com port that could handle a full 2Mbp/s when connected at 9600.

We also throttled the data back at the embedded device end :slight_smile:

On 7 September 2010 16:37, wrote:

Alex Brown wrote:

> the problem I have at the moment is getting my PDO to respond
> to any requests what so ever.
>
> I am implementing the Read, write and IOControl events but none

> of the[m] fire.

Right: you’re actually going to want to watch for internal IOCTL requests, namely of the kind seen here:

http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx

The vast majority of them will be submit URB internal IOCTLs, which are documented here:

http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx

You should expect to respond to these sorts of requests:

1) Get device descriptor

2) Get config descriptor (first 9 bytes, then the whole thing). Your config descriptor should appear as a CDC ACM device as specified in usbcdc11.pdf.

3) Set config (passing back your choice of pipe handle values, etc.)

4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)

5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving actual data, both asynchronous notifications i.e. DSR and the actual port data itself)

… and so on

I guess this is a little more complicated than I first thought/remembered, but I still think it will be easier than writing your own serial driver, the serial driver semantics are extremely complicated and very hard to get totally right (especially if you are dealing with esoteric user-mode code like mscomm32.ocx).

Your other alternative is to start with the KMDF serial sample and rip out all the hardware-based lower edge code and replace it with interaction to a raw PDO or control device. However, you would still have to go through all the complexity of defining a contract between usermode and the raw PDO to indicate and receive port data and asynchronous notifications. In my opinion it’s easier to integrate this into essentially a blank slate (your bus driver) rather than placing it into two dozen different spots in a driver that you did not write.

Also, usbser and the WDK serial driver do not behave exactly the same and have different semantics in various situations so if you are dealing with existing code that was using usbser, starting from serial may be painful.


NTDEV is sponsored by OSR

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

— NTDEV is sponsored by OSR 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

Thanks for the reply.

I think the user memory is not being persisted.

I get the bug check from the following line of code

if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)

just for completions sake this is what im doing before:

WdfRequestGetParameters(PendingRead,&PendingReadParams);
PendingReadURB = PendingReadParams.Parameters.Others.Arg1;

if (PendingReadURB != NULL)
{
if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
is it possible the request parameters are being lost? Do I need to reply to
the child driver to say this request is pending. I thought the framework did
that for me or am I wrong there?

10 September 2010 14:16, Thomas F. Divine wrote:

> Approach 2 is the way to go, but it looks like you haven’t got it right.
>
> Do check to insure that the user memory involved in reading IN data is
> persistent until the read completes.
>
> If you are using an OVERLAPPED structure, don’t allocate it on the stack.
> Don’t have your read buffer on the stack.
>
> Take a look at some of the WDK documentation and samples that perform
> asynchronous I/O.
>
> Good luck,
>
> Thomas F. Divine
>
>
> From: Alex Brown
> Sent: Friday, September 10, 2010 7:18 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland
>
> Hi Again,
>
> I need a little more guidance. so far I have managed to respond the the
> various URB requests and get to the stage where I’m getting bulk transfers.
>
> so far the Bulk OUT is working OK. I can read the buffer the child driver
> has sent and can get the text out using kdPrint (I know this
> is dangerous and its not staying, it was just a test)
>
> what has stumped me is the IN. I have tried a number of approaches when
> handling this one
>
> Approach 1:
>
> - Request comes in
> - Look to see if data is available
> - if data is available send, else complete the request
> with .TransferBufferLength=0;
>
> This caused the system to hit 100% CPU usage, hard to tell what was
> happening but I am assuming USBSER.sys (the child driver)
> was continually sending IN requests
>
> Approach 2:
>
> - Request comes in
> - If no data is available forward the request to a manual queue
> - when data is available grab the request, copy data to
> .TransfereBuffer, set .TransferBufferLength and complete the request
>
> The problem I get with this approach is I get a bug check (0c0000008F,
> 0xC0000005) Access Violation when i’m trying to read or write to the urb.
> The urb has been pulled from the requests parameters.
>
> Approach 3:
>
> - When an in request comes in poll to see if data has arrived.
>
> It did not suppose me that this locked the CPU to 100% and didn’t work. I
> couldnt find a way of putting the thread to sleep (sorry about
> the terminology, I’m used to .net) so other threads could use the cpu.
>
> At the moment the data to be sent on an IN request is being generated by
> the driver. its a bit dumb at the moment, just trying to sent
> OK when I see a on the OUT transaction.
>
> Any help is appreciated
>
> On 7 September 2010 16:46, Alex Brown wrote:
>
>> I’m not fining it as bad as I initally thought I would Chris.
>>
>> Its knowing things like you need to look for internal IOCTLS. I am happy
>> with the approch I am taking.
>>
>> The applications connecting to the COM port will be expecting it to be a
>> modem so I think its the right choice.
>>
>> Just for interest, the two things we found before with usbser:
>>
>> 1) we got over this detachment problem in the end.
>>
>> 2) The issue we saw was caused by usbser not throttling. So mscomm.osx
>> (groan) thought we where connected at 9600 baud. our application send
>> 64bytes in every read. this lead to vb6 and mscomm falling over. We switched
>> to a .net com port that could handle a full 2Mbp/s when connected at 9600.
>>
>> We also throttled the data back at the embedded device end :slight_smile:
>>
>> On 7 September 2010 16:37, wrote:
>>
>>> Alex Brown wrote:
>>>
>>> > the problem I have at the moment is getting my PDO to respond
>>> > to any requests what so ever.
>>> >
>>> > I am implementing the Read, write and IOControl events but none
>>> > of the[m] fire.
>>>
>>> Right: you’re actually going to want to watch for internal IOCTL
>>> requests, namely of the kind seen here:
>>>
>>> http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx
>>>
>>> The vast majority of them will be submit URB internal IOCTLs, which are
>>> documented here:
>>>
>>> http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx
>>>
>>> You should expect to respond to these sorts of requests:
>>>
>>> 1) Get device descriptor
>>>
>>> 2) Get config descriptor (first 9 bytes, then the whole thing). Your
>>> config descriptor should appear as a CDC ACM device as specified in
>>> usbcdc11.pdf.
>>>
>>> 3) Set config (passing back your choice of pipe handle values, etc.)
>>>
>>> 4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)
>>>
>>> 5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving
>>> actual data, both asynchronous notifications i.e. DSR and the actual port
>>> data itself)
>>>
>>> … and so on
>>>
>>> I guess this is a little more complicated than I first
>>> thought/remembered, but I still think it will be easier than writing your
>>> own serial driver, the serial driver semantics are extremely complicated and
>>> very hard to get totally right (especially if you are dealing with esoteric
>>> user-mode code like mscomm32.ocx).
>>>
>>> Your other alternative is to start with the KMDF serial sample and rip
>>> out all the hardware-based lower edge code and replace it with interaction
>>> to a raw PDO or control device. However, you would still have to go through
>>> all the complexity of defining a contract between usermode and the raw PDO
>>> to indicate and receive port data and asynchronous notifications. In my
>>> opinion it’s easier to integrate this into essentially a blank slate (your
>>> bus driver) rather than placing it into two dozen different spots in a
>>> driver that you did not write.
>>>
>>> Also, usbser and the WDK serial driver do not behave exactly the same and
>>> have different semantics in various situations so if you are dealing with
>>> existing code that was using usbser, starting from serial may be painful.
>>>
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> 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
>>>
>>
>>
> — NTDEV is sponsored by OSR 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
> —
> NTDEV is sponsored by OSR
>
> 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
>

What is the value of TransferBufferMdl?

Mark Roddy

On Fri, Sep 10, 2010 at 9:59 AM, Alex Brown wrote:

> Thanks for the reply.
>
> I think the user memory is not being persisted.
>
> I get the bug check from the following line of code
>
> if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
>
> just for completions sake this is what im doing before:
>
> WdfRequestGetParameters(PendingRead,&PendingReadParams);
> PendingReadURB = PendingReadParams.Parameters.Others.Arg1;
>
> if (PendingReadURB != NULL)
> {
> if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
> is it possible the request parameters are being lost? Do I need to reply
> to the child driver to say this request is pending. I thought the framework
> did that for me or am I wrong there?
>
> 10 September 2010 14:16, Thomas F. Divine wrote:
>
>> Approach 2 is the way to go, but it looks like you haven’t got it right.
>>
>> Do check to insure that the user memory involved in reading IN data is
>> persistent until the read completes.
>>
>> If you are using an OVERLAPPED structure, don’t allocate it on the stack.
>> Don’t have your read buffer on the stack.
>>
>> Take a look at some of the WDK documentation and samples that perform
>> asynchronous I/O.
>>
>> Good luck,
>>
>> Thomas F. Divine
>>
>>
>> From: Alex Brown
>> Sent: Friday, September 10, 2010 7:18 AM
>> To: Windows System Software Devs Interest List
>> Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland
>>
>> Hi Again,
>>
>> I need a little more guidance. so far I have managed to respond the the
>> various URB requests and get to the stage where I’m getting bulk transfers.
>>
>> so far the Bulk OUT is working OK. I can read the buffer the child driver
>> has sent and can get the text out using kdPrint (I know this
>> is dangerous and its not staying, it was just a test)
>>
>> what has stumped me is the IN. I have tried a number of approaches when
>> handling this one
>>
>> Approach 1:
>>
>> - Request comes in
>> - Look to see if data is available
>> - if data is available send, else complete the request
>> with .TransferBufferLength=0;
>>
>> This caused the system to hit 100% CPU usage, hard to tell what was
>> happening but I am assuming USBSER.sys (the child driver)
>> was continually sending IN requests
>>
>> Approach 2:
>>
>> - Request comes in
>> - If no data is available forward the request to a manual queue
>> - when data is available grab the request, copy data to
>> .TransfereBuffer, set .TransferBufferLength and complete the request
>>
>> The problem I get with this approach is I get a bug check (0c0000008F,
>> 0xC0000005) Access Violation when i’m trying to read or write to the urb.
>> The urb has been pulled from the requests parameters.
>>
>> Approach 3:
>>
>> - When an in request comes in poll to see if data has arrived.
>>
>> It did not suppose me that this locked the CPU to 100% and didn’t work. I
>> couldnt find a way of putting the thread to sleep (sorry about
>> the terminology, I’m used to .net) so other threads could use the cpu.
>>
>> At the moment the data to be sent on an IN request is being generated by
>> the driver. its a bit dumb at the moment, just trying to sent
>> OK when I see a on the OUT transaction.
>>
>> Any help is appreciated
>>
>> On 7 September 2010 16:46, Alex Brown wrote:
>>
>>> I’m not fining it as bad as I initally thought I would Chris.
>>>
>>> Its knowing things like you need to look for internal IOCTLS. I am
>>> happy with the approch I am taking.
>>>
>>> The applications connecting to the COM port will be expecting it to be a
>>> modem so I think its the right choice.
>>>
>>> Just for interest, the two things we found before with usbser:
>>>
>>> 1) we got over this detachment problem in the end.
>>>
>>> 2) The issue we saw was caused by usbser not throttling. So mscomm.osx
>>> (groan) thought we where connected at 9600 baud. our application send
>>> 64bytes in every read. this lead to vb6 and mscomm falling over. We switched
>>> to a .net com port that could handle a full 2Mbp/s when connected at 9600.
>>>
>>> We also throttled the data back at the embedded device end :slight_smile:
>>>
>>> On 7 September 2010 16:37, wrote:
>>>
>>>> Alex Brown wrote:
>>>>
>>>> > the problem I have at the moment is getting my PDO to respond
>>>> > to any requests what so ever.
>>>> >
>>>> > I am implementing the Read, write and IOControl events but none
>>>> > of the[m] fire.
>>>>
>>>> Right: you’re actually going to want to watch for internal IOCTL
>>>> requests, namely of the kind seen here:
>>>>
>>>> http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx
>>>>
>>>> The vast majority of them will be submit URB internal IOCTLs, which are
>>>> documented here:
>>>>
>>>> http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx
>>>>
>>>> You should expect to respond to these sorts of requests:
>>>>
>>>> 1) Get device descriptor
>>>>
>>>> 2) Get config descriptor (first 9 bytes, then the whole thing). Your
>>>> config descriptor should appear as a CDC ACM device as specified in
>>>> usbcdc11.pdf.
>>>>
>>>> 3) Set config (passing back your choice of pipe handle values, etc.)
>>>>
>>>> 4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)
>>>>
>>>> 5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving
>>>> actual data, both asynchronous notifications i.e. DSR and the actual port
>>>> data itself)
>>>>
>>>> … and so on
>>>>
>>>> I guess this is a little more complicated than I first
>>>> thought/remembered, but I still think it will be easier than writing your
>>>> own serial driver, the serial driver semantics are extremely complicated and
>>>> very hard to get totally right (especially if you are dealing with esoteric
>>>> user-mode code like mscomm32.ocx).
>>>>
>>>> Your other alternative is to start with the KMDF serial sample and rip
>>>> out all the hardware-based lower edge code and replace it with interaction
>>>> to a raw PDO or control device. However, you would still have to go through
>>>> all the complexity of defining a contract between usermode and the raw PDO
>>>> to indicate and receive port data and asynchronous notifications. In my
>>>> opinion it’s easier to integrate this into essentially a blank slate (your
>>>> bus driver) rather than placing it into two dozen different spots in a
>>>> driver that you did not write.
>>>>
>>>> Also, usbser and the WDK serial driver do not behave exactly the same
>>>> and have different semantics in various situations so if you are dealing
>>>> with existing code that was using usbser, starting from serial may be
>>>> painful.
>>>>
>>>> —
>>>> NTDEV is sponsored by OSR
>>>>
>>>> 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
>>>>
>>>
>>>
>> — NTDEV is sponsored by OSR 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
>> —
>> NTDEV is sponsored by OSR
>>
>> 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
>>
>
> — NTDEV is sponsored by OSR 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

Hi

Right, I have found the problem.

I was not calling WDF_REQUEST_PARAMETERS_INIT before
calling WdfRequestGetParameters. Thats what happens when you dont have
enough coffee.

I am now getting TransferBuffer == NULL and TransferBufferMDL == NULL. Only
just got to this stage… as always thanks for the help. if anyone has any
clues for the latest im grateful

On 10 September 2010 15:31, Mark Roddy wrote:

> What is the value of TransferBufferMdl?
>
> Mark Roddy
>
>
> On Fri, Sep 10, 2010 at 9:59 AM, Alex Brown wrote:
>
>> Thanks for the reply.
>>
>> I think the user memory is not being persisted.
>>
>> I get the bug check from the following line of code
>>
>> if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
>>
>> just for completions sake this is what im doing before:
>>
>> WdfRequestGetParameters(PendingRead,&PendingReadParams);
>> PendingReadURB = PendingReadParams.Parameters.Others.Arg1;
>>
>> if (PendingReadURB != NULL)
>> {
>> if (PendingReadURB->UrbBulkOrInterruptTransfer.TransferBuffer != NULL)
>> is it possible the request parameters are being lost? Do I need to reply
>> to the child driver to say this request is pending. I thought the framework
>> did that for me or am I wrong there?
>>
>> 10 September 2010 14:16, Thomas F. Divine wrote:
>>
>>> Approach 2 is the way to go, but it looks like you haven’t got it
>>> right.
>>>
>>> Do check to insure that the user memory involved in reading IN data is
>>> persistent until the read completes.
>>>
>>> If you are using an OVERLAPPED structure, don’t allocate it on the stack.
>>> Don’t have your read buffer on the stack.
>>>
>>> Take a look at some of the WDK documentation and samples that perform
>>> asynchronous I/O.
>>>
>>> Good luck,
>>>
>>> Thomas F. Divine
>>>
>>>
>>> From: Alex Brown
>>> Sent: Friday, September 10, 2010 7:18 AM
>>> To: Windows System Software Devs Interest List
>>> Subject: Re: [ntdev] Virtual KMDF and IPC to application in userland
>>>
>>> Hi Again,
>>>
>>> I need a little more guidance. so far I have managed to respond the the
>>> various URB requests and get to the stage where I’m getting bulk transfers.
>>>
>>> so far the Bulk OUT is working OK. I can read the buffer the child driver
>>> has sent and can get the text out using kdPrint (I know this
>>> is dangerous and its not staying, it was just a test)
>>>
>>> what has stumped me is the IN. I have tried a number of approaches when
>>> handling this one
>>>
>>> Approach 1:
>>>
>>> - Request comes in
>>> - Look to see if data is available
>>> - if data is available send, else complete the request
>>> with .TransferBufferLength=0;
>>>
>>> This caused the system to hit 100% CPU usage, hard to tell what was
>>> happening but I am assuming USBSER.sys (the child driver)
>>> was continually sending IN requests
>>>
>>> Approach 2:
>>>
>>> - Request comes in
>>> - If no data is available forward the request to a manual queue
>>> - when data is available grab the request, copy data to
>>> .TransfereBuffer, set .TransferBufferLength and complete the request
>>>
>>> The problem I get with this approach is I get a bug check (0c0000008F,
>>> 0xC0000005) Access Violation when i’m trying to read or write to the urb.
>>> The urb has been pulled from the requests parameters.
>>>
>>> Approach 3:
>>>
>>> - When an in request comes in poll to see if data has arrived.
>>>
>>> It did not suppose me that this locked the CPU to 100% and didn’t work. I
>>> couldnt find a way of putting the thread to sleep (sorry about
>>> the terminology, I’m used to .net) so other threads could use the cpu.
>>>
>>> At the moment the data to be sent on an IN request is being generated by
>>> the driver. its a bit dumb at the moment, just trying to sent
>>> OK when I see a on the OUT transaction.
>>>
>>> Any help is appreciated
>>>
>>> On 7 September 2010 16:46, Alex Brown wrote:
>>>
>>>> I’m not fining it as bad as I initally thought I would Chris.
>>>>
>>>> Its knowing things like you need to look for internal IOCTLS. I am
>>>> happy with the approch I am taking.
>>>>
>>>> The applications connecting to the COM port will be expecting it to be a
>>>> modem so I think its the right choice.
>>>>
>>>> Just for interest, the two things we found before with usbser:
>>>>
>>>> 1) we got over this detachment problem in the end.
>>>>
>>>> 2) The issue we saw was caused by usbser not throttling. So mscomm.osx
>>>> (groan) thought we where connected at 9600 baud. our application send
>>>> 64bytes in every read. this lead to vb6 and mscomm falling over. We switched
>>>> to a .net com port that could handle a full 2Mbp/s when connected at 9600.
>>>>
>>>> We also throttled the data back at the embedded device end :slight_smile:
>>>>
>>>> On 7 September 2010 16:37, wrote:
>>>>
>>>>> Alex Brown wrote:
>>>>>
>>>>> > the problem I have at the moment is getting my PDO to respond
>>>>> > to any requests what so ever.
>>>>> >
>>>>> > I am implementing the Read, write and IOControl events but none
>>>>> > of the[m] fire.
>>>>>
>>>>> Right: you’re actually going to want to watch for internal IOCTL
>>>>> requests, namely of the kind seen here:
>>>>>
>>>>> http://msdn.microsoft.com/en-us/library/ff537421(VS.85).aspx
>>>>>
>>>>> The vast majority of them will be submit URB internal IOCTLs, which are
>>>>> documented here:
>>>>>
>>>>> http://msdn.microsoft.com/en-us/library/ff538923(VS.85).aspx
>>>>>
>>>>> You should expect to respond to these sorts of requests:
>>>>>
>>>>> 1) Get device descriptor
>>>>>
>>>>> 2) Get config descriptor (first 9 bytes, then the whole thing). Your
>>>>> config descriptor should appear as a CDC ACM device as specified in
>>>>> usbcdc11.pdf.
>>>>>
>>>>> 3) Set config (passing back your choice of pipe handle values, etc.)
>>>>>
>>>>> 4) URB_FUNCTION_CLASS_* (for SET_LINE_CODING et. al)
>>>>>
>>>>> 5) URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER (for sending and receiving
>>>>> actual data, both asynchronous notifications i.e. DSR and the actual port
>>>>> data itself)
>>>>>
>>>>> … and so on
>>>>>
>>>>> I guess this is a little more complicated than I first
>>>>> thought/remembered, but I still think it will be easier than writing your
>>>>> own serial driver, the serial driver semantics are extremely complicated and
>>>>> very hard to get totally right (especially if you are dealing with esoteric
>>>>> user-mode code like mscomm32.ocx).
>>>>>
>>>>> Your other alternative is to start with the KMDF serial sample and rip
>>>>> out all the hardware-based lower edge code and replace it with interaction
>>>>> to a raw PDO or control device. However, you would still have to go through
>>>>> all the complexity of defining a contract between usermode and the raw PDO
>>>>> to indicate and receive port data and asynchronous notifications. In my
>>>>> opinion it’s easier to integrate this into essentially a blank slate (your
>>>>> bus driver) rather than placing it into two dozen different spots in a
>>>>> driver that you did not write.
>>>>>
>>>>> Also, usbser and the WDK serial driver do not behave exactly the same
>>>>> and have different semantics in various situations so if you are dealing
>>>>> with existing code that was using usbser, starting from serial may be
>>>>> painful.
>>>>>
>>>>> —
>>>>> NTDEV is sponsored by OSR
>>>>>
>>>>> 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
>>>>>
>>>>
>>>>
>>> — NTDEV is sponsored by OSR 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
>>> —
>>> NTDEV is sponsored by OSR
>>>
>>> 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
>>>
>>
>> — NTDEV is sponsored by OSR 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
>
>
> — NTDEV is sponsored by OSR 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
>

Alex Brown wrote:

I am now getting TransferBuffer == NULL and TransferBufferMDL
== NULL. Only just got to this stage… as always thanks for the
help. if anyone has any clues for the latest im grateful

As others have already pointed, your approach #2 is correct whereas if you get a bulk read URB and you have no data, you store it away in a manual queue (for cancel safety) and complete it later once some data comes in.

(I’m not sure what Thomas Divine was talking about – these are I/O’s coming directly from usbser and have no relation to any userspace memory, in fact these URBs come without any userspace app even opening the device…)

Anyway, consider that you’re actually going to be getting *two* separate bulk read URBs here, one for the interrupt pipe (for async serial notifications), and one for the “data” pipe (i.e. the “OK” etc.). Are you responding to the right one? I don’t see how both TransferBuffer and the MDL can be null.

Also, the URB structure is really a union, did you inspect the header to see if it’s really a bulk/interrupt request? Keep in mind that you’re going to see some endpoint zero activity (to send the various CDC ACM control requests) before you ever get bulk URBs.