Source code of Windows XP (NT5)
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.

1146 lines
22 KiB

  1. //
  2. // DISPLAY OSCHOOSE SCREENS
  3. //
  4. #include <nt.h>
  5. #include <ntrtl.h>
  6. #include <nturtl.h>
  7. #include <ntseapi.h>
  8. #include <windows.h>
  9. #include <winsock.h>
  10. #undef ERROR
  11. #include <stdio.h>
  12. CHAR DomainName[64];
  13. CHAR UserName[64];
  14. CHAR Password[64];
  15. VOID
  16. BiosConsoleWrite(
  17. IN ULONG FileId,
  18. OUT PUCHAR Buffer,
  19. IN ULONG Length,
  20. OUT PULONG Count
  21. );
  22. ULONG __cdecl
  23. BiosConsoleGetKey(
  24. void
  25. );
  26. ULONG __cdecl
  27. BiosConsoleGetCounter(
  28. void
  29. );
  30. #include "..\boot\oschoice\oscheap.c"
  31. #define _BUILDING_OSDISP_
  32. #include "..\boot\oschoice\parse.c"
  33. #if DBG
  34. ULONG NetDebugFlag =
  35. DEBUG_ERROR |
  36. DEBUG_OSC;
  37. #endif
  38. //
  39. // This is declared and expected by parse.c, so we defined the functions
  40. // for the macros it uses (GET_KEY and GET_COUNTER) and NULL the rest out.
  41. //
  42. EXTERNAL_SERVICES_TABLE ServicesTable = {
  43. NULL, // RebootProcessor
  44. NULL, // DiskIOSystem
  45. BiosConsoleGetKey,
  46. BiosConsoleGetCounter,
  47. NULL, // Reboot
  48. NULL, // AbiosServices
  49. NULL, // DetectHardware
  50. NULL, // HardwareCursor
  51. NULL, // GetDateTime
  52. NULL, // ComPort
  53. NULL, // IsMcaMachine
  54. NULL, // GetStallCount
  55. NULL, // InitializeDisplayForNt
  56. NULL, // GetMemoryDescriptor
  57. NULL, // GetEddsSector
  58. NULL, // GetElToritoStatus
  59. NULL // GetExtendedInt13Params
  60. };
  61. PEXTERNAL_SERVICES_TABLE ExternalServicesTable = &ServicesTable;
  62. //
  63. // This is used by the ArcWrite function -- it only cares about the firmware vector
  64. // which is the 28th entry.
  65. //
  66. PVOID FirmwareVector[38] = {
  67. NULL, NULL, NULL, NULL, NULL,
  68. NULL, NULL, NULL, NULL, NULL,
  69. NULL, NULL, NULL, NULL, NULL,
  70. NULL, NULL, NULL, NULL, NULL,
  71. NULL, NULL, NULL, NULL, NULL,
  72. NULL, NULL, (PVOID)BiosConsoleWrite, NULL, NULL,
  73. NULL, NULL, NULL, NULL, NULL,
  74. NULL, NULL, NULL
  75. };
  76. SYSTEM_PARAMETER_BLOCK GlobalSystemBlock = {
  77. 0, // Signature
  78. 0, // Length
  79. 0, // Version
  80. 0, // Revision
  81. NULL, // RestartBlock
  82. NULL, // DebugBlock
  83. NULL, // GenerateExceptionVector
  84. NULL, // TlbMissExceptionVector
  85. sizeof(FirmwareVector),
  86. FirmwareVector,
  87. 0, // VendorVectorLength
  88. NULL, // VendorVector
  89. 0, // AdapterCount
  90. 0, // Adapter0Type
  91. 0, // Adapter0Length
  92. NULL // Adapter0Vector
  93. };
  94. //
  95. // Current screen position.
  96. //
  97. USHORT TextColumn = 0;
  98. USHORT TextRow = 0;
  99. //
  100. // Height and width of the console.
  101. //
  102. USHORT ScreenWidthCells;
  103. USHORT ScreenHeightCells;
  104. //
  105. // Current text attribute
  106. //
  107. UCHAR TextCurrentAttribute = 0x07; // start with white on black.
  108. //
  109. // Standard input and output handles.
  110. //
  111. HANDLE StandardInput;
  112. HANDLE StandardOutput;
  113. UCHAR EightySpaces[] =
  114. " ";
  115. //
  116. // defines for doing console I/O
  117. //
  118. #define CSI 0x95
  119. #define SGR_INVERSE 7
  120. #define SGR_NORMAL 0
  121. //
  122. // static data for console I/O
  123. //
  124. BOOLEAN ControlSequence=FALSE;
  125. BOOLEAN EscapeSequence=FALSE;
  126. BOOLEAN FontSelection=FALSE;
  127. BOOLEAN HighIntensity=FALSE;
  128. BOOLEAN Blink=FALSE;
  129. ULONG PCount=0;
  130. #define CONTROL_SEQUENCE_MAX_PARAMETER 10
  131. ULONG Parameter[CONTROL_SEQUENCE_MAX_PARAMETER];
  132. #define KEY_INPUT_BUFFER_SIZE 16
  133. UCHAR KeyBuffer[KEY_INPUT_BUFFER_SIZE];
  134. ULONG KeyBufferEnd=0;
  135. ULONG KeyBufferStart=0;
  136. //
  137. // array for translating between ANSI colors and the VGA standard
  138. //
  139. UCHAR TranslateColor[] = {0,4,2,6,1,5,3,7};
  140. #define ASCI_ESC 0x1b
  141. //
  142. // Need this to link.
  143. //
  144. ULONG BlConsoleOutDeviceId = 0;
  145. CHAR
  146. BlProcessScreen(
  147. IN PCHAR InputString,
  148. OUT PCHAR OutputString
  149. );
  150. CHAR g_OutputString[1024];
  151. int __cdecl
  152. main (argc, argv)
  153. int argc;
  154. char *argv[];
  155. {
  156. DWORD Error;
  157. int i;
  158. HANDLE hFile;
  159. DWORD fileSize, bytesRead;
  160. PCHAR fileBuffer;
  161. CONSOLE_SCREEN_BUFFER_INFO bufferInfo;
  162. CONSOLE_CURSOR_INFO cursorInfo;
  163. COORD coord;
  164. PCHAR pszScreenName;
  165. CHAR LastKey;
  166. if (argc < 2) {
  167. printf("USAGE: %s [screen-file-name]\n", argv[0]);
  168. return -1;
  169. }
  170. //
  171. // Set up the console correctly. We allocate our own and resize
  172. // it to 80 x 25.
  173. //
  174. FreeConsole();
  175. AllocConsole();
  176. StandardInput = GetStdHandle(STD_INPUT_HANDLE);
  177. StandardOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  178. ScreenWidthCells = 81;
  179. ScreenHeightCells = 25;
  180. coord.X = ScreenWidthCells;
  181. coord.Y = ScreenHeightCells;
  182. SetConsoleScreenBufferSize(StandardOutput, coord);
  183. //
  184. // This actually turns *off* most processing.
  185. //
  186. SetConsoleMode(StandardInput, ENABLE_PROCESSED_INPUT);
  187. //
  188. // Hide the cursor.
  189. //
  190. cursorInfo.dwSize = 1;
  191. cursorInfo.bVisible = FALSE;
  192. SetConsoleCursorInfo(StandardOutput, &cursorInfo);
  193. //
  194. // Open the first parameter as a file.
  195. //
  196. pszScreenName = argv[1];
  197. NextScreen:
  198. hFile = CreateFileA(pszScreenName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
  199. if (hFile == INVALID_HANDLE_VALUE ) {
  200. printf("Could not open %s!\n", argv[1]);
  201. return -1;
  202. }
  203. fileSize = GetFileSize(hFile, NULL);
  204. printf("File %s is %d bytes\n", argv[1], fileSize);
  205. fileBuffer = LocalAlloc(0, fileSize+1);
  206. if (fileBuffer == NULL) {
  207. printf("Allocate failed!\n");
  208. return -1;
  209. }
  210. if (!ReadFile(hFile, fileBuffer, fileSize, &bytesRead, NULL)) {
  211. printf("Read failed\n");
  212. return -1;
  213. }
  214. if (bytesRead != fileSize) {
  215. printf("Too few bytes read\n");
  216. return -1;
  217. }
  218. CloseHandle(hFile);
  219. fileBuffer[fileSize] = '\0';
  220. LastKey = BlProcessScreen(fileBuffer, g_OutputString);
  221. if (SpecialAction == ACTION_REFRESH)
  222. goto NextScreen;
  223. {
  224. PCHAR psz = strchr( g_OutputString, '\n' );
  225. if ( psz )
  226. *psz = '\0';
  227. pszScreenName = g_OutputString;
  228. if ( strcmp( pszScreenName, "REBOOT" ) != 0
  229. && strcmp( pszScreenName, "LAUNCH" ) != 0 \
  230. && strcmp( pszScreenName, "" ) != 0 ) {
  231. // add the extension and jump to the next screen
  232. strcat( g_OutputString, ".osc" );
  233. goto NextScreen;
  234. }
  235. }
  236. //
  237. // I can't figure out how to write to the old console -- so for
  238. // now just display it and pause.
  239. //
  240. BlpClearScreen();
  241. SetConsoleTextAttribute(StandardOutput, 0x7);
  242. printf("String returned was <%s>\n", g_OutputString);
  243. printf("Press any key to exit\n");
  244. while (GET_KEY() == 0) {
  245. ;
  246. }
  247. }
  248. VOID
  249. TextGetCursorPosition(
  250. OUT PULONG X,
  251. OUT PULONG Y
  252. )
  253. /*++
  254. Routine Description:
  255. Gets the position of the soft cursor.
  256. Arguments:
  257. X - Receives column coordinate of where character would be written.
  258. Y - Receives row coordinate of where next character would be written.
  259. Returns:
  260. Nothing.
  261. --*/
  262. {
  263. *X = (ULONG)TextColumn;
  264. *Y = (ULONG)TextRow;
  265. }
  266. VOID
  267. TextSetCursorPosition(
  268. IN ULONG X,
  269. IN ULONG Y
  270. )
  271. /*++
  272. Routine Description:
  273. Moves the location of the software cursor to the specified X,Y position
  274. on screen.
  275. Arguments:
  276. X - Supplies the X-position of the cursor
  277. Y - Supplies the Y-position of the cursor
  278. Return Value:
  279. None.
  280. --*/
  281. {
  282. COORD coord;
  283. TextColumn = (USHORT)X;
  284. TextRow = (USHORT)Y;
  285. coord.X = (USHORT)X;
  286. coord.Y = (USHORT)Y;
  287. SetConsoleCursorPosition(StandardOutput, coord);
  288. }
  289. VOID
  290. TextSetCurrentAttribute(
  291. IN UCHAR Attribute
  292. )
  293. /*++
  294. Routine Description:
  295. Sets the character attribute to be used for subsequent text display.
  296. Arguments:
  297. Returns:
  298. Nothing.
  299. --*/
  300. {
  301. TextCurrentAttribute = Attribute;
  302. SetConsoleTextAttribute(StandardOutput, Attribute);
  303. }
  304. UCHAR
  305. TextGetCurrentAttribute(
  306. VOID
  307. )
  308. {
  309. return(TextCurrentAttribute);
  310. }
  311. PUCHAR
  312. TextCharOut(
  313. IN PUCHAR pc
  314. )
  315. {
  316. DWORD numWritten;
  317. WriteConsoleA(StandardOutput, pc, 1, &numWritten, NULL);
  318. return(pc+1);
  319. }
  320. VOID
  321. TextClearToEndOfLine(
  322. VOID
  323. )
  324. /*++
  325. Routine Description:
  326. Clears from the current cursor position to the end of the line
  327. by writing blanks with the current video attribute.
  328. Arguments:
  329. None
  330. Returns:
  331. Nothing
  332. --*/
  333. {
  334. unsigned u;
  335. ULONG OldX,OldY;
  336. UCHAR temp;
  337. //
  338. // Fill with blanks up to char before cursor position.
  339. //
  340. temp = ' ';
  341. TextGetCursorPosition(&OldX,&OldY);
  342. for(u=TextColumn; u<ScreenWidthCells; u++) {
  343. TextCharOut(&temp);
  344. }
  345. TextSetCursorPosition(OldX,OldY);
  346. }
  347. VOID
  348. TextClearFromStartOfLine(
  349. VOID
  350. )
  351. /*++
  352. Routine Description:
  353. Clears from the start of the line to the current cursor position
  354. by writing blanks with the current video attribute.
  355. The cursor position is not changed.
  356. Arguments:
  357. None
  358. Returns:
  359. Nothing
  360. --*/
  361. {
  362. unsigned u;
  363. ULONG OldX,OldY;
  364. UCHAR temp = ' ';
  365. //
  366. // Fill with blanks up to char before cursor position.
  367. //
  368. TextGetCursorPosition(&OldX,&OldY);
  369. TextSetCursorPosition(0,OldY);
  370. for(u=0; u<TextColumn; u++) {
  371. TextCharOut(&temp);
  372. }
  373. TextSetCursorPosition(OldX,OldY);
  374. }
  375. VOID
  376. TextClearToEndOfDisplay(
  377. VOID
  378. )
  379. /*++
  380. Routine Description:
  381. Clears from the current cursor position to the end of the video
  382. display by writing blanks with the current video attribute.
  383. The cursor position is not changed.
  384. Arguments:
  385. None
  386. Returns:
  387. Nothing
  388. --*/
  389. {
  390. USHORT x,y;
  391. ULONG OldX,OldY;
  392. DWORD numWritten;
  393. TextGetCursorPosition(&OldX,&OldY);
  394. //
  395. // Clear current line
  396. //
  397. TextClearToEndOfLine();
  398. //
  399. // Clear the remaining lines
  400. //
  401. for(y=TextRow+1; y<ScreenHeightCells; y++) {
  402. TextSetCursorPosition(0, y);
  403. WriteConsoleA(StandardOutput, EightySpaces, ScreenWidthCells, &numWritten, NULL);
  404. }
  405. TextSetCursorPosition(OldX,OldY);
  406. }
  407. VOID
  408. TextClearDisplay(
  409. VOID
  410. )
  411. /*++
  412. Routine Description:
  413. Clears the video display and positions the cursor
  414. at the upper left corner of the screen (0,0).
  415. Arguments:
  416. None
  417. Returns:
  418. Nothing
  419. --*/
  420. {
  421. USHORT y;
  422. DWORD numWritten;
  423. //
  424. // Clear screen.
  425. //
  426. for(y=0; y<ScreenHeightCells; y++) {
  427. TextSetCursorPosition(0, y);
  428. WriteConsoleA(StandardOutput, EightySpaces, ScreenWidthCells, &numWritten, NULL);
  429. }
  430. TextSetCursorPosition(0,0);
  431. }
  432. //
  433. // This function was stolen from ..\lib\i386\biosdrv.c (except the return
  434. // type was changed to VOID).
  435. //
  436. VOID
  437. BiosConsoleWrite(
  438. IN ULONG FileId,
  439. OUT PUCHAR Buffer,
  440. IN ULONG Length,
  441. OUT PULONG Count
  442. )
  443. /*++
  444. Routine Description:
  445. Outputs to the console. (In this case, the VGA display)
  446. Arguments:
  447. FileId - Supplies the FileId to be written (should always be 1 for this
  448. function)
  449. Buffer - Supplies characters to be output
  450. Length - Supplies the length of the buffer (in bytes)
  451. Count - Returns the actual number of bytes written
  452. Return Value:
  453. ESUCCESS - Console write completed succesfully.
  454. --*/
  455. {
  456. ARC_STATUS Status;
  457. PUCHAR String;
  458. ULONG Index;
  459. UCHAR a;
  460. PUCHAR p;
  461. //
  462. // Process each character in turn.
  463. //
  464. Status = ESUCCESS;
  465. String = (PUCHAR)Buffer;
  466. for ( *Count = 0 ;
  467. *Count < Length ;
  468. (*Count)++, String++ ) {
  469. //
  470. // If we're in the middle of a control sequence, continue scanning,
  471. // otherwise process character.
  472. //
  473. if (ControlSequence) {
  474. //
  475. // If the character is a digit, update parameter value.
  476. //
  477. if ((*String >= '0') && (*String <= '9')) {
  478. Parameter[PCount] = Parameter[PCount] * 10 + *String - '0';
  479. continue;
  480. }
  481. //
  482. // If we are in the middle of a font selection sequence, this
  483. // character must be a 'D', otherwise reset control sequence.
  484. //
  485. if (FontSelection) {
  486. //if (*String == 'D') {
  487. //
  488. // //
  489. // // Other fonts not implemented yet.
  490. // //
  491. //
  492. //} else {
  493. //}
  494. ControlSequence = FALSE;
  495. FontSelection = FALSE;
  496. continue;
  497. }
  498. switch (*String) {
  499. //
  500. // If a semicolon, move to the next parameter.
  501. //
  502. case ';':
  503. PCount++;
  504. if (PCount > CONTROL_SEQUENCE_MAX_PARAMETER) {
  505. PCount = CONTROL_SEQUENCE_MAX_PARAMETER;
  506. }
  507. Parameter[PCount] = 0;
  508. break;
  509. //
  510. // If a 'J', erase part or all of the screen.
  511. //
  512. case 'J':
  513. switch (Parameter[0]) {
  514. case 0:
  515. //
  516. // Erase to end of the screen
  517. //
  518. TextClearToEndOfDisplay();
  519. break;
  520. case 1:
  521. //
  522. // Erase from the beginning of the screen
  523. //
  524. break;
  525. default:
  526. //
  527. // Erase entire screen
  528. //
  529. TextClearDisplay();
  530. break;
  531. }
  532. ControlSequence = FALSE;
  533. break;
  534. //
  535. // If a 'K', erase part or all of the line.
  536. //
  537. case 'K':
  538. switch (Parameter[0]) {
  539. //
  540. // Erase to end of the line.
  541. //
  542. case 0:
  543. TextClearToEndOfLine();
  544. break;
  545. //
  546. // Erase from the beginning of the line.
  547. //
  548. case 1:
  549. TextClearFromStartOfLine();
  550. break;
  551. //
  552. // Erase entire line.
  553. //
  554. default :
  555. TextClearFromStartOfLine();
  556. TextClearToEndOfLine();
  557. break;
  558. }
  559. ControlSequence = FALSE;
  560. break;
  561. //
  562. // If a 'H', move cursor to position.
  563. //
  564. case 'H':
  565. TextSetCursorPosition(Parameter[1]-1, Parameter[0]-1);
  566. ControlSequence = FALSE;
  567. break;
  568. //
  569. // If a ' ', could be a FNT selection command.
  570. //
  571. case ' ':
  572. FontSelection = TRUE;
  573. break;
  574. case 'm':
  575. //
  576. // Select action based on each parameter.
  577. //
  578. // Blink and HighIntensity are by default disabled
  579. // each time a new SGR is specified, unless they are
  580. // explicitly specified again, in which case these
  581. // will be set to TRUE at that time.
  582. //
  583. HighIntensity = FALSE;
  584. Blink = FALSE;
  585. for ( Index = 0 ; Index <= PCount ; Index++ ) {
  586. switch (Parameter[Index]) {
  587. //
  588. // Attributes off.
  589. //
  590. case 0:
  591. TextSetCurrentAttribute(7);
  592. HighIntensity = FALSE;
  593. Blink = FALSE;
  594. break;
  595. //
  596. // High Intensity.
  597. //
  598. case 1:
  599. TextSetCurrentAttribute(0xf);
  600. HighIntensity = TRUE;
  601. break;
  602. //
  603. // Underscored.
  604. //
  605. case 4:
  606. break;
  607. //
  608. // Blink.
  609. //
  610. case 5:
  611. TextSetCurrentAttribute(0x87);
  612. Blink = TRUE;
  613. break;
  614. //
  615. // Reverse Video.
  616. //
  617. case 7:
  618. TextSetCurrentAttribute(0x70);
  619. HighIntensity = FALSE;
  620. Blink = FALSE;
  621. break;
  622. //
  623. // Font selection, not implemented yet.
  624. //
  625. case 10:
  626. case 11:
  627. case 12:
  628. case 13:
  629. case 14:
  630. case 15:
  631. case 16:
  632. case 17:
  633. case 18:
  634. case 19:
  635. break;
  636. //
  637. // Foreground Color
  638. //
  639. case 30:
  640. case 31:
  641. case 32:
  642. case 33:
  643. case 34:
  644. case 35:
  645. case 36:
  646. case 37:
  647. a = TextGetCurrentAttribute();
  648. a &= 0x70;
  649. a |= TranslateColor[Parameter[Index]-30];
  650. if (HighIntensity) {
  651. a |= 0x08;
  652. }
  653. if (Blink) {
  654. a |= 0x80;
  655. }
  656. TextSetCurrentAttribute(a);
  657. break;
  658. //
  659. // Background Color
  660. //
  661. case 40:
  662. case 41:
  663. case 42:
  664. case 43:
  665. case 44:
  666. case 45:
  667. case 46:
  668. case 47:
  669. a = TextGetCurrentAttribute();
  670. a &= 0x8f;
  671. a |= TranslateColor[Parameter[Index]-40] << 4;
  672. TextSetCurrentAttribute(a);
  673. break;
  674. default:
  675. break;
  676. }
  677. }
  678. default:
  679. ControlSequence = FALSE;
  680. break;
  681. }
  682. //
  683. // This is not a control sequence, check for escape sequence.
  684. //
  685. } else {
  686. //
  687. // If escape sequence, check for control sequence, otherwise
  688. // process single character.
  689. //
  690. if (EscapeSequence) {
  691. //
  692. // Check for '[', means control sequence, any other following
  693. // character is ignored.
  694. //
  695. if (*String == '[') {
  696. ControlSequence = TRUE;
  697. //
  698. // Initialize first parameter.
  699. //
  700. PCount = 0;
  701. Parameter[0] = 0;
  702. }
  703. EscapeSequence = FALSE;
  704. //
  705. // This is not a control or escape sequence, process single character.
  706. //
  707. } else {
  708. switch (*String) {
  709. //
  710. // Check for escape sequence.
  711. //
  712. case ASCI_ESC:
  713. EscapeSequence = TRUE;
  714. break;
  715. default:
  716. p = TextCharOut(String);
  717. //
  718. // Each pass through the loop increments String by 1.
  719. // If we output a dbcs char we need to increment by
  720. // one more.
  721. //
  722. (*Count) += (p - String) - 1;
  723. String += (p - String) - 1;
  724. break;
  725. }
  726. }
  727. }
  728. }
  729. return;
  730. }
  731. ULONG __cdecl
  732. BiosConsoleGetKey(
  733. VOID
  734. )
  735. {
  736. INPUT_RECORD inputRecord;
  737. DWORD numRead;
  738. //
  739. // Loop until we see a key event or nothing.
  740. //
  741. while (TRUE) {
  742. PeekConsoleInput(
  743. StandardInput,
  744. &inputRecord,
  745. 1,
  746. &numRead);
  747. if (numRead == 0) {
  748. //
  749. // We read nothing -- sleep for a bit (since callers tend to loop
  750. // calling this) and return.
  751. //
  752. Sleep(100);
  753. return 0;
  754. }
  755. ReadConsoleInput(
  756. StandardInput,
  757. &inputRecord,
  758. 1,
  759. &numRead);
  760. if (inputRecord.EventType != KEY_EVENT) {
  761. continue;
  762. }
  763. //
  764. // We had a key event -- process the key down ones.
  765. //
  766. if (inputRecord.Event.KeyEvent.bKeyDown) {
  767. //
  768. // Construct the correct scancode/ASCII value combination.
  769. //
  770. //
  771. // HACK: shift-tab needs to be special-cased for some reason.
  772. //
  773. if ((inputRecord.Event.KeyEvent.uChar.AsciiChar == 0x09) &&
  774. ((inputRecord.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) != 0)) {
  775. return 0x0f00;
  776. } else {
  777. return
  778. (((inputRecord.Event.KeyEvent.wVirtualScanCode) & 0xff) << 8) +
  779. inputRecord.Event.KeyEvent.uChar.AsciiChar;
  780. }
  781. }
  782. }
  783. }
  784. ULONG __cdecl
  785. BiosConsoleGetCounter(
  786. VOID
  787. )
  788. {
  789. //
  790. // GetTickCount is in milliseconds, we want an 18.2/sec counter
  791. //
  792. return (GetTickCount() * 182) / 10000;
  793. }
  794. //
  795. // These two functions were taken from ..\lib\regboot.c.
  796. //
  797. VOID
  798. BlpPositionCursor(
  799. IN ULONG Column,
  800. IN ULONG Row
  801. )
  802. /*++
  803. Routine Description:
  804. Sets the position of the cursor on the screen.
  805. Arguments:
  806. Column - supplies new Column for the cursor position.
  807. Row - supplies new Row for the cursor position.
  808. Return Value:
  809. None.
  810. --*/
  811. {
  812. CHAR Buffer[16];
  813. ULONG Count;
  814. sprintf(Buffer, ASCI_CSI_OUT "%d;%dH", Row, Column);
  815. PRINTL(Buffer);
  816. }
  817. VOID
  818. BlpClearScreen(
  819. VOID
  820. )
  821. /*++
  822. Routine Description:
  823. Clears the screen.
  824. Arguments:
  825. None
  826. Return Value:
  827. None.
  828. --*/
  829. {
  830. CHAR Buffer[16];
  831. ULONG Count;
  832. sprintf(Buffer, ASCI_CSI_OUT "2J");
  833. PRINTL(Buffer);
  834. }