Remove always defined FEATURE_CORECLR
[platform/upstream/coreclr.git] / src / vm / assemblyname.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*============================================================
6 **
7 ** Header:  AssemblyName.cpp
8 **
9 ** Purpose: Implements AssemblyName (loader domain) architecture
10 **
11 **
12
13
14 **
15 ===========================================================*/
16
17 #include "common.h"
18
19 #include <stdlib.h>
20 #include <shlwapi.h>
21
22 #include "assemblyname.hpp"
23 #include "security.h"
24 #include "field.h"
25 #ifdef FEATURE_FUSION
26 #include "fusion.h"
27 #endif
28 #include "strongname.h"
29 #include "eeconfig.h"
30
31 #ifndef URL_ESCAPE_AS_UTF8
32 #define URL_ESCAPE_AS_UTF8              0x00040000  // Percent-encode all non-ASCII characters as their UTF-8 equivalents.
33 #endif 
34
35 FCIMPL1(Object*, AssemblyNameNative::GetFileInformation, StringObject* filenameUNSAFE)
36 {
37     FCALL_CONTRACT;
38
39     struct _gc
40     {
41         ASSEMBLYNAMEREF result;
42         STRINGREF       filename;
43     } gc;
44
45     gc.result   = NULL;
46     gc.filename = (STRINGREF) filenameUNSAFE;
47
48     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
49
50     if (gc.filename == NULL)
51         COMPlusThrow(kArgumentNullException, W("ArgumentNull_FileName"));
52
53     if (gc.filename->GetStringLength() == 0)
54         COMPlusThrow(kArgumentException, W("Argument_EmptyFileName"));
55
56     gc.result = (ASSEMBLYNAMEREF) AllocateObject(MscorlibBinder::GetClass(CLASS__ASSEMBLY_NAME));
57
58
59     ///////////////////////////////////////////////
60     SString sFileName(gc.filename->GetBuffer());
61     PEImageHolder pImage = PEImage::OpenImage(sFileName, MDInternalImport_NoCache);
62
63     EX_TRY
64     {
65         // Allow AssemblyLoadContext.GetAssemblyName for native images on CoreCLR
66         if (pImage->HasNTHeaders() && pImage->HasCorHeader() && pImage->HasNativeHeader())
67             pImage->VerifyIsNIAssembly();
68         else
69             pImage->VerifyIsAssembly();
70     }
71     EX_CATCH
72     {
73         Exception *ex = GET_EXCEPTION();
74         EEFileLoadException::Throw(sFileName,ex->GetHR(),ex);
75     }
76     EX_END_CATCH_UNREACHABLE;
77
78     SString sUrl = sFileName;
79     PEAssembly::PathToUrl(sUrl);
80
81     AssemblySpec spec;
82     spec.InitializeSpec(TokenFromRid(mdtAssembly,1),pImage->GetMDImport(),NULL,TRUE);
83     spec.AssemblyNameInit(&gc.result, pImage);
84     
85     HELPER_METHOD_FRAME_END();
86     return OBJECTREFToObject(gc.result);
87 }
88 FCIMPLEND
89
90 FCIMPL1(Object*, AssemblyNameNative::ToString, Object* refThisUNSAFE)
91 {
92     FCALL_CONTRACT;
93
94     OBJECTREF pObj          = NULL;
95     ASSEMBLYNAMEREF pThis   = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE;
96     HELPER_METHOD_FRAME_BEGIN_RET_1(pThis);
97
98     if (pThis == NULL)
99         COMPlusThrow(kNullReferenceException, W("NullReference_This"));
100
101     Thread *pThread = GetThread();
102
103     CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
104
105     AssemblySpec spec;
106     spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &pThis, FALSE, FALSE); 
107
108     StackSString name;
109 #ifndef FEATURE_FUSION
110     spec.GetFileOrDisplayName(ASM_DISPLAYF_VERSION |
111                               ASM_DISPLAYF_CULTURE |
112                               ASM_DISPLAYF_PUBLIC_KEY_TOKEN,
113                               name);
114 #else
115     spec.GetFileOrDisplayName(0, name);
116 #endif // FEATURE_FUSION
117
118     pObj = (OBJECTREF) StringObject::NewString(name);
119
120     HELPER_METHOD_FRAME_END();
121     return OBJECTREFToObject(pObj);
122 }
123 FCIMPLEND
124
125
126 FCIMPL1(Object*, AssemblyNameNative::GetPublicKeyToken, Object* refThisUNSAFE)
127 {
128     FCALL_CONTRACT;
129
130     OBJECTREF orOutputArray = NULL;
131     OBJECTREF refThis       = (OBJECTREF) refThisUNSAFE;
132     HELPER_METHOD_FRAME_BEGIN_RET_1(refThis);
133
134     if (refThis == NULL)
135         COMPlusThrow(kNullReferenceException, W("NullReference_This"));
136
137     ASSEMBLYNAMEREF orThis = (ASSEMBLYNAMEREF)refThis;
138     U1ARRAYREF orPublicKey = orThis->GetPublicKey();
139
140     if (orPublicKey != NULL) {
141         DWORD cb = orPublicKey->GetNumComponents();
142         StrongNameBufferHolder<BYTE> pbToken;
143
144         if (cb) {    
145             CQuickBytes qb;
146             BYTE *pbKey = (BYTE*) qb.AllocThrows(cb);
147             memcpy(pbKey, orPublicKey->GetDataPtr(), cb);
148
149             {
150                 GCX_PREEMP();
151                 if (!StrongNameTokenFromPublicKey(pbKey, cb, &pbToken, &cb))
152                     COMPlusThrowHR(StrongNameErrorInfo());
153             }
154         }
155
156         Security::CopyEncodingToByteArray(pbToken, cb, &orOutputArray);
157     }
158
159     HELPER_METHOD_FRAME_END();
160     return OBJECTREFToObject(orOutputArray);
161 }
162 FCIMPLEND
163
164
165 FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent)
166 {
167     FCALL_CONTRACT;
168
169     ASSEMBLYNAMEREF pThis = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE;
170     HRESULT hr = S_OK;
171     
172     HELPER_METHOD_FRAME_BEGIN_1(pThis);
173     
174     *pAssemblyRef = NULL;
175
176     if (pThis == NULL)
177         COMPlusThrow(kNullReferenceException, W("NullReference_This"));
178
179     Thread * pThread = GetThread();
180
181     CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
182
183     AssemblySpec spec;
184     hr = spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF *) &pThis, TRUE, FALSE); 
185
186     if (SUCCEEDED(hr))
187     {
188         spec.AssemblyNameInit(&pThis,NULL);
189     }
190     else if ((hr == FUSION_E_INVALID_NAME) && fRaiseResolveEvent)
191     {
192         Assembly * pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(&spec, fForIntrospection, FALSE);
193
194         if (pAssembly == NULL)
195         {
196             EEFileLoadException::Throw(&spec, hr);
197         }
198         else
199         {
200             *((OBJECTREF *) (&(*pAssemblyRef))) = pAssembly->GetExposedObject();
201         }
202     }
203     else
204     {
205         ThrowHR(hr);
206     }
207     
208     HELPER_METHOD_FRAME_END();
209 }
210 FCIMPLEND
211
212 /// "parse" tells us to parse the simple name of the assembly as if it was the full name
213 /// almost never the right thing to do, but needed for compat
214 /* static */
215 FCIMPL3(FC_BOOL_RET, AssemblyNameNative::ReferenceMatchesDefinition, AssemblyNameBaseObject* refUNSAFE, AssemblyNameBaseObject* defUNSAFE, CLR_BOOL fParse)
216 {
217     FCALL_CONTRACT;
218
219     struct _gc
220     {
221         ASSEMBLYNAMEREF pRef;
222         ASSEMBLYNAMEREF pDef;
223     } gc;
224     gc.pRef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (refUNSAFE);
225     gc.pDef = (ASSEMBLYNAMEREF)ObjectToOBJECTREF (defUNSAFE);
226
227     BOOL result = FALSE;
228     HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
229
230     Thread *pThread = GetThread();
231
232     CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease
233
234     if (gc.pRef == NULL)
235         COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName"));
236     if (gc.pDef == NULL)
237         COMPlusThrow(kArgumentNullException, W("ArgumentNull_AssemblyName"));
238
239     AssemblySpec refSpec;
240     refSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pRef, fParse, FALSE);
241
242     AssemblySpec defSpec;
243     defSpec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF*) &gc.pDef, fParse, FALSE);
244
245 #ifdef FEATURE_FUSION
246     SafeComHolder<IAssemblyName> pRefName (NULL);
247     IfFailThrow(refSpec.CreateFusionName(&pRefName, FALSE));
248
249     SafeComHolder <IAssemblyName> pDefName (NULL);
250     IfFailThrow(defSpec.CreateFusionName(&pDefName, FALSE));
251
252     // Order matters: Ref->IsEqual(Def)
253     result = (S_OK == pRefName->IsEqual(pDefName, ASM_CMPF_IL_ALL));
254 #else
255     result=AssemblySpec::RefMatchesDef(&refSpec,&defSpec);
256 #endif
257     HELPER_METHOD_FRAME_END();
258     FC_RETURN_BOOL(result);
259 }
260 FCIMPLEND