USB device detection via query registry information

Discussion in 'Windows Vista Drivers' started by kelly, Aug 27, 2008.

  1. kelly

    kelly Guest

    Besides using the WM_DEVICECHANGE to detect a USB device insert/remove,
    I tried to use scan registry information ""HARDWARE\\DEVICEMAP\\SERIALCOMM"
    to check, and using CreateFile() to open USB com port right after I find a
    new-coming device.
    So far, the method works fine in single-core PC while in dual-core PC, I
    found that if I invoke CreateFile() right after I find the device from
    registry, the operation will return error code 2 (implying that "The system
    cannot find the file specified.").
    If I delay to invoke CreateFile() by sleep(1), for example, the error will
    not occur again.
    Thus, I am wondering how the initialization process of underlying driver
    actually work.
    Is registry update operation finished before the the device driver is ready?
    Thanks!
     
    kelly, Aug 27, 2008
    #1
    1. Advertisements

  2. you are tying 2 different concept together and you are getting lucky that it
    works at all. the driver writes to the SERIALCOMM key as it is starting up.
    if you find the value in the middle of this start up and try to use it, yes
    it will fail on CreateFile. The documented and *correct* way is to use
    WM_DEVICECHANGE and register for device interface arrivals for the device(s)
    you care about opening.

    d
     
    Doron Holan [MSFT], Aug 27, 2008
    #2
    1. Advertisements

  3. I am not the OP, but I wanted to weigh in on this discussion of detecting
    new USB serial port (virtual com port).

    Serial ports seem to be a special case. While I've never gotten "file not
    found", I have been able to exclusively open the device interface path only
    to find that the SERENUM filter trashed my settings and installed a mouse
    driver (heuristic device identification failed -- the device is not a
    mouse).

    Next, WM_DEVICECHANGE is quite unreliable. It is necessary to also poll the
    list of ports (of course using SetupDi* functions, not registry access, and
    test the device state) because the user-mode WM_DEVICECHANGE handler needs
    an arbitrary amount of time to complete (by definition, user-mode processes
    can be blocked by higher-priority user or kernel tasks) and some device
    insertion notifications are not delivered in this case.

    Perhaps someone can explain why WM_DEVICECHANGE messages are sent rather
    than posted? The only purpose for sending I can think of would be to make
    configuration changes before the device becomes visible to other
    applications, but WM_DEVICECHANGE isn't usable for this purpose anyway
    because AFAICT the order apps receive WM_DEVICECHANGE isn't controlled, as
    well as re-entrancy problems with setting device configuration from
    WM_DEVICECHANGE handler.
     
    Ben Voigt [C++ MVP], Aug 28, 2008
    #3
  4. I've never heard of or observed this phenomenon, and your explanation
    for why you think it happens is nebulous at best. Do you have a
    reproducible example?
     
    chris.aseltine, Aug 28, 2008
    #4
  5. i agree with chris, i have never heard of this happening

    d
     
    Doron Holan [MSFT], Aug 28, 2008
    #5
  6. kelly

    David Miller Guest

    David Miller, Aug 28, 2008
    #6
  7. kelly

    David Miller Guest

    Oops. I forgot the most important flag of all:

    BSF_NOTIMEOUTIFNOTHUNG

    “Waits for a response to the message, as long as the recipient is not being
    unresponsive. Does not time out.â€
     
    David Miller, Aug 28, 2008
    #7
  8. kelly

    David Miller Guest

    PostMessage() can’t marshall the DEV_BROADCAST_HDR structure in the lParam.

    I bet BroadcastSystemMessage() is calling SendMessageTimeout() or doing
    something similar. FYI SendMessageTimeout() gives each window five seconds
    to respond.

    “This function considers a thread is not responding if it has not called
    GetMessage or a similar function within five seconds.â€

    http://msdn.microsoft.com/en-us/library/ms644952(VS.85).aspx
     
    David Miller, Aug 28, 2008
    #8
  9. I don't remember for sure, but I think I observed this behavior fairly
    frequently when the device was surprise removed and reinserted (i.e. bus
    reset) all before WM_DEVICECHANGE processing for the original insertion
    completed.

    Of course, it could be the communication protocol with the device itself
    broke down and never reached the ready state. There's a lot of additional
    testing needed on the system.

    I am quite sure about the mouse issue though. I was able to open a handle
    to the com port and Windows also decided to detect a mouse. This shouldn't
    be possible, either Windows should detect the mouse first and my CreateFile
    fails or else my CreateFile succeeds first and then SERENUM can't listen for
    data to run its heuristic mouse detection.

    There's another problem where disabling the device in the WM_DEVICECHANGE
    handler reliably and reproducibly shuts down the entire Windows Device
    Manager / Plug and Play system. (This was one attempted workaround for the
    aforementioned false mouse detection).

    This is why I say WM_DEVICECHANGE isn't a 100% reliable method for
    determining when the device is ready for use.
     
    Ben Voigt [C++ MVP], Aug 28, 2008
    #9
  10. The question is: Which of the flags is used to send WM_DEVICECHANGE? And
    does it vary at all based on the driver?

    Also, how is "not being unresponsive" determined? If a thread is trying to
    pump messages but doesn't get scheduled due to other activities, is that
    unresponsive? How about if a 30ms (cpu time, not wall clock time) handler
    with no message pumping gets pre-empted by other threads?

    There are generally no bounds on the time needed for a user thread to
    complete a task on a system shared with other arbitrary threads.
     
    Ben Voigt [C++ MVP], Aug 28, 2008
    #10
  11. for serial mouse detection, there is a window between detection and driver
    load. serenum opens the port, detects the device, closes the port and then
    enumerates the child device. the child device stack will then attempt to
    open the port again. in between the serenum close and the child stack open,
    your app can easily open the port. if you do open the port in this window,
    the serial mouse driver will fail to open the port and fail the pnp start

    d

    --
    Please do not send e-mail directly to this alias. this alias is for
    newsgroup purposes only.
    This posting is provided "AS IS" with no warranties, and confers no rights.
     
    Doron Holan [MSFT], Aug 30, 2008
    #11
  12. What I observed was:

    My application had an open handle to the port.

    AND

    The serial mouse driver was spamming my system with pointer motion and mouse
    clicks.

    I cannot tell you with certainty which opened the port first, I just
    understand that it should not be possible for both sermouse and a user-mode
    application to have the port open no matter which goes first. My
    application opened the port using the device interface path received through
    WM_DEVICECHANGE and SetupDi* queries. Is there any chance that the way file
    sharing and exclusivity is enforced might this and the DosDevices link these
    as separate? Although, I should think that serenum and sermouse should also
    use the raw interface path.
     
    Ben Voigt [C++ MVP], Sep 3, 2008
    #12
  13. sermouse opens the underlying serial port just like an app does. are you
    seeing this with the in box serial.sys driver? or with a 3rd party driver
    like one for a usb->serial device?

    --
    Please do not send e-mail directly to this alias. this alias is for
    newsgroup purposes only.
    This posting is provided "AS IS" with no warranties, and confers no rights.


     
    Doron Holan [MSFT], Sep 3, 2008
    #13
  14. It's USB/serial converter, from FTDI (doesn't use communication device
    class). Their driver is WHQL. I wouldn't doubt that their driver is
    causing the problem since one version ago simply opening a device on a
    multicore system was BSOD within 10 seconds. Which doesn't totally absolve
    MS of responsibility. What's the good of WHQL if even buggy drivers can be
    approved?

    serenum and sermouse are out-of-the-box XP as far as I can determine.

    I should be able to load the problem configuration in a kernel debugger and
    have debug output from my userland application showing the result of the
    device interface open. If someone could advise me on how to enable tracing
    of serenum/sermouse or where to set a breakpoint, I could determine the
    order of events definitively.
     
    Ben Voigt [C++ MVP], Sep 3, 2008
    #14
  15. WHQL is not a 100% measure of quality across an entire driver, rather it is
    a set of tests specifically designed to test very specific parts of a
    driver. why is msft reponsible for the crud that FTDI wrote? serenum and
    sermouse work as expected on the in box version of serial, it correctly
    enforces exclusivity to the port

    d

    --
    Please do not send e-mail directly to this alias. this alias is for
    newsgroup purposes only.
    This posting is provided "AS IS" with no warranties, and confers no rights.


     
    Doron Holan [MSFT], Sep 3, 2008
    #15
  16. kelly

    Pavel A. Guest

    Ben Voigt [C++ MVP] wrote:
    ........
    WHQL definitely does test on multicore machines.
    Unlikely that a not SMP capable driver could pass.
    Maybe adding debug prints around calls to the driver in the app can
    help. You can call DebugPrintEx from usermode so messages will appear in
    windbg or crash dump. Below is what I use.

    Regards,
    --PA

    ~~~~~~~~~~~~~ cut here ~~~~~~~~~~~~
    #define _WIN32_WINNT 0x0501 // minimal platform: WinXP
    #include <windows.h>

    // Borrowed from DDK dpfilter.h
    #define DPFLTR_ERROR_LEVEL 0
    #define DPFLTR_WARNING_LEVEL 1
    #define DPFLTR_TRACE_LEVEL 2
    #define DPFLTR_INFO_LEVEL 3
    #define DPFLTR_MASK 0x8000000

    #define DPFLTR_IHVDRIVER_ID 77
    #define DPFLTR_SYSTEM_ID 0
    #define DPFLTR_VERIFIER_ID 93

    extern ULONG ( __stdcall *f_vDbgPrintEx)( ULONG ComponentId, ULONG
    Level, PCCH Format, va_list arglist);

    void KernelDbgPrint( PCCH Fmt, ... )
    {
    ULONG n;
    va_list arglist;

    if( !vDbgPrintEx) ) {
    FARPROC f;
    HMODULE hm = _GLOBL_ GetModuleHandle(TEXT("ntdll.dll"));
    f = _GLOBL_ GetProcAddress( hm, "vDbgPrintEx" );
    if( !f ) return;
    memcpy( &f_vDbgPrintEx, &f, sizeof(f) );
    }

    va_start( arglist, Fmt );
    n = f_vDbgPrintEx( DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, Fmt, arglist );
    va_end( arglist );
    }

    ~~~~~~~~~~ cut here ~~~~~~~~
     
    Pavel A., Sep 3, 2008
    #16
  17. Hmmm. Well, for some reason this driver did pass. Maybe some hardware
    configurations avoid the buggy code (the same driver package supports
    several different FTDI USB converter chips, and the virtual com port driver
    can be loaded or not depending on settings in the EEPROM).
    I appreciate the code snippet, however it isn't much good to trace my
    CreateFile call unless I can also enable tracing on the serenum and sermouse
    drivers, so I can log a total ordering of the different port open and close
    events (assuming that these are included in the driver trace output at all).
     
    Ben Voigt [C++ MVP], Sep 5, 2008
    #17
  18. WHQL is realistically not going to be able to catch all bugs before
    shipment, so maybe the answer is for WHQL signing to require a commitment
    from the driver developer to participate in the BSOD crash dump program and
    issue timely bug fixes (this is usually what is meant by having a "quality"
    process in sw development, right?). A public "Wall of BSOD Shame" listing
    drivers with known bugs and no fix might also be worth considering. Yes
    these things would not come free, but is it important to Microsoft to shed
    the reputation for Windows being crash-prone?
     
    Ben Voigt [C++ MVP], Sep 5, 2008
    #18
  19. a wall of shame is not practical. by getting signed, the vendor does get a
    clear window into their OCA/bluescreen data that we collect. it is up to
    the vendor to look the collected data.

    d

    --
    Please do not send e-mail directly to this alias. this alias is for
    newsgroup purposes only.
    This posting is provided "AS IS" with no warranties, and confers no rights.


     
    Doron Holan [MSFT], Sep 5, 2008
    #19
  20. Ok, but does the level to which they utilize that data and release fixes
    influence approval of the next WHQL submission? That may be too hard to
    judge, but at least making them certify that they have analyzed the
    bluescreen data associated to their existing products might shock some
    people into doing so.

    Fixing bugs needs to be stated as mandatory and have the developer agree to
    do it, regardless of the actual level of enforcement. Similarly vendors
    need to be given a hard time if they fail to provide a driver compatible
    with a new Windows version for products released in the last 3 years or
    offered for sale in the last 12 months.
     
    Ben Voigt [C++ MVP], Sep 5, 2008
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.