CommonLib.c 55 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197
  1. /** @file
  2. Common basic Library Functions
  3. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
  4. This program and the accompanying materials
  5. are licensed and made available under the terms and conditions of the BSD License
  6. which accompanies this distribution. The full text of the license may be found at
  7. http://opensource.org/licenses/bsd-license.php
  8. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  10. **/
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <ctype.h>
  15. #ifdef __GNUC__
  16. #include <unistd.h>
  17. #else
  18. #include <direct.h>
  19. #endif
  20. #include "CommonLib.h"
  21. #include "EfiUtilityMsgs.h"
  22. #define SAFE_STRING_CONSTRAINT_CHECK(Expression, Status) \
  23. do { \
  24. ASSERT (Expression); \
  25. if (!(Expression)) { \
  26. return Status; \
  27. } \
  28. } while (FALSE)
  29. VOID
  30. PeiZeroMem (
  31. IN VOID *Buffer,
  32. IN UINTN Size
  33. )
  34. /*++
  35. Routine Description:
  36. Set Buffer to zero for Size bytes.
  37. Arguments:
  38. Buffer - Memory to set.
  39. Size - Number of bytes to set
  40. Returns:
  41. None
  42. --*/
  43. {
  44. INT8 *Ptr;
  45. Ptr = Buffer;
  46. while (Size--) {
  47. *(Ptr++) = 0;
  48. }
  49. }
  50. VOID
  51. PeiCopyMem (
  52. IN VOID *Destination,
  53. IN VOID *Source,
  54. IN UINTN Length
  55. )
  56. /*++
  57. Routine Description:
  58. Copy Length bytes from Source to Destination.
  59. Arguments:
  60. Destination - Target of copy
  61. Source - Place to copy from
  62. Length - Number of bytes to copy
  63. Returns:
  64. None
  65. --*/
  66. {
  67. CHAR8 *Destination8;
  68. CHAR8 *Source8;
  69. Destination8 = Destination;
  70. Source8 = Source;
  71. while (Length--) {
  72. *(Destination8++) = *(Source8++);
  73. }
  74. }
  75. VOID
  76. ZeroMem (
  77. IN VOID *Buffer,
  78. IN UINTN Size
  79. )
  80. {
  81. PeiZeroMem (Buffer, Size);
  82. }
  83. VOID
  84. CopyMem (
  85. IN VOID *Destination,
  86. IN VOID *Source,
  87. IN UINTN Length
  88. )
  89. {
  90. PeiCopyMem (Destination, Source, Length);
  91. }
  92. INTN
  93. CompareGuid (
  94. IN EFI_GUID *Guid1,
  95. IN EFI_GUID *Guid2
  96. )
  97. /*++
  98. Routine Description:
  99. Compares to GUIDs
  100. Arguments:
  101. Guid1 - guid to compare
  102. Guid2 - guid to compare
  103. Returns:
  104. = 0 if Guid1 == Guid2
  105. != 0 if Guid1 != Guid2
  106. --*/
  107. {
  108. INT32 *g1;
  109. INT32 *g2;
  110. INT32 r;
  111. //
  112. // Compare 32 bits at a time
  113. //
  114. g1 = (INT32 *) Guid1;
  115. g2 = (INT32 *) Guid2;
  116. r = g1[0] - g2[0];
  117. r |= g1[1] - g2[1];
  118. r |= g1[2] - g2[2];
  119. r |= g1[3] - g2[3];
  120. return r;
  121. }
  122. EFI_STATUS
  123. GetFileImage (
  124. IN CHAR8 *InputFileName,
  125. OUT CHAR8 **InputFileImage,
  126. OUT UINT32 *BytesRead
  127. )
  128. /*++
  129. Routine Description:
  130. This function opens a file and reads it into a memory buffer. The function
  131. will allocate the memory buffer and returns the size of the buffer.
  132. Arguments:
  133. InputFileName The name of the file to read.
  134. InputFileImage A pointer to the memory buffer.
  135. BytesRead The size of the memory buffer.
  136. Returns:
  137. EFI_SUCCESS The function completed successfully.
  138. EFI_INVALID_PARAMETER One of the input parameters was invalid.
  139. EFI_ABORTED An error occurred.
  140. EFI_OUT_OF_RESOURCES No resource to complete operations.
  141. --*/
  142. {
  143. FILE *InputFile;
  144. UINT32 FileSize;
  145. //
  146. // Verify input parameters.
  147. //
  148. if (InputFileName == NULL || strlen (InputFileName) == 0 || InputFileImage == NULL) {
  149. return EFI_INVALID_PARAMETER;
  150. }
  151. //
  152. // Open the file and copy contents into a memory buffer.
  153. //
  154. //
  155. // Open the file
  156. //
  157. InputFile = fopen (LongFilePath (InputFileName), "rb");
  158. if (InputFile == NULL) {
  159. Error (NULL, 0, 0001, "Error opening the input file", InputFileName);
  160. return EFI_ABORTED;
  161. }
  162. //
  163. // Go to the end so that we can determine the file size
  164. //
  165. if (fseek (InputFile, 0, SEEK_END)) {
  166. Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
  167. fclose (InputFile);
  168. return EFI_ABORTED;
  169. }
  170. //
  171. // Get the file size
  172. //
  173. FileSize = ftell (InputFile);
  174. if (FileSize == -1) {
  175. Error (NULL, 0, 0003, "Error parsing the input file", InputFileName);
  176. fclose (InputFile);
  177. return EFI_ABORTED;
  178. }
  179. //
  180. // Allocate a buffer
  181. //
  182. *InputFileImage = malloc (FileSize);
  183. if (*InputFileImage == NULL) {
  184. fclose (InputFile);
  185. return EFI_OUT_OF_RESOURCES;
  186. }
  187. //
  188. // Reset to the beginning of the file
  189. //
  190. if (fseek (InputFile, 0, SEEK_SET)) {
  191. Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
  192. fclose (InputFile);
  193. free (*InputFileImage);
  194. *InputFileImage = NULL;
  195. return EFI_ABORTED;
  196. }
  197. //
  198. // Read all of the file contents.
  199. //
  200. *BytesRead = fread (*InputFileImage, sizeof (UINT8), FileSize, InputFile);
  201. if (*BytesRead != sizeof (UINT8) * FileSize) {
  202. Error (NULL, 0, 0004, "Error reading the input file", InputFileName);
  203. fclose (InputFile);
  204. free (*InputFileImage);
  205. *InputFileImage = NULL;
  206. return EFI_ABORTED;
  207. }
  208. //
  209. // Close the file
  210. //
  211. fclose (InputFile);
  212. return EFI_SUCCESS;
  213. }
  214. EFI_STATUS
  215. PutFileImage (
  216. IN CHAR8 *OutputFileName,
  217. IN CHAR8 *OutputFileImage,
  218. IN UINT32 BytesToWrite
  219. )
  220. /*++
  221. Routine Description:
  222. This function opens a file and writes OutputFileImage into the file.
  223. Arguments:
  224. OutputFileName The name of the file to write.
  225. OutputFileImage A pointer to the memory buffer.
  226. BytesToWrite The size of the memory buffer.
  227. Returns:
  228. EFI_SUCCESS The function completed successfully.
  229. EFI_INVALID_PARAMETER One of the input parameters was invalid.
  230. EFI_ABORTED An error occurred.
  231. EFI_OUT_OF_RESOURCES No resource to complete operations.
  232. --*/
  233. {
  234. FILE *OutputFile;
  235. UINT32 BytesWrote;
  236. //
  237. // Verify input parameters.
  238. //
  239. if (OutputFileName == NULL || strlen (OutputFileName) == 0 || OutputFileImage == NULL) {
  240. return EFI_INVALID_PARAMETER;
  241. }
  242. //
  243. // Open the file and copy contents into a memory buffer.
  244. //
  245. //
  246. // Open the file
  247. //
  248. OutputFile = fopen (LongFilePath (OutputFileName), "wb");
  249. if (OutputFile == NULL) {
  250. Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);
  251. return EFI_ABORTED;
  252. }
  253. //
  254. // Write all of the file contents.
  255. //
  256. BytesWrote = fwrite (OutputFileImage, sizeof (UINT8), BytesToWrite, OutputFile);
  257. if (BytesWrote != sizeof (UINT8) * BytesToWrite) {
  258. Error (NULL, 0, 0002, "Error writing the output file", OutputFileName);
  259. fclose (OutputFile);
  260. return EFI_ABORTED;
  261. }
  262. //
  263. // Close the file
  264. //
  265. fclose (OutputFile);
  266. return EFI_SUCCESS;
  267. }
  268. UINT8
  269. CalculateChecksum8 (
  270. IN UINT8 *Buffer,
  271. IN UINTN Size
  272. )
  273. /*++
  274. Routine Description:
  275. This function calculates the value needed for a valid UINT8 checksum
  276. Arguments:
  277. Buffer Pointer to buffer containing byte data of component.
  278. Size Size of the buffer
  279. Returns:
  280. The 8 bit checksum value needed.
  281. --*/
  282. {
  283. return (UINT8) (0x100 - CalculateSum8 (Buffer, Size));
  284. }
  285. UINT8
  286. CalculateSum8 (
  287. IN UINT8 *Buffer,
  288. IN UINTN Size
  289. )
  290. /*++
  291. Routine Description::
  292. This function calculates the UINT8 sum for the requested region.
  293. Arguments:
  294. Buffer Pointer to buffer containing byte data of component.
  295. Size Size of the buffer
  296. Returns:
  297. The 8 bit checksum value needed.
  298. --*/
  299. {
  300. UINTN Index;
  301. UINT8 Sum;
  302. Sum = 0;
  303. //
  304. // Perform the byte sum for buffer
  305. //
  306. for (Index = 0; Index < Size; Index++) {
  307. Sum = (UINT8) (Sum + Buffer[Index]);
  308. }
  309. return Sum;
  310. }
  311. UINT16
  312. CalculateChecksum16 (
  313. IN UINT16 *Buffer,
  314. IN UINTN Size
  315. )
  316. /*++
  317. Routine Description::
  318. This function calculates the value needed for a valid UINT16 checksum
  319. Arguments:
  320. Buffer Pointer to buffer containing byte data of component.
  321. Size Size of the buffer
  322. Returns:
  323. The 16 bit checksum value needed.
  324. --*/
  325. {
  326. return (UINT16) (0x10000 - CalculateSum16 (Buffer, Size));
  327. }
  328. UINT16
  329. CalculateSum16 (
  330. IN UINT16 *Buffer,
  331. IN UINTN Size
  332. )
  333. /*++
  334. Routine Description:
  335. This function calculates the UINT16 sum for the requested region.
  336. Arguments:
  337. Buffer Pointer to buffer containing byte data of component.
  338. Size Size of the buffer
  339. Returns:
  340. The 16 bit checksum
  341. --*/
  342. {
  343. UINTN Index;
  344. UINT16 Sum;
  345. Sum = 0;
  346. //
  347. // Perform the word sum for buffer
  348. //
  349. for (Index = 0; Index < Size; Index++) {
  350. Sum = (UINT16) (Sum + Buffer[Index]);
  351. }
  352. return (UINT16) Sum;
  353. }
  354. EFI_STATUS
  355. PrintGuid (
  356. IN EFI_GUID *Guid
  357. )
  358. /*++
  359. Routine Description:
  360. This function prints a GUID to STDOUT.
  361. Arguments:
  362. Guid Pointer to a GUID to print.
  363. Returns:
  364. EFI_SUCCESS The GUID was printed.
  365. EFI_INVALID_PARAMETER The input was NULL.
  366. --*/
  367. {
  368. if (Guid == NULL) {
  369. Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
  370. return EFI_INVALID_PARAMETER;
  371. }
  372. printf (
  373. "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
  374. (unsigned) Guid->Data1,
  375. Guid->Data2,
  376. Guid->Data3,
  377. Guid->Data4[0],
  378. Guid->Data4[1],
  379. Guid->Data4[2],
  380. Guid->Data4[3],
  381. Guid->Data4[4],
  382. Guid->Data4[5],
  383. Guid->Data4[6],
  384. Guid->Data4[7]
  385. );
  386. return EFI_SUCCESS;
  387. }
  388. EFI_STATUS
  389. PrintGuidToBuffer (
  390. IN EFI_GUID *Guid,
  391. IN OUT UINT8 *Buffer,
  392. IN UINT32 BufferLen,
  393. IN BOOLEAN Uppercase
  394. )
  395. /*++
  396. Routine Description:
  397. This function prints a GUID to a buffer
  398. Arguments:
  399. Guid - Pointer to a GUID to print.
  400. Buffer - Pointer to a user-provided buffer to print to
  401. BufferLen - Size of the Buffer
  402. Uppercase - If use upper case.
  403. Returns:
  404. EFI_SUCCESS The GUID was printed.
  405. EFI_INVALID_PARAMETER The input was NULL.
  406. EFI_BUFFER_TOO_SMALL The input buffer was not big enough
  407. --*/
  408. {
  409. if (Guid == NULL) {
  410. Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with a NULL value");
  411. return EFI_INVALID_PARAMETER;
  412. }
  413. if (BufferLen < PRINTED_GUID_BUFFER_SIZE) {
  414. Error (NULL, 0, 2000, "Invalid parameter", "PrintGuidToBuffer() called with invalid buffer size");
  415. return EFI_BUFFER_TOO_SMALL;
  416. }
  417. if (Uppercase) {
  418. sprintf (
  419. (CHAR8 *)Buffer,
  420. "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
  421. (unsigned) Guid->Data1,
  422. Guid->Data2,
  423. Guid->Data3,
  424. Guid->Data4[0],
  425. Guid->Data4[1],
  426. Guid->Data4[2],
  427. Guid->Data4[3],
  428. Guid->Data4[4],
  429. Guid->Data4[5],
  430. Guid->Data4[6],
  431. Guid->Data4[7]
  432. );
  433. } else {
  434. sprintf (
  435. (CHAR8 *)Buffer,
  436. "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  437. (unsigned) Guid->Data1,
  438. Guid->Data2,
  439. Guid->Data3,
  440. Guid->Data4[0],
  441. Guid->Data4[1],
  442. Guid->Data4[2],
  443. Guid->Data4[3],
  444. Guid->Data4[4],
  445. Guid->Data4[5],
  446. Guid->Data4[6],
  447. Guid->Data4[7]
  448. );
  449. }
  450. return EFI_SUCCESS;
  451. }
  452. #ifdef __GNUC__
  453. size_t _filelength(int fd)
  454. {
  455. struct stat stat_buf;
  456. fstat(fd, &stat_buf);
  457. return stat_buf.st_size;
  458. }
  459. #ifndef __CYGWIN__
  460. char *strlwr(char *s)
  461. {
  462. char *p = s;
  463. for(;*s;s++) {
  464. *s = tolower(*s);
  465. }
  466. return p;
  467. }
  468. #endif
  469. #endif
  470. #define WINDOWS_EXTENSION_PATH "\\\\?\\"
  471. #define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"
  472. //
  473. // Global data to store full file path. It is not required to be free.
  474. //
  475. CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];
  476. CHAR8 *
  477. LongFilePath (
  478. IN CHAR8 *FileName
  479. )
  480. /*++
  481. Routine Description:
  482. Convert FileName to the long file path, which can support larger than 260 length.
  483. Arguments:
  484. FileName - FileName.
  485. Returns:
  486. LongFilePath A pointer to the converted long file path.
  487. --*/
  488. {
  489. #ifdef __GNUC__
  490. //
  491. // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here.
  492. // unix has no limitation on file path. Just return FileName.
  493. //
  494. return FileName;
  495. #else
  496. CHAR8 *RootPath;
  497. CHAR8 *PathPointer;
  498. CHAR8 *NextPointer;
  499. PathPointer = (CHAR8 *) FileName;
  500. if (FileName != NULL) {
  501. //
  502. // Add the extension string first to support long file path.
  503. //
  504. mCommonLibFullPath[0] = 0;
  505. strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);
  506. if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {
  507. //
  508. // network path like \\server\share to \\?\UNC\server\share
  509. //
  510. strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);
  511. FileName ++;
  512. } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {
  513. //
  514. // Relative file path. Convert it to absolute path.
  515. //
  516. RootPath = getcwd (NULL, 0);
  517. if (RootPath != NULL) {
  518. if (strlen (mCommonLibFullPath) + strlen (RootPath) > MAX_LONG_FILE_PATH - 1) {
  519. Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
  520. free (RootPath);
  521. return NULL;
  522. }
  523. strncat (mCommonLibFullPath, RootPath, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  524. if (FileName[0] != '\\' && FileName[0] != '/') {
  525. if (strlen (mCommonLibFullPath) + 1 > MAX_LONG_FILE_PATH - 1) {
  526. Error (NULL, 0, 2000, "Invalid parameter", "RootPath is too long!");
  527. free (RootPath);
  528. return NULL;
  529. }
  530. //
  531. // Attach directory separator
  532. //
  533. strncat (mCommonLibFullPath, "\\", MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  534. }
  535. free (RootPath);
  536. }
  537. }
  538. //
  539. // Construct the full file path
  540. //
  541. if (strlen (mCommonLibFullPath) + strlen (FileName) > MAX_LONG_FILE_PATH - 1) {
  542. Error (NULL, 0, 2000, "Invalid parameter", "FileName %s is too long!", FileName);
  543. return NULL;
  544. }
  545. strncat (mCommonLibFullPath, FileName, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  546. //
  547. // Convert directory separator '/' to '\\'
  548. //
  549. PathPointer = (CHAR8 *) mCommonLibFullPath;
  550. do {
  551. if (*PathPointer == '/') {
  552. *PathPointer = '\\';
  553. }
  554. } while (*PathPointer ++ != '\0');
  555. //
  556. // Convert ":\\\\" to ":\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
  557. //
  558. if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {
  559. *(PathPointer + 2) = '\0';
  560. strncat (mCommonLibFullPath, PathPointer + 3, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  561. }
  562. //
  563. // Convert ".\\" to "", because it doesn't work with WINDOWS_EXTENSION_PATH.
  564. //
  565. while ((PathPointer = strstr (mCommonLibFullPath, ".\\")) != NULL) {
  566. *PathPointer = '\0';
  567. strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  568. }
  569. //
  570. // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.
  571. //
  572. while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {
  573. *PathPointer = '\0';
  574. strncat (mCommonLibFullPath, PathPointer + 2, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  575. }
  576. //
  577. // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.
  578. //
  579. while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {
  580. NextPointer = PathPointer + 3;
  581. do {
  582. PathPointer --;
  583. } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');
  584. if (*PathPointer == '\\') {
  585. //
  586. // Skip one directory
  587. //
  588. *PathPointer = '\0';
  589. strncat (mCommonLibFullPath, NextPointer, MAX_LONG_FILE_PATH - strlen (mCommonLibFullPath) - 1);
  590. } else {
  591. //
  592. // No directory is found. Just break.
  593. //
  594. break;
  595. }
  596. }
  597. PathPointer = mCommonLibFullPath;
  598. }
  599. return PathPointer;
  600. #endif
  601. }
  602. CHAR16
  603. InternalCharToUpper (
  604. CHAR16 Char
  605. )
  606. {
  607. if (Char >= L'a' && Char <= L'z') {
  608. return (CHAR16) (Char - (L'a' - L'A'));
  609. }
  610. return Char;
  611. }
  612. UINTN
  613. StrnLenS (
  614. CONST CHAR16 *String,
  615. UINTN MaxSize
  616. )
  617. {
  618. UINTN Length;
  619. ASSERT (((UINTN) String & BIT0) == 0);
  620. //
  621. // If String is a null pointer or MaxSize is 0, then the StrnLenS function returns zero.
  622. //
  623. if ((String == NULL) || (MaxSize == 0)) {
  624. return 0;
  625. }
  626. Length = 0;
  627. while (String[Length] != 0) {
  628. if (Length >= MaxSize - 1) {
  629. return MaxSize;
  630. }
  631. Length++;
  632. }
  633. return Length;
  634. }
  635. VOID *
  636. InternalAllocatePool (
  637. UINTN AllocationSize
  638. )
  639. {
  640. VOID * Memory;
  641. Memory = malloc(AllocationSize);
  642. ASSERT(Memory != NULL);
  643. return Memory;
  644. }
  645. VOID *
  646. InternalReallocatePool (
  647. UINTN OldSize,
  648. UINTN NewSize,
  649. VOID *OldBuffer OPTIONAL
  650. )
  651. {
  652. VOID *NewBuffer;
  653. NewBuffer = AllocateZeroPool (NewSize);
  654. if (NewBuffer != NULL && OldBuffer != NULL) {
  655. memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
  656. free(OldBuffer);
  657. }
  658. return NewBuffer;
  659. }
  660. VOID *
  661. ReallocatePool (
  662. UINTN OldSize,
  663. UINTN NewSize,
  664. VOID *OldBuffer OPTIONAL
  665. )
  666. {
  667. return InternalReallocatePool (OldSize, NewSize, OldBuffer);
  668. }
  669. /**
  670. Returns the length of a Null-terminated Unicode string.
  671. This function returns the number of Unicode characters in the Null-terminated
  672. Unicode string specified by String.
  673. If String is NULL, then ASSERT().
  674. If String is not aligned on a 16-bit boundary, then ASSERT().
  675. If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  676. PcdMaximumUnicodeStringLength Unicode characters, not including the
  677. Null-terminator, then ASSERT().
  678. @param String A pointer to a Null-terminated Unicode string.
  679. @return The length of String.
  680. **/
  681. UINTN
  682. StrLen (
  683. CONST CHAR16 *String
  684. )
  685. {
  686. UINTN Length;
  687. ASSERT (String != NULL);
  688. ASSERT (((UINTN) String & BIT0) == 0);
  689. for (Length = 0; *String != L'\0'; String++, Length++) {
  690. //
  691. // If PcdMaximumUnicodeStringLength is not zero,
  692. // length should not more than PcdMaximumUnicodeStringLength
  693. //
  694. }
  695. return Length;
  696. }
  697. BOOLEAN
  698. InternalSafeStringIsOverlap (
  699. IN VOID *Base1,
  700. IN UINTN Size1,
  701. IN VOID *Base2,
  702. IN UINTN Size2
  703. )
  704. {
  705. if ((((UINTN)Base1 >= (UINTN)Base2) && ((UINTN)Base1 < (UINTN)Base2 + Size2)) ||
  706. (((UINTN)Base2 >= (UINTN)Base1) && ((UINTN)Base2 < (UINTN)Base1 + Size1))) {
  707. return TRUE;
  708. }
  709. return FALSE;
  710. }
  711. BOOLEAN
  712. InternalSafeStringNoStrOverlap (
  713. IN CHAR16 *Str1,
  714. IN UINTN Size1,
  715. IN CHAR16 *Str2,
  716. IN UINTN Size2
  717. )
  718. {
  719. return !InternalSafeStringIsOverlap (Str1, Size1 * sizeof(CHAR16), Str2, Size2 * sizeof(CHAR16));
  720. }
  721. /**
  722. Convert a Null-terminated Unicode decimal string to a value of type UINT64.
  723. This function outputs a value of type UINT64 by interpreting the contents of
  724. the Unicode string specified by String as a decimal number. The format of the
  725. input Unicode string String is:
  726. [spaces] [decimal digits].
  727. The valid decimal digit character is in the range [0-9]. The function will
  728. ignore the pad space, which includes spaces or tab characters, before
  729. [decimal digits]. The running zero in the beginning of [decimal digits] will
  730. be ignored. Then, the function stops at the first character that is a not a
  731. valid decimal character or a Null-terminator, whichever one comes first.
  732. If String is NULL, then ASSERT().
  733. If Data is NULL, then ASSERT().
  734. If String is not aligned in a 16-bit boundary, then ASSERT().
  735. If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  736. PcdMaximumUnicodeStringLength Unicode characters, not including the
  737. Null-terminator, then ASSERT().
  738. If String has no valid decimal digits in the above format, then 0 is stored
  739. at the location pointed to by Data.
  740. If the number represented by String exceeds the range defined by UINT64, then
  741. MAX_UINT64 is stored at the location pointed to by Data.
  742. If EndPointer is not NULL, a pointer to the character that stopped the scan
  743. is stored at the location pointed to by EndPointer. If String has no valid
  744. decimal digits right after the optional pad spaces, the value of String is
  745. stored at the location pointed to by EndPointer.
  746. @param String Pointer to a Null-terminated Unicode string.
  747. @param EndPointer Pointer to character that stops scan.
  748. @param Data Pointer to the converted value.
  749. @retval RETURN_SUCCESS Value is translated from String.
  750. @retval RETURN_INVALID_PARAMETER If String is NULL.
  751. If Data is NULL.
  752. If PcdMaximumUnicodeStringLength is not
  753. zero, and String contains more than
  754. PcdMaximumUnicodeStringLength Unicode
  755. characters, not including the
  756. Null-terminator.
  757. @retval RETURN_UNSUPPORTED If the number represented by String exceeds
  758. the range defined by UINT64.
  759. **/
  760. RETURN_STATUS
  761. StrDecimalToUint64S (
  762. CONST CHAR16 *String,
  763. CHAR16 **EndPointer, OPTIONAL
  764. UINT64 *Data
  765. )
  766. {
  767. ASSERT (((UINTN) String & BIT0) == 0);
  768. //
  769. // 1. Neither String nor Data shall be a null pointer.
  770. //
  771. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  772. SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
  773. //
  774. // 2. The length of String shall not be greater than RSIZE_MAX.
  775. //
  776. if (RSIZE_MAX != 0) {
  777. SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  778. }
  779. if (EndPointer != NULL) {
  780. *EndPointer = (CHAR16 *) String;
  781. }
  782. //
  783. // Ignore the pad spaces (space or tab)
  784. //
  785. while ((*String == L' ') || (*String == L'\t')) {
  786. String++;
  787. }
  788. //
  789. // Ignore leading Zeros after the spaces
  790. //
  791. while (*String == L'0') {
  792. String++;
  793. }
  794. *Data = 0;
  795. while (InternalIsDecimalDigitCharacter (*String)) {
  796. //
  797. // If the number represented by String overflows according to the range
  798. // defined by UINT64, then MAX_UINT64 is stored in *Data and
  799. // RETURN_UNSUPPORTED is returned.
  800. //
  801. if (*Data > ((MAX_UINT64 - (*String - L'0'))/10)) {
  802. *Data = MAX_UINT64;
  803. if (EndPointer != NULL) {
  804. *EndPointer = (CHAR16 *) String;
  805. }
  806. return RETURN_UNSUPPORTED;
  807. }
  808. *Data = (*Data) * 10 + (*String - L'0');
  809. String++;
  810. }
  811. if (EndPointer != NULL) {
  812. *EndPointer = (CHAR16 *) String;
  813. }
  814. return RETURN_SUCCESS;
  815. }
  816. /**
  817. Convert a Null-terminated Unicode hexadecimal string to a value of type
  818. UINT64.
  819. This function outputs a value of type UINT64 by interpreting the contents of
  820. the Unicode string specified by String as a hexadecimal number. The format of
  821. the input Unicode string String is:
  822. [spaces][zeros][x][hexadecimal digits].
  823. The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F].
  824. The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix.
  825. If "x" appears in the input string, it must be prefixed with at least one 0.
  826. The function will ignore the pad space, which includes spaces or tab
  827. characters, before [zeros], [x] or [hexadecimal digit]. The running zero
  828. before [x] or [hexadecimal digit] will be ignored. Then, the decoding starts
  829. after [x] or the first valid hexadecimal digit. Then, the function stops at
  830. the first character that is a not a valid hexadecimal character or NULL,
  831. whichever one comes first.
  832. If String is NULL, then ASSERT().
  833. If Data is NULL, then ASSERT().
  834. If String is not aligned in a 16-bit boundary, then ASSERT().
  835. If PcdMaximumUnicodeStringLength is not zero, and String contains more than
  836. PcdMaximumUnicodeStringLength Unicode characters, not including the
  837. Null-terminator, then ASSERT().
  838. If String has no valid hexadecimal digits in the above format, then 0 is
  839. stored at the location pointed to by Data.
  840. If the number represented by String exceeds the range defined by UINT64, then
  841. MAX_UINT64 is stored at the location pointed to by Data.
  842. If EndPointer is not NULL, a pointer to the character that stopped the scan
  843. is stored at the location pointed to by EndPointer. If String has no valid
  844. hexadecimal digits right after the optional pad spaces, the value of String
  845. is stored at the location pointed to by EndPointer.
  846. @param String Pointer to a Null-terminated Unicode string.
  847. @param EndPointer Pointer to character that stops scan.
  848. @param Data Pointer to the converted value.
  849. @retval RETURN_SUCCESS Value is translated from String.
  850. @retval RETURN_INVALID_PARAMETER If String is NULL.
  851. If Data is NULL.
  852. If PcdMaximumUnicodeStringLength is not
  853. zero, and String contains more than
  854. PcdMaximumUnicodeStringLength Unicode
  855. characters, not including the
  856. Null-terminator.
  857. @retval RETURN_UNSUPPORTED If the number represented by String exceeds
  858. the range defined by UINT64.
  859. **/
  860. RETURN_STATUS
  861. StrHexToUint64S (
  862. CONST CHAR16 *String,
  863. CHAR16 **EndPointer, OPTIONAL
  864. UINT64 *Data
  865. )
  866. {
  867. ASSERT (((UINTN) String & BIT0) == 0);
  868. //
  869. // 1. Neither String nor Data shall be a null pointer.
  870. //
  871. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  872. SAFE_STRING_CONSTRAINT_CHECK ((Data != NULL), RETURN_INVALID_PARAMETER);
  873. //
  874. // 2. The length of String shall not be greater than RSIZE_MAX.
  875. //
  876. if (RSIZE_MAX != 0) {
  877. SAFE_STRING_CONSTRAINT_CHECK ((StrnLenS (String, RSIZE_MAX + 1) <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  878. }
  879. if (EndPointer != NULL) {
  880. *EndPointer = (CHAR16 *) String;
  881. }
  882. //
  883. // Ignore the pad spaces (space or tab)
  884. //
  885. while ((*String == L' ') || (*String == L'\t')) {
  886. String++;
  887. }
  888. //
  889. // Ignore leading Zeros after the spaces
  890. //
  891. while (*String == L'0') {
  892. String++;
  893. }
  894. if (InternalCharToUpper (*String) == L'X') {
  895. if (*(String - 1) != L'0') {
  896. *Data = 0;
  897. return RETURN_SUCCESS;
  898. }
  899. //
  900. // Skip the 'X'
  901. //
  902. String++;
  903. }
  904. *Data = 0;
  905. while (InternalIsHexaDecimalDigitCharacter (*String)) {
  906. //
  907. // If the number represented by String overflows according to the range
  908. // defined by UINT64, then MAX_UINT64 is stored in *Data and
  909. // RETURN_UNSUPPORTED is returned.
  910. //
  911. if (*Data > ((MAX_UINT64 - InternalHexCharToUintn (*String))>>4)) {
  912. *Data = MAX_UINT64;
  913. if (EndPointer != NULL) {
  914. *EndPointer = (CHAR16 *) String;
  915. }
  916. return RETURN_UNSUPPORTED;
  917. }
  918. *Data = ((*Data) << 4) + InternalHexCharToUintn (*String);
  919. String++;
  920. }
  921. if (EndPointer != NULL) {
  922. *EndPointer = (CHAR16 *) String;
  923. }
  924. return RETURN_SUCCESS;
  925. }
  926. UINT64
  927. StrDecimalToUint64 (
  928. CONST CHAR16 *String
  929. )
  930. {
  931. UINT64 Result;
  932. StrDecimalToUint64S (String, (CHAR16 **) NULL, &Result);
  933. return Result;
  934. }
  935. UINT64
  936. StrHexToUint64 (
  937. CONST CHAR16 *String
  938. )
  939. {
  940. UINT64 Result;
  941. StrHexToUint64S (String, (CHAR16 **) NULL, &Result);
  942. return Result;
  943. }
  944. UINTN
  945. StrSize (
  946. CONST CHAR16 *String
  947. )
  948. {
  949. return (StrLen (String) + 1) * sizeof (*String);
  950. }
  951. UINT64
  952. ReadUnaligned64 (
  953. CONST UINT64 *Buffer
  954. )
  955. {
  956. ASSERT (Buffer != NULL);
  957. return *Buffer;
  958. }
  959. UINT64
  960. WriteUnaligned64 (
  961. UINT64 *Buffer,
  962. UINT64 Value
  963. )
  964. {
  965. ASSERT (Buffer != NULL);
  966. return *Buffer = Value;
  967. }
  968. EFI_GUID *
  969. CopyGuid (
  970. EFI_GUID *DestinationGuid,
  971. CONST EFI_GUID *SourceGuid
  972. )
  973. {
  974. WriteUnaligned64 (
  975. (UINT64*)DestinationGuid,
  976. ReadUnaligned64 ((CONST UINT64*)SourceGuid)
  977. );
  978. WriteUnaligned64 (
  979. (UINT64*)DestinationGuid + 1,
  980. ReadUnaligned64 ((CONST UINT64*)SourceGuid + 1)
  981. );
  982. return DestinationGuid;
  983. }
  984. UINT16
  985. SwapBytes16 (
  986. UINT16 Value
  987. )
  988. {
  989. return (UINT16) ((Value<< 8) | (Value>> 8));
  990. }
  991. UINT32
  992. SwapBytes32 (
  993. UINT32 Value
  994. )
  995. {
  996. UINT32 LowerBytes;
  997. UINT32 HigherBytes;
  998. LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value);
  999. HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16));
  1000. return (LowerBytes << 16 | HigherBytes);
  1001. }
  1002. BOOLEAN
  1003. InternalIsDecimalDigitCharacter (
  1004. CHAR16 Char
  1005. )
  1006. {
  1007. return (BOOLEAN) (Char >= L'0' && Char <= L'9');
  1008. }
  1009. VOID *
  1010. InternalAllocateCopyPool (
  1011. UINTN AllocationSize,
  1012. CONST VOID *Buffer
  1013. )
  1014. {
  1015. VOID *Memory;
  1016. ASSERT (Buffer != NULL);
  1017. Memory = malloc (AllocationSize);
  1018. if (Memory != NULL) {
  1019. Memory = memcpy (Memory, Buffer, AllocationSize);
  1020. }
  1021. return Memory;
  1022. }
  1023. BOOLEAN
  1024. InternalIsHexaDecimalDigitCharacter (
  1025. CHAR16 Char
  1026. )
  1027. {
  1028. return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) ||
  1029. (Char >= L'A' && Char <= L'F') ||
  1030. (Char >= L'a' && Char <= L'f'));
  1031. }
  1032. UINTN
  1033. InternalHexCharToUintn (
  1034. CHAR16 Char
  1035. )
  1036. {
  1037. if (InternalIsDecimalDigitCharacter (Char)) {
  1038. return Char - L'0';
  1039. }
  1040. return (10 + InternalCharToUpper (Char) - L'A');
  1041. }
  1042. /**
  1043. Convert a Null-terminated Unicode hexadecimal string to a byte array.
  1044. This function outputs a byte array by interpreting the contents of
  1045. the Unicode string specified by String in hexadecimal format. The format of
  1046. the input Unicode string String is:
  1047. [XX]*
  1048. X is a hexadecimal digit character in the range [0-9], [a-f] and [A-F].
  1049. The function decodes every two hexadecimal digit characters as one byte. The
  1050. decoding stops after Length of characters and outputs Buffer containing
  1051. (Length / 2) bytes.
  1052. If String is not aligned in a 16-bit boundary, then ASSERT().
  1053. If String is NULL, then ASSERT().
  1054. If Buffer is NULL, then ASSERT().
  1055. If Length is not multiple of 2, then ASSERT().
  1056. If PcdMaximumUnicodeStringLength is not zero and Length is greater than
  1057. PcdMaximumUnicodeStringLength, then ASSERT().
  1058. If MaxBufferSize is less than (Length / 2), then ASSERT().
  1059. @param String Pointer to a Null-terminated Unicode string.
  1060. @param Length The number of Unicode characters to decode.
  1061. @param Buffer Pointer to the converted bytes array.
  1062. @param MaxBufferSize The maximum size of Buffer.
  1063. @retval RETURN_SUCCESS Buffer is translated from String.
  1064. @retval RETURN_INVALID_PARAMETER If String is NULL.
  1065. If Data is NULL.
  1066. If Length is not multiple of 2.
  1067. If PcdMaximumUnicodeStringLength is not zero,
  1068. and Length is greater than
  1069. PcdMaximumUnicodeStringLength.
  1070. @retval RETURN_UNSUPPORTED If Length of characters from String contain
  1071. a character that is not valid hexadecimal
  1072. digit characters, or a Null-terminator.
  1073. @retval RETURN_BUFFER_TOO_SMALL If MaxBufferSize is less than (Length / 2).
  1074. **/
  1075. RETURN_STATUS
  1076. StrHexToBytes (
  1077. CONST CHAR16 *String,
  1078. UINTN Length,
  1079. UINT8 *Buffer,
  1080. UINTN MaxBufferSize
  1081. )
  1082. {
  1083. UINTN Index;
  1084. ASSERT (((UINTN) String & BIT0) == 0);
  1085. //
  1086. // 1. None of String or Buffer shall be a null pointer.
  1087. //
  1088. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  1089. SAFE_STRING_CONSTRAINT_CHECK ((Buffer != NULL), RETURN_INVALID_PARAMETER);
  1090. //
  1091. // 2. Length shall not be greater than RSIZE_MAX.
  1092. //
  1093. if (RSIZE_MAX != 0) {
  1094. SAFE_STRING_CONSTRAINT_CHECK ((Length <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  1095. }
  1096. //
  1097. // 3. Length shall not be odd.
  1098. //
  1099. SAFE_STRING_CONSTRAINT_CHECK (((Length & BIT0) == 0), RETURN_INVALID_PARAMETER);
  1100. //
  1101. // 4. MaxBufferSize shall equal to or greater than Length / 2.
  1102. //
  1103. SAFE_STRING_CONSTRAINT_CHECK ((MaxBufferSize >= Length / 2), RETURN_BUFFER_TOO_SMALL);
  1104. //
  1105. // 5. String shall not contains invalid hexadecimal digits.
  1106. //
  1107. for (Index = 0; Index < Length; Index++) {
  1108. if (!InternalIsHexaDecimalDigitCharacter (String[Index])) {
  1109. break;
  1110. }
  1111. }
  1112. if (Index != Length) {
  1113. return RETURN_UNSUPPORTED;
  1114. }
  1115. //
  1116. // Convert the hex string to bytes.
  1117. //
  1118. for(Index = 0; Index < Length; Index++) {
  1119. //
  1120. // For even characters, write the upper nibble for each buffer byte,
  1121. // and for even characters, the lower nibble.
  1122. //
  1123. if ((Index & BIT0) == 0) {
  1124. Buffer[Index / 2] = (UINT8) InternalHexCharToUintn (String[Index]) << 4;
  1125. } else {
  1126. Buffer[Index / 2] |= (UINT8) InternalHexCharToUintn (String[Index]);
  1127. }
  1128. }
  1129. return RETURN_SUCCESS;
  1130. }
  1131. /**
  1132. Convert a Null-terminated Unicode GUID string to a value of type
  1133. EFI_GUID.
  1134. This function outputs a GUID value by interpreting the contents of
  1135. the Unicode string specified by String. The format of the input
  1136. Unicode string String consists of 36 characters, as follows:
  1137. aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
  1138. The pairs aa - pp are two characters in the range [0-9], [a-f] and
  1139. [A-F], with each pair representing a single byte hexadecimal value.
  1140. The mapping between String and the EFI_GUID structure is as follows:
  1141. aa Data1[24:31]
  1142. bb Data1[16:23]
  1143. cc Data1[8:15]
  1144. dd Data1[0:7]
  1145. ee Data2[8:15]
  1146. ff Data2[0:7]
  1147. gg Data3[8:15]
  1148. hh Data3[0:7]
  1149. ii Data4[0:7]
  1150. jj Data4[8:15]
  1151. kk Data4[16:23]
  1152. ll Data4[24:31]
  1153. mm Data4[32:39]
  1154. nn Data4[40:47]
  1155. oo Data4[48:55]
  1156. pp Data4[56:63]
  1157. If String is NULL, then ASSERT().
  1158. If Guid is NULL, then ASSERT().
  1159. If String is not aligned in a 16-bit boundary, then ASSERT().
  1160. @param String Pointer to a Null-terminated Unicode string.
  1161. @param Guid Pointer to the converted GUID.
  1162. @retval RETURN_SUCCESS Guid is translated from String.
  1163. @retval RETURN_INVALID_PARAMETER If String is NULL.
  1164. If Data is NULL.
  1165. @retval RETURN_UNSUPPORTED If String is not as the above format.
  1166. **/
  1167. RETURN_STATUS
  1168. StrToGuid (
  1169. CONST CHAR16 *String,
  1170. EFI_GUID *Guid
  1171. )
  1172. {
  1173. RETURN_STATUS Status;
  1174. EFI_GUID LocalGuid;
  1175. ASSERT (((UINTN) String & BIT0) == 0);
  1176. //
  1177. // 1. None of String or Guid shall be a null pointer.
  1178. //
  1179. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  1180. SAFE_STRING_CONSTRAINT_CHECK ((Guid != NULL), RETURN_INVALID_PARAMETER);
  1181. //
  1182. // Get aabbccdd in big-endian.
  1183. //
  1184. Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data1), (UINT8 *) &LocalGuid.Data1, sizeof (LocalGuid.Data1));
  1185. if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data1)] != L'-') {
  1186. return RETURN_UNSUPPORTED;
  1187. }
  1188. //
  1189. // Convert big-endian to little-endian.
  1190. //
  1191. LocalGuid.Data1 = SwapBytes32 (LocalGuid.Data1);
  1192. String += 2 * sizeof (LocalGuid.Data1) + 1;
  1193. //
  1194. // Get eeff in big-endian.
  1195. //
  1196. Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data2), (UINT8 *) &LocalGuid.Data2, sizeof (LocalGuid.Data2));
  1197. if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data2)] != L'-') {
  1198. return RETURN_UNSUPPORTED;
  1199. }
  1200. //
  1201. // Convert big-endian to little-endian.
  1202. //
  1203. LocalGuid.Data2 = SwapBytes16 (LocalGuid.Data2);
  1204. String += 2 * sizeof (LocalGuid.Data2) + 1;
  1205. //
  1206. // Get gghh in big-endian.
  1207. //
  1208. Status = StrHexToBytes (String, 2 * sizeof (LocalGuid.Data3), (UINT8 *) &LocalGuid.Data3, sizeof (LocalGuid.Data3));
  1209. if (RETURN_ERROR (Status) || String[2 * sizeof (LocalGuid.Data3)] != L'-') {
  1210. return RETURN_UNSUPPORTED;
  1211. }
  1212. //
  1213. // Convert big-endian to little-endian.
  1214. //
  1215. LocalGuid.Data3 = SwapBytes16 (LocalGuid.Data3);
  1216. String += 2 * sizeof (LocalGuid.Data3) + 1;
  1217. //
  1218. // Get iijj.
  1219. //
  1220. Status = StrHexToBytes (String, 2 * 2, &LocalGuid.Data4[0], 2);
  1221. if (RETURN_ERROR (Status) || String[2 * 2] != L'-') {
  1222. return RETURN_UNSUPPORTED;
  1223. }
  1224. String += 2 * 2 + 1;
  1225. //
  1226. // Get kkllmmnnoopp.
  1227. //
  1228. Status = StrHexToBytes (String, 2 * 6, &LocalGuid.Data4[2], 6);
  1229. if (RETURN_ERROR (Status)) {
  1230. return RETURN_UNSUPPORTED;
  1231. }
  1232. CopyGuid (Guid, &LocalGuid);
  1233. return RETURN_SUCCESS;
  1234. }
  1235. /**
  1236. Compares up to a specified length the contents of two Null-terminated Unicode strings,
  1237. and returns the difference between the first mismatched Unicode characters.
  1238. This function compares the Null-terminated Unicode string FirstString to the
  1239. Null-terminated Unicode string SecondString. At most, Length Unicode
  1240. characters will be compared. If Length is 0, then 0 is returned. If
  1241. FirstString is identical to SecondString, then 0 is returned. Otherwise, the
  1242. value returned is the first mismatched Unicode character in SecondString
  1243. subtracted from the first mismatched Unicode character in FirstString.
  1244. If Length > 0 and FirstString is NULL, then ASSERT().
  1245. If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT().
  1246. If Length > 0 and SecondString is NULL, then ASSERT().
  1247. If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT().
  1248. If PcdMaximumUnicodeStringLength is not zero, and Length is greater than
  1249. PcdMaximumUnicodeStringLength, then ASSERT().
  1250. If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than
  1251. PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
  1252. then ASSERT().
  1253. If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than
  1254. PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator,
  1255. then ASSERT().
  1256. @param FirstString A pointer to a Null-terminated Unicode string.
  1257. @param SecondString A pointer to a Null-terminated Unicode string.
  1258. @param Length The maximum number of Unicode characters to compare.
  1259. @retval 0 FirstString is identical to SecondString.
  1260. @return others FirstString is not identical to SecondString.
  1261. **/
  1262. INTN
  1263. StrnCmp (
  1264. CONST CHAR16 *FirstString,
  1265. CONST CHAR16 *SecondString,
  1266. UINTN Length
  1267. )
  1268. {
  1269. if (Length == 0) {
  1270. return 0;
  1271. }
  1272. //
  1273. // ASSERT both strings are less long than PcdMaximumUnicodeStringLength.
  1274. // Length tests are performed inside StrLen().
  1275. //
  1276. ASSERT (StrSize (FirstString) != 0);
  1277. ASSERT (StrSize (SecondString) != 0);
  1278. while ((*FirstString != L'\0') &&
  1279. (*SecondString != L'\0') &&
  1280. (*FirstString == *SecondString) &&
  1281. (Length > 1)) {
  1282. FirstString++;
  1283. SecondString++;
  1284. Length--;
  1285. }
  1286. return *FirstString - *SecondString;
  1287. }
  1288. VOID *
  1289. AllocateCopyPool (
  1290. UINTN AllocationSize,
  1291. CONST VOID *Buffer
  1292. )
  1293. {
  1294. return InternalAllocateCopyPool (AllocationSize, Buffer);
  1295. }
  1296. INTN
  1297. StrCmp (
  1298. CONST CHAR16 *FirstString,
  1299. CONST CHAR16 *SecondString
  1300. )
  1301. {
  1302. //
  1303. // ASSERT both strings are less long than PcdMaximumUnicodeStringLength
  1304. //
  1305. ASSERT (StrSize (FirstString) != 0);
  1306. ASSERT (StrSize (SecondString) != 0);
  1307. while ((*FirstString != L'\0') && (*FirstString == *SecondString)) {
  1308. FirstString++;
  1309. SecondString++;
  1310. }
  1311. return *FirstString - *SecondString;
  1312. }
  1313. UINT64
  1314. SwapBytes64 (
  1315. UINT64 Value
  1316. )
  1317. {
  1318. return InternalMathSwapBytes64 (Value);
  1319. }
  1320. UINT64
  1321. InternalMathSwapBytes64 (
  1322. UINT64 Operand
  1323. )
  1324. {
  1325. UINT64 LowerBytes;
  1326. UINT64 HigherBytes;
  1327. LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand);
  1328. HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32));
  1329. return (LowerBytes << 32 | HigherBytes);
  1330. }
  1331. RETURN_STATUS
  1332. StrToIpv4Address (
  1333. CONST CHAR16 *String,
  1334. CHAR16 **EndPointer,
  1335. EFI_IPv4_ADDRESS *Address,
  1336. UINT8 *PrefixLength
  1337. )
  1338. {
  1339. RETURN_STATUS Status;
  1340. UINTN AddressIndex;
  1341. UINT64 Uint64;
  1342. EFI_IPv4_ADDRESS LocalAddress;
  1343. UINT8 LocalPrefixLength;
  1344. CHAR16 *Pointer;
  1345. LocalPrefixLength = MAX_UINT8;
  1346. LocalAddress.Addr[0] = 0;
  1347. ASSERT (((UINTN) String & BIT0) == 0);
  1348. //
  1349. // 1. None of String or Guid shall be a null pointer.
  1350. //
  1351. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  1352. SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
  1353. for (Pointer = (CHAR16 *) String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
  1354. if (!InternalIsDecimalDigitCharacter (*Pointer)) {
  1355. //
  1356. // D or P contains invalid characters.
  1357. //
  1358. break;
  1359. }
  1360. //
  1361. // Get D or P.
  1362. //
  1363. Status = StrDecimalToUint64S ((CONST CHAR16 *) Pointer, &Pointer, &Uint64);
  1364. if (RETURN_ERROR (Status)) {
  1365. return RETURN_UNSUPPORTED;
  1366. }
  1367. if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
  1368. //
  1369. // It's P.
  1370. //
  1371. if (Uint64 > 32) {
  1372. return RETURN_UNSUPPORTED;
  1373. }
  1374. LocalPrefixLength = (UINT8) Uint64;
  1375. } else {
  1376. //
  1377. // It's D.
  1378. //
  1379. if (Uint64 > MAX_UINT8) {
  1380. return RETURN_UNSUPPORTED;
  1381. }
  1382. LocalAddress.Addr[AddressIndex] = (UINT8) Uint64;
  1383. AddressIndex++;
  1384. }
  1385. //
  1386. // Check the '.' or '/', depending on the AddressIndex.
  1387. //
  1388. if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
  1389. if (*Pointer == L'/') {
  1390. //
  1391. // '/P' is in the String.
  1392. // Skip "/" and get P in next loop.
  1393. //
  1394. Pointer++;
  1395. } else {
  1396. //
  1397. // '/P' is not in the String.
  1398. //
  1399. break;
  1400. }
  1401. } else if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
  1402. if (*Pointer == L'.') {
  1403. //
  1404. // D should be followed by '.'
  1405. //
  1406. Pointer++;
  1407. } else {
  1408. return RETURN_UNSUPPORTED;
  1409. }
  1410. }
  1411. }
  1412. if (AddressIndex < ARRAY_SIZE (Address->Addr)) {
  1413. return RETURN_UNSUPPORTED;
  1414. }
  1415. memcpy (Address, &LocalAddress, sizeof (*Address));
  1416. if (PrefixLength != NULL) {
  1417. *PrefixLength = LocalPrefixLength;
  1418. }
  1419. if (EndPointer != NULL) {
  1420. *EndPointer = Pointer;
  1421. }
  1422. return RETURN_SUCCESS;
  1423. }
  1424. RETURN_STATUS
  1425. StrToIpv6Address (
  1426. CONST CHAR16 *String,
  1427. CHAR16 **EndPointer,
  1428. EFI_IPv6_ADDRESS *Address,
  1429. UINT8 *PrefixLength
  1430. )
  1431. {
  1432. RETURN_STATUS Status;
  1433. UINTN AddressIndex;
  1434. UINT64 Uint64;
  1435. EFI_IPv6_ADDRESS LocalAddress;
  1436. UINT8 LocalPrefixLength;
  1437. CONST CHAR16 *Pointer;
  1438. CHAR16 *End;
  1439. UINTN CompressStart;
  1440. BOOLEAN ExpectPrefix;
  1441. LocalPrefixLength = MAX_UINT8;
  1442. CompressStart = ARRAY_SIZE (Address->Addr);
  1443. ExpectPrefix = FALSE;
  1444. ASSERT (((UINTN) String & BIT0) == 0);
  1445. //
  1446. // 1. None of String or Guid shall be a null pointer.
  1447. //
  1448. SAFE_STRING_CONSTRAINT_CHECK ((String != NULL), RETURN_INVALID_PARAMETER);
  1449. SAFE_STRING_CONSTRAINT_CHECK ((Address != NULL), RETURN_INVALID_PARAMETER);
  1450. for (Pointer = String, AddressIndex = 0; AddressIndex < ARRAY_SIZE (Address->Addr) + 1;) {
  1451. if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
  1452. if (*Pointer != L':') {
  1453. //
  1454. // ":" or "/" should be followed by digit characters.
  1455. //
  1456. return RETURN_UNSUPPORTED;
  1457. }
  1458. //
  1459. // Meet second ":" after previous ":" or "/"
  1460. // or meet first ":" in the beginning of String.
  1461. //
  1462. if (ExpectPrefix) {
  1463. //
  1464. // ":" shall not be after "/"
  1465. //
  1466. return RETURN_UNSUPPORTED;
  1467. }
  1468. if (CompressStart != ARRAY_SIZE (Address->Addr) || AddressIndex == ARRAY_SIZE (Address->Addr)) {
  1469. //
  1470. // "::" can only appear once.
  1471. // "::" can only appear when address is not full length.
  1472. //
  1473. return RETURN_UNSUPPORTED;
  1474. } else {
  1475. //
  1476. // Remember the start of zero compressing.
  1477. //
  1478. CompressStart = AddressIndex;
  1479. Pointer++;
  1480. if (CompressStart == 0) {
  1481. if (*Pointer != L':') {
  1482. //
  1483. // Single ":" shall not be in the beginning of String.
  1484. //
  1485. return RETURN_UNSUPPORTED;
  1486. }
  1487. Pointer++;
  1488. }
  1489. }
  1490. }
  1491. if (!InternalIsHexaDecimalDigitCharacter (*Pointer)) {
  1492. if (*Pointer == L'/') {
  1493. //
  1494. // Might be optional "/P" after "::".
  1495. //
  1496. if (CompressStart != AddressIndex) {
  1497. return RETURN_UNSUPPORTED;
  1498. }
  1499. } else {
  1500. break;
  1501. }
  1502. } else {
  1503. if (!ExpectPrefix) {
  1504. //
  1505. // Get X.
  1506. //
  1507. Status = StrHexToUint64S (Pointer, &End, &Uint64);
  1508. if (RETURN_ERROR (Status) || End - Pointer > 4) {
  1509. //
  1510. // Number of hexadecimal digit characters is no more than 4.
  1511. //
  1512. return RETURN_UNSUPPORTED;
  1513. }
  1514. Pointer = End;
  1515. //
  1516. // Uint64 won't exceed MAX_UINT16 if number of hexadecimal digit characters is no more than 4.
  1517. //
  1518. ASSERT (AddressIndex + 1 < ARRAY_SIZE (Address->Addr));
  1519. LocalAddress.Addr[AddressIndex] = (UINT8) ((UINT16) Uint64 >> 8);
  1520. LocalAddress.Addr[AddressIndex + 1] = (UINT8) Uint64;
  1521. AddressIndex += 2;
  1522. } else {
  1523. //
  1524. // Get P, then exit the loop.
  1525. //
  1526. Status = StrDecimalToUint64S (Pointer, &End, &Uint64);
  1527. if (RETURN_ERROR (Status) || End == Pointer || Uint64 > 128) {
  1528. //
  1529. // Prefix length should not exceed 128.
  1530. //
  1531. return RETURN_UNSUPPORTED;
  1532. }
  1533. LocalPrefixLength = (UINT8) Uint64;
  1534. Pointer = End;
  1535. break;
  1536. }
  1537. }
  1538. //
  1539. // Skip ':' or "/"
  1540. //
  1541. if (*Pointer == L'/') {
  1542. ExpectPrefix = TRUE;
  1543. } else if (*Pointer == L':') {
  1544. if (AddressIndex == ARRAY_SIZE (Address->Addr)) {
  1545. //
  1546. // Meet additional ":" after all 8 16-bit address
  1547. //
  1548. break;
  1549. }
  1550. } else {
  1551. //
  1552. // Meet other character that is not "/" or ":" after all 8 16-bit address
  1553. //
  1554. break;
  1555. }
  1556. Pointer++;
  1557. }
  1558. if ((AddressIndex == ARRAY_SIZE (Address->Addr) && CompressStart != ARRAY_SIZE (Address->Addr)) ||
  1559. (AddressIndex != ARRAY_SIZE (Address->Addr) && CompressStart == ARRAY_SIZE (Address->Addr))
  1560. ) {
  1561. //
  1562. // Full length of address shall not have compressing zeros.
  1563. // Non-full length of address shall have compressing zeros.
  1564. //
  1565. return RETURN_UNSUPPORTED;
  1566. }
  1567. memcpy (&Address->Addr[0], &LocalAddress.Addr[0], CompressStart);
  1568. if (AddressIndex > CompressStart) {
  1569. memset (&Address->Addr[CompressStart], 0, ARRAY_SIZE (Address->Addr) - AddressIndex);
  1570. memcpy (
  1571. &Address->Addr[CompressStart + ARRAY_SIZE (Address->Addr) - AddressIndex],
  1572. &LocalAddress.Addr[CompressStart],
  1573. AddressIndex - CompressStart
  1574. );
  1575. }
  1576. if (PrefixLength != NULL) {
  1577. *PrefixLength = LocalPrefixLength;
  1578. }
  1579. if (EndPointer != NULL) {
  1580. *EndPointer = (CHAR16 *) Pointer;
  1581. }
  1582. return RETURN_SUCCESS;
  1583. }
  1584. RETURN_STATUS
  1585. UnicodeStrToAsciiStrS (
  1586. CONST CHAR16 *Source,
  1587. CHAR8 *Destination,
  1588. UINTN DestMax
  1589. )
  1590. {
  1591. UINTN SourceLen;
  1592. ASSERT (((UINTN) Source & BIT0) == 0);
  1593. //
  1594. // 1. Neither Destination nor Source shall be a null pointer.
  1595. //
  1596. SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
  1597. SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
  1598. //
  1599. // 2. DestMax shall not be greater than ASCII_RSIZE_MAX or RSIZE_MAX.
  1600. //
  1601. if (ASCII_RSIZE_MAX != 0) {
  1602. SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= ASCII_RSIZE_MAX), RETURN_INVALID_PARAMETER);
  1603. }
  1604. if (RSIZE_MAX != 0) {
  1605. SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  1606. }
  1607. //
  1608. // 3. DestMax shall not equal zero.
  1609. //
  1610. SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
  1611. //
  1612. // 4. DestMax shall be greater than StrnLenS (Source, DestMax).
  1613. //
  1614. SourceLen = StrnLenS (Source, DestMax);
  1615. SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
  1616. //
  1617. // 5. Copying shall not take place between objects that overlap.
  1618. //
  1619. SAFE_STRING_CONSTRAINT_CHECK (!InternalSafeStringIsOverlap (Destination, DestMax, (VOID *)Source, (SourceLen + 1) * sizeof(CHAR16)), RETURN_ACCESS_DENIED);
  1620. //
  1621. // convert string
  1622. //
  1623. while (*Source != '\0') {
  1624. //
  1625. // If any Unicode characters in Source contain
  1626. // non-zero value in the upper 8 bits, then ASSERT().
  1627. //
  1628. ASSERT (*Source < 0x100);
  1629. *(Destination++) = (CHAR8) *(Source++);
  1630. }
  1631. *Destination = '\0';
  1632. return RETURN_SUCCESS;
  1633. }
  1634. RETURN_STATUS
  1635. StrCpyS (
  1636. CHAR16 *Destination,
  1637. UINTN DestMax,
  1638. CONST CHAR16 *Source
  1639. )
  1640. {
  1641. UINTN SourceLen;
  1642. ASSERT (((UINTN) Destination & BIT0) == 0);
  1643. ASSERT (((UINTN) Source & BIT0) == 0);
  1644. //
  1645. // 1. Neither Destination nor Source shall be a null pointer.
  1646. //
  1647. SAFE_STRING_CONSTRAINT_CHECK ((Destination != NULL), RETURN_INVALID_PARAMETER);
  1648. SAFE_STRING_CONSTRAINT_CHECK ((Source != NULL), RETURN_INVALID_PARAMETER);
  1649. //
  1650. // 2. DestMax shall not be greater than RSIZE_MAX.
  1651. //
  1652. if (RSIZE_MAX != 0) {
  1653. SAFE_STRING_CONSTRAINT_CHECK ((DestMax <= RSIZE_MAX), RETURN_INVALID_PARAMETER);
  1654. }
  1655. //
  1656. // 3. DestMax shall not equal zero.
  1657. //
  1658. SAFE_STRING_CONSTRAINT_CHECK ((DestMax != 0), RETURN_INVALID_PARAMETER);
  1659. //
  1660. // 4. DestMax shall be greater than StrnLenS(Source, DestMax).
  1661. //
  1662. SourceLen = StrnLenS (Source, DestMax);
  1663. SAFE_STRING_CONSTRAINT_CHECK ((DestMax > SourceLen), RETURN_BUFFER_TOO_SMALL);
  1664. //
  1665. // 5. Copying shall not take place between objects that overlap.
  1666. //
  1667. SAFE_STRING_CONSTRAINT_CHECK (InternalSafeStringNoStrOverlap (Destination, DestMax, (CHAR16 *)Source, SourceLen + 1), RETURN_ACCESS_DENIED);
  1668. //
  1669. // The StrCpyS function copies the string pointed to by Source (including the terminating
  1670. // null character) into the array pointed to by Destination.
  1671. //
  1672. while (*Source != 0) {
  1673. *(Destination++) = *(Source++);
  1674. }
  1675. *Destination = 0;
  1676. return RETURN_SUCCESS;
  1677. }
  1678. VOID *
  1679. AllocateZeroPool (
  1680. UINTN AllocationSize
  1681. )
  1682. {
  1683. VOID * Memory;
  1684. Memory = malloc(AllocationSize);
  1685. ASSERT (Memory != NULL);
  1686. if (Memory == NULL) {
  1687. fprintf(stderr, "Not memory for malloc\n");
  1688. }
  1689. memset(Memory, 0, AllocationSize);
  1690. return Memory;
  1691. }
  1692. VOID *
  1693. AllocatePool (
  1694. UINTN AllocationSize
  1695. )
  1696. {
  1697. return InternalAllocatePool (AllocationSize);
  1698. }
  1699. UINT16
  1700. WriteUnaligned16 (
  1701. UINT16 *Buffer,
  1702. UINT16 Value
  1703. )
  1704. {
  1705. ASSERT (Buffer != NULL);
  1706. return *Buffer = Value;
  1707. }
  1708. UINT16
  1709. ReadUnaligned16 (
  1710. CONST UINT16 *Buffer
  1711. )
  1712. {
  1713. ASSERT (Buffer != NULL);
  1714. return *Buffer;
  1715. }
  1716. /**
  1717. Return whether the integer string is a hex string.
  1718. @param Str The integer string
  1719. @retval TRUE Hex string
  1720. @retval FALSE Decimal string
  1721. **/
  1722. BOOLEAN
  1723. IsHexStr (
  1724. CHAR16 *Str
  1725. )
  1726. {
  1727. //
  1728. // skip preceding white space
  1729. //
  1730. while ((*Str != 0) && *Str == L' ') {
  1731. Str ++;
  1732. }
  1733. //
  1734. // skip preceding zeros
  1735. //
  1736. while ((*Str != 0) && *Str == L'0') {
  1737. Str ++;
  1738. }
  1739. return (BOOLEAN) (*Str == L'x' || *Str == L'X');
  1740. }
  1741. /**
  1742. Convert integer string to uint.
  1743. @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
  1744. @return A UINTN value represented by Str
  1745. **/
  1746. UINTN
  1747. Strtoi (
  1748. CHAR16 *Str
  1749. )
  1750. {
  1751. if (IsHexStr (Str)) {
  1752. return (UINTN)StrHexToUint64 (Str);
  1753. } else {
  1754. return (UINTN)StrDecimalToUint64 (Str);
  1755. }
  1756. }
  1757. /**
  1758. Convert integer string to 64 bit data.
  1759. @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
  1760. @param Data A pointer to the UINT64 value represented by Str
  1761. **/
  1762. VOID
  1763. Strtoi64 (
  1764. CHAR16 *Str,
  1765. UINT64 *Data
  1766. )
  1767. {
  1768. if (IsHexStr (Str)) {
  1769. *Data = StrHexToUint64 (Str);
  1770. } else {
  1771. *Data = StrDecimalToUint64 (Str);
  1772. }
  1773. }
  1774. /**
  1775. Converts a Unicode string to ASCII string.
  1776. @param Str The equivalent Unicode string
  1777. @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
  1778. to the next ASCII string next to it
  1779. **/
  1780. VOID
  1781. StrToAscii (
  1782. CHAR16 *Str,
  1783. CHAR8 **AsciiStr
  1784. )
  1785. {
  1786. CHAR8 *Dest;
  1787. Dest = *AsciiStr;
  1788. while (!IS_NULL (*Str)) {
  1789. *(Dest++) = (CHAR8) *(Str++);
  1790. }
  1791. *Dest = 0;
  1792. //
  1793. // Return the string next to it
  1794. //
  1795. *AsciiStr = Dest + 1;
  1796. }
  1797. /**
  1798. Gets current sub-string from a string list, before return
  1799. the list header is moved to next sub-string. The sub-string is separated
  1800. by the specified character. For example, the separator is ',', the string
  1801. list is "2,0,3", it returns "2", the remain list move to "0,3"
  1802. @param List A string list separated by the specified separator
  1803. @param Separator The separator character
  1804. @return A pointer to the current sub-string
  1805. **/
  1806. CHAR16 *
  1807. SplitStr (
  1808. CHAR16 **List,
  1809. CHAR16 Separator
  1810. )
  1811. {
  1812. CHAR16 *Str;
  1813. CHAR16 *ReturnStr;
  1814. Str = *List;
  1815. ReturnStr = Str;
  1816. if (IS_NULL (*Str)) {
  1817. return ReturnStr;
  1818. }
  1819. //
  1820. // Find first occurrence of the separator
  1821. //
  1822. while (!IS_NULL (*Str)) {
  1823. if (*Str == Separator) {
  1824. break;
  1825. }
  1826. Str++;
  1827. }
  1828. if (*Str == Separator) {
  1829. //
  1830. // Find a sub-string, terminate it
  1831. //
  1832. *Str = L'\0';
  1833. Str++;
  1834. }
  1835. //
  1836. // Move to next sub-string
  1837. //
  1838. *List = Str;
  1839. return ReturnStr;
  1840. }