]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Application/Shell/ConsoleLogger.c
Fix the memory leak issue and enhance the check for CoreReadImageFile return.
[mirror_edk2.git] / ShellPkg / Application / Shell / ConsoleLogger.c
CommitLineData
a405b86d 1/** @file\r
2 Provides interface to shell console logger.\r
3\r
733f138d 4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
a405b86d 5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12**/\r
13\r
14#include "ConsoleLogger.h"\r
15#include "Shell.h"\r
16\r
17STATIC CONST CHAR16 mCrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };\r
18\r
19/**\r
20 Install our intermediate ConOut into the system table to\r
21 keep a log of all the info that is displayed to the user.\r
22\r
23 @param[in] ScreensToSave Sets how many screen-worths of data to save.\r
24 @param[out] ConsoleInfo The object to pass into later functions.\r
25\r
26 @retval EFI_SUCCESS The operation was successful.\r
27 @return other The operation failed.\r
28\r
29 @sa ConsoleLoggerResetBuffers\r
30 @sa InstallProtocolInterface\r
31**/\r
32EFI_STATUS\r
33EFIAPI\r
34ConsoleLoggerInstall(\r
35 IN CONST UINTN ScreensToSave,\r
36 OUT CONSOLE_LOGGER_PRIVATE_DATA **ConsoleInfo\r
37 )\r
38{\r
39 EFI_STATUS Status;\r
40 ASSERT(ConsoleInfo != NULL);\r
41\r
733f138d 42 (*ConsoleInfo) = AllocateZeroPool(sizeof(CONSOLE_LOGGER_PRIVATE_DATA));\r
3c865f20 43 if ((*ConsoleInfo) == NULL) {\r
44 return (EFI_OUT_OF_RESOURCES);\r
45 }\r
a405b86d 46\r
733f138d 47 (*ConsoleInfo)->Signature = CONSOLE_LOGGER_PRIVATE_DATA_SIGNATURE;\r
48 (*ConsoleInfo)->OldConOut = gST->ConOut;\r
49 (*ConsoleInfo)->OldConHandle = gST->ConsoleOutHandle;\r
50 (*ConsoleInfo)->Buffer = NULL;\r
51 (*ConsoleInfo)->BufferSize = 0;\r
52 (*ConsoleInfo)->OriginalStartRow = 0;\r
53 (*ConsoleInfo)->CurrentStartRow = 0;\r
54 (*ConsoleInfo)->RowsPerScreen = 0;\r
55 (*ConsoleInfo)->ColsPerScreen = 0;\r
56 (*ConsoleInfo)->Attributes = NULL;\r
57 (*ConsoleInfo)->AttribSize = 0;\r
58 (*ConsoleInfo)->ScreenCount = ScreensToSave;\r
59 (*ConsoleInfo)->HistoryMode.MaxMode = 1;\r
60 (*ConsoleInfo)->HistoryMode.Mode = 0;\r
61 (*ConsoleInfo)->HistoryMode.Attribute = 0;\r
62 (*ConsoleInfo)->HistoryMode.CursorColumn = 0;\r
63 (*ConsoleInfo)->HistoryMode.CursorRow = 0;\r
64 (*ConsoleInfo)->HistoryMode.CursorVisible = FALSE;\r
65 (*ConsoleInfo)->OurConOut.Reset = ConsoleLoggerReset;\r
66 (*ConsoleInfo)->OurConOut.OutputString = ConsoleLoggerOutputString;\r
67 (*ConsoleInfo)->OurConOut.TestString = ConsoleLoggerTestString;\r
68 (*ConsoleInfo)->OurConOut.QueryMode = ConsoleLoggerQueryMode;\r
69 (*ConsoleInfo)->OurConOut.SetMode = ConsoleLoggerSetMode;\r
70 (*ConsoleInfo)->OurConOut.SetAttribute = ConsoleLoggerSetAttribute;\r
71 (*ConsoleInfo)->OurConOut.ClearScreen = ConsoleLoggerClearScreen;\r
a405b86d 72 (*ConsoleInfo)->OurConOut.SetCursorPosition = ConsoleLoggerSetCursorPosition;\r
733f138d 73 (*ConsoleInfo)->OurConOut.EnableCursor = ConsoleLoggerEnableCursor;\r
74 (*ConsoleInfo)->OurConOut.Mode = gST->ConOut->Mode;\r
75 (*ConsoleInfo)->Enabled = TRUE;\r
a405b86d 76\r
77 Status = ConsoleLoggerResetBuffers(*ConsoleInfo);\r
78 if (EFI_ERROR(Status)) {\r
8be0ba36 79 SHELL_FREE_NON_NULL((*ConsoleInfo));\r
80 *ConsoleInfo = NULL;\r
a405b86d 81 return (Status);\r
82 }\r
83\r
84 Status = gBS->InstallProtocolInterface(&gImageHandle, &gEfiSimpleTextOutProtocolGuid, EFI_NATIVE_INTERFACE, (VOID*)&((*ConsoleInfo)->OurConOut));\r
8be0ba36 85 if (EFI_ERROR(Status)) {\r
86 SHELL_FREE_NON_NULL((*ConsoleInfo)->Buffer);\r
87 SHELL_FREE_NON_NULL((*ConsoleInfo)->Attributes);\r
88 SHELL_FREE_NON_NULL((*ConsoleInfo));\r
89 *ConsoleInfo = NULL;\r
90 return (Status);\r
91 }\r
a405b86d 92\r
a405b86d 93 gST->ConsoleOutHandle = gImageHandle;\r
733f138d 94 gST->ConOut = &(*ConsoleInfo)->OurConOut;\r
a405b86d 95\r
96 return (Status);\r
97}\r
98\r
99/**\r
100 Return the system to the state it was before InstallConsoleLogger\r
101 was installed.\r
102\r
733f138d 103 @param[in] ConsoleInfo The object from the install function.\r
a405b86d 104\r
105 @retval EFI_SUCCESS The operation was successful\r
106 @return other The operation failed. This was from UninstallProtocolInterface.\r
107**/\r
108EFI_STATUS\r
109EFIAPI\r
110ConsoleLoggerUninstall(\r
111 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
112 )\r
113{\r
114 ASSERT(ConsoleInfo != NULL);\r
115 ASSERT(ConsoleInfo->OldConOut != NULL);\r
116\r
117 if (ConsoleInfo->Buffer != NULL) {\r
118 FreePool(ConsoleInfo->Buffer);\r
119 DEBUG_CODE(ConsoleInfo->Buffer = NULL;);\r
120 DEBUG_CODE(ConsoleInfo->BufferSize = 0;);\r
121 }\r
122 if (ConsoleInfo->Attributes != NULL) {\r
123 FreePool(ConsoleInfo->Attributes);\r
124 DEBUG_CODE(ConsoleInfo->Attributes = NULL;);\r
125 DEBUG_CODE(ConsoleInfo->AttribSize = 0;);\r
126 }\r
127\r
128 gST->ConsoleOutHandle = ConsoleInfo->OldConHandle;\r
129 gST->ConOut = ConsoleInfo->OldConOut;\r
130\r
131 return (gBS->UninstallProtocolInterface(gImageHandle, &gEfiSimpleTextOutProtocolGuid, (VOID*)&ConsoleInfo->OurConOut));\r
132}\r
133\r
134/**\r
135 Displays previously logged output back to the screen.\r
136\r
137 This will scroll the screen forwards and backwards through the log of previous\r
138 output. If Rows is 0 then the size of 1/2 the screen will be scrolled. If Rows\r
139 is (UINTN)(-1) then the size of the screen will be scrolled.\r
140\r
141 @param[in] Forward If TRUE then the log will be displayed forwards (scroll to newer).\r
142 If FALSE then the log will be displayed backwards (scroll to older).\r
143 @param[in] Rows Determines how many rows the log should scroll.\r
144 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
145**/\r
146EFI_STATUS\r
147EFIAPI\r
148ConsoleLoggerDisplayHistory(\r
149 IN CONST BOOLEAN Forward,\r
150 IN CONST UINTN Rows,\r
151 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
152 )\r
153{\r
154 UINTN RowChange;\r
155\r
156 ASSERT(ConsoleInfo != NULL);\r
157\r
158 //\r
159 // Calculate the row number change\r
160 //\r
161 switch (Rows) {\r
162 case ((UINTN)(-1)):\r
163 RowChange = ConsoleInfo->RowsPerScreen;\r
164 break;\r
165 case (0):\r
166 RowChange = ConsoleInfo->RowsPerScreen / 2;\r
167 break;\r
168 default:\r
169 RowChange = Rows;\r
170 break;\r
171 }\r
172\r
173 //\r
174 // Do the math for direction\r
175 //\r
176 if (Forward) {\r
177 if ((ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow) < RowChange) {\r
178 RowChange = ConsoleInfo->OriginalStartRow - ConsoleInfo->CurrentStartRow;\r
179 }\r
180 } else {\r
181 if (ConsoleInfo->CurrentStartRow < RowChange) {\r
182 RowChange = ConsoleInfo->CurrentStartRow;\r
183 }\r
184 }\r
185\r
186 //\r
187 // If we are already at one end or the other\r
188 //\r
189 if (RowChange == 0) {\r
190 return (EFI_SUCCESS);\r
191 }\r
192\r
193 //\r
194 // Clear the screen\r
195 //\r
196 ConsoleInfo->OldConOut->ClearScreen(ConsoleInfo->OldConOut);\r
197\r
198 //\r
199 // Set the new start row\r
200 //\r
201 if (Forward) {\r
202 ConsoleInfo->CurrentStartRow += RowChange;\r
203 } else {\r
204 ConsoleInfo->CurrentStartRow -= RowChange;\r
205 }\r
206\r
207 //\r
208 // Change the screen\r
209 //\r
210 return (UpdateDisplayFromHistory(ConsoleInfo));\r
211}\r
212\r
213/**\r
214 Function to return to normal output whent he scrolling is complete.\r
215 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
216\r
217 @retval EFI_SUCCESS The operation was successful.\r
218 @return other The operation failed. See UpdateDisplayFromHistory.\r
219\r
220 @sa UpdateDisplayFromHistory\r
221**/\r
222EFI_STATUS\r
223EFIAPI\r
224ConsoleLoggerStopHistory(\r
225 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
226 )\r
227{\r
228 ASSERT(ConsoleInfo != NULL);\r
229 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {\r
230 return (EFI_SUCCESS);\r
231 }\r
232 ConsoleInfo->CurrentStartRow = ConsoleInfo->OriginalStartRow;\r
233 return (UpdateDisplayFromHistory(ConsoleInfo));\r
234}\r
235\r
236/**\r
237 Updates the hidden ConOut to be displaying the correct stuff.\r
238 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
239\r
240 @retval EFI_SUCCESS The operation was successful.\r
241 @return other The operation failed.\r
242**/\r
243EFI_STATUS\r
244EFIAPI\r
245UpdateDisplayFromHistory(\r
246 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
247 )\r
248{\r
249 EFI_STATUS Status;\r
250 EFI_STATUS RetVal;\r
251 CHAR16 *Screen;\r
252 INT32 *Attributes;\r
253 UINTN CurrentRow;\r
254 CHAR16 TempCharHolder;\r
255 UINTN Column;\r
256 INT32 CurrentAttrib;\r
257 UINTN CurrentColumn;\r
258 CHAR16 *StringSegment;\r
259 CHAR16 *StringSegmentEnd;\r
260 CHAR16 StringSegmentEndChar;\r
ad7782a4 261 INT32 OrigAttribute;\r
a405b86d 262\r
263 ASSERT(ConsoleInfo != NULL);\r
264 TempCharHolder = CHAR_NULL;\r
265 RetVal = EFI_SUCCESS;\r
ad7782a4 266 OrigAttribute = ConsoleInfo->OldConOut->Mode->Attribute;\r
a405b86d 267\r
268 //\r
269 // Disable cursor visibility and move it to the top left corner\r
270 //\r
271 ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, FALSE);\r
272 ConsoleInfo->OldConOut->SetCursorPosition (ConsoleInfo->OldConOut, 0, 0);\r
273\r
274 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];\r
275 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];\r
276 for ( CurrentRow = 0\r
277 ; CurrentRow < ConsoleInfo->RowsPerScreen\r
278 ; CurrentRow++\r
279 , Screen += (ConsoleInfo->ColsPerScreen + 2)\r
280 , Attributes += ConsoleInfo->ColsPerScreen\r
281 ){\r
282 //\r
283 // dont use the last char - prevents screen scroll\r
284 //\r
285 if (CurrentRow == (ConsoleInfo->RowsPerScreen-1)){\r
286 TempCharHolder = Screen[ConsoleInfo->ColsPerScreen - 1];\r
287 Screen[ConsoleInfo->ColsPerScreen - 1] = CHAR_NULL;\r
288 }\r
289\r
290 for ( Column = 0\r
291 ; Column < ConsoleInfo->ColsPerScreen\r
292 ; Column++\r
293 ){\r
294 if (Screen[Column] != CHAR_NULL) {\r
295 CurrentAttrib = Attributes[Column];\r
296 CurrentColumn = Column;\r
297 StringSegment = &Screen[Column];\r
298\r
299 //\r
300 // Find the first char with a different arrribute and make that temporarily NULL\r
301 // so we can do fewer printout statements. (later) restore that one and we will\r
302 // start at that collumn on the next loop.\r
303 //\r
304 StringSegmentEndChar = CHAR_NULL;\r
305 for ( StringSegmentEnd = StringSegment\r
306 ; StringSegmentEnd != CHAR_NULL\r
307 ; StringSegmentEnd++\r
308 , Column++\r
309 ){\r
310 if (Attributes[Column] != CurrentAttrib) {\r
311 StringSegmentEndChar = *StringSegmentEnd;\r
312 *StringSegmentEnd = CHAR_NULL;\r
313 break;\r
314 }\r
315 } // StringSegmentEnd loop\r
316\r
317 //\r
318 // Now write out as much as had the same Attributes\r
319 //\r
320\r
321 ConsoleInfo->OldConOut->SetAttribute(ConsoleInfo->OldConOut, CurrentAttrib);\r
322 ConsoleInfo->OldConOut->SetCursorPosition(ConsoleInfo->OldConOut, CurrentColumn, CurrentRow);\r
323 Status = ConsoleInfo->OldConOut->OutputString(ConsoleInfo->OldConOut, StringSegment);\r
324\r
325 if (EFI_ERROR(Status)) {\r
326 ASSERT(FALSE);\r
327 RetVal = Status;\r
328 }\r
329\r
330 //\r
331 // If we found a change in attribute put the character back and decrement the column\r
332 // so when it increments it will point at that character and we will start printing\r
333 // a segment with that new attribute\r
334 //\r
335 if (StringSegmentEndChar != CHAR_NULL) {\r
336 *StringSegmentEnd = StringSegmentEndChar;\r
337 StringSegmentEndChar = CHAR_NULL;\r
338 Column--;\r
339 }\r
340 }\r
341 } // column for loop\r
342\r
343 //\r
344 // If we removed the last char and this was the last row put it back\r
345 //\r
346 if (TempCharHolder != CHAR_NULL) {\r
347 Screen[ConsoleInfo->ColsPerScreen - 1] = TempCharHolder;\r
348 TempCharHolder = CHAR_NULL;\r
349 }\r
350 } // row for loop\r
351\r
352 //\r
353 // If we are setting the screen back to original turn on the cursor and make it visible\r
354 // and set the attributes back to what they were\r
355 //\r
356 if (ConsoleInfo->CurrentStartRow == ConsoleInfo->OriginalStartRow) {\r
357 ConsoleInfo->OldConOut->SetAttribute (\r
358 ConsoleInfo->OldConOut,\r
359 ConsoleInfo->HistoryMode.Attribute\r
360 );\r
361 ConsoleInfo->OldConOut->SetCursorPosition (\r
362 ConsoleInfo->OldConOut,\r
363 ConsoleInfo->HistoryMode.CursorColumn,\r
364 ConsoleInfo->HistoryMode.CursorRow - ConsoleInfo->OriginalStartRow\r
365 );\r
366\r
367 Status = ConsoleInfo->OldConOut->EnableCursor (\r
368 ConsoleInfo->OldConOut,\r
369 ConsoleInfo->HistoryMode.CursorVisible\r
370 );\r
371 if (EFI_ERROR (Status)) {\r
372 RetVal = Status;\r
373 }\r
ad7782a4 374 } else {\r
375 ConsoleInfo->OldConOut->SetAttribute (\r
376 ConsoleInfo->OldConOut,\r
377 OrigAttribute\r
378 );\r
a405b86d 379 }\r
380\r
381 return (RetVal);\r
382}\r
383\r
384/**\r
385 Reset the text output device hardware and optionaly run diagnostics\r
386\r
387 @param This pointer to EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL\r
388 @param ExtendedVerification Indicates that a more extensive test may be performed\r
389\r
390 @retval EFI_SUCCESS The text output device was reset.\r
391 @retval EFI_DEVICE_ERROR The text output device is not functioning correctly and\r
392 could not be reset.\r
393**/\r
394EFI_STATUS\r
395EFIAPI\r
396ConsoleLoggerReset (\r
397 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
398 IN BOOLEAN ExtendedVerification\r
399 )\r
400{\r
401 EFI_STATUS Status;\r
402 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
403 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
404\r
405 //\r
406 // Forward the request to the original ConOut\r
407 //\r
408 Status = ConsoleInfo->OldConOut->Reset (ConsoleInfo->OldConOut, ExtendedVerification);\r
409\r
410 //\r
411 // Check that the buffers are still correct for logging\r
412 //\r
413 if (!EFI_ERROR (Status)) {\r
414 ConsoleLoggerResetBuffers(ConsoleInfo);\r
415 }\r
416\r
417 return Status;\r
418}\r
419\r
420/**\r
421 Appends a string to the history buffer. If the buffer is full then the oldest\r
422 information in the buffer will be dropped. Information is added in a line by\r
423 line manner such that an empty line takes up just as much space as a full line.\r
424\r
425 @param[in] String String pointer to add.\r
426 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
427**/\r
428EFI_STATUS\r
429EFIAPI\r
430AppendStringToHistory(\r
431 IN CONST CHAR16 *String,\r
432 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
433 )\r
434{\r
435 CONST CHAR16 *Walker;\r
436 UINTN CopySize;\r
437 UINTN PrintIndex;\r
438 UINTN Index;\r
439\r
440 ASSERT(ConsoleInfo != NULL);\r
441\r
442 for ( Walker = String\r
443 ; Walker != NULL && *Walker != CHAR_NULL\r
444 ; Walker++\r
445 ){\r
446 switch (*Walker) {\r
447 case (CHAR_BACKSPACE):\r
448 if (ConsoleInfo->HistoryMode.CursorColumn > 0) {\r
449 ConsoleInfo->HistoryMode.CursorColumn--;\r
450 }\r
451 break;\r
452 case (CHAR_LINEFEED):\r
453 if (ConsoleInfo->HistoryMode.CursorRow >= (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1)) {\r
454 //\r
455 // Should never be bigger\r
456 //\r
457 ASSERT(ConsoleInfo->HistoryMode.CursorRow == (INT32)((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)-1));\r
458\r
459 //\r
460 // scroll history attributes 'up' 1 row and set the last row to default attribute\r
461 //\r
462 CopySize = ConsoleInfo->ColsPerScreen\r
463 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)\r
464 * sizeof(ConsoleInfo->Attributes[0]);\r
465 ASSERT(CopySize < ConsoleInfo->AttribSize);\r
466 CopyMem(\r
467 ConsoleInfo->Attributes,\r
468 ConsoleInfo->Attributes + ConsoleInfo->ColsPerScreen,\r
469 CopySize\r
470 );\r
471\r
472 for ( Index = 0\r
473 ; Index < ConsoleInfo->ColsPerScreen\r
474 ; Index++\r
475 ){\r
476 *(ConsoleInfo->Attributes + (CopySize/sizeof(ConsoleInfo->Attributes)) + Index) = ConsoleInfo->HistoryMode.Attribute;\r
477 }\r
478\r
479 //\r
480 // scroll history buffer 'up' 1 row and set the last row to spaces (L' ')\r
481 //\r
482 CopySize = (ConsoleInfo->ColsPerScreen + 2)\r
483 * ((ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount) - 1)\r
484 * sizeof(ConsoleInfo->Buffer[0]);\r
485 ASSERT(CopySize < ConsoleInfo->BufferSize);\r
486 CopyMem(\r
487 ConsoleInfo->Buffer,\r
488 ConsoleInfo->Buffer + (ConsoleInfo->ColsPerScreen + 2),\r
489 CopySize\r
490 );\r
491\r
492 //\r
493 // Set that last row of chars to spaces\r
494 //\r
495 SetMem16(((UINT8*)ConsoleInfo->Buffer)+CopySize, ConsoleInfo->ColsPerScreen*sizeof(CHAR16), L' ');\r
496 } else {\r
497 //\r
498 // we are not on the last row\r
499 //\r
500\r
501 //\r
502 // We should not be scrolling history\r
503 //\r
504 ASSERT (ConsoleInfo->OriginalStartRow == ConsoleInfo->CurrentStartRow);\r
505 //\r
506 // are we at the end of a row?\r
507 //\r
508 if (ConsoleInfo->HistoryMode.CursorRow == (INT32) (ConsoleInfo->OriginalStartRow + ConsoleInfo->RowsPerScreen - 1)) {\r
509 ConsoleInfo->OriginalStartRow++;\r
510 ConsoleInfo->CurrentStartRow++;\r
511 }\r
512 ConsoleInfo->HistoryMode.CursorRow++;\r
513 }\r
514 break;\r
515 case (CHAR_CARRIAGE_RETURN):\r
516 //\r
517 // Move the cursor to the beginning of the current row.\r
518 //\r
519 ConsoleInfo->HistoryMode.CursorColumn = 0;\r
520 break;\r
521 default:\r
522 //\r
523 // Acrtually print characters into the history buffer\r
524 //\r
525\r
526 PrintIndex = ConsoleInfo->HistoryMode.CursorRow * ConsoleInfo->ColsPerScreen + ConsoleInfo->HistoryMode.CursorColumn;\r
527\r
528 for ( // no initializer needed\r
529 ; ConsoleInfo->HistoryMode.CursorColumn < (INT32) ConsoleInfo->ColsPerScreen\r
530 ; ConsoleInfo->HistoryMode.CursorColumn++\r
531 , PrintIndex++\r
532 , Walker++\r
533 ){\r
534 if (*Walker == CHAR_NULL\r
535 ||*Walker == CHAR_BACKSPACE\r
536 ||*Walker == CHAR_LINEFEED\r
537 ||*Walker == CHAR_CARRIAGE_RETURN\r
538 ){\r
539 Walker--;\r
540 break;\r
541 }\r
542 //\r
543 // The buffer is 2*CursorRow more since it has that many \r\n characters at the end of each row.\r
544 //\r
545\r
546 ASSERT(PrintIndex + ConsoleInfo->HistoryMode.CursorRow < ConsoleInfo->BufferSize);\r
547 ConsoleInfo->Buffer[PrintIndex + (2*ConsoleInfo->HistoryMode.CursorRow)] = *Walker;\r
548 ASSERT(PrintIndex < ConsoleInfo->AttribSize);\r
549 ConsoleInfo->Attributes[PrintIndex] = ConsoleInfo->HistoryMode.Attribute;\r
550 } // for loop\r
551\r
552 //\r
553 // Add the carriage return and line feed at the end of the lines\r
554 //\r
555 if (ConsoleInfo->HistoryMode.CursorColumn >= (INT32)ConsoleInfo->ColsPerScreen) {\r
556 AppendStringToHistory(L"\r\n", ConsoleInfo);\r
557 Walker--;\r
558 }\r
559\r
560 break;\r
561 } // switch for character\r
562 } // for loop\r
563\r
564 return (EFI_SUCCESS);\r
565}\r
566\r
567/**\r
568 Worker function to handle printing the output to the screen\r
569 and the history buffer\r
570\r
571 @param[in] String The string to output\r
572 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
573\r
574 @retval EFI_SUCCESS The string was printed\r
575 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
576 the text.\r
577 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
578 defined text mode.\r
579 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
580 characters in the Unicode string could not be\r
581 rendered and were skipped.\r
582**/\r
583EFI_STATUS\r
584EFIAPI\r
585ConsoleLoggerOutputStringSplit(\r
586 IN CONST CHAR16 *String,\r
587 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
588 )\r
589{\r
590 EFI_STATUS Status;\r
591\r
592 //\r
593 // Forward the request to the original ConOut\r
594 //\r
595 Status = ConsoleInfo->OldConOut->OutputString (ConsoleInfo->OldConOut, (CHAR16*)String);\r
596\r
597 if (EFI_ERROR(Status)) {\r
598 return (Status);\r
599 }\r
600\r
601 return (AppendStringToHistory(String, ConsoleInfo));\r
602}\r
603\r
604/**\r
605 Function to handle page break mode.\r
606\r
607 This function will prompt for continue or break.\r
608\r
609 @retval EFI_SUCCESS Continue was choosen\r
610 @return other Break was choosen\r
611**/\r
612EFI_STATUS\r
613EFIAPI\r
614ConsoleLoggerDoPageBreak(\r
615 VOID\r
616 )\r
617{\r
618 SHELL_PROMPT_RESPONSE *Resp;\r
619 EFI_STATUS Status;\r
620\r
621 Resp = NULL;\r
622 ASSERT(ShellInfoObject.PageBreakEnabled);\r
623 ShellInfoObject.PageBreakEnabled = FALSE;\r
624 Status = ShellPromptForResponseHii(ShellPromptResponseTypeQuitContinue, STRING_TOKEN(STR_SHELL_QUIT_CONT), ShellInfoObject.HiiHandle, (VOID**)&Resp);\r
625 ShellInfoObject.PageBreakEnabled = TRUE;\r
626 ASSERT(Resp != NULL);\r
627 if (Resp == NULL) {\r
628 return (EFI_NOT_FOUND);\r
629 }\r
630 if (EFI_ERROR(Status)) {\r
631 if (Resp != NULL) {\r
632 FreePool(Resp);\r
633 }\r
634 return (Status);\r
635 }\r
636 if (*Resp == ShellPromptResponseContinue) {\r
637 FreePool(Resp);\r
733f138d 638 ShellInfoObject.ConsoleInfo->RowCounter = 0;\r
639// ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorRow = 0;\r
640// ShellInfoObject.ConsoleInfo->OurConOut.Mode->CursorColumn = 0;\r
641\r
a405b86d 642 return (EFI_SUCCESS);\r
643 } else if (*Resp == ShellPromptResponseQuit) {\r
644 FreePool(Resp);\r
645 ShellInfoObject.ConsoleInfo->Enabled = FALSE;\r
646 return (EFI_DEVICE_ERROR);\r
647 } else {\r
648 ASSERT(FALSE);\r
649 }\r
650 return (EFI_SUCCESS);\r
651}\r
652/**\r
653 Worker function to handle printing the output with page breaks.\r
654\r
655 @param[in] String The string to output\r
656 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
657\r
658 @retval EFI_SUCCESS The string was printed\r
659 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
660 the text.\r
661 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
662 defined text mode.\r
663 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
664 characters in the Unicode string could not be\r
665 rendered and were skipped.\r
666**/\r
667EFI_STATUS\r
668EFIAPI\r
669ConsoleLoggerPrintWithPageBreak(\r
733f138d 670 IN CONST CHAR16 *String,\r
a405b86d 671 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
672 )\r
673{\r
674 CONST CHAR16 *Walker;\r
675 CONST CHAR16 *LineStart;\r
733f138d 676 CHAR16 *StringCopy;\r
a405b86d 677 CHAR16 TempChar;\r
678\r
733f138d 679 StringCopy = NULL;\r
680 StringCopy = StrnCatGrow(&StringCopy, NULL, String, 0);\r
681 if (StringCopy == NULL) {\r
682 return (EFI_OUT_OF_RESOURCES);\r
683 }\r
684\r
685 for ( Walker = StringCopy\r
686 , LineStart = StringCopy\r
a405b86d 687 ; Walker != NULL && *Walker != CHAR_NULL\r
688 ; Walker++\r
689 ){\r
690 switch (*Walker) {\r
691 case (CHAR_BACKSPACE):\r
692 if (ConsoleInfo->OurConOut.Mode->CursorColumn > 0) {\r
693 ConsoleInfo->OurConOut.Mode->CursorColumn--;\r
694 }\r
695 break;\r
696 case (CHAR_LINEFEED):\r
697 //\r
698 // add a temp NULL terminator\r
699 //\r
700 TempChar = *(Walker + 1);\r
701 *((CHAR16*)(Walker+1)) = CHAR_NULL;\r
702\r
703 //\r
704 // output the string\r
705 //\r
706 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
707\r
708 //\r
709 // restore the temp NULL terminator to it's original character\r
710 //\r
711 *((CHAR16*)(Walker+1)) = TempChar;\r
712\r
713 //\r
714 // Update LineStart Variable\r
715 //\r
716 LineStart = Walker + 1;\r
717\r
718 //\r
719 // increment row count\r
720 //\r
721 ShellInfoObject.ConsoleInfo->RowCounter++;\r
722 ConsoleInfo->OurConOut.Mode->CursorRow++;\r
723\r
724 break;\r
725 case (CHAR_CARRIAGE_RETURN):\r
726 //\r
727 // Move the cursor to the beginning of the current row.\r
728 //\r
729 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;\r
730 break;\r
731 default:\r
732 //\r
733 // increment column count\r
734 //\r
735 ConsoleInfo->OurConOut.Mode->CursorColumn++;\r
736 //\r
737 // check if that is the last column\r
738 //\r
a49f6a2f 739 if ((INTN)ConsoleInfo->ColsPerScreen == ConsoleInfo->OurConOut.Mode->CursorColumn + 1) {\r
a405b86d 740 //\r
741 // output a line similar to the linefeed character.\r
742 //\r
743\r
744 //\r
745 // add a temp NULL terminator\r
746 //\r
747 TempChar = *(Walker + 1);\r
748 *((CHAR16*)(Walker+1)) = CHAR_NULL;\r
749\r
750 //\r
751 // output the string\r
752 //\r
753 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
754\r
755 //\r
756 // restore the temp NULL terminator to it's original character\r
757 //\r
758 *((CHAR16*)(Walker+1)) = TempChar;\r
759\r
760 //\r
761 // Update LineStart Variable\r
762 //\r
a49f6a2f 763 LineStart = Walker + 1;\r
a405b86d 764\r
765 //\r
766 // increment row count and zero the column\r
767 //\r
768 ShellInfoObject.ConsoleInfo->RowCounter++;\r
769 ConsoleInfo->OurConOut.Mode->CursorRow++;\r
770 ConsoleInfo->OurConOut.Mode->CursorColumn = 0;\r
771 } // last column on line\r
772 break;\r
773 } // switch for character\r
774\r
775 //\r
776 // check if that was the last printable row. If yes handle PageBreak mode\r
777 //\r
778 if ((ConsoleInfo->RowsPerScreen) -1 == ShellInfoObject.ConsoleInfo->RowCounter) {\r
779 if (EFI_ERROR(ConsoleLoggerDoPageBreak())) {\r
780 //\r
781 // We got an error which means 'break' and halt the printing\r
782 //\r
733f138d 783 SHELL_FREE_NON_NULL(StringCopy);\r
a405b86d 784 return (EFI_DEVICE_ERROR);\r
785 }\r
786 }\r
787 } // for loop\r
788\r
789 if (LineStart != NULL && *LineStart != CHAR_NULL) {\r
790 ConsoleLoggerOutputStringSplit (LineStart, ConsoleInfo);\r
791 }\r
792\r
733f138d 793 SHELL_FREE_NON_NULL(StringCopy);\r
a405b86d 794 return (EFI_SUCCESS);\r
795}\r
796\r
797/**\r
798 Write a Unicode string to the output device.\r
799\r
800 @param[in] This Protocol instance pointer.\r
801 @param[in] WString The NULL-terminated Unicode string to be displayed on the output\r
802 device(s). All output devices must also support the Unicode\r
803 drawing defined in this file.\r
804 @retval EFI_SUCCESS The string was output to the device.\r
805 @retval EFI_DEVICE_ERROR The device reported an error while attempting to output\r
806 the text.\r
807 @retval EFI_UNSUPPORTED The output device's mode is not currently in a\r
808 defined text mode.\r
809 @retval EFI_WARN_UNKNOWN_GLYPH This warning code indicates that some of the\r
810 characters in the Unicode string could not be\r
811 rendered and were skipped.\r
812**/\r
813EFI_STATUS\r
814EFIAPI\r
815ConsoleLoggerOutputString (\r
816 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
817 IN CHAR16 *WString\r
818 )\r
819{\r
a49f6a2f 820 EFI_INPUT_KEY Key;\r
821 UINTN EventIndex;\r
a405b86d 822 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
823 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
733f138d 824 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {\r
825 return (EFI_UNSUPPORTED);\r
826 }\r
a405b86d 827 ASSERT(ShellInfoObject.ConsoleInfo == ConsoleInfo);\r
a49f6a2f 828 if (ShellInfoObject.HaltOutput) {\r
829 //\r
830 // just get some key\r
831 //\r
832 gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);\r
833 gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
834 ShellInfoObject.HaltOutput = FALSE;\r
835 }\r
a405b86d 836 if (!ShellInfoObject.ConsoleInfo->Enabled) {\r
837 return (EFI_DEVICE_ERROR);\r
838 } else if (ShellInfoObject.PageBreakEnabled) {\r
839 return (ConsoleLoggerPrintWithPageBreak(WString, ConsoleInfo));\r
840 } else {\r
841 return (ConsoleLoggerOutputStringSplit(WString, ConsoleInfo));\r
842 }\r
843}\r
844\r
845/**\r
846 Verifies that all characters in a Unicode string can be output to the\r
847 target device.\r
848\r
849 @param[in] This Protocol instance pointer.\r
850 @param[in] WString The NULL-terminated Unicode string to be examined for the output\r
851 device(s).\r
852\r
853 @retval EFI_SUCCESS The device(s) are capable of rendering the output string.\r
854 @retval EFI_UNSUPPORTED Some of the characters in the Unicode string cannot be\r
855 rendered by one or more of the output devices mapped\r
856 by the EFI handle.\r
857\r
858**/\r
859EFI_STATUS\r
860EFIAPI\r
861ConsoleLoggerTestString (\r
862 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
863 IN CHAR16 *WString\r
864 )\r
865{\r
866 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
867 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
868 //\r
869 // Forward the request to the original ConOut\r
870 //\r
871 return (ConsoleInfo->OldConOut->TestString (ConsoleInfo->OldConOut, WString));\r
872}\r
873\r
874/**\r
875 Returns information for an available text mode that the output device(s)\r
876 supports.\r
877\r
878 @param[in] This Protocol instance pointer.\r
879 @param[in] ModeNumber The mode number to return information on.\r
880 @param[out] Columns Upon return, the number of columns in the selected geometry\r
881 @param[out] Rows Upon return, the number of rows in the selected geometry\r
882\r
883 @retval EFI_SUCCESS The requested mode information was returned.\r
884 @retval EFI_DEVICE_ERROR The device had an error and could not\r
885 complete the request.\r
886 @retval EFI_UNSUPPORTED The mode number was not valid.\r
887**/\r
888EFI_STATUS\r
889EFIAPI\r
890ConsoleLoggerQueryMode (\r
891 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
892 IN UINTN ModeNumber,\r
893 OUT UINTN *Columns,\r
894 OUT UINTN *Rows\r
895 )\r
896{\r
897 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
898 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
899 //\r
900 // Forward the request to the original ConOut\r
901 //\r
902 return (ConsoleInfo->OldConOut->QueryMode (\r
903 ConsoleInfo->OldConOut,\r
904 ModeNumber,\r
905 Columns,\r
906 Rows\r
907 ));\r
908}\r
909\r
910/**\r
911 Sets the output device(s) to a specified mode.\r
912\r
913 @param[in] This Protocol instance pointer.\r
914 @param[in] ModeNumber The mode number to set.\r
915\r
916\r
917 @retval EFI_SUCCESS The requested text mode was set.\r
918 @retval EFI_DEVICE_ERROR The device had an error and\r
919 could not complete the request.\r
920 @retval EFI_UNSUPPORTED The mode number was not valid.\r
921**/\r
922EFI_STATUS\r
923EFIAPI\r
924ConsoleLoggerSetMode (\r
733f138d 925 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
926 IN UINTN ModeNumber\r
a405b86d 927 )\r
928{\r
929 EFI_STATUS Status;\r
930\r
931 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
932 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
933\r
934 //\r
935 // Forward the request to the original ConOut\r
936 //\r
937 Status = ConsoleInfo->OldConOut->SetMode (ConsoleInfo->OldConOut, ModeNumber);\r
938\r
939 //\r
940 // Check that the buffers are still correct for logging\r
941 //\r
942 if (!EFI_ERROR (Status)) {\r
733f138d 943 ConsoleInfo->OurConOut.Mode = gST->ConOut->Mode;\r
a405b86d 944 ConsoleLoggerResetBuffers(ConsoleInfo);\r
945 }\r
946\r
947 return Status;\r
948}\r
949\r
950/**\r
951 Sets the background and foreground colors for the OutputString () and\r
952 ClearScreen () functions.\r
953\r
954 @param[in] This Protocol instance pointer.\r
955 @param[in] Attribute The attribute to set. Bits 0..3 are the foreground color, and\r
956 bits 4..6 are the background color. All other bits are undefined\r
957 and must be zero. The valid Attributes are defined in this file.\r
958\r
959 @retval EFI_SUCCESS The attribute was set.\r
960 @retval EFI_DEVICE_ERROR The device had an error and\r
961 could not complete the request.\r
962 @retval EFI_UNSUPPORTED The attribute requested is not defined.\r
963\r
964**/\r
965EFI_STATUS\r
966EFIAPI\r
967ConsoleLoggerSetAttribute (\r
968 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
969 IN UINTN Attribute\r
970 )\r
971{\r
972 EFI_STATUS Status;\r
973\r
974 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
975 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
976\r
977 //\r
978 // Forward the request to the original ConOut\r
979 //\r
980 Status = ConsoleInfo->OldConOut->SetAttribute (ConsoleInfo->OldConOut, Attribute);\r
981\r
982 //\r
983 // Record console output history\r
984 //\r
985 if (!EFI_ERROR (Status)) {\r
986 ConsoleInfo->HistoryMode.Attribute = (INT32) Attribute;\r
987 }\r
988\r
989 return Status;\r
990}\r
991\r
992/**\r
993 Clears the output device(s) display to the currently selected background\r
994 color.\r
995\r
996 @param[in] This Protocol instance pointer.\r
997\r
998 @retval EFI_SUCCESS The operation completed successfully.\r
999 @retval EFI_DEVICE_ERROR The device had an error and\r
1000 could not complete the request.\r
1001 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
1002**/\r
1003EFI_STATUS\r
1004EFIAPI\r
1005ConsoleLoggerClearScreen (\r
1006 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This\r
1007 )\r
1008{\r
1009 EFI_STATUS Status;\r
1010 CHAR16 *Screen;\r
1011 INT32 *Attributes;\r
1012 UINTN Row;\r
1013 UINTN Column;\r
733f138d 1014 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
a405b86d 1015\r
733f138d 1016 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {\r
1017 return (EFI_UNSUPPORTED);\r
1018 }\r
a405b86d 1019\r
a405b86d 1020 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
1021\r
1022 //\r
1023 // Forward the request to the original ConOut\r
1024 //\r
1025 Status = ConsoleInfo->OldConOut->ClearScreen (ConsoleInfo->OldConOut);\r
1026\r
1027 //\r
1028 // Record console output history\r
1029 //\r
1030 if (!EFI_ERROR (Status)) {\r
1df5c64c 1031 Screen = &ConsoleInfo->Buffer[(ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->CurrentStartRow];\r
a405b86d 1032 Attributes = &ConsoleInfo->Attributes[ConsoleInfo->ColsPerScreen * ConsoleInfo->CurrentStartRow];\r
1033 for ( Row = ConsoleInfo->OriginalStartRow\r
1034 ; Row < (ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount)\r
1035 ; Row++\r
1036 ){\r
1037 for ( Column = 0\r
1038 ; Column < ConsoleInfo->ColsPerScreen\r
1039 ; Column++\r
1040 , Screen++\r
1041 , Attributes++\r
1042 ){\r
1043 *Screen = L' ';\r
1044 *Attributes = ConsoleInfo->OldConOut->Mode->Attribute;\r
1045 }\r
1046 //\r
1047 // Skip the NULL on each column end in text buffer only\r
1048 //\r
1df5c64c 1049 Screen += 2;\r
a405b86d 1050 }\r
1051 ConsoleInfo->HistoryMode.CursorColumn = 0;\r
1052 ConsoleInfo->HistoryMode.CursorRow = 0;\r
1053 }\r
1054\r
1055 return Status;\r
1056}\r
1057\r
1058/**\r
1059 Sets the current coordinates of the cursor position\r
1060\r
1061 @param[in] This Protocol instance pointer.\r
1062 @param[in] Column Column to put the cursor in. Must be between zero and Column returned from QueryMode\r
1063 @param[in] Row Row to put the cursor in. Must be between zero and Row returned from QueryMode\r
1064\r
1065 @retval EFI_SUCCESS The operation completed successfully.\r
1066 @retval EFI_DEVICE_ERROR The device had an error and\r
1067 could not complete the request.\r
1068 @retval EFI_UNSUPPORTED The output device is not in a valid text mode, or the\r
1069 cursor position is invalid for the current mode.\r
1070**/\r
1071EFI_STATUS\r
1072EFIAPI\r
1073ConsoleLoggerSetCursorPosition (\r
1074 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1075 IN UINTN Column,\r
1076 IN UINTN Row\r
1077 )\r
1078{\r
1079 EFI_STATUS Status;\r
a405b86d 1080 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
733f138d 1081\r
1082 if (ShellInfoObject.ShellInitSettings.BitUnion.Bits.NoConsoleOut) {\r
1083 return (EFI_UNSUPPORTED);\r
1084 }\r
1085\r
a405b86d 1086 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
1087 //\r
1088 // Forward the request to the original ConOut\r
1089 //\r
1090 Status = ConsoleInfo->OldConOut->SetCursorPosition (\r
1091 ConsoleInfo->OldConOut,\r
1092 Column,\r
1093 Row\r
1094 );\r
1095\r
1096 //\r
1097 // Record console output history\r
1098 //\r
1099 if (!EFI_ERROR (Status)) {\r
1100 ConsoleInfo->HistoryMode.CursorColumn = (INT32)Column;\r
1101 ConsoleInfo->HistoryMode.CursorRow = (INT32)(ConsoleInfo->OriginalStartRow + Row);\r
1102 }\r
1103\r
1104 return Status;\r
1105}\r
1106\r
1107/**\r
1108 Makes the cursor visible or invisible\r
1109\r
1110 @param[in] This Protocol instance pointer.\r
1111 @param[in] Visible If TRUE, the cursor is set to be visible. If FALSE, the cursor is\r
1112 set to be invisible.\r
1113\r
1114 @retval EFI_SUCCESS The operation completed successfully.\r
1115 @retval EFI_DEVICE_ERROR The device had an error and could not complete the\r
1116 request, or the device does not support changing\r
1117 the cursor mode.\r
1118 @retval EFI_UNSUPPORTED The output device is not in a valid text mode.\r
1119**/\r
1120EFI_STATUS\r
1121EFIAPI\r
1122ConsoleLoggerEnableCursor (\r
1123 IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,\r
1124 IN BOOLEAN Visible\r
1125 )\r
1126{\r
1127 EFI_STATUS Status;\r
1128\r
1129 CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo;\r
1130 ConsoleInfo = CONSOLE_LOGGER_PRIVATE_DATA_FROM_THIS(This);\r
1131 //\r
1132 // Forward the request to the original ConOut\r
1133 //\r
1134 Status = ConsoleInfo->OldConOut->EnableCursor (ConsoleInfo->OldConOut, Visible);\r
1135\r
1136 //\r
1137 // Record console output history\r
1138 //\r
1139 if (!EFI_ERROR (Status)) {\r
1140 ConsoleInfo->HistoryMode.CursorVisible = Visible;\r
1141 }\r
1142\r
1143 return Status;\r
1144}\r
1145\r
1146/**\r
1147 Function to update and verify that the current buffers are correct.\r
1148\r
1149 @param[in] ConsoleInfo The pointer to the instance of the console logger information.\r
1150\r
1151 This will be used when a mode has changed or a reset ocurred to verify all\r
1152 history buffers.\r
1153**/\r
1154EFI_STATUS\r
1155EFIAPI\r
1156ConsoleLoggerResetBuffers(\r
1157 IN CONSOLE_LOGGER_PRIVATE_DATA *ConsoleInfo\r
1158 )\r
1159{\r
1160 EFI_STATUS Status;\r
1161\r
1162 if (ConsoleInfo->Buffer != NULL) {\r
1163 FreePool(ConsoleInfo->Buffer);\r
1164 ConsoleInfo->Buffer = NULL;\r
1165 ConsoleInfo->BufferSize = 0;\r
1166 }\r
1167 if (ConsoleInfo->Attributes != NULL) {\r
1168 FreePool(ConsoleInfo->Attributes);\r
1169 ConsoleInfo->Attributes = NULL;\r
1170 ConsoleInfo->AttribSize = 0;\r
1171 }\r
1172\r
1173 Status = gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &ConsoleInfo->ColsPerScreen, &ConsoleInfo->RowsPerScreen);\r
1174 if (EFI_ERROR(Status)){\r
1175 return (Status);\r
1176 }\r
1177\r
1178 ConsoleInfo->BufferSize = (ConsoleInfo->ColsPerScreen + 2) * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Buffer[0]);\r
1179 ConsoleInfo->AttribSize = ConsoleInfo->ColsPerScreen * ConsoleInfo->RowsPerScreen * ConsoleInfo->ScreenCount * sizeof(ConsoleInfo->Attributes[0]);\r
1180\r
1181 ConsoleInfo->Buffer = (CHAR16*)AllocateZeroPool(ConsoleInfo->BufferSize);\r
1182\r
1183 if (ConsoleInfo->Buffer == NULL) {\r
1184 return (EFI_OUT_OF_RESOURCES);\r
1185 }\r
1186\r
1187 ConsoleInfo->Attributes = (INT32*)AllocateZeroPool(ConsoleInfo->AttribSize);\r
1188 if (ConsoleInfo->Attributes == NULL) {\r
1189 FreePool(ConsoleInfo->Buffer);\r
1190 ConsoleInfo->Buffer = NULL;\r
1191 return (EFI_OUT_OF_RESOURCES);\r
1192 }\r
1193\r
a405b86d 1194 CopyMem (&ConsoleInfo->HistoryMode, ConsoleInfo->OldConOut->Mode, sizeof (EFI_SIMPLE_TEXT_OUTPUT_MODE));\r
1195\r
1196 return (EFI_SUCCESS);\r
1197}\r