Microsoft DirectX 8.1 (C++)

Blocking the Active Request

This topic applies to Windows XP Home Edition and Windows XP Professional only.

When a new request becomes active, the CA Manager notifies each policy by calling its ICAPolicy::CheckRequest method. At that point, the policy decides whether to block the request. Depending on the policy, it might check the channel number, look for rating values in data streams, look for data encryption, or anything else. Useful methods on the CA request object include ICARequest::get_RequestedItem, which returns the original tune request; and ICARequest::get_ScheduleEntry, which returns the schedule entry from the Guide Store.

The policy must also check whether the user already purchased the request through this policy. If so, the policy should not block the request. For example, the user might tune away from a program that he or she has purchased, and then tune back to it. The user might purchase a show in advance, through an offer. In the extreme case, the user’s system might crash in the middle of a program and need to be restarted.

To determine if a service was purchased, a policy must provide some kind of internal, persistent storage. The storage mechanism is private to the policy (and the tolls that it creates). It could be a private interface to a smart card, a database, or even a text file that supports multiple access. There can be multiple instances of the Video Control, and thus multiple instances of the same policy. All the instances must share the same storage, and access it in a thread-safe way.

If the policy determines that it should deny the request, it should add a denial to the request’s denial collection. To do this, perform the following steps:

  1. Retrieve the denial collection. Call the ICARequest::get_Denials method.
  2. Create a new denial and add it to the collection. Call the ICADenials::get_AddNew method; parameters include a short description and the initial state (either denied or transient). The method returns a pointer to the ICADenial interface.
  3. Use the ICADenial::put_Description method to add descriptions in other formats: long description, HTML, and XML.

Also at this time, add any tolls that apply to this denial, as follows:

  1. Retrieve the tolls collection from the denial. Call the ICADenial::get_Tolls method.
  2. Create a new toll, using private methods in the policy object.
  3. Initialize the toll. At the least, you must specify the CA Manager, the tolled object (in this case, the denial), and the owning policy. For more information, see Writing Tolls.
  4. Add the toll to the collection. Call the ICATolls::Add method.

Many of the details depend on the implementation of the policy, but the following example shows an outline of what to do:

STDMETHODIMP CPolicy::CheckRequest(ICARequest *pReq)
{
    HRESULT hr = S_OK;
    if(NULL == pReq)
        return S_OK;
    // Determine somehow whether to deny this request.
    BOOL fShouldBeDenied = MyPrivateFunction(pReq);
    if(fShouldBeDenied)
    {
        CComPtr<ICADenials> pDenials;
        CComPtr<ICADenial> pDenial;
        CComBSTR bstrDesc(OLESTR("Example Denial"));

        // Add a new denial to the denials collection.
        hr = preq->get_Denials(&pDenials);
        hr = pDenials->get_AddNew(this, bstrDesc, pReq, Denied, &pDenial);
        // Add descriptions in other formats (not shown).

        // Create a new toll and add it to the tolls collection.
        CComPtr<ICATollsPtr> pTolls;
        hr = pDenial->get_Tolls(&pTolls);
        CMyTollObject *pTollObject = new CMyTollObject();
        if (pToll)
        {
            CComQIPtr<ICAToll> pToll(pTollObject);
            // Initialize pointers on the toll (not shown).
            hr = pTolls->Add(pToll);
        }
    }
    return hr;
}

If any non-transient denials block the request when the CheckRequest method returns, the Video Control will not run the filter graph.