/*
 * WINE ct-api wrapper
 *
 * Copyright 2007 Christian Eggers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"
#include <string.h>
#include "wine/library.h"
#include "wine/debug.h"
#include "windef.h"
#include "winreg.h"
#include "winnls.h"
#include "ctapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(ctapi32);

#define FALLBACK_LIBCTAPI "libctapi.so"
static const WCHAR value_name[] = {'l','i','b','r','a','r','y',0};


static IS8 (*pCT_init)(IU16 ctn, IU16 pn) = NULL;
static IS8 (*pCT_data)(IU16 ctn, IU8 *dad, IU8 *sad, IU16 lenc, IU8 *command,
	IU16 *lenr, IU8 *response) = NULL;
static IS8 (*pCT_close)(IU16 ctn) = NULL;

static void *ctapi_handle = NULL;


static int load_functions(void) {
	char soname[MAX_PATH] = FALLBACK_LIBCTAPI, buffer[MAX_PATH];
	LONG result;
	HKEY key_handle;

	if (pCT_init) /* loaded already */
		return 0;

	/* Try to get name of low level library from registry */
        /* @@ Wine registry key: HKCU\Software\Wine\ctapi32 */
	result = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\ctapi32", 0, KEY_READ, &key_handle);
	if (result == ERROR_SUCCESS) {
		DWORD type, size;
		WCHAR buffer_w[MAX_PATH];

		size = sizeof(buffer_w) - sizeof(WCHAR);  /* Leave space for null termination */
		result = RegQueryValueExW(key_handle, value_name, NULL, &type, (LPBYTE)buffer_w, &size);
		if ((result == ERROR_SUCCESS) && (type == REG_SZ)) {
			int len;

			/* Null termination */
			buffer_w[size / sizeof(WCHAR)] = '\0';
			len = WideCharToMultiByte(CP_UNIXCP, 0, buffer_w, -1, buffer, sizeof(buffer), NULL, NULL);
			if (len)
				memcpy(soname, buffer, len);
		}
		RegCloseKey(key_handle);
	}

	TRACE("Loading library '%s'\n", soname);
	ctapi_handle = wine_dlopen(soname, RTLD_NOW, NULL, 0);
	if (ctapi_handle) {
		TRACE("Successfully loaded '%s'\n", soname);
	}
	else {
		MESSAGE("Wine cannot find any usable hardware library, ctapi32.dll not working.\n");
		MESSAGE("Please create the key \"HKEY_CURRENT_USER\\Software\\Wine\\ctapi32\" in your registry\n");
		MESSAGE("and set the value \"library\" to your library name (e.g. \"libctapi-cyberjack.so.1\" or \"/usr/lib/readers/libctapi.so\").\n");
		return 1;
	}

#define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ctapi_handle, #f, NULL, 0)) == NULL){WARN("Can't find symbol %s\n", #f); return 1;}
LOAD_FUNCPTR(CT_init);
LOAD_FUNCPTR(CT_data);
LOAD_FUNCPTR(CT_close);
#undef LOAD_FUNCPTR

	return 0;
}

static void unload_functions(void)
{
	pCT_close = NULL;
	pCT_data = NULL;
	pCT_init = NULL;
	if (ctapi_handle)
		wine_dlclose(ctapi_handle, NULL, 0);
}


/*
 *  ct-API specific functions
 */

IS8 WINAPI WIN_CT_init(IU16 ctn, IU16 pn)
{
	if (!pCT_init)
		return ERR_HOST;
	return pCT_init(ctn, pn);
}

IS8 WINAPI WIN_CT_data(IU16 ctn, IU8 *dad, IU8 *sad, IU16 lenc, IU8 *command, IU16 *lenr, IU8 *response)
{
	if (!pCT_data)
		return ERR_HOST;
	return pCT_data(ctn, dad, sad, lenc, command, lenr, response);
}

IS8 WINAPI WIN_CT_close(IU16 ctn)
{
	if (!pCT_close)
		return ERR_HOST;
	return pCT_close(ctn);
}

/*
 *  Dll Main function
 */
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("%p,%x,%p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            DisableThreadLibraryCalls(hinstDLL);
            /* Try to load low-level library */
            if (load_functions() != 0)
		return FALSE;  /* error */
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            unload_functions();
            break;
        }
    }

    return TRUE;
}
