AVStream: separate GUIDs for propertyset and interface ?

I am creating a KsProxyplugin (+ propertypages) for an AVStream(capture)filter and I am using the well-known paper by Max Paklin as guide for this(http://www.wd-3.com/archive/KsProxyPlugin.htm)

Everything works fine and the propertyPages are loaded if I create an instance of the filter in graphedit. Also, I can successfully call myFilter->QueryInterface(GUID_of_propertyset,(void**) m_ppInterface) when I instantiate a captureFilter in an application.

The example of Max Paklin uses the same GUID for the propertySet as for the proxyInterface. He mentions in the article that he did this by choice (for the sake of simplicity) and that he (and I quote) ?could have run guidgen twice so as to create separate GUIDs for the interface and class/property-set identifiers?.
I would like to have separate GUIDs for the interface and the property-set.
However, I did not succeed in using separate GUIDs for the propertyset and the interface. When I use a different GUID for the interface, the interface is ?not implemented? when I call myFilter->QueryInterface(interfaceGUID, (void**)m_ppInterface). Also, Graphedit can?t create the propertypages anymore.

I did change the implementation of the RegisterDll()-method to register the new GUID. The result being that the IID-property of the MediaInterfaces{PropetySetGUID} was the GUID of the proxyInterface. I also tried changing the implementation of the createInstance() method of the pluginIface so that CoCreateInstance(interfaceGUID) is called instead of the piOuterUnknown->QueryInterface(propertySetGUID) which is in the example of Max Paklin. None of these 2 modifications helped me.

So my question is: Could somebody explain to me why this doesn?t work when the GUID of the propertySet <> GUID of the proxyInterface. Or, if I?m doing something wrong, could somebody steer me in the right direction?

Thanks,

  • Bernard Willaert
    Software Engineer
    Barco - HealthCare division
    Belgium

xxxxx@hotmail.com wrote:

I am creating a KsProxyplugin (+ propertypages) for an AVStream(capture)filter and I am using the well-known paper by Max Paklin as guide for this(http://www.wd-3.com/archive/KsProxyPlugin.htm)

As far as I know, that document represents the only sample KS proxy
plugin that exists in the world today, and even now it remains the best
source of information about KS proxys. It would behoove Microsoft to
save a copy in MSDN somewhere.

The example of Max Paklin uses the same GUID for the propertySet as for the proxyInterface. He mentions in the article that he did this by choice (for the sake of simplicity) and that he (and I quote) ?could have run guidgen twice so as to create separate GUIDs for the interface and class/property-set identifiers?.

Yes. You connect the two in the registry, in Control\MediaInterfaces.
The key name is the KS property set identifier, and the value is the IID
GUID. So, for example:

HKLM,SYSTEM\CurrentControlSet\Control\MediaInterfaces{11111111-1111-1111-1111-111111111111},IID,1,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22

So, KS property set {11111111-1111-1111-1111-111111111111} would map to
the COM interface id {22222222-2222-2222-2222-222222222222}. Note that
I have avoided making any embarrassing endian mistakes through my clever
choice of GUID.

You probably have to change the key in Control\MediaSets as well, so
Graphedit knows how to map the property interface to a property page CLSID.

HKLM,SYSTEM\CurrentControlSet\Control\MediaSets{22222222-2222-2222-2222-222222222222}\PropertyPages{33333333-3333-3333-3333-333333333333},“I2C
Access”

But, I have to ask, what is be the point? This stuff is already
confusing enough as it is, and I don’t see that you gain anything.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Hello Tim,
Thank you for your input.
I modified the registry-entries in MediaInterface and MediaSets, but without success.
It looks like this:
System\CurrentControlSet\Control\MediaInterfaces{PROPERTYSET_GUID} with IID (bytearray): GUID of propertyInterface-GUID (=COM-object)
System\CurrentControlSet\Control\MediaSets{propertyInterface-GUID}\PropertyPages{propertyPage-GUID}

When I call myFilter->QueryInterface(__uuidof(CaptureInterface),(void**)m_ppIface), the HRESULT = 0x80004002 which means that the interface is not supported.
Also, in Graphedit I have ?the requested propertypage cannot be displayed?

Can you perhaps explain ?how? the capturefilter ?knows? which COM-objects to load on initialization? Maybe there is something more to it than just the registry-entries because that only seem to work when both GUIDs are the same. (It is not clear to my why this regentry is even needed, when the GUID of the property-set is the same as for the property-interface.) What is also not clear is where the 0x80004002-error comes from. Is that the captureFilter that ?says? that it doesn?t support this interface? In other words: which implementation is called when I call myFilter->QueryInterface(__uuidof(CaptureInterface),(void**)m_ppIface)?

The use case is the following: we have a capure filter which has a very specific (hardware related) set of properties (=propertyset). We want to hide this device-specific complexity from the users for a few reasons.
User-friendliness is one: by providing a more user (or developer) friendly interface to configure the captureFilter (=propertyInterface). The API of this interface is much more high level. The deduction of the device-specific set of properties is done under the hood based on the user input. So this propertyInterface is not simply a passthrough of values such as the Max Paklin example. There is a whole bunch of stuff going on in between receiving the use rinput and configuring the actual capture filter. The property-page reflects the API of this propertyInterface.

I thought it was confusing to have the same GUID for both the propertySet and propertyInterface, because they serve different purposes.

Secondly, the GUID of the propertyInterface is something we ship together with the captureFiter. We don?t want to ship the GUID of the propertySet because we don?t want users to manipulate the propertySet directly (without using the propertyInterface). We don?t want that because setting the propertySet with unvalid values can result in a system-crash (BSOD and such). It is probably quite possible to figure out the GUID of this propertyset even if we don?t provide it (by inspecting the registry), but we don?t want to encourage or support the usage of the propertyset to configure the capture filter.
So, I hope that gives you some better insight in why I prefer separate GUID for the propertyset and the propertyInterface.

  • Bernard Willaert

xxxxx@hotmail.com wrote:

When I call myFilter->QueryInterface(__uuidof(CaptureInterface),(void**)m_ppIface), the HRESULT = 0x80004002 which means that the interface is not supported.
Also, in Graphedit I have ?the requested propertypage cannot be displayed?

Can you perhaps explain ?how? the capturefilter ?knows? which COM-objects to load on initialization?

Your driver exposes a table of property sets in its KSPIN_DESCRIPTOR or
KSFILTER_DESCRIPTOR. When you create your filter factory, AVStream adds
those to the standard property sets that it handles. When Ksproxy
starts up, it enumerates the list of supported properties in the KS
driver it is handling. When it gets to a property set it doesn’t
already know, it checks the MediaInterfaces tree in the registry to see
if it is listed. If it is listed, it uses the CLSID to load the plugin
and initializes it. Then, when someone sends a QueryInterface to
ksproxy, it checks the list of interfaces that are built in, and if it
isn’t immediately found, it passes the IID on to all of the loaded plugins.

Maybe there is something more to it than just the registry-entries because that only seem to work when both GUIDs are the same. (It is not clear to my why this regentry is even needed, when the GUID of the property-set is the same as for the property-interface.)

I’ve often wondered the same thing. I’ve always assumed it was because
the GUIDs didn’t have to match.

What is also not clear is where the 0x80004002-error comes from. Is that the captureFilter that ?says? that it doesn?t support this interface? In other words: which implementation is called when I call myFilter->QueryInterface(__uuidof(CaptureInterface),(void**)m_ppIface)?

The IBaseFilter instance you have points to ksproxy.ax (well,
technically it is kswdmcap.ax, but the effect is the same). That is
your driver’s agent in user mode. It is ksproxy that tracks the
interfaces that map to the property sets advertised by your driver.

User-friendliness is one: by providing a more user (or developer) friendly interface to configure the captureFilter (=propertyInterface). The API of this interface is much more high level. The deduction of the device-specific set of properties is done under the hood based on the user input. So this propertyInterface is not simply a passthrough of values such as the Max Paklin example. There is a whole bunch of stuff going on in between receiving the use rinput and configuring the actual capture filter. The property-page reflects the API of this propertyInterface.

I thought it was confusing to have the same GUID for both the propertySet and propertyInterface, because they serve different purposes.

Well, that’s not supposed to be the case. The property interface is
supposed to be the COM-friendly face of your property set. But that’s a
rather delicate philosophical point.

Secondly, the GUID of the propertyInterface is something we ship together with the captureFiter. We don?t want to ship the GUID of the propertySet because we don?t want users to manipulate the propertySet directly (without using the propertyInterface). We don?t want that because setting the propertySet with unvalid values can result in a system-crash (BSOD and such).

I have two comments about this.

First, you can’t prevent this. Your COM interface is just a friendly
wrapper. It’s another way in, but it’s not the only way in. It doesn’t
prevent direct access. Any user can go enumerate the property sets you
support (ksstudio does that in a nice tabulated way). From that
enumeration, they can get your property set GUID. Once they have the
GUID, they can call IKsControl->KsProperty to talk to the driver
directly, bypassing your plugin.

Now, are users likely to do that? No, and the answer is “no” whether
the two GUIDs are the same or different.

Second, if a non-privileged user can send property requests to your
driver that cause a BSOD, then your driver is poorly designed. You need
to have the protections in the driver, not in the proxy plugin. Part of
the WHQL testing sends random property requests to your driver, to see
if it survives.

It is probably quite possible to figure out the GUID of this propertyset even if we don?t provide it (by inspecting the registry), but we don?t want to encourage or support the usage of the propertyset to configure the capture filter.
So, I hope that gives you some better insight in why I prefer separate GUID for the propertyset and the propertyInterface.

Not yet, no. I don’t see that you’ve gained anything.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Ok, thank you Tim, I understand.
You made it clear that it doesn?t make much sense to try and hide the propertyset by assigning it a separate GUID. And I do agree that users probably won?t bother circumventing the propertyinterface. But still, it would be nice if there was a way to securely enforce 1 single way to configure the captureFilter and make the propertyset private. It would make it a lot easier for us (in our usecase) to prevent users (or applications) of doing things with the device they are not allowed to do. (ie. resource management in context of access-rights, enforcing license-agreements, ?)
I also noted your concern about the lack of inputvalidation in the driver. That is a good point.
So the only gain left in having separate GUIDs for the propertySet and the propertyInterface is that it would give us a better understanding of what happens under the hood. But we have a working solution (with the same GUIDs) so we probably won?t spend much more time on it.

  • Bernard Willaert