/*****************************************************************************************
*  Copyright (c) 2004, Beijing Senselock Data Security Centre
*  All rights reserved.
*
*  Filename£ºsample_11.c
*          
*  Briefs£º  The purpose of this snippet is to demonstrate how to use different SenseLock EL directories
*            as in different software products. 
*            
*            
*  History:        
*  --------------------------------------------------------        
*            11/08/2004 v1.0.0.0 Lihua created
*            
*            
*******************************************************************************************/

#include <stdio.h>
#include <conio.h>
#include <assert.h>

#include "..\..\inc\win32\sense4.h"
#include "..\..\inc\win32\PSense4.h"
#include "..\..\common\common.h"

#define S4_EXE_FILE_ID "ef11"

/* global variable definition */
SENSE4_CONTEXT stS4Ctx = {0};
unsigned long dwResult = 0;

/* 
	If the destination dir with the name "lpszDirName" exist,erase all its content.
	If not,create a dir with this name.Then change its default DEV_PIN and USER_PIN
	with the value specified.

    Return:
		If succeed, it returns 1 (TRUE), else it returns 0 (FALSE).
*/
unsigned long OperateOnDir(const  char *lpszDirName, void *lpNewPin, unsigned long dwNewPinLen, 
					                              void *lpNewUsrPin, unsigned long dwNewUsrPinLen)
{
	unsigned char lpOldPin[] = "123456781234567812345678";
	unsigned long dwOldPinLen = sizeof(lpOldPin)-1;
	
	unsigned char lpOldUsrPin[] = "12345678";
	unsigned long dwOldUsrPinLen = sizeof(lpOldUsrPin)-1;

	unsigned long dwSubDirSize = 10000;/* estimated directory size: 10K */
	
	/* to make sure you are in the root dir */
	printf("Change to root directory...\n");
	dwResult = S4ChangeDir(&stS4Ctx, "\\");
	if (dwResult != S4_SUCCESS) 
	{
		printf("Change directory failed! <error code: 0x%08x>\n",dwResult);
		return 0;
	}
	printf("Success!\n");

	printf("Change directory to %s...\n", lpszDirName);
	dwResult = S4ChangeDir(&stS4Ctx, lpszDirName);
	if (dwResult != S4_SUCCESS && dwResult != S4_FILE_NOT_FOUND) 
	{
		printf("Change directory failed! <error code: 0x%08x>\n",dwResult);
		return 0;
	}else if (dwResult == S4_SUCCESS)
	{
		printf("Success!\n");
		/* directory already exist,erase the dir so as to erase all the file under the dir */
		printf("To erase all the file under %s,first verify DEV_PIN...\n", lpszDirName);
		dwResult = S4VerifyPin(&stS4Ctx, lpNewPin, dwNewPinLen, S4_DEV_PIN);
		if (dwResult != S4_SUCCESS) 
		{
			printf("Verify DEV_PIN failed! <error code: 0x%08x>\n",dwResult);
			return 0;
		}
		printf("Success!\n");
		
		printf("Erasing...\n");
		dwResult = S4EraseDir(&stS4Ctx, NULL);
		if (dwResult != S4_SUCCESS) 
		{
			printf("Erase directory %s failed! <error code: 0x%08x>\n", lpszDirName, dwResult);
			return 0;
		}
		printf("Success!\n");
		
	}else /* create a directory named "lpszDirName"*/
	{
		printf("Not exist!Now create directory %s...\n", lpszDirName);
		
		/* need to verify DEV_PIN of root directory first */
		printf("Verify DEV_PIN of root directory...\n");
		dwResult = S4VerifyPin(&stS4Ctx, lpOldPin, dwOldPinLen, S4_DEV_PIN);
		if (dwResult != S4_SUCCESS) 
		{
			printf("Verify DEV_PIN failed! <error code: 0x%08x>\n",dwResult);
			return 0;
		}
		printf("Success!\n");
		
		printf("Create directory %s ...\n", lpszDirName);
		dwResult = S4CreateDir(&stS4Ctx, lpszDirName, dwSubDirSize, S4_CREATE_SUB_DIR);
		if (dwResult != S4_SUCCESS) 
		{
			printf("Create %s directory failed! <error code: 0x%08x>\n",lpszDirName, dwResult);
			return 0;
		}
		printf("Success!\n");
	
	}
	/* change DEV_PIN and USR_PIN after directory creation or erasion,that's important! */
	printf("Change USER_PIN of directory %s...\n", lpszDirName);
	dwResult = S4ChangePin(&stS4Ctx,lpOldUsrPin,dwOldUsrPinLen,lpNewUsrPin,dwNewUsrPinLen,S4_USER_PIN);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Change USER_PIN of directory %s failed! <error code: 0x%08x>\n", lpszDirName, dwResult);
		return 0;
	}
	printf("Success!\n");

	printf("Change DEV_PIN of directory %s...\n", lpszDirName);
	dwResult = S4ChangePin(&stS4Ctx,lpOldPin,dwOldPinLen,lpNewPin,dwNewPinLen,S4_DEV_PIN);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Change DEV_PIN of directory %s failed! <error code: 0x%08x>\n", lpszDirName, dwResult);
		return 0;
	}
	printf("Success!\n");
	return 1;
}


int main(int argc, char* argv[])
{
	unsigned char lpNewPin[] = "zaq12wsxcde34rfvbgt56yhn";
	unsigned long dwNewPinLen = sizeof(lpNewPin)-1;

	unsigned char lpNewUsrPin[] = "zaq12wsx";
	unsigned long dwNewUsrPinLen = sizeof(lpNewUsrPin)-1;

	unsigned char lpNewPin_1[] = "hehe1234haha432178909834";
	unsigned long dwNewPinLen_1 = sizeof(lpNewPin_1)-1;
	
	unsigned char lpNewUsrPin_1[] = "heha1235";
	unsigned long dwNewUsrPinLen_1 = sizeof(lpNewUsrPin_1)-1;
	
	unsigned long dwFileSize = 3000;/* estimated file size: 3K */
	unsigned long dwBytesWritten = 0;

	unsigned char test[8] = {3,1,8,2,5,4,7,6};
	unsigned long dwBytesReturned = 0;

	
	printf("Open first SenseLock EL device...\n");
	if (!(dwResult = OpenS4ByIndex(FIRST_S4_INDEX, &stS4Ctx)))
	{
		return 1;
	} 
	printf("Success!\n");
	
	if (!OperateOnDir("df01", lpNewPin, dwNewPinLen, lpNewUsrPin, dwNewUsrPinLen))
	{
		ResetAndCloseS4(&stS4Ctx);
		return 1;
	}
	
	dwFileSize = 0;
	printf("Write hex file \"sample_10_hw.hex\" to \"df01\"....\n");
	dwResult = PS4WriteFile(&stS4Ctx, S4_EXE_FILE_ID, "sample_10_hw.hex", &dwFileSize, 
		S4_CREATE_NEW, S4_HEX_FILE, &dwBytesWritten);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Write file to device failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}
	printf("Success!\n");
	
    
	dwResult = S4VerifyPin(&stS4Ctx, lpNewUsrPin, dwNewUsrPinLen, S4_USER_PIN);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Verify USER_PIN failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}

    printf("Data to be bubble-ordered:");
	hexprint(stdout, test, sizeof(test));
	
	printf("Execute program \"df01\\ef11\" in SenseLock EL...\n");
	dwResult = S4Execute(&stS4Ctx, S4_EXE_FILE_ID, test, sizeof(test), test, sizeof(test), &dwBytesReturned);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Execute program in SenseLock EL failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}
	printf("Success!\n");

    printf("Data after being bubble-ordered:");
	hexprint(stdout, test, sizeof(test));


	if (!OperateOnDir("df02", lpNewPin_1, dwNewPinLen_1, lpNewUsrPin_1, dwNewUsrPinLen_1))
	{
		ResetAndCloseS4(&stS4Ctx);
		return 1;
	}
	dwFileSize = 0;
	printf("Write hex file \"sample_11_hw.hex\" to \"df02\"....\n");
	dwResult = PS4WriteFile(&stS4Ctx, S4_EXE_FILE_ID, "sample_11_hw.hex", &dwFileSize, 
		S4_CREATE_NEW, S4_HEX_FILE, &dwBytesWritten);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Write file to device failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}
	printf("Success!\n");
	
    printf("Data to be bubble-ordered:");
	hexprint(stdout, test, sizeof(test));
    
	dwResult = S4VerifyPin(&stS4Ctx, lpNewUsrPin_1, dwNewUsrPinLen_1, S4_USER_PIN);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Verify USER_PIN failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}
	
	printf("Execute program  \"df02\\ef11\" in SenseLock EL...\n");
	dwResult = S4Execute(&stS4Ctx, S4_EXE_FILE_ID, test, sizeof(test), test, sizeof(test), &dwBytesReturned);
	if (dwResult != S4_SUCCESS) 
	{
		printf("Execute program in SenseLock EL failed! <error code: 0x%08x>\n",dwResult);
		ResetAndCloseS4(&stS4Ctx);
		return dwResult;
	}
	printf("Success!\n");
	
    printf("Data after being bubble-ordered:");
	hexprint(stdout, test, sizeof(test));
	
	ResetAndCloseS4(&stS4Ctx);
    getch(); 
	return dwResult;
}
