Mercurial > pub > dyncall > dyncall
annotate dynload/dynload_windows.c @ 356:2f64957d6a46
- fix to dynload to build with musl libc (latter has dlinfo but not RTLD_SELF, so fallback to dl_iterate_phdr if on ELF targets)
author | Tassilo Philipp |
---|---|
date | Tue, 25 Feb 2020 16:07:45 +0100 |
parents | 655cafde0859 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 | |
3 Package: dyncall | |
4 Library: dynload | |
5 File: dynload/dynload_windows.c | |
6 Description: | |
7 License: | |
8 | |
350
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
9 Copyright (c) 2007-2020 Daniel Adler <dadler@uni-goettingen.de>, |
0 | 10 Tassilo Philipp <tphilipp@potion-studios.com> |
11 | |
12 Permission to use, copy, modify, and distribute this software for any | |
13 purpose with or without fee is hereby granted, provided that the above | |
14 copyright notice and this permission notice appear in all copies. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
23 | |
24 */ | |
25 | |
26 | |
27 | |
28 /* | |
29 | |
30 dynload_windows.c | |
31 | |
32 dynload module for .dll files | |
33 | |
34 */ | |
35 | |
36 | |
37 #include "dynload.h" | |
308 | 38 #include "dynload_alloc.h" |
0 | 39 |
40 #include <windows.h> | |
41 | |
229 | 42 |
0 | 43 DLLib* dlLoadLibrary(const char* libPath) |
44 { | |
308 | 45 if(libPath == NULL) |
46 return (DLLib*)GetModuleHandle(NULL); | |
47 else { | |
350
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
48 /* convert from UTF-8 to wide chars, so count required size */ |
308 | 49 DLLib* pLib; |
50 wchar_t* ws; | |
51 int r = MultiByteToWideChar(CP_UTF8, 0, libPath, -1, NULL, 0); | |
52 if(!r) { | |
53 return NULL; | |
54 } | |
55 | |
350
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
56 /* Reserve temp space with room for extra '.' suffix (see below) */ |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
57 ws = (wchar_t*)dlAllocMem((r+1) * sizeof(wchar_t)); |
308 | 58 if(!ws) |
59 return NULL; | |
60 | |
350
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
61 /* Convert path and add a '.' suffix, needed to tell windows not to add |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
62 .dll to any path that doesn't have it (see MS doc for LoadLibraryW). |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
63 This is to get same behaviour as on other platforms which don't do any |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
64 magic like this. Library search path behaviour stays unaffected, though */ |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
65 pLib = NULL; |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
66 if(MultiByteToWideChar(CP_UTF8, 0, libPath, -1, ws, r) == r) { |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
67 ws[r-1] = '.'; |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
68 ws[r] = 0; |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
69 pLib = (DLLib*)LoadLibraryW(ws); |
655cafde0859
- dynload/windows: dlLoadLibrary behaviour now more in line with other platforms by not trying to load provided path with .dll suffix
Tassilo Philipp
parents:
310
diff
changeset
|
70 } |
308 | 71 |
72 /* ... free temp space and return handle */ | |
73 dlFreeMem(ws); | |
74 return pLib; | |
75 } | |
0 | 76 } |
77 | |
242 | 78 |
79 void* dlFindSymbol(DLLib* pLib, const char* pSymbolName) | |
0 | 80 { |
242 | 81 return (void*)GetProcAddress((HINSTANCE)pLib, pSymbolName); |
0 | 82 } |
83 | |
242 | 84 |
85 void dlFreeLibrary(DLLib* pLib) | |
0 | 86 { |
242 | 87 FreeLibrary((HINSTANCE)pLib); |
0 | 88 } |
89 | |
242 | 90 |
91 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize) | |
92 { | |
308 | 93 /* get the path name as wide chars, then convert to UTF-8; we need */ |
94 /* some trial and error to figure out needed wide char string length */ | |
95 | |
96 wchar_t* ws; | |
97 int r; | |
98 | |
99 /* num chars to alloc temp space for, and upper limit, must be both power */ | |
100 /* of 2s for loop to be precise and to test allow testing up to 32768 chars */ | |
101 /* (including \0), which is the extended path ("\\?\...") maximum */ | |
102 static const int MAX_EXT_PATH = 1<<15; /* max extended path length (32768) */ | |
103 int nc = 1<<6; /* guess start buffer size, */ | |
104 | |
310 | 105 while(nc <= MAX_EXT_PATH)/*@@@ add testcode for super long paths*/ |
308 | 106 { |
107 ws = (wchar_t*)dlAllocMem(nc * sizeof(wchar_t)); | |
108 if(!ws) | |
109 break; | |
110 | |
111 r = GetModuleFileNameW((HMODULE)pLib, ws, nc); | |
112 | |
113 /* r == nc if string was truncated, double temp buffer size */ | |
114 if(r == nc) { | |
310 | 115 nc <<= 1; |
308 | 116 dlFreeMem(ws); |
117 continue; | |
118 } | |
119 /* error if r is 0 */ | |
120 else if(!r) { | |
121 dlFreeMem(ws); | |
122 break; | |
123 } | |
124 | |
125 /* check if output buffer is big enough */ | |
126 r = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL); | |
127 if(r <= bufSize) | |
128 r = WideCharToMultiByte(CP_UTF8, 0, ws, -1, sOut, bufSize, NULL, NULL); | |
129 | |
130 /* cleanup and return either size of copied bytes or needed buffer size */ | |
131 dlFreeMem(ws); | |
132 return r; | |
133 } | |
134 | |
135 return 0; | |
242 | 136 } |
137 |