// VC7Sample.cpp : Example for Rockey4 Class library.
//

#include "stdafx.h"

#include "comdef.h"			//Include this for _variant_t.
#include "Ry4Com_i.c"		//Include this for IID_IRockey4,CLISD_CRockey4
#include "Ry4Com.h"			//Include this for IRockey4.
#include "Ry4ComDef.h"		

//Convert byte array to Variant type

VARIANT ByteArray2Variant(BYTE* pSrc,DWORD dwLen)
{
	VARIANT			vRet;
	SAFEARRAYBOUND	sab;

	sab.lLbound=0;
	sab.cElements=dwLen;

	vRet.vt=VT_ARRAY|VT_UI1;		
	vRet.parray=SafeArrayCreate(VT_UI1,1,&sab);

	BYTE* pArrayData=NULL;

	SafeArrayAccessData(vRet.parray,(void**)&pArrayData);

	memcpy(pArrayData,pSrc,dwLen);

	SafeArrayUnaccessData(vRet.parray);

	return vRet;
}

//Get byte array from VARIANT.
BYTE* UseVariantData(VARIANT& vt,DWORD* pLength=NULL)
{
	BYTE* pRet=NULL;	

	SafeArrayAccessData(vt.parray,(void**)&pRet);

	if(pLength)
	{
		*pLength=vt.parray->rgsabound[0].cElements;
	}	

	return pRet;
}

void UnUseVariantData(VARIANT& vt)
{
	SafeArrayUnaccessData(vt.parray);
}


//routine to show error information.
void ShowErrorInfo(DWORD dwErr,LPCTSTR csFuncName)
{
	_tprintf(_T("***** Error Occoured in %s, retcode=%08x\n"),csFuncName,dwErr);
}


//MACRO to show a error message.
#define  CheckResult(code,func) if(FAILED(code)){ ShowErrorInfo(code,func); goto ENDFUNC;}


//Main function.
int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT		hRet;
	IRockey4*	pRy4=NULL;
	int			i;

	//data used by function.
	DWORD		lp1=0,lp2=0;
	WORD		p1=0,p2=0,p3=0,p4=0,handle=0;
	_variant_t	vaBuffer=(int)0;					//this need comdef.h

	int		iMaxRockey=0;
	DWORD	uiarrRy4ID[32];
	DWORD	iCurrID;

	//Demo 0, Create interface.
	CoInitialize(NULL);

	hRet=CoCreateInstance(CLSID_CRockey4,NULL,CLSCTX_INPROC_SERVER,IID_IRockey4,(void**)&pRy4);
	if(FAILED(hRet))
	{
		printf("Error: Create IRockey4 failed, code %08X\n",hRet);
		goto ENDFUNC;
	}

	

	
	//demo1: Find rockey. id=0,need setting p1,p2,p3,p4 to password.
	p1=0xc44c; p2=0xc8f8; p3=0x0799; p4=0xc43b;
	hRet=pRy4->DoCmd(RY_FIND,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	if(FAILED(hRet)) 
	{
		printf("No ROCKEY4 found. Please insert one and retry.\n"); 
		goto ENDFUNC;
	}

	uiarrRy4ID[iMaxRockey]=lp1;
	iMaxRockey++;

	//demo2: Find Next rockey.
	while(1)
	{
		//Find another Ry4.
		p1=0xc44c; p2=0xc8f8; p3=0x0799; p4=0xc43b;
		hRet=pRy4->DoCmd(RY_FIND_NEXT,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
		if(FAILED(hRet)) break;

		uiarrRy4ID[iMaxRockey]=lp1;
		iMaxRockey++;
	}

	//print all rockeys found.
	for(i=0; i<iMaxRockey; i++)
	{
		printf("(%d) %08X\n",i,uiarrRy4ID[i]);
	}
	printf("Found %d Rockey4(s).\n",iMaxRockey);
	

	//select an ID.
	if(iMaxRockey>1)
	{
		DWORD dwIndex;

		printf("Please input the index to open.(>=0,<%d)\n",iMaxRockey);
		scanf("%d",&dwIndex);

		iCurrID=uiarrRy4ID[dwIndex];
	}
	else iCurrID=uiarrRy4ID[0];


	//Demo3: Open rockey4. LP1 is Ry4ID.
	lp1=iCurrID;
	p1=0xc44c; p2=0xc8f8; p3=0x0799; p4=0xc43b;

	hRet=pRy4->DoCmd(RY_OPEN,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Open");

	printf("Opened,handle is %08X,type is %08X\n",handle,lp2);

	//Demo4: Write 24 bytes to UDZ. p1=index of first address, p2=length,obBuffer=data,in byte array.
	//Caution: Normal Ry4(include Ry4USB) has 24 bytes UDZ, Ry4Net,Ry4Plus has 80 bytes UDZ.

	BYTE byWriteData[24];

	for(i=0; i<24; i++) byWriteData[i]=(BYTE)i;

	printf("Writting 24 bytes to user data zone...\n");

	p1=0; p2=24; 
	vaBuffer=ByteArray2Variant(byWriteData,24);

	hRet=pRy4->DoCmd(RY_WRITE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Open");

	printf("[OK]\n");	

	//Demo5: Read UDZ Zone, 24 bytes.
	BYTE*	byReadData=NULL;
	DWORD	dwReadLen;

	printf("Reading 24 bytes from user data zone...\n");

	p1=0;p2=24;vaBuffer=(int)0;
	hRet=pRy4->DoCmd(RY_READ,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Read");

	byReadData=UseVariantData(vaBuffer,&dwReadLen);

	for(i=0; i<(int)dwReadLen; i++)
	{
		printf("%02X ",byReadData[i]);
	}

	printf("\n[OK]\n");

	UnUseVariantData(vaBuffer);

	vaBuffer=(int)0;

	//Demo6: Generate 4 random number.
	WORD usRandom[4];

	printf("Generating 8 bytes random...\n");

	for(int i=0; i<4; i++)
	{
		hRet=pRy4->DoCmd(RY_RANDOM,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
		CheckResult(hRet,"IRockey4.Random");

		usRandom[i]=p1;
		printf("%04X ",p1);
	}

	printf("\n[OK]\n");

	//Demo7:Generate seed code. lp2 is seed.
	printf("Generating seed code, seed=0x193F4701...\n");

	lp2=0x193F4701;
	hRet=pRy4->DoCmd(RY_SEED,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Seed");

	printf("[OK], seed code is %04X %04X %04X %04X\n",p1,p2,p3,p4);

	//Demo8:Write UID to 0x19303A78.
	printf("Writting user ID, ID=0x19303A78...\n");

	lp1=0x19303A78;
	hRet=pRy4->DoCmd(RY_WRITE_USERID,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.WriteUserID");

	printf("[OK]\n");

	lp1=0;

	//Demo9: Read UID.
	printf("Reading user ID...\n");
	hRet=pRy4->DoCmd(RY_READ_USERID,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.ReadUserID");

	printf("[OK],User ID is %08X\n",lp1);

	//Demo10:Set module 0x08, number is 3, can be decreased.
	printf("Setting module 8, number is 3, can be decreased...\n");

	p1=8; p2=3; p3=1;
	hRet=pRy4->DoCmd(RY_SET_MOUDLE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.SetModule");

	printf("[OK]\n");

	//Demo11:Check module. p1=module index
	printf("Checking module 8...\n");

	p1=8;
	hRet=pRy4->DoCmd(RY_CHECK_MOUDLE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.CheckModule");

	printf("[OK], bValidate=%d, bDecreasable=%d\n",p2,p3);

	//Demo12: Decrease. p1=module index.
	for(int i=0; i<3; i++)
	{
		p1=8;
		printf("Module 8,Decrease %d... ",i);
		hRet=pRy4->DoCmd(RY_DECREASE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
		CheckResult(hRet,"IRockey4.Decrease");

		//Check module status
		p1=8;
		hRet=pRy4->DoCmd(RY_CHECK_MOUDLE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
		CheckResult(hRet,"IRockey4.CheckModule");


		printf("[OK], bValidate=%d, bDecreasable=%d\n",p2,p3);
	}

	//Demo13:Write arithmetic to UAZ,

	BSTR csArith=L"A=A+B,C=C+D,B=E+F,D=G+H";

	wprintf(L"Writting arithmetic to UAZ,%s\n",csArith);

	p1=0; vaBuffer=csArith;
	hRet=pRy4->DoCmd(RY_WRITE_ARITHMETIC,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.WriteArithmetic");

	printf("[OK]\n");

	vaBuffer=(int)0;

	//Demo14,Calculate 1
	printf("Calculate 1,A=1,B=2,C=3,D=4...");

	lp1=0; lp2=8; p1=1; p2=2; p3=3; p4=4;
	hRet=pRy4->DoCmd(RY_CALCULATE1,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Calculate1");

	printf("[OK],result: A=%04X,B=%04X,C=%04X,D=%04X\n",p1,p2,p3,p4);

	//Demo15,Calculate 2
	printf("Calculate 2,A=1,B=2,C=3,D=4...");

	lp1=0; lp2=0x19303A09; p1=1; p2=2; p3=3; p4=4;
	hRet=pRy4->DoCmd(RY_CALCULATE2,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Calculate2");

	printf("[OK],result: A=%04X,B=%04X,C=%04X,D=%04X\n",p1,p2,p3,p4);

	//Demo16,Calculate 3
	printf("Calculate 3,A=1,B=2,C=3,D=4...");

	lp1=0; lp2=8; p1=1; p2=2; p3=3; p4=4;
	hRet=pRy4->DoCmd(RY_CALCULATE3,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Calculate3");

	printf("[OK],result: A=%04X,B=%04X,C=%04X,D=%04X\n",p1,p2,p3,p4);

	//Demo17,Close.
	printf("Closing handle %04X...",handle);

	hRet=pRy4->DoCmd(RY_CLOSE,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
	CheckResult(hRet,"IRockey4.Close");

	printf("[OK]\n");

ENDFUNC:

	if(pRy4) pRy4->Release();

	CoUninitialize();
	return 0;
}

