1/** 2 @file 3 Display the handles in the system 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 18 19/** 20 Respond with the handles in the system 21 22 @param [in] SocketFD The socket's file descriptor to add to the list. 23 @param [in] pPort The WSDT_PORT structure address 24 @param [out] pbDone Address to receive the request completion status 25 26 @retval EFI_SUCCESS The request was successfully processed 27 28**/ 29EFI_STATUS 30HandlePage ( 31 IN int SocketFD, 32 IN WSDT_PORT * pPort, 33 OUT BOOLEAN * pbDone 34 ) 35{ 36 INTN Digit; 37 INTN Entries; 38 INTN Index; 39 UINTN GuidCount; 40 UINTN LengthInBytes; 41 UINT8 * pDigit; 42 EFI_HANDLE * pHandleArray; 43 EFI_HANDLE * pHandle; 44 EFI_HANDLE * pHandleEnd; 45 EFI_GUID ** ppGuidArray; 46 EFI_GUID ** ppGuid; 47 EFI_GUID ** ppGuidEnd; 48 INTN Shift; 49 EFI_STATUS Status; 50 UINTN Value; 51 CONST UINTN cDigit [] = { 52 3, 2, 1, 0, 5, 4, 7, 6, 8, 9, 10, 11, 12, 13, 14, 15 }; 53 54 DBG_ENTER ( ); 55 56 // 57 // Send the handles page 58 // 59 for ( ; ; ) { 60 // 61 // Send the page header 62 // 63 Status = HttpPageHeader ( SocketFD, pPort, L"Handle Database" ); 64 if ( EFI_ERROR ( Status )) { 65 break; 66 } 67 68 // 69 // Build the table header 70 // 71 Status = HttpSendAnsiString ( SocketFD, 72 pPort, 73 "<h1>Handle Database</h1>\r\n" 74 "<table border=\"1\">\r\n" 75 " <tr bgcolor=\"c0c0ff\"><th>Handle</th><th>Protocol Guids</th></tr>\r\n" ); 76 if ( EFI_ERROR ( Status )) { 77 break; 78 } 79 80 // 81 // Determine the number of handles in the database 82 // 83 LengthInBytes = 0; 84 Status = gBS->LocateHandle ( AllHandles, 85 NULL, 86 NULL, 87 &LengthInBytes, 88 NULL ); 89 if ( EFI_BUFFER_TOO_SMALL == Status ) { 90 // 91 // Allocate space for the handles 92 // 93 Status = gBS->AllocatePool ( EfiRuntimeServicesData, 94 LengthInBytes, 95 (VOID **) &pHandleArray ); 96 if ( !EFI_ERROR ( Status )) { 97 // 98 // Get the list of handles 99 // 100 Status = gBS->LocateHandle ( AllHandles, 101 NULL, 102 NULL, 103 &LengthInBytes, 104 pHandleArray ); 105 if ( !EFI_ERROR ( Status )) { 106 Entries = LengthInBytes / sizeof ( *pHandleArray ); 107 pHandle = pHandleArray; 108 pHandleEnd = &pHandle [ Entries ]; 109 while ( pHandleEnd > pHandle ) { 110 // 111 // Build the table entry for this page 112 // 113 Status = HttpSendAnsiString ( SocketFD, 114 pPort, 115 "<tr><td><code>0x" ); 116 if ( EFI_ERROR ( Status )) { 117 break; 118 } 119 Value = (UINTN) *pHandle; 120 for ( Shift = ( sizeof ( Shift ) << 3 ) - 4; 0 <= Shift; Shift -= 4 ) { 121 // 122 // Convert the next address nibble to ANSI hex 123 // 124 Digit = (( Value >> Shift ) & 0xf ) | '0'; 125 if ( '9' < Digit ) { 126 Digit += 'a' - '0' - 10; 127 } 128 129 // 130 // Display the address digit 131 // 132 Status = HttpSendByte ( SocketFD, 133 pPort, 134 (UINT8) Digit ); 135 if ( EFI_ERROR ( Status )) { 136 break; 137 } 138 } 139 if ( EFI_ERROR ( Status )) { 140 break; 141 } 142 143 // 144 // Start the second column 145 // 146 Status = HttpSendAnsiString ( SocketFD, 147 pPort, 148 "</code></td><td><code>\r\n" ); 149 if ( EFI_ERROR ( Status )) { 150 break; 151 } 152 153 // 154 // Determine the number of protocols connected to this handle 155 // 156 Status = gBS->ProtocolsPerHandle ( *pHandle, 157 &ppGuidArray, 158 &GuidCount ); 159 if ( EFI_ERROR ( Status )) { 160 break; 161 } 162 ppGuid = ppGuidArray; 163 ppGuidEnd = &ppGuid [ GuidCount ]; 164 while ( ppGuidEnd > ppGuid ) { 165 // 166 // Display the guid 167 // 168 pDigit = (UINT8 *) *ppGuid; 169 for ( Index = 0; 16 > Index; Index++ ) { 170 // 171 // Separate the portions of the GUID 172 // 99E87DCF-6162-40c5-9FA1-32111F5197F7 173 // 174 if (( 4 == Index ) 175 || ( 6 == Index ) 176 || ( 8 == Index ) 177 || ( 10 == Index )) { 178 Status = HttpSendByte ( SocketFD, 179 pPort, 180 '-' ); 181 if ( EFI_ERROR ( Status )) { 182 break; 183 } 184 } 185 186 // 187 // Display the GUID digits 188 // 189 Value = pDigit [ cDigit [ Index ]]; 190 for ( Shift = 4; 0 <= Shift; Shift -= 4 ) { 191 // 192 // Convert the next address nibble to ANSI hex 193 // 194 Digit = (( Value >> Shift ) & 0xf ) | '0'; 195 if ( '9' < Digit ) { 196 Digit += 'a' - '0' - 10; 197 } 198 199 // 200 // Display the address digit 201 // 202 Status = HttpSendByte ( SocketFD, 203 pPort, 204 (UINT8) Digit ); 205 if ( EFI_ERROR ( Status )) { 206 break; 207 } 208 } 209 if ( EFI_ERROR ( Status )) { 210 break; 211 } 212 } 213 214 // 215 // Separate each GUID 216 // 217 Status = HttpSendAnsiString ( SocketFD, 218 pPort, 219 "<br/>\r\n" ); 220 if ( EFI_ERROR ( Status )) { 221 break; 222 } 223 224 // 225 // Set the next protocol 226 // 227 ppGuid+= 1; 228 } 229 230 // 231 // Free the GUID array 232 // 233 gBS->FreePool ( ppGuidArray ); 234 if ( EFI_ERROR ( Status )) { 235 break; 236 } 237 238 // 239 // End the row 240 // 241 Status = HttpSendAnsiString ( SocketFD, 242 pPort, 243 "</code></td></tr>\r\n" ); 244 if ( EFI_ERROR ( Status )) { 245 break; 246 } 247 248 // 249 // Set the next handle 250 // 251 pHandle += 1; 252 } 253 } 254 255 // 256 // Done with the handle array 257 // 258 gBS->FreePool ( pHandleArray ); 259 } 260 } 261 262 // 263 // Build the table trailer 264 // 265 Status = HttpSendAnsiString ( SocketFD, 266 pPort, 267 "</table>\r\n" ); 268 if ( EFI_ERROR ( Status )) { 269 break; 270 } 271 272 // 273 // Send the page trailer 274 // 275 Status = HttpPageTrailer ( SocketFD, pPort, pbDone ); 276 break; 277 } 278 279 // 280 // Return the operation status 281 // 282 DBG_EXIT_STATUS ( Status ); 283 return Status; 284} 285