/*--------------------------------------------------------------*
 * UniMate Drive PKCS#11 global.c
 * 2015-04-10
 * Global function
 *--------------------------------------------------------------*/


#include "global.h"

#if (defined(_WIN32) || defined(_WIN64))
#define pkcs11_path "UniMateP11.dll"
HINSTANCE hLib = NULL;
#elif defined(_Linux)
#define pkcs11_path "libUniMateP11.so"
#include <dlfcn.h>
void *hLib = NULL;
char *error = NULL;
#endif


int leave (char * c)
{
	printf ("%s\n", (c == NULL? "" : c));
	return PKCS_FAILED;
}

CK_FUNCTION_LIST_PTR InitFunctionList()
{
	CK_C_GetFunctionList pGFL = NULL;
	CK_FUNCTION_LIST_PTR fl = NULL;
	unsigned long rv;

	printf ("Load %s.\n", pkcs11_path);
#if (defined(_WIN32) || defined(_WIN64))

	/* Load the library
	 */
	if ((hLib = LoadLibrary(pkcs11_path)) == NULL)
	{
		leave ("Cannot load PKCS 11 DLL.");
		return NULL;
	}

	/* Find the entry point
	 */
	if ( (pGFL = (CK_C_GetFunctionList)GetProcAddress(hLib, "C_GetFunctionList")) == NULL )
	{
		leave ("Cannot find GetFunctionList().");
		return NULL;
	}

#elif defined(_Linux)

	/* Linux load the library
	 */
	hLib = dlopen(pkcs11_path, RTLD_LAZY );
	if (!hLib){
		printf("Cannot load %s.\n", pkcs11_path);
		printf("Open Error:%s.\n",dlerror());
		return 0;
	}

	/* Find the entry point.
	 */
	pGFL = (CK_C_GetFunctionList)dlsym(hLib,"C_GetFunctionList");
	if ( pGFL == NULL)
	{
		leave ("Cannot find GetFunctionList().");
		return NULL;
	}

#endif

	if((rv = pGFL(&fl)) != PKCS_OK)
	{
		leave ("Can't get function list. \n");
		return NULL;
	}

	return fl;
}

void Finalize()
{
	if ( hLib != NULL )
	{
#if (defined(_WIN32) || defined(_WIN64))
		FreeLibrary(hLib);
#elif defined(_Linux)
		dlclose(hLib);
#endif	
	}
}