netcdf-c/libncpoco/cp_win32.c
DWesl 4ef68740a3 STY: Move nulldup backup definition from cp_win32.c to ncconfigure.h
Allow definition to be used in more places.
Should probably consolidate definition a few places.
2022-10-29 09:48:22 -04:00

188 lines
3.7 KiB
C
Executable File

/*********************************************************************
* Copyright 1993, UCAR/Unidata
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
* Derived from poco library from Boost Software: see nccpoco/LICENSE file.
*********************************************************************/
#ifdef _WIN32
#include "config.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <windows.h>
#include <errhandlingapi.h>
#include "netcdf.h"
#include "ncpoco.h"
#include "ncpathmgr.h"
#ifdef USE_MUTEX
static CRITICAL_SECTION mutex;
#endif
static const char* driveletters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
/* Forward */
static int isAbsolutePath(const char* path);
/**************************************************/
int
ncp_win32_initialize()
{
int ret = 1;
#ifdef USE_MUTEX
InitializeCriticalSectionAndSpinCount(&mutex, 4000);
#endif
(void)SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
return ret;
}
int
ncp_win32_finalize()
{
#ifdef USE_MUTEX
DeleteCriticalSection(&mutex);
#endif
return 1;
}
/**************************************************/
#ifdef USE_MUTEX
static void lock(void) {EnterCriticalSection(&mutex);}
#else
#define lock()
#endif
#ifdef USE_MUTEX
static void unlock(void) {LeaveCriticalSection(&mutex);}
#else
#define unlock()
#endif
/**************************************************/
static int
init(NCPSharedLib* lib)
{
int ret = NC_NOERR;
return ret;
}
static int
reclaim(NCPSharedLib* lib)
{
int ret = NC_NOERR;
return ret;
}
static int
load(NCPSharedLib* lib , const char* path0, int flags)
{
int ret = NC_NOERR;
DWORD realflags = 0;
char* path = NULL;
path = NCpathcvt(path0);
if(path == NULL) {ret = NC_EINVAL; goto done;}
lock();
if(lib->state.handle != NULL)
{ret = NC_EEXIST; goto ldone;}
lib->path = nulldup(path);
lib->flags = flags;
if(isAbsolutePath(path)) realflags |= LOAD_WITH_ALTERED_SEARCH_PATH;
lib->state.flags = realflags;
lib->state.handle = LoadLibraryExA(path, 0, realflags);
if(lib->state.handle == NULL) {
int errcode = GetLastError();
char* msg = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &msg, 0, NULL);
if(msg) {
strncpy(lib->err.msg,msg,sizeof(lib->err.msg));
} else
lib->err.msg[0] = '\0';
ret = NC_ENOTFOUND;
goto ldone;
}
ldone:
unlock();
done:
nullfree(path);
return ret;
}
static int
unload(NCPSharedLib* lib)
{
int ret = NC_NOERR;
lock();
if(lib->state.handle != NULL) {
FreeLibrary((HMODULE)lib->state.handle);
lib->state.handle = NULL;
goto done;
}
done:
unlock();
return ret;
}
static int
isLoaded(NCPSharedLib* lib)
{
return lib->state.handle != NULL;
}
static void*
getsymbol(NCPSharedLib* lib, const char* name)
{
void* result = NULL;
lock();
if(lib->state.handle != NULL) {
result = (void*)GetProcAddress((HMODULE)lib->state.handle,name);
}
unlock();
return result;
}
static const char*
getpath(NCPSharedLib* lib)
{
return lib->path;
}
static int
isAbsolutePath(const char* path)
{
if(path == NULL || path[0] == '\0')
return 0;
if(strchr(driveletters,path[0]) != NULL
&& path[1] == ':'
&& (path[2] == '/' || path[2] == '\\'))
return 1;
if(path[0] == '/' || path[2] == '\\')
return 1;
return 0;
}
struct NCPAPI ncp_win32_api = {
init,
reclaim,
load,
unload,
isLoaded,
getsymbol,
getpath,
};
#endif /*_WIN32*/