/**@@@+++@@@@******************************************************************
**
** Microsoft Windows Media
** Copyright (C) Microsoft Corporation. All rights reserved.
**
***@@@---@@@@******************************************************************
*/

/*Most of function has additional argument using as flags to
  decide which input should be overwritten:
	1st bit overwrite LicContext
 	2nd bit overwrite LicEnumContext
	3rd bit overwrite g_pbLicense 
	4th bit overwrite g_pbLicense size
	5th bit overwrite pbKID
 	6th bit overwrite pbLID
*/

// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <ctype.h>
#include <time.h>
#include "tclib.h"
#include "tstutils.h"
#include "drmutilities.h"
#include "drmxmlparser.h"
#include "drmpkcrypto.h"
#include "drmcontextsizes.h"
#include "drmlicstore.h"
#include "tOEMIMP.h"
#include "DX_VOS_Utils.h"



char              _wcszLidTag_char[] = "LID";
char			  _wcszLidTag_buff[6];
static DRM_STRING _wcszLidTag = {(DRM_WCHAR *)_wcszLidTag_buff, sizeof(_wcszLidTag_char)-1};

char              _wcszKidTag_char[] = "KID";
char              _wcszKidTag_buff[6];
static DRM_STRING _wcszKidTag = {(DRM_WCHAR *)_wcszKidTag_buff, sizeof(_wcszKidTag_char)-1};

char              _wcszLicenseTag_char[] = "LICENSE";
char              _wcszLicenseTag_buff[14];
static DRM_STRING _wcszLicenseTag = {(DRM_WCHAR *)_wcszLicenseTag_buff, sizeof(_wcszLicenseTag_char)-1};

char              _wcszDataTag_char[] = "DATA";
char              _wcszDataTag_buff[8];
static DRM_STRING _wcszDataTag = {(DRM_WCHAR *)_wcszDataTag_buff, sizeof(_wcszDataTag_char)-1};

char              _wcszLicensorInfoTag_char[] = "LICENSORINFO";
char              _wcszLicensorInfoTag_buff[24];
static DRM_STRING _wcszLicensorInfoTag = {(DRM_WCHAR *)_wcszLicensorInfoTag_buff, sizeof(_wcszLicensorInfoTag_char)-1};
 
/*global variables*/
static clock_t g_clockStart,g_clockEnd;
static DRM_HDS_CONTEXT *g_pHdsContext = NULL;
static DRM_LICSTORE_CONTEXT g_oContext;
static DRM_LICSTOREENUM_CONTEXT g_oLicEnumContext;
static DRM_BYTE *g_pbLicense=NULL;
static DRM_KID g_KID;
static DRM_LID g_LID;


/**********************************************************/
  
DRM_RESULT TestLicStoreOpenStore(long argc, char **argv);
DRM_RESULT TestLicStoreCloseStore(long argc, char **argv);
DRM_RESULT TestLicStoreAddLicense(long argc, char **argv);
DRM_RESULT TestLicStoreGetLicense(long argc, char **argv);
DRM_RESULT TestLicStoreEnumDelete(long argc, char **argv);
DRM_RESULT TestLicStoreInitEnum(long argc, char **argv);
DRM_RESULT TestLicStoreEnumNext(long argc, char **argv);
DRM_RESULT TestLicStoreReinitialize(long iIndex, char **argv); 
DRM_RESULT TestLicStoreLog(long iIndex, char **argv); 
 
/*performance test*/
DRM_RESULT TestLicStoreAddMultiLicenses(long argc, char **argv);

DRM_BOOL UpdateLicenseKeys(	DRM_BYTE **buffer, long iOption, long iNumLicense)
{
 	DRM_WCHAR* temp=(DRM_WCHAR*)*buffer;
  	DRM_WCHAR szUnique[7];
  	DRM_CHAR cSzUnique[7];
	int i=0;
 	/*compose unique number*/
	DX_VOS_MemSet(szUnique, 0, sizeof(szUnique));
	DX_VOS_MemSet(cSzUnique, 0, sizeof(cSzUnique));
	/*dirty workaround to print iNumLicense to the end of the string (6 digits)*/
	/*1.print the number to mbs*/
	DX_VOS_SPrintf(cSzUnique, SIZEOF( cSzUnique ), "%i", iNumLicense);
	/*2.get the length of the sting*/
	i = DX_VOS_StrLen(cSzUnique)+ 1;
	/*shif the number to th end of the string*/
	DX_VOS_FastMemCpy(&cSzUnique[7-i],&cSzUnique[0],i);
	/*set '0'(not 0x0) the start of the string*/
	DX_VOS_MemSet(cSzUnique,'0',7-i);
	/* convert to wide char */
	OEM_mbstowcs(szUnique,cSzUnique,SIZEOF( szUnique ));
/*	_snwprintf(szUnique, SIZEOF( szUnique), L"%.6i", iNumLicense);*/
 
	/*update g_LID*/
	temp=temp+56;
	for(i=0; i<6; i++, temp++){
		*temp=szUnique[i];
 	}

	/*Update g_KID within license*/
	if(iOption&16){
		temp=temp+44;
		for(i=0; i<6; i++){
			*temp=szUnique[i];
		}
 	}
    return TRUE;
}

/*  Reinitialize all if iIndex=0*/
DRM_RESULT TestLicStoreReinitialize(long iIndex, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;

	if (argv!=NULL){
		iIndex=(int)OEM_atoi(argv[0]);
	}

 	if(iIndex==0 ||iIndex==1){ 
		DX_VOS_MemSet(&g_oContext, 0, sizeof(g_oContext)); 
 	}
 	if(iIndex==0 ||iIndex==2){ 
		DX_VOS_MemSet(&g_oLicEnumContext, 0, sizeof(g_oLicEnumContext)); 
	}
 	if(iIndex==0||iIndex==3){
		DX_VOS_MemFree(g_pbLicense);
		g_pbLicense=NULL;
	}
  	if(iIndex==0 ||iIndex==4){ 
		DX_VOS_MemSet(&g_KID, 0, sizeof(DRM_KID)); 
	}
 	if(iIndex==0 ||iIndex==5){ 
		DX_VOS_MemSet(&g_LID, 0, sizeof(DRM_LID)); 
	}
	if(iIndex==20)
		RemoveDRMFile(RMFILE_STORE);
 	return dr;
}

/*	Test API DRM_LST_Open
	argv[0]: status of DRM_LICSTORE_CONTEXT: NULL or Normal
	argv[1]: status of DRM_HDS_CONTEXT: NULL or Normal
	argv[2]: optional flag to delete the store file before the API: 1 to delete
*/
DRM_RESULT TestLicStoreOpenStore(long argc, char **argv)
{
	DRM_RESULT dr;

	ChkArg(argc >= 2);
 
	/*remove the file*/
	if (argc > 2 && argv[2] && OEM_atoi(argv[2]) == 1) {
		TestLicStoreReinitialize(20, NULL);
	}

	ChkDR(DRM_LST_Open(
		argv[0]? &g_oContext: NULL,
		argv[1]? g_pHdsContext: NULL));
 
ErrorExit:
  	return dr;
}

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

	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreCloseStore: argv[%d]=%s", i, argv[i]);
	}

	/*the 2nd argument to indicate whether it needs to remove the file*/
	if(argc<3){
		Log("Trace", "\t\tFrom TestLicStoreCloseStore: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}
	if(!IsDigitalOnlyString(argv[1])||!IsDigitalOnlyString(argv[2])){
		Log("Trace", "\t\tFrom TestLicStoreCloseStore: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}

	ChkDR(DRM_LST_Close(argv[0]? &g_oContext: NULL));
ErrorExit:
 	/*remove the file*/
	if(OEM_atoi(argv[1])==1){
		TestLicStoreReinitialize(20, NULL);
	}
   	return dr;
}

DRM_RESULT TestLicStoreAddLicense(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
 	DRM_DWORD cbLicense=0;
	long iOption=0,i;
	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreAddLicense: argv[%d]=%s", i, argv[i]);
	}

	/*at least four arguments. The last one is used to decide whether to overwrite*/
 	if(argc<4){
		Log("Trace", "\t\tFrom TestLicStoreAddLicense: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}

	if(!IsDigitalOnlyString(argv[1])||!IsDigitalOnlyString(argv[3])){
		Log("Trace", "\t\tFrom TestLicStoreAddLicense: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}
  
 	iOption=(long)OEM_atol(argv[3]);

	/*the 3rd bit for overwriting g_pbLicense*/
	if(iOption&4){
		TestLicStoreReinitialize(3, NULL);
		if(argv[2]!=NULL){ /*empty string*/
			if(!(*argv[2])){
				ChkMem(g_pbLicense=(DRM_BYTE*)DX_VOS_MemMalloc(1));
				g_pbLicense[0] = 0;
			}
 			/*load license from a file. The file name is given by argv[2]*/ 
            /*DX: license path changed*/
			else if ( !LoadTestFile("licenses", argv[2], &g_pbLicense, &cbLicense)){
				Log("Trace", "Cannot load file: %s", argv[2]);
				ChkDR(DRM_E_FAIL);
			}	
		}
 	}
	/*the 4th bit for overwriting g_pbLicense size*/
	if(iOption&8)
 	 	cbLicense=(DRM_DWORD)OEM_atol(argv[1]);
 
    // BUGBUG  This will always fail.  Last 3 params need to be fixed.
	#ifdef __unix__
	ChkArg(g_pbLicense    != NULL
        && cbLicense !=0
	&& (cbLicense    < cbLicense+sizeof(DRM_DWORD))); /* Test for wrap around */


	#endif
	ChkDR(DRM_LST_AddLicense(argv[0]? &g_oContext: NULL, cbLicense, g_pbLicense, NULL, NULL, 0));
ErrorExit:
	return dr;
}

/*parse given license to retrieve g_KID and g_LID */
DRM_RESULT  TestLicStoreGetLicenseKeys(long argc, char **argv)
{
    DRM_RESULT dr=DRM_SUCCESS;
    DRM_CONST_STRING wszXmlStr;
    DRM_CONST_STRING wszXmlSubNode;
    DRM_CONST_STRING wszLIDValue, wszKIDValue;
    DRM_CONST_STRING wszXmlNode;
    DRM_UINT cbKID=DRM_ID_SIZE;
	DRM_DWORD cbLicense=0;

 	TestLicStoreReinitialize(4, NULL);
	TestLicStoreReinitialize(5, NULL);
	if(argv[0]!=NULL){
		/*load license from a file. The file name is given by argv[0]*/ 
        /*DX: license path changed*/
		if ( !LoadTestFile("licenses", argv[0], &g_pbLicense, &cbLicense)){
			Log("Trace", "Cannot load file: %s", argv[0]);
			ChkDR(DRM_E_FAIL);
		}	
	}
	else{
		ChkDR(DRM_E_FAIL);
	}

    wszXmlStr.pwszString = (DRM_WCHAR*)g_pbLicense;
    wszXmlStr.cchString = cbLicense/SIZEOF(DRM_WCHAR);;

     /* extract the version string */
	DX_VOS_Utf8ToUtf16(_wcszLicenseTag.pwszString, sizeof(_wcszLicenseTag_char)*sizeof(DRM_WCHAR), _wcszLicenseTag_char);
    ChkDR(DRM_XML_GetNode(&wszXmlStr, (const DRM_CONST_STRING *)&_wcszLicenseTag, NULL, NULL, 0, &wszXmlNode, &wszXmlSubNode));

	/* extract LicensorInfo node */
    wszXmlStr = wszXmlSubNode;
	DX_VOS_Utf8ToUtf16(_wcszLicensorInfoTag.pwszString, sizeof(_wcszLicensorInfoTag_char)*sizeof(DRM_WCHAR), _wcszLicensorInfoTag_char);
    ChkDR(DRM_XML_GetNode(&wszXmlStr, (const DRM_CONST_STRING *)&_wcszLicensorInfoTag, NULL, NULL, 0,NULL, &wszXmlSubNode));
    
    /* extract Data node */
    wszXmlStr = wszXmlSubNode;
	DX_VOS_Utf8ToUtf16(_wcszDataTag.pwszString, sizeof(_wcszDataTag_char)*sizeof(DRM_WCHAR), _wcszDataTag_char);
    ChkDR(DRM_XML_GetNode(&wszXmlStr, (const DRM_CONST_STRING *)&_wcszDataTag, NULL, NULL, 0,NULL, &wszXmlSubNode));

      /* extract g_LID, g_KID and priority node */
    wszXmlStr = wszXmlSubNode;
	DX_VOS_Utf8ToUtf16(_wcszLidTag.pwszString, sizeof(_wcszLidTag_char)*sizeof(DRM_WCHAR), _wcszLidTag_char);
    ChkDR(DRM_XML_GetNode(&wszXmlStr, (const DRM_CONST_STRING *)&_wcszLidTag, NULL, NULL, 0,&wszXmlNode, &wszLIDValue));
	DX_VOS_Utf8ToUtf16(_wcszKidTag.pwszString, sizeof(_wcszKidTag_char)*sizeof(DRM_WCHAR), _wcszKidTag_char);
    ChkDR(DRM_XML_GetNode(&wszXmlStr, (const DRM_CONST_STRING *)&_wcszKidTag, NULL, NULL, 0,&wszXmlNode, &wszKIDValue));
     
    /* convert extracted g_LID to GUID */
    ChkDR(DRM_UTL_StringToGuid(&wszLIDValue, (DRM_GUID*)g_LID.rgb));
   
    /* base64 decode g_KID */
    ChkDR(DRM_B64_DecodeW(&wszKIDValue, (DRM_DWORD *)&cbKID, g_KID.rgb, 0));
   
ErrorExit:
  	return dr;
}

DRM_RESULT TestLicStoreGetLicense(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DRM_DWORD cbLicense=0;
   	long iOption=0;
	int iLIDNullFlag=0,iKIDNullFlag=0;
	long i;
	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreGetLicense: argv[%d]=%s", i, argv[i]);
	}
	/*at least six arguments. The last one is used to decide whether we need to overwrite*/
	if(argc<6){
		Log("Trace", "\t\tFrom TestLicStoreGetLicense: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}
	if(!IsDigitalOnlyString(argv[4])||!IsDigitalOnlyString(argv[5])){
		Log("Trace", "\t\tFrom TestLicStoreGetLicense: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}
  
	iOption=(long)OEM_atol(argv[5]);

 	/*3rd bit for overwriting g_pbLicense*/
	if(iOption&4){
		TestLicStoreReinitialize(3, NULL);
		if(argv[3]!=NULL){
 			ChkMem(g_pbLicense=(DRM_BYTE*)DX_VOS_MemMalloc(DX_VOS_StrLen(argv[3])+1));
			DX_VOS_FastMemCpy(g_pbLicense, argv[3], DX_VOS_StrLen(argv[3])+1);
		}
	}	
	/*4th bit for overwriting g_pbLicense size*/
	if(iOption&8){
 		cbLicense=(DRM_DWORD)OEM_atol(argv[4]);
	}
	/*5th bit for overwriting g_KID*/
	if(iOption&16){
		TestLicStoreReinitialize(4, NULL);
		if(argv[1]!=NULL){
			DX_VOS_FastMemCpy(g_KID.rgb, argv[1], min(DX_VOS_StrLen(argv[1])+1, DRM_ID_SIZE));
		}
		else
			iKIDNullFlag=1;
	}
	/*6th bit for overwriting g_LID*/
	if(iOption&32){
		TestLicStoreReinitialize(5, NULL);
		if(argv[2]!=NULL){
			DX_VOS_FastMemCpy(g_LID.rgb, argv[2], min(DX_VOS_StrLen(argv[2])+1, DRM_ID_SIZE));
		}
		else
			iLIDNullFlag=1;
	}


	dr=DRM_LST_GetLicense(argv[0]? &g_oContext: NULL, 
		iKIDNullFlag>0?NULL:&g_KID, 
		iLIDNullFlag>0?NULL:&g_LID, 
        NULL,
		g_pbLicense, 
		(iOption&1)? NULL: &cbLicense);

	if (dr==DRM_E_BUFFERTOOSMALL){
		DX_VOS_MemFree(g_pbLicense);
		ChkMem(g_pbLicense = DX_VOS_MemMalloc(cbLicense + 1));
	}
	else{
		ChkDR(dr);
	}
	ChkDR(DRM_LST_GetLicense(argv[0]? &g_oContext: NULL ,&g_KID,&g_LID, NULL, g_pbLicense, (iOption&1)? NULL: &cbLicense));

ErrorExit:
  	return dr;
}

DRM_RESULT TestLicStoreInitEnum(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	int iEnumContextNullFlag=0, iKIDNullFlag=0;
	DRM_BOOL fPrioritized=FALSE;
	long iOption=0,i;
	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreInitEnum: argv[%d]=%s", i, argv[i]);
	}
	/*at least 5 arguments. The last one is used to decide whether we need to overwrite the context*/
	if(argc<5){
		Log("Trace", "\t\tFrom TestLicStoreInitEnum: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}

	if(!IsDigitalOnlyString(argv[2])||!IsDigitalOnlyString(argv[4])){
		Log("Trace", "\t\tFrom TestLicStoreInitEnum: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}
  
  	iOption=(long)OEM_atol(argv[4]);

	/*g_KID*/
	if(iOption&16){
		TestLicStoreReinitialize(4, NULL);
		if(argv[1]!=NULL){
			DX_VOS_FastMemCpy(g_KID.rgb, argv[1], min(DX_VOS_StrLen(argv[1])+1, DRM_ID_SIZE));
		}
		else
			iKIDNullFlag=1;
	}
	/*fPrioritized flag*/
	if(1==OEM_atol(argv[2]))
		fPrioritized=TRUE;

	/*enum context*/
	if(argv[3]!=NULL){
		DX_VOS_MemSet(&g_oLicEnumContext, 0, sizeof(g_oLicEnumContext));
		DX_VOS_FastMemCpy(&g_oLicEnumContext, argv[3],DX_VOS_StrLen(argv[3])+1);			 
	}
	else
		iEnumContextNullFlag=1;
 
	ChkDR(DRM_LST_InitEnum(argv[0]? &g_oContext: NULL,iKIDNullFlag>0?NULL:&g_KID, fPrioritized,iEnumContextNullFlag>0?NULL:&g_oLicEnumContext));
ErrorExit:
 	return dr;
}

DRM_RESULT TestLicStoreEnumNext(long argc, char **argv)
{
	long dr=DRM_SUCCESS;
  	long i;
	int iKIDNullFlag=0, iLIDNullFlag=0, iSizeNullFlag=0;
	DRM_KID pVerifyKID;
	DRM_LID pVerifyLID;
 	DRM_DWORD cbLicense=0;
	DRM_CONST_STRING wszLIDValue, wszKIDValue;
	DRM_DWORD cbKID=0;
 	DRM_WCHAR pwszAttr[256]={0};

	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreEnumNext: argv[%d]=%s", i, argv[i]);
	}
	/*at least 7 arguments. The last one is used to decide whether we need to overwrite the context*/
	/*5th and 6th arguments are used to verify the results*/
	if(argc<7){
		Log("Trace", "\t\tFrom TestLicStoreEnumNext: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}
	if(!IsDigitalOnlyString(argv[6])){ 
		Log("Trace", "\t\tFrom TestLicStoreEnumLicense: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}
  
	/*get g_KID and g_LID*/
	if(argv[1]!=NULL){
		DX_VOS_FastMemCpy(g_KID.rgb, argv[1], min(DX_VOS_StrLen(argv[1])+1, DRM_ID_SIZE));
	}
	else
		iKIDNullFlag=1;

	if(argv[2]!=NULL){
		DX_VOS_FastMemCpy(g_LID.rgb, argv[2], min(DX_VOS_StrLen(argv[2])+1, DRM_ID_SIZE));
	}
	else
		iLIDNullFlag=1;
	
 	/*license size*/
	if(argv[3]!=NULL){
		cbLicense=(DRM_DWORD)OEM_atol(argv[3]);
	}
	else
		iSizeNullFlag=1;

	ChkDR(DRM_LST_EnumNext(argv[0]? &g_oLicEnumContext: NULL, iKIDNullFlag>0?NULL:&g_KID,iLIDNullFlag>0?NULL:&g_LID,NULL,iSizeNullFlag>0?NULL:&cbLicense));

	/*verify the results*/
  	if(argv[4]!=NULL && iKIDNullFlag!=1){
	 	OEM_mbstowcs(pwszAttr, argv[4], DX_VOS_StrLen(argv[4]));
		wszKIDValue.pwszString=pwszAttr;
		wszKIDValue.cchString= (DRM_DWORD)DX_VOS_StrLen(argv[4]);

		/* base64 decode g_KID */
		DX_VOS_MemSet(&pVerifyKID, 0, sizeof(DRM_KID));
		cbKID=wszKIDValue.cchString;
		ChkDR(DRM_B64_DecodeW(&wszKIDValue, &cbKID, pVerifyKID.rgb, 0));

		if(DX_VOS_StrNCmp((const DxChar*)pVerifyKID.rgb,(const DxChar*)g_KID.rgb,DRM_ID_SIZE)){
			ChkDR(DRM_E_FAIL);
		}
	}
	if(argv[5]!=NULL && iLIDNullFlag!=1){
	 	DX_VOS_MemSet(pwszAttr,0,sizeof(pwszAttr));
		OEM_mbstowcs(pwszAttr, argv[5],  DX_VOS_StrLen(argv[5])+1);
		wszLIDValue.pwszString=pwszAttr;
		wszLIDValue.cchString= (DRM_DWORD)DX_VOS_StrLen(argv[5]);
		DX_VOS_MemSet(&pVerifyLID, 0, sizeof(DRM_LID));
		ChkDR(DRM_UTL_StringToGuid(&wszLIDValue, (DRM_GUID*)pVerifyLID.rgb));

		if(DX_VOS_StrNCmp((const DxChar*)pVerifyLID.rgb,(const DxChar*)g_LID.rgb,DRM_ID_SIZE)){
			ChkDR(DRM_E_FAIL);
		}
	}

ErrorExit:
  	return dr;
}

DRM_RESULT TestLicStoreEnumDelete(long argc, char **argv)
{
	return DRM_LST_EnumDelete(argv[0]? &g_oLicEnumContext: NULL);
}

/*Performance test*/
DRM_RESULT TestLicStoreAddMultiLicenses(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DRM_DWORD cbLicense=0;
  	long iOption=0,iNumLicense=0, iNumKeyBase=0,i=0;  
 	
	for(i=0; i<argc; i++){
		Log("Trace", "\t\tFrom TestLicStoreAddMultiLicenses: argv[%d]=%s", i, argv[i]);
	}
	/*at least four arguments. 
	The first one is the base license file name;
	The second one is total license number;
	The third one is the starting key number;
	The fouth one is used to decide whether we need to overwrite
	*/
	if(argc<4||argv[0]==NULL){
		Log("Trace", "\t\tFrom TestLicStoreAddMultiLicenses: error in number of arguments.");
		ChkDR(DRM_E_FAIL);
	}
	if(!IsDigitalOnlyString(argv[1])||!IsDigitalOnlyString(argv[2])||!IsDigitalOnlyString(argv[3])){
		Log("Trace", "\t\tFrom TestLicStoreAddMultiLicenses: error in the argument.");
		ChkDR(DRM_E_FAIL);
	}
  	 
	iOption=(long)OEM_atol(argv[3]);
	iNumLicense=(long)OEM_atol(argv[1]);
	iNumKeyBase=(long)OEM_atol(argv[2]);

	Log("Trace", "\t\tStart adding %d licenses to the store.", iNumLicense);
 	while(iNumLicense-->0){
		TestLicStoreReinitialize(3, NULL);
		cbLicense=0;
 		/*load license from a file. The file name is given by argv[0]*/ 
        /*DX: license path changed*/
		if ( !LoadTestFile("licenses", argv[0], &g_pbLicense, &cbLicense)){
			Log("Trace", "Cannot load file: %s", argv[0]);
			ChkDR(DRM_E_FAIL);
		}
		UpdateLicenseKeys(&g_pbLicense, iOption, iNumKeyBase);

        // BUGBUG  This will always fail.  Last 3 params need to be fixed.
 		ChkDR(DRM_LST_AddLicense(&g_oContext, cbLicense, g_pbLicense, NULL, NULL, 0));
		iNumKeyBase++;
  	}
	Log("Trace", "\t\tSuccessfully added the licenses to the store.");
   
ErrorExit:
 	return dr;
}

DRM_RESULT TestLicStoreLog(long argc, char **argv)
{
#ifdef WINCE_TEST
	return DRM_SUCCESS;
#else
	DRM_RESULT dr=DRM_SUCCESS;
	int iActionType;
	DxVosFile fp=NULL;
	char szFileName[32]="LicstorePerfLog.txt";

	/*at least four arguments. 
	  1st is the index to indicate 
			0: remove old file; 
			1: start an action; 
			2: end an action;
			3: log a statement;
			4: remove the log file.
	  2nd is the description of the action.
	*/
	if(argc<2||!IsDigitalOnlyString(argv[0])){
 		ChkDR(DRM_E_FAIL);
	}
	iActionType=(int)OEM_atoi(argv[0]);
	if(0==iActionType){
		Log("Trace", "\t\t****** %s ******", argv[1]);
		DX_VOS_FOpen(&fp,szFileName, "w+");
	}
	else if(1==iActionType){
		g_clockStart=clock();
 	}
	else if(2==iActionType){
		g_clockEnd=clock();
		Log("Trace", "%s. It took %ld milliseconds.", argv[1], g_clockEnd-g_clockStart);
		DX_VOS_FOpen(&fp,szFileName, "r+");
		DX_VOS_FSeekEx(fp,0,DX_SEEK_END);
	}
	else if(3==iActionType){
		Log("Trace", "%s.", argv[1]);
		DX_VOS_FOpen(&fp,szFileName, "r+");
		DX_VOS_FSeekEx(fp,0,DX_SEEK_END);
	}
	else if(4==iActionType){
		remove(szFileName);
	}
	else{
		ChkDR(DRM_E_FAIL); 
	}
	if(iActionType!=1&&iActionType!=4){
		if (fp == NULL){ 
 			ChkDR(DRM_E_FAIL);
		}
		DX_VOS_FClose(fp);
	}
ErrorExit:
	return dr;
#endif
}

DRM_RESULT LS_PreTestCase(long lTCID, char *strTCName)
{
	DRM_RESULT dr;
	DRM_CONST_STRING wszHDSPath;

	RemoveDRMFile(RMFILE_STORE);
	//ChkDR(SetDeviceEnv(L"devcerttemplate.dat", L"priv.dat", TRUE));
	tGetDeviceStorePathname(&wszHDSPath);
	ChkDR(OpenHDS(&g_pHdsContext, wszHDSPath.pwszString, FALSE));
ErrorExit:
	return dr;
}

DRM_RESULT LS_PostTestCase(long lTCID, char *strTCName)
{
	DRM_RESULT dr;
	DRM_LST_Close(&g_oContext);
	ChkDR(CloseHDS(g_pHdsContext));
	g_pHdsContext = NULL;
ErrorExit:
	return dr;
}


/*
BEGIN_APIMAP(testlicstore_ansi, "testlicstore")
 	API_ENTRY(TestLicStoreOpenStore)
	API_ENTRY(TestLicStoreCloseStore)
	API_ENTRY(TestLicStoreAddLicense)
 	API_ENTRY(TestLicStoreGetLicense)
	API_ENTRY(TestLicStoreGetLicenseKeys)
  	API_ENTRY(TestLicStoreEnumDelete)
	API_ENTRY(TestLicStoreReinitialize)
	API_ENTRY(TestLicStoreAddMultiLicenses)
	API_ENTRY(TestLicStoreInitEnum)
	API_ENTRY(TestLicStoreEnumNext)
	API_ENTRY(TestLicStoreLog)
END_APIMAP
*/

