0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dynload
|
|
5 File: dynload/dynload_windows.c
|
|
6 Description:
|
|
7 License:
|
|
8
|
281
|
9 Copyright (c) 2007-2018 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 {
|
|
48 /* convert from UTF-8 to wide chars, so count required size... */
|
|
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
|
|
56 /* ... reserve temp space, ... */
|
|
57 ws = (wchar_t*)dlAllocMem(r * sizeof(wchar_t));
|
|
58 if(!ws)
|
|
59 return NULL;
|
|
60
|
|
61 /* ... convert (and use r as success flag), ... */
|
|
62 r = (MultiByteToWideChar(CP_UTF8, 0, libPath, -1, ws, r) == r);
|
310
|
63 pLib = (DLLib*)(r ? LoadLibraryW(ws) : NULL);
|
308
|
64
|
|
65 /* ... free temp space and return handle */
|
|
66 dlFreeMem(ws);
|
|
67 return pLib;
|
|
68 }
|
0
|
69 }
|
|
70
|
242
|
71
|
|
72 void* dlFindSymbol(DLLib* pLib, const char* pSymbolName)
|
0
|
73 {
|
242
|
74 return (void*)GetProcAddress((HINSTANCE)pLib, pSymbolName);
|
0
|
75 }
|
|
76
|
242
|
77
|
|
78 void dlFreeLibrary(DLLib* pLib)
|
0
|
79 {
|
242
|
80 FreeLibrary((HINSTANCE)pLib);
|
0
|
81 }
|
|
82
|
242
|
83
|
|
84 int dlGetLibraryPath(DLLib* pLib, char* sOut, int bufSize)
|
|
85 {
|
308
|
86 /* get the path name as wide chars, then convert to UTF-8; we need */
|
|
87 /* some trial and error to figure out needed wide char string length */
|
|
88
|
|
89 wchar_t* ws;
|
|
90 int r;
|
|
91
|
|
92 /* num chars to alloc temp space for, and upper limit, must be both power */
|
|
93 /* of 2s for loop to be precise and to test allow testing up to 32768 chars */
|
|
94 /* (including \0), which is the extended path ("\\?\...") maximum */
|
|
95 static const int MAX_EXT_PATH = 1<<15; /* max extended path length (32768) */
|
|
96 int nc = 1<<6; /* guess start buffer size, */
|
|
97
|
310
|
98 while(nc <= MAX_EXT_PATH)/*@@@ add testcode for super long paths*/
|
308
|
99 {
|
|
100 ws = (wchar_t*)dlAllocMem(nc * sizeof(wchar_t));
|
|
101 if(!ws)
|
|
102 break;
|
|
103
|
|
104 r = GetModuleFileNameW((HMODULE)pLib, ws, nc);
|
|
105
|
|
106 /* r == nc if string was truncated, double temp buffer size */
|
|
107 if(r == nc) {
|
310
|
108 nc <<= 1;
|
308
|
109 dlFreeMem(ws);
|
|
110 continue;
|
|
111 }
|
|
112 /* error if r is 0 */
|
|
113 else if(!r) {
|
|
114 dlFreeMem(ws);
|
|
115 break;
|
|
116 }
|
|
117
|
|
118 /* check if output buffer is big enough */
|
|
119 r = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL);
|
|
120 if(r <= bufSize)
|
|
121 r = WideCharToMultiByte(CP_UTF8, 0, ws, -1, sOut, bufSize, NULL, NULL);
|
|
122
|
|
123 /* cleanup and return either size of copied bytes or needed buffer size */
|
|
124 dlFreeMem(ws);
|
|
125 return r;
|
|
126 }
|
|
127
|
|
128 return 0;
|
242
|
129 }
|
|
130
|