Microsoft DirectX 8.1 (C++) |
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:
Also at this time, add any tolls that apply to this denial, as follows:
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.