//*@@@+++@@@@******************************************************************
//
// Microsoft Windows Media Foundation
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//*@@@---@@@@******************************************************************
//
import "mfmediaengine.idl";

#pragma region Application Family
cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)")

////////////////////////////////////////////////////////////////////////////////////////////////////
//  Definitions for access to the Content Decryption Module (CDM) for encrypted media extensions support.
//

// IMFContentDecryptionModuleSession is designed based on EME MediaKeySession:
// https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession
[
    object,
    uuid(4e233efd-1dd2-49e8-b577-d63eee4c0d33),
    pointer_default(unique)
]
interface IMFContentDecryptionModuleSession : IUnknown
{
    // A unique string identifier generated by the CDM that can be used by the application
    // to identify session objects.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-sessionid
    HRESULT GetSessionId(
        [out] LPWSTR *sessionId
    );

    // The expiration time for all key(s) in the session, or NaN if no such time exists or
    // if the license explicitly never expires, as determined by the CDM.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-expiration
    // expiration is based on https://tc39.es/ecma262/#sec-time-values-and-time-range
    HRESULT GetExpiration(
        [out] double *expiration
    );

    // A reference to an array of key IDs known to the session to the current status
    // of the associated key. Each entry MUST have a unique key ID.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-keystatuses
    HRESULT GetKeyStatuses(
        [out, size_is(, *numKeyStatuses)] MFMediaKeyStatus **keyStatuses,
        [out] UINT *numKeyStatuses
    );

    // Loads the data stored for the specified session into this object.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-load
    HRESULT Load(
        [in] LPCWSTR sessionId,
        [out] BOOL *loaded
    );

    // Generates a license request based on the initData. A message of type "license-request" or
    // "individualization-request" will always be queued if the algorithm succeeds
    // and the promise is resolved.
    // Structure for init data is based on initDataType
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-generaterequest
    // https://www.w3.org/TR/eme-initdata-registry/
    HRESULT GenerateRequest(
        [in] LPCWSTR initDataType,
        [in, size_is(initDataSize)] const BYTE *initData,
        [in] DWORD initDataSize
    );

    // Provides messages, including licenses, to the CDM.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-update
    HRESULT Update(
        [in, size_is(responseSize)] const BYTE *response,
        [in] DWORD responseSize
    );

    // Indicates that the application no longer needs the session and the CDM should release any resources
    // associated with the session and close it. Persisted data should not be released or cleared.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-close
    HRESULT Close();

    // Removes all license(s) and key(s) associated with the session. For persistent session types,
    // other session data will be cleared as defined for each session type once a
    // release message acknowledgment is processed by Update().
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysession-remove
    HRESULT Remove();
}

// IMFContentDecryptionModuleSessionCallbacks is designed based on EME keystatuseschange event:
// https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-evt-keystatuseschange
[
    object,
    uuid(3f96ee40-ad81-4096-8470-59a4b770f89a),
    pointer_default(unique)
]
interface IMFContentDecryptionModuleSessionCallbacks : IUnknown
{
    // The CDM has generated a message for the session.
    HRESULT KeyMessage(
        [in] MF_MEDIAKEYSESSION_MESSAGETYPE messageType,
        [in, size_is(messageSize)] const BYTE *message,
        [in] DWORD messageSize,
        [in, optional] LPCWSTR destinationURL
    );

    // There has been a change in the keys in the session or their status.
    HRESULT KeyStatusChanged();
}

[
    object,
    uuid(87be986c-10be-4943-bf48-4b54ce1983a2),
    pointer_default(unique)
]
interface IMFContentDecryptionModule : IUnknown
{
    // This method allows the caller to specify the IMFContentEnabler interface that shall be used
    // by the Content Decryption Module.
    // The IMFContentEnabler is normally obtained from IMFInputTrustAuthority::RequestAccess.
    HRESULT SetContentEnabler(
        [in] IMFContentEnabler *contentEnabler,
        [in] IMFAsyncResult *result
    );

    // Provides an object for IMFContentDecryptionModuleSession suspend events.
    HRESULT GetSuspendNotify([out] IMFCdmSuspendNotify **notify);

    // This method allows the caller to specify the IMFPMPHostApp interface, which represents
    // a protected process. The IMFPMPHostApp interface is used by the CDM to create the
    // IMFTrustedInput object.
    HRESULT SetPMPHostApp([in] IMFPMPHostApp *pmpHostApp);

    // Creates an object based on the EME spec MediaKeySession object:
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeys-createsession
    HRESULT CreateSession(
        [in] MF_MEDIAKEYSESSION_TYPE sessionType,
        [in] IMFContentDecryptionModuleSessionCallbacks *callbacks,
        [out] IMFContentDecryptionModuleSession **session
    );

    // Provides a server certificate to be used to encrypt messages to the license server.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeys-setservercertificate
    HRESULT SetServerCertificate(
        [in, size_is(certificateSize)] const BYTE *certificate,
        [in] DWORD certificateSize
    );

    // Creates an IMFTrustedInput object that implements the decryption of content.
    // ContentInitData will only be used if initData from
    // IMFContentDecryptionModuleSession::GenerateRequest is not provided or incomplete.
    // Initialization Data should be structured in PSSH Box Format. For more details, see
    // https://www.w3.org/TR/eme-initdata-cenc/#common-system
    HRESULT CreateTrustedInput(
        [in, size_is(contentInitDataSize)] const BYTE *contentInitData,
        [in] DWORD contentInitDataSize,
        [out] IMFTrustedInput **trustedInput
    );

    // Identifies the SystemIDs that this object supports.
    // SystemIDs are identifiers used in the "cenc" Initialization Data Format. For more details, see
    // https://w3c.github.io/encrypted-media/format-registry/initdata/cenc.html
    // systemIds should be allocated and freed using CoTaskMem.
    HRESULT GetProtectionSystemIds(
        [out, size_is(, *count)] GUID **systemIds,
        [out] DWORD *count
    );
}

// IMFContentDecryptionModuleAccess is designed based on MediaKeySystemAccess:
// https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#mediakeysystemaccess-interface
[
    object,
    uuid(a853d1f4-e2a0-4303-9edc-f1a68ee43136),
    pointer_default(unique)
]
interface IMFContentDecryptionModuleAccess : IUnknown
{
    // Creates an object based on the EME spec MediaKeys object:
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#mediakeys-interface
    // Supported contentDecryptionModuleProperties are detailed below.
    HRESULT CreateContentDecryptionModule(
        [in] IPropertyStore *contentDecryptionModuleProperties,
        [out] IMFContentDecryptionModule **contentDecryptionModule
    );

    // Returns the supported combination of configuration options.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysystemaccess-getconfiguration
    HRESULT GetConfiguration(
        [out] IPropertyStore **configuration
    );

    // Identifies the Key System being used.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#dom-mediakeysystemaccess-keysystem
    // String should be allocated and freed using CoTaskMem.
    HRESULT GetKeySystem(
        [out] LPWSTR *keySystem
    );
}

// Property keys that can be passed to CreateContentDecryptionModule

// This Property is a LPWSTR that represents a file path.
// Use this property to pass a storage location the CDM can use for content specific data.
// The app should delete the store location after the CDM object has been released.
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_CONTENTDECRYPTIONMODULE_INPRIVATESTOREPATH = { { 0x730cb3ac, 0x51dc, 0x49da, { 0xa5, 0x78, 0xb9, 0x53, 0x86, 0xb6, 0x2a, 0xfe } }, 0x01 }; ")

// This Property is a LPWSTR that represents a file path.
// Use this property to pass a storage location the CDM can use for initialization.
// This storage location will also be used for content specific data if INPRIVATESTOREPATH is not set.
// The app should not delete the store location to optimize performance of the CDM.
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_CONTENTDECRYPTIONMODULE_STOREPATH =          { { 0x77d993b9, 0xba61, 0x4bb7, { 0x92, 0xc6, 0x18, 0xc8, 0x6a, 0x18, 0x9c, 0x06 } }, 0x02 }; ")

// This Property is a LPWSTR used in the Store Content Decryption Module scenario.
// The CDM implementer should look for this property and pass to the
// MediaProtectionPMPServer constructor as "Windows.Media.Protection.PMPStoreContext" Property.
// Users calling the CreateContentDecryptionModule should not create this property.
cpp_quote("EXTERN_C const DECLSPEC_SELECTANY PROPERTYKEY MF_CONTENTDECRYPTIONMODULE_PMPSTORECONTEXT =    { { 0x6d2a2835, 0xc3a9, 0x4681, { 0x97, 0xf2, 0x0a, 0xf5, 0x6b, 0xe9, 0x34, 0x46 } }, 0x03 }; ")

[
    object,
    uuid(7d5abf16-4cbb-4e08-b977-9ba59049943e),
    local
]
interface IMFContentDecryptionModuleFactory : IUnknown
{
    // Identifies what Key Systems are be supported.
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#key-system
    BOOL IsTypeSupported(
        [in] LPCWSTR keySystem,
        [in, optional] LPCWSTR contentType
    );

    // Creates an object based on the EME spec MediaKeySystemAccess object:
    // https://www.w3.org/TR/2017/REC-encrypted-media-20170918/#mediakeysystemaccess-interface
    // See IMFMediaKeySystemAccess::CreateMediaKeys for configuration information.
    HRESULT CreateContentDecryptionModuleAccess(
        [in] LPCWSTR keySystem,
        [in, size_is(, numConfigurations)] IPropertyStore **configurations,
        [in] DWORD numConfigurations,
        [out] IMFContentDecryptionModuleAccess **contentDecryptionModuleAccess
    );
}

//
// MF_CONTENTDECRYPTIONMODULE_SERVICE
// Service GUID used to obtain interfaces from an IMFContentDecryptionModule implementation, e.g.,
// the IMediaProtectionPMPServer interface. An implementation of IMFContentDecryptionModule
// should implement IMFGetService and support this service GUID.
//
// {15320C45-FF80-484A-9DCB-0DF894E69A13}
cpp_quote("EXTERN_GUID( MF_CONTENTDECRYPTIONMODULE_SERVICE, 0x15320c45, 0xff80, 0x484a, 0x9d, 0xcb, 0xd, 0xf8, 0x94, 0xe6, 0x9a, 0x1);")

// 2df7b51e-797b-4d06-be71-d14a52cf8421
// Class ID for the activator of Encrypted Media Extension objects. The activator implements IMFActivate.
// Invoking IMFActivate::ActivateObject allows objects to be activated via an activatable class ID in 
// the same context/process as the activator.
cpp_quote("EXTERN_GUID(MF_ENCRYPTEDMEDIAEXTENSIONS_ACTIVATE, ")
cpp_quote("    0x2df7b51e, 0x797b, 0x4d06, 0xbe, 0x71, 0xd1, 0x4a, 0x52, 0xcf, 0x84, 0x21);")

// 77631a31-e5e7-4785-bf17-20f57b224802
// Attribute which holds the activatable class ID of the Encrypted Media Extension object in the content 
// protection system, represented as a string. 
// Eg. "Windows.Media.Protection.PlayReady.PlayReadyWinRTTrustedInput"
cpp_quote("EXTERN_GUID(MF_ENCRYPTEDMEDIAEXTENSIONS_ACTIVATABLE_CLASS_ID,")
cpp_quote("    0x77631a31, 0xe5e7, 0x4785, 0xbf, 0x17, 0x20, 0xf5, 0x7b, 0x22, 0x48, 0x02);")

// 3e73735c-e6c0-481d-8260-ee5db1343b5f
// A binary blob containing initialization data for the Encrypted Media Extension object.
cpp_quote("EXTERN_GUID(MF_ENCRYPTEDMEDIAEXTENSIONS_INITIALIZATION_DATA,")
cpp_quote("    0x3e73735c, 0xe6c0, 0x481d, 0x82, 0x60, 0xee, 0x5d, 0xb1, 0x34, 0x3b, 0x5f);")

/// <summary>
///     Creates an EncryptedMediaExtensionsStoreActivate for StoreContentDecryptionModule scenarios.
///     The activate can be created in the protected process and activated in the app process.
/// </summary>
/// <param name="pmpHost">
///     The IMFPMPHostApp with the necessary information to
///     create an EncryptedMediaExtensions Store Object for this app package.
/// </param>
/// <param name="objectStream">
///     The object stream that will be loaded via IMFActivate::Load.
/// </param>
/// <param name="classId">
///     String representing the target object's activatable class id.
/// </param>
/// <param name="activate">
///     Returns pointer to an EncryptedMediaExtensions Store Activate
/// </param>
cpp_quote("STDAPI MFCreateEncryptedMediaExtensionsStoreActivate(")
cpp_quote("    _In_ IMFPMPHostApp *pmpHost,")
cpp_quote("    _In_ IStream *objectStream,")
cpp_quote("    _In_ LPCWSTR classId,")
cpp_quote("    _Outptr_ IMFActivate** activate")
cpp_quote("    );")

cpp_quote("#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) */")
#pragma endregion
