1 /*-------------------------------------------------------------------------
2  *
3  * mingwcompat.c
4  *	  MinGW compatibility functions
5  *
6  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
7  *
8  * IDENTIFICATION
9  *	  src/backend/port/win32/mingwcompat.c
10  *
11  *-------------------------------------------------------------------------
12  */
13 
14 #include "postgres.h"
15 
16 #ifndef _MSC_VER
17 /*
18  * MingW defines an extern to this struct, but the actual struct isn't present
19  * in any library. It's trivial enough that we can safely define it
20  * ourselves.
21  */
22 const struct in6_addr in6addr_any = {{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}};
23 
24 
25 /*
26  * This file contains loaders for functions that are missing in the MinGW
27  * import libraries. It's only for actual Win32 API functions, so they are
28  * all present in proper Win32 compilers.
29  */
30 static HMODULE kernel32 = NULL;
31 
32 /*
33  * Load DLL file just once regardless of how many functions
34  * we load/call in it.
35  */
36 static void
LoadKernel32()37 LoadKernel32()
38 {
39 	if (kernel32 != NULL)
40 		return;
41 
42 	kernel32 = LoadLibraryEx("kernel32.dll", NULL, 0);
43 	if (kernel32 == NULL)
44 		ereport(FATAL,
45 				(errmsg_internal("could not load kernel32.dll: error code %lu",
46 								 GetLastError())));
47 }
48 
49 
50 /*
51  * Replacement for RegisterWaitForSingleObject(), which lives in
52  * kernel32.dll
53  */
54 typedef
55 BOOL		(WINAPI * __RegisterWaitForSingleObject)
56 			(PHANDLE, HANDLE, WAITORTIMERCALLBACK, PVOID, ULONG, ULONG);
57 static __RegisterWaitForSingleObject _RegisterWaitForSingleObject = NULL;
58 
59 BOOL		WINAPI
RegisterWaitForSingleObject(PHANDLE phNewWaitObject,HANDLE hObject,WAITORTIMERCALLBACK Callback,PVOID Context,ULONG dwMilliseconds,ULONG dwFlags)60 RegisterWaitForSingleObject(PHANDLE phNewWaitObject,
61 							HANDLE hObject,
62 							WAITORTIMERCALLBACK Callback,
63 							PVOID Context,
64 							ULONG dwMilliseconds,
65 							ULONG dwFlags)
66 {
67 	if (_RegisterWaitForSingleObject == NULL)
68 	{
69 		LoadKernel32();
70 
71 		_RegisterWaitForSingleObject = (__RegisterWaitForSingleObject)
72 			GetProcAddress(kernel32, "RegisterWaitForSingleObject");
73 
74 		if (_RegisterWaitForSingleObject == NULL)
75 			ereport(FATAL,
76 					(errmsg_internal("could not locate RegisterWaitForSingleObject in kernel32.dll: error code %lu",
77 									 GetLastError())));
78 	}
79 
80 	return (_RegisterWaitForSingleObject)
81 		(phNewWaitObject, hObject, Callback, Context, dwMilliseconds, dwFlags);
82 }
83 
84 #endif
85