/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1995-1996 Robert Gentleman and Ross Ihaka
 *  Copyright (C) 1997-2021 The R Core Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  https://www.R-project.org/Licenses/
 */

/*  Dynamic Loading Support: See ../main/Rdynload.c and ../include/Rdynpriv.h
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <string.h>
#include <stdlib.h>
#include <Defn.h>
#include <Rmath.h>
#include <direct.h>
#define WIN32_LEAN_AND_MEAN 1
/* Eventually #define _WIN32_WINNT 0x0502 for SetDllDirectoryA */
#include <windows.h>

/* SetDllDirectory is supported under XP SP1 and later.
   If called with a non-NULL argument it sets the argument to be
   the second item on the DLL search path (after the application
   launch directory).  This is removed if called with NULL.

   Prior to XP SP1 the second item was the current directory, but this
   has (by default, 'safe DLL search mode') been moved below the
   Windows dirs.  Using SetDllDirectory removes it altogether.

   We fudge this via the current directory in earlier systems.
 */
typedef BOOL (WINAPI *PSDD)(LPCTSTR);

int setDLLSearchPath(const char *path)
{
    int res = 0; /* failure */
    PSDD p = (PSDD) -1;
    static char wd[MAX_PATH] = "";  /* stored real current directory */

    // XP SP1 and later.
    if(p == (PSDD) -1)
	p = (PSDD) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
				  "SetDllDirectoryA");
    if(p) {
	res = p(path);
    } else { /* Windows 2000 */
	if(path) {
	    GetCurrentDirectory(MAX_PATH, wd);
	    SetCurrentDirectory(path);
	} else if (wd[0]) {
	    SetCurrentDirectory(wd);
	    wd[0] = '\0';
	}
    }
    return res;
}

#include <R_ext/Rdynload.h>
#include <Rdynpriv.h>


	/* Inserts the specified DLL at the head of the DLL list */
	/* Returns 1 if the library was successfully added */
	/* and returns 0 if the library table is full or */
	/* or if LoadLibrary fails for some reason. */

static void fixPath(char *path)
{
    char *p;
    for(p = path; *p != '\0'; p++) if(*p == '\\') *p = '/';
}

static HINSTANCE R_loadLibrary(const char *path, int asLocal, int now,
			       const char *search);
static DL_FUNC getRoutine(DllInfo *info, char const *name);

static void R_getDLLError(char *buf, int len);
static void GetFullDLLPath(SEXP call, char *buf, const char *path);

static void closeLibrary(HINSTANCE handle)
{
    FreeLibrary(handle);
}

void InitFunctionHashing()
{
    R_osDynSymbol->loadLibrary = R_loadLibrary;
    R_osDynSymbol->dlsym = getRoutine;
    R_osDynSymbol->closeLibrary = closeLibrary;
    R_osDynSymbol->getError = R_getDLLError;

#ifdef CACHE_DLL_SYM
    R_osDynSymbol->deleteCachedSymbols = Rf_deleteCachedSymbols;
    R_osDynSymbol->lookupCachedSymbol = Rf_lookupCachedSymbol;
#endif

    R_osDynSymbol->fixPath = fixPath;
    R_osDynSymbol->getFullDLLPath = GetFullDLLPath;
}

#ifndef _MCW_EM
_CRTIMP unsigned int __cdecl
_controlfp (unsigned int unNew, unsigned int unMask);
_CRTIMP unsigned int __cdecl _clearfp (void);
/* Control word masks for unMask */
#define	_MCW_EM		0x0008001F	/* Error masks */
#define	_MCW_IC		0x00040000	/* Infinity */
#define	_MCW_RC		0x00000300	/* Rounding */
#define	_MCW_PC		0x00030000	/* Precision */
#endif

HINSTANCE R_loadLibrary(const char *path, int asLocal, int now,
			const char *search)
{
    HINSTANCE tdlh;
    unsigned int dllcw, rcw;
    int useSearch = search && search[0];

    rcw = _controlfp(0,0) & ~_MCW_IC;  /* Infinity control is ignored */
    _clearfp();
    if(useSearch) setDLLSearchPath(search);
    tdlh = LoadLibrary(path);
    if(useSearch) setDLLSearchPath(NULL);
    dllcw = _controlfp(0,0) & ~_MCW_IC;
    if (dllcw != rcw) {
	_controlfp(rcw, _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC);
	if (LOGICAL(GetOption1(install("warn.FPU")))[0])
	    warning(_("DLL attempted to change FPU control word from %x to %x"),
		    rcw,dllcw);
    }
    return(tdlh);
}

static DL_FUNC getRoutine(DllInfo *info, char const *name)
{
    DL_FUNC f;
    f = (DL_FUNC) GetProcAddress(info->handle, name);
    return(f);
}

static void R_getDLLError(char *buf, int len)
{
    LPSTR lpMsgBuf, p;
    char *q;
    FormatMessage(
	FORMAT_MESSAGE_ALLOCATE_BUFFER |
	FORMAT_MESSAGE_FROM_SYSTEM |
	FORMAT_MESSAGE_IGNORE_INSERTS,
	NULL,
	GetLastError(),
	MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
	(LPSTR) &lpMsgBuf,
	0,
	NULL
	);
    strcpy(buf, "LoadLibrary failure:  ");
    q = buf + strlen(buf);
    /* It seems that Win 7 returns error messages with CRLF terminators */
    for (p = lpMsgBuf; *p; p++) if (*p != '\r') *q++ = *p;
    LocalFree(lpMsgBuf);
}

static void GetFullDLLPath(SEXP call, char *buf, const char *path)
{
    char *p;

    if ((path[0] != '/') && (path[0] != '\\') && (path[1] != ':')) {
	if (!getcwd(buf, MAX_PATH))
	    errorcall(call, _("cannot get working directory"));
	strcat(buf, "\\");
	strcat(buf, path);
    } else
	strcpy(buf, path);
    /* fix slashes to allow inconsistent usage later */
    for (p = buf; *p; p++) if (*p == '\\') *p = '/';
}
