USB device detection, device classification, and files handling for USB storage dev (Win 10 IoT Ent)

Hi Dear Team,
Need some help in identifying and validating the approach for one of our following requirement:

We have a Pentium x64 based single board computer appliance with few USB interface.

We want to write the software (kernel or user mode) to:

  1. Detect after USB device get connected to USB interface
  2. After detection we want to identify the type of device connected (keyboard, mouse, storage device etc)
  3. a) If USB device connected is USB storage device, we want to scan the files on the connected USB storage drive
    b) Delete black listed file (e.g. executable files) if available on usb device.

For above requirement we think we can do following:

  1. Write USB host controller filter driver to detect and identify the the usb device connected
  2. For usb storage device, write the file system filter driver to scan the files and delete the black listed files

Is this high level approach for the above requirement correct?
Is this doable in user mode using UMDF?

We know the WDF framework (KMDF and UMDF) at high-level and wrote few sample filter drivers earlier.
We have osr learning kit (usb and pci) and we are trying to get some hands on on USB driver with the sample driver available.

Seeking expert comments on the approach or if possible any alternative approaches will be of great help to validate the same.

Thanks in advance.

–mht

Nope… I don’t think you have the right approach at all.

Let’s step back one step: As so many posters here, you’ve asked us HOW to implement something, not how to solve your basic problem. We refer to this as the “pigs and wings problem” here.

Ignoring what you asked, I’m going to guess that you want to implement some sort of automatic scanning for USB storage devices. If that’s NOT what you want to do, post here and tell us what you’re trying to accomplish.

HOW you want to implement this depends a lot on the specific of what you want to do, and how you want to do it.

You way that you want to scan the drive when it’s attached (and, presumably, block access to the device before the scan has been completed). If you think about this a bit, you might decide that this isn’t nearly as nice a solution as you initially thought: Scanning all the files on a flash drive can take a LONG time.

But, you could do all this with a file system minifilter. Have the filter determine if the volume is connected via USB. Yes, this can be tricky, but this is really the only place that you have much work to do. Do the scanning itself in a user-mode app (like a service). Don’t even THINK of doing the scanning in kernel mode.

Peter

The problem as you have described it does not require a driver at all. You could do all of that with a simple applications that registers for device interface changes, scans any newly arrived mass storage devices, and does your deletes. However, that’s going to make it more difficult to install updated apps and drivers or run diagnostics.

And, of course, it won’t work at all with read-only USB drives.

You could do all of that with a simple applications that registers for device interface changes

Oh, that could be a good approach, Mr. Roberts! I didn’t think of that one.

The only DISadvantage to that approach that I can see is that you can’t block access to the drive until the scan has been completed. If that’s in fact one of the user’s requirements.

Peter

A lot depends on where this product is intended to be installed. Appropriate solutions for mass market consumer products can be much different than for a closed system - especially in the area of security software.

for consumer grade distribution, deleting files off of the USB drive will frustrate and infuriate users. They may understand files that are ‘blocked for security’ but to actually remove them without any confirmation will bring you no end of trouble I think.

and the point about read only media is another important one.

you probably can ‘effectively’ block access using a UM solution that registers callbacks as long as you are content to unmount the filesystem and open the disk as raw. race conditions galore, and you have to hope that you can understand what FS the drive is formatted with, but it probably could be done.

instead of all of this, probably what you want is a file system filter that rejects access to certain files based on the pattern of the file name. Don’t even attempt to scan the drive or do anything else, but just fail the create request with a suitable error (access denied or similar)

I don’t know enough about how to tell the difference between USB storage and other kinds to recommend any way to check the pattern of the file name (I do mostly networking) but there is probably a way

Thank you Tim, Peter, MBond2 for your valuable inputs.

As suggested by Tim, as of now I am exploring on developing user application using device interface change notification apis.

actually the user is supposed to connect usb storage device to bring update/upgrade packages to system. And other usb devices like keyboard, mouse etc can be connected on need basis. We are planning to log the details of files deleted or not able to delete the files due to appropriate reason

A minifilter would be able to do what you want.

Mark Roddy

Hi Mark,

A minifilter would be able to do what you want.
do you mean mini filter over USB host controller driver?

As Tim suggested, with device interface change notification I am able to capture the arrival/ removal of usb device. but still exploring on how to proceed to next thing of getting handle to the files on the usb storage and then eventually deleting it.

Thanks for all valuable inputs.
—mht

no a filesystem minifilter that figures out if it has been attached to a
usb volume and does your file filtering requirements.

This:
"3) a) If USB device connected is USB storage device, we want to scan the
files on the connected USB storage drive

b) Delete black listed file (e.g. executable files) if available on usb
device. "

Could easily be done using a filesystem minifilter.

Mark Roddy

but still exploring on how to proceed to next thing of getting handle to the files on the usb storage

How about by… ah… programmatically doing a directory listing? What am I missing?

Could easily be done using a filesystem minifilter

And, again, the actual scanning and deleting would be done in user mode (see FltCreateSectionForDataScan, as one possible way to go).

Peter

Following are implementation update on the above requirement

We were able to implement above requirement using below apis -
RegisterDeviceNotification - to receive the usb arrival/ removal notification
Volume management apis - to scan the usb drive and delete blacklisted files

Now my next enhancement is to run this software as C++ windows service on Window 10 enterprise.
Followed the following link for creating the service -
https://docs.microsoft.com/en-in/windows/win32/services/the-complete-service-sample

Plus many more samples - but in all samples and my customized code - StartServiceCtrlDispatcher() function fails with error 1063.

1063 is ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
This error is returned if the program is being run as a console application rather than as a service.
If the program will be run as a console application for debugging purposes, structure it such that service-specific code is not called when this error is returned.

How to call “StartServiceCtrlDispatcher” api, I have tried all recommendations given on the StartServiceCtrlDispatcher() api page + many other webpages. But issue is intact.

Looking for some expert advise on what possibly I am doing wrong or possible solution.
I tried with unicode and mbcs project type, multiple sample code refactoring of code.
Almost spent 2-3 weeks on this. So any pointers on fixing this issue will be of great great help.

Thanks in advance,
–mht

We have a Pentium x64 based single board computer appliance with few USB interface.

Use Linux.

The only DISadvantage to that approach that I can see is that you can’t block access to the drive until the scan has been completed. If that’s in fact one of the user’s requirements.

Linux again.

– pa

StartServiceCtrlDispatcher will always fail unless your process is actually running as a service. it is possible to debug processes that run as services, but it is much less straight forward than if they can also run as normal console processes that can be started by the debugger normally.

I assume that your problem is that you would like to debug device notification changes that are sent by the SCM into your service control handler?

I did this once long ago when service processes lived in session 0 (google shatter attack to see why that’s not done any more) and it was easy at that time. Just include a DebugBreak() call in your code somewhere and wait for your debugger to be invoked. I have no idea if that still works with the radical changes to the security boundaries since then, but I will likely be finding out for myself soon as I have the misfortune of needing to write a windows server cluster resource dll that probably has to get debugged in a similar way

I am able to resolve the issue (StartServiceCtrlDispatcher() returning 1063 error). I was able to make the sample (url given above) work with some changes. But I not sure what exactly was the fix.

  1. For receiving Device Notification from windows service, we need to use RegisterServiceCtrlHandlerEx() instead of RegisterServiceCtrlHandler()
  2. ServiceCtrlHandler() need to add case for SERVICE_CONTROL_DEVICEEVENT. here we can have handler function to carry out application logic.
    for me it was it was checking notification for arrival/ removal of device (DBT_DEVICEREMOVECOMPLETE, DBT_DEVICEARRIVAL).
    If arrival, scan the newly added usb mass storage drive. Currently I am detecting if there is change in no of drives on the machine to identify if added device is mass storage / non mass storage device. I think there might be other ways to get this details.
  3. for SERVICE_CONTROL_SHUTDOWN case - need to add UnregisterDeviceNotification()

without looking at the original code, you must be debugging when running under the SCM unless you have made extensive accommodations. that would get you around StartServiceCtrlDispatcher failing

yes, HandlerEx has the event data that you need to handle device change notifications

yes, you should unregister, but if this is a service that does not run in a shared process (as is the case for virtually all non-Microsoft services), the whole process will die shortly, so whatever cleanup needs to be done will be done by the OS anyways