Home | History | Annotate | Download | only in WebServer
      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 **/
     29 EFI_STATUS
     30 HandlePage (
     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