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 | // AssemblyMD.cpp |
6 | // |
7 | |
8 | // |
9 | // Implementation for the assembly meta data emit code (code:IMetaDataAssemblyEmit). |
10 | // |
11 | //***************************************************************************** |
12 | #include "stdafx.h" |
13 | #include "regmeta.h" |
14 | #include "mdutil.h" |
15 | #include "rwutil.h" |
16 | #include "mdlog.h" |
17 | #include "importhelper.h" |
18 | |
19 | #include <strongname.h> |
20 | |
21 | #ifdef _MSC_VER |
22 | #pragma warning(disable: 4102) |
23 | #endif |
24 | |
25 | #ifdef FEATURE_METADATA_EMIT |
26 | |
27 | //******************************************************************************* |
28 | // Define an Assembly and set the attributes. |
29 | //******************************************************************************* |
30 | STDMETHODIMP RegMeta::DefineAssembly( // S_OK or error. |
31 | const void *pbPublicKey, // [IN] Public key of the assembly. |
32 | ULONG cbPublicKey, // [IN] Count of bytes in the public key. |
33 | ULONG ulHashAlgId, // [IN] Hash Algorithm. |
34 | LPCWSTR szName, // [IN] Name of the assembly. |
35 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
36 | DWORD dwAssemblyFlags, // [IN] Flags. |
37 | mdAssembly *pma) // [OUT] Returned Assembly token. |
38 | { |
39 | HRESULT hr = S_OK; |
40 | |
41 | AssemblyRec *pRecord = NULL; // The assembly record. |
42 | ULONG iRecord; // RID of the assembly record. |
43 | |
44 | if (szName == NULL || pMetaData == NULL || pma == NULL) |
45 | return E_INVALIDARG; |
46 | |
47 | BEGIN_ENTRYPOINT_NOTHROW; |
48 | |
49 | LOG((LOGMD, "RegMeta::DefineAssembly(0x%08x, 0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x)\n" , |
50 | pbPublicKey, cbPublicKey, ulHashAlgId, MDSTR(szName), pMetaData, |
51 | dwAssemblyFlags, pma)); |
52 | |
53 | START_MD_PERF(); |
54 | LOCKWRITE(); |
55 | |
56 | _ASSERTE(szName && pMetaData && pma); |
57 | |
58 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
59 | |
60 | // Assembly defs always contain a full public key (assuming they're strong |
61 | // named) rather than the tokenized version. Force the flag on to indicate |
62 | // this, and this way blindly copying public key & flags from a def to a ref |
63 | // will work (though the ref will be bulkier than strictly necessary). |
64 | if (cbPublicKey != 0) |
65 | dwAssemblyFlags |= afPublicKey; |
66 | |
67 | if (CheckDups(MDDupAssembly)) |
68 | { // Should be no more than one -- just check count of records. |
69 | if (m_pStgdb->m_MiniMd.getCountAssemblys() > 0) |
70 | { // S/b only one, so we know the rid. |
71 | iRecord = 1; |
72 | // If ENC, let them update the existing record. |
73 | if (IsENCOn()) |
74 | IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRecord(iRecord, &pRecord)); |
75 | else |
76 | { // Not ENC, so it is a duplicate. |
77 | *pma = TokenFromRid(iRecord, mdtAssembly); |
78 | hr = META_S_DUPLICATE; |
79 | goto ErrExit; |
80 | } |
81 | } |
82 | } |
83 | else |
84 | { // Not ENC, not duplicate checking, so shouldn't already have one. |
85 | _ASSERTE(m_pStgdb->m_MiniMd.getCountAssemblys() == 0); |
86 | } |
87 | |
88 | // Create a new record, if needed. |
89 | if (pRecord == NULL) |
90 | { |
91 | IfFailGo(m_pStgdb->m_MiniMd.AddAssemblyRecord(&pRecord, &iRecord)); |
92 | } |
93 | |
94 | // Set the output parameter. |
95 | *pma = TokenFromRid(iRecord, mdtAssembly); |
96 | |
97 | IfFailGo(_SetAssemblyProps(*pma, pbPublicKey, cbPublicKey, ulHashAlgId, szName, pMetaData, dwAssemblyFlags)); |
98 | |
99 | ErrExit: |
100 | |
101 | STOP_MD_PERF(DefineAssembly); |
102 | END_ENTRYPOINT_NOTHROW; |
103 | |
104 | return hr; |
105 | } // RegMeta::DefineAssembly |
106 | |
107 | //******************************************************************************* |
108 | // Define an AssemblyRef and set the attributes. |
109 | //******************************************************************************* |
110 | STDMETHODIMP RegMeta::DefineAssemblyRef( // S_OK or error. |
111 | const void *pbPublicKeyOrToken, // [IN] Public key or token of the assembly. |
112 | ULONG cbPublicKeyOrToken, // [IN] Count of bytes in the public key or token. |
113 | LPCWSTR szName, // [IN] Name of the assembly being referenced. |
114 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
115 | const void *pbHashValue, // [IN] Hash Blob. |
116 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
117 | DWORD dwAssemblyRefFlags, // [IN] Flags. |
118 | mdAssemblyRef *pmar) // [OUT] Returned AssemblyRef token. |
119 | { |
120 | HRESULT hr = S_OK; |
121 | |
122 | AssemblyRefRec *pRecord = NULL; |
123 | ULONG iRecord; |
124 | |
125 | if (szName == NULL || pmar == NULL || pMetaData == NULL) |
126 | return E_INVALIDARG; |
127 | |
128 | BEGIN_ENTRYPOINT_NOTHROW; |
129 | |
130 | LOG((LOGMD, "RegMeta::DefineAssemblyRef(0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n" , |
131 | pbPublicKeyOrToken, cbPublicKeyOrToken, MDSTR(szName), pMetaData, pbHashValue, |
132 | cbHashValue, dwAssemblyRefFlags, pmar)); |
133 | |
134 | START_MD_PERF(); |
135 | LOCKWRITE(); |
136 | |
137 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
138 | |
139 | _ASSERTE(szName && pmar); |
140 | |
141 | if (CheckDups(MDDupAssemblyRef)) |
142 | { |
143 | LPUTF8 szUTF8Name, szUTF8Locale; |
144 | UTF8STR(szName, szUTF8Name); |
145 | UTF8STR(pMetaData->szLocale, szUTF8Locale); |
146 | hr = ImportHelper::FindAssemblyRef(&m_pStgdb->m_MiniMd, |
147 | szUTF8Name, |
148 | szUTF8Locale, |
149 | pbPublicKeyOrToken, |
150 | cbPublicKeyOrToken, |
151 | pMetaData->usMajorVersion, |
152 | pMetaData->usMinorVersion, |
153 | pMetaData->usBuildNumber, |
154 | pMetaData->usRevisionNumber, |
155 | dwAssemblyRefFlags, |
156 | pmar); |
157 | if (SUCCEEDED(hr)) |
158 | { |
159 | if (IsENCOn()) |
160 | { |
161 | IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRefRecord(RidFromToken(*pmar), &pRecord)); |
162 | } |
163 | else |
164 | { |
165 | hr = META_S_DUPLICATE; |
166 | goto ErrExit; |
167 | } |
168 | } |
169 | else if (hr != CLDB_E_RECORD_NOTFOUND) |
170 | { |
171 | IfFailGo(hr); |
172 | } |
173 | } |
174 | |
175 | // Create a new record if needed. |
176 | if (pRecord == NULL) |
177 | { |
178 | // Create a new record. |
179 | IfFailGo(m_pStgdb->m_MiniMd.AddAssemblyRefRecord(&pRecord, &iRecord)); |
180 | |
181 | // Set the output parameter. |
182 | *pmar = TokenFromRid(iRecord, mdtAssemblyRef); |
183 | } |
184 | |
185 | // Set rest of the attributes. |
186 | SetCallerDefine(); |
187 | IfFailGo(_SetAssemblyRefProps(*pmar, pbPublicKeyOrToken, cbPublicKeyOrToken, szName, pMetaData, |
188 | pbHashValue, cbHashValue, |
189 | dwAssemblyRefFlags)); |
190 | ErrExit: |
191 | SetCallerExternal(); |
192 | |
193 | STOP_MD_PERF(DefineAssemblyRef); |
194 | END_ENTRYPOINT_NOTHROW; |
195 | |
196 | return hr; |
197 | } // RegMeta::DefineAssemblyRef |
198 | |
199 | //******************************************************************************* |
200 | // Define a File and set the attributes. |
201 | //******************************************************************************* |
202 | STDMETHODIMP RegMeta::DefineFile( // S_OK or error. |
203 | LPCWSTR szName, // [IN] Name of the file. |
204 | const void *pbHashValue, // [IN] Hash Blob. |
205 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
206 | DWORD dwFileFlags, // [IN] Flags. |
207 | mdFile *pmf) // [OUT] Returned File token. |
208 | { |
209 | HRESULT hr = S_OK; |
210 | |
211 | BEGIN_ENTRYPOINT_NOTHROW; |
212 | |
213 | FileRec *pRecord = NULL; |
214 | ULONG iRecord; |
215 | |
216 | LOG((LOGMD, "RegMeta::DefineFile(%S, %#08x, %#08x, %#08x, %#08x)\n" , |
217 | MDSTR(szName), pbHashValue, cbHashValue, dwFileFlags, pmf)); |
218 | |
219 | START_MD_PERF(); |
220 | LOCKWRITE(); |
221 | |
222 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
223 | |
224 | _ASSERTE(szName && pmf); |
225 | |
226 | if (CheckDups(MDDupFile)) |
227 | { |
228 | LPUTF8 szUTF8Name; |
229 | UTF8STR(szName, szUTF8Name); |
230 | hr = ImportHelper::FindFile(&m_pStgdb->m_MiniMd, szUTF8Name, pmf); |
231 | if (SUCCEEDED(hr)) |
232 | { |
233 | if (IsENCOn()) |
234 | { |
235 | IfFailGo(m_pStgdb->m_MiniMd.GetFileRecord(RidFromToken(*pmf), &pRecord)); |
236 | } |
237 | else |
238 | { |
239 | hr = META_S_DUPLICATE; |
240 | goto ErrExit; |
241 | } |
242 | } |
243 | else if (hr != CLDB_E_RECORD_NOTFOUND) |
244 | { |
245 | IfFailGo(hr); |
246 | } |
247 | } |
248 | |
249 | // Create a new record if needed. |
250 | if (pRecord == NULL) |
251 | { |
252 | // Create a new record. |
253 | IfFailGo(m_pStgdb->m_MiniMd.AddFileRecord(&pRecord, &iRecord)); |
254 | |
255 | // Set the output parameter. |
256 | *pmf = TokenFromRid(iRecord, mdtFile); |
257 | |
258 | // Set the name. |
259 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_File, FileRec::COL_Name, pRecord, szName)); |
260 | } |
261 | |
262 | // Set rest of the attributes. |
263 | IfFailGo(_SetFileProps(*pmf, pbHashValue, cbHashValue, dwFileFlags)); |
264 | ErrExit: |
265 | |
266 | STOP_MD_PERF(DefineFile); |
267 | END_ENTRYPOINT_NOTHROW; |
268 | |
269 | return hr; |
270 | } // RegMeta::DefineFile |
271 | |
272 | //******************************************************************************* |
273 | // Define a ExportedType and set the attributes. |
274 | //******************************************************************************* |
275 | STDMETHODIMP RegMeta::DefineExportedType( // S_OK or error. |
276 | LPCWSTR szName, // [IN] Name of the Com Type. |
277 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType. |
278 | mdTypeDef tkTypeDef, // [IN] TypeDef token within the file. |
279 | DWORD dwExportedTypeFlags, // [IN] Flags. |
280 | mdExportedType *pmct) // [OUT] Returned ExportedType token. |
281 | { |
282 | HRESULT hr = S_OK; |
283 | |
284 | BEGIN_ENTRYPOINT_NOTHROW; |
285 | |
286 | ExportedTypeRec *pRecord = NULL; |
287 | ULONG iRecord; |
288 | LPSTR szNameUTF8; |
289 | LPCSTR szTypeNameUTF8; |
290 | LPCSTR szTypeNamespaceUTF8; |
291 | |
292 | LOG((LOGMD, "RegMeta::DefineExportedType(%S, %#08x, %08x, %#08x, %#08x)\n" , |
293 | MDSTR(szName), tkImplementation, tkTypeDef, |
294 | dwExportedTypeFlags, pmct)); |
295 | |
296 | START_MD_PERF(); |
297 | LOCKWRITE(); |
298 | |
299 | // Validate name for prefix. |
300 | if (szName == NULL) |
301 | IfFailGo(E_INVALIDARG); |
302 | |
303 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
304 | |
305 | //SLASHES2DOTS_NAMESPACE_BUFFER_UNICODE(szName, szName); |
306 | |
307 | UTF8STR(szName, szNameUTF8); |
308 | // Split the name into name/namespace pair. |
309 | ns::SplitInline(szNameUTF8, szTypeNamespaceUTF8, szTypeNameUTF8); |
310 | |
311 | _ASSERTE(szName && dwExportedTypeFlags != ULONG_MAX && pmct); |
312 | _ASSERTE(TypeFromToken(tkImplementation) == mdtFile || |
313 | TypeFromToken(tkImplementation) == mdtAssemblyRef || |
314 | TypeFromToken(tkImplementation) == mdtExportedType || |
315 | tkImplementation == mdTokenNil); |
316 | |
317 | if (CheckDups(MDDupExportedType)) |
318 | { |
319 | hr = ImportHelper::FindExportedType(&m_pStgdb->m_MiniMd, |
320 | szTypeNamespaceUTF8, |
321 | szTypeNameUTF8, |
322 | tkImplementation, |
323 | pmct); |
324 | if (SUCCEEDED(hr)) |
325 | { |
326 | if (IsENCOn()) |
327 | { |
328 | IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(*pmct), &pRecord)); |
329 | } |
330 | else |
331 | { |
332 | hr = META_S_DUPLICATE; |
333 | goto ErrExit; |
334 | } |
335 | } |
336 | else if (hr != CLDB_E_RECORD_NOTFOUND) |
337 | { |
338 | IfFailGo(hr); |
339 | } |
340 | } |
341 | |
342 | // Create a new record if needed. |
343 | if (pRecord == NULL) |
344 | { |
345 | // Create a new record. |
346 | IfFailGo(m_pStgdb->m_MiniMd.AddExportedTypeRecord(&pRecord, &iRecord)); |
347 | |
348 | // Set the output parameter. |
349 | *pmct = TokenFromRid(iRecord, mdtExportedType); |
350 | |
351 | // Set the TypeName and TypeNamespace. |
352 | IfFailGo(m_pStgdb->m_MiniMd.PutString(TBL_ExportedType, |
353 | ExportedTypeRec::COL_TypeName, pRecord, szTypeNameUTF8)); |
354 | if (szTypeNamespaceUTF8) |
355 | { |
356 | IfFailGo(m_pStgdb->m_MiniMd.PutString(TBL_ExportedType, |
357 | ExportedTypeRec::COL_TypeNamespace, pRecord, szTypeNamespaceUTF8)); |
358 | } |
359 | } |
360 | |
361 | // Set rest of the attributes. |
362 | IfFailGo(_SetExportedTypeProps(*pmct, tkImplementation, tkTypeDef, |
363 | dwExportedTypeFlags)); |
364 | ErrExit: |
365 | |
366 | STOP_MD_PERF(DefineExportedType); |
367 | END_ENTRYPOINT_NOTHROW; |
368 | |
369 | return hr; |
370 | } // RegMeta::DefineExportedType |
371 | |
372 | //******************************************************************************* |
373 | // Define a Resource and set the attributes. |
374 | //******************************************************************************* |
375 | STDMETHODIMP RegMeta::DefineManifestResource( // S_OK or error. |
376 | LPCWSTR szName, // [IN] Name of the ManifestResource. |
377 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. |
378 | DWORD dwOffset, // [IN] Offset to the beginning of the resource within the file. |
379 | DWORD dwResourceFlags, // [IN] Flags. |
380 | mdManifestResource *pmmr) // [OUT] Returned ManifestResource token. |
381 | { |
382 | HRESULT hr = S_OK; |
383 | |
384 | BEGIN_ENTRYPOINT_NOTHROW; |
385 | |
386 | ManifestResourceRec *pRecord = NULL; |
387 | ULONG iRecord; |
388 | |
389 | LOG((LOGMD, "RegMeta::DefineManifestResource(%S, %#08x, %#08x, %#08x, %#08x)\n" , |
390 | MDSTR(szName), tkImplementation, dwOffset, dwResourceFlags, pmmr)); |
391 | |
392 | START_MD_PERF(); |
393 | LOCKWRITE(); |
394 | |
395 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
396 | |
397 | _ASSERTE(szName && dwResourceFlags != ULONG_MAX && pmmr); |
398 | _ASSERTE(TypeFromToken(tkImplementation) == mdtFile || |
399 | TypeFromToken(tkImplementation) == mdtAssemblyRef || |
400 | tkImplementation == mdTokenNil); |
401 | |
402 | if (CheckDups(MDDupManifestResource)) |
403 | { |
404 | LPUTF8 szUTF8Name; |
405 | UTF8STR(szName, szUTF8Name); |
406 | hr = ImportHelper::FindManifestResource(&m_pStgdb->m_MiniMd, szUTF8Name, pmmr); |
407 | if (SUCCEEDED(hr)) |
408 | { |
409 | if (IsENCOn()) |
410 | { |
411 | IfFailGo(m_pStgdb->m_MiniMd.GetManifestResourceRecord(RidFromToken(*pmmr), &pRecord)); |
412 | } |
413 | else |
414 | { |
415 | hr = META_S_DUPLICATE; |
416 | goto ErrExit; |
417 | } |
418 | } |
419 | else if (hr != CLDB_E_RECORD_NOTFOUND) |
420 | { |
421 | IfFailGo(hr); |
422 | } |
423 | } |
424 | |
425 | // Create a new record if needed. |
426 | if (pRecord == NULL) |
427 | { |
428 | // Create a new record. |
429 | IfFailGo(m_pStgdb->m_MiniMd.AddManifestResourceRecord(&pRecord, &iRecord)); |
430 | |
431 | // Set the output parameter. |
432 | *pmmr = TokenFromRid(iRecord, mdtManifestResource); |
433 | |
434 | // Set the name. |
435 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_ManifestResource, |
436 | ManifestResourceRec::COL_Name, pRecord, szName)); |
437 | } |
438 | |
439 | // Set the rest of the attributes. |
440 | IfFailGo(_SetManifestResourceProps(*pmmr, tkImplementation, |
441 | dwOffset, dwResourceFlags)); |
442 | |
443 | ErrExit: |
444 | |
445 | STOP_MD_PERF(DefineManifestResource); |
446 | END_ENTRYPOINT_NOTHROW; |
447 | |
448 | return hr; |
449 | } // RegMeta::DefineManifestResource |
450 | |
451 | //******************************************************************************* |
452 | // Set the specified attributes on the given Assembly token. |
453 | //******************************************************************************* |
454 | STDMETHODIMP RegMeta::SetAssemblyProps( // S_OK or error. |
455 | mdAssembly ma, // [IN] Assembly token. |
456 | const void *pbPublicKey, // [IN] Public key of the assembly. |
457 | ULONG cbPublicKey, // [IN] Count of bytes in the public key. |
458 | ULONG ulHashAlgId, // [IN] Hash Algorithm. |
459 | LPCWSTR szName, // [IN] Name of the assembly. |
460 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
461 | DWORD dwAssemblyFlags) // [IN] Flags. |
462 | { |
463 | HRESULT hr = S_OK; |
464 | |
465 | BEGIN_ENTRYPOINT_NOTHROW; |
466 | |
467 | _ASSERTE(TypeFromToken(ma) == mdtAssembly && RidFromToken(ma)); |
468 | |
469 | LOG((LOGMD, "RegMeta::SetAssemblyProps(%#08x, %#08x, %#08x, %#08x %S, %#08x, %#08x)\n" , |
470 | ma, pbPublicKey, cbPublicKey, ulHashAlgId, MDSTR(szName), pMetaData, dwAssemblyFlags)); |
471 | |
472 | START_MD_PERF(); |
473 | LOCKWRITE(); |
474 | |
475 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
476 | |
477 | IfFailGo(_SetAssemblyProps(ma, pbPublicKey, cbPublicKey, ulHashAlgId, szName, pMetaData, dwAssemblyFlags)); |
478 | |
479 | ErrExit: |
480 | STOP_MD_PERF(SetAssemblyProps); |
481 | END_ENTRYPOINT_NOTHROW; |
482 | |
483 | return hr; |
484 | } // STDMETHODIMP SetAssemblyProps() |
485 | |
486 | //******************************************************************************* |
487 | // Set the specified attributes on the given AssemblyRef token. |
488 | //******************************************************************************* |
489 | STDMETHODIMP RegMeta::SetAssemblyRefProps( // S_OK or error. |
490 | mdAssemblyRef ar, // [IN] AssemblyRefToken. |
491 | const void *pbPublicKeyOrToken, // [IN] Public key or token of the assembly. |
492 | ULONG cbPublicKeyOrToken, // [IN] Count of bytes in the public key or token. |
493 | LPCWSTR szName, // [IN] Name of the assembly being referenced. |
494 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
495 | const void *pbHashValue, // [IN] Hash Blob. |
496 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
497 | DWORD dwAssemblyRefFlags) // [IN] Flags. |
498 | { |
499 | HRESULT hr = S_OK; |
500 | |
501 | BEGIN_ENTRYPOINT_NOTHROW; |
502 | |
503 | _ASSERTE(TypeFromToken(ar) == mdtAssemblyRef && RidFromToken(ar)); |
504 | |
505 | LOG((LOGMD, "RegMeta::SetAssemblyRefProps(0x%08x, 0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n" , |
506 | ar, pbPublicKeyOrToken, cbPublicKeyOrToken, MDSTR(szName), pMetaData, pbHashValue, cbHashValue, |
507 | dwAssemblyRefFlags)); |
508 | |
509 | START_MD_PERF(); |
510 | LOCKWRITE(); |
511 | |
512 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
513 | |
514 | IfFailGo(_SetAssemblyRefProps( |
515 | ar, |
516 | pbPublicKeyOrToken, |
517 | cbPublicKeyOrToken, |
518 | szName, |
519 | pMetaData, |
520 | pbHashValue, |
521 | cbHashValue, |
522 | dwAssemblyRefFlags)); |
523 | |
524 | ErrExit: |
525 | STOP_MD_PERF(SetAssemblyRefProps); |
526 | END_ENTRYPOINT_NOTHROW; |
527 | |
528 | return hr; |
529 | } // RegMeta::SetAssemblyRefProps |
530 | |
531 | //******************************************************************************* |
532 | // Set the specified attributes on the given File token. |
533 | //******************************************************************************* |
534 | STDMETHODIMP RegMeta::SetFileProps( // S_OK or error. |
535 | mdFile file, // [IN] File token. |
536 | const void *pbHashValue, // [IN] Hash Blob. |
537 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
538 | DWORD dwFileFlags) // [IN] Flags. |
539 | { |
540 | HRESULT hr = S_OK; |
541 | |
542 | BEGIN_ENTRYPOINT_NOTHROW; |
543 | |
544 | |
545 | _ASSERTE(TypeFromToken(file) == mdtFile && RidFromToken(file)); |
546 | |
547 | LOG((LOGMD, "RegMeta::SetFileProps(%#08x, %#08x, %#08x, %#08x)\n" , |
548 | file, pbHashValue, cbHashValue, dwFileFlags)); |
549 | START_MD_PERF(); |
550 | LOCKWRITE(); |
551 | |
552 | IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); |
553 | |
554 | IfFailGo( _SetFileProps(file, pbHashValue, cbHashValue, dwFileFlags) ); |
555 | |
556 | ErrExit: |
557 | |
558 | STOP_MD_PERF(SetFileProps); |
559 | END_ENTRYPOINT_NOTHROW; |
560 | |
561 | return hr; |
562 | } // RegMeta::SetFileProps |
563 | |
564 | //******************************************************************************* |
565 | // Set the specified attributes on the given ExportedType token. |
566 | //******************************************************************************* |
567 | STDMETHODIMP RegMeta::SetExportedTypeProps( // S_OK or error. |
568 | mdExportedType ct, // [IN] ExportedType token. |
569 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType. |
570 | mdTypeDef tkTypeDef, // [IN] TypeDef token within the file. |
571 | DWORD dwExportedTypeFlags) // [IN] Flags. |
572 | { |
573 | HRESULT hr = S_OK; |
574 | |
575 | BEGIN_ENTRYPOINT_NOTHROW; |
576 | |
577 | |
578 | LOG((LOGMD, "RegMeta::SetExportedTypeProps(%#08x, %#08x, %#08x, %#08x)\n" , |
579 | ct, tkImplementation, tkTypeDef, dwExportedTypeFlags)); |
580 | |
581 | START_MD_PERF(); |
582 | LOCKWRITE(); |
583 | |
584 | IfFailGo( _SetExportedTypeProps( ct, tkImplementation, tkTypeDef, dwExportedTypeFlags) ); |
585 | |
586 | ErrExit: |
587 | |
588 | STOP_MD_PERF(SetExportedTypeProps); |
589 | END_ENTRYPOINT_NOTHROW; |
590 | |
591 | return hr; |
592 | } // RegMeta::SetExportedTypeProps |
593 | |
594 | //******************************************************************************* |
595 | // Set the specified attributes on the given ManifestResource token. |
596 | //******************************************************************************* |
597 | STDMETHODIMP RegMeta::SetManifestResourceProps(// S_OK or error. |
598 | mdManifestResource mr, // [IN] ManifestResource token. |
599 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. |
600 | DWORD dwOffset, // [IN] Offset to the beginning of the resource within the file. |
601 | DWORD dwResourceFlags) // [IN] Flags. |
602 | { |
603 | HRESULT hr = S_OK; |
604 | |
605 | BEGIN_ENTRYPOINT_NOTHROW; |
606 | |
607 | LOG((LOGMD, "RegMeta::SetManifestResourceProps(%#08x, %#08x, %#08x, %#08x)\n" , |
608 | mr, tkImplementation, dwOffset, |
609 | dwResourceFlags)); |
610 | |
611 | _ASSERTE(TypeFromToken(tkImplementation) == mdtFile || |
612 | TypeFromToken(tkImplementation) == mdtAssemblyRef || |
613 | tkImplementation == mdTokenNil); |
614 | |
615 | START_MD_PERF(); |
616 | LOCKWRITE(); |
617 | |
618 | IfFailGo( _SetManifestResourceProps( mr, tkImplementation, dwOffset, dwResourceFlags) ); |
619 | |
620 | ErrExit: |
621 | |
622 | STOP_MD_PERF(SetManifestResourceProps); |
623 | END_ENTRYPOINT_NOTHROW; |
624 | |
625 | return hr; |
626 | } // STDMETHODIMP RegMeta::SetManifestResourceProps() |
627 | |
628 | //******************************************************************************* |
629 | // Helper: Set the specified attributes on the given Assembly token. |
630 | //******************************************************************************* |
631 | HRESULT RegMeta::_SetAssemblyProps( // S_OK or error. |
632 | mdAssembly ma, // [IN] Assembly token. |
633 | const void *pbPublicKey, // [IN] Originator of the assembly. |
634 | ULONG cbPublicKey, // [IN] Count of bytes in the Originator blob. |
635 | ULONG ulHashAlgId, // [IN] Hash Algorithm. |
636 | LPCWSTR szName, // [IN] Name of the assembly. |
637 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
638 | DWORD dwAssemblyFlags) // [IN] Flags. |
639 | { |
640 | AssemblyRec *pRecord = NULL; // The assembly record. |
641 | HRESULT hr = S_OK; |
642 | |
643 | IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRecord(RidFromToken(ma), &pRecord)); |
644 | |
645 | // Set the data. |
646 | if (pbPublicKey) |
647 | IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_Assembly, AssemblyRec::COL_PublicKey, |
648 | pRecord, pbPublicKey, cbPublicKey)); |
649 | if (ulHashAlgId != ULONG_MAX) |
650 | pRecord->SetHashAlgId(ulHashAlgId); |
651 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Assembly, AssemblyRec::COL_Name, pRecord, szName)); |
652 | if (pMetaData->usMajorVersion != USHRT_MAX) |
653 | pRecord->SetMajorVersion(pMetaData->usMajorVersion); |
654 | if (pMetaData->usMinorVersion != USHRT_MAX) |
655 | pRecord->SetMinorVersion(pMetaData->usMinorVersion); |
656 | if (pMetaData->usBuildNumber != USHRT_MAX) |
657 | pRecord->SetBuildNumber(pMetaData->usBuildNumber); |
658 | if (pMetaData->usRevisionNumber != USHRT_MAX) |
659 | pRecord->SetRevisionNumber(pMetaData->usRevisionNumber); |
660 | if (pMetaData->szLocale) |
661 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Assembly, AssemblyRec::COL_Locale, |
662 | pRecord, pMetaData->szLocale)); |
663 | |
664 | dwAssemblyFlags = (dwAssemblyFlags & ~afPublicKey) | (cbPublicKey ? afPublicKey : 0); |
665 | pRecord->SetFlags(dwAssemblyFlags); |
666 | IfFailGo(UpdateENCLog(ma)); |
667 | |
668 | ErrExit: |
669 | |
670 | |
671 | return hr; |
672 | } // HRESULT RegMeta::_SetAssemblyProps() |
673 | |
674 | //******************************************************************************* |
675 | // Helper: Set the specified attributes on the given AssemblyRef token. |
676 | //******************************************************************************* |
677 | HRESULT RegMeta::_SetAssemblyRefProps( // S_OK or error. |
678 | mdAssemblyRef ar, // [IN] AssemblyRefToken. |
679 | const void *pbPublicKeyOrToken, // [IN] Public key or token of the assembly. |
680 | ULONG cbPublicKeyOrToken, // [IN] Count of bytes in the public key or token. |
681 | LPCWSTR szName, // [IN] Name of the assembly being referenced. |
682 | const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. |
683 | const void *pbHashValue, // [IN] Hash Blob. |
684 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
685 | DWORD dwAssemblyRefFlags) // [IN] Flags. |
686 | { |
687 | AssemblyRefRec *pRecord; |
688 | HRESULT hr = S_OK; |
689 | |
690 | IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRefRecord(RidFromToken(ar), &pRecord)); |
691 | |
692 | if (pbPublicKeyOrToken) |
693 | IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_PublicKeyOrToken, |
694 | pRecord, pbPublicKeyOrToken, cbPublicKeyOrToken)); |
695 | if (szName) |
696 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_AssemblyRef, AssemblyRefRec::COL_Name, |
697 | pRecord, szName)); |
698 | if (pMetaData) |
699 | { |
700 | if (pMetaData->usMajorVersion != USHRT_MAX) |
701 | pRecord->SetMajorVersion(pMetaData->usMajorVersion); |
702 | if (pMetaData->usMinorVersion != USHRT_MAX) |
703 | pRecord->SetMinorVersion(pMetaData->usMinorVersion); |
704 | if (pMetaData->usBuildNumber != USHRT_MAX) |
705 | pRecord->SetBuildNumber(pMetaData->usBuildNumber); |
706 | if (pMetaData->usRevisionNumber != USHRT_MAX) |
707 | pRecord->SetRevisionNumber(pMetaData->usRevisionNumber); |
708 | if (pMetaData->szLocale) |
709 | IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_AssemblyRef, |
710 | AssemblyRefRec::COL_Locale, pRecord, pMetaData->szLocale)); |
711 | |
712 | } |
713 | if (pbHashValue) |
714 | IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_HashValue, |
715 | pRecord, pbHashValue, cbHashValue)); |
716 | if (dwAssemblyRefFlags != ULONG_MAX) |
717 | pRecord->SetFlags(PrepareForSaving(dwAssemblyRefFlags)); |
718 | |
719 | IfFailGo(UpdateENCLog(ar)); |
720 | |
721 | ErrExit: |
722 | |
723 | |
724 | return hr; |
725 | } // RegMeta::_SetAssemblyRefProps |
726 | |
727 | //******************************************************************************* |
728 | // Helper: Set the specified attributes on the given File token. |
729 | //******************************************************************************* |
730 | HRESULT RegMeta::_SetFileProps( // S_OK or error. |
731 | mdFile file, // [IN] File token. |
732 | const void *pbHashValue, // [IN] Hash Blob. |
733 | ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. |
734 | DWORD dwFileFlags) // [IN] Flags. |
735 | { |
736 | FileRec *pRecord; |
737 | HRESULT hr = S_OK; |
738 | |
739 | IfFailGo(m_pStgdb->m_MiniMd.GetFileRecord(RidFromToken(file), &pRecord)); |
740 | |
741 | if (pbHashValue) |
742 | IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_File, FileRec::COL_HashValue, pRecord, |
743 | pbHashValue, cbHashValue)); |
744 | if (dwFileFlags != ULONG_MAX) |
745 | pRecord->SetFlags(dwFileFlags); |
746 | |
747 | IfFailGo(UpdateENCLog(file)); |
748 | ErrExit: |
749 | return hr; |
750 | } // RegMeta::_SetFileProps |
751 | |
752 | //******************************************************************************* |
753 | // Helper: Set the specified attributes on the given ExportedType token. |
754 | //******************************************************************************* |
755 | HRESULT RegMeta::_SetExportedTypeProps( // S_OK or error. |
756 | mdExportedType ct, // [IN] ExportedType token. |
757 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType. |
758 | mdTypeDef tkTypeDef, // [IN] TypeDef token within the file. |
759 | DWORD dwExportedTypeFlags) // [IN] Flags. |
760 | { |
761 | ExportedTypeRec *pRecord; |
762 | HRESULT hr = S_OK; |
763 | |
764 | IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(ct), &pRecord)); |
765 | |
766 | if(! IsNilToken(tkImplementation)) |
767 | IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation, |
768 | pRecord, tkImplementation)); |
769 | if (! IsNilToken(tkTypeDef)) |
770 | { |
771 | _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef); |
772 | pRecord->SetTypeDefId(tkTypeDef); |
773 | } |
774 | if (dwExportedTypeFlags != ULONG_MAX) |
775 | pRecord->SetFlags(dwExportedTypeFlags); |
776 | |
777 | IfFailGo(UpdateENCLog(ct)); |
778 | ErrExit: |
779 | return hr; |
780 | } // RegMeta::_SetExportedTypeProps |
781 | |
782 | //******************************************************************************* |
783 | // Helper: Set the specified attributes on the given ManifestResource token. |
784 | //******************************************************************************* |
785 | HRESULT RegMeta::_SetManifestResourceProps(// S_OK or error. |
786 | mdManifestResource mr, // [IN] ManifestResource token. |
787 | mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. |
788 | DWORD dwOffset, // [IN] Offset to the beginning of the resource within the file. |
789 | DWORD dwResourceFlags) // [IN] Flags. |
790 | { |
791 | ManifestResourceRec *pRecord = NULL; |
792 | HRESULT hr = S_OK; |
793 | |
794 | IfFailGo(m_pStgdb->m_MiniMd.GetManifestResourceRecord(RidFromToken(mr), &pRecord)); |
795 | |
796 | // Set the attributes. |
797 | if (tkImplementation != mdTokenNil) |
798 | IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ManifestResource, |
799 | ManifestResourceRec::COL_Implementation, pRecord, tkImplementation)); |
800 | if (dwOffset != ULONG_MAX) |
801 | pRecord->SetOffset(dwOffset); |
802 | if (dwResourceFlags != ULONG_MAX) |
803 | pRecord->SetFlags(dwResourceFlags); |
804 | |
805 | IfFailGo(UpdateENCLog(mr)); |
806 | |
807 | ErrExit: |
808 | return hr; |
809 | } // RegMeta::_SetManifestResourceProps |
810 | |
811 | #endif //FEATURE_METADATA_EMIT |
812 | |