I had an occasion to write a device selector query that selects no devices. The idea is that you have a function that returns a device selector query for “Find all devices that can X”, but you happen to know that X can’t be done because of some unmet prerequisite unrelated to the devices themselves. What’s the most efficient device selector query that selects no devices?
One thing that doesn’t work is returning the empty string. In Advanced Query Syntax, the empty string is the opposite of what we want: The empty string selects everything.
Each clause in Advanced Query Syntax takes the form of (property) (match operator) (value). For example,
System.Devices.InterfaceClassGuid:="{DEEBE6AD-9E01-47E2-A3B2-A66AA2C036C9}" System.Size:>1kb System.FileName:~<"Copy of"
One way to specify a query that matches no devices is to specify contradictory requirements.
System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#False
The InterfaceÂEnabled property cannot be both True and False, so this will match no devices.
On the other hand, I wondered whether this would make two passes, one to gather all the devices where the interface is enabled, and then (to process the AND clause) a second pass over those devices to find the ones where the interface is disabled. Should I add a garbage query at the front to reduce the search space as quickly as possible?
System.Devices.InterfaceClassGuid:="{91F9F631-CD92-42C5-91A4-FBAEAF4DBF09}" AND
System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND
System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#False
The interface class GUID I picked is one that I generated just now, so I know it won’t match any valid interface GUID.
It turns out that this garbage query at the front does help.
The device selector query evaluator contains optimizations if the query includes an AND clause that does an equality comparison against one of the following properties:
Property | Optimized for DeviceInformationKind | |
---|---|---|
DeviceInterface | Device | |
System.Devices.DeviceInstanceId | Yes | |
System.Devices.ClassGuid | Yes | Yes |
System.Devices.ContainerId | Yes | Yes |
System.Devices.PanelId | Yes |
There are shortcuts in the device management subsystem that can find all devices that match one of those properties, so if one of those properties is involved in the query as an AND clause, the query evaluator can use those shortcuts to get the list of candidate devices quickly, rather than having to enumerate all the devices. Once it gets the list of candidates, it can then evaluate the other AND conditions to filter the results.
Therefore, a fast query that produces no results could be
System.Devices.DeviceInstanceId:="{91F9F631-CD92-42C5-91A4-FBAEAF4DBF09}" AND
System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True AND
System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#False
We filter against one of the magic optimized properties (the device instance ID), which will quickly produce no results. The last two clauses (looking for something that is both true and false) ensure that even if something by some freak of bad luck happens to match our GUID, it will nevertheless be rejected.
Update: Commenter Henrik Arlinghaus pointed out a simpler query: Just require the DeviceInstanceId to be two different GUIDs simultaneously.
System.Devices.DeviceInstanceId:="{91F9F631-CD92-42C5-91A4-FBAEAF4DBF09}" AND System.Devices.DeviceInstanceId:="{E6D41CCF-B31E-45C6-AF59-1B45BB431F6D}"
Whoever designed AQS never thought about making it support “true” and “false” natively?
I assume you are limited to a single GUID clause? Otherwise, if GUID := {X} AND GUID := {Y} should also work.
Can UUIDs be validated? Are you allowed to search for the Nil UUID {00000000-0000-0000-0000-000000000000}? Or something that looks enough like a UUID but can’t actually be generated in practice?
Surely that uuid should have been generated from the MAC address of that same network card that defined the DirectX capability that no sane driver would claim to support?
(The one you cite is a UUID4 (random) though.)
Nice callback! But isn’t the point of the UUID that it’s astronomically unlikely to get a collision even though each one is randomly generated? Rendering the long-obsolete network card in question destroyed before it’s time…
When i ask ISearchQueryHelper to "GenerateSQLFromUserQuery" using:
<code>
It generates the SQL query containing the `System.Devices.InterfaceClassGuid`:
<code>
Except the column System.Devices.InterfaceClassGuid is not found in the SystemIndex.
I even set the query syntax mode to "advanced":
<code>
So i'm obviously conceptually missing something. Is this field not something that is can be found in the Windows Search catalog? Is this for querying some other area of the system?
This isn’t a search indexer query. It’s a plug and play device query.
That’s an interesting function design pattern. I might have to steal that.
It’s nice that an API would write all the plumbing to do an
on all the fields in all the objects in its memory.
I wonder if which properties are indexed? E.g. if there was an index on the InterfaceClassGuid property, searching for a non-existent property would require only an index lookup rather than a full table scan