1 /** 2 @file 3 Display the configuration table 4 5 Copyright (c) 2011-2012, Intel Corporation 6 All rights reserved. This program and the accompanying materials 7 are licensed and made available under the terms and conditions of the BSD License 8 which accompanies this distribution. The full text of the license may be found at 9 http://opensource.org/licenses/bsd-license.php 10 11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13 14 **/ 15 16 #include <WebServer.h> 17 #include <Guid/Acpi.h> 18 #include <Guid/DebugImageInfoTable.h> 19 #include <Guid/DxeServices.h> 20 #include <Guid/HobList.h> 21 #include <Guid/MemoryTypeInformation.h> 22 #include <Guid/LoadModuleAtFixedAddress.h> 23 24 25 typedef struct { 26 CHAR16 * GuidName; 27 EFI_GUID * pGuid; 28 CHAR16 * pWebPage; 29 } GUID_NAME; 30 31 CONST GUID_NAME mGuidName[] = { 32 { L"gEfiAcpi10TableGuid", &gEfiAcpi10TableGuid, PAGE_ACPI_RSDP_10B }, 33 { L"gEfiAcpiTableGuid", &gEfiAcpiTableGuid, PAGE_ACPI_RSDP_30 }, 34 { L"gEfiDebugImageInfoTableGuid", &gEfiDebugImageInfoTableGuid, NULL }, 35 { L"gEfiDxeServicesTableGuid", &gEfiDxeServicesTableGuid, PAGE_DXE_SERVICES_TABLE }, 36 { L"gEfiHobListGuid", &gEfiHobListGuid, NULL }, 37 { L"gEfiMemoryTypeInformationGuid", &gEfiMemoryTypeInformationGuid, NULL }, 38 { L"gLoadFixedAddressConfigurationTableGuid", &gLoadFixedAddressConfigurationTableGuid, NULL } 39 }; 40 41 /** 42 Display a row containing a GUID value 43 44 @param [in] SocketFD The socket's file descriptor to add to the list. 45 @param [in] pPort The WSDT_PORT structure address 46 @param [in] pName Address of a zero terminated name string 47 @param [in] pGuid Address of the GUID to display 48 49 @retval EFI_SUCCESS The request was successfully processed 50 51 **/ 52 EFI_STATUS 53 RowGuid ( 54 IN int SocketFD, 55 IN WSDT_PORT * pPort, 56 IN CONST CHAR8 * pName, 57 IN CONST EFI_GUID * pGuid 58 ) 59 { 60 CONST GUID_NAME * pGuidName; 61 CONST GUID_NAME * pGuidNameEnd; 62 EFI_STATUS Status; 63 UINTN Value; 64 65 DBG_ENTER ( ); 66 67 // 68 // Use for/break instead of goto 69 // 70 for ( ; ; ) { 71 Status = HttpSendAnsiString ( SocketFD, 72 pPort, 73 "<tr><td>" ); 74 if ( EFI_ERROR ( Status )) { 75 break; 76 } 77 Status = HttpSendAnsiString ( SocketFD, 78 pPort, 79 pName ); 80 if ( EFI_ERROR ( Status )) { 81 break; 82 } 83 Status = HttpSendAnsiString ( SocketFD, 84 pPort, 85 "</td><td><code>" ); 86 if ( EFI_ERROR ( Status )) { 87 break; 88 } 89 90 // 91 // Determine if this is a known GUID 92 // 93 pGuidName = &mGuidName[0]; 94 pGuidNameEnd = &pGuidName[ sizeof ( mGuidName ) / sizeof ( mGuidName[0])]; 95 while ( pGuidNameEnd > pGuidName ) { 96 if ( CompareGuid ( pGuidName->pGuid, pGuid )) { 97 // 98 // Display the web link if available 99 // 100 if ( NULL != pGuidName->pWebPage ) { 101 Status = HttpSendAnsiString ( SocketFD, 102 pPort, 103 "<a target=\"_blank\" href=\"" ); 104 if ( EFI_ERROR ( Status )) { 105 break; 106 } 107 Status = HttpSendUnicodeString ( SocketFD, 108 pPort, 109 pGuidName->pWebPage ); 110 if ( EFI_ERROR ( Status )) { 111 break; 112 } 113 Status = HttpSendAnsiString ( SocketFD, 114 pPort, 115 "\">" ); 116 if ( EFI_ERROR ( Status )) { 117 break; 118 } 119 } 120 121 // 122 // Display the GUID name 123 // 124 Status = HttpSendUnicodeString ( SocketFD, 125 pPort, 126 pGuidName->GuidName ); 127 128 // 129 // Complete the web link if available 130 // 131 if ( NULL != pGuidName->pWebPage ) { 132 if ( EFI_ERROR ( Status )) { 133 break; 134 } 135 Status = HttpSendAnsiString ( SocketFD, 136 pPort, 137 "</a>" ); 138 } 139 break; 140 } 141 142 // 143 // Set the next GUID name 144 // 145 pGuidName += 1; 146 } 147 if ( EFI_ERROR ( Status )) { 148 break; 149 } 150 151 // 152 // Only if the entry is not known, display the GUID and type 153 // 154 if ( pGuidNameEnd <= pGuidName ) { 155 // 156 // Display the GUID 157 // 158 Status = HttpSendGuid ( SocketFD, 159 pPort, 160 pGuid ); 161 if ( EFI_ERROR ( Status )) { 162 break; 163 } 164 165 // 166 // Display the GUID type 167 // 168 Status = HttpSendAnsiString ( SocketFD, 169 pPort, 170 "<br/><a target=\"_blank\" href=\"http://www.ietf.org/rfc/rfc4122.txt\">Guid Type</a>: " ); 171 if ( EFI_ERROR ( Status )) { 172 break; 173 } 174 Value = pGuid->Data4[1]; 175 Value >>= 5; 176 if ( 3 >= Value ) { 177 // 178 // Network type 179 // 180 Status = HttpSendAnsiString ( SocketFD, 181 pPort, 182 "Network " ); 183 } 184 else if ( 5 >= Value ) { 185 // 186 // Standard type 187 // 188 Status = HttpSendAnsiString ( SocketFD, 189 pPort, 190 "Standard " ); 191 if ( EFI_ERROR ( Status )) { 192 break; 193 } 194 195 // 196 // Decode the standard type using RFC 4122 197 // 198 Value = pGuid->Data3; 199 Value >>= 12; 200 switch ( Value ) { 201 default: 202 // 203 // Display the MAC address 204 // 205 Status = HttpSendAnsiString ( SocketFD, 206 pPort, 207 "Version " ); 208 if ( EFI_ERROR ( Status )) { 209 break; 210 } 211 Status = HttpSendValue ( SocketFD, 212 pPort, 213 pGuid->Data3 >> 12 ); 214 break; 215 216 case 1: 217 Status = HttpSendAnsiString ( SocketFD, 218 pPort, 219 "MAC address" ); 220 break; 221 222 case 2: 223 Status = HttpSendAnsiString ( SocketFD, 224 pPort, 225 "DCE Security" ); 226 break; 227 228 case 3: 229 Status = HttpSendAnsiString ( SocketFD, 230 pPort, 231 "MD5 hash" ); 232 break; 233 234 case 4: 235 Status = HttpSendAnsiString ( SocketFD, 236 pPort, 237 "Random" ); 238 break; 239 240 case 5: 241 Status = HttpSendAnsiString ( SocketFD, 242 pPort, 243 "SHA-1 hash" ); 244 break; 245 } 246 } 247 else if ( 6 == Value ) { 248 // 249 // Microsoft's Component Object Model (COM) type 250 // 251 Status = HttpSendAnsiString ( SocketFD, 252 pPort, 253 "Microsoft COM" ); 254 } 255 else { 256 // 257 // Reserved type 258 // 259 Status = HttpSendAnsiString ( SocketFD, 260 pPort, 261 "Reserved" ); 262 } 263 } 264 265 // 266 // Done with this entry 267 // 268 Status = HttpSendAnsiString ( SocketFD, 269 pPort, 270 "</code></td></tr>\r\n" ); 271 break; 272 } 273 274 // 275 // Return the operation status 276 // 277 DBG_EXIT_STATUS ( Status ); 278 return Status; 279 } 280 281 282 /** 283 Respond with the configuration tables 284 285 @param [in] SocketFD The socket's file descriptor to add to the list. 286 @param [in] pPort The WSDT_PORT structure address 287 @param [out] pbDone Address to receive the request completion status 288 289 @retval EFI_SUCCESS The request was successfully processed 290 291 **/ 292 EFI_STATUS 293 ConfigurationTablePage ( 294 IN int SocketFD, 295 IN WSDT_PORT * pPort, 296 OUT BOOLEAN * pbDone 297 ) 298 { 299 EFI_CONFIGURATION_TABLE * pEnd; 300 EFI_CONFIGURATION_TABLE * pTable; 301 EFI_STATUS Status; 302 303 DBG_ENTER ( ); 304 305 // 306 // Send the system table page 307 // 308 for ( ; ; ) { 309 // 310 // Send the page and table header 311 // 312 Status = TableHeader ( SocketFD, pPort, L"Configuration Tables", gST ); 313 if ( EFI_ERROR ( Status )) { 314 break; 315 } 316 317 // 318 // Display the table size 319 // 320 Status = RowDecimalValue ( SocketFD, 321 pPort, 322 "Entries", 323 gST->NumberOfTableEntries ); 324 if ( EFI_ERROR ( Status )) { 325 break; 326 } 327 328 // 329 // Determine the location of the configuration tables 330 // 331 pTable = gST->ConfigurationTable; 332 pEnd = &pTable[ gST->NumberOfTableEntries ]; 333 while ( pEnd > pTable ) { 334 Status = RowGuid ( SocketFD, 335 pPort, 336 "VendorGuid", 337 &pTable->VendorGuid ); 338 if ( EFI_ERROR ( Status )) { 339 break; 340 } 341 Status = RowPointer ( SocketFD, 342 pPort, 343 "VendorTable", 344 (VOID *)pTable->VendorTable, 345 NULL ); 346 if ( EFI_ERROR ( Status )) { 347 break; 348 } 349 350 // 351 // Set the next row 352 // 353 pTable += 1; 354 } 355 356 // 357 // Build the table trailer 358 // 359 Status = TableTrailer ( SocketFD, 360 pPort, 361 pbDone ); 362 break; 363 } 364 365 // 366 // Return the operation status 367 // 368 DBG_EXIT_STATUS ( Status ); 369 return Status; 370 } 371