// Данный тест проверяет работу управляющих команд,
// передаваемых библиотеке функцией C_Ctrl.
#include "test_common.h"

int
main(int argc, char *argv[]){
	CK_RV rc;
	CK_C_GetFunctionList pfoo = NULL;
	int i;

	for (i=1; i<argc; i++) {
		if (strcmp("-api", argv[i]) == 0) {
			i++;
			api_path = argv[i];
		} else if (strcmp("-user_pin", argv[i]) == 0) {
			i++;
			user_pin = argv[i];
		}
	}

#ifdef WIN32
	dll = LoadLibrary(api_path);
#else   
	dll = dlopen(api_path, RTLD_NOW);
#endif   
	if ( dll == NULL ) {
		fprintf(stderr, "Can't load PKCS#11 API library. Check API path.\n"); 
		return CKR_GENERAL_ERROR;
	}
#ifdef WIN32
	pfoo = (CK_C_GetFunctionList)GetProcAddress(dll, "C_GetFunctionList");
#else
	pfoo = (CK_C_GetFunctionList)dlsym(dll, "C_GetFunctionList");
#endif   
	if (pfoo == NULL ) {
		fprintf(stderr, "Couldn't get C_GetFunctionList address\n");
		return CKR_GENERAL_ERROR;
	}
   
	rc = pfoo(&funcs);
	if (rc != CKR_OK) {
		fprintf(stderr, "Error in  C_GetFunctionList 0x%X\n", rc );
		return rc;
	}
#ifdef WIN32
	pctrl = (CK_C_Ctrl)GetProcAddress(dll, "C_Ctrl");
#else
	pctrl = (CK_C_Ctrl)dlsym(dll, "C_Ctrl");
#endif   

	// Конфигурируем путь к файлу сообщений
	rc = pctrl(PKCS11_CTRL_LOG_PATH, 0, 
		(void *)"./log.txt", NULL);
	if (rc != CKR_OK) {
		fprintf(stderr, "C_Ctrl failed: 0x%x\n", rc);
		return rc;
	}

	rc = funcs->C_Initialize(NULL);
	if (rc != CKR_OK) {
		show_error("C_Initialize", rc);
		return rc;
	}

	rc = funcs->C_GetSlotList(CK_TRUE, NULL, &SlotCount);
	if (rc != CKR_OK) {
		SlotList = NULL;
		printf("Get slot list result: 0x%x\n", rc);
		return rc;
	}
	printf("%d slots found\n", SlotCount);
	if (SlotCount > 0)
	{   
		SlotList = (CK_SLOT_ID_PTR) malloc(SlotCount * sizeof(CK_SLOT_ID));
		rc = funcs->C_GetSlotList(CK_TRUE, SlotList, &SlotCount);
		if (rc != CKR_OK) {
			SlotList = NULL;
			SlotCount = 0;
			printf("Get slot list result: 0x%x\n", rc);
			return rc;
		}
	} else {
		SlotList = NULL;
		return CKR_OK;
	}

	if (SlotCount > 0) {
		// Передаем ошибочный NULL в аргументе, чтобы получить
		// сообщение об ошибке в лог-файле.
		rc = funcs->C_GetTokenInfo(SlotList[0], NULL);
	}

	if (SlotList){
		free(SlotList);
		SlotList=NULL;
	}
	printf("C_Ctrl test SUCCESS\n");
	return CKR_OK;
}
