/********************************************************************* * 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 #include #include #include #include #include #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*/