summaryrefslogtreecommitdiffstats
path: root/src/port/win32dlopen.c
blob: da82c86fc54ebd60799d1d584776905cead4f17d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*-------------------------------------------------------------------------
 *
 * win32dlopen.c
 *	  dynamic loader for Windows
 *
 * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *	  src/port/win32dlopen.c
 *
 *-------------------------------------------------------------------------
 */

#include "c.h"

static char last_dyn_error[512];

static void
set_dl_error(void)
{
	DWORD		err = GetLastError();

	if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS |
					  FORMAT_MESSAGE_FROM_SYSTEM,
					  NULL,
					  err,
					  MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
					  last_dyn_error,
					  sizeof(last_dyn_error) - 1,
					  NULL) == 0)
	{
		snprintf(last_dyn_error, sizeof(last_dyn_error) - 1,
				 "unknown error %lu", err);
	}
}

char *
dlerror(void)
{
	if (last_dyn_error[0])
		return last_dyn_error;
	else
		return NULL;
}

int
dlclose(void *handle)
{
	if (!FreeLibrary((HMODULE) handle))
	{
		set_dl_error();
		return 1;
	}
	last_dyn_error[0] = 0;
	return 0;
}

void *
dlsym(void *handle, const char *symbol)
{
	void	   *ptr;

	ptr = GetProcAddress((HMODULE) handle, symbol);
	if (!ptr)
	{
		set_dl_error();
		return NULL;
	}
	last_dyn_error[0] = 0;
	return ptr;
}

void *
dlopen(const char *file, int mode)
{
	HMODULE		h;
	int			prevmode;

	/* Disable popup error messages when loading DLLs */
	prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
	h = LoadLibrary(file);
	SetErrorMode(prevmode);

	if (!h)
	{
		set_dl_error();
		return NULL;
	}
	last_dyn_error[0] = 0;
	return (void *) h;
}