Symbian3/PDK/Source/GUID-43080A86-72D3-5422-953E-A5EF79961D7B.dita
changeset 3 46218c8b8afa
parent 1 25a17d01db0c
child 5 f345bda72bc4
--- a/Symbian3/PDK/Source/GUID-43080A86-72D3-5422-953E-A5EF79961D7B.dita	Thu Mar 11 15:24:26 2010 +0000
+++ b/Symbian3/PDK/Source/GUID-43080A86-72D3-5422-953E-A5EF79961D7B.dita	Thu Mar 11 18:02:22 2010 +0000
@@ -1,362 +1,350 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
-<!-- This component and the accompanying materials are made available under the terms of the License 
-"Eclipse Public License v1.0" which accompanies this distribution, 
-and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
-<!-- Initial Contributors:
-    Nokia Corporation - initial contribution.
-Contributors: 
--->
-<!DOCTYPE concept
-  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
-<concept id="GUID-43080A86-72D3-5422-953E-A5EF79961D7B" xml:lang="en"><title>Writing
-a UPS Policy Evaluator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
-<section><title>Introduction</title> <p>Policy Evaluators are ECOM plug-ins.
-They allow security decisions to be specific to the data on which the service
-acts instead of simply granting full access to the service, for example "Allow
-application X to send SMS messages to 01234567". This is supported through
-the fingerprint functionality. They allow a security decision to be specific
-to an individual script executing within a scripting host. This is supported
-through the client entity field. And they allow a prompt to be displayed even
-if the user selected "Always" or "Never". This could be based on a usage threshold
-or simply as additional confirmation if the user selected "Never". This is
-supported through the force prompt functionality. </p> <p> <b>Note</b>: when
-a user selects “Never” or “Always”, the UPS creates a record in a decision
-database. This record identifies the system server UID, service UID, client
-SID, client entity name (name of an entity running within a client process,
-for example, a script identifier) and a "fingerprint" for a given decision. </p> <p>The
-purpose of a Policy Evaluator is to allow device creators to optionally customise
-the behaviour of the UPS at run-time. Policy Evaluators may: </p> <ul>
-<li id="GUID-1D5DD614-02E3-56AA-A0A6-A694E2311A0E"><p>Allow security decisions
-to be specific to the data on which the service acts instead of simply granting
-full access to the service, for example "Allow application X to send SMS messages
-to 01234567". This is supported via the fingerprint functionality. </p> </li>
-<li id="GUID-5B5E3EB4-5C93-5E4E-BB6E-39F889AD3610"><p>Allow a security decision
-to be specific to an individual script executing within a scripting host.
-This is supported via the client entity field. </p> </li>
-<li id="GUID-8B26DA57-A9DF-5D99-A259-2E6DF7C4DCCE"><p>Allow a prompt to be
-displayed even if the user selected "Always" or "Never". This could be based
-on a usage threshold or simply as additional confirmation if the user selected
-"Never". This is supported via the force prompt functionality. </p> </li>
-</ul> </section>
-<section><title>Procedure</title> <p>Writing policy evaluator includes the
-following: </p> <ol id="GUID-F50174F6-3619-545A-8844-D4DA64B1B339">
-<li id="GUID-246EF2AB-23D9-5B1B-BC4C-8CCFB545C307"><p>Generating fingerprints </p> </li>
-<li id="GUID-4427FF70-9461-566A-8567-FC6EEF879475"><p>Forcing prompts </p> </li>
-<li id="GUID-703D9B83-78A0-5EA6-8D1C-685D2BC847EA"><p>Defining default policy
-evaluator </p> </li>
-</ol> <p>Policy evaluators implement the <codeph>CPolicyEvaluator</codeph> interface. </p> <p><b>Generating
-fingerprints</b> </p> <p>The key task of the policy evaluator is to generate
-fingerprints. A fingerprint is a collection of data describing the service
-being requested. The fingerprint usually includes the <codeph>destination</codeph> string,
-for example a telephone number, supplied by the service that is matched to
-the <codeph>destination</codeph> string of a policy in the policy file. </p> <p>The
-policy evaluator must implement the <codeph>GenerateFingerprints()</codeph> function,
-which is a pure virtual function, declared in the <xref href="GUID-FDE91CAC-1588-3EED-B509-08168F4B881B.dita"><apiname>CPolicyEvaluator</apiname></xref> base
-class. The function is asynchronous to allow the implementation to call other
-server processes. </p> <p>The following table describes the parameters for
-the <codeph>GenerateFingerprints()</codeph> function: </p> <table id="GUID-963D89B8-EB90-5668-8A08-588EF1E94C43">
-<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
-<thead>
-<row>
-<entry>Parameter</entry>
-<entry>Description</entry>
-</row>
-</thead>
-<tbody>
-<row>
-<entry><p> <codeph>aRequest</codeph>  </p> </entry>
-<entry><p>Data that the system server provides to the UPS, including the ClientSid,
-ServerSid and ServiceId. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aPolicy</codeph>  </p> </entry>
-<entry><p>Details of the policy for the service. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aFingerprints</codeph>  </p> </entry>
-<entry><p>Array of fingerprints. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aClientEntity</codeph>  </p> </entry>
-<entry><p>Details of client entity (will be null if the client process is
-not an execution host or the policy evaluator does not support client entities). </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aDialogCreatorParams</codeph>  </p> </entry>
-<entry><p>Opaque data, which can be any other information for use in the fingerprint
-or to be displayed in the dialog. </p> </entry>
-</row>
-<row>
-<entry><p> <codeph>aStatus</codeph>  </p> </entry>
-<entry><p>The request status used to contain completion information for the
-function. </p> </entry>
-</row>
-</tbody>
-</tgroup>
-</table> <p>The following code fragment is a sample implementation of the <codeph>GenerateFingerprints()</codeph> function. </p> <codeblock id="GUID-B8555FDF-8BDD-5D22-AA20-AA9A4B35148A" xml:space="preserve">void CRefPolicyEvaluator::GenerateFingerprints(
- const CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy, 
-    RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity*&amp; aClientEntity, 
-    const TAny*&amp; aDialogCreatorParams, TRequestStatus&amp; aStatus)
-    {
-    iRequest = &amp;aRequest;
-    iPolicy = &amp;aPolicy;
-    iFingerprints = &amp;aFingerprints;        
-
-    // This OUT parameter *could* be set to point to data structure
-    // owned by this policy evaluator that is read by the dialog-creator.
-    aDialogCreatorParams = 0;
-    
-    // The client entity field only needs to be set if the policy evaluator
-    // is designed to identify scripts/non-native applications being executed
-    // by the client application.
-    aClientEntity = 0;                
-    
-    iClientStatus = &amp;aStatus;
-    aStatus = KRequestPending;
-    
-    // Kick off policy evaluator state machine
-    iStatus = KRequestPending;
-    TRequestStatus* status = &amp;iStatus;
-    SetActive();
-    User::RequestComplete(status, KErrNone);
-    }
-</codeblock> <p> <codeph>RunL()</codeph> is called when the request completes.
-The fingerprint is created and appended to the fingerprint array in <codeph>RunL()</codeph>.
-The following example shows a hash of a destination being created for a fingerprint
-as well as an empty fingerprint for decisions that apply to all destinations. </p> <codeblock id="GUID-EB57F6E0-C3B2-5CDC-B9FF-A570B73B4C74" xml:space="preserve">void CRefPolicyEvaluator::RunL()
-    {    
-    // Create most specific hash first i.e. HASH(destination)
-    // Information from the opaque data supplied by the system server 
-    // may also be used.
-    // N.B. The UPS does not require the fingerprint to be a hash. However,
-    // the fingerprint is limited to 32 bytes.    
-    iDigest-&gt;Reset();
-    const TDesC&amp; d = iRequest-&gt;Destination();
-    TPtrC8 p(reinterpret_cast&lt;const TUint8*&gt;(d.Ptr()), d.Length() * 2);
-    TPtrC8 h(iDigest-&gt;Hash(p));
-    
-    CFingerprint* f = CFingerprint::NewLC(h, d);
-    iFingerprints-&gt;AppendL(f);
-    CleanupStack::Pop(f);
-
-    // An empty fingerprint may be used for decisions that apply to
-    // all destinations.
-    f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
-    iFingerprints-&gt;AppendL(f);
-    CleanupStack::Pop(f);
-        
-    User::RequestComplete(iClientStatus, KErrNone);
-    }
-</codeblock> <p><b>Forcing prompts</b> </p> <p>You can implement the <codeph>ForcePromptL()</codeph> function
-to force a prompt, even if the UPS has found a persistent decision for the
-request in the decision database. It may be desirable to force a prompt in
-some cases such as: </p> <ul>
-<li id="GUID-4C9DDFB3-C358-534F-8E65-42E1BC672D64"><p>if a threshold has been
-reached, for example the number of MMS messages sent on a particular day </p> </li>
-<li id="GUID-5D5E02E5-DA19-5A30-8071-CD64631FBEAD"><p>if a phone user has
-selected "Never", because denying a request to a non-UPS-aware application
-may cause it to fail — the user may not realise that the previous selection
-of "Never" has caused the failure or may not know how to find the management
-application to revert the decision </p> </li>
-</ul> <p>The UPS invokes the <codeph>ForcePromptL()</codeph> function after
-a matching record is found in the database. The <codeph>ForcePromptL()</codeph> function
-is defined in the <codeph>CPolicyEvaluator</codeph> base class. The implementation
-in the base class always returns <codeph>EFalse</codeph>. To force a prompt,
-device creators need to override this function and return <codeph>ETrue</codeph>.
-A sample implementation is as follows. The <codeph>aNewEvaluatorInfo</codeph> field
-is a policy evaluator defined 32-bit field. It could be used to store usage
-thresholds or as a flag that indicates that the prompt has already been forced. </p> <codeblock id="GUID-4E60DCA5-7F25-5FC7-B173-05E1A15FCEE6" xml:space="preserve">TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord&amp; aDecision, TUint&amp; aNewEvaluatorInfo)
-    {
-    // In this example, if the user selects Never, then they are prompted
-    // once more in-case they did not intend to select Never. 
-    // The "Evaluator Info" field is used to ensure the prompt is only forced once.
-    //
-    // The base class implementation (CPolicyEvaluator::ForcePromptL) 
-    // always returns EFalse.
-    aNewEvaluatorInfo = 1;
-    return (aDecision.iResult == 0 &amp;&amp; aDecision.iEvaluatorInfo == 0);
-    }
-</codeblock> <p><b>Defining default policy evaluator</b> </p> <p>If device
-creators do not define a policy evaluator, a default (internal) policy evaluator
-is returned. The default policy evaluator returns a single, null fingerprint.
-The default policy evaluator does not override the <codeph>ForcePromptL()</codeph> API. </p> </section>
-<section><title> Upgrading policy evaluators </title> <p>A policy evaluator
-can be overwritten or eclipsed without restarting the UPS, if it is delivered
-through an appropriately signed upgrade. </p> <ul>
-<li id="GUID-086FABB6-13C0-5D98-8B2A-1D38BD620EB5"><p>The ECOM plug-in will
-be reloaded only when there are no active <codeph>RUpsSubsession::Authorise()</codeph> requests. </p> </li>
-<li id="GUID-CD95EB32-9438-5AA1-BA80-8C90DC304642"><p>The decision records
-are not deleted if the policy evaluator is changed. If the policy evaluator
-is not backwards compatible then new policy files with a new <codeph>majorversion</codeph> number
-should be delivered. </p> </li>
-<li id="GUID-DC1804B8-A052-52AC-96DC-32C3BBADE2A8"><p>SWI Observer informs
-the UPS that the plug-ins may have changed whenever Software Install modifies <filepath>sys\bin</filepath> on
-the system drive. There is no need to explicitly register changes to plug-ins. </p> </li>
-</ul> </section>
-<section><title> Policy evaluator example</title> <p>The following code shows
-an example of a full implementation of the policy evaluator file: </p> <codeblock id="GUID-D1615A8D-334C-5718-BFD6-EC3004A09F3A" xml:space="preserve">// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of the License "Symbian Foundation License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-
-// refpolicyevaluator.cpp
-
-#include "refpolicyevaluator.h"
-#include &lt;ecom/implementationproxy.h&gt;
-#include &lt;ups/cliententity.h&gt;
-#include &lt;ups/fingerprint.h&gt;
-#include &lt;ups/upsdb.h&gt;
-
-using namespace UserPromptService;
-
-static const TUint KRefPolicyEvaluatorImplementationId = 0x10285814;
-
-CPolicyEvaluator* CRefPolicyEvaluator::CreatePolicyEvaluatorL()
-/**
-Factory method that instantiates a new policy evaluator ECOM plug-in.
-
-@return A pointer to the new reference policy evaluator object.
-*/
-    {
-    CRefPolicyEvaluator* self = new (ELeave)CRefPolicyEvaluator();
-    CleanupStack::PushL(self);
-    self-&gt;ConstructL();
-    CleanupStack::Pop(self);
-    return self;
-    }
-
-static const TImplementationProxy ImplementationTable[] = 
-    {
-    IMPLEMENTATION_PROXY_ENTRY(KRefPolicyEvaluatorImplementationId, CRefPolicyEvaluator::CreatePolicyEvaluatorL)
-    };
-
-EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt&amp; aTableCount)
-/**
-Standard ECOM factory
-*/
-    {
-    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
-    return ImplementationTable;
-    }    
-    
-
-CRefPolicyEvaluator::CRefPolicyEvaluator()
-/**
-Constructor
-*/
-    : CPolicyEvaluator()
-    {
-    CActiveScheduler::Add(this);
-    }
-    
-CRefPolicyEvaluator::~CRefPolicyEvaluator()
-/**
-Destructor
-*/
-    {
-    Deque();
-    delete iDigest;
-    }
-
-void CRefPolicyEvaluator::ConstructL()
-/**
-Second phase constructor, creates the message digest
-*/
-    {    
-    iDigest = CMessageDigestFactory::NewDigestL(CMessageDigest::EMD5);
-    }
-
-// From CActive
-void CRefPolicyEvaluator::DoCancel()
-    {    
-    // Logically should Cancel the internal outstanding requst, but
-    // currently GenerateFingerprints has already completed it.
-
-    // And need to complete the clients request
-    if (iClientStatus)
-        {
-        User::RequestComplete(iClientStatus, KErrCancel);
-        }
-    }
-    
-TInt CRefPolicyEvaluator::RunError(TInt aError)
-    {
-    if (iClientStatus)
-        {
-        User::RequestComplete(iClientStatus, aError);
-        }
-    return KErrNone;
-    }
-    
-void CRefPolicyEvaluator::RunL()
-    {    
-    // Create most specific hash first i.e. HASH(destination)
-    // Information from the opaque data supplied by the system server 
-    // may also be used.
-    // N.B. The UPS does not require the fingerprint to be a hash. However,
-    // the fingerprint is limited to 32 bytes.    
-    iDigest-&gt;Reset();
-    const TDesC&amp; d = iRequest-&gt;Destination();
-    TPtrC8 p(reinterpret_cast&lt;const TUint8*&gt;(d.Ptr()), d.Length() * 2);
-    TPtrC8 h(iDigest-&gt;Hash(p));
-    
-    CFingerprint* f = CFingerprint::NewLC(h, d);
-    iFingerprints-&gt;AppendL(f);
-    CleanupStack::Pop(f);
-
-    // An empty fingerprint may be used for decisions that apply to
-    // all destinations.
-    f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
-    iFingerprints-&gt;AppendL(f);
-    CleanupStack::Pop(f);
-        
-    User::RequestComplete(iClientStatus, KErrNone);
-    }
-
-void CRefPolicyEvaluator::GenerateFingerprints(
-    const CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy, 
-    RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity*&amp; aClientEntity, 
-    const TAny*&amp; aDialogCreatorParams, TRequestStatus&amp; aStatus)
-    {
-    iRequest = &amp;aRequest;
-    iPolicy = &amp;aPolicy;
-    iFingerprints = &amp;aFingerprints;        
-
-    // This OUT parameter *could* be set to point to data structure
-    // owned by this policy evaluator that is read by the dialog-creator.
-    aDialogCreatorParams = 0;
-    
-    // The client entity field only needs to be set if the policy evaluator
-    // is designed to identify scripts/non-native applications being executed
-    // by the client application.
-    aClientEntity = 0;                
-    
-    iClientStatus = &amp;aStatus;
-    aStatus = KRequestPending;
-    
-    // Kick off policy evaluator state machine
-    iStatus = KRequestPending;
-    TRequestStatus* status = &amp;iStatus;
-    SetActive();
-    User::RequestComplete(status, KErrNone);
-    }
-
-TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord&amp; aDecision, TUint&amp; aNewEvaluatorInfo)
-    {
-    // In this example, if the user selects Never, then they are prompted
-    // once more in-case they did not intend to select Never. 
-    // The "Evaluator Info" field is used to ensure the prompt is only forced once.
-    //
-    // The base class implementation (CPolicyEvaluator::ForcePromptL) 
-    // always returns EFalse.
-    aNewEvaluatorInfo = 1;
-    return (aDecision.iResult == 0 &amp;&amp; aDecision.iEvaluatorInfo == 0);
-    }
-</codeblock> </section>
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-43080A86-72D3-5422-953E-A5EF79961D7B" xml:lang="en"><title>Writing
+a UPS Policy Evaluator</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<section id="GUID-56EDF170-1A32-4275-8799-99D13C485E1E"><title>Introduction</title> <p>Policy Evaluators are ECOM plug-ins.
+They allow security decisions to be specific to the data on which the service
+acts instead of simply granting full access to the service, for example "Allow
+application X to send SMS messages to 01234567". This is supported through
+the fingerprint functionality. They allow a security decision to be specific
+to an individual script executing within a scripting host. This is supported
+through the client entity field. And they allow a prompt to be displayed even
+if the user selected "Always" or "Never". This could be based on a usage threshold
+or simply as additional confirmation if the user selected "Never". This is
+supported through the force prompt functionality. </p> <p> <b>Note</b>: when
+a user selects “Never” or “Always”, the UPS creates a record in a decision
+database. This record identifies the system server UID, service UID, client
+SID, client entity name (name of an entity running within a client process,
+for example, a script identifier) and a "fingerprint" for a given decision. </p> <p>The
+purpose of a Policy Evaluator is to allow device creators to optionally customise
+the behaviour of the UPS at run-time. Policy Evaluators may: </p> <ul>
+<li id="GUID-1D5DD614-02E3-56AA-A0A6-A694E2311A0E"><p>Allow security decisions
+to be specific to the data on which the service acts instead of simply granting
+full access to the service, for example "Allow application X to send SMS messages
+to 01234567". This is supported via the fingerprint functionality. </p> </li>
+<li id="GUID-5B5E3EB4-5C93-5E4E-BB6E-39F889AD3610"><p>Allow a security decision
+to be specific to an individual script executing within a scripting host.
+This is supported via the client entity field. </p> </li>
+<li id="GUID-8B26DA57-A9DF-5D99-A259-2E6DF7C4DCCE"><p>Allow a prompt to be
+displayed even if the user selected "Always" or "Never". This could be based
+on a usage threshold or simply as additional confirmation if the user selected
+"Never". This is supported via the force prompt functionality. </p> </li>
+</ul> </section>
+<section id="GUID-CCBB139D-0F1C-4AD4-B2F2-062CF660A0DE"><title>Procedure</title> <p>Writing policy evaluator includes the
+following: </p> <ol id="GUID-F50174F6-3619-545A-8844-D4DA64B1B339">
+<li id="GUID-246EF2AB-23D9-5B1B-BC4C-8CCFB545C307"><p>Generating fingerprints </p> </li>
+<li id="GUID-4427FF70-9461-566A-8567-FC6EEF879475"><p>Forcing prompts </p> </li>
+<li id="GUID-703D9B83-78A0-5EA6-8D1C-685D2BC847EA"><p>Defining default policy
+evaluator </p> </li>
+</ol> <p>Policy evaluators implement the <codeph>CPolicyEvaluator</codeph> interface. </p> <p><b>Generating
+fingerprints</b> </p> <p>The key task of the policy evaluator is to generate
+fingerprints. A fingerprint is a collection of data describing the service
+being requested. The fingerprint usually includes the <codeph>destination</codeph> string,
+for example a telephone number, supplied by the service that is matched to
+the <codeph>destination</codeph> string of a policy in the policy file. </p> <p>The
+policy evaluator must implement the <codeph>GenerateFingerprints()</codeph> function,
+which is a pure virtual function, declared in the <xref href="GUID-FDE91CAC-1588-3EED-B509-08168F4B881B.dita"><apiname>CPolicyEvaluator</apiname></xref> base
+class. The function is asynchronous to allow the implementation to call other
+server processes. </p> <p>The following table describes the parameters for
+the <codeph>GenerateFingerprints()</codeph> function: </p> <table id="GUID-963D89B8-EB90-5668-8A08-588EF1E94C43">
+<tgroup cols="2"><colspec colname="col0"/><colspec colname="col1"/>
+<thead>
+<row>
+<entry>Parameter</entry>
+<entry>Description</entry>
+</row>
+</thead>
+<tbody>
+<row>
+<entry><p> <codeph>aRequest</codeph>  </p> </entry>
+<entry><p>Data that the system server provides to the UPS, including the ClientSid,
+ServerSid and ServiceId. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aPolicy</codeph>  </p> </entry>
+<entry><p>Details of the policy for the service. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aFingerprints</codeph>  </p> </entry>
+<entry><p>Array of fingerprints. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aClientEntity</codeph>  </p> </entry>
+<entry><p>Details of client entity (will be null if the client process is
+not an execution host or the policy evaluator does not support client entities). </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aDialogCreatorParams</codeph>  </p> </entry>
+<entry><p>Opaque data, which can be any other information for use in the fingerprint
+or to be displayed in the dialog. </p> </entry>
+</row>
+<row>
+<entry><p> <codeph>aStatus</codeph>  </p> </entry>
+<entry><p>The request status used to contain completion information for the
+function. </p> </entry>
+</row>
+</tbody>
+</tgroup>
+</table> <p>The following code fragment is a sample implementation of the <codeph>GenerateFingerprints()</codeph> function. </p> <codeblock id="GUID-B8555FDF-8BDD-5D22-AA20-AA9A4B35148A" xml:space="preserve">void CRefPolicyEvaluator::GenerateFingerprints(
+ const CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy, 
+    RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity*&amp; aClientEntity, 
+    const TAny*&amp; aDialogCreatorParams, TRequestStatus&amp; aStatus)
+    {
+    iRequest = &amp;aRequest;
+    iPolicy = &amp;aPolicy;
+    iFingerprints = &amp;aFingerprints;        
+
+    // This OUT parameter *could* be set to point to data structure
+    // owned by this policy evaluator that is read by the dialog-creator.
+    aDialogCreatorParams = 0;
+    
+    // The client entity field only needs to be set if the policy evaluator
+    // is designed to identify scripts/non-native applications being executed
+    // by the client application.
+    aClientEntity = 0;                
+    
+    iClientStatus = &amp;aStatus;
+    aStatus = KRequestPending;
+    
+    // Kick off policy evaluator state machine
+    iStatus = KRequestPending;
+    TRequestStatus* status = &amp;iStatus;
+    SetActive();
+    User::RequestComplete(status, KErrNone);
+    }
+</codeblock> <p> <codeph>RunL()</codeph> is called when the request completes.
+The fingerprint is created and appended to the fingerprint array in <codeph>RunL()</codeph>.
+The following example shows a hash of a destination being created for a fingerprint
+as well as an empty fingerprint for decisions that apply to all destinations. </p> <codeblock id="GUID-EB57F6E0-C3B2-5CDC-B9FF-A570B73B4C74" xml:space="preserve">void CRefPolicyEvaluator::RunL()
+    {    
+    // Create most specific hash first i.e. HASH(destination)
+    // Information from the opaque data supplied by the system server 
+    // may also be used.
+    // N.B. The UPS does not require the fingerprint to be a hash. However,
+    // the fingerprint is limited to 32 bytes.    
+    iDigest-&gt;Reset();
+    const TDesC&amp; d = iRequest-&gt;Destination();
+    TPtrC8 p(reinterpret_cast&lt;const TUint8*&gt;(d.Ptr()), d.Length() * 2);
+    TPtrC8 h(iDigest-&gt;Hash(p));
+    
+    CFingerprint* f = CFingerprint::NewLC(h, d);
+    iFingerprints-&gt;AppendL(f);
+    CleanupStack::Pop(f);
+
+    // An empty fingerprint may be used for decisions that apply to
+    // all destinations.
+    f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
+    iFingerprints-&gt;AppendL(f);
+    CleanupStack::Pop(f);
+        
+    User::RequestComplete(iClientStatus, KErrNone);
+    }
+</codeblock> <p><b>Forcing prompts</b> </p> <p>You can implement the <codeph>ForcePromptL()</codeph> function
+to force a prompt, even if the UPS has found a persistent decision for the
+request in the decision database. It may be desirable to force a prompt in
+some cases such as: </p> <ul>
+<li id="GUID-4C9DDFB3-C358-534F-8E65-42E1BC672D64"><p>if a threshold has been
+reached, for example the number of MMS messages sent on a particular day </p> </li>
+<li id="GUID-5D5E02E5-DA19-5A30-8071-CD64631FBEAD"><p>if a phone user has
+selected "Never", because denying a request to a non-UPS-aware application
+may cause it to fail — the user may not realise that the previous selection
+of "Never" has caused the failure or may not know how to find the management
+application to revert the decision </p> </li>
+</ul> <p>The UPS invokes the <codeph>ForcePromptL()</codeph> function after
+a matching record is found in the database. The <codeph>ForcePromptL()</codeph> function
+is defined in the <codeph>CPolicyEvaluator</codeph> base class. The implementation
+in the base class always returns <codeph>EFalse</codeph>. To force a prompt,
+device creators need to override this function and return <codeph>ETrue</codeph>.
+A sample implementation is as follows. The <codeph>aNewEvaluatorInfo</codeph> field
+is a policy evaluator defined 32-bit field. It could be used to store usage
+thresholds or as a flag that indicates that the prompt has already been forced. </p> <codeblock id="GUID-4E60DCA5-7F25-5FC7-B173-05E1A15FCEE6" xml:space="preserve">TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord&amp; aDecision, TUint&amp; aNewEvaluatorInfo)
+    {
+    // In this example, if the user selects Never, then they are prompted
+    // once more in-case they did not intend to select Never. 
+    // The "Evaluator Info" field is used to ensure the prompt is only forced once.
+    //
+    // The base class implementation (CPolicyEvaluator::ForcePromptL) 
+    // always returns EFalse.
+    aNewEvaluatorInfo = 1;
+    return (aDecision.iResult == 0 &amp;&amp; aDecision.iEvaluatorInfo == 0);
+    }
+</codeblock> <p><b>Defining default policy evaluator</b> </p> <p>If device
+creators do not define a policy evaluator, a default (internal) policy evaluator
+is returned. The default policy evaluator returns a single, null fingerprint.
+The default policy evaluator does not override the <codeph>ForcePromptL()</codeph> API. </p> </section>
+<section id="GUID-987ECDA9-5728-4A7A-AB38-D58A7CC097AC"><title> Upgrading policy evaluators </title> <p>A policy evaluator
+can be overwritten or eclipsed without restarting the UPS, if it is delivered
+through an appropriately signed upgrade. </p> <ul>
+<li id="GUID-086FABB6-13C0-5D98-8B2A-1D38BD620EB5"><p>The ECOM plug-in will
+be reloaded only when there are no active <codeph>RUpsSubsession::Authorise()</codeph> requests. </p> </li>
+<li id="GUID-CD95EB32-9438-5AA1-BA80-8C90DC304642"><p>The decision records
+are not deleted if the policy evaluator is changed. If the policy evaluator
+is not backwards compatible then new policy files with a new <codeph>majorversion</codeph> number
+should be delivered. </p> </li>
+<li id="GUID-DC1804B8-A052-52AC-96DC-32C3BBADE2A8"><p>SWI Observer informs
+the UPS that the plug-ins may have changed whenever Software Install modifies <filepath>sys\bin</filepath> on
+the system drive. There is no need to explicitly register changes to plug-ins. </p> </li>
+</ul> </section>
+<section id="GUID-48624948-C1C9-4DEA-A6E1-6E4B9AC72E8E"><title> Policy evaluator example</title> <p>The following code shows
+an example of a full implementation of the policy evaluator file: </p> <codeblock id="GUID-D1615A8D-334C-5718-BFD6-EC3004A09F3A" xml:space="preserve">#include "refpolicyevaluator.h"
+#include &lt;ecom/implementationproxy.h&gt;
+#include &lt;ups/cliententity.h&gt;
+#include &lt;ups/fingerprint.h&gt;
+#include &lt;ups/upsdb.h&gt;
+
+using namespace UserPromptService;
+
+static const TUint KRefPolicyEvaluatorImplementationId = 0x10285814;
+
+CPolicyEvaluator* CRefPolicyEvaluator::CreatePolicyEvaluatorL()
+/**
+Factory method that instantiates a new policy evaluator ECOM plug-in.
+
+@return A pointer to the new reference policy evaluator object.
+*/
+    {
+    CRefPolicyEvaluator* self = new (ELeave)CRefPolicyEvaluator();
+    CleanupStack::PushL(self);
+    self-&gt;ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+static const TImplementationProxy ImplementationTable[] = 
+    {
+    IMPLEMENTATION_PROXY_ENTRY(KRefPolicyEvaluatorImplementationId, CRefPolicyEvaluator::CreatePolicyEvaluatorL)
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt&amp; aTableCount)
+/**
+Standard ECOM factory
+*/
+    {
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+    return ImplementationTable;
+    }    
+    
+
+CRefPolicyEvaluator::CRefPolicyEvaluator()
+/**
+Constructor
+*/
+    : CPolicyEvaluator()
+    {
+    CActiveScheduler::Add(this);
+    }
+    
+CRefPolicyEvaluator::~CRefPolicyEvaluator()
+/**
+Destructor
+*/
+    {
+    Deque();
+    delete iDigest;
+    }
+
+void CRefPolicyEvaluator::ConstructL()
+/**
+Second phase constructor, creates the message digest
+*/
+    {    
+    iDigest = CMessageDigestFactory::NewDigestL(CMessageDigest::EMD5);
+    }
+
+// From CActive
+void CRefPolicyEvaluator::DoCancel()
+    {    
+    // Logically should Cancel the internal outstanding requst, but
+    // currently GenerateFingerprints has already completed it.
+
+    // And need to complete the clients request
+    if (iClientStatus)
+        {
+        User::RequestComplete(iClientStatus, KErrCancel);
+        }
+    }
+    
+TInt CRefPolicyEvaluator::RunError(TInt aError)
+    {
+    if (iClientStatus)
+        {
+        User::RequestComplete(iClientStatus, aError);
+        }
+    return KErrNone;
+    }
+    
+void CRefPolicyEvaluator::RunL()
+    {    
+    // Create most specific hash first i.e. HASH(destination)
+    // Information from the opaque data supplied by the system server 
+    // may also be used.
+    // N.B. The UPS does not require the fingerprint to be a hash. However,
+    // the fingerprint is limited to 32 bytes.    
+    iDigest-&gt;Reset();
+    const TDesC&amp; d = iRequest-&gt;Destination();
+    TPtrC8 p(reinterpret_cast&lt;const TUint8*&gt;(d.Ptr()), d.Length() * 2);
+    TPtrC8 h(iDigest-&gt;Hash(p));
+    
+    CFingerprint* f = CFingerprint::NewLC(h, d);
+    iFingerprints-&gt;AppendL(f);
+    CleanupStack::Pop(f);
+
+    // An empty fingerprint may be used for decisions that apply to
+    // all destinations.
+    f = CFingerprint::NewLC(KNullDesC8, KNullDesC);
+    iFingerprints-&gt;AppendL(f);
+    CleanupStack::Pop(f);
+        
+    User::RequestComplete(iClientStatus, KErrNone);
+    }
+
+void CRefPolicyEvaluator::GenerateFingerprints(
+    const CPromptRequest&amp; aRequest, const CPolicy&amp; aPolicy, 
+    RPointerArray&lt;CFingerprint&gt;&amp; aFingerprints, const CClientEntity*&amp; aClientEntity, 
+    const TAny*&amp; aDialogCreatorParams, TRequestStatus&amp; aStatus)
+    {
+    iRequest = &amp;aRequest;
+    iPolicy = &amp;aPolicy;
+    iFingerprints = &amp;aFingerprints;        
+
+    // This OUT parameter *could* be set to point to data structure
+    // owned by this policy evaluator that is read by the dialog-creator.
+    aDialogCreatorParams = 0;
+    
+    // The client entity field only needs to be set if the policy evaluator
+    // is designed to identify scripts/non-native applications being executed
+    // by the client application.
+    aClientEntity = 0;                
+    
+    iClientStatus = &amp;aStatus;
+    aStatus = KRequestPending;
+    
+    // Kick off policy evaluator state machine
+    iStatus = KRequestPending;
+    TRequestStatus* status = &amp;iStatus;
+    SetActive();
+    User::RequestComplete(status, KErrNone);
+    }
+
+TBool CRefPolicyEvaluator::ForcePromptL(const CDecisionRecord&amp; aDecision, TUint&amp; aNewEvaluatorInfo)
+    {
+    // In this example, if the user selects Never, then they are prompted
+    // once more in-case they did not intend to select Never. 
+    // The "Evaluator Info" field is used to ensure the prompt is only forced once.
+    //
+    // The base class implementation (CPolicyEvaluator::ForcePromptL) 
+    // always returns EFalse.
+    aNewEvaluatorInfo = 1;
+    return (aDecision.iResult == 0 &amp;&amp; aDecision.iEvaluatorInfo == 0);
+    }
+</codeblock> </section>
 </conbody></concept>
\ No newline at end of file