/*
 * 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 BOOL load_functions(void) {
	char soname[MAX_PATH] = FALLBACK_LIBCTAPI, buffer[MAX_PATH];
	LONG result;
	HKEY key_handle;

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

	/* 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 FALSE;
	}

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

        return TRUE;
}

/*
 *  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())
		return FALSE;  /* error */
            break;
        case DLL_PROCESS_DETACH:
            if (lpvReserved) break;
            if (ctapi_handle) wine_dlclose(ctapi_handle, NULL, 0);
            break;
    }

    return TRUE;
}
