/**@@@+++@@@@******************************************************************
**
** Microsoft Windows Media
** Copyright (C) Microsoft Corporation. All rights reserved.
**
***@@@---@@@@******************************************************************
*/
//#include <stdlib.h>
#include "drmcommon.h"
#include "drmutilities.h"
#include "drmcontextsizes.h"
#include "drmmanager.h"
#include "tOEMIMP.h"
#include "tclib.h"
#include "tLicGen.h"
#include "tResponsegen.h"
#include "tstutils.h"
#include "tGetClientID.h"
#include "drmcmdlnpars.h"
#include "drmxmlparser.h"
#include "drmxmlbuilder.h"
#include "drmmetercertprivkey.h"
#include "drmcrt.h"


DRM_MANAGER_CONTEXT *m_pContextManager;
DRM_CHAR *m_pLogFile = "RefMeteringTestLogFile.xml";

/**********************************************************/

DRM_RESULT _GetMeterCertFromFile(const DRM_WCHAR *pwchInFile, DRM_WCHAR  *pwchMeterCert)
{
    DRM_RESULT dr = DRM_E_FILENOTFOUND;
    OEM_FILEHDL hfile    = OEM_INVALID_HANDLE_VALUE;

    if (pwchInFile)
    {
        DRM_WCHAR  *pwchFile = NULL;
        DRM_DWORD   cbFile   = 0,
        cbRead   = 0;

        if ((hfile = OEM_OpenFile (pwchInFile, 
                                    OEM_GENERIC_READ, 
                                    OEM_FILE_SHARE_NONE, 
                                    OEM_OPEN_EXISTING, 
                                    OEM_ATTRIBUTE_NORMAL)) != OEM_INVALID_HANDLE_VALUE)
        {
            dr = DRM_E_FILEREADERROR;
            if (OEM_GetFileSize (hfile, &cbFile))
            {
                if ((pwchFile = (DRM_WCHAR*)OEM_malloc (cbFile + 2)) != NULL)
                {
                    DX_VOS_MemSet(pwchFile, 0, cbFile+2);
                    if (OEM_ReadFile (hfile, pwchFile, cbFile, &cbRead))
                    {
                        DX_VOS_FastMemCpy(pwchMeterCert,pwchFile,cbFile);
                        dr = DRM_SUCCESS;
                    }
                    else
                    {
                        Log (m_pLogFile, "Unable to input file read file %S.\n", pwchInFile);
                    }

                    OEM_free (pwchFile);
                }
                else
                {
                    Log (m_pLogFile, "Unable to allocate memory to read file.\n");
                }
            }
            else
            {
                Log (m_pLogFile, "Unable to get size for file file.\n");
            }
        }
        else
        {
            /* argument not supplied */            
            Log (m_pLogFile, "Input file %S could not open.\n", pwchInFile);
        }
    }

     if (hfile != OEM_INVALID_HANDLE_VALUE)
        OEM_CloseFile (hfile);
	 return dr;

}
DRM_RESULT _GetMeterResponseFromFile(const DRM_WCHAR *pwchInResponseFile, DRM_WCHAR  **pwchMeterResponse)
{
    DRM_RESULT dr = DRM_E_FILENOTFOUND;
    OEM_FILEHDL hfile         = OEM_INVALID_HANDLE_VALUE;

    *pwchMeterResponse = NULL;

    if (pwchInResponseFile)
    {
        DRM_WCHAR  *pwchFile      = NULL;
        DRM_DWORD   cbFile        = 0,
                    cbRead        = 0;

        if ((hfile = OEM_OpenFile (pwchInResponseFile, 
                                    OEM_GENERIC_READ, 
                                    OEM_FILE_SHARE_NONE, 
                                    OEM_OPEN_EXISTING, 
                                    OEM_ATTRIBUTE_NORMAL)) != OEM_INVALID_HANDLE_VALUE)
        {
            dr = DRM_E_FILEREADERROR;
            if (OEM_GetFileSize (hfile, &cbFile))
            {
                if ((pwchFile = (DRM_WCHAR*)OEM_malloc (cbFile + 2)) != NULL)
                {
                    DX_VOS_MemSet(pwchFile, 0, cbFile+2);
                    if (OEM_ReadFile (hfile, pwchFile, cbFile, &cbRead))
                    {
                        *pwchMeterResponse = pwchFile;
                        pwchFile = NULL;
                        dr = DRM_SUCCESS;
                    }
                    else
                    {
                        Log (m_pLogFile, "Unable to input file read file %S.\n", pwchInResponseFile);
                        OEM_free (pwchFile);
                    }

                }
                else
                {
                    Log (m_pLogFile, "Unable to allocate memory to read file.\n");
                }
            }
            else
            {
                Log (m_pLogFile, "Unable to get size for file file.\n");
            }

        }
    }
    else
    {
        /* argument not supplied */

        Log (m_pLogFile, "Input file %S could not open.\n", pwchInResponseFile);
    }    

    if (hfile != OEM_INVALID_HANDLE_VALUE)
        OEM_CloseFile (hfile);
    return dr;
}

static DRM_DWORD _RequiredCharsForResponse(
    DRM_CONST_STRING *pdstrRecords,
    DRM_BOOL          fPartialData,
    DRM_DWORD        *pcchKIDs)
{
    DRM_DWORD  cchRequired = 25;
    DRM_INT    iKid        = 0;
    DRM_RESULT dr          = DRM_SUCCESS;

    ChkArg (pdstrRecords != NULL);
    ChkArg (pcchKIDs     != NULL);

    *pcchKIDs = 0;
    
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagMetering.cchString, 
                                               0,       
                                               g_dstrAttributeType.cchString,
                                               g_dstrResponse.cchString);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagData.cchString,     
                                               0,        
                                               0,                 
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagMID.cchString,      
                                               CCH_BASE64_EQUIV (SIZEOF (DRM_MID)),     
                                               0,                 
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagTID.cchString,
                                               CCH_BASE64_EQUIV (SIZEOF (DRM_TID)),
                                               0,
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagRecords.cchString,
                                               0,
                                               0,
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagCmd.cchString,
                                               g_dstrReset.cchString, 
                                               0,
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagHash.cchString,     
                                               0,
                                               0,
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagHashAlg.cchString,
                                               0,
                                               g_dstrAttributeType.cchString, 
                                               g_dstrHMAC.cchString);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagValue.cchString,
                                               CCH_BASE64_EQUIV (SHA_DIGEST_LEN),
                                               0,
                                               0);
                                                 
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagKID.cchString,
                                               0,
                                               0,
                                               0);

    if (fPartialData)
    {
        cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagPartialData.cchString, 
                                                   g_dstr1.cchString, 
                                                   0, 
                                                   0);
    }

    while (TRUE)
    {
        DRM_CONST_STRING dstrKIDCurr = EMPTY_DRM_STRING;

        if (DRM_SUCCEEDED (DRM_XML_GetNode (pdstrRecords, &g_dstrTagKID, NULL, NULL, iKid++, NULL, &dstrKIDCurr)))
        {
            *pcchKIDs += DRM_XMB_RequiredCharsForTag(g_dstrTagKID.cchString, 
                                                     0, 
                                                     g_dstrLabelValue.cchString, 
                                                     CCH_BASE64_EQUIV (SIZEOF (DRM_KID)));
        }
        else
        {
            break;
        }
    }

    cchRequired += CCH_BASE64_EQUIV ((*pcchKIDs + PK_ENC_CIPHERTEXT_LEN) * SIZEOF (DRM_WCHAR));
    cchRequired += DRM_XMB_RequiredCharsForTag(g_dstrTagMSDRMSignature.cchString,
                                               CCH_BASE64_EQUIV (PK_ENC_SIGNATURE_LEN),
                                               0,
                                               0);


ErrorExit:    
    return cchRequired;
}

/*******************************************************************
*                  PRIVATE FUNCTION WriteMeterResponse
*
* purpose: Write the XML with signature to the output file
*******************************************************************/

static DRM_RESULT WriteMeterResponse(
    DRM_CONST_STRING *pdstrFileResponse,
    DRM_CONST_STRING *pdstrMID,
    DRM_CONST_STRING *pdstrTID,
    DRM_CONST_STRING *pdstrRecords,
    PUBKEY           *ppubkeEncrypt,
    PRIVKEY          *pSignKey)
{
    DRM_BOOL          fPartialData = 0;
    OEM_FILEHDL       hFileOut = OEM_INVALID_HANDLE_VALUE;
    DRM_RESULT       dr         = DRM_SUCCESS;
    DRM_DWORD        cbOut      = 0;
    DRM_DWORD        cbWritten  = 0;
    DRM_DWORD        cchKIDs    = 0;
    DRM_INT          iKID       = 0;
    DRM_STRING       strXML     = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKID    = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKIDB64 = EMPTY_DRM_STRING;
    DRM_STRING       dstrClose  = EMPTY_DRM_STRING;
    _XMBContext     *pbOut      = NULL;
    DRM_WCHAR       *pwszOut    = NULL;
    DRM_CRYPTO_CONTEXT *pcontextCrypto   = NULL;


    hFileOut = OEM_OpenFile(pdstrFileResponse->pwszString,
                                OEM_GENERIC_WRITE,
                                OEM_FILE_SHARE_NONE,
                                OEM_CREATE_ALWAYS,
                                OEM_ATTRIBUTE_NORMAL);
    if (hFileOut == OEM_INVALID_HANDLE_VALUE)
        ChkDR(DRM_E_FILEWRITEERROR);

    ChkMem(pcontextCrypto = OEM_malloc(SIZEOF (DRM_CRYPTO_CONTEXT)));

    cbOut     =  SIZEOF (DRM_WCHAR) * _RequiredCharsForResponse(pdstrRecords, fPartialData, &cchKIDs) ;
       
    if (cchKIDs ==0)
    {
        ChkDR(DRM_E_INVALIDARG);
    }

    ChkMem(pbOut = OEM_malloc(cbOut));

    ChkDR(DRM_XMB_CreateDocument(cbOut,  pbOut,               &g_dstrTagMetering));              /* <METERDATA type="response"> */
    ChkDR(DRM_XMB_AddAttribute  (pbOut, &g_dstrAttributeType, &g_dstrResponse));

    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagData, NULL,        NULL, NULL, wttOpen));   /*   <DATA> */
    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagMID,  pdstrMID,    NULL, NULL, wttClosed)); /*     <MID>base64</MID> */
    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagTID,  pdstrTID,    NULL, NULL, wttClosed)); /*     <TID>base64</TID> */
    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagCmd, &g_dstrReset, NULL, NULL, wttClosed)); /*     <COMMAND>RESET</COMMAND> */
    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagRecords, NULL,     NULL, NULL, wttOpen)); /*     <RECORDS> */

    while (TRUE)
    {
        dr = DRM_XML_GetNode(pdstrRecords, &g_dstrTagKID, NULL, NULL, iKID++, &dstrKID, NULL);

        if (DRM_SUCCEEDED (dr))
        {
            /* extract the value="KIDasbase64" from the challenge */

            ChkDR(DRM_XML_GetNodeAttribute(&dstrKID, &g_dstrLabelValue, &dstrKIDB64));

            /* write the KID entries in the response */

            ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagKID, NULL, &g_dstrLabelValue, &dstrKIDB64, wttClosed));   /*   <KID value="base64"/> */
        }
        else if (dr == DRM_E_NOMORE
              || dr == DRM_E_XMLNOTFOUND)
        {
            dr = DRM_SUCCESS;
            break;
        }
        else
        {
            ChkDR(dr);
        }
    } /* end while more KIDs */
//printf("%S\n", (DRM_WCHAR*)(pbOut + 32));
    ChkDR(DRM_XMB_EncryptAndCloseCurrNode(pbOut, 
                                           pcontextCrypto,
                                           ppubkeEncrypt,
                                           NULL)); /* </RECORDS> */
   
    if (fPartialData)
    {                                                                 /*     <PARTIALDATA>1</PARTIALDATA> */
        ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagPartialData, &g_dstr1, NULL, NULL, wttClosed));
    }

    /*Close the data node */
    ChkDR(DRM_XMB_CloseCurrNode(pbOut, &dstrClose));
    ChkDR(DRM_XMB_CloseDocument(pbOut, &strXML));  /* </METERDATA> */

    DRM_memmove (pbOut,
             PB_DSTR(&strXML),
             CB_DSTR(&strXML));

    pwszOut = (DRM_WCHAR *) pbOut;
    pwszOut [strXML.cchString] = g_wchNull;

    dr = OEM_WriteFile(hFileOut, (DRM_VOID *) pwszOut, CB_DSTR(&strXML), &cbWritten)
                ? DRM_SUCCESS
                : DRM_E_FILEWRITEERROR;

ErrorExit:

    if (pbOut != NULL)
    {
        OEM_free(pbOut);
    }
    if (pcontextCrypto != NULL)
    {
        OEM_free(pcontextCrypto);
    }

    if (hFileOut != OEM_INVALID_HANDLE_VALUE)
        OEM_CloseFile(hFileOut);
    return dr;
}

DRM_RESULT _SignResponse(DRM_CONST_STRING *pdstrResponse, 
                         DRM_CONST_STRING *pdstrCert,
                         DRM_CONST_STRING *pdstrOut,
                         PRIVKEY *pSignKey)
{
    DRM_RESULT dr = DRM_SUCCESS;
    _XMBContext     *pbOut      = NULL;
    DRM_WCHAR       *pwszOut    = NULL;
    DRM_CRYPTO_CONTEXT *pcontextCrypto   = NULL;
    DRM_DWORD cbOut = 0;
    DRM_CONST_STRING dstrSign   = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrListTop = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrDataNode = EMPTY_DRM_STRING;
    DRM_STRING       strXML     = EMPTY_DRM_STRING;
    DRM_DWORD        cbBuffer   = 0;

    ChkMem(pcontextCrypto = OEM_malloc(SIZEOF (DRM_CRYPTO_CONTEXT)));

    cbOut = (SIZEOF (DRM_WCHAR) * pdstrResponse->cchString) * 3;
    cbOut += SIZEOF (DRM_WCHAR) * pdstrCert->cchString ;
    cbOut += 1000;

    ChkMem(pbOut = OEM_malloc(cbOut));


    ChkDR(DRM_XML_GetNode(pdstrResponse, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrDataNode))

    ChkDR(DRM_XMB_CreateDocument(cbOut,  pbOut,               &g_dstrTagMetering));              /* <METERDATA type="response"> */
    ChkDR(DRM_XMB_AddAttribute  (pbOut, &g_dstrAttributeType, &g_dstrResponse));
    /*Sign it with Signing key*/

    ChkDR(DRM_XMB_OpenNode(pbOut,&g_dstrTagData));
    ChkDR(DRM_XMB_AddData(pbOut, &dstrDataNode));
    ChkDR(DRM_XMB_CloseCurrNode(pbOut, &strXML));
    ChkDR(DRM_PK_Sign(pcontextCrypto->rgbCryptoContext, 
                pSignKey,
                (DRM_BYTE *)strXML.pwszString, 
                CB_DSTR(&strXML), 
                pcontextCrypto->union_cert.cert.sign));

    /*Base64 encode signature*/
    cbBuffer=PK_ENC_SIGNATURE_B64LEN;
    ChkDR(DRM_B64_EncodeW((DRM_BYTE *)pcontextCrypto->union_cert.cert.sign, 
                           PK_ENC_SIGNATURE_LEN, 
              (DRM_WCHAR *)pcontextCrypto->rgbCryptoContext, 
                          &cbBuffer, 
                          0));
    /*Write to tag*/

    DSTR_FROM_PB(&dstrSign, pcontextCrypto->rgbCryptoContext, cbBuffer*SIZEOF(DRM_WCHAR));
    
    ChkDR(DRM_XMB_WriteTag(pbOut, &g_dstrTagMSDRMSignature, &dstrSign, NULL, NULL, wttClosed));

    ChkDR(DRM_XMB_AppendNode(pbOut, pdstrCert));
    ChkDR(DRM_XMB_CloseDocument(pbOut, &strXML));  /* </METERDATA> */

    DRM_memmove (pbOut,
             PB_DSTR(&strXML),
             CB_DSTR(&strXML));

    pwszOut = (DRM_WCHAR *) pbOut;
    pwszOut [strXML.cchString] = g_wchNull;

    pdstrOut->pwszString = pwszOut;
    pdstrOut->cchString = strXML.cchString;
ErrorExit:
    return dr;
}

/*

	argv[0] - filename of first metering response
	argv[1] - filename of second metering response
	argv[2] - whether the TIDs in argv[0] and argv[1] should match.
*/

DRM_RESULT TestDRM_VerifyTID(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;

	DRM_CONST_STRING	dstrMeterResp = EMPTY_DRM_STRING;
	DRM_WCHAR			*pwchMeterResponse = 0;
	DRM_CONST_STRING	dstrListTop = EMPTY_DRM_STRING;
	DRM_CONST_STRING	dstrListData = EMPTY_DRM_STRING;
	DRM_CONST_STRING	dstrMID = EMPTY_DRM_STRING;
    DRM_CONST_STRING	dstrTID1 = EMPTY_DRM_STRING;
	DRM_CONST_STRING	dstrTID2 = EMPTY_DRM_STRING;

	ChkArg(argc>2);

#ifdef WINCE_TEST
	char szFilename[256]={0};
	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[0]);
	MakeDRMString(&dstrMeterResp, szFilename);
#else
    MakeDRMString(&dstrMeterResp, argv[0]);
#endif

	ChkDR(_GetMeterResponseFromFile(dstrMeterResp.pwszString, &pwchMeterResponse));
	ChkArg(pwchMeterResponse);

	dstrMeterResp.cchString = DRM_wcslen(pwchMeterResponse);
	dstrMeterResp.pwszString = pwchMeterResponse;

	//parse TID out from first response
	ChkDR(DRM_XML_GetNode(&dstrMeterResp, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrListData));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagMID, NULL, NULL, 0, NULL, &dstrMID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagTID, NULL, NULL, 0, NULL, &dstrTID1));

#ifdef WINCE_TEST
	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[1]);
	MakeDRMString(&dstrMeterResp, szFilename);
#else
    MakeDRMString(&dstrMeterResp, argv[1]);

#endif
	
	ChkDR(_GetMeterResponseFromFile(dstrMeterResp.pwszString, &pwchMeterResponse));
	ChkArg(pwchMeterResponse);

	dstrMeterResp.cchString = DRM_wcslen(pwchMeterResponse);
	dstrMeterResp.pwszString = pwchMeterResponse;

	//parse TID out from second response
	ChkDR(DRM_XML_GetNode(&dstrMeterResp, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrListData));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagMID, NULL, NULL, 0, NULL, &dstrMID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagTID, NULL, NULL, 0, NULL, &dstrTID2));

	if(!DX_VOS_StrCmp("TRUE",argv[2])) //TIDs should match
	{
		if(!DRM_UTL_DSTRStringsEqual(&dstrTID1,&dstrTID2))
			ChkDR(DRM_E_FAIL);
	}
	else //TIDs should not match
	{
		if(DRM_UTL_DSTRStringsEqual(&dstrTID1,&dstrTID2))
			ChkDR(DRM_E_FAIL);
	}

ErrorExit:
	if(pwchMeterResponse)
		OEM_free(pwchMeterResponse);
	return dr;
}


/*
    argv[0] - MID
    argv[1] - Number of KIDs to add.
*/

DRM_RESULT TestDRM_Manager_AddManyMeteringData(long argc, char **argv)
{
    DRM_RESULT dr = DRM_SUCCESS;
    DRM_METERING_CONTEXT meterStore = {0};
    DRM_BYTE rgbPasswordSST [__CB_DECL(SHA_DIGEST_LEN)] = { 0 };
    DRM_CONST_STRING dstrMID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrAction = EMPTY_DRM_STRING;
    DRM_MANAGER_CONTEXT_INTERNAL *pcontext = (DRM_MANAGER_CONTEXT_INTERNAL *) m_pContextManager;
    DRM_BB_CONTEXT *pcontextBlackBox = &pcontext->oBlackBoxContext;
    DRM_HDS_CONTEXT *pHdsContext = &pcontext->oHdsContext;
    long index = 0;
    long kidCount = 0;
    DRM_MID mid = {0};
    DRM_KID kid = {0};
    DRM_DWORD cbMID = SIZEOF (mid);
    TOKEN token = {0};
    DRM_BOOL bStoreOpen = FALSE;
    DRM_WCHAR kidbuf[CCH_BASE64_EQUIV(sizeof(DRM_MID))+1] = {0};
    DRM_WCHAR buff[SIZEOF (DRM_KID)];
    DRM_DWORD cch = 0;
    
	MakeDRMString(&dstrMID, argv[0]);
    ChkDR(DRM_BBX_HashValue((DRM_BYTE*)dstrMID.pwszString,dstrMID.cchString*2,rgbPasswordSST,pcontextBlackBox));

    cbMID = SIZEOF(mid);
    ChkDR(DRM_B64_DecodeW(&dstrMID, &cbMID, (DRM_BYTE  *)&mid, 0));        

    kidCount = OEM_atoi(argv[1]);
    for (index = 0; index < kidCount; index++)
    {
        int subIndex = 0;
        DX_VOS_MemSet(buff, 0, SIZEOF(buff));
        for (subIndex = 0; subIndex < 12; subIndex++)
        {
           buff[subIndex] = (DRM_WCHAR)OEM_rand();
        }

        cch = CCH_BASE64_EQUIV(SIZEOF (DRM_KID));
        DRM_B64_EncodeW((DRM_BYTE*)buff, SIZEOF (DRM_KID), kidbuf, &cch, 0);
        dstrKID.pwszString = kidbuf;
        dstrKID.cchString = DRM_wcslen(kidbuf);;

        ChkDR(DRM_B64_DecodeW(&dstrKID, &cch, (DRM_BYTE  *)&kid, 0));        
        MakeDRMString(&dstrAction, "Play");

        ChkDR(DRM_MTR_OpenId(&meterStore, &mid, &kid, rgbPasswordSST, pHdsContext));
        bStoreOpen = TRUE;

        // zero out any data
        ChkDR(DRM_SST_GetTokenValue(&meterStore, &dstrAction, &token));
        token.val.lValue = 1;
        token.TokenType  = TOKEN_LONG;
        ChkDR(DRM_SST_SetTokenValue(&meterStore, &dstrAction , &token));

        DRM_MTR_CloseContext(&meterStore, pHdsContext);
        bStoreOpen = FALSE;
    }            
ErrorExit:    

    if (bStoreOpen)
        DRM_MTR_CloseContext(&meterStore, pHdsContext);

    return dr;
}

/*
    argv[0] - MID
    argv[1] - KID
    argv[2] - Action
    argv[3] - Value
*/
DRM_RESULT TestDRM_Manager_AddMeteringData(long argc, char **argv)
{
    DRM_RESULT dr = DRM_SUCCESS;
    DRM_METERING_CONTEXT meterStore = {0};
    DRM_BYTE rgbPasswordSST [__CB_DECL(SHA_DIGEST_LEN)] = { 0 };
    DRM_CONST_STRING dstrMID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrAction = EMPTY_DRM_STRING;
    DRM_MANAGER_CONTEXT_INTERNAL *pcontext = (DRM_MANAGER_CONTEXT_INTERNAL *) m_pContextManager;
    DRM_BB_CONTEXT *pcontextBlackBox = &pcontext->oBlackBoxContext;
    DRM_HDS_CONTEXT *pHdsContext = &pcontext->oHdsContext;
    long index = 0;
    long count = 0;
    DRM_MID mid = {0};
    DRM_KID kid = {0};
    DRM_DWORD cbMID = SIZEOF (mid);
    DRM_DWORD cbKID = SIZEOF (kid);
    TOKEN token = {0};
    DRM_BOOL bStoreOpen = FALSE;

	MakeDRMString(&dstrMID, argv[0]);

    ChkDR(DRM_BBX_HashValue((DRM_BYTE*)dstrMID.pwszString,dstrMID.cchString*2,rgbPasswordSST,pcontextBlackBox));

    cbMID = SIZEOF(mid);
    cbKID = SIZEOF(kid);
    ChkDR(DRM_B64_DecodeW(&dstrMID, &cbMID, (DRM_BYTE  *)&mid, 0));        

    MakeDRMString(&dstrKID, argv[1]);
    ChkDR(DRM_B64_DecodeW(&dstrKID, &cbKID, (DRM_BYTE  *)&kid, 0));        

    MakeDRMString(&dstrAction, argv[2]);

    ChkDR(DRM_MTR_OpenId(&meterStore, &mid, &kid, rgbPasswordSST, pHdsContext));
    bStoreOpen = TRUE;
    count = OEM_atoi(argv[3]);

    // zero out any data
    ChkDR(DRM_SST_GetTokenValue(&meterStore, &dstrAction, &token));
    token.val.lValue = 0;
    token.TokenType  = TOKEN_LONG;
    ChkDR(DRM_SST_SetTokenValue(&meterStore, &dstrAction , &token));

    // call DRM_MTR_IncrementCount instead of directly setting value above to test DRM_MTR_IncrementCount.
    for (index = 0; index < count; index++)
    {
        ChkDR(DRM_MTR_OpenId(&meterStore, &mid, &kid, rgbPasswordSST, pHdsContext));
        bStoreOpen = TRUE;
        ChkDR(DRM_MTR_IncrementCount(&meterStore, &dstrAction));
        DRM_MTR_CloseContext(&meterStore, pHdsContext);
        bStoreOpen = FALSE;
    }
ErrorExit:    

    if (bStoreOpen)
        DRM_MTR_CloseContext(&meterStore, pHdsContext);

    return dr;
}


DRM_RESULT _GetMeteringDataAsXML(_XMBContext *pbData, DRM_DWORD cbData, PRIVKEY *pPrivKey, DRM_CONST_STRING *pretXML)
{
    DRM_RESULT dr = DRM_SUCCESS;
    DRM_CRYPTO_CONTEXT *pcontextCrypto   = NULL;
    DRM_CONST_STRING dstrXML = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrListTop = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrListData = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrRecords = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrMID = EMPTY_DRM_STRING;
/*    DRM_DWORD cbBuffer = 0;*/

    ChkMem (pcontextCrypto = OEM_malloc (sizeof (DRM_CRYPTO_CONTEXT)));
    DSTR_FROM_PB(&dstrXML, pbData, cbData);

    ChkDR(DRM_XML_GetNode(&dstrXML, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrListData));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagMID, NULL, NULL, 0, NULL, &dstrMID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagRecords, NULL, NULL, 0, NULL, &dstrRecords));

    ChkDR (DRM_XML_GetAndDecryptNode (&dstrListData,
                                     &g_dstrTagRecords,
                                      NULL,
                                      NULL,
                                      0,
                                      pcontextCrypto,
                                      pPrivKey,
                                      NULL,
                                      &dstrRecords));

    pretXML->pwszString = dstrXML.pwszString;
    pretXML->cchString = dstrXML.cchString;

ErrorExit:
    if (pcontextCrypto != NULL)
    {
        OEM_free (pcontextCrypto);
    }
    return dr;
}

/*
    argv[0] - Metering Certificate file
    argv[1] - file private key
    argv[2] - response file
    argv[3] - Max Number of bytes in challenge
    ...
*/
DRM_RESULT TestDRM_Manager_GeneratePartialMeterChallenge(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;

 	DRM_CONST_STRING dstrMeterCertInFile = EMPTY_DRM_STRING;

    _XMBContext         *pbMeteringData = NULL;
    DRM_DWORD            cbMeteringData = 0;
    DRM_CONST_STRING     dstrMeterCert  = EMPTY_DRM_STRING;
/*	DRM_CONST_STRING     dstrMeterResp   = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING     dstrMeteringXML = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrPrivKey = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING     dstrPubkey = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING     dstrExpMID = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING     dstrExpKID = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING     dstrExpAction = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING     dstrExpValue = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING     dstrFileOut = EMPTY_DRM_STRING;

/*	DRM_DWORD            flagsResponse = 0;*/
    DRM_DWORD            cbReqd = 0;
/*    long index = 0;*/
/*    long subindex = 0;*/
    DRM_DWORD   maxLen = 0;
/*    DRM_BOOL bFound = FALSE;*/
    DRM_CONST_STRING dstrListTop = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrListData = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrRecords = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrMID = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING dstrKID = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING dstrTID = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING dstrKidData = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING dstrTmpCert = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING dstrAction = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING dstrActionData = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING dstrValue = EMPTY_DRM_STRING;*/
/*    DRM_CONST_STRING dstrNodeRoot = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING dstrFallbackCert = EMPTY_DRM_STRING;

	DRM_WCHAR  pwchMeterCert[2000] = {0};

#ifdef WINCE_TEST   
	char szFilename[256]={0};
	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[0]);
 	MakeDRMString(&dstrMeterCertInFile, szFilename);
#else
	/* DX: full data path added */
    MakeDRMString(&dstrMeterCertInFile, argv[0]);
#endif
	MakeDRMString(&dstrPrivKey, argv[1]);

    maxLen = OEM_atol(argv[3]);

    ChkDR(DRM_B64_DecodeW(&dstrPrivKey, 
                         &cbReqd, 
                          NULL, 
                          DRM_BASE64_DECODE_IN_PLACE));

    ChkDR  (_GetMeterCertFromFile(dstrMeterCertInFile.pwszString, pwchMeterCert));

	dstrMeterCert.cchString  = DRM_wcslen (pwchMeterCert);
    dstrMeterCert.pwszString = pwchMeterCert;

    dr = DRM_MGR_GenerateMeterChallenge (m_pContextManager, &dstrMeterCert, NULL, NULL, NULL, &cbMeteringData);

    ChkFAIL (dr == DRM_E_BUFFERTOOSMALL 
          || DRM_SUCCEEDED (dr))

    dr = DRM_SUCCESS;

    cbMeteringData = min(cbMeteringData, maxLen);

    ChkMem (pbMeteringData = (_XMBContext*)OEM_malloc (cbMeteringData));
    DX_VOS_Printf("%s %s\n", argv[0], argv[2] ? argv[2] : "No response");
    ChkDR(DRM_MGR_GenerateMeterChallenge (m_pContextManager, &dstrMeterCert, NULL, NULL, pbMeteringData, &cbMeteringData));

    cbMeteringData *= SIZEOF(DRM_WCHAR);

    ChkDR(_GetMeteringDataAsXML(pbMeteringData, cbMeteringData, (PRIVKEY *)dstrPrivKey.pwszString, &dstrMeteringXML));
//printf("%S\n", dstrMeteringXML.pwszString);
    ChkDR(DRM_XML_GetNode(&dstrMeteringXML, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrListData));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagMID, NULL, NULL, 0, NULL, &dstrMID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagTID, NULL, NULL, 0, NULL, &dstrTID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagRecords, NULL, NULL, 0, NULL, &dstrRecords));
    ChkDR(DRM_XML_GetNode(&dstrListTop,  &g_dstrTagCertificate, NULL, NULL, 0, NULL, &dstrFallbackCert));

    {
        PKCERT fallbackCert;
        DRM_DWORD cbB64Decode = 0;
        cbB64Decode = SIZEOF(PKCERT);
        ChkDR(DRM_B64_DecodeW(&dstrFallbackCert, &cbB64Decode, (DRM_BYTE *)&fallbackCert, 0));

        if (argv[2])
        {
#ifdef WINCE_TEST   
		    DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[2]);
 		    MakeDRMString(&dstrFileOut, szFilename);
#else
            /* DX: full path added */
            MakeDRMString(&dstrFileOut, argv[2]);
#endif
            WriteMeterResponse(&dstrFileOut, &dstrMID, &dstrTID, &dstrRecords, (PUBKEY *)&fallbackCert.pk.pk, (PRIVKEY*)dstrPrivKey.pwszString);
        }
        else if (dstrRecords.cchString)
        {
            ChkDR(DRM_E_FAIL);
        }
    }
ErrorExit:

    if (pbMeteringData != NULL)
    {
        OEM_free (pbMeteringData);
    }

    return dr;
}

/*
    argv[0] - Metering Certificate file
    argv[1] - file private key
    argv[2] - response file [optional]
    argv[3] - expected Mid [optional]
    argv[4] - expected KID [optional]
    argv[5] - expected Action [optional]
    argv[6] - expected value [optional]
    argv[7] - expected KID [optional]
    argv[8] - expected Action [optional]
    argv[9] - expected value [optional]
    ...
*/
DRM_RESULT TestDRM_Manager_GenerateMeterChallenge(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;

 	DRM_CONST_STRING dstrMeterCertInFile = EMPTY_DRM_STRING;

    _XMBContext         *pbMeteringData = NULL;
    DRM_DWORD            cbMeteringData = 0;
    DRM_CONST_STRING     dstrMeterCert  = EMPTY_DRM_STRING;
/*	DRM_CONST_STRING     dstrMeterResp   = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING     dstrMeteringXML = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrPrivKey = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING     dstrPubkey = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING     dstrExpMID = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrExpKID = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrExpAction = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrExpValue = EMPTY_DRM_STRING;
    DRM_CONST_STRING     dstrFileOut = EMPTY_DRM_STRING;

/*	DRM_DWORD            flagsResponse = 0;*/
    DRM_DWORD            cbReqd = 0;
    long index = 0;
    long subindex = 0;
    DRM_BOOL bFound = FALSE;
    DRM_CONST_STRING dstrListTop = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrListData = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrRecords = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrMID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrTID = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrKidData = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING dstrTmpCert = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING dstrAction = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrActionData = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrValue = EMPTY_DRM_STRING;
/*    DRM_CONST_STRING dstrNodeRoot = EMPTY_DRM_STRING;*/
    DRM_CONST_STRING dstrFallbackCert = EMPTY_DRM_STRING;

	DRM_WCHAR  pwchMeterCert[2000] = {0};

#ifdef WINCE_TEST   
	char szFilename[256]={0};
	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[0]);
 	MakeDRMString(&dstrMeterCertInFile, szFilename);
#else
    MakeDRMString(&dstrMeterCertInFile, argv[0]);
#endif
	MakeDRMString(&dstrPrivKey, argv[1]);

    ChkDR(DRM_B64_DecodeW(&dstrPrivKey, 
                         &cbReqd, 
                          NULL, 
                          DRM_BASE64_DECODE_IN_PLACE));

    ChkDR  (_GetMeterCertFromFile(dstrMeterCertInFile.pwszString, pwchMeterCert));

	dstrMeterCert.cchString  = DRM_wcslen (pwchMeterCert);
    dstrMeterCert.pwszString = pwchMeterCert;


    dr = DRM_MGR_GenerateMeterChallenge (m_pContextManager, &dstrMeterCert, NULL, NULL, NULL, &cbMeteringData);

    if (dr != DRM_E_BUFFERTOOSMALL 
          && dr != DRM_SUCCESS)
    {
        ChkDR(dr);
    }


    dr = DRM_SUCCESS;

    ChkMem (pbMeteringData = (_XMBContext*)OEM_malloc (cbMeteringData));
    
    ChkDR(DRM_MGR_GenerateMeterChallenge (m_pContextManager, &dstrMeterCert, NULL, NULL, pbMeteringData, &cbMeteringData));
    cbMeteringData *= SIZEOF(DRM_WCHAR);

    ChkDR(_GetMeteringDataAsXML(pbMeteringData, cbMeteringData, (PRIVKEY *)dstrPrivKey.pwszString, &dstrMeteringXML));

    ChkDR(DRM_XML_GetNode(&dstrMeteringXML, &g_dstrTagMetering, NULL, NULL, 0, NULL, &dstrListTop));
    ChkDR(DRM_XML_GetNode(&dstrListTop, &g_dstrTagData, NULL, NULL, 0, NULL, &dstrListData));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagMID, NULL, NULL, 0, NULL, &dstrMID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagTID, NULL, NULL, 0, NULL, &dstrTID));
    ChkDR(DRM_XML_GetNode(&dstrListData, &g_dstrTagRecords, NULL, NULL, 0, NULL, &dstrRecords));

    if (argc < 3)
    {   // expect no data
        if (dstrRecords.cchString == 0)
            goto ErrorExit; // success
        else
            ChkDR(DRM_E_FAIL);
    }
    else if (dstrRecords.cchString == 0)
    {   // expected data
        ChkDR(DRM_E_FAIL);
    }
    

    ChkDR(DRM_XML_GetNode(&dstrRecords, &g_dstrTagKID, NULL, NULL, subindex, &dstrKidData, &dstrKID));
    ChkDR(DRM_XML_GetNode(&dstrListTop,  &g_dstrTagCertificate, NULL, NULL, 0, NULL, &dstrFallbackCert));

    if (argc >= 7)
    {
        MakeDRMString(&dstrExpMID, argv[3]);

        /*Verify MIDs*/
        if (! DRM_UTL_DSTRStringsEqual(&dstrExpMID,&dstrMID))
        {
            ChkDR(DRM_E_METERING_MID_MISMATCH);
        }
        
        for (index = 4; index < argc; index += 3)
        {
            MakeDRMString(&dstrExpKID, argv[index]);
            subindex = 0;
            bFound = FALSE;
            for(subindex = 0;;subindex++)
            {
                ChkDR(DRM_XML_GetNode(&dstrRecords, &g_dstrTagKID, NULL, NULL, subindex, &dstrKidData, &dstrKID));
                ChkDR(DRM_XML_GetNodeAttribute(&dstrKidData, &g_dstrLabelValue, &dstrValue));
                if (! DRM_UTL_DSTRStringsEqual(&dstrExpKID,&dstrValue))
                {
                    continue;
                }
                else
                {
                    bFound = TRUE;
                    break;
                }
            }
            if (!bFound)    // KID not found
                ChkDR(DRM_E_FAIL);
            bFound = FALSE;
            subindex = 0;
            MakeDRMString(&dstrExpAction, argv[index+1]);
            for (subindex = 0;;subindex++)
            {
                ChkDR(DRM_XML_GetNode(&dstrKID, &g_dstrTagAction, NULL, NULL, subindex, &dstrActionData, &dstrAction));
                ChkDR(DRM_XML_GetNodeAttribute(&dstrActionData, &g_dstrLabelValue, &dstrValue));
                if (! DRM_UTL_DSTRStringsEqual(&dstrExpAction,&dstrValue))
                {
                    continue;
                }
                else
                {
                    bFound = TRUE;
                    break;
                }
            }
            if (!bFound)    // Action not found
                ChkDR(DRM_E_FAIL);

            MakeDRMString(&dstrExpValue, argv[index+2]);
            if (!DRM_UTL_DSTRStringsEqual(&dstrExpValue,&dstrAction))
                ChkDR(DRM_E_FAIL);
        }
    }
    if (argc > 2 && *argv[2])
    {
        PKCERT fallbackCert;
        DRM_DWORD cbB64Decode = 0;
        cbB64Decode = SIZEOF(PKCERT);
        ChkDR(DRM_B64_DecodeW(&dstrFallbackCert, &cbB64Decode, (DRM_BYTE *)&fallbackCert, 0));

#ifdef WINCE_TEST   
		DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[2]);
 		MakeDRMString(&dstrFileOut, szFilename);
#else
        MakeDRMString(&dstrFileOut, argv[2]);
#endif
        WriteMeterResponse(&dstrFileOut, &dstrMID, &dstrTID, &dstrRecords, (PUBKEY *)&fallbackCert.pk.pk, (PRIVKEY*)dstrPrivKey.pwszString);
    }
ErrorExit:

    if (pbMeteringData != NULL)
    {
        OEM_free (pbMeteringData);
    }

    return dr;
}


/*
    argv[0] - Metering Certificate file
    argv[1] - file private key
    argv[2] - response file
*/
DRM_RESULT TestDRM_Manager_ProcessMeterResponse(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
 	DRM_DWORD            flagsResponse = 0;
	DRM_CONST_STRING dstrMeterReponseInFile = EMPTY_DRM_STRING;
 	DRM_CONST_STRING dstrMeterCertInFile = EMPTY_DRM_STRING;
 	DRM_CONST_STRING dstrSignedReponse = EMPTY_DRM_STRING;
    DRM_CONST_STRING dstrMeterCert = EMPTY_DRM_STRING;
    DRM_WCHAR  pwchMeterCert[2000] = {0};
    DRM_CONST_STRING     dstrPrivKey = EMPTY_DRM_STRING;
    DRM_DWORD            cbReqd = 0;
/*    DRM_DWORD start = 0, end = 0;*/

	DRM_CONST_STRING     dstrMeterResp   = EMPTY_DRM_STRING;

	DRM_WCHAR  *pwchMeterResponse = 0;

#ifdef WINCE_TEST   
	char szFilename[256]={0};
	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[0]);
 	MakeDRMString(&dstrMeterCertInFile, szFilename);
#else
	MakeDRMString(&dstrMeterCertInFile, argv[0]);
#endif
    ChkDR  (_GetMeterCertFromFile(dstrMeterCertInFile.pwszString, pwchMeterCert));

	dstrMeterCert.cchString  = DRM_wcslen (pwchMeterCert);
    dstrMeterCert.pwszString = pwchMeterCert;

    MakeDRMString(&dstrPrivKey, argv[1]);

    ChkDR(DRM_B64_DecodeW(&dstrPrivKey, 
                         &cbReqd, 
                          NULL, 
                          DRM_BASE64_DECODE_IN_PLACE));

#ifdef WINCE_TEST   
 	DX_VOS_SPrintf(szFilename,256,"%s\\%s",BASE_DIR, argv[2]);
 	MakeDRMString(&dstrMeterReponseInFile, szFilename);
#else
    MakeDRMString(&dstrMeterReponseInFile, argv[2]);
#endif
	ChkDR  (_GetMeterResponseFromFile(dstrMeterReponseInFile.pwszString, &pwchMeterResponse));
    ChkArg(pwchMeterResponse);

	dstrMeterResp.cchString  = DRM_wcslen (pwchMeterResponse);
    dstrMeterResp.pwszString = pwchMeterResponse;

    ChkDR(_SignResponse(&dstrMeterResp, &dstrMeterCert, &dstrSignedReponse, (PRIVKEY*)dstrPrivKey.pwszString));

/*	start = GetTickCount();*/
	ChkDR  (DRM_MGR_ProcessMeterResponse (m_pContextManager,
                             (DRM_BYTE *) PB_DSTR (&dstrSignedReponse),
                                          CB_DSTR (&dstrSignedReponse),
                                          &flagsResponse));
/*	end = GetTickCount();*/
/*	printf("DRM_MGR_ProcessMeterResponse took %d\n", end - start);*/
 
 ErrorExit: 
    if (pwchMeterResponse)
        OEM_free(pwchMeterResponse);

    return dr;
}

DRM_RESULT TestDRM_Manager_Initialize(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;	

    return dr;
}

DRM_RESULT MT_PreTestCase(long lTCID, char *strTCName)
{
	const DRM_WCHAR devCertTemplate[] = { TWO_BYTES('d','e'), TWO_BYTES('v','c'),
									 	  TWO_BYTES('e','r'), TWO_BYTES('t','t'),
										  TWO_BYTES('e','m'), TWO_BYTES('p','l'),
										  TWO_BYTES('a','t'), TWO_BYTES('e','.'),
										  TWO_BYTES('d','a'), TWO_BYTES('t','\0') };
	const DRM_WCHAR priv[] = { TWO_BYTES('p','r'), TWO_BYTES('i','v'), TWO_BYTES('.','d'),
							   TWO_BYTES('a','t'), TWO_BYTES('\0',0) };

	DRM_RESULT dr = DRM_SUCCESS;	
    DRM_CONST_STRING dstrStoreName = EMPTY_DRM_STRING;
/*    DRM_HDS_CONTEXT *pHDS = NULL;*/

	RemoveDRMFile(RMFILE_STORE);
    /*DX: added full path*/
	ChkDR(SetDeviceEnv(devCertTemplate, priv, TRUE));

	tGetDeviceStorePathname(&dstrStoreName);


	ChkMem (m_pContextManager = (DRM_MANAGER_CONTEXT*)OEM_malloc (sizeof (DRM_MANAGER_CONTEXT)))
    ChkDR (DRM_MGR_Initialize (m_pContextManager, &dstrStoreName));

ErrorExit:

	return dr;
}

DRM_RESULT MT_PostTestCase(long lTCID, char *strTCName)
{
	RemoveDRMFile(RMFILE_STORE);

	if (m_pContextManager != NULL)
    {
        DRM_MGR_Uninitialize(m_pContextManager);
        OEM_free (m_pContextManager);
        m_pContextManager = NULL;
    }

	return DRM_SUCCESS;
}

/*
IMPLEMENT_DEFAULT_WARPTEST

BEGIN_APIMAP(RefMeteringTest_ansi, "Metering")	
	API_ENTRY(TestDRM_Manager_GenerateMeterChallenge)
	API_ENTRY(TestDRM_Manager_ProcessMeterResponse)
    API_ENTRY(TestDRM_Manager_Initialize)
    API_ENTRY(TestDRM_Manager_AddMeteringData)
    API_ENTRY(TestDRM_Manager_AddManyMeteringData)
    API_ENTRY(TestDRM_Manager_GeneratePartialMeterChallenge)
	API_ENTRY(TestDRM_VerifyTID)
END_APIMAP
*/

