@@ -6157,7 +6157,7 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryFromPath(LPCWSTR libraryPath, BOOL thr
6157
6157
6158
6158
// static
6159
6159
NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryByName (LPCWSTR libraryName, Assembly *callingAssembly,
6160
- BOOL hasDllImportSearchFlag , DWORD dllImportSearchFlag ,
6160
+ BOOL hasDllImportSearchFlags , DWORD dllImportSearchFlags ,
6161
6161
BOOL throwOnError)
6162
6162
{
6163
6163
CONTRACTL
@@ -6170,15 +6170,15 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryByName(LPCWSTR libraryName, Assembly *
6170
6170
6171
6171
LoadLibErrorTracker errorTracker;
6172
6172
6173
- // First checks if a default DllImportSearchPathFlag was passed in, if so, use that value.
6173
+ // First checks if a default dllImportSearchPathFlags was passed in, if so, use that value.
6174
6174
// Otherwise checks if the assembly has the DefaultDllImportSearchPathsAttribute attribute. If so, use that value.
6175
6175
BOOL searchAssemblyDirectory = TRUE ;
6176
- DWORD dllImportSearchPathFlag = 0 ;
6176
+ DWORD dllImportSearchPathFlags = 0 ;
6177
6177
6178
- if (hasDllImportSearchFlag )
6178
+ if (hasDllImportSearchFlags )
6179
6179
{
6180
- dllImportSearchPathFlag = dllImportSearchFlag & ~DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6181
- searchAssemblyDirectory = dllImportSearchFlag & DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6180
+ dllImportSearchPathFlags = dllImportSearchFlags & ~DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6181
+ searchAssemblyDirectory = dllImportSearchFlags & DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6182
6182
6183
6183
}
6184
6184
else
@@ -6187,13 +6187,13 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryByName(LPCWSTR libraryName, Assembly *
6187
6187
6188
6188
if (pModule->HasDefaultDllImportSearchPathsAttribute ())
6189
6189
{
6190
- dllImportSearchPathFlag = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6190
+ dllImportSearchPathFlags = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6191
6191
searchAssemblyDirectory = pModule->DllImportSearchAssemblyDirectory ();
6192
6192
}
6193
6193
}
6194
6194
6195
6195
NATIVE_LIBRARY_HANDLE hmod =
6196
- LoadLibraryModuleBySearch (callingAssembly, searchAssemblyDirectory, dllImportSearchPathFlag , &errorTracker, libraryName);
6196
+ LoadLibraryModuleBySearch (callingAssembly, searchAssemblyDirectory, dllImportSearchPathFlags , &errorTracker, libraryName);
6197
6197
6198
6198
if (throwOnError && (hmod == nullptr ))
6199
6199
{
@@ -6212,11 +6212,11 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(NDirectMethodDesc * pMD
6212
6212
// First checks if the method has DefaultDllImportSearchPathsAttribute. If so, use that value.
6213
6213
// Otherwise checks if the assembly has the attribute. If so, use that value.
6214
6214
BOOL searchAssemblyDirectory = TRUE ;
6215
- DWORD dllImportSearchPathFlag = 0 ;
6215
+ DWORD dllImportSearchPathFlags = 0 ;
6216
6216
6217
6217
if (pMD->HasDefaultDllImportSearchPathsAttribute ())
6218
6218
{
6219
- dllImportSearchPathFlag = pMD->DefaultDllImportSearchPathsAttributeCachedValue ();
6219
+ dllImportSearchPathFlags = pMD->DefaultDllImportSearchPathsAttributeCachedValue ();
6220
6220
searchAssemblyDirectory = pMD->DllImportSearchAssemblyDirectory ();
6221
6221
}
6222
6222
else
@@ -6225,13 +6225,13 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(NDirectMethodDesc * pMD
6225
6225
6226
6226
if (pModule->HasDefaultDllImportSearchPathsAttribute ())
6227
6227
{
6228
- dllImportSearchPathFlag = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6228
+ dllImportSearchPathFlags = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6229
6229
searchAssemblyDirectory = pModule->DllImportSearchAssemblyDirectory ();
6230
6230
}
6231
6231
}
6232
6232
6233
6233
Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6234
- return LoadLibraryModuleBySearch (pAssembly, searchAssemblyDirectory, dllImportSearchPathFlag , pErrorTracker, wszLibName);
6234
+ return LoadLibraryModuleBySearch (pAssembly, searchAssemblyDirectory, dllImportSearchPathFlags , pErrorTracker, wszLibName);
6235
6235
}
6236
6236
6237
6237
// static
@@ -6280,23 +6280,32 @@ INT_PTR NDirect::GetNativeLibraryExport(NATIVE_LIBRARY_HANDLE handle, LPCWSTR sy
6280
6280
return address;
6281
6281
}
6282
6282
6283
+ #ifndef PLATFORM_UNIX
6284
+ BOOL IsWindowsAPI (PCWSTR wszLibName)
6285
+ {
6286
+ // This is replicating quick check from the OS implementation of api sets.
6287
+ return SString::_wcsnicmp (wszLibName, W (" api-" ), 4 ) == 0 ||
6288
+ SString::_wcsnicmp (wszLibName, W (" ext-" ), 4 ) == 0 ;
6289
+ }
6290
+ #endif // !PLATFORM_UNIX
6291
+
6283
6292
// static
6284
- NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaHost (NDirectMethodDesc * pMD, AppDomain* pDomain, PCWSTR wszLibName)
6293
+ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaHost (NDirectMethodDesc * pMD, PCWSTR wszLibName)
6285
6294
{
6286
6295
STANDARD_VM_CONTRACT;
6287
6296
// Dynamic Pinvoke Support:
6288
6297
// Check if we need to provide the host a chance to provide the unmanaged dll
6289
6298
6290
6299
#ifndef PLATFORM_UNIX
6291
- // Prevent Overriding of Windows API sets.
6292
- // This is replicating quick check from the OS implementation of api sets.
6293
- if (SString::_wcsnicmp (wszLibName, W (" api-" ), 4 ) == 0 || SString::_wcsnicmp (wszLibName, W (" ext-" ), 4 ) == 0 )
6300
+ if (IsWindowsAPI (wszLibName))
6294
6301
{
6302
+ // Prevent Overriding of Windows API sets.
6295
6303
return NULL ;
6296
6304
}
6297
- #endif
6305
+ #endif // !PLATFORM_UNIX
6298
6306
6299
6307
LPVOID hmod = NULL ;
6308
+ AppDomain* pDomain = GetAppDomain ();
6300
6309
CLRPrivBinderCoreCLR *pTPABinder = pDomain->GetTPABinderContext ();
6301
6310
Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6302
6311
@@ -6362,6 +6371,55 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaHost(NDirectMethodDesc * pMD,
6362
6371
return (NATIVE_LIBRARY_HANDLE)hmod;
6363
6372
}
6364
6373
6374
+ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaCallBack (NDirectMethodDesc * pMD, LPCWSTR wszLibName)
6375
+ {
6376
+ #ifndef PLATFORM_UNIX
6377
+ if (IsWindowsAPI (wszLibName))
6378
+ {
6379
+ // Prevent Overriding of Windows API sets.
6380
+ return NULL ;
6381
+ }
6382
+ #endif // !PLATFORM_UNIX
6383
+
6384
+ DWORD dllImportSearchPathFlags = 0 ;
6385
+ BOOL hasDllImportSearchPathFlags = pMD->HasDefaultDllImportSearchPathsAttribute ();
6386
+ if (hasDllImportSearchPathFlags)
6387
+ {
6388
+ dllImportSearchPathFlags = pMD->DefaultDllImportSearchPathsAttributeCachedValue ();
6389
+ if (pMD->DllImportSearchAssemblyDirectory ())
6390
+ dllImportSearchPathFlags |= DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6391
+ }
6392
+
6393
+ GCX_COOP ();
6394
+
6395
+ struct {
6396
+ STRINGREF libNameRef;
6397
+ OBJECTREF assemblyRef;
6398
+ } protect;
6399
+
6400
+
6401
+ Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6402
+ protect.libNameRef = StringObject::NewString (wszLibName);
6403
+ protect.assemblyRef = pAssembly->GetExposedObject ();
6404
+
6405
+ NATIVE_LIBRARY_HANDLE handle = NULL ;
6406
+
6407
+ GCPROTECT_BEGIN (protect);
6408
+
6409
+ PREPARE_NONVIRTUAL_CALLSITE (METHOD__MARSHAL__LOADLIBRARYCALLBACKSTUB);
6410
+ DECLARE_ARGHOLDER_ARRAY (args, 4 );
6411
+ args[ARGNUM_0] = STRINGREF_TO_ARGHOLDER (protect.libNameRef );
6412
+ args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER (protect.assemblyRef );
6413
+ args[ARGNUM_2] = BOOL_TO_ARGHOLDER (hasDllImportSearchPathFlags);
6414
+ args[ARGNUM_3] = DWORD_TO_ARGHOLDER (dllImportSearchPathFlags);
6415
+
6416
+ // Make the call
6417
+ CALL_MANAGED_METHOD (handle, NATIVE_LIBRARY_HANDLE, args);
6418
+ GCPROTECT_END ();
6419
+
6420
+ return handle;
6421
+ }
6422
+
6365
6423
// Try to load the module alongside the assembly where the PInvoke was declared.
6366
6424
NATIVE_LIBRARY_HANDLE NDirect::LoadFromPInvokeAssemblyDirectory (Assembly *pAssembly, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
6367
6425
{
@@ -6385,11 +6443,12 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadFromPInvokeAssemblyDirectory(Assembly *pAssem
6385
6443
}
6386
6444
6387
6445
// Try to load the module from the native DLL search directories
6388
- NATIVE_LIBRARY_HANDLE NDirect::LoadFromNativeDllSearchDirectories (AppDomain* pDomain, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
6446
+ NATIVE_LIBRARY_HANDLE NDirect::LoadFromNativeDllSearchDirectories (LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
6389
6447
{
6390
6448
STANDARD_VM_CONTRACT;
6391
6449
6392
6450
NATIVE_LIBRARY_HANDLE hmod = NULL ;
6451
+ AppDomain* pDomain = GetAppDomain ();
6393
6452
6394
6453
if (pDomain->HasNativeDllSearchDirectories ())
6395
6454
{
@@ -6511,7 +6570,7 @@ static void DetermineLibNameVariations(const WCHAR** libNameVariations, int* num
6511
6570
// Search for the library and variants of its name in probing directories.
6512
6571
// static
6513
6572
NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch (Assembly *callingAssembly,
6514
- BOOL searchAssemblyDirectory, DWORD dllImportSearchPathFlag ,
6573
+ BOOL searchAssemblyDirectory, DWORD dllImportSearchPathFlags ,
6515
6574
LoadLibErrorTracker * pErrorTracker, LPCWSTR wszLibName)
6516
6575
{
6517
6576
STANDARD_VM_CONTRACT;
@@ -6521,7 +6580,7 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(Assembly *callingAssemb
6521
6580
#if defined(FEATURE_CORESYSTEM) && !defined(PLATFORM_UNIX)
6522
6581
// Try to go straight to System32 for Windows API sets. This is replicating quick check from
6523
6582
// the OS implementation of api sets.
6524
- if (SString::_wcsnicmp (wszLibName, W ( " api- " ), 4 ) == 0 || SString::_wcsnicmp (wszLibName, W ( " ext- " ), 4 ) == 0 )
6583
+ if (IsWindowsAPI (wszLibName) )
6525
6584
{
6526
6585
hmod = LocalLoadLibraryHelper (wszLibName, LOAD_LIBRARY_SEARCH_SYSTEM32, pErrorTracker);
6527
6586
if (hmod != NULL )
@@ -6549,7 +6608,7 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(Assembly *callingAssemb
6549
6608
currLibNameVariation.Printf (prefixSuffixCombinations[i], PLATFORM_SHARED_LIB_PREFIX_W, wszLibName, PLATFORM_SHARED_LIB_SUFFIX_W);
6550
6609
6551
6610
// NATIVE_DLL_SEARCH_DIRECTORIES set by host is considered well known path
6552
- hmod = LoadFromNativeDllSearchDirectories (pDomain, currLibNameVariation, loadWithAlteredPathFlags, pErrorTracker);
6611
+ hmod = LoadFromNativeDllSearchDirectories (currLibNameVariation, loadWithAlteredPathFlags, pErrorTracker);
6553
6612
if (hmod != NULL )
6554
6613
{
6555
6614
return hmod;
@@ -6558,11 +6617,11 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(Assembly *callingAssemb
6558
6617
if (!libNameIsRelativePath)
6559
6618
{
6560
6619
DWORD flags = loadWithAlteredPathFlags;
6561
- if ((dllImportSearchPathFlag & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) != 0 )
6620
+ if ((dllImportSearchPathFlags & LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR) != 0 )
6562
6621
{
6563
6622
// LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR is the only flag affecting absolute path. Don't OR the flags
6564
6623
// unconditionally as all absolute path P/Invokes could then lose LOAD_WITH_ALTERED_SEARCH_PATH.
6565
- flags |= dllImportSearchPathFlag ;
6624
+ flags |= dllImportSearchPathFlags ;
6566
6625
}
6567
6626
6568
6627
hmod = LocalLoadLibraryHelper (currLibNameVariation, flags, pErrorTracker);
@@ -6573,14 +6632,14 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(Assembly *callingAssemb
6573
6632
}
6574
6633
else if ((callingAssembly != nullptr ) && searchAssemblyDirectory)
6575
6634
{
6576
- hmod = LoadFromPInvokeAssemblyDirectory (callingAssembly, currLibNameVariation, loadWithAlteredPathFlags | dllImportSearchPathFlag , pErrorTracker);
6635
+ hmod = LoadFromPInvokeAssemblyDirectory (callingAssembly, currLibNameVariation, loadWithAlteredPathFlags | dllImportSearchPathFlags , pErrorTracker);
6577
6636
if (hmod != NULL )
6578
6637
{
6579
6638
return hmod;
6580
6639
}
6581
6640
}
6582
6641
6583
- hmod = LocalLoadLibraryHelper (currLibNameVariation, dllImportSearchPathFlag , pErrorTracker);
6642
+ hmod = LocalLoadLibraryHelper (currLibNameVariation, dllImportSearchPathFlags , pErrorTracker);
6584
6643
if (hmod != NULL )
6585
6644
{
6586
6645
return hmod;
@@ -6610,7 +6669,7 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(Assembly *callingAssemb
6610
6669
Assembly *pAssembly = spec.LoadAssembly (FILE_LOADED);
6611
6670
Module *pModule = pAssembly->FindModuleByName (szLibName);
6612
6671
6613
- hmod = LocalLoadLibraryHelper (pModule->GetPath (), loadWithAlteredPathFlags | dllImportSearchPathFlag , pErrorTracker);
6672
+ hmod = LocalLoadLibraryHelper (pModule->GetPath (), loadWithAlteredPathFlags | dllImportSearchPathFlags , pErrorTracker);
6614
6673
}
6615
6674
}
6616
6675
@@ -6631,19 +6690,28 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
6631
6690
if ( !name || !*name )
6632
6691
return NULL ;
6633
6692
6634
- ModuleHandleHolder hmod;
6635
6693
6636
6694
PREFIX_ASSUME ( name != NULL );
6637
6695
MAKE_WIDEPTR_FROMUTF8 ( wszLibName, name );
6638
6696
6697
+ ModuleHandleHolder hmod = LoadLibraryModuleViaCallBack (pMD, wszLibName);
6698
+ if (hmod != NULL )
6699
+ {
6700
+ #ifdef FEATURE_PAL
6701
+ // Register the system library handle with PAL and get a PAL library handle
6702
+ hmod = PAL_RegisterLibraryDirect (hmod, wszLibName);
6703
+ #endif // FEATURE_PAL
6704
+ return hmod.Extract ();
6705
+ }
6706
+
6639
6707
AppDomain* pDomain = GetAppDomain ();
6640
6708
6641
6709
// AssemblyLoadContext is not supported in AppX mode and thus,
6642
6710
// we should not perform PInvoke resolution via it when operating in
6643
6711
// AppX mode.
6644
6712
if (!AppX::IsAppXProcess ())
6645
6713
{
6646
- hmod = LoadLibraryModuleViaHost (pMD, pDomain, wszLibName);
6714
+ hmod = LoadLibraryModuleViaHost (pMD, wszLibName);
6647
6715
if (hmod != NULL )
6648
6716
{
6649
6717
#ifdef FEATURE_PAL
0 commit comments