Use the BSD license Fix errors detected by GCC compiler in WebServer/ConfigurationTable.c Add libraries: CpuLib, DxeServicesTableLib and MtrrLib Signed-off-by: lpleahy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13115 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1736 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1736 lines
		
	
	
		
			39 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
  @file
 | 
						|
  HTTP processing for the web server.
 | 
						|
 | 
						|
  Copyright (c) 2011-2012, Intel Corporation
 | 
						|
  All rights reserved. This program and the accompanying materials
 | 
						|
  are licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include <WebServer.h>
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Get a UTF-8 character from the buffer
 | 
						|
 | 
						|
  @param [in] pData     The address of the buffer containing the character
 | 
						|
  @param [out] ppData   The address to receive the next character address
 | 
						|
 | 
						|
  @return     The character value
 | 
						|
 | 
						|
**/
 | 
						|
INTN
 | 
						|
HttpCharGet (
 | 
						|
  IN UINT8 * pData,
 | 
						|
  IN UINT8 ** ppData
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN Data;
 | 
						|
  INTN Character;
 | 
						|
  INTN Control;
 | 
						|
  INTN Mask;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Verify that there is some data left
 | 
						|
  //
 | 
						|
  if ( NULL == pData ) {
 | 
						|
    //
 | 
						|
    //  No data to return
 | 
						|
    //
 | 
						|
    pData = NULL;
 | 
						|
    Character = 0;
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    //
 | 
						|
    //  Get the first portion of the character
 | 
						|
    //
 | 
						|
    Character = *pData++;
 | 
						|
    Control = Character;
 | 
						|
    Mask = 0xc0;
 | 
						|
 | 
						|
    //
 | 
						|
    //  Append the rest of the character
 | 
						|
    //
 | 
						|
    if ( 0 != ( Control & 0x80 )) {
 | 
						|
      while ( 0 != ( Control & 0x40 )) {
 | 
						|
        Character &= Mask;
 | 
						|
        Mask <<= 5;
 | 
						|
        Control <<= 1;
 | 
						|
        Character <<= 6;
 | 
						|
        Data = *pData++ & 0x3f;
 | 
						|
        if ( 0x80 != ( Data & 0xc0 )) {
 | 
						|
          //
 | 
						|
          //  Invalid character
 | 
						|
          //
 | 
						|
          pData = NULL;
 | 
						|
          Character = 0;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        Character |= Data & 0x3f;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the next character location and the character
 | 
						|
  //
 | 
						|
  *ppData = pData;
 | 
						|
  return Character;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Transmit a portion of the HTTP response
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpFlush (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN LengthInBytes;
 | 
						|
  UINT8 * pBuffer;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  pBuffer = &pPort->TxBuffer[0];
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    //  Attempt to send the data
 | 
						|
    //
 | 
						|
    LengthInBytes = send ( SocketFD,
 | 
						|
                           pBuffer,
 | 
						|
                           pPort->TxBytes,
 | 
						|
                           0 );
 | 
						|
    if ( -1 != LengthInBytes ) {
 | 
						|
      //
 | 
						|
      //  Account for the data sent
 | 
						|
      //
 | 
						|
      pBuffer += LengthInBytes;
 | 
						|
      pPort->TxBytes -= LengthInBytes;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      //
 | 
						|
      //  Transmit error
 | 
						|
      //
 | 
						|
      Status = EFI_DEVICE_ERROR;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  } while ( 0 < pPort->TxBytes );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Convert the ANSI character to lower case
 | 
						|
 | 
						|
  @param [in] Character The character to convert to lower case.
 | 
						|
 | 
						|
  @return   The lower case character
 | 
						|
 | 
						|
**/
 | 
						|
INTN
 | 
						|
HttpLowerCase (
 | 
						|
  IN INTN Character
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  //  Determine if the character is upper case
 | 
						|
  //
 | 
						|
  if (( 'A' <= Character ) && ( 'Z' >= Character )) {
 | 
						|
    Character += 'a' - 'A';
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the lower case value of the character
 | 
						|
  //
 | 
						|
  return Character;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Match a Unicode string against a UTF-8 string
 | 
						|
 | 
						|
  @param [in] pString     A zero terminated Unicode string
 | 
						|
  @param [in] pData       A zero terminated UTF-8 string
 | 
						|
  @param [in] bIgnoreCase TRUE if case is to be ignored
 | 
						|
 | 
						|
  @return     The difference between the last two characters tested.
 | 
						|
              Returns -1 for error.
 | 
						|
 | 
						|
**/
 | 
						|
INTN
 | 
						|
HttpMatch (
 | 
						|
  IN UINT16 * pString,
 | 
						|
  IN UINT8 * pData,
 | 
						|
  IN BOOLEAN bIgnoreCase
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN Character1;
 | 
						|
  INTN Character2;
 | 
						|
  INTN Difference;
 | 
						|
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    //  Get the character from the comparison string
 | 
						|
    //
 | 
						|
    Character1 = *pString++;
 | 
						|
 | 
						|
    //
 | 
						|
    //  Convert the character to lower case
 | 
						|
    //
 | 
						|
    if ( bIgnoreCase ) {
 | 
						|
      Character1 = HttpLowerCase ( Character1 );
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Get the character from the request
 | 
						|
    //
 | 
						|
    Character2 = HttpCharGet ( pData, &pData );
 | 
						|
    if ( NULL == pData ) {
 | 
						|
       //
 | 
						|
       // Error getting character
 | 
						|
       //
 | 
						|
       Difference = -1;
 | 
						|
       break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Convert the character to lower case
 | 
						|
    //
 | 
						|
    if ( bIgnoreCase ) {
 | 
						|
      Character2 = HttpLowerCase ( Character2 );
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Compare the characters
 | 
						|
    //
 | 
						|
    Difference = Character1 - Character2;
 | 
						|
    if ( 0 != Difference ) {
 | 
						|
      return Difference;
 | 
						|
    }
 | 
						|
  } while ( 0 != Character1 );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the difference
 | 
						|
  //
 | 
						|
  return Difference;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Buffer the HTTP page header
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] pTitle        A zero terminated Unicode title string
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpPageHeader (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN CONST CHAR16 * pTitle
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Build the page header
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  "<!DOCTYPE "
 | 
						|
                                  "HTML "
 | 
						|
                                  "PUBLIC "
 | 
						|
                                  "\"-//W3C//DTD HTML 4.01 Transitional//EN\" "
 | 
						|
                                  "\"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendAnsiString ( SocketFD, pPort, "<html lang=\"en-US\">\r\n" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    if ( NULL != pTitle ) {
 | 
						|
      Status = HttpSendAnsiString ( SocketFD, pPort, "  <head>\r\n" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendAnsiString ( SocketFD, pPort, "    <title>" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendUnicodeString ( SocketFD, pPort, pTitle );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendAnsiString ( SocketFD, pPort, "</title>\r\n" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendAnsiString ( SocketFD, pPort, "  </head>\r\n" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    Status = HttpSendAnsiString ( SocketFD, pPort, "  <body>\r\n" );
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Respond with an error indicating that the page was not found
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [out] pbDone       Address to receive the request completion status
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpPageNotFound (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN BOOLEAN * pbDone
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Send the page not found
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    //
 | 
						|
    //  Send the page header
 | 
						|
    //
 | 
						|
    Status = HttpPageHeader ( SocketFD, pPort, L"404 Not found" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Send the page body
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  "ERROR <b>404</b><br />"
 | 
						|
                                  "Requested page is not available\r\n" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Send the page trailer
 | 
						|
    //
 | 
						|
    Status = HttpPageTrailer ( SocketFD, pPort, pbDone );
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Buffer and send the HTTP page trailer
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [out] pbDone       Address to receive the request completion status
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpPageTrailer (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN BOOLEAN * pbDone
 | 
						|
  )
 | 
						|
{
 | 
						|
  int RetVal;
 | 
						|
  EFI_STATUS Status;
 | 
						|
  socklen_t LengthInBytes;
 | 
						|
  struct sockaddr_in6 LocalAddress;
 | 
						|
  struct sockaddr_in6 RemoteAddress;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Build the page header
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    LengthInBytes = sizeof ( LocalAddress );
 | 
						|
    RetVal = getsockname ( SocketFD, (struct sockaddr *)&LocalAddress, &LengthInBytes );
 | 
						|
    if ( 0 == RetVal ) {
 | 
						|
      LengthInBytes = sizeof ( LocalAddress );
 | 
						|
      RetVal = getpeername ( SocketFD, (struct sockaddr *)&RemoteAddress, &LengthInBytes );
 | 
						|
      if ( 0 == RetVal ) {
 | 
						|
        //
 | 
						|
        //  Seperate the body from the trailer
 | 
						|
        //
 | 
						|
        Status = HttpSendAnsiString ( SocketFD, pPort, "  <hr>\r\n<code>" );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        //  Display the system addresses and the page transfer direction
 | 
						|
        //
 | 
						|
        Status = HttpSendIpAddress ( SocketFD, pPort, &LocalAddress );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        Status = HttpSendAnsiString ( SocketFD, pPort, "  -->  " );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        Status = HttpSendIpAddress ( SocketFD, pPort, &RemoteAddress );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
        Status = HttpSendAnsiString ( SocketFD, pPort, "</code>\r\n" );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Terminate the page
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD, pPort, "  </body>\r\n" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendAnsiString ( SocketFD, pPort, "  </html>\r\n" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Send the page trailer
 | 
						|
    //
 | 
						|
    Status = HttpFlush ( SocketFD, pPort );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Mark the page as complete
 | 
						|
    //
 | 
						|
    *pbDone = TRUE;
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Replace a space with a zero
 | 
						|
 | 
						|
  @param [in] pData     The request buffer address
 | 
						|
  @param [in] pEnd      End of buffer address
 | 
						|
 | 
						|
  @return     The next character location
 | 
						|
 | 
						|
**/
 | 
						|
UINT8 *
 | 
						|
HttpReplaceSpace (
 | 
						|
  IN UINT8 * pData,
 | 
						|
  IN UINT8 * pEnd
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN Character;
 | 
						|
  UINT8 * pSpace;
 | 
						|
 | 
						|
  pSpace = pData;
 | 
						|
  while ( pEnd > pData ) {
 | 
						|
    //
 | 
						|
    //  Get the character from the request
 | 
						|
    //
 | 
						|
    Character = HttpCharGet ( pData, &pData );
 | 
						|
    if ( ' ' == Character ) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    pSpace = pData;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Replace the space character with zero
 | 
						|
  //
 | 
						|
  ZeroMem ( pSpace, pData - pSpace );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the next character location
 | 
						|
  //
 | 
						|
  return pData;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Process an HTTP request
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [out] pbDone       Address to receive the request completion status
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpRequest (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  OUT BOOLEAN * pbDone
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8 * pData;
 | 
						|
  UINT8 * pEnd;
 | 
						|
  CONST DT_PAGE * pPage;
 | 
						|
  CONST DT_PAGE * pPageEnd;
 | 
						|
  UINT8 * pVerb;
 | 
						|
  UINT8 * pVersion;
 | 
						|
  UINT8 * pWebPage;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume the request is not finished
 | 
						|
  //
 | 
						|
  *pbDone = FALSE;
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  for ( ; ; ) {
 | 
						|
 | 
						|
    //
 | 
						|
    //  Attempt to parse the command
 | 
						|
    //
 | 
						|
    pData = &pPort->Request[0];
 | 
						|
    pEnd = &pData[ pPort->RequestLength ];
 | 
						|
    pVerb = pData;
 | 
						|
    pWebPage = HttpReplaceSpace ( pVerb, pEnd );
 | 
						|
    if ( pEnd <= pWebPage ) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    pVersion = HttpReplaceSpace ( pWebPage, pEnd );
 | 
						|
    if ( pEnd <= pVersion ) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Validate the request
 | 
						|
    //
 | 
						|
    if ( 0 != HttpMatch ( L"GET", pVerb, TRUE )) {
 | 
						|
      //
 | 
						|
      //  Invalid request type
 | 
						|
      //
 | 
						|
      DEBUG (( DEBUG_REQUEST,
 | 
						|
                "HTTP: Invalid verb\r\n" ));
 | 
						|
      Status = EFI_NOT_FOUND;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Walk the page table
 | 
						|
    //
 | 
						|
    pPage = &mPageList[0];
 | 
						|
    pPageEnd = &pPage[ mPageCount ];
 | 
						|
    while ( pPageEnd > pPage ) {
 | 
						|
      //
 | 
						|
      //  Determine if the page was located
 | 
						|
      //
 | 
						|
      if ( 0 == HttpMatch ( pPage->pPageName, pWebPage, FALSE )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Set the next page
 | 
						|
      //
 | 
						|
      pPage += 1;
 | 
						|
    }
 | 
						|
    if ( pPageEnd <= pPage ) {
 | 
						|
      //
 | 
						|
      //  The page was not found
 | 
						|
      //
 | 
						|
      DEBUG (( DEBUG_REQUEST,
 | 
						|
                "HTTP: Page not found in page table\r\n" ));
 | 
						|
      Status = EFI_NOT_FOUND;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Respond with the page contents
 | 
						|
    //
 | 
						|
    Status = pPage->pfnResponse ( SocketFD, pPort, pbDone );
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return page not found if necessary
 | 
						|
  //
 | 
						|
  if ( EFI_NOT_FOUND == Status ) {
 | 
						|
    Status = HttpPageNotFound ( SocketFD, pPort, pbDone );
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Buffer data for sending
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] LengthInBytes Length of valid data in the buffer
 | 
						|
  @param [in] pBuffer       Buffer of data to send
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSend (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN size_t LengthInBytes,
 | 
						|
  IN CONST UINT8 * pBuffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  size_t DataBytes;
 | 
						|
  size_t MaxBytes;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    //  Determine how much data fits into the buffer
 | 
						|
    //
 | 
						|
    MaxBytes = sizeof ( pPort->TxBuffer );
 | 
						|
    DataBytes = MaxBytes - pPort->TxBytes;
 | 
						|
    if ( DataBytes > LengthInBytes ) {
 | 
						|
      DataBytes = LengthInBytes;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Copy the data into the buffer
 | 
						|
    //
 | 
						|
    CopyMem ( &pPort->TxBuffer[ pPort->TxBytes ],
 | 
						|
              pBuffer,
 | 
						|
              DataBytes );
 | 
						|
 | 
						|
    //
 | 
						|
    //  Account for the data copied
 | 
						|
    //
 | 
						|
    pPort->TxBytes += DataBytes;
 | 
						|
    LengthInBytes -= DataBytes;
 | 
						|
 | 
						|
    //
 | 
						|
    //  Transmit the buffer if it is full
 | 
						|
    //
 | 
						|
    if ( MaxBytes <= pPort->TxBytes ) {
 | 
						|
      Status = HttpFlush ( SocketFD, pPort );
 | 
						|
    }
 | 
						|
  } while (( EFI_SUCCESS == Status ) && ( 0 < LengthInBytes ));
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Send an ANSI string
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] pString       A zero terminated Unicode string
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendAnsiString (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN CONST char * pString
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONST char * pData;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the characters in he string
 | 
						|
  //
 | 
						|
  pData = pString;
 | 
						|
  while ( 0 != *pData ) {
 | 
						|
    pData += 1;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Send the string
 | 
						|
  //
 | 
						|
  Status = HttpSend ( SocketFD,
 | 
						|
                      pPort,
 | 
						|
                      pData - pString,
 | 
						|
                      (CONST UINT8 *)pString );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Buffer a single byte
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] Data          The data byte to send
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendByte (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN UINT8 Data
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Send the data byte
 | 
						|
  //
 | 
						|
  Status = HttpSend ( SocketFD,
 | 
						|
                      pPort,
 | 
						|
                      1,
 | 
						|
                      &Data );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Display a character
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] Character     Character to display
 | 
						|
  @param [in] pReplacement  Replacement character string
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendCharacter (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN CHAR8 Character,
 | 
						|
  IN CHAR8 * pReplacement
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Determine if this is a printable character
 | 
						|
  //
 | 
						|
  if (( 0x20 <= Character ) && ( 0x7f > Character )) {
 | 
						|
    if ( '<' == Character ) {
 | 
						|
      //
 | 
						|
      //  Replace with HTML equivalent
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    "<" );
 | 
						|
    }
 | 
						|
    else if ( '>' == Character ) {
 | 
						|
      //
 | 
						|
      //  Replace with HTML equivalent
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    ">" );
 | 
						|
    }
 | 
						|
    else if ( '&' == Character ) {
 | 
						|
      //
 | 
						|
      //  Replace with HTML equivalent
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    "&" );
 | 
						|
    }
 | 
						|
    else if ( '\"' == Character ) {
 | 
						|
      //
 | 
						|
      //  Replace with HTML equivalent
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    """ );
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      //
 | 
						|
      //  Display the character
 | 
						|
      //
 | 
						|
      Status = HttpSendByte ( SocketFD,
 | 
						|
                              pPort,
 | 
						|
                              Character );
 | 
						|
    }
 | 
						|
  }
 | 
						|
  else {
 | 
						|
    //
 | 
						|
    //  Not a displayable character
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  pReplacement );
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Send a buffer dump
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] ByteCount     The number of bytes to display
 | 
						|
  @param [in] pData         Address of the byte array
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendDump (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN UINTN ByteCount,
 | 
						|
  IN CONST UINT8 * pData
 | 
						|
  )
 | 
						|
{
 | 
						|
  INTN BytesToDisplay;
 | 
						|
  UINT8 Character;
 | 
						|
  INTN Index;
 | 
						|
  INTN InitialSpaces;
 | 
						|
  CONST UINT8 * pDataEnd;
 | 
						|
  CONST UINT8 * pEnd;
 | 
						|
  CONST UINT8 * pTemp;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Use for/break instead of goto
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    //
 | 
						|
    //  Start the field value
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  "<code>" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Walk the bytes to be displayed
 | 
						|
    //
 | 
						|
    pEnd = &pData[ ByteCount ];
 | 
						|
    while ( pEnd > pData ) {
 | 
						|
      //
 | 
						|
      //  Display the address
 | 
						|
      //
 | 
						|
      Status = HttpSendHexBits ( SocketFD,
 | 
						|
                                 pPort,
 | 
						|
                                 sizeof ( pData ) * 8,
 | 
						|
                                 (UINT64)(UINTN)pData );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Separate the address and data
 | 
						|
      //
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, ':' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Position the starting data correctly
 | 
						|
      //
 | 
						|
      InitialSpaces = (UINTN)pData;
 | 
						|
      InitialSpaces &= BYTES_ON_A_LINE - 1;
 | 
						|
      for ( Index = SPACES_ADDRESS_TO_DATA
 | 
						|
                  + (( 2 + SPACES_BETWEEN_BYTES )
 | 
						|
                        * InitialSpaces );
 | 
						|
            0 < Index; Index-- ) {
 | 
						|
        Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                      pPort,
 | 
						|
                                      " " );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Display the data
 | 
						|
      //
 | 
						|
      BytesToDisplay = pEnd - pData;
 | 
						|
      if (( BYTES_ON_A_LINE - InitialSpaces ) < BytesToDisplay ) {
 | 
						|
        BytesToDisplay = BYTES_ON_A_LINE - InitialSpaces;
 | 
						|
      }
 | 
						|
      pDataEnd = &pData[ BytesToDisplay ];
 | 
						|
      pTemp = pData;
 | 
						|
      while ( pDataEnd > pTemp ) {
 | 
						|
        Status = HttpSendHexBits ( SocketFD,
 | 
						|
                                   pPort,
 | 
						|
                                   8,
 | 
						|
                                   *pTemp++ );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        //
 | 
						|
        //  Separate the data bytes
 | 
						|
        //
 | 
						|
        for ( Index = SPACES_BETWEEN_BYTES; 0 < Index; Index-- ) {
 | 
						|
          Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                        pPort,
 | 
						|
                                        " " );
 | 
						|
          if ( EFI_ERROR ( Status )) {
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Separate the data from the ASCII display
 | 
						|
      //
 | 
						|
      for ( Index = (( 2 + SPACES_BETWEEN_BYTES )
 | 
						|
                       * ( BYTES_ON_A_LINE - BytesToDisplay - InitialSpaces ))
 | 
						|
                  - SPACES_BETWEEN_BYTES
 | 
						|
                  + SPACES_DATA_TO_ASCII
 | 
						|
                  + InitialSpaces;
 | 
						|
            0 < Index; Index-- ) {
 | 
						|
        Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                      pPort,
 | 
						|
                                      " " );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Display the ASCII data
 | 
						|
      //
 | 
						|
      while ( pDataEnd > pData ) {
 | 
						|
        Character = *pData++;
 | 
						|
        Status = HttpSendCharacter ( SocketFD,
 | 
						|
                                     pPort,
 | 
						|
                                     Character,
 | 
						|
                                     "." );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Terminate the line
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    "<br/>\r\n" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Terminate the field value and row
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  "</code>\r\n" );
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Display a row containing a GUID value
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] pGuid         Address of the GUID to display
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendGuid (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN CONST EFI_GUID * pGuid
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Index;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  DBG_ENTER ( );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Use for/break instead of goto
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    //
 | 
						|
    //  Display the GUID in a form found in the code
 | 
						|
    //
 | 
						|
    //  E.g. 0xca16005f, 0x11ec, 0x4bdc, { 0x99, 0x97, 0x27, 0x2c, 0xa9, 0xba, 0x15, 0xe5 }
 | 
						|
    //
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the first 32 bits
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  "0x" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendHexBits ( SocketFD,
 | 
						|
                               pPort,
 | 
						|
                               32,
 | 
						|
                               pGuid->Data1 );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the second 16 bits
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  ", 0x" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendHexBits ( SocketFD,
 | 
						|
                               pPort,
 | 
						|
                               16,
 | 
						|
                               pGuid->Data2 );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the thrid 16 bits
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  ", 0x" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendHexBits ( SocketFD,
 | 
						|
                               pPort,
 | 
						|
                               16,
 | 
						|
                               pGuid->Data3 );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Place the last 64 bits in braces
 | 
						|
    //
 | 
						|
    Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  ", { 0x" );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    for ( Index = 0; 7 >= Index; Index++ ) {
 | 
						|
      //
 | 
						|
      //  Display the next 8 bits
 | 
						|
      //
 | 
						|
      Status = HttpSendHexBits ( SocketFD,
 | 
						|
                                 pPort,
 | 
						|
                                 8,
 | 
						|
                                 pGuid->Data4[ Index ]);
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Separate the bytes
 | 
						|
      //
 | 
						|
      Status = HttpSendAnsiString ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    ( 7 != Index ) ? ", 0x" : " }" );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  DBG_EXIT_STATUS ( Status );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output a hex value to the HTML page
 | 
						|
 | 
						|
  @param [in] SocketFD    Socket file descriptor
 | 
						|
  @param [in] pPort       The WSDT_PORT structure address
 | 
						|
  @param [in] Bits        Number of bits to display
 | 
						|
  @param [in] Value       Value to display
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Successfully displayed the address
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendHexBits (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN INT32 Bits,
 | 
						|
  IN UINT64 Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT32 Digit;
 | 
						|
  INT32 Shift;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the list of divisors
 | 
						|
  //
 | 
						|
  Shift = (( Bits + 3 ) & ( ~3 )) - 4;
 | 
						|
  while ( 0 <= Shift ) {
 | 
						|
    //
 | 
						|
    //  Determine the next digit
 | 
						|
    //
 | 
						|
    Digit = (UINT32)(( Value >> Shift ) & 0xf );
 | 
						|
    if ( 10 <= Digit ) {
 | 
						|
      Digit += 'a' - '0' - 10;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the digit
 | 
						|
    //
 | 
						|
    Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Set the next shift
 | 
						|
    //
 | 
						|
    Shift -= 4;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output a hex value to the HTML page
 | 
						|
 | 
						|
  @param [in] SocketFD    Socket file descriptor
 | 
						|
  @param [in] pPort       The WSDT_PORT structure address
 | 
						|
  @param [in] Value       Value to display
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Successfully displayed the address
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendHexValue (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN UINT64 Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN bDisplayZeros;
 | 
						|
  UINT32 Digit;
 | 
						|
  INT32 Shift;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the list of divisors
 | 
						|
  //
 | 
						|
  bDisplayZeros = FALSE;
 | 
						|
  Shift = 60;
 | 
						|
  do {
 | 
						|
    //
 | 
						|
    //  Determine the next digit
 | 
						|
    //
 | 
						|
    Digit = (UINT32)(( Value >> Shift ) & 0xf );
 | 
						|
    if ( 10 <= Digit ) {
 | 
						|
      Digit += 'a' - '0' - 10;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Suppress leading zeros
 | 
						|
    //
 | 
						|
    if (( 0 != Digit ) || bDisplayZeros || ( 0 == Shift )) {
 | 
						|
      bDisplayZeros = TRUE;
 | 
						|
 | 
						|
      //
 | 
						|
      //  Display the digit
 | 
						|
      //
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Set the next shift
 | 
						|
    //
 | 
						|
    Shift -= 4;
 | 
						|
  } while ( 0 <= Shift );
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output an IP6 address value to the HTML page
 | 
						|
 | 
						|
  @param [in] SocketFD          Socket file descriptor
 | 
						|
  @param [in] pPort             The WSDT_PORT structure address
 | 
						|
  @param [in] Value             Value to display
 | 
						|
  @param [in] bFirstValue       TRUE if first value
 | 
						|
  @param [in] bLastValue        TRUE if last value
 | 
						|
  @param [in] bZeroSuppression  TRUE while zeros are being suppressed
 | 
						|
  @param [in] pbZeroSuppression Address to receive TRUE when zero suppression
 | 
						|
                                has started, use NULL if next colon value not
 | 
						|
                                needed.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Successfully displayed the address
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendIp6Value (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN UINT16 Value,
 | 
						|
  IN BOOLEAN bFirstValue,
 | 
						|
  IN BOOLEAN bLastValue,
 | 
						|
  IN BOOLEAN bZeroSuppression,
 | 
						|
  IN BOOLEAN * pbZeroSuppression
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN bZeroSuppressionStarting;
 | 
						|
  UINT32 Digit;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Use break instead of goto
 | 
						|
  //
 | 
						|
  bZeroSuppressionStarting = FALSE;
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
  for ( ; ; ) {
 | 
						|
    //
 | 
						|
    //  Display the leading colon if necessary
 | 
						|
    //
 | 
						|
    if ( bZeroSuppression && ( bLastValue || ( 0 != Value ))) {
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, ':' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Skip over a series of zero values
 | 
						|
    //
 | 
						|
    bZeroSuppressionStarting = (BOOLEAN)( 0 == Value );
 | 
						|
    if ( !bZeroSuppressionStarting ) {
 | 
						|
      //
 | 
						|
      //  Display the value
 | 
						|
      //
 | 
						|
      Digit = ( Value >> 4 ) & 0xf;
 | 
						|
      Status = HttpSendHexValue ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  Digit );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Digit = Value & 0xf;
 | 
						|
      Status = HttpSendHexValue ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  Digit );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Digit = ( Value >> 12 ) & 0xf;
 | 
						|
      Status = HttpSendHexValue ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  Digit );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Digit = ( Value >> 8 ) & 0xf;
 | 
						|
      Status = HttpSendHexValue ( SocketFD,
 | 
						|
                                  pPort,
 | 
						|
                                  Digit );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the trailing colon if necessary
 | 
						|
    //
 | 
						|
    if (( !bLastValue ) && ( bFirstValue || ( 0 != Value ))) {
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, ':' );
 | 
						|
    }
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the next colon display
 | 
						|
  if ( NULL != pbZeroSuppression ) {
 | 
						|
    *pbZeroSuppression = bZeroSuppressionStarting;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output an IP address to the HTML page
 | 
						|
 | 
						|
  @param [in] SocketFD    Socket file descriptor
 | 
						|
  @param [in] pPort       The WSDT_PORT structure address
 | 
						|
  @param [in] pAddress    Address of the socket address
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Successfully displayed the address
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendIpAddress (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN struct sockaddr_in6 * pAddress
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN bZeroSuppression;
 | 
						|
  UINT32 Index;
 | 
						|
  struct sockaddr_in * pIpv4;
 | 
						|
  struct sockaddr_in6 * pIpv6;
 | 
						|
  UINT16 PortNumber;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Use break instead of goto
 | 
						|
  //
 | 
						|
  for ( ; ; ) {
 | 
						|
    //
 | 
						|
    //  Determine the type of address
 | 
						|
    //
 | 
						|
    if ( AF_INET6 == pAddress->sin6_family ) {
 | 
						|
      pIpv6 = pAddress;
 | 
						|
 | 
						|
      //
 | 
						|
      //  Display the address in RFC2732 format
 | 
						|
      //
 | 
						|
      bZeroSuppression = FALSE;
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, '[' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      for ( Index = 0; 8 > Index; Index++ ) {
 | 
						|
        Status = HttpSendIp6Value ( SocketFD,
 | 
						|
                                    pPort,
 | 
						|
                                    pIpv6->sin6_addr.__u6_addr.__u6_addr16[ Index ],
 | 
						|
                                    (BOOLEAN)( 0 == Index ),
 | 
						|
                                    (BOOLEAN)( 7 == Index ),
 | 
						|
                                    bZeroSuppression,
 | 
						|
                                    &bZeroSuppression );
 | 
						|
        if ( EFI_ERROR ( Status )) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Separate the port number
 | 
						|
      //
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, ']' );
 | 
						|
 | 
						|
      //
 | 
						|
      //  Get the port number
 | 
						|
      //
 | 
						|
      PortNumber = pIpv6->sin6_port;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      //
 | 
						|
      //  Output the IPv4 address
 | 
						|
      //
 | 
						|
      pIpv4 = (struct sockaddr_in *)pAddress;
 | 
						|
      Status = HttpSendValue ( SocketFD, pPort, (UINT8)pIpv4->sin_addr.s_addr );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, '.' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 8 ));
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, '.' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 16 ));
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, '.' );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
      Status = HttpSendValue ( SocketFD, pPort, (UINT8)( pIpv4->sin_addr.s_addr >> 24 ));
 | 
						|
 | 
						|
      //
 | 
						|
      //  Get the port number
 | 
						|
      //
 | 
						|
      PortNumber = pIpv4->sin_port;
 | 
						|
    }
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Display the port number
 | 
						|
    //
 | 
						|
    Status = HttpSendByte ( SocketFD, pPort, ':' );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    Status = HttpSendValue ( SocketFD, pPort, htons ( PortNumber ));
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Send a Unicode string
 | 
						|
 | 
						|
  @param [in] SocketFD      The socket's file descriptor to add to the list.
 | 
						|
  @param [in] pPort         The WSDT_PORT structure address
 | 
						|
  @param [in] pString       A zero terminated Unicode string
 | 
						|
 | 
						|
  @retval EFI_SUCCESS       The request was successfully processed
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendUnicodeString (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN CONST UINT16 * pString
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT8 Data;
 | 
						|
  UINT16 Character;
 | 
						|
  EFI_STATUS Status;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the characters in he string
 | 
						|
  //
 | 
						|
  while ( 0 != ( Character = *pString++ )) {
 | 
						|
    //
 | 
						|
    //  Convert the character to UTF-8
 | 
						|
    //
 | 
						|
    if ( 0 != ( Character & 0xf800 )) {
 | 
						|
      //
 | 
						|
      //  Send the upper 4 bits
 | 
						|
      //
 | 
						|
      Data = (UINT8)(( Character >> 12 ) & 0xf );
 | 
						|
      Data |= 0xe0;
 | 
						|
      Status = HttpSendByte ( SocketFD,
 | 
						|
                              pPort,
 | 
						|
                              Data );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Send the next 6 bits
 | 
						|
      //
 | 
						|
      Data = (UINT8)(( Character >> 6 ) & 0x3f );
 | 
						|
      Data |= 0x80;
 | 
						|
      Status = HttpSendByte ( SocketFD,
 | 
						|
                              pPort,
 | 
						|
                              Data );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Send the last 6 bits
 | 
						|
      //
 | 
						|
      Data = (UINT8)( Character & 0x3f );
 | 
						|
      Data |= 0x80;
 | 
						|
    }
 | 
						|
    else if ( 0 != ( Character & 0x0780 )) {
 | 
						|
      //
 | 
						|
      //  Send the upper 5 bits
 | 
						|
      //
 | 
						|
      Data = (UINT8)(( Character >> 6 ) & 0x1f );
 | 
						|
      Data |= 0xc0;
 | 
						|
      Status = HttpSendByte ( SocketFD,
 | 
						|
                              pPort,
 | 
						|
                              Data );
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Send the last 6 bits
 | 
						|
      //
 | 
						|
      Data = (UINT8)( Character & 0x3f );
 | 
						|
      Data |= 0x80;
 | 
						|
    }
 | 
						|
    else {
 | 
						|
      Data = (UINT8)( Character & 0x7f );
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Send the last data byte
 | 
						|
    //
 | 
						|
    Status = HttpSendByte ( SocketFD,
 | 
						|
                            pPort,
 | 
						|
                            Data );
 | 
						|
    if ( EFI_ERROR ( Status )) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Output a value to the HTML page
 | 
						|
 | 
						|
  @param [in] SocketFD    Socket file descriptor
 | 
						|
  @param [in] pPort       The WSDT_PORT structure address
 | 
						|
  @param [in] Value       Value to display
 | 
						|
 | 
						|
  @retval EFI_SUCCESS Successfully displayed the address
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
HttpSendValue (
 | 
						|
  IN int SocketFD,
 | 
						|
  IN WSDT_PORT * pPort,
 | 
						|
  IN UINT64 Value
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOOLEAN bDisplayZeros;
 | 
						|
  UINT64 Digit;
 | 
						|
  CONST UINT64 * pEnd;
 | 
						|
  CONST UINT64 * pDivisor;
 | 
						|
  CONST UINT64 pDivisors[ ] = {
 | 
						|
     10000000000000000000ULL,
 | 
						|
      1000000000000000000ULL,
 | 
						|
       100000000000000000ULL,
 | 
						|
        10000000000000000ULL,
 | 
						|
         1000000000000000ULL,
 | 
						|
          100000000000000ULL,
 | 
						|
           10000000000000ULL,
 | 
						|
            1000000000000ULL,
 | 
						|
             100000000000ULL,
 | 
						|
              10000000000ULL,
 | 
						|
               1000000000ULL,
 | 
						|
                100000000ULL,
 | 
						|
                 10000000ULL,
 | 
						|
                  1000000ULL,
 | 
						|
                   100000ULL,
 | 
						|
                    10000ULL,
 | 
						|
                     1000ULL,
 | 
						|
                      100ULL,
 | 
						|
                       10ULL
 | 
						|
  };
 | 
						|
  EFI_STATUS Status;
 | 
						|
  UINT64 Temp;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Assume success
 | 
						|
  //
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  //
 | 
						|
  //  Walk the list of divisors
 | 
						|
  //
 | 
						|
  bDisplayZeros = FALSE;
 | 
						|
  pDivisor = &pDivisors[0];
 | 
						|
  pEnd = &pDivisor[ sizeof ( pDivisors ) / sizeof ( pDivisors[0])];
 | 
						|
  while ( pEnd > pDivisor ) {
 | 
						|
    //
 | 
						|
    //  Determine the next digit
 | 
						|
    //
 | 
						|
    Digit = Value / *pDivisor;
 | 
						|
 | 
						|
    //
 | 
						|
    //  Suppress leading zeros
 | 
						|
    //
 | 
						|
    if (( 0 != Digit ) || bDisplayZeros ) {
 | 
						|
      bDisplayZeros = TRUE;
 | 
						|
 | 
						|
      //
 | 
						|
      //  Display the digit
 | 
						|
      //
 | 
						|
      Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Digit ));
 | 
						|
      if ( EFI_ERROR ( Status )) {
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      //  Determine the remainder
 | 
						|
      //
 | 
						|
      Temp = *pDivisor * Digit;
 | 
						|
      Value -= Temp;
 | 
						|
    }
 | 
						|
 | 
						|
    //
 | 
						|
    //  Set the next divisor
 | 
						|
    //
 | 
						|
    pDivisor += 1;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Display the final digit
 | 
						|
  //
 | 
						|
  if ( !EFI_ERROR ( Status )) {
 | 
						|
    Status = HttpSendByte ( SocketFD, pPort, (UINT8)( '0' + Value ));
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  //  Return the operation status
 | 
						|
  //
 | 
						|
  return Status;
 | 
						|
}
 |