使用 Windows V2 凭据提供程序的钻石继承

Diamond inheritance using Windows V2 Credential Providers

以下情况:

我有一个实现 IConnectableCredentialProviderCredential 接口的工作 V1 CP。这种依赖关系是访问 IQueryContinueWithStatus 接口所必需的,我需要它。

class CCredential : public IConnectableCredentialProviderCredential
{
    [...]

IConnectableCredentialProviderCredential 实施 ICredentialProviderCredential.

COM IUknown 查询方法使用此代码段完成:

IFACEMETHODIMP QueryInterface(__in REFIID riid, __deref_out void** ppv)
{
    static const QITAB qitOnlyCredUI[] =
    {
        QITABENT(CCredential, ICredentialProviderCredential),
        { 0 },
    };

    static const QITAB qitFull[] =
    {
        QITABENT(CCredential, ICredentialProviderCredential), // IID_ICredentialProviderCredential
        QITABENT(CCredential, IConnectableCredentialProviderCredential), // IID_IConnectableCredentialProviderCredential            
        { 0 },
    };

[...]

现在我想将提供程序迁移为 V2 CP 并实现 ICredentialProviderCredential2 接口,但与 IQueryContinueWithStatus 接口保持兼容。此外,删除 QITABENT(CCredential, ICredentialProviderCredential) 不是选项,因为在请求 CredUI 的情况下 qitOnlyCredUI 是必需的,它不支持 IQueryContinueWithStatus.

class CCredential : public IConnectableCredentialProviderCredential,
                    public ICredentialProviderCredential2,
                    public ICredentialProviderCredentialWithFieldOptions
{
    [...]

ICredentialProviderCredential2 实施 ICredentialProviderCredential.

实现 COM QueryInterface 方法如:

IFACEMETHODIMP QueryInterface(__in REFIID riid, __deref_out void** ppv)
{
    static const QITAB qitOnlyCredUI[] =
    {
        QITABENT(CCredential, ICredentialProviderCredential),
        { 0 },
    };

    static const QITAB qitFull[] =
    {
        QITABENT(CCredential, ICredentialProviderCredential), // IID_ICredentialProviderCredential
        QITABENT(CCredential, ICredentialProviderCredential2), // IID_ICredentialProviderCredential2
        QITABENT(CCredential, IConnectableCredentialProviderCredential), // IID_IConnectableCredentialProviderCredential            
        QITABENT(CCredential, ICredentialProviderCredentialWithFieldOptions), //IID_ICredentialProviderCredentialWithFieldOptions
        { 0 },
    };

这是钻石问题开始的地方,因为 ICredentialProviderCredential2IConnectableCredentialProviderCredential 都实现了 ICredentialProviderCredential.

尝试编译肯定会导致编译器抱怨 ICredentialProviderCredential 基 class.

的定义不明确

知道如何实现吗?

您需要为您的案例使用 QITABENTMULTI() 宏。它记录在 shlwapi.h 中。我不知道为什么它不在 MSDN 上。