@@ -60,47 +60,83 @@ SharedLibrary::~SharedLibrary()
60
60
}
61
61
62
62
Status
63
- SharedLibrary::SetLibraryDirectory (const std::string& path)
63
+ SharedLibrary::AddLibraryDirectory (
64
+ const std::string& path, void ** directory_cookie)
64
65
{
65
66
#ifdef _WIN32
66
- LOG_VERBOSE (1 ) << " SetLibraryDirectory : path = " << path;
67
+ LOG_VERBOSE (1 ) << " AddLibraryDirectory : path = " << path;
67
68
std::wstring wpath = LocalizedPath::GetWindowsValidPath (path);
68
- if (!SetDllDirectoryW (wpath.c_str ())) {
69
- LPSTR err_buffer = nullptr ;
70
- size_t size = FormatMessageA (
71
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
72
- FORMAT_MESSAGE_IGNORE_INSERTS,
73
- NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
74
- (LPSTR)&err_buffer, 0 , NULL );
75
- std::string errstr (err_buffer, size);
76
- LocalFree (err_buffer);
69
+ if (mAdditionalDependencyDirs .empty ()) {
70
+ *directory_cookie = nullptr ;
71
+ if (!SetDllDirectoryW (wpath.c_str ())) {
72
+ LPSTR err_buffer = nullptr ;
73
+ size_t size = FormatMessageA (
74
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
75
+ FORMAT_MESSAGE_IGNORE_INSERTS,
76
+ NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
77
+ (LPSTR)&err_buffer, 0 , NULL );
78
+ std::string errstr (err_buffer, size);
79
+ LocalFree (err_buffer);
77
80
78
- return Status (
79
- Status::Code::NOT_FOUND,
80
- " unable to set dll path " + path + " : " + errstr);
81
+ return Status (
82
+ Status::Code::NOT_FOUND,
83
+ " unable to set dll path " + path + " : " + errstr);
84
+ }
85
+ } else {
86
+ *directory_cookie = AddDllDirectory (wpath.c_str ());
87
+ if (*directory_cookie == nullptr ) {
88
+ LPSTR err_buffer = nullptr ;
89
+ size_t size = FormatMessageA (
90
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
91
+ FORMAT_MESSAGE_IGNORE_INSERTS,
92
+ NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
93
+ (LPSTR)&err_buffer, 0 , NULL );
94
+ std::string errstr (err_buffer, size);
95
+ LocalFree (err_buffer);
96
+
97
+ return Status (
98
+ Status::Code::NOT_FOUND,
99
+ " unable to add dll path " + path + " : " + errstr);
100
+ }
81
101
}
82
102
#endif
83
103
84
104
return Status::Success;
85
105
}
86
106
87
107
Status
88
- SharedLibrary::ResetLibraryDirectory ( )
108
+ SharedLibrary::RemoveLibraryDirectory ( void * directory_cookie )
89
109
{
90
110
#ifdef _WIN32
91
- LOG_VERBOSE (1 ) << " ResetLibraryDirectory" ;
92
- if (!SetDllDirectoryW (NULL )) {
93
- LPSTR err_buffer = nullptr ;
94
- size_t size = FormatMessageA (
95
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
96
- FORMAT_MESSAGE_IGNORE_INSERTS,
97
- NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
98
- (LPSTR)&err_buffer, 0 , NULL );
99
- std::string errstr (err_buffer, size);
100
- LocalFree (err_buffer);
111
+ LOG_VERBOSE (1 ) << " RemoveLibraryDirectory" ;
112
+ if (mAdditionalDependencyDirs .empty ()) {
113
+ if (!SetDllDirectoryW (NULL )) {
114
+ LPSTR err_buffer = nullptr ;
115
+ size_t size = FormatMessageA (
116
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
117
+ FORMAT_MESSAGE_IGNORE_INSERTS,
118
+ NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
119
+ (LPSTR)&err_buffer, 0 , NULL );
120
+ std::string errstr (err_buffer, size);
121
+ LocalFree (err_buffer);
101
122
102
- return Status (
103
- Status::Code::NOT_FOUND, " unable to reset dll path: " + errstr);
123
+ return Status (
124
+ Status::Code::NOT_FOUND, " unable to reset dll path: " + errstr);
125
+ }
126
+ } else {
127
+ if (!RemoveDllDirectory (directory_cookie)) {
128
+ LPSTR err_buffer = nullptr ;
129
+ size_t size = FormatMessageA (
130
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
131
+ FORMAT_MESSAGE_IGNORE_INSERTS,
132
+ NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
133
+ (LPSTR)&err_buffer, 0 , NULL );
134
+ std::string errstr (err_buffer, size);
135
+ LocalFree (err_buffer);
136
+
137
+ return Status (
138
+ Status::Code::NOT_FOUND, " unable to remove dll path: " + errstr);
139
+ }
104
140
}
105
141
#endif
106
142
@@ -126,17 +162,29 @@ SharedLibrary::OpenLibraryHandle(const std::string& path, void** handle)
126
162
// Need to put shared library directory on the DLL path so that any
127
163
// dependencies of the shared library are found
128
164
const std::string library_dir = DirName (path);
129
- RETURN_IF_ERROR (SetLibraryDirectory (library_dir));
165
+ void * directory_cookie = nullptr ;
166
+ RETURN_IF_ERROR (AddLibraryDirectory (library_dir, &directory_cookie));
130
167
131
168
// HMODULE is typedef of void*
132
169
// https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
133
170
LOG_VERBOSE (1 ) << " OpenLibraryHandle: path = " << path;
134
171
std::wstring wpath = LocalizedPath::GetWindowsValidPath (path);
135
- *handle = LoadLibraryW (wpath.c_str ());
172
+
173
+
174
+ RETURN_IF_ERROR (AddAdditionalDependencyDirs ());
175
+
176
+ uint32_t load_flags = 0x00000000 ;
177
+ if (!mAdditionalDirHandles .empty ()) {
178
+ load_flags =
179
+ LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS;
180
+ }
181
+ *handle = LoadLibraryExW (wpath.c_str (), NULL , load_flags);
182
+
183
+ RETURN_IF_ERROR (RemoveAdditionalDependencyDirs ());
136
184
137
185
// Remove the dll path added above... do this unconditionally before
138
186
// check for failure in dll load.
139
- RETURN_IF_ERROR (ResetLibraryDirectory ( ));
187
+ RETURN_IF_ERROR (RemoveLibraryDirectory (directory_cookie ));
140
188
141
189
if (*handle == nullptr ) {
142
190
LPSTR err_buffer = nullptr ;
@@ -244,59 +292,26 @@ SharedLibrary::GetEntrypoint(
244
292
return Status::Success;
245
293
}
246
294
295
+
247
296
Status
248
- SharedLibrary::AddAdditionalDependencyDir (
249
- const std::string& additional_path, std::wstring& original_path)
297
+ SharedLibrary::SetAdditionalDependencyDirs (const std::string& additional_path)
250
298
{
251
299
#ifdef _WIN32
252
- const std::wstring PATH (L" Path" );
253
-
254
300
if (additional_path.back () != ' ;' ) {
255
301
return Status (
256
302
Status::Code::INVALID_ARG,
257
303
" backend config parameter \" additional-dependency-dirs\" is malformed. "
258
304
" Each additional path provided should terminate with a ';'." );
259
305
}
260
306
261
- DWORD len = GetEnvironmentVariableW (PATH. c_str (), NULL , 0 ) ;
262
- if (len > 0 ) {
263
- original_path. resize (len);
264
- GetEnvironmentVariableW (PATH. c_str (), &original_path[ 0 ], len );
265
- } else {
266
- original_path = L" " ;
307
+ size_t pos = 0 , pos_end = 0 ;
308
+ std::string token;
309
+ while ((pos_end = additional_path. find ( ' ; ' , pos)) != std::string::npos) {
310
+ token = additional_path. substr (pos, pos_end - pos );
311
+ mAdditionalDependencyDirs . push_back (token);
312
+ pos = pos_end + 1 ;
267
313
}
268
314
269
- LOG_VERBOSE (1 ) << " Environment before extending PATH: "
270
- << std::string (original_path.begin (), original_path.end ());
271
-
272
- std::wstring updated_path_value =
273
- std::wstring (additional_path.begin (), additional_path.end ());
274
- updated_path_value += original_path;
275
-
276
- if (!SetEnvironmentVariableW (PATH.c_str (), updated_path_value.c_str ())) {
277
- LPSTR err_buffer = nullptr ;
278
- size_t size = FormatMessageA (
279
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
280
- FORMAT_MESSAGE_IGNORE_INSERTS,
281
- NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
282
- (LPSTR)&err_buffer, 0 , NULL );
283
- std::string errstr (err_buffer, size);
284
- LocalFree (err_buffer);
285
- return Status (
286
- Status::Code::INTERNAL,
287
- " failed to append user-provided directory to PATH " + errstr);
288
- }
289
-
290
- if (LOG_VERBOSE_IS_ON (1 )) {
291
- std::wstring path_after;
292
- len = GetEnvironmentVariableW (PATH.c_str (), NULL , 0 );
293
- if (len > 0 ) {
294
- path_after.resize (len);
295
- GetEnvironmentVariableW (PATH.c_str (), &path_after[0 ], len);
296
- }
297
- LOG_VERBOSE (1 ) << " Environment after extending PATH: "
298
- << std::string (path_after.begin (), path_after.end ());
299
- }
300
315
#else
301
316
LOG_WARNING
302
317
<< " The parameter \" additional-dependency-dirs\" has been specified but "
@@ -306,37 +321,49 @@ SharedLibrary::AddAdditionalDependencyDir(
306
321
return Status::Success;
307
322
}
308
323
324
+ #ifdef _WIN32
309
325
Status
310
- SharedLibrary::RemoveAdditionalDependencyDir ( const std::wstring& original_path )
326
+ SharedLibrary::AddAdditionalDependencyDirs ( )
311
327
{
312
- #ifdef _WIN32
313
- const std::wstring PATH (L" Path" );
314
- if (!SetEnvironmentVariableW (PATH.c_str (), original_path.c_str ())) {
315
- LPSTR err_buffer = nullptr ;
316
- size_t size = FormatMessageA (
317
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
318
- FORMAT_MESSAGE_IGNORE_INSERTS,
319
- NULL , GetLastError (), MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
320
- (LPSTR)&err_buffer, 0 , NULL );
321
- std::string errstr (err_buffer, size);
322
- LocalFree (err_buffer);
323
- return Status (
324
- Status::Code::INTERNAL,
325
- " failed to restore PATH to its original configuration " + errstr);
328
+ LOG_VERBOSE (1 ) << " Adding " << mAdditionalDependencyDirs .size ()
329
+ << " additional directories to search for dependencies" ;
330
+ for (auto it = mAdditionalDependencyDirs .begin ();
331
+ it != mAdditionalDependencyDirs .end (); it++) {
332
+ void * additional_dir_cookie = nullptr ;
333
+ RETURN_IF_ERROR (AddLibraryDirectory (*it, &additional_dir_cookie));
334
+ mAdditionalDirHandles .push_back (additional_dir_cookie);
326
335
}
327
336
328
- if (LOG_VERBOSE_IS_ON (1 )) {
329
- std::wstring path_after;
330
- DWORD len = GetEnvironmentVariableW (PATH.c_str (), NULL , 0 );
331
- if (len > 0 ) {
332
- path_after.resize (len);
333
- GetEnvironmentVariableW (PATH.c_str (), &path_after[0 ], len);
337
+ return Status::Success;
338
+ }
339
+
340
+ Status
341
+ SharedLibrary::RemoveAdditionalDependencyDirs ()
342
+ {
343
+ for (auto it = mAdditionalDirHandles .begin ();
344
+ it != mAdditionalDirHandles .end (); it++) {
345
+ if (*it == nullptr ) {
346
+ return Status (
347
+ Status::Code::INTERNAL,
348
+ " failed to remove a non-existent additional directory " );
349
+ }
350
+
351
+ if (RemoveDllDirectory (*it)) {
352
+ if (LOG_VERBOSE_IS_ON (1 )) {
353
+ LOG_VERBOSE (1 ) << " Removed an additional directory." ;
354
+ }
355
+ } else {
356
+ if (LOG_VERBOSE_IS_ON (1 )) {
357
+ LOG_VERBOSE (1 ) << " Failed to remove additional directory." ;
358
+ }
359
+ return Status (
360
+ Status::Code::INTERNAL, " unable to remove dependency directory" );
334
361
}
335
- LOG_VERBOSE (1 ) << " Environment after restoring PATH: "
336
- << std::string (path_after.begin (), path_after.end ());
337
362
}
338
- #endif
363
+ mAdditionalDirHandles .clear ();
364
+
339
365
return Status::Success;
340
366
}
367
+ #endif
341
368
342
369
}} // namespace triton::core
0 commit comments