I have a USB device and a C# application communicating with it.
Presently I am using a connect button to connect with the device from my application. This is a HID device and on Connect I will register for change notifications and from then onwards my application can display 'DEVICE ON LINE" or off line and act upon, based on windows WM_DEVICECHANGE message.

But I need to avoid this 'Connect' button!

What I need is to call my HIDdevice find and connect function upon a device plugging in. Then it seems OK.

So I am trapping this WM_DEVICECHANGE message.

When the application starts if the device is not present , I wont be able register it for notifications.(Am I correct?) So the device is not registered and when the device plugs in , I am getting windows message with wparam value 7 (Means a device is plugged or unplugged!).Actually that is all I needed to call my function.But I am getting 3 or 4 messages in sequence - all with wparam as 7.

How I can solve this?


You can register for device notifications regardless of whether the device is present.

RegisterDeviceNotification and UnregisterDeviceNotification

You can issue to the former to receive all the WM_DEVICECHANGE notifications for a specific class guid.

The wParam you then need to check for (when you receive the WM_DEVICECHANGE) is DBT_DEVICEARRIVAL, which indicates a device has been attached.

You will still need to do some checks to make sure that the device inserted is the one you are looking for, but this is down to yourself ^^

EDIT: If you're receiving 3 or 4 of the same messages after a single insert this could be caused by a driver installation, or the fact you have registered multiple times without unregistering. You will receive a notification for each registered handle.

The DBT_DEVICEARRIVAL code is 0x800 which indicates the device is attached and ready. Waiting for 0x007 could lead to "bad things happening" as this indicates "something" has happened, but you aren't sure what.

EDIT 2: Here's a link that describes the DBT_DEVICEARRIVAL event

Thanks for the details. I will go through and will be back.

First of all I am not an experienced programmer, This USB device I am doing is by putting together code pieces from the Internet.(I may sound silly sometimes- Hope it is OK while learning.)

My multiple message seems not because of multiple registration. Even after a restart without connecting the device or running my registration code, I am getting two messages on a device removal and 4 on device attached. may be something else in my code or driver issue as you mentioned.
If I connect a mass storage class device like a USB drive, am getting proper device arrival message accompanied by the dummy duplicates with 7 as wParm.
That dummy messages is not a problem(At least for now) if I can get the device registered even before plugging in- because after registration amoung the 4 or 5 medssages received one will be 'device attached' which is all what I need) I cant understand from the linked page how to register without first getting the device connected and getting the Guid and device name.(The USB HID code I am following is doing like that).
Can I get some more info on how to register prior to plug in, if I have product ID and vendor ID of the device to be plugged in?

Ok, when you register for the device notifications you aren't actually registering any particular device, you're asking windows to inform you of the attachment notification. It sounds like you've got that part done.

The second part is that when you receive the DBT_DEVICEARRIVAL event you also receive a struct that gives you information about the device that has been attached. You can use that information to determine if the device that has been attached is actually your device or another device.

Your device should have a "class guid" you can find it by plugging in your device, going to device manager and looking at the resources properties of it. That at least gives you a very basic filter. I'm not sure why you're receiving so many 007 messages unless your app runs right on startup of the system as it's initialising the USB.

The product and vendor ID you mention should be given to you in the devicearrival struct (lParam) if you match those, then you have your device handle.

I'm sorry if this sounds too complicated but I can't think of a way to simplify it.

Thanks a lot for the detailed reply. Things are getting clearer.
My device is a HID device. So I will get the HID class Guid and will register it for my application. Even if mixed with some 07 messages, I can extract my device attachment message. I need to get my form registered for HID device arrivals.

Thanks a lot will be back.
Thanks for the effort. I will make sure it is not wasted.


Thanks a lot. I got it working!!
First on application start up I retrieved a class guid using HidD_GetHidGuid API call.
Then I will register it to get messages on HID device arrival.
Now I am getting messages for my HID device also-(mixed with wparm 7).
So when I get a device arrived message I will call my device detection and registration function.
All ok!
Only thing is that My device detection function has built in registration code. Instead of manipulating on that ,I am unregistering once to avoid the double message as you mentioned.(It is working now - will see later if any consequences for my crude methods-(registering and unregistering).
Only thing is even if a USB Thump drive is plugged, my message mechanism will trigger- but for some other custom class devices it is not triggering. Is this Mass storage class devices are auto registered to active window?
No issues on that.

Thanks a lot for your help. Really helpful for me.(I am a Microcontroller Programmer basically- So watching my windows program working is very encouraging.)
Thank you

What do you mean by registration code?

It would be handy if you didn't have to unregister, as you can then detect device removal.

The thumb drive shouldn't have the same device id/vendor id, but it *will* trigger the event if it is registered as a HID class on its USB controller.

Your best bet is upon receiving DEVICEARRIVAL, cast your lParam to the DEV_BROADCAST_HDR. This should contain a property called dbch_devicetype .

You need to check this device type and pick the correct structure. The structures all begin with the same two dwords, "size" and "type" check the second dword for the type. If you look at the DEV_BROADCAST_HDR link I posted, that has a list of the possible structs it could be. To check it's type you can check it against DBT_DEVTYPE_<TYPE> where type is the last part of the struct name. So DEV_BROADCAST_PORT type would be DBT_DEVTYPE_PORT.

These structs also have either friendly names or device identifiers so you should be able to easily identify which is yours.

Sorry for the confusion.
Actually by registration code what I meant was the device notification registration.
Tomorrow I will try this method.
Thank you

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.