1 | /*␊ |
2 | * Convert.c␊ |
3 | * Implement conversion utility functions␊ |
4 | * Create UUID parsing functions and gather other conversion routines␊ |
5 | * --Rek␊ |
6 | */␊ |
7 | ␊ |
8 | #include "convert.h"␊ |
9 | ␊ |
10 | /** Transform a 16 bytes hexadecimal value UUID to a string */␊ |
11 | const char * getStringFromUUID(const EFI_CHAR8* eUUID)␊ |
12 | {␊ |
13 | ␉static char msg[UUID_LEN*2 + 8] = "";␊ |
14 | ␉if (!eUUID) return "";␊ |
15 | ␉const unsigned char * uuid = (unsigned char*) eUUID;␊ |
16 | ␉sprintf(msg, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",␊ |
17 | ␉␉ uuid[0], uuid[1], uuid[2], uuid[3], ␊ |
18 | ␉␉ uuid[4], uuid[5], uuid[6], uuid[7],␊ |
19 | ␉␉ uuid[8], uuid[9], uuid[10],uuid[11],␊ |
20 | ␉␉ uuid[12],uuid[13],uuid[14],uuid[15]);␊ |
21 | ␉return msg ;␊ |
22 | }␊ |
23 | ␊ |
24 | /** Parse an UUID string into an (EFI_CHAR8*) buffer */␊ |
25 | EFI_CHAR8* getUUIDFromString(const char *source)␊ |
26 | {␊ |
27 | ␉if (!source)␊ |
28 | ␉{␊ |
29 | ␉␉return 0;␊ |
30 | ␉}␊ |
31 | ␊ |
32 | ␉int␉i = strlen(source);␊ |
33 | ␉if (i != 36)␊ |
34 | ␉{ // e.g 00112233-4455-6677-8899-AABBCCDDEEFF␊ |
35 | ␉␉verbose("[ERROR] UUID='%s' has incorrect length=%d. Use format: 00112233-4455-6677-8899-AABBCCDDEEFF.\n", source, i);␊ |
36 | ␉␉return 0;␊ |
37 | ␉}␊ |
38 | ␊ |
39 | ␉char␉*p = (char *)source;␊ |
40 | ␉char␉buf[3];␊ |
41 | ␉static EFI_CHAR8 uuid[UUID_LEN+1] = "";␊ |
42 | ␊ |
43 | ␉buf[2] = '\0';␊ |
44 | ␉for (i = 0; i < UUID_LEN; i++)␊ |
45 | ␉{␊ |
46 | ␉␉if (p[0] == '\0' || p[1] == '\0' || !isxdigit(p[0]) || !isxdigit(p[1]))␊ |
47 | ␉␉{␊ |
48 | ␉␉␉verbose("[ERROR] UUID='%s' syntax error.\n", source);␊ |
49 | ␉␉␉return 0;␊ |
50 | ␉␉}␊ |
51 | ␉␉buf[0] = *p++;␊ |
52 | ␉␉buf[1] = *p++;␊ |
53 | ␉␉uuid[i] = (unsigned char) strtoul(buf, NULL, 16);␊ |
54 | ␉␉if ((*p == '-') && ((i % 2) == 1) && (i < UUID_LEN - 1))␊ |
55 | ␉␉{␊ |
56 | ␉␉␉p++;␊ |
57 | ␉␉}␊ |
58 | ␉}␊ |
59 | ␉uuid[UUID_LEN]='\0';␊ |
60 | ␊ |
61 | ␉if (*p != '\0')␊ |
62 | ␉{␊ |
63 | ␉␉verbose("[ERROR] UUID='%s' syntax error\n", source);␊ |
64 | ␉␉return 0;␊ |
65 | ␉}␊ |
66 | ␉return uuid;␊ |
67 | }␊ |
68 | ␊ |
69 | /** XXX AsereBLN replace by strtoul */␊ |
70 | uint32_t ascii_hex_to_int(char *buff) ␊ |
71 | {␊ |
72 | ␉uint32_t␉value = 0, i, digit;␊ |
73 | ␉for(i = 0; i < strlen(buff); i++)␊ |
74 | ␉{␊ |
75 | ␉␉if (buff[i] >= 48 && buff[i] <= 57)␉␉// '0' through '9'␊ |
76 | ␉␉␉digit = buff[i] - 48;␊ |
77 | ␉␉else if (buff[i] >= 65 && buff[i] <= 70)␉// 'A' through 'F'␊ |
78 | ␉␉␉digit = buff[i] - 55;␊ |
79 | ␉␉else if (buff[i] >= 97 && buff[i] <= 102)␉// 'a' through 'f'␊ |
80 | ␉␉␉digit = buff[i] - 87;␊ |
81 | ␉␉else␊ |
82 | ␉␉␉return value;␊ |
83 | ␊ |
84 | ␉␉value = digit + 16 * value;␊ |
85 | ␉}␊ |
86 | ␉return␉value;␊ |
87 | }␊ |
88 | ␊ |
89 | void *convertHexStr2Binary(const char *hexStr, int *outLength)␊ |
90 | {␊ |
91 | ␉int len;␊ |
92 | ␉char hexNibble;␊ |
93 | ␉char hexByte[2];␊ |
94 | ␉uint8_t binChar;␊ |
95 | ␉uint8_t *binStr;␊ |
96 | ␉int hexStrIdx, binStrIdx, hexNibbleIdx;␊ |
97 | ␊ |
98 | ␉len = strlen(hexStr);␊ |
99 | ␉if (len > 1)␊ |
100 | ␉{␊ |
101 | ␉␉// the resulting binary will be the half size of the input hex string␊ |
102 | ␉␉binStr = malloc(len / 2);␊ |
103 | ␊ |
104 | ␉␉binStrIdx = 0;␊ |
105 | ␉␉hexNibbleIdx = 0;␊ |
106 | ␉␉for (hexStrIdx = 0; hexStrIdx < len; hexStrIdx++)␊ |
107 | ␉␉{␊ |
108 | ␉␉␉hexNibble = hexStr[hexStrIdx];␊ |
109 | ␊ |
110 | ␉␉␉// ignore all chars except valid hex numbers␊ |
111 | ␉␉␉if ( (hexNibble >= '0' && hexNibble <= '9') ||␊ |
112 | ␉␉␉␉(hexNibble >= 'A' && hexNibble <= 'F') ||␊ |
113 | ␉␉␉␉(hexNibble >= 'a' && hexNibble <= 'f') )␊ |
114 | ␉␉␉{␊ |
115 | ␉␉␉␉hexByte[hexNibbleIdx++] = hexNibble;␊ |
116 | ␊ |
117 | ␉␉␉␉// found both two nibbles, convert to binary␊ |
118 | ␉␉␉␉if (hexNibbleIdx == 2)␊ |
119 | ␉␉␉␉{␊ |
120 | ␉␉␉␉␉binChar = 0;␊ |
121 | ␊ |
122 | ␉␉␉␉for (hexNibbleIdx = 0; hexNibbleIdx < sizeof(hexByte); hexNibbleIdx++)␊ |
123 | ␉␉␉␉{␊ |
124 | ␉␉␉␉␉if (hexNibbleIdx > 0)␊ |
125 | ␉␉␉␉␉{␊ |
126 | ␉␉␉␉␉␉binChar = binChar << 4;␊ |
127 | ␉␉␉␉␉}␊ |
128 | ␊ |
129 | ␉␉␉␉␉if (hexByte[hexNibbleIdx] <= '9') binChar += hexByte[hexNibbleIdx] - '0';␊ |
130 | ␉␉␉␉␉else if (hexByte[hexNibbleIdx] <= 'F') binChar += hexByte[hexNibbleIdx] - ('A' - 10);␊ |
131 | ␉␉␉␉␉else if (hexByte[hexNibbleIdx] <= 'f') binChar += hexByte[hexNibbleIdx] - ('a' - 10);␊ |
132 | ␉␉␉␉}␊ |
133 | ␊ |
134 | ␉␉␉␉binStr[binStrIdx++] = binChar;␉␉␉␉␉␉␊ |
135 | ␉␉␉␉hexNibbleIdx = 0;␊ |
136 | ␉␉␉␉}␊ |
137 | ␉␉␉}␊ |
138 | ␉␉}␊ |
139 | ␉␉*outLength = binStrIdx;␊ |
140 | ␉␉return binStr;␊ |
141 | ␉}␊ |
142 | ␉else␊ |
143 | ␉{␊ |
144 | ␉␉*outLength = 0;␊ |
145 | ␉␉return NULL;␊ |
146 | ␉}␊ |
147 | }␊ |
148 | ␊ |
149 | // FIXME: can't use my original code here,␊ |
150 | // Ironically, trying to reuse convertHexStr2Binary() would RESET the system!␊ |
151 | /*␊ |
152 | static EFI_CHAR8* getUUIDFromString2(const char * szInUUID)␊ |
153 | {␊ |
154 | char szUUID[UUID_LEN+1], *p=szUUID;␊ |
155 | int size=0;␊ |
156 | void* ret;␊ |
157 | ␊ |
158 | if (!szInUUID || strlen(szInUUID)<UUID_LEN) return (EFI_CHAR8*) 0;␊ |
159 | ␊ |
160 | while(*szInUUID) if (*szInUUID!='-') *p++=*szInUUID++; else szInUUID++;␊ |
161 | *p='\0';␊ |
162 | ret = convertHexStr2Binary(szUUID, &size);␊ |
163 | if (!ret || size!=UUID_LEN) ␊ |
164 | {␊ |
165 | verbose("UUID: cannot convert string <%s> to valid UUID.\n", szUUID);␊ |
166 | return (EFI_CHAR8*) 0;␊ |
167 | }␊ |
168 | return (EFI_CHAR8*) ret; // new allocated buffer containing the converted string to bin␊ |
169 | }␊ |
170 | */␊ |
171 | |