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//*******************************************************************************
30STDMETHODIMP 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
99ErrExit:
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//*******************************************************************************
110STDMETHODIMP 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));
190ErrExit:
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//*******************************************************************************
202STDMETHODIMP 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));
264ErrExit:
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//*******************************************************************************
275STDMETHODIMP 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));
364ErrExit:
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//*******************************************************************************
375STDMETHODIMP 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
443ErrExit:
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//*******************************************************************************
454STDMETHODIMP 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
479ErrExit:
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//*******************************************************************************
489STDMETHODIMP 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
524ErrExit:
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//*******************************************************************************
534STDMETHODIMP 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
556ErrExit:
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//*******************************************************************************
567STDMETHODIMP 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
586ErrExit:
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//*******************************************************************************
597STDMETHODIMP 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
620ErrExit:
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//*******************************************************************************
631HRESULT 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
668ErrExit:
669
670
671 return hr;
672} // HRESULT RegMeta::_SetAssemblyProps()
673
674//*******************************************************************************
675// Helper: Set the specified attributes on the given AssemblyRef token.
676//*******************************************************************************
677HRESULT 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
721ErrExit:
722
723
724 return hr;
725} // RegMeta::_SetAssemblyRefProps
726
727//*******************************************************************************
728// Helper: Set the specified attributes on the given File token.
729//*******************************************************************************
730HRESULT 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));
748ErrExit:
749 return hr;
750} // RegMeta::_SetFileProps
751
752//*******************************************************************************
753// Helper: Set the specified attributes on the given ExportedType token.
754//*******************************************************************************
755HRESULT 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));
778ErrExit:
779 return hr;
780} // RegMeta::_SetExportedTypeProps
781
782//*******************************************************************************
783// Helper: Set the specified attributes on the given ManifestResource token.
784//*******************************************************************************
785HRESULT 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
807ErrExit:
808 return hr;
809} // RegMeta::_SetManifestResourceProps
810
811#endif //FEATURE_METADATA_EMIT
812