]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/PiSmbiosRecordOnDataHubSmbiosRecordThunk/Translate.c
Fix CRLF format
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / PiSmbiosRecordOnDataHubSmbiosRecordThunk / Translate.c
CommitLineData
bd1a4d18 1/** @file\r
024b1029 2 Translate the DataHub records via EFI_DATA_HUB_PROTOCOL to Smbios recorders \r
3 via EFI_SMBIOS_PROTOCOL.\r
4 \r
afe05b7a 5Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
584d5652 6This program and the accompanying materials\r
024b1029 7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "Thunk.h"\r
17\r
18EFI_GUID ZeroGuid = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };\r
19EFI_SMBIOS_PROTOCOL *mSmbiosProtocol = NULL;\r
20\r
21/**\r
22 Release the structure Node. \r
23 \r
24 @param StructureNode Point to SMBIOS_STRUCTURE_NODE which will be removed.\r
25**/\r
26VOID\r
27ReleaseStructureNode (\r
28 SMBIOS_STRUCTURE_NODE *StructureNode\r
29 )\r
30{\r
31 EFI_SMBIOS_PROTOCOL *Smbios;\r
32 \r
33 RemoveEntryList (&(StructureNode->Link));\r
34 Smbios = GetSmbiosProtocol();\r
35 ASSERT (Smbios != NULL);\r
36 Smbios->Remove (Smbios, StructureNode->SmbiosHandle);\r
37 gBS->FreePool (StructureNode);\r
38}\r
39\r
40/**\r
41 Process a datahub's record and find corresponding translation way to translate\r
42 to SMBIOS record.\r
43 \r
44 @param Record Point to datahub record.\r
45**/\r
46VOID\r
47SmbiosProcessDataRecord (\r
48 IN EFI_DATA_RECORD_HEADER *Record\r
49 )\r
50{\r
51 EFI_DATA_RECORD_HEADER *RecordHeader;\r
52 EFI_SUBCLASS_TYPE1_HEADER *DataHeader;\r
53 UINTN Index;\r
54 SMBIOS_CONVERSION_TABLE_ENTRY *Conversion;\r
55 UINT8 *SrcData;\r
56 UINTN SrcDataSize;\r
57 LIST_ENTRY *Link;\r
58 SMBIOS_STRUCTURE_NODE *StructureNode;\r
59 BOOLEAN StructureCreated;\r
60 EFI_STATUS Status;\r
61 \r
62 Conversion = NULL;\r
63 StructureNode = NULL;\r
64 StructureCreated = FALSE;\r
65 RecordHeader = Record;\r
66 DataHeader = (EFI_SUBCLASS_TYPE1_HEADER *) (Record + 1);\r
67 SrcData = (UINT8 *) (DataHeader + 1);\r
68 SrcDataSize = RecordHeader->RecordSize - RecordHeader->HeaderSize - sizeof (EFI_SUBCLASS_TYPE1_HEADER);\r
69\r
70 if (DataHeader->HeaderSize != sizeof (EFI_SUBCLASS_TYPE1_HEADER) ||\r
71 DataHeader->Instance == EFI_SUBCLASS_INSTANCE_RESERVED ||\r
72 DataHeader->SubInstance == EFI_SUBCLASS_INSTANCE_RESERVED\r
73 ) {\r
74 //\r
75 // Invalid Data Record\r
76 //\r
77 goto Done;\r
78 }\r
79\r
80 Index = 0;\r
81 while(TRUE) {\r
82 //\r
83 // Find a matching entry in the conversion table for this\r
84 // (SubClass, RecordNumber) pair\r
85 //\r
86 for (; !CompareGuid (&(mConversionTable[Index].SubClass), &ZeroGuid); Index++) {\r
87 if (CompareGuid (\r
88 &(mConversionTable[Index].SubClass),\r
89 &(RecordHeader->DataRecordGuid)\r
90 )) {\r
91 if (mConversionTable[Index].RecordType == DataHeader->RecordType) {\r
92 break;\r
93 }\r
94 }\r
95 }\r
96\r
97 if (CompareGuid (&(mConversionTable[Index].SubClass), &ZeroGuid)) {\r
98 //\r
99 // We cannot find a matching entry in conversion table,\r
100 // this means this data record cannot be used for SMBIOS.\r
101 // Just skip it.\r
102 //\r
103 goto Done;\r
104 }\r
105\r
106 Conversion = &mConversionTable[Index++];\r
107\r
108 //\r
109 // Find corresponding structure in the Structure List\r
110 //\r
111 for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {\r
112\r
113 StructureNode = CR (\r
114 Link,\r
115 SMBIOS_STRUCTURE_NODE,\r
116 Link,\r
117 SMBIOS_STRUCTURE_NODE_SIGNATURE\r
118 );\r
119\r
26a76fbc 120 if (Conversion->StructureLocatingMethod == BySubclassInstanceSubinstanceProducer) {\r
024b1029 121 //\r
122 // Look at SubClass, Instance, SubInstance and ProducerName for a matching\r
123 // node\r
124 //\r
125 if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&\r
126 StructureNode->Instance == DataHeader->Instance &&\r
127 StructureNode->SubInstance == DataHeader->SubInstance &&\r
128 CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))\r
129 ) {\r
afe05b7a 130 if (Conversion->SmbiosType >= 0x80) {\r
024b1029 131 if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {\r
132 break;\r
133 }\r
134 } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {\r
135 break;\r
136 }\r
137 }\r
138\r
26a76fbc 139 } else if (Conversion->StructureLocatingMethod == BySubClassInstanceProducer) {\r
024b1029 140 //\r
141 // Look at SubClass, Instance and ProducerName for a matching node\r
142 //\r
143 if (CompareGuid (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid)) &&\r
144 StructureNode->Instance == DataHeader->Instance &&\r
145 CompareGuid (&(StructureNode->ProducerName), &(RecordHeader->ProducerName))\r
146 ) {\r
afe05b7a 147 if (Conversion->SmbiosType >= 0x80) {\r
024b1029 148 if (StructureNode->SmbiosType == ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type) {\r
149 break;\r
150 }\r
151 } else if (StructureNode->SmbiosType == Conversion->SmbiosType) {\r
152 break;\r
153 }\r
154 }\r
155\r
156 } else {\r
157 //\r
158 // Invalid conversion table entry\r
159 //\r
160 goto Done;\r
161 }\r
162 }\r
163\r
234980f6 164 if (Link == &mStructureList || StructureNode == NULL) {\r
024b1029 165\r
166 //\r
167 // Not found, create a new structure\r
168 //\r
169 StructureNode = AllocateZeroPool (sizeof (SMBIOS_STRUCTURE_NODE));\r
170\r
bd1a4d18 171 if (StructureNode == NULL) {\r
024b1029 172 goto Done;\r
173 }\r
174\r
26a76fbc 175 if (Conversion->StructureLocatingMethod == BySubclassInstanceSubinstanceProducer) {\r
024b1029 176 //\r
177 // Fill in SubClass, Instance, SubInstance and ProducerName\r
178 //\r
179 CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));\r
180 StructureNode->Instance = DataHeader->Instance;\r
181 StructureNode->SubInstance = DataHeader->SubInstance;\r
182 CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));\r
183\r
26a76fbc 184 } else if (Conversion->StructureLocatingMethod == BySubClassInstanceProducer) {\r
024b1029 185 //\r
186 // Fill in at SubClass, Instance and ProducerName, mark SubInstance as Non\r
187 // Applicable\r
188 //\r
189 CopyMem (&(StructureNode->SubClass), &(RecordHeader->DataRecordGuid), sizeof (EFI_GUID));\r
190 StructureNode->Instance = DataHeader->Instance;\r
191 StructureNode->SubInstance = EFI_SUBCLASS_INSTANCE_NON_APPLICABLE;\r
192 CopyMem (&(StructureNode->ProducerName), &(RecordHeader->ProducerName), sizeof (EFI_GUID));\r
193\r
194 }\r
195 //\r
196 // Allocate the structure instance\r
197 //\r
198 StructureNode->StructureSize = SmbiosGetTypeMinimalLength (Conversion->SmbiosType);\r
024b1029 199 \r
200 //\r
201 // StructureSize include the TWO trailing zero byte.\r
202 //\r
203 if (StructureNode->StructureSize < (sizeof(SMBIOS_STRUCTURE) + 2)) {\r
204 //\r
205 // Invalid Type\r
206 //\r
207 gBS->FreePool (StructureNode);\r
208 goto Done;\r
209 }\r
210\r
afe05b7a 211 //\r
212 // Assign correct SmbiosType when OEM type and Non-OEM type\r
213 //\r
214 if (Conversion->SmbiosType >= 0x80) {\r
215 StructureNode->SmbiosType = ((SMBIOS_STRUCTURE_HDR *) SrcData)->Type;\r
216 } else {\r
217 StructureNode->SmbiosType = Conversion->SmbiosType;\r
218 }\r
219 \r
73c5d34e 220 StructureNode->SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
024b1029 221 Status = SmbiosProtocolCreateRecord (\r
222 NULL, \r
223 StructureNode\r
224 );\r
225 if (EFI_ERROR (Status)) {\r
226 goto Done;\r
227 }\r
228 //\r
229 // Temporary cache the structrue pointer to Smbios database.\r
230 //\r
231 StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);\r
232 \r
233 InitializeListHead (&StructureNode->LinkDataFixup);\r
234\r
235 //\r
236 // Insert the Structure Node into the Strucutre List\r
237 //\r
238 StructureNode->Signature = SMBIOS_STRUCTURE_NODE_SIGNATURE;\r
239 InsertTailList (&mStructureList, &(StructureNode->Link));\r
240\r
241 StructureCreated = TRUE;\r
242\r
243 }\r
244 \r
245 \r
246 //\r
247 // Re-calculate the structure pointer to Smbios database.\r
248 //\r
249 StructureNode->Structure = GetSmbiosBufferFromHandle (StructureNode->SmbiosHandle, StructureNode->SmbiosType, NULL);\r
250 \r
251 //\r
252 // Fill the Structure's field corresponding to this data record\r
253 //\r
26a76fbc 254 if (Conversion->FieldFillingMethod == RecordDataUnchangedOffsetSpecified) {\r
024b1029 255 //\r
256 // Field data is just the record data without transforming and\r
257 // offset is specified directly in the conversion table entry\r
258 //\r
259 if (Conversion->FieldOffset + SrcDataSize > StructureNode->Structure->Length) {\r
260 //\r
261 // Invalid Conversion Table Entry\r
262 //\r
263 if (StructureCreated) {\r
264 ReleaseStructureNode (StructureNode);\r
265 }\r
266\r
267 goto Done;\r
268 }\r
269 \r
270 CopyMem ((UINT8 *) (StructureNode->Structure) + Conversion->FieldOffset, SrcData, SrcDataSize);\r
271\r
26a76fbc 272 } else if (Conversion->FieldFillingMethod == ByFunctionWithOffsetSpecified) {\r
024b1029 273 //\r
274 // Field offfset is specified in the conversion table entry, but\r
275 // record data needs to be transformed to be filled into the field,\r
276 // so let the FieldFillingFunction do it.\r
277 //\r
bd1a4d18 278 if (Conversion->FieldFillingFunction == NULL) {\r
024b1029 279 //\r
280 // Invalid Conversion Table Entry\r
281 //\r
282 if (StructureCreated) {\r
283 ReleaseStructureNode (StructureNode);\r
284 }\r
285\r
286 goto Done;\r
287 }\r
288\r
289 Status = Conversion->FieldFillingFunction (\r
290 StructureNode,\r
291 Conversion->FieldOffset,\r
292 SrcData,\r
293 (UINT32) SrcDataSize\r
294 );\r
295 if (EFI_ERROR (Status)) {\r
296 if (StructureCreated) {\r
297 ReleaseStructureNode (StructureNode);\r
298 }\r
299\r
300 goto Done;\r
301 }\r
26a76fbc 302 } else if (Conversion->FieldFillingMethod == ByFunction) {\r
024b1029 303 //\r
304 // Both field offset and field content are determined by\r
305 // FieldFillingFunction\r
306 //\r
bd1a4d18 307 if (Conversion->FieldFillingFunction == NULL) {\r
024b1029 308 //\r
309 // Invalid Conversion Table Entry\r
310 //\r
311 if (StructureCreated) {\r
312 ReleaseStructureNode (StructureNode);\r
313 }\r
314\r
315 goto Done;\r
316 }\r
317\r
318 Status = Conversion->FieldFillingFunction (\r
319 StructureNode,\r
320 0,\r
321 SrcData,\r
322 (UINT32) SrcDataSize\r
323 );\r
324 if (EFI_ERROR (Status)) {\r
325 if (StructureCreated) {\r
326 ReleaseStructureNode (StructureNode);\r
327 }\r
328\r
329 goto Done;\r
330 }\r
26a76fbc 331 } else if (Conversion->FieldFillingMethod == ByFunctionWithWholeDataRecord) {\r
024b1029 332 //\r
333 // Both field offset and field content are determined by\r
334 // FieldFillingFunction and the function accepts the whole data record\r
335 // including the data header\r
336 //\r
bd1a4d18 337 if (Conversion->FieldFillingFunction == NULL) {\r
024b1029 338 //\r
339 // Invalid Conversion Table Entry\r
340 //\r
341 if (StructureCreated) {\r
342 ReleaseStructureNode (StructureNode);\r
343 }\r
344\r
345 goto Done;\r
346 }\r
347\r
348 Status = Conversion->FieldFillingFunction (\r
349 StructureNode,\r
350 0,\r
351 DataHeader,\r
352 RecordHeader->RecordSize - RecordHeader->HeaderSize\r
353 );\r
354 if (EFI_ERROR (Status)) {\r
355 if (StructureCreated) {\r
356 ReleaseStructureNode (StructureNode);\r
357 }\r
358\r
359 goto Done;\r
360 }\r
361 } else {\r
362 //\r
363 // Invalid Conversion Table Entry\r
364 //\r
365 if (StructureCreated) {\r
366 ReleaseStructureNode (StructureNode);\r
367 }\r
368\r
369 goto Done;\r
370 }\r
afe05b7a 371 \r
372 //\r
373 // SmbiosEnlargeStructureBuffer is called to remove and add again\r
374 // this SMBIOS entry to reflash SMBIOS table in configuration table.\r
375 //\r
376 SmbiosEnlargeStructureBuffer (\r
377 StructureNode,\r
378 StructureNode->Structure->Length,\r
379 StructureNode->StructureSize,\r
380 StructureNode->StructureSize\r
381 );\r
024b1029 382 }\r
383Done:\r
384 return ;\r
385}\r
386\r
387/**\r
388 Calculate the minimal length for a SMBIOS type. This length maybe not equal\r
389 to sizeof (SMBIOS_RECORD_STRUCTURE), but defined in conformance chapter in SMBIOS specification.\r
390 \r
391 @param Type SMBIOS's type.\r
392 \r
393 @return the minimal length of a smbios record.\r
394**/\r
395UINT32\r
396SmbiosGetTypeMinimalLength (\r
397 IN UINT8 Type\r
398 )\r
399{\r
400 UINTN Index;\r
401\r
402 for (Index = 0; mTypeInfoTable[Index].MinLength != 0; Index++) {\r
403 if (mTypeInfoTable[Index].Type == Type) {\r
404 return mTypeInfoTable[Index].MinLength;\r
405 }\r
406 }\r
407\r
408 return 0;\r
409}\r
410\r
411/**\r
412 Get pointer of EFI_SMBIOS_PROTOCOL.\r
413 \r
414 @return pointer of EFI_SMBIOS_PROTOCOL.\r
415**/\r
416EFI_SMBIOS_PROTOCOL*\r
417GetSmbiosProtocol(\r
418 VOID\r
419 )\r
420{\r
421 EFI_STATUS Status;\r
422 \r
423 if (mSmbiosProtocol == NULL) {\r
424 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID*) &mSmbiosProtocol);\r
425 ASSERT_EFI_ERROR (Status);\r
426 } \r
427 \r
428 ASSERT (mSmbiosProtocol != NULL);\r
429 return mSmbiosProtocol; \r
430} \r
431\r
432/**\r
433 Create a blank smbios record. The datahub record is only a field of smbios record.\r
434 So before fill any field from datahub's record. A blank smbios record need to be \r
435 created.\r
436 \r
437 @param ProducerHandle The produce handle for a datahub record\r
438 @param StructureNode Point to SMBIOS_STRUCTURE_NODE\r
439 \r
440 @retval EFI_OUT_OF_RESOURCES Fail to allocate memory for new blank SMBIOS record.\r
441 @retval EFI_SUCCESS Success to create blank smbios record.\r
442**/\r
443EFI_STATUS\r
444SmbiosProtocolCreateRecord (\r
445 IN EFI_HANDLE ProducerHandle, OPTIONAL\r
446 IN SMBIOS_STRUCTURE_NODE *StructureNode\r
447 )\r
448{\r
449 EFI_SMBIOS_PROTOCOL *Smbios;\r
450 EFI_SMBIOS_TABLE_HEADER *BlankRecord;\r
451 EFI_STATUS Status;\r
452 SMBIOS_STRUCTURE_NODE *RefStructureNode;\r
453 LIST_ENTRY *Link;\r
454 LIST_ENTRY *Link1;\r
455 LIST_ENTRY *Link2; \r
456 SMBIOS_LINK_DATA_FIXUP_NODE *LinkDataFixupNode;\r
457 UINT8 *BufferPointer;\r
458 \r
459 Smbios = GetSmbiosProtocol();\r
460 ASSERT (Smbios != NULL);\r
461 \r
462 //\r
463 // Prepare a blank smbios record.\r
464 //\r
465 BlankRecord = (EFI_SMBIOS_TABLE_HEADER*) AllocateZeroPool (StructureNode->StructureSize);\r
466 if (BlankRecord == NULL) {\r
467 return EFI_OUT_OF_RESOURCES;\r
468 }\r
469 BlankRecord->Type = StructureNode->SmbiosType;\r
470 BlankRecord->Length = (UINT8) (StructureNode->StructureSize - 2);\r
471 \r
472 //\r
473 // Add blank record into SMBIOS database.\r
474 //\r
475 Status = Smbios->Add (Smbios, NULL, &StructureNode->SmbiosHandle, BlankRecord);\r
476 FreePool (BlankRecord);\r
477 \r
478 //\r
479 // Fix up the InterLink node for new added smbios record if some other\r
480 // existing smbios record want to link this new record's handle.\r
481 //\r
482 for (Link = mStructureList.ForwardLink; Link != &mStructureList; Link = Link->ForwardLink) {\r
483 RefStructureNode = CR (Link, SMBIOS_STRUCTURE_NODE, Link, SMBIOS_STRUCTURE_NODE_SIGNATURE);\r
484 for (Link1 = RefStructureNode->LinkDataFixup.ForwardLink; Link1 != &RefStructureNode->LinkDataFixup;) {\r
485 LinkDataFixupNode = CR (Link1, SMBIOS_LINK_DATA_FIXUP_NODE, Link, SMBIOS_LINK_DATA_FIXUP_NODE_SIGNATURE);\r
486 Link2 = Link1;\r
487 Link1 = Link1->ForwardLink;\r
488 \r
489 if ((StructureNode->SmbiosType != LinkDataFixupNode->TargetType) ||\r
490 !(CompareGuid (&StructureNode->SubClass, &LinkDataFixupNode->SubClass)) ||\r
491 (StructureNode->Instance != LinkDataFixupNode->LinkData.Instance) ||\r
492 (StructureNode->SubInstance != LinkDataFixupNode->LinkData.SubInstance)) {\r
493 continue;\r
494 }\r
495 \r
496 //\r
497 // Fill the field with the handle found\r
498 //\r
499 BufferPointer = (UINT8 *) (RefStructureNode->Structure) + LinkDataFixupNode->Offset;\r
500 *BufferPointer = (UINT8) (StructureNode->SmbiosHandle & 0xFF);\r
501 *(BufferPointer + 1) = (UINT8) ((StructureNode->SmbiosHandle >> 8) & 0xFF);\r
502 BufferPointer = NULL;\r
503\r
504 RemoveEntryList (Link2);\r
505 FreePool (LinkDataFixupNode);\r
506 }\r
507 }\r
508 \r
509 return Status;\r
510} \r
511\r
512/**\r
513 Get pointer of a SMBIOS record's buffer according to its handle.\r
514 \r
515 @param Handle The handle of SMBIOS record want to be searched.\r
516 @param Type The type of SMBIOS record want to be searched.\r
517 @param ProducerHandle The producer handle of SMBIOS record.\r
518 \r
519 @return EFI_SMBIOS_TABLE_HEADER Point to a SMBIOS record's buffer.\r
520**/ \r
521EFI_SMBIOS_TABLE_HEADER*\r
522GetSmbiosBufferFromHandle (\r
523 IN EFI_SMBIOS_HANDLE Handle,\r
524 IN EFI_SMBIOS_TYPE Type,\r
525 IN EFI_HANDLE ProducerHandle OPTIONAL\r
526 )\r
527{\r
528 EFI_SMBIOS_PROTOCOL* Smbios;\r
529 EFI_SMBIOS_HANDLE SearchingHandle;\r
530 EFI_SMBIOS_TABLE_HEADER *RecordInSmbiosDatabase;\r
531 EFI_STATUS Status;\r
532 \r
73c5d34e 533 SearchingHandle = SMBIOS_HANDLE_PI_RESERVED;\r
024b1029 534 Smbios = GetSmbiosProtocol();\r
535 ASSERT (Smbios != NULL);\r
536 \r
537 do {\r
538 Status = Smbios->GetNext (Smbios, &SearchingHandle, &Type, &RecordInSmbiosDatabase, NULL);\r
539 } while ((SearchingHandle != Handle) && (Status != EFI_NOT_FOUND));\r
540 \r
541 return RecordInSmbiosDatabase;\r
542} \r
543\r
544/**\r
545\r
546 Get the full size of smbios structure including optional strings that follow the formatted structure.\r
547\r
548 @param Head Pointer to the beginning of smbios structure.\r
549 @param Size The returned size.\r
550 @param NumberOfStrings The returned number of optional strings that follow the formatted structure.\r
551\r
552 @retval EFI_SUCCESS Size retured in Size.\r
553 @retval EFI_INVALID_PARAMETER Input smbios structure mal-formed or Size is NULL.\r
554 \r
555**/\r
556EFI_STATUS\r
557EFIAPI\r
558GetSmbiosStructureSize (\r
559 IN EFI_SMBIOS_TABLE_HEADER *Head,\r
560 OUT UINT32 *Size,\r
561 OUT UINT8 *NumberOfStrings\r
562 )\r
563{\r
564 UINT32 FullSize;\r
565 UINT8 StrLen;\r
566 INT8* CharInStr;\r
567 \r
568 if (Size == NULL || NumberOfStrings == NULL) {\r
569 return EFI_INVALID_PARAMETER;\r
570 }\r
571\r
572 FullSize = Head->Length;\r
573 CharInStr = (INT8*)Head + Head->Length;\r
574 *Size = FullSize;\r
575 *NumberOfStrings = 0;\r
576 StrLen = 0;\r
577 //\r
578 // look for the two consecutive zeros, check the string limit by the way.\r
579 //\r
580 while (*CharInStr != 0 || *(CharInStr+1) != 0) { \r
581 if (*CharInStr == 0) {\r
582 *Size += 1;\r
583 CharInStr++;\r
584 }\r
585\r
586 for (StrLen = 0 ; StrLen < SMBIOS_STRING_MAX_LENGTH; StrLen++) {\r
587 if (*(CharInStr+StrLen) == 0) {\r
588 break;\r
589 } \r
590 }\r
591\r
592 if (StrLen == SMBIOS_STRING_MAX_LENGTH) {\r
593 return EFI_INVALID_PARAMETER;\r
594 }\r
595 //\r
596 // forward the pointer\r
597 //\r
598 CharInStr += StrLen;\r
599 *Size += StrLen;\r
600 *NumberOfStrings += 1;\r
601 \r
602 }\r
603\r
604 //\r
605 // count ending two zeros.\r
606 //\r
607 *Size += 2;\r
608 return EFI_SUCCESS; \r
609}\r