/**@@@+++@@@@******************************************************************
**
** Microsoft Windows Media
** Copyright (C) Microsoft Corporation. All rights reserved.
**
***@@@---@@@@******************************************************************
*/
#include "testdevicestore.h"

/*Most of function has additional argument using as flags to
  decide which input should be overwritten:
	1st bit overwrite g_pManagerContext
*/

/*global variables*/
DRM_CONST_STRING g_wszDeviceStoreName = {0};
static DRM_MANAGER_CONTEXT *g_pManagerContext = NULL;

#if DRM_SUPPORT_DEVICESTORE
DRM_DEVICESTORE_CONTEXT *g_pDeviceStoreContext = NULL;
DRM_DEVICESTORE_HANDLE g_hDeviceHandle = NULL;
#endif

/*antirollback clock*/
long g_lOffset=0;

static DRM_WORD g_wCurrentYear;

/*multiple stores*/
char *g_szFilePath=NULL;

/*Perf - timing info */
#ifdef PERF_TEST
DRM_UINT64 g_CurrTime, g_DiffTime;
#endif
#if DRM_SUPPORT_DEVICESTORE

/* TestDeviceStoreRegisterDevice takes a device ID and creates
an entry for it in the HDS.

argv[0]: deviceid to register
argv[1]: optional: context is NULL
argv[2]: optional: device handle is NULL 
 
*/
DRM_RESULT TestDeviceStoreRegisterDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context
	DRM_DWORD iOption2 = 1;

    ChkArg( argc >= 1 );

	if (argv[0])
	{
		DeviceID.pbBlob = argv[0];
		DeviceID.cbBlob = DX_VOS_StrLen( argv[0] );
	}

	if (argc >= 2 && argv[1] != NULL)
		iOption1 = OEM_atol(argv[1]);
	if (argc >= 3 && argv[2] != NULL)
		iOption2 = OEM_atol(argv[2]);
    
	START_TIMER(g_CurrTime);
	dr = DRM_DVS_RegisterDevice( iOption1? g_pDeviceStoreContext : NULL,
								DeviceID, 
								iOption2? &g_hDeviceHandle : NULL );
	STOP_TIMER("DRM_DVS_RegisterDevice",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/*  TestDeviceStoreUnRegisterDevice removes a registered device's
entry from the HDS.

argv[0]: deviceid to unregister
argv[1]: optional: context is NULL
  
*/

DRM_RESULT TestDeviceStoreUnRegisterDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context

    ChkArg( argc >= 1 );

	if ( argv[0] )
	{
		DeviceID.pbBlob = argv[0];
		DeviceID.cbBlob = DX_VOS_StrLen( argv[0] );
	}

	if(argc>=2 && argv[1] != NULL)
		iOption1 = OEM_atol(argv[1]);
    
	START_TIMER(g_CurrTime);
	dr = DRM_DVS_UnRegisterDevice( iOption1? g_pDeviceStoreContext : NULL, DeviceID );
	STOP_TIMER("DRM_DVS_UnRegisterDevice",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/* TestDeviceStoreCommitDevice is used to save changes made to
a device handle for a registered device to the HDS.

argv[0]: optional: Device handle is NULL. 

*/

DRM_RESULT TestDeviceStoreCommitDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

	if (argc >= 1 && 0 == DX_VOS_StrCmp( "NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);

	START_TIMER(g_CurrTime);
	dr = DRM_DVS_CommitDevice( iOption1? g_hDeviceHandle : NULL );
	STOP_TIMER("DRM_DVS_CommitDevice",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/*  TestDeviceStoreFreeDevice clears an existing device handle.
If the device handle's flag fDontCommitOnFree is TRUE, any changes
will be lost when the handle is freed.  Otherwise DRM_DVS_FreeDevice
will call DRM_DVS_CommitDevice during the free operation.

argv[0]: optional: device handle is NULL. 
argv[1]: optional: don't commit any changes during free operation

*/

DRM_RESULT TestDeviceStoreFreeDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	_DeviceHandle *pDeviceHandle = NULL;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

	if (argc >= 1 && 0 == DX_VOS_StrCmp("NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);
	if (argc >= 2)
	{
		ChkArg(argv[1]);
		if (0 != MEMCMP(L"TRUE", argv[1], DX_VOS_StrLen(argv[1])) && g_hDeviceHandle != NULL)
		{
			//Don't commit any changes when freeing this device handle
			pDeviceHandle = (_DeviceHandle *)g_hDeviceHandle;
			pDeviceHandle->fDontCommitOnFree = TRUE;
		}
	}

	START_TIMER(g_CurrTime);
	DRM_DVS_FreeDevice( iOption1? g_hDeviceHandle : NULL );
	STOP_TIMER("DRM_DVS_FreeDevice",g_CurrTime,g_DiffTime);
    g_hDeviceHandle = NULL;

ErrorExit:
  	return dr;
}

/* TestDeviceStoreGetDeviceByID returns a device handle for a
registered device, given a device ID.

argv[0]: deviceid to register
argv[1]: optional: context is NULL
argv[2]: optional: device handle is NULL

*/

DRM_RESULT TestDeviceStoreGetDeviceByID(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context/handle
	DRM_DWORD iOption2 = 1;

    ChkArg( argc >= 1 );

	if (argv[0])
	{
		DeviceID.pbBlob = argv[0];
		DeviceID.cbBlob = DX_VOS_StrLen( argv[0] );
	}

	if (argc >= 2 && argv[1] != NULL)
		iOption1 = OEM_atol(argv[1]);
	if (argc >= 3 && argv[2] != NULL)
		iOption2 = OEM_atol(argv[2]);

	START_TIMER(g_CurrTime);
	dr = DRM_DVS_GetDeviceByID( iOption1? g_pDeviceStoreContext : NULL, 
								DeviceID, 
								iOption2? &g_hDeviceHandle : NULL);
	STOP_TIMER("DRM_DVS_GetDeviceByID",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/* TestDeviceStoreGetFirstDevice returns the first registered device
the the HDS.

argv[0]: optional: context is NULL
argv[1]: optional: device handle is NULL

*/
DRM_RESULT TestDeviceStoreGetFirstDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context/handle
	DRM_DWORD iOption2 = 1;
	
	if (argc >= 1 && 0 == DX_VOS_StrCmp("NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);
	if (argc >= 2 && argv[1] != NULL)
		iOption2 = OEM_atol(argv[1]);

	START_TIMER(g_CurrTime);
	dr = DRM_DVS_GetFirstDevice( iOption1? g_pDeviceStoreContext : NULL,
								iOption2? &g_hDeviceHandle : NULL );
	STOP_TIMER("DRM_DVS_GetFirstDevice",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/* TestDeviceStoreGetNextDevice returns the next registered device
found the in the HDS.  If no more devices are present the API call
fails with DRM_E_NOMORE.

argv[0]: optional: context is NULL
argv[1]: optional: device handle is NULL
*/

DRM_RESULT TestDeviceStoreGetNextDevice(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context/handle
	DRM_DWORD iOption2 = 1;

	if (argc >= 1 && 0 == DX_VOS_StrCmp("NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);
	if (argc >= 2 && argv[1] != NULL)
		iOption2 = OEM_atol(argv[1]);

	START_TIMER(g_CurrTime);
	dr = DRM_DVS_GetNextDevice( iOption1? g_pDeviceStoreContext : NULL,
								iOption2? &g_hDeviceHandle : NULL );
	STOP_TIMER("DRM_DVS_GetNextDevice",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/* TestDeviceStoreGetDeviceID gets the DeviceID from the store
when given a handle to the device.

argv[0]: deviceid to retrieve
argv[1]: optional: device handle is NULL

*/
DRM_RESULT TestDeviceStoreGetDeviceID(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
    DRM_BYTE *pbDeviceID = NULL;
    DRM_DWORD cbDeviceID = 0;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

    ChkArg( argc >= 1 );

	if (argc >= 2 && argv[1] != NULL)
		iOption1 = OEM_atol(argv[1]);

    dr = DRM_DVS_GetDeviceID( g_hDeviceHandle, NULL, &cbDeviceID );

    if( dr == DRM_E_BUFFERTOOSMALL )
    {
        ChkMem( pbDeviceID = OEM_malloc( cbDeviceID ) );
		START_TIMER(g_CurrTime);
		dr = DRM_DVS_GetDeviceID( iOption1? g_hDeviceHandle : NULL,
								  pbDeviceID, &cbDeviceID );
		STOP_TIMER("DRM_DVS_GetDeviceID",g_CurrTime,g_DiffTime);
    }
    ChkDR( dr );

    ChkArg( pbDeviceID != NULL
        && cbDeviceID == DX_VOS_StrLen(argv[0]) );

    ChkArg( MEMCMP( pbDeviceID, argv[0], cbDeviceID ) == 0 );

ErrorExit:
	SAFE_OEM_FREE(pbDeviceID);
  	return dr;
}

/* Set an attribute for the device we currently have a handle to.
Changes must be committed with CommitDevice or FreeDevice with
g_hDeviceHandle->fDontCommitOnFree set to TRUE.

argv[0]: attribute name
argv[1]: attribute value
argv[2]: optional: device handle is NULL
*/

DRM_RESULT TestDeviceStoreSetDeviceAttr(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_BYTEBLOB AttrName = {0};
	DRM_BYTEBLOB AttrValue = {0};
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

    ChkArg( argc >= 2 );

	if (argc >= 3 && argv[2] != NULL)
		iOption1 = OEM_atol(argv[2]);

	if(argv[0])
	{
		AttrName.pbBlob = argv[0];
		AttrName.cbBlob = DX_VOS_StrLen( argv[0] );
	}

	if(argv[1])
	{
		AttrValue.pbBlob = argv[1];
		AttrValue.cbBlob = DX_VOS_StrLen( argv[1] );
	}
    
	START_TIMER(g_CurrTime);
	dr = DRM_DVS_SetDeviceAttr( iOption1? g_hDeviceHandle : NULL, 
								AttrName, AttrValue );
	STOP_TIMER("DRM_DVS_SetDeviceAttr",g_CurrTime,g_DiffTime);
	ChkDR(dr);

ErrorExit:
  	return dr;
}

/* Get a specified attribute from the device we currently have a
handle to.

argv[0]: attribute name
argv[1]: expected attribute value
argv[2]: optional: device handle is NULL 

*/
DRM_RESULT TestDeviceStoreGetDeviceAttr(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DRM_BYTEBLOB AttrName = {0};
    DRM_BYTE *pbAttrValue = NULL;
    DRM_DWORD cbAttrValue = 0;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

    ChkArg( argc >= 2 );

	if(argc >= 3 && argv[2] != NULL)
		iOption1 = OEM_atol(argv[2]);

	if (argv[0])
	{
		AttrName.pbBlob = argv[0];
		AttrName.cbBlob = DX_VOS_StrLen( argv[0] );
	}
    
    dr = DRM_DVS_GetDeviceAttr( g_hDeviceHandle, AttrName, NULL, &cbAttrValue );

    if( dr == DRM_E_BUFFERTOOSMALL )
    {
        ChkMem( pbAttrValue = OEM_malloc( cbAttrValue ) );
		START_TIMER(g_CurrTime);
		dr = DRM_DVS_GetDeviceAttr( iOption1? g_hDeviceHandle : NULL,
									AttrName, pbAttrValue, &cbAttrValue );
		STOP_TIMER("DRM_DVS_GetDeviceAttr",g_CurrTime,g_DiffTime);
    }
    ChkDR( dr );

    ChkArg( pbAttrValue != NULL
        && cbAttrValue == DX_VOS_StrLen(argv[1]) );

    ChkArg( MEMCMP( pbAttrValue, argv[1], cbAttrValue ) == 0 );

ErrorExit:
    SAFE_OEM_FREE( pbAttrValue );
  	return dr;
}

/* get an attribute of the device by it's index and verify that it matches what is given 

argv[0]: attribute index
argv[1]: expected attribute name
argv[2]: expected attribute value
argv[3]: optional: device handle is NULL 

*/

DRM_RESULT TestDeviceStoreGetDeviceAttrByIndex(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
    DRM_BYTE *pbAttrName = NULL;
    DRM_DWORD cbAttrName = 0;
    DRM_BYTE *pbAttrValue = NULL;
    DRM_DWORD cbAttrValue = 0;
	DRM_DWORD iAttrIndex = 0;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle

    ChkArg( argc >= 3 );

	if (argv[0])
		iAttrIndex=OEM_atol(argv[0]);

	if (argc >= 4 && argv[3] != NULL)
		iOption1 = OEM_atol(argv[3]);

	dr = DRM_DVS_GetDeviceAttrByIndex( g_hDeviceHandle, iAttrIndex, NULL, &cbAttrName, NULL, &cbAttrValue );

    if( dr == DRM_E_BUFFERTOOSMALL )
    {
        ChkMem( pbAttrName = OEM_malloc( cbAttrName ) );
        ChkMem( pbAttrValue = OEM_malloc( cbAttrValue ) );
		START_TIMER(g_CurrTime);
		dr = DRM_DVS_GetDeviceAttrByIndex( iOption1? g_hDeviceHandle : NULL, iAttrIndex,
											pbAttrName, &cbAttrName, pbAttrValue, &cbAttrValue );
		STOP_TIMER("DRM_DVS_GetDeviceAttrByIndex",g_CurrTime,g_DiffTime);
    }
    ChkDR( dr );

    ChkArg( pbAttrValue != NULL
        && cbAttrValue == DX_VOS_StrLen(argv[2])
        && pbAttrName != NULL
        && cbAttrName == DX_VOS_StrLen(argv[1]) );

    ChkArg( MEMCMP( pbAttrValue, argv[2], cbAttrValue ) == 0 );
    ChkArg( MEMCMP( pbAttrName, argv[1], cbAttrName ) == 0 );

ErrorExit:
    SAFE_OEM_FREE( pbAttrName );
    SAFE_OEM_FREE( pbAttrValue );
  	return dr;
}


/* count the attributes of the device and verify that it matches 

argv[0]: expected attribute count
argv[1]: optional: device handle is NULL 

*/

DRM_RESULT TestDeviceStoreGetDeviceAttrCount(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
    DRM_DWORD dwCount = 0;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real handle
	DRM_DWORD	i;
    ChkArg( argc >= 1 );

	if ( argc >= 2 && argv[1] != NULL)
		iOption1 = OEM_atol(argv[1]);

    START_TIMER(g_CurrTime);
	dr = DRM_DVS_GetDeviceAttrCount( iOption1? g_hDeviceHandle : NULL, &dwCount );
	STOP_TIMER("DRM_DVS_GetDeviceAttrCount",g_CurrTime,g_DiffTime);

    ChkArg( dwCount == OEM_atol(argv[0]) );

ErrorExit:
  	return dr;
}

/* TestDeviceStoreChangeTime changes the system time on the test machine.

argv[0]: offset in seconds, positive to go forward, negative to rollback

*/

DRM_RESULT TestDeviceStoreChangeTime(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	long lOffset;
 
	ChkArg(argc == 1 && argv[0]);
	lOffset = OEM_atol(argv[0]);
	tChangeSystemTime(lOffset);
	g_lOffset += lOffset;
#ifdef WINCE_TEST
	Sleep(2000);
#endif
ErrorExit:
  	return dr;
}

/* TestDeviceStoreInitialize: allows us to call DRM_DVS_Initialize more than
once or with NULLs for some tests.  DRM_DVS_Initialize is called once during
PreTestCase.

argv[0]: optional -- Device Store context is NULL.
argv[1]: optional -- Manage Context is NULL.
 
*/

DRM_RESULT TestDeviceStoreInitialize(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real contexts
	DRM_DWORD iOption2 = 1;

#if DRM_SUPPORT_DEVICESTORE

	if (argc >= 1 && 0 == DX_VOS_StrCmp("NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);
	if (argc >= 2 && argv[1] != NULL)
		iOption2 = OEM_atol(argv[1]);

	START_TIMER(g_CurrTime);
	dr = DRM_DVS_Initialize( iOption1 ? g_pDeviceStoreContext : NULL, 
							 iOption2 ? g_pManagerContext : NULL);
	STOP_TIMER("DRM_DVS_Initialize",g_CurrTime,g_DiffTime);
	ChkDR(dr);
#endif

ErrorExit:
	return dr;
}


/* TestDeviceStoreUninitialize: allows us to call DRM_DVS_Uninitialize more than
once  or with NULLs for some tests.  DRM_DVS_Uninitialize will also be called once 
during PostTestCase.

argv[0]: optional -- Device Store context is NULL.

*/

DRM_RESULT TestDeviceStoreUninitialize(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DRM_DWORD iOption1 = 1; //default to TRUE so we pass in the real context

#if DRM_SUPPORT_DEVICESTORE
	
	if (argc >= 1 && 0 == DX_VOS_StrCmp("NULL", argv[0]))
		iOption1 = OEM_atol(argv[0]);

	START_TIMER(g_CurrTime);
	DRM_DVS_Uninitialize(iOption1 ? g_pDeviceStoreContext : NULL);
	STOP_TIMER("DRM_DVS_Uninitialize",g_CurrTime,g_DiffTime);
	ChkDR(dr);
#endif

ErrorExit:
	return dr;
}

/*_EnumerateAllDevicesAndAttr calls DRM_DVS_GetDevice for every registered
device in the storem and for every device calls DRM_DVS_GetDeviceAttrCount and 
DRM_DVS_GetDeviceAttrByIndex for every attribute the device has.*/
DRM_RESULT _EnumerateAllDevicesAndAttr()
{
	DRM_RESULT dr=DRM_SUCCESS;
	DWORD dwNumAttr=0;
    DRM_BYTE *pbAttrName = NULL;
    DRM_DWORD cbAttrName = 0;
    DRM_BYTE *pbAttrValue = NULL;
    DRM_DWORD cbAttrValue = 0;
	DRM_DWORD i = 0;

	START_TIMER(g_CurrTime);

	ChkDR(DRM_DVS_GetFirstDevice(g_pDeviceStoreContext, &g_hDeviceHandle));

	//as long as we are getting a valid device handle, iterate through each device and get all its attributes.
	while(DRM_SUCCEEDED(dr))
	{
		ChkDR(DRM_DVS_GetDeviceAttrCount( g_hDeviceHandle, &dwNumAttr ));
		for (i=0; i < dwNumAttr; i++)
		{
			dr=DRM_DVS_GetDeviceAttrByIndex(g_hDeviceHandle, i, pbAttrName, &cbAttrName, pbAttrValue, &cbAttrValue);
			if (dr==DRM_E_BUFFERTOOSMALL)
			{
				ChkMem( pbAttrName = OEM_malloc( cbAttrName ) );
				ChkMem( pbAttrValue = OEM_malloc( cbAttrValue ) );
				ChkDR(DRM_DVS_GetDeviceAttrByIndex(g_hDeviceHandle, i, pbAttrName, &cbAttrName, pbAttrValue, &cbAttrValue));
			}
		}

		DRM_DVS_FreeDevice(g_hDeviceHandle);
		dr=DRM_DVS_GetNextDevice(g_pDeviceStoreContext, &g_hDeviceHandle);
	}

	//if we enumerated all n devices the loop stops with DRM_E_NOMORE
	//when trying to get device n+1.  This is expected.
	if (dr == DRM_E_NOMORE)
		dr = DRM_SUCCESS;

ErrorExit:
	STOP_TIMER("Enumerate all devices and attributes",g_CurrTime,g_DiffTime);
	SAFE_OEM_FREE(pbAttrName);
	SAFE_OEM_FREE(pbAttrValue);
	return dr;
}


/* TestDeviceStoreRegisterManyDevices allows us to register devices in bulk 
without cluttering test scripts up with dozens of calls to TestDeviceStoreRegisterDevice.
Additionally, it will let us set an arbitrary number of attributes for each device.

argv[0]= Device Name.  A numeric ID will be appended to the name for each separate device.
argv[1]= Number of devices to register.
argv[2]= Optional: Attribute Name.  The device name will prefix and a numeric ID will be appended to the
attribute name for each attribute set to a device.
argv[3]= Optional: Number of attributes to set for each device.
argv[4]= Optional: Attribute value to set.
*/

DRM_RESULT TestDeviceStoreRegisterManyDevices(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DWORD dwNumDevices=0;
	DWORD dwNumAttr=0;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_BYTEBLOB AttrName = {0};
	DRM_BYTEBLOB AttrValue = {0};
	DRM_BYTE szDeviceID[100] = {0};
	DRM_BYTE szAttrName[100] = {0};
	DRM_BYTE szAttrValue[100] = {0};
	DRM_DWORD i = 0;
	DRM_DWORD j = 0;

	ChkArg ( argc >= 2 );

	if (argc >= 3)
		ChkArg(argv[2]);

	if (argc >= 4)
	{ //if we supplied a number of attributes to be set, keep track of it
		ChkArg(argv[3]);
		dwNumAttr = OEM_atol(argv[3]);
	}

	if (argc >= 5)
		ChkArg(argv[4]);

	dwNumDevices=OEM_atol(argv[1]);

	START_TIMER(gCurrTime);
	for(i=0; i<dwNumDevices; i++)
	{
		//construct unique device ID from parameters given
		DX_VOS_SPrintf( szDeviceID,sizeof(szDeviceID), "%s%d", argv[0], i);
		DeviceID.pbBlob = szDeviceID;
	    DeviceID.cbBlob = DX_VOS_StrLen( szDeviceID );

		ChkDR(DRM_DVS_RegisterDevice( g_pDeviceStoreContext, DeviceID, &g_hDeviceHandle ));

		if (argc >=5) //do we have attribute name/value pairs to set for device?
		{
			for (j=0; j < dwNumAttr; j++)
			{
				//construct unique attribute name and value pair from API args.
				DX_VOS_SPrintf( szAttrName,sizeof(szAttrName), "%s%d", argv[2], j);
				AttrName.pbBlob = szAttrName;
				AttrName.cbBlob = DX_VOS_StrLen( szAttrName );

				DX_VOS_SPrintf( szAttrValue,sizeof(szAttrValue), "%s%d", argv[4], j);
				AttrValue.pbBlob = szAttrValue;
				AttrValue.cbBlob = DX_VOS_StrLen( szAttrValue );

				dr = DRM_DVS_SetDeviceAttr( g_hDeviceHandle, AttrName, AttrValue );
				ChkDR(dr)
			}
		}

		ChkDR(DRM_DVS_CommitDevice( g_hDeviceHandle ));
		DRM_DVS_FreeDevice( g_hDeviceHandle );
	}
	STOP_TIMER("DRM_DVS_RegisterDevice for many devices", g_CurrTime, g_DiffTime);

	ChkDR(_EnumerateAllDevicesAndAttr());

ErrorExit:

	//if we failed somewhere in the process we need to shut down the timer.
	if DRM_FAILED(dr)
		STOP_TIMER("DRM_DVS_RegisterDevice for many devices", g_CurrTime, g_DiffTime);
	return dr;
}

/* TestDeviceStoreUnRegisterManyDevices allows us to unregister devices in bulk
that were set with TestDeviceStoreRegisterManyDevices without cluttering test 
scripts up with dozens of calls to TestDeviceStoreUnRegisterDevice.

argv[0]= Device Name.  A numeric ID will be appended to the name for each separate device,
as done in TestDeviceStoreUnRegisterManyDevices.
argv[1]= Number of devices to unregister.
*/

DRM_RESULT TestDeviceStoreUnRegisterManyDevices(long argc, char **argv)
{
	DRM_RESULT dr = DRM_SUCCESS;
	DWORD dwNumDevicesToUnReg = 0;
	DRM_BYTE szDeviceID[100] = {0};
	DRM_BYTEBLOB DeviceID = {0};
	DRM_DWORD i = 0;

	ChkArg(argc == 2);

	dwNumDevicesToUnReg=OEM_atol(argv[1]);	

	START_TIMER(g_CurrTime);

	for(i=0; i<dwNumDevicesToUnReg; i++)
	{
		//construct device ID from args passed in
		DX_VOS_SPrintf( szDeviceID,sizeof(szDeviceID), "%s%d", argv[0], i);
		DeviceID.pbBlob = szDeviceID;
	    DeviceID.cbBlob = DX_VOS_StrLen( szDeviceID );

		ChkDR(DRM_DVS_UnRegisterDevice( g_pDeviceStoreContext, DeviceID ));

	}

ErrorExit:
	STOP_TIMER("DRM_DVS_UnRegisterDevice for many devices", g_CurrTime, g_DiffTime);
	return dr;
}

/* TestDeviceStoreSetManyAttr allows us to set an arbitrary number of attributes 
for a device without cluttering test scripts up with dozens of calls to TestDeviceStoreSetAttr

argv[0]= Device Name.
argv[1]= Attribute Name.  The device name will prefix and a numeric ID will be appended to the
attribute name for each attribute set to a device.
argv[2]= Number of attributes to set to the device.
argv[3]= Attribute value to set.
*/

DRM_RESULT TestDeviceStoreSetManyAttr(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DWORD dwNumAttr=0;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_BYTEBLOB AttrName = {0};
	DRM_BYTEBLOB AttrValue = {0};
	DRM_BYTE szAttrName[100] = {0};
	DRM_BYTE szAttrValue[100] = {0};
	DRM_DWORD i = 0;

	ChkArg(argc == 4);

	dwNumAttr=OEM_atol(argv[2]);

	DeviceID.pbBlob = argv[0];
	DeviceID.cbBlob = DX_VOS_StrLen(argv[0]);

	ChkDR(DRM_DVS_GetDeviceByID(g_pDeviceStoreContext, DeviceID, &g_hDeviceHandle));

	START_TIMER(g_CurrTime);
	for (i=0; i < dwNumAttr; i++)
	{
		//construct unique attribute name/value pair from given parameters.
		DX_VOS_SPrintf( szAttrName,sizeof(szAttrName), "%s%d", argv[1], i);
		AttrName.pbBlob = szAttrName;
		AttrName.cbBlob = DX_VOS_StrLen( szAttrName );

		DX_VOS_SPrintf( szAttrValue,sizeof(szAttrValue), "%s%d", argv[3], i);
		AttrValue.pbBlob = szAttrValue;
		AttrValue.cbBlob = DX_VOS_StrLen( szAttrValue );

		ChkDR(DRM_DVS_SetDeviceAttr( g_hDeviceHandle, AttrName, AttrValue ));
	}

	ChkDR(DRM_DVS_CommitDevice( g_hDeviceHandle ));
	DRM_DVS_FreeDevice( g_hDeviceHandle );

ErrorExit:
	STOP_TIMER("Add many attributes to one device",g_CurrTime,g_DiffTime);
	return dr;
}

/* TestDeviceStoreGetManyAttr allows us to get an arbitrary number of attributes 
from a device set with TestDeviceStoreSetManyAttr without cluttering test scripts 
up with dozens of calls to TestDeviceStoreGetAttr.

argv[0]= Device Name.
argv[1]= Attribute Name.  The device name will prefix and a numeric ID will be appended to the
attribute name for each attribute to get from a device.
argv[2]= Attribute value to compare.
*/

DRM_RESULT TestDeviceStoreGetManyAttr(long argc, char **argv)
{
	DRM_RESULT dr=DRM_SUCCESS;
	DWORD dwNumAttr=0;
	DRM_BYTEBLOB DeviceID = {0};
	DRM_BYTEBLOB AttrName = {0};
	DRM_BYTEBLOB AttrValue = {0};
	DRM_BYTE szAttrName[100] = {0};
	DRM_BYTE szAttrValue[100] = {0};
	DRM_DWORD i = 0;

	ChkArg(argc == 3);

	DeviceID.pbBlob = argv[0];
	DeviceID.cbBlob = DX_VOS_StrLen(argv[0]);

	ChkDR(DRM_DVS_GetDeviceByID(g_pDeviceStoreContext, DeviceID, &g_hDeviceHandle));

	ChkDR(DRM_DVS_GetDeviceAttrCount( g_hDeviceHandle, &dwNumAttr ));

	START_TIMER(g_CurrTime);
	for (i=0; i < dwNumAttr-1; i++)
	{
		//construct unique attribute value/data pair from given parameters.
		DX_VOS_SPrintf( szAttrName,sizeof(szAttrName), "%s%d", argv[1], i);
		AttrName.pbBlob = szAttrName;
		AttrName.cbBlob = DX_VOS_StrLen( szAttrName );

		DX_VOS_SPrintf( szAttrValue,sizeof(szAttrValue), "%s%d", argv[2], i);

		dr = DRM_DVS_GetDeviceAttr( g_hDeviceHandle, AttrName, AttrValue.pbBlob, &AttrValue.cbBlob );

		if (dr==DRM_E_BUFFERTOOSMALL)
		{
			ChkMem( AttrValue.pbBlob = OEM_malloc( AttrValue.cbBlob ) );
			ChkDR(DRM_DVS_GetDeviceAttr(g_hDeviceHandle, AttrName, AttrValue.pbBlob, &AttrValue.cbBlob));
		}

		if (0 != MEMCMP(AttrValue.pbBlob, szAttrValue, AttrValue.cbBlob ))
			ChkDR(DRM_E_FAIL);
	}

ErrorExit:
	STOP_TIMER("Get many attributes from one device",g_CurrTime,g_DiffTime);
	return dr;
}


#endif

DRM_RESULT DS_PreTestCase(long lTCID, char *strTCName)
{
	DRM_RESULT dr;
	DRM_CHAR szPerfLogFile[60];
	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) };

	DX_VOS_SPrintf(szPerfLogFile,sizeof(szPerfLogFile), "%d_JanusPerf.log", lTCID);
	START_PERFLOG(szPerfLogFile);

	g_wCurrentYear = 0;
	g_lOffset = 0;
	
	ChkDR(RemoveDRMFile(RMFILE_STORE));
 	ChkDR(SetDeviceEnv(devCertTemplate, priv, TRUE));
	ChkDR(OEM_SetClockResetState(FALSE));

	ChkMem(g_pManagerContext = (DRM_MANAGER_CONTEXT*)OEM_malloc(sizeof(DRM_MANAGER_CONTEXT)));
#if DRM_SUPPORT_DEVICESTORE
    ChkMem(g_pDeviceStoreContext = (DRM_DEVICESTORE_CONTEXT*)OEM_malloc(sizeof(DRM_DEVICESTORE_CONTEXT)));
#endif
	tGetDeviceStorePathname(&g_wszDeviceStoreName);

	ChkDR( DRM_MGR_Initialize(g_pManagerContext, &g_wszDeviceStoreName) );
#if DRM_SUPPORT_DEVICESTORE
	START_TIMER(g_CurrTime);
    dr = DRM_DVS_Initialize( g_pDeviceStoreContext, g_pManagerContext );
	STOP_TIMER("DRM_DVS_Initialize",g_CurrTime,g_DiffTime);
	ChkDR(dr);
#endif
ErrorExit:
	return dr;
}

DRM_RESULT DS_PostTestCase(long lTCID, char *strTCName)
{
	DRM_RESULT dr = DRM_SUCCESS;

	tChangeSystemTime(-g_lOffset); /* Reverse any time changes in the test case.*/
	g_lOffset=0;

#if DRM_SUPPORT_DEVICESTORE
    DRM_DVS_FreeDevice( g_hDeviceHandle );

    if( g_pDeviceStoreContext != NULL )
    {
		START_TIMER(g_CurrTime);
        DRM_DVS_Uninitialize(g_pDeviceStoreContext);
		STOP_TIMER("DRM_DVS_Uninitialize",g_CurrTime,g_DiffTime);
        SAFE_OEM_FREE( g_pDeviceStoreContext );
    }
#endif

	if ( g_pManagerContext != NULL )
    {
		DRM_MGR_Uninitialize( g_pManagerContext );
		SAFE_OEM_FREE( g_pManagerContext );
	}

	RemoveDRMFile(RMFILE_STORE);
	if(g_szFilePath)
	  	DX_VOS_FDelete(g_szFilePath);

	if (g_wCurrentYear) { /* Set the clock back to current year */
		/*_SetYearOnMachineClock(g_wCurrentYear);*/
		g_wCurrentYear = 0;
	}

	STOP_PERFLOG;

	return dr;
}

/*
IMPLEMENT_DEFAULT_WARPTEST

BEGIN_APIMAP(testdevicestore_ansi, "DailyTestDeviceStore")
#if DRM_SUPPORT_DEVICESTORE
    API_ENTRY(TestDeviceStoreGetFirstDevice)
    API_ENTRY(TestDeviceStoreGetNextDevice)
    API_ENTRY(TestDeviceStoreGetDeviceByID)
    API_ENTRY(TestDeviceStoreGetDeviceID)
    API_ENTRY(TestDeviceStoreGetDeviceAttrCount)
    API_ENTRY(TestDeviceStoreGetDeviceAttrByIndex)
    API_ENTRY(TestDeviceStoreGetDeviceAttr)
    API_ENTRY(TestDeviceStoreSetDeviceAttr)
    API_ENTRY(TestDeviceStoreCommitDevice)
    API_ENTRY(TestDeviceStoreFreeDevice)
    API_ENTRY(TestDeviceStoreRegisterDevice)
    API_ENTRY(TestDeviceStoreUnRegisterDevice)
	API_ENTRY(TestDeviceStoreChangeTime)
	API_ENTRY(TestDeviceStoreInitialize)
	API_ENTRY(TestDeviceStoreUninitialize)
	API_ENTRY(TestDeviceStoreRegisterManyDevices)
	API_ENTRY(TestDeviceStoreUnRegisterManyDevices)
	API_ENTRY(TestDeviceStoreSetManyAttr)
	API_ENTRY(TestDeviceStoreGetManyAttr)
#endif
END_APIMAP
*/

