Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.1 KiB

  1. #include <efi.h>
  2. #include <efilib.h>
  3. typedef CHAR16* PWSTR;
  4. typedef const PWSTR PCWSTR;
  5. EFI_STATUS GetInputKey(
  6. EFI_INPUT_KEY* pKey);
  7. void DisplayKey(EFI_INPUT_KEY* pKey);
  8. // This string is used to check when the user has pressed "q" followed
  9. // by "u" followed by "i" followed by "t". This is the method to quit
  10. // the application and return to the EFI prompt.
  11. const PWSTR pszExitString = L"quit";
  12. // Constants to use when displaying what key was pressed.
  13. // Note that this array is indexed by EFI scan code, and includes
  14. // all keystrokes enumerated in the EFI v1.02 specification document.
  15. PCWSTR pszKeyStrings[] =
  16. {
  17. L"NULL scan code", // 0x00
  18. L"Move cursor up 1 row", // 0x01
  19. L"Move cursor down 1 row", // 0x02
  20. L"Move cursor right 1 column", // 0x03
  21. L"Move cursor left 1 column", // 0x04
  22. L"Home", // 0x05
  23. L"End", // 0x06
  24. L"Insert", // 0x07
  25. L"Delete", // 0x08
  26. L"Page Up", // 0x09
  27. L"Page Down", // 0x0a
  28. L"Function 1", // 0x0b
  29. L"Function 2", // 0x0c
  30. L"Function 3", // 0x0d
  31. L"Function 4", // 0x0e
  32. L"Function 5", // 0x0f
  33. L"Function 6", // 0x10
  34. L"Function 7", // 0x11
  35. L"Function 8", // 0x12
  36. L"Function 9", // 0x13
  37. L"Function 10", // 0x14
  38. L"INVALID scan code", // 0x15
  39. L"INVALID scan code", // 0x16
  40. L"Escape", // 0x17
  41. };
  42. // This is the main routine. After initializing the SDX library, we will
  43. // wait in a loop for keys to be pressed, and then we will display what
  44. // those keys are. I have made an effort to make the output as useful as
  45. // possible.
  46. EFI_STATUS EfiMain(
  47. IN EFI_HANDLE ImageHandle,
  48. IN EFI_SYSTEM_TABLE *SystemTable)
  49. {
  50. EFI_INPUT_KEY Key;
  51. EFI_STATUS Status;
  52. PWSTR pszExitCounter = pszExitString;
  53. // Initialize the EFI SDX libraries
  54. InitializeLib( ImageHandle, SystemTable );
  55. // Echo some message to the user, as the initialization takes
  56. // some time. At least the user will know when he can start
  57. // pressing keys.
  58. Print(L"EFI Keystroke Echo Utility.\n");
  59. Print(L"Type \"quit\" to quit.\n");
  60. // We will continue until the user has pressed quit. Note that each
  61. // successive correct key will cause pszExitCounter to be incremented,
  62. // and this will cause it to eventually point at the NULL character that
  63. // is terminating pszExitString.
  64. while (*pszExitCounter!=L'\0')
  65. {
  66. // Get a keystroke
  67. Status = GetInputKey(
  68. &Key);
  69. if (EFI_ERROR(Status))
  70. {
  71. Print(L"Error in ReadKeyStroke (0x%08x).\n", Status);
  72. break;
  73. }
  74. // Display the keystroke
  75. DisplayKey(&Key);
  76. // Check if this is the next key in the quit sequence
  77. if (Key.UnicodeChar==*pszExitCounter)
  78. {
  79. // If it is, then look for the next one.
  80. pszExitCounter++;
  81. }
  82. else
  83. {
  84. // Else start at the beginning.
  85. pszExitCounter = pszExitString;
  86. }
  87. }
  88. // We are quitting, so tell the user.
  89. Print(L"We are done.\n");
  90. // If you return the status, EFI will kindly give the user an English
  91. // error message.
  92. return Status;
  93. }
  94. EFI_STATUS GetInputKey(
  95. OUT EFI_INPUT_KEY* pKey)
  96. {
  97. EFI_STATUS Status;
  98. // Wait until a keystroke is available
  99. WaitForSingleEvent(
  100. ST->ConIn->WaitForKey,
  101. 0);
  102. // Read the key that has been pressed
  103. Status = ST->ConIn->ReadKeyStroke(
  104. ST->ConIn,
  105. pKey);
  106. // Return the status, whether success or failure
  107. return Status;
  108. }
  109. void DisplayKey(EFI_INPUT_KEY* pKey)
  110. {
  111. // Firstly, let's display the raw keystroke
  112. Print(L"0x%04x 0x%04x - ", pKey->ScanCode, pKey->UnicodeChar);
  113. // Let's check if this is a Unicode only key (some character)
  114. if (pKey->ScanCode==0)
  115. {
  116. // Is this a printable character
  117. if (pKey->UnicodeChar>=33 && pKey->UnicodeChar<=127)
  118. {
  119. // If so, print the character
  120. Print(L"\"%c\"", pKey->UnicodeChar);
  121. }
  122. else
  123. {
  124. // Else print it's numerical value
  125. Print(L"(CHAR16)0x%04x", pKey->UnicodeChar);
  126. }
  127. }
  128. // Check to ensure that this scancode is in the range that we have
  129. // a string constant for ...
  130. else if (pKey->ScanCode>=0 && pKey->ScanCode<=0x17)
  131. {
  132. // Display the string constant for our keystroke
  133. Print(L"%s", pszKeyStrings[pKey->ScanCode]);
  134. }
  135. else
  136. {
  137. // We know nothing about this keystroke, so say so.
  138. Print(L"INVALID scan code", pszKeyStrings[pKey->ScanCode]);
  139. }
  140. Print(L"\n");
  141. }