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

#include "stdafx.h"
#include "conio.h"

#include "comdef.h"			//Include this for _variant_t.
#include "NetRY4Com_i.c"	//Include this for IID_INetRockey4,IID_INetRy4Util,CLISD_CNetRockey4
#include "NetRY4Com.h"		//Include this for INetRockey4.
#include "NR4ComDef.h"		//Include this for error code definations.	


//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;
	INetRockey4*	pRy4=NULL;
	INetRy4Util*	pNetUtil=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
	_bstr_t		csSvrName;							//store server name.

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

	//Demo 0, Create interface.

	CoInitialize(NULL);

	//Create INetRockey4 interface.
	hRet=CoCreateInstance(CLSID_CNetRockey4,NULL,CLSCTX_INPROC_SERVER,IID_INetRockey4,(void**)&pRy4);
	if(FAILED(hRet))
	{
		printf("Error: Create INetRockey4 failed, code %08X\n",hRet);
		goto ENDFUNC;
	}

	//Query INetRy4Util Interface.
	hRet=pRy4->QueryInterface(IID_INetRy4Util,(void**)&pNetUtil);
	if(FAILED(hRet))
	{
		printf("Error: Query INetRy4Util failed, code %08X\n",hRet);
		goto ENDFUNC;
	}
	else
	{
		//You can set ini path name here. 

		// BSTR	st=L"c:\\temp\\clicfg.ini";

		// pNetUtil->SetIniPathName(st);
		
	}	

	
	//demo1: Find rockey. id=0,need setting p1,p2 to password.
	

	p1=0xc44c; p2=0xc8f8;
	vaBuffer=(int)0;	

	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;
	}

	//print to screen. vaBuffer is name of server.
	csSvrName=vaBuffer;
	wprintf(L"(%d) %08X  @  %s\n",iMaxRockey,lp1,(BSTR)csSvrName);

	uiarrRy4ID[iMaxRockey]=lp1;
	iMaxRockey++;

	//demo2: Find Next rockey.
	while(1)
	{
		//Find another Ry4.
		p1=0xc44c; p2=0xc8f8;
		vaBuffer=(int)0;

		hRet=pRy4->DoCmd(RY_FIND_NEXT,&handle,&lp1,&lp2,&p1,&p2,&p3,&p4,&vaBuffer);
		if(FAILED(hRet)) break;

		//print to screen. vaBuffer is name of server.
		csSvrName=vaBuffer;
		wprintf(L"(%d) %08X  @  %s\n",iMaxRockey,lp1,(BSTR)csSvrName);

		//Record it.
		uiarrRy4ID[iMaxRockey]=lp1;
		iMaxRockey++;
	}
	
	printf("Found %d Rockey4(s).\n",iMaxRockey);
	

	//select an ID.
	
	DWORD dwIndex,dwModule;

	while(1)
	{
		printf("Please input  Index & Module to login.( such as: 0 0 )\n");
		scanf("%d %d",&dwIndex,&dwModule);

		//dwIndex < iMaxRockey && dwModule<16
		if(dwIndex<(DWORD)iMaxRockey && LOWORD(dwModule)<16) break;
	}	

	iCurrID=uiarrRy4ID[dwIndex];
	


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

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

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

	//You can see it in NrMon.exe now :)
	printf("Press any key to continue...\n");
	getch();

	//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,"INetRockey4.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,"INetRockey4.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,"INetRockey4.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,"INetRockey4.Seed");

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


	//demo8 is not available for NetROCKEY4.

	

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

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


	//demo10 is not available for NetROCKEY4.
	

	//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,"INetRockey4.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,"INetRockey4.Decrease");

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


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

	//demo13 is not available for NetROCKEY4.

	
	//Demo14,Calculate 1
	printf("Calculate 1 ...");

	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,"INetRockey4.Calculate1");

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

	//Demo15,Calculate 2
	printf("Calculate 2 ...");

	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,"INetRockey4.Calculate2");

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

	//Demo16,Calculate 3
	printf("Calculate 3 ...");

	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,"INetRockey4.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,"INetRockey4.Close");

	printf("[OK]\n");

ENDFUNC:

	if(pRy4) pRy4->Release();

	CoUninitialize();
	return 0;
}

