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
HandlePage(IN int SocketFD,IN WSDT_PORT * pPort,OUT BOOLEAN * pbDone)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