51
51
#include " clr/fs/path.h"
52
52
using namespace clr ::fs;
53
53
54
- // The Bit 0x2 has different semantics in DllImportSearchPath and LoadLibraryExA flags.
55
- // In DllImportSearchPath enum, bit 0x2 represents SearchAssemblyDirectory -- which is performed by CLR.
56
- // Unlike other bits in this enum, this bit shouldn't be directly passed on to LoadLibrary()
57
- #define DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY 0x2
58
-
59
54
// remove when we get an updated SDK
60
55
#define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100
61
56
#define LOAD_LIBRARY_SEARCH_DEFAULT_DIRS 0x00001000
@@ -6127,6 +6122,57 @@ bool NDirect::s_fSecureLoadLibrarySupported = false;
6127
6122
#define PLATFORM_SHARED_LIB_PREFIX_W W (" " )
6128
6123
#endif // !FEATURE_PAL
6129
6124
6125
+ // The Bit 0x2 has different semantics in DllImportSearchPath and LoadLibraryExA flags.
6126
+ // In DllImportSearchPath enum, bit 0x2 represents SearchAssemblyDirectory -- which is performed by CLR.
6127
+ // Unlike other bits in this enum, this bit shouldn't be directly passed on to LoadLibrary()
6128
+ #define DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY 0x2
6129
+
6130
+ // DllImportSearchPathFlags is a special enumeration, whose values are tied closely with LoadLibrary flags.
6131
+ // There is no "default" value DllImportSearchPathFlags. In the absence of DllImportSearchPath attribute,
6132
+ // CoreCLR's LoadLibrary implementation uses the following defaults.
6133
+ // Other implementations of LoadLibrary callbacks/events are free to use other default conventions.
6134
+ void GetDefaultDllImportSearchPathFlags (DWORD *dllImportSearchPathFlags, BOOL *searchAssemblyDirectory)
6135
+ {
6136
+ STANDARD_VM_CONTRACT;
6137
+
6138
+ *searchAssemblyDirectory = TRUE ;
6139
+ *dllImportSearchPathFlags = 0 ;
6140
+ }
6141
+
6142
+ // If a module has the DllImportSearchPathAttribute, get DllImportSearchPathFlags from it, and return true.
6143
+ // Otherwise, get the default value for the flags, and return false.
6144
+ BOOL GetDllImportSearchPathFlags (Module *pModule, DWORD *dllImportSearchPathFlags, BOOL *searchAssemblyDirectory)
6145
+ {
6146
+ STANDARD_VM_CONTRACT;
6147
+
6148
+ if (pModule->HasDefaultDllImportSearchPathsAttribute ())
6149
+ {
6150
+ *dllImportSearchPathFlags = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6151
+ *searchAssemblyDirectory = pModule->DllImportSearchAssemblyDirectory ();
6152
+ return true ;
6153
+ }
6154
+
6155
+ GetDefaultDllImportSearchPathFlags (dllImportSearchPathFlags, searchAssemblyDirectory);
6156
+ return false ;
6157
+ }
6158
+
6159
+ // If a pInvoke has DllImportSearchPathAttribute, get DllImportSearchPathFlags from it, and returns true.
6160
+ // Otherwise, if the containing assembly has the DllImportSearchPathAttribute, get DllImportSearchPathFlags from it, and returns true.
6161
+ // Otherwise, return false (out parameters are untouched).
6162
+ BOOL GetDllImportSearchPathFlags (NDirectMethodDesc * pMD, DWORD *dllImportSearchPathFlags, BOOL *searchAssemblyDirectory)
6163
+ {
6164
+ STANDARD_VM_CONTRACT;
6165
+
6166
+ if (pMD->HasDefaultDllImportSearchPathsAttribute ())
6167
+ {
6168
+ *dllImportSearchPathFlags = pMD->DefaultDllImportSearchPathsAttributeCachedValue ();
6169
+ *searchAssemblyDirectory = pMD->DllImportSearchAssemblyDirectory ();
6170
+ return true ;
6171
+ }
6172
+
6173
+ return GetDllImportSearchPathFlags (pMD->GetModule (), dllImportSearchPathFlags, searchAssemblyDirectory);
6174
+ }
6175
+
6130
6176
// static
6131
6177
NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryFromPath (LPCWSTR libraryPath, BOOL throwOnError)
6132
6178
{
@@ -6165,25 +6211,21 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryByName(LPCWSTR libraryName, Assembly *
6165
6211
LoadLibErrorTracker errorTracker;
6166
6212
6167
6213
// First checks if a default dllImportSearchPathFlags was passed in, if so, use that value.
6168
- // Otherwise checks if the assembly has the DefaultDllImportSearchPathsAttribute attribute. If so, use that value.
6169
- BOOL searchAssemblyDirectory = TRUE ;
6170
- DWORD dllImportSearchPathFlags = 0 ;
6214
+ // Otherwise checks if the assembly has the DefaultDllImportSearchPathsAttribute attribute.
6215
+ // If so, use that value.
6216
+ BOOL searchAssemblyDirectory;
6217
+ DWORD dllImportSearchPathFlags;
6171
6218
6172
6219
if (hasDllImportSearchFlags)
6173
6220
{
6174
6221
dllImportSearchPathFlags = dllImportSearchFlags & ~DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6175
6222
searchAssemblyDirectory = dllImportSearchFlags & DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY;
6176
6223
6177
6224
}
6178
- else
6225
+ else
6179
6226
{
6180
- Module * pModule = callingAssembly->GetManifestModule ();
6181
-
6182
- if (pModule->HasDefaultDllImportSearchPathsAttribute ())
6183
- {
6184
- dllImportSearchPathFlags = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6185
- searchAssemblyDirectory = pModule->DllImportSearchAssemblyDirectory ();
6186
- }
6227
+ GetDllImportSearchPathFlags (callingAssembly->GetManifestModule (),
6228
+ &dllImportSearchPathFlags, &searchAssemblyDirectory);
6187
6229
}
6188
6230
6189
6231
NATIVE_LIBRARY_HANDLE hmod =
@@ -6203,26 +6245,10 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleBySearch(NDirectMethodDesc * pMD
6203
6245
{
6204
6246
STANDARD_VM_CONTRACT;
6205
6247
6206
- // First checks if the method has DefaultDllImportSearchPathsAttribute. If so, use that value.
6207
- // Otherwise checks if the assembly has the attribute. If so, use that value.
6208
- BOOL searchAssemblyDirectory = TRUE ;
6209
- DWORD dllImportSearchPathFlags = 0 ;
6248
+ BOOL searchAssemblyDirectory;
6249
+ DWORD dllImportSearchPathFlags;
6210
6250
6211
- if (pMD->HasDefaultDllImportSearchPathsAttribute ())
6212
- {
6213
- dllImportSearchPathFlags = pMD->DefaultDllImportSearchPathsAttributeCachedValue ();
6214
- searchAssemblyDirectory = pMD->DllImportSearchAssemblyDirectory ();
6215
- }
6216
- else
6217
- {
6218
- Module * pModule = pMD->GetModule ();
6219
-
6220
- if (pModule->HasDefaultDllImportSearchPathsAttribute ())
6221
- {
6222
- dllImportSearchPathFlags = pModule->DefaultDllImportSearchPathsAttributeCachedValue ();
6223
- searchAssemblyDirectory = pModule->DllImportSearchAssemblyDirectory ();
6224
- }
6225
- }
6251
+ GetDllImportSearchPathFlags (pMD, &dllImportSearchPathFlags, &searchAssemblyDirectory);
6226
6252
6227
6253
Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6228
6254
return LoadLibraryModuleBySearch (pAssembly, searchAssemblyDirectory, dllImportSearchPathFlags, pErrorTracker, wszLibName);
@@ -6452,18 +6478,20 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaCallback(NDirectMethodDesc *
6452
6478
{
6453
6479
STANDARD_VM_CONTRACT;
6454
6480
6455
- NATIVE_LIBRARY_HANDLE handle = NULL ;
6456
-
6457
- DWORD dllImportSearchPathFlags = 0 ;
6458
- BOOL hasDllImportSearchPathFlags = pMD->HasDefaultDllImportSearchPathsAttribute ();
6459
- if (hasDllImportSearchPathFlags)
6481
+ if (pMD->GetModule ()->IsSystem ())
6460
6482
{
6461
- dllImportSearchPathFlags = pMD-> DefaultDllImportSearchPathsAttributeCachedValue ();
6462
- if (pMD-> DllImportSearchAssemblyDirectory ())
6463
- dllImportSearchPathFlags |= DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY ;
6483
+ // Don't attempt to callback on Corelib itself.
6484
+ // The LoadLibrary callback stub is managed code that requires CoreLib
6485
+ return NULL ;
6464
6486
}
6465
6487
6488
+ DWORD dllImportSearchPathFlags;
6489
+ BOOL searchAssemblyDirectory;
6490
+ BOOL hasDllImportSearchPathFlags = GetDllImportSearchPathFlags (pMD, &dllImportSearchPathFlags, &searchAssemblyDirectory);
6491
+ dllImportSearchPathFlags |= searchAssemblyDirectory ? DLLIMPORTSEARCHPATH_ASSEMBLYDIRECTORY : 0 ;
6492
+
6466
6493
Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6494
+ NATIVE_LIBRARY_HANDLE handle = NULL ;
6467
6495
6468
6496
GCX_COOP ();
6469
6497
@@ -6491,87 +6519,6 @@ NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaCallback(NDirectMethodDesc *
6491
6519
return handle;
6492
6520
}
6493
6521
6494
- // Return the AssemblyLoadContext for an assembly
6495
- INT_PTR GetManagedAssemblyLoadContext (Assembly* pAssembly)
6496
- {
6497
- STANDARD_VM_CONTRACT;
6498
-
6499
- PTR_ICLRPrivBinder pBindingContext = pAssembly->GetManifestFile ()->GetBindingContext ();
6500
- if (pBindingContext == NULL )
6501
- {
6502
- // GetBindingContext() returns NULL for System.Private.CoreLib
6503
- return NULL ;
6504
- }
6505
-
6506
- UINT_PTR assemblyBinderID = 0 ;
6507
- IfFailThrow (pBindingContext->GetBinderID (&assemblyBinderID));
6508
-
6509
- AppDomain *pDomain = GetAppDomain ();
6510
- ICLRPrivBinder *pCurrentBinder = reinterpret_cast <ICLRPrivBinder *>(assemblyBinderID);
6511
-
6512
- #ifdef FEATURE_COMINTEROP
6513
- if (AreSameBinderInstance (pCurrentBinder, pDomain->GetWinRtBinder ()))
6514
- {
6515
- // No ALC associated handle with WinRT Binders.
6516
- return NULL ;
6517
- }
6518
- #endif // FEATURE_COMINTEROP
6519
-
6520
- // The code here deals with two implementations of ICLRPrivBinder interface:
6521
- // - CLRPrivBinderCoreCLR for the TPA binder in the default ALC, and
6522
- // - CLRPrivBinderAssemblyLoadContext for custom ALCs.
6523
- // in order obtain the associated ALC handle.
6524
- INT_PTR ptrManagedAssemblyLoadContext = AreSameBinderInstance (pCurrentBinder, pDomain->GetTPABinderContext ())
6525
- ? ((CLRPrivBinderCoreCLR *)pCurrentBinder)->GetManagedAssemblyLoadContext ()
6526
- : ((CLRPrivBinderAssemblyLoadContext *)pCurrentBinder)->GetManagedAssemblyLoadContext ();
6527
-
6528
- return ptrManagedAssemblyLoadContext;
6529
- }
6530
-
6531
- // static
6532
- NATIVE_LIBRARY_HANDLE NDirect::LoadLibraryModuleViaEvent (NDirectMethodDesc * pMD, PCWSTR wszLibName)
6533
- {
6534
- STANDARD_VM_CONTRACT;
6535
-
6536
- NATIVE_LIBRARY_HANDLE hmod = NULL ;
6537
- Assembly* pAssembly = pMD->GetMethodTable ()->GetAssembly ();
6538
- INT_PTR ptrManagedAssemblyLoadContext = GetManagedAssemblyLoadContext (pAssembly);
6539
-
6540
- if (ptrManagedAssemblyLoadContext == NULL )
6541
- {
6542
- return NULL ;
6543
- }
6544
-
6545
- GCX_COOP ();
6546
-
6547
- struct {
6548
- STRINGREF DllName;
6549
- OBJECTREF AssemblyRef;
6550
- } gc = { NULL , NULL };
6551
-
6552
- GCPROTECT_BEGIN (gc);
6553
-
6554
- gc.DllName = StringObject::NewString (wszLibName);
6555
- gc.AssemblyRef = pAssembly->GetExposedObject ();
6556
-
6557
- // Prepare to invoke System.Runtime.Loader.AssemblyLoadContext.ResolveUnmanagedDllUsingEvent method
6558
- // While ResolveUnmanagedDllUsingEvent() could compute the AssemblyLoadContext using the AssemblyRef
6559
- // argument, it will involve another pInvoke to the runtime. So AssemblyLoadContext is passed in
6560
- // as an additional argument.
6561
- PREPARE_NONVIRTUAL_CALLSITE (METHOD__ASSEMBLYLOADCONTEXT__RESOLVEUNMANAGEDDLLUSINGEVENT);
6562
- DECLARE_ARGHOLDER_ARRAY (args, 3 );
6563
- args[ARGNUM_0] = STRINGREF_TO_ARGHOLDER (gc.DllName );
6564
- args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER (gc.AssemblyRef );
6565
- args[ARGNUM_2] = PTR_TO_ARGHOLDER (ptrManagedAssemblyLoadContext);
6566
-
6567
- // Make the call
6568
- CALL_MANAGED_METHOD (hmod, NATIVE_LIBRARY_HANDLE, args);
6569
-
6570
- GCPROTECT_END ();
6571
-
6572
- return hmod;
6573
- }
6574
-
6575
6522
// Try to load the module alongside the assembly where the PInvoke was declared.
6576
6523
NATIVE_LIBRARY_HANDLE NDirect::LoadFromPInvokeAssemblyDirectory (Assembly *pAssembly, LPCWSTR libName, DWORD flags, LoadLibErrorTracker *pErrorTracker)
6577
6524
{
@@ -6842,7 +6789,7 @@ HINSTANCE NDirect::LoadLibraryModule(NDirectMethodDesc * pMD, LoadLibErrorTracke
6842
6789
if ( !name || !*name )
6843
6790
return NULL ;
6844
6791
6845
- PREFIX_ASSUME ( name != NULL );
6792
+ PREFIX_ASSUME ( name != NULL );
6846
6793
MAKE_WIDEPTR_FROMUTF8 ( wszLibName, name );
6847
6794
6848
6795
ModuleHandleHolder hmod = LoadLibraryModuleViaCallback (pMD, wszLibName);
0 commit comments