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.

1803 lines
51 KiB

  1. //depot/Lab01_N/Windows/Core/ntcon/client/iostubs.c#2 - integrate change 10363 (text)
  2. /*++
  3. Copyright (c) 1985 - 1999, Microsoft Corporation
  4. Module Name:
  5. iostubs.c
  6. Abstract:
  7. This module contains the stubs for the console I/O API.
  8. Author:
  9. Therese Stowell (thereses) 14-Nov-1990
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #pragma hdrstop
  15. #if !defined(BUILD_WOW6432)
  16. BOOL
  17. APIENTRY
  18. GetConsoleInput(
  19. IN HANDLE hConsoleInput,
  20. OUT PINPUT_RECORD lpBuffer,
  21. IN DWORD nLength,
  22. OUT LPDWORD lpNumberOfEventsRead,
  23. IN USHORT wFlags,
  24. IN BOOLEAN Unicode
  25. )
  26. /*++
  27. Parameters:
  28. hConsoleInput - Supplies an open handle to CONIN$ that is to be
  29. read. The handle must have been created with GENERIC_READ access.
  30. lpBuffer - Supplies the address of a buffer to receive the data read
  31. from the input buffer.
  32. nLength - Supplies the length of lpBuffer in INPUT_RECORDs.
  33. lpNumberOfEventsRead - Pointer to number of events read.
  34. wFlags - Flags that control how data is read.
  35. Return Value:
  36. TRUE - The operation was successful.
  37. FALSE/NULL - The operation failed.
  38. Extended error status is available using GetLastError.
  39. --*/
  40. {
  41. PCSR_CAPTURE_HEADER CaptureBuffer;
  42. CONSOLE_API_MSG m;
  43. PCONSOLE_GETCONSOLEINPUT_MSG a = &m.u.GetConsoleInput;
  44. //
  45. // If it's not a well formed handle, don't bother going to the server.
  46. //
  47. if (!CONSOLE_HANDLE(hConsoleInput)) {
  48. try {
  49. *lpNumberOfEventsRead = 0;
  50. SET_LAST_ERROR(ERROR_INVALID_HANDLE);
  51. } except( EXCEPTION_EXECUTE_HANDLER ) {
  52. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  53. }
  54. return FALSE;
  55. }
  56. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  57. a->InputHandle = hConsoleInput;
  58. a->NumRecords = nLength;
  59. a->Flags = wFlags;
  60. a->Unicode = Unicode;
  61. //
  62. // for speed in the case where we're only reading a few records, we have
  63. // a buffer in the msg we pass to the server. this means we don't have to
  64. // allocate a capture buffer.
  65. //
  66. if (nLength > INPUT_RECORD_BUFFER_SIZE) {
  67. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  68. nLength * sizeof(INPUT_RECORD)
  69. );
  70. if (CaptureBuffer == NULL) {
  71. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  72. return FALSE;
  73. }
  74. CsrCaptureMessageBuffer( CaptureBuffer,
  75. NULL,
  76. nLength * sizeof(INPUT_RECORD),
  77. (PVOID *) &a->BufPtr
  78. );
  79. } else {
  80. a->BufPtr = a->Record;
  81. CaptureBuffer = NULL;
  82. }
  83. CsrClientCallServer( (PCSR_API_MSG)&m,
  84. CaptureBuffer,
  85. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  86. ConsolepGetConsoleInput
  87. ),
  88. sizeof( *a )
  89. );
  90. try {
  91. if (NT_SUCCESS( m.ReturnValue )) {
  92. *lpNumberOfEventsRead = a->NumRecords;
  93. RtlCopyMemory(lpBuffer, a->BufPtr, a->NumRecords * sizeof(INPUT_RECORD));
  94. }
  95. else {
  96. *lpNumberOfEventsRead = 0;
  97. SET_LAST_NT_ERROR(m.ReturnValue);
  98. }
  99. } except( EXCEPTION_EXECUTE_HANDLER ) {
  100. if (CaptureBuffer != NULL) {
  101. CsrFreeCaptureBuffer( CaptureBuffer );
  102. }
  103. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  104. return FALSE;
  105. }
  106. if (CaptureBuffer != NULL) {
  107. CsrFreeCaptureBuffer( CaptureBuffer );
  108. }
  109. return NT_SUCCESS(m.ReturnValue);
  110. }
  111. #endif //!defined(BUILD_WOW6432)
  112. #if !defined(BUILD_WOW64)
  113. BOOL
  114. APIENTRY
  115. PeekConsoleInputA(
  116. HANDLE hConsoleInput,
  117. PINPUT_RECORD lpBuffer,
  118. DWORD nLength,
  119. LPDWORD lpNumberOfEventsRead
  120. )
  121. {
  122. return GetConsoleInput(hConsoleInput,
  123. lpBuffer,
  124. nLength,
  125. lpNumberOfEventsRead,
  126. CONSOLE_READ_NOREMOVE | CONSOLE_READ_NOWAIT,
  127. FALSE);
  128. }
  129. BOOL
  130. APIENTRY
  131. PeekConsoleInputW(
  132. HANDLE hConsoleInput,
  133. PINPUT_RECORD lpBuffer,
  134. DWORD nLength,
  135. LPDWORD lpNumberOfEventsRead
  136. )
  137. /*++
  138. Parameters:
  139. hConsoleInput - Supplies an open handle to CONIN$ that is to be
  140. read. The handle must have been created with GENERIC_READ access.
  141. lpBuffer - Supplies the address of a buffer to receive the data read
  142. from the input buffer.
  143. nLength - Supplies the length of lpBuffer in INPUT_RECORDs.
  144. lpNumberOfEventsRead - Pointer to number of events read.
  145. Return Value:
  146. TRUE - The operation was successful.
  147. FALSE/NULL - The operation failed.
  148. Extended error status is available using GetLastError.
  149. --*/
  150. {
  151. return GetConsoleInput(hConsoleInput,
  152. lpBuffer,
  153. nLength,
  154. lpNumberOfEventsRead,
  155. CONSOLE_READ_NOREMOVE | CONSOLE_READ_NOWAIT,
  156. TRUE);
  157. }
  158. BOOL
  159. APIENTRY
  160. ReadConsoleInputA(
  161. HANDLE hConsoleInput,
  162. PINPUT_RECORD lpBuffer,
  163. DWORD nLength,
  164. LPDWORD lpNumberOfEventsRead
  165. )
  166. {
  167. return GetConsoleInput(hConsoleInput,
  168. lpBuffer,
  169. nLength,
  170. lpNumberOfEventsRead,
  171. 0,
  172. FALSE);
  173. }
  174. BOOL
  175. APIENTRY
  176. ReadConsoleInputW(
  177. HANDLE hConsoleInput,
  178. PINPUT_RECORD lpBuffer,
  179. DWORD nLength,
  180. LPDWORD lpNumberOfEventsRead
  181. )
  182. /*++
  183. Parameters:
  184. hConsoleInput - Supplies an open handle to CONIN$ that is to be
  185. read. The handle must have been created with GENERIC_READ access.
  186. lpBuffer - Supplies the address of a buffer to receive the data read
  187. from the input buffer.
  188. nLength - Supplies the length of lpBuffer in INPUT_RECORDs.
  189. lpNumberOfEventsRead - Pointer to number of events read.
  190. Return Value:
  191. TRUE - The operation was successful.
  192. FALSE/NULL - The operation failed.
  193. Extended error status is available using GetLastError.
  194. --*/
  195. {
  196. return GetConsoleInput(hConsoleInput,
  197. lpBuffer,
  198. nLength,
  199. lpNumberOfEventsRead,
  200. 0,
  201. TRUE);
  202. }
  203. BOOL
  204. APIENTRY
  205. ReadConsoleInputExA(
  206. HANDLE hConsoleInput,
  207. PINPUT_RECORD lpBuffer,
  208. DWORD nLength,
  209. LPDWORD lpNumberOfEventsRead,
  210. USHORT wFlags
  211. )
  212. {
  213. return GetConsoleInput(hConsoleInput,
  214. lpBuffer,
  215. nLength,
  216. lpNumberOfEventsRead,
  217. wFlags,
  218. FALSE);
  219. }
  220. BOOL
  221. APIENTRY
  222. ReadConsoleInputExW(
  223. HANDLE hConsoleInput,
  224. PINPUT_RECORD lpBuffer,
  225. DWORD nLength,
  226. LPDWORD lpNumberOfEventsRead,
  227. USHORT wFlags
  228. )
  229. /*++
  230. Parameters:
  231. hConsoleInput - Supplies an open handle to CONIN$ that is to be
  232. read. The handle must have been created with GENERIC_READ access.
  233. lpBuffer - Supplies the address of a buffer to receive the data read
  234. from the input buffer.
  235. nLength - Supplies the length of lpBuffer in INPUT_RECORDs.
  236. lpNumberOfEventsRead - Pointer to number of events read.
  237. wFlags - Flags that control how data is read.
  238. Return Value:
  239. TRUE - The operation was successful.
  240. FALSE/NULL - The operation failed.
  241. Extended error status is available using GetLastError.
  242. --*/
  243. {
  244. return GetConsoleInput(hConsoleInput,
  245. lpBuffer,
  246. nLength,
  247. lpNumberOfEventsRead,
  248. wFlags,
  249. TRUE);
  250. }
  251. #endif //!defined(BUILD_WOW64)
  252. #if !defined(BUILD_WOW6432)
  253. BOOL
  254. APIENTRY
  255. WriteConsoleInputInternal(
  256. IN HANDLE hConsoleInput,
  257. IN CONST INPUT_RECORD *lpBuffer,
  258. IN DWORD nLength,
  259. OUT LPDWORD lpNumberOfEventsWritten,
  260. IN BOOLEAN Unicode,
  261. IN BOOLEAN Append
  262. )
  263. /*++
  264. Parameters:
  265. hConsoleInput - Supplies an open handle to CONIN$ that is to be
  266. written. The handle must have been created with GENERIC_WRITE access.
  267. lpBuffer - Supplies the address of a buffer containing the input records
  268. to write to the input buffer.
  269. nLength - Supplies the length of lpBuffer in INPUT_RECORDs.
  270. lpNumberOfEventsWritten - Pointer to number of events written.
  271. Unicode - TRUE if characters are unicode
  272. Append - TRUE if append to end of input stream. if FALSE, write to the
  273. beginning of the input stream (used by VDM).
  274. Return Value:
  275. TRUE - The operation was successful.
  276. FALSE/NULL - The operation failed.
  277. Extended error status is available using GetLastError.
  278. --*/
  279. {
  280. PCSR_CAPTURE_HEADER CaptureBuffer;
  281. CONSOLE_API_MSG m;
  282. PCONSOLE_WRITECONSOLEINPUT_MSG a = &m.u.WriteConsoleInput;
  283. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  284. a->InputHandle = hConsoleInput;
  285. a->NumRecords = nLength;
  286. a->Unicode = Unicode;
  287. a->Append = Append;
  288. //
  289. // for speed in the case where we're only writing a few records, we have
  290. // a buffer in the msg we pass to the server. this means we don't have to
  291. // allocate a capture buffer.
  292. //
  293. if (nLength > INPUT_RECORD_BUFFER_SIZE) {
  294. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  295. nLength * sizeof(INPUT_RECORD)
  296. );
  297. if (CaptureBuffer == NULL) {
  298. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  299. return FALSE;
  300. }
  301. CsrCaptureMessageBuffer( CaptureBuffer,
  302. (PCHAR) lpBuffer,
  303. nLength * sizeof(INPUT_RECORD),
  304. (PVOID *) &a->BufPtr
  305. );
  306. } else {
  307. a->BufPtr = a->Record;
  308. CaptureBuffer = NULL;
  309. try {
  310. RtlCopyMemory(a->BufPtr, lpBuffer, nLength * sizeof(INPUT_RECORD));
  311. } except( EXCEPTION_EXECUTE_HANDLER ) {
  312. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  313. return FALSE;
  314. }
  315. }
  316. CsrClientCallServer( (PCSR_API_MSG)&m,
  317. CaptureBuffer,
  318. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  319. ConsolepWriteConsoleInput
  320. ),
  321. sizeof( *a )
  322. );
  323. if (CaptureBuffer != NULL) {
  324. CsrFreeCaptureBuffer( CaptureBuffer );
  325. }
  326. try {
  327. *lpNumberOfEventsWritten = a->NumRecords;
  328. } except( EXCEPTION_EXECUTE_HANDLER ) {
  329. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  330. return FALSE;
  331. }
  332. if (!NT_SUCCESS(m.ReturnValue)) {
  333. SET_LAST_NT_ERROR(m.ReturnValue);
  334. return FALSE;
  335. }
  336. else {
  337. return TRUE;
  338. }
  339. }
  340. #endif //!defined(BUILD_WOW6432)
  341. #if !defined(BUILD_WOW64)
  342. BOOL
  343. APIENTRY
  344. WriteConsoleInputA(
  345. HANDLE hConsoleInput,
  346. CONST INPUT_RECORD *lpBuffer,
  347. DWORD nLength,
  348. LPDWORD lpNumberOfEventsWritten
  349. )
  350. {
  351. return WriteConsoleInputInternal(hConsoleInput,lpBuffer,nLength,lpNumberOfEventsWritten,FALSE,TRUE);
  352. }
  353. BOOL
  354. APIENTRY
  355. WriteConsoleInputW(
  356. HANDLE hConsoleInput,
  357. CONST INPUT_RECORD *lpBuffer,
  358. DWORD nLength,
  359. LPDWORD lpNumberOfEventsWritten
  360. )
  361. {
  362. return WriteConsoleInputInternal(hConsoleInput,lpBuffer,nLength,lpNumberOfEventsWritten,TRUE,TRUE);
  363. }
  364. #endif //!defined(BUILD_WOW64)
  365. #if !defined(BUILD_WOW6432)
  366. VOID
  367. CopyRectangle(
  368. IN CONST CHAR_INFO *Source,
  369. IN COORD SourceSize,
  370. IN PSMALL_RECT SourceRect,
  371. OUT PCHAR_INFO Target,
  372. IN COORD TargetSize,
  373. IN COORD TargetPoint
  374. )
  375. /*++
  376. Routine Description:
  377. This routine copies a rectangular region, doing any necessary clipping.
  378. Arguments:
  379. Source - pointer to source buffer
  380. SourceSize - dimensions of source buffer
  381. SourceRect - rectangle in source buffer to copy
  382. Target - pointer to target buffer
  383. TargetSize - dimensions of target buffer
  384. TargetPoint - upper left coordinates of target rectangle
  385. Return Value:
  386. --*/
  387. {
  388. #define SCREEN_BUFFER_POINTER(BASE,X,Y,XSIZE,CELLSIZE) ((ULONG_PTR)BASE + ((XSIZE * (Y)) + (X)) * (ULONG)CELLSIZE)
  389. CONST CHAR_INFO *SourcePtr;
  390. PCHAR_INFO TargetPtr;
  391. SHORT i,j;
  392. SHORT XSize,YSize;
  393. BOOLEAN WholeSource,WholeTarget;
  394. XSize = (SHORT)CONSOLE_RECT_SIZE_X(SourceRect);
  395. YSize = (SHORT)CONSOLE_RECT_SIZE_Y(SourceRect);
  396. // do clipping. we only clip for target, not source.
  397. if (XSize > (SHORT)(TargetSize.X - TargetPoint.X + 1)) {
  398. XSize = (SHORT)(TargetSize.X - TargetPoint.X + 1);
  399. }
  400. if (YSize > (SHORT)(TargetSize.Y - TargetPoint.Y + 1)) {
  401. YSize = (SHORT)(TargetSize.Y - TargetPoint.Y + 1);
  402. }
  403. WholeSource = WholeTarget = FALSE;
  404. if (XSize == SourceSize.X) {
  405. ASSERT (SourceRect->Left == 0);
  406. if (SourceRect->Top == 0) {
  407. SourcePtr = Source;
  408. }
  409. else {
  410. SourcePtr = (PCHAR_INFO) SCREEN_BUFFER_POINTER(Source,
  411. SourceRect->Left,
  412. SourceRect->Top,
  413. SourceSize.X,
  414. sizeof(CHAR_INFO));
  415. }
  416. WholeSource = TRUE;
  417. }
  418. if (XSize == TargetSize.X) {
  419. ASSERT (TargetPoint.X == 0);
  420. if (TargetPoint.Y == 0) {
  421. TargetPtr = Target;
  422. }
  423. else {
  424. TargetPtr = (PCHAR_INFO) SCREEN_BUFFER_POINTER(Target,
  425. TargetPoint.X,
  426. TargetPoint.Y,
  427. TargetSize.X,
  428. sizeof(CHAR_INFO));
  429. }
  430. WholeTarget = TRUE;
  431. }
  432. if (WholeSource && WholeTarget) {
  433. memmove(TargetPtr,SourcePtr,XSize*YSize*sizeof(CHAR_INFO));
  434. return;
  435. }
  436. for (i=0;i<YSize;i++) {
  437. if (!WholeTarget) {
  438. TargetPtr = (PCHAR_INFO) SCREEN_BUFFER_POINTER(Target,
  439. TargetPoint.X,
  440. TargetPoint.Y+i,
  441. TargetSize.X,
  442. sizeof(CHAR_INFO));
  443. }
  444. if (!WholeSource) {
  445. SourcePtr = (PCHAR_INFO) SCREEN_BUFFER_POINTER(Source,
  446. SourceRect->Left,
  447. SourceRect->Top+i,
  448. SourceSize.X,
  449. sizeof(CHAR_INFO));
  450. }
  451. for (j=0;j<XSize;j++,SourcePtr++,TargetPtr++) {
  452. *TargetPtr = *SourcePtr;
  453. }
  454. }
  455. }
  456. BOOL
  457. APIENTRY
  458. ReadConsoleOutputInternal(
  459. IN HANDLE hConsoleOutput,
  460. OUT PCHAR_INFO lpBuffer,
  461. IN COORD dwBufferSize,
  462. IN COORD dwBufferCoord,
  463. IN OUT PSMALL_RECT lpReadRegion,
  464. IN BOOLEAN Unicode
  465. )
  466. /*++
  467. Parameters:
  468. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  469. that is to be read. The handle must have been created with
  470. GENERIC_READ access.
  471. lpBuffer - Supplies the address of a buffer to receive the data read
  472. from the screen buffer. This pointer is treated as the origin of
  473. a two dimensional array of size dwBufferSize.
  474. dwBufferSize - size of lpBuffer
  475. dwBufferCoord - coordinates of upper left point in buffer to receive
  476. read data.
  477. lpReadRegion - Supplies on input the address of a structure indicating the
  478. rectangle within the screen buffer to read from. The fields in
  479. the structure are column and row coordinates. On output, the fields
  480. contain the actual region read.
  481. Return Value:
  482. TRUE - The operation was successful.
  483. FALSE/NULL - The operation failed. Extended error status is available
  484. using GetLastError.
  485. --*/
  486. {
  487. PCSR_CAPTURE_HEADER CaptureBuffer;
  488. CONSOLE_API_MSG m;
  489. PCONSOLE_READCONSOLEOUTPUT_MSG a = &m.u.ReadConsoleOutput;
  490. ULONG NumChars;
  491. COORD SourceSize;
  492. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  493. a->OutputHandle = hConsoleOutput;
  494. a->Unicode = Unicode;
  495. //
  496. // clip region to read based on caller's buffer size
  497. //
  498. SourceSize.X = (SHORT)CONSOLE_RECT_SIZE_X(lpReadRegion);
  499. if (SourceSize.X > dwBufferSize.X-dwBufferCoord.X)
  500. SourceSize.X = dwBufferSize.X-dwBufferCoord.X;
  501. SourceSize.Y = (SHORT)CONSOLE_RECT_SIZE_Y(lpReadRegion);
  502. if (SourceSize.Y > dwBufferSize.Y-dwBufferCoord.Y)
  503. SourceSize.Y = dwBufferSize.Y-dwBufferCoord.Y;
  504. a->CharRegion.Left = lpReadRegion->Left;
  505. a->CharRegion.Right = (SHORT)(lpReadRegion->Left + SourceSize.X - 1);
  506. a->CharRegion.Top = lpReadRegion->Top;
  507. a->CharRegion.Bottom = (SHORT)(lpReadRegion->Top + SourceSize.Y - 1);
  508. //
  509. // for speed in the case where we're only reading one character, we have
  510. // a buffer in the msg we pass to the server. this means we don't have to
  511. // allocate a capture buffer.
  512. //
  513. NumChars = SourceSize.X * SourceSize.Y;
  514. if (NumChars > 1) {
  515. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  516. NumChars * sizeof(CHAR_INFO)
  517. );
  518. if (CaptureBuffer == NULL) {
  519. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  520. return FALSE;
  521. }
  522. CsrCaptureMessageBuffer( CaptureBuffer,
  523. NULL,
  524. NumChars * sizeof(CHAR_INFO),
  525. (PVOID *) &a->BufPtr
  526. );
  527. }
  528. else {
  529. CaptureBuffer = NULL;
  530. a->BufPtr = &a->Char;
  531. }
  532. CsrClientCallServer( (PCSR_API_MSG)&m,
  533. CaptureBuffer,
  534. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  535. ConsolepReadConsoleOutput
  536. ),
  537. sizeof( *a )
  538. );
  539. if (NT_SUCCESS( m.ReturnValue )) {
  540. try {
  541. SMALL_RECT SourceRect;
  542. SourceRect.Left = a->CharRegion.Left - lpReadRegion->Left;
  543. SourceRect.Top = a->CharRegion.Top - lpReadRegion->Top;
  544. SourceRect.Right = SourceRect.Left +
  545. (a->CharRegion.Right - a->CharRegion.Left);
  546. SourceRect.Bottom = SourceRect.Top +
  547. (a->CharRegion.Bottom - a->CharRegion.Top);
  548. dwBufferCoord.X += SourceRect.Left;
  549. dwBufferCoord.Y += SourceRect.Top;
  550. CopyRectangle(a->BufPtr,
  551. SourceSize,
  552. &SourceRect,
  553. lpBuffer,
  554. dwBufferSize,
  555. dwBufferCoord
  556. );
  557. } except( EXCEPTION_EXECUTE_HANDLER ) {
  558. if (CaptureBuffer != NULL) {
  559. CsrFreeCaptureBuffer( CaptureBuffer );
  560. }
  561. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  562. return FALSE;
  563. }
  564. }
  565. if (CaptureBuffer != NULL) {
  566. CsrFreeCaptureBuffer( CaptureBuffer );
  567. }
  568. *lpReadRegion = a->CharRegion;
  569. if (!NT_SUCCESS(m.ReturnValue)) {
  570. SET_LAST_NT_ERROR(m.ReturnValue);
  571. return FALSE;
  572. }
  573. else {
  574. return TRUE;
  575. }
  576. }
  577. #endif //!defined(BUILD_WOW6432)
  578. #if !defined(BUILD_WOW64)
  579. BOOL
  580. APIENTRY
  581. ReadConsoleOutputW(
  582. HANDLE hConsoleOutput,
  583. PCHAR_INFO lpBuffer,
  584. COORD dwBufferSize,
  585. COORD dwBufferCoord,
  586. PSMALL_RECT lpReadRegion
  587. )
  588. {
  589. return ReadConsoleOutputInternal(hConsoleOutput,
  590. lpBuffer,
  591. dwBufferSize,
  592. dwBufferCoord,
  593. lpReadRegion,
  594. TRUE
  595. );
  596. }
  597. BOOL
  598. APIENTRY
  599. ReadConsoleOutputA(
  600. HANDLE hConsoleOutput,
  601. PCHAR_INFO lpBuffer,
  602. COORD dwBufferSize,
  603. COORD dwBufferCoord,
  604. PSMALL_RECT lpReadRegion
  605. )
  606. {
  607. return ReadConsoleOutputInternal(hConsoleOutput,
  608. lpBuffer,
  609. dwBufferSize,
  610. dwBufferCoord,
  611. lpReadRegion,
  612. FALSE
  613. );
  614. }
  615. #endif //!defined(BUILD_WOW64)
  616. #if !defined(BUILD_WOW6432)
  617. BOOL
  618. APIENTRY
  619. WriteConsoleOutputInternal(
  620. IN HANDLE hConsoleOutput,
  621. IN CONST CHAR_INFO *lpBuffer,
  622. IN COORD dwBufferSize,
  623. IN COORD dwBufferCoord,
  624. IN PSMALL_RECT lpWriteRegion,
  625. IN BOOLEAN Unicode
  626. )
  627. /*++
  628. Parameters:
  629. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  630. that is to be written. The handle must have been created with
  631. GENERIC_WRITE access.
  632. lpBuffer - Supplies the address of a buffer containing the data to write
  633. to the screen buffer. This buffer is treated as a two dimensional
  634. array.
  635. dwBufferSize - size of lpBuffer
  636. dwBufferCoord - coordinates of upper left point in buffer to write data
  637. from.
  638. lpWriteRegion - Supplies on input the address of a structure indicating the
  639. rectangle within the screen buffer to write to. The fields in
  640. the structure are column and row coordinates. On output, the fields
  641. contain the actual region written.
  642. Return Value:
  643. TRUE - The operation was successful.
  644. FALSE/NULL - The operation failed. Extended error status is available
  645. using GetLastError.
  646. --*/
  647. {
  648. PCSR_CAPTURE_HEADER CaptureBuffer;
  649. CONSOLE_API_MSG m;
  650. PCONSOLE_WRITECONSOLEOUTPUT_MSG a = &m.u.WriteConsoleOutput;
  651. ULONG NumChars;
  652. COORD SourceSize;
  653. COORD TargetPoint;
  654. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  655. a->OutputHandle = hConsoleOutput;
  656. a->Unicode = Unicode;
  657. //
  658. // clip region to write based on caller's buffer size
  659. //
  660. SourceSize.X = (SHORT)CONSOLE_RECT_SIZE_X(lpWriteRegion);
  661. if (SourceSize.X > dwBufferSize.X-dwBufferCoord.X)
  662. SourceSize.X = dwBufferSize.X-dwBufferCoord.X;
  663. SourceSize.Y = (SHORT)CONSOLE_RECT_SIZE_Y(lpWriteRegion);
  664. if (SourceSize.Y > dwBufferSize.Y-dwBufferCoord.Y)
  665. SourceSize.Y = dwBufferSize.Y-dwBufferCoord.Y;
  666. if (SourceSize.X <= 0 ||
  667. SourceSize.Y <= 0) {
  668. SET_LAST_ERROR(ERROR_INVALID_PARAMETER);
  669. return FALSE;
  670. }
  671. a->CharRegion.Left = lpWriteRegion->Left;
  672. a->CharRegion.Right = (SHORT)(lpWriteRegion->Left + SourceSize.X - 1);
  673. a->CharRegion.Top = lpWriteRegion->Top;
  674. a->CharRegion.Bottom = (SHORT)(lpWriteRegion->Top + SourceSize.Y - 1);
  675. //
  676. // for speed in the case where we're only writing one character, we have
  677. // a buffer in the msg we pass to the server. this means we don't have to
  678. // allocate a capture buffer.
  679. //
  680. NumChars = SourceSize.X * SourceSize.Y;
  681. if (NumChars > 1) {
  682. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  683. NumChars * sizeof(CHAR_INFO)
  684. );
  685. if (CaptureBuffer == NULL) {
  686. a->ReadVM=TRUE;
  687. a->BufPtr = RtlAllocateHeap( RtlProcessHeap(), 0, NumChars * sizeof(CHAR_INFO));
  688. if (a->BufPtr == NULL) {
  689. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  690. return FALSE;
  691. }
  692. } else {
  693. a->ReadVM=FALSE;
  694. CsrCaptureMessageBuffer( CaptureBuffer,
  695. NULL,
  696. NumChars * sizeof(CHAR_INFO),
  697. (PVOID *) &a->BufPtr
  698. );
  699. }
  700. }
  701. else {
  702. a->ReadVM=FALSE;
  703. CaptureBuffer = NULL;
  704. a->BufPtr = &a->Char;
  705. }
  706. try {
  707. SMALL_RECT SourceRect;
  708. SourceRect.Left = dwBufferCoord.X;
  709. SourceRect.Top = dwBufferCoord.Y;
  710. SourceRect.Right = (SHORT)(dwBufferCoord.X+SourceSize.X-1);
  711. SourceRect.Bottom = (SHORT)(dwBufferCoord.Y+SourceSize.Y-1);
  712. TargetPoint.X = 0;
  713. TargetPoint.Y = 0;
  714. CopyRectangle(lpBuffer,
  715. dwBufferSize,
  716. &SourceRect,
  717. a->BufPtr,
  718. SourceSize,
  719. TargetPoint
  720. );
  721. } except( EXCEPTION_EXECUTE_HANDLER ) {
  722. if (CaptureBuffer != NULL) {
  723. CsrFreeCaptureBuffer( CaptureBuffer );
  724. } else if (a->ReadVM) {
  725. // a->BufPtr was allocated with RtlAllocateHeap.
  726. RtlFreeHeap( RtlProcessHeap(), 0, a->BufPtr);
  727. }
  728. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  729. return FALSE;
  730. }
  731. CsrClientCallServer( (PCSR_API_MSG)&m,
  732. CaptureBuffer,
  733. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  734. ConsolepWriteConsoleOutput
  735. ),
  736. sizeof( *a )
  737. );
  738. if (CaptureBuffer != NULL) {
  739. CsrFreeCaptureBuffer( CaptureBuffer );
  740. } else if (a->ReadVM) {
  741. // a->BufPtr was allocated with RtlAllocateHeap.
  742. RtlFreeHeap(RtlProcessHeap(),0,a->BufPtr);
  743. }
  744. *lpWriteRegion = a->CharRegion;
  745. if (!NT_SUCCESS(m.ReturnValue)) {
  746. SET_LAST_NT_ERROR(m.ReturnValue);
  747. return FALSE;
  748. }
  749. else {
  750. return TRUE;
  751. }
  752. }
  753. #endif //!defined(BUILD_WOW6432)
  754. #if !defined(BUILD_WOW64)
  755. BOOL
  756. APIENTRY
  757. WriteConsoleOutputW(
  758. HANDLE hConsoleOutput,
  759. CONST CHAR_INFO *lpBuffer,
  760. COORD dwBufferSize,
  761. COORD dwBufferCoord,
  762. PSMALL_RECT lpWriteRegion
  763. )
  764. {
  765. return WriteConsoleOutputInternal(hConsoleOutput,
  766. lpBuffer,
  767. dwBufferSize,
  768. dwBufferCoord,
  769. lpWriteRegion,
  770. TRUE
  771. );
  772. }
  773. BOOL
  774. APIENTRY
  775. WriteConsoleOutputA(
  776. HANDLE hConsoleOutput,
  777. CONST CHAR_INFO *lpBuffer,
  778. COORD dwBufferSize,
  779. COORD dwBufferCoord,
  780. PSMALL_RECT lpWriteRegion
  781. )
  782. {
  783. return WriteConsoleOutputInternal(hConsoleOutput,
  784. lpBuffer,
  785. dwBufferSize,
  786. dwBufferCoord,
  787. lpWriteRegion,
  788. FALSE
  789. );
  790. }
  791. #endif //defined(BUILD_WOW64)
  792. #if !defined(BUILD_WOW6432)
  793. BOOL
  794. APIENTRY
  795. ReadConsoleOutputString(
  796. IN HANDLE hConsoleOutput,
  797. OUT LPVOID lpString,
  798. IN DWORD nLength,
  799. IN DWORD nSize,
  800. IN DWORD fFlags,
  801. IN COORD dwReadCoord,
  802. OUT LPDWORD lpNumberOfElementsRead
  803. )
  804. /*++
  805. Parameters:
  806. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  807. that is to be read. The handle must have been created with
  808. GENERIC_READ access.
  809. lpString - Supplies the address of a buffer to receive the character
  810. or attribute string read from the screen buffer.
  811. nLength - Size of lpCharacter buffer in elements.
  812. nSize - Size of element to read.
  813. fFlags - flag indicating what type of string to copy
  814. dwReadCoord - Screen buffer coordinates of string to read.
  815. read data.
  816. lpNumberOfElementsRead - Pointer to number of events read.
  817. Return Value:
  818. TRUE - The operation was successful.
  819. FALSE/NULL - The operation failed.
  820. Extended error status is available using GetLastError.
  821. --*/
  822. {
  823. PCSR_CAPTURE_HEADER CaptureBuffer;
  824. CONSOLE_API_MSG m;
  825. PCONSOLE_READCONSOLEOUTPUTSTRING_MSG a = &m.u.ReadConsoleOutputString;
  826. ULONG DataLength;
  827. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  828. a->OutputHandle = hConsoleOutput;
  829. a->NumRecords = nLength;
  830. a->StringType = fFlags;
  831. a->ReadCoord = dwReadCoord;
  832. DataLength = nLength*nSize;
  833. //
  834. // for speed in the case where the string is small, we have a buffer
  835. // in the msg we pass to the server. this means we don't have to
  836. // allocate a capture buffer.
  837. //
  838. if (DataLength > sizeof(a->String)) {
  839. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  840. DataLength
  841. );
  842. if (CaptureBuffer == NULL) {
  843. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  844. return FALSE;
  845. }
  846. CsrCaptureMessageBuffer( CaptureBuffer,
  847. NULL,
  848. DataLength,
  849. (PVOID *) &a->BufPtr
  850. );
  851. }
  852. else {
  853. a->BufPtr = a->String;
  854. CaptureBuffer = NULL;
  855. }
  856. CsrClientCallServer( (PCSR_API_MSG)&m,
  857. CaptureBuffer,
  858. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  859. ConsolepReadConsoleOutputString
  860. ),
  861. sizeof( *a )
  862. );
  863. try {
  864. *lpNumberOfElementsRead = a->NumRecords;
  865. if (NT_SUCCESS( m.ReturnValue )) {
  866. RtlCopyMemory(lpString, a->BufPtr, a->NumRecords * nSize);
  867. }
  868. else {
  869. SET_LAST_NT_ERROR(m.ReturnValue);
  870. }
  871. } except( EXCEPTION_EXECUTE_HANDLER ) {
  872. if (CaptureBuffer != NULL) {
  873. CsrFreeCaptureBuffer( CaptureBuffer );
  874. }
  875. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  876. return FALSE;
  877. }
  878. if (CaptureBuffer != NULL) {
  879. CsrFreeCaptureBuffer( CaptureBuffer );
  880. }
  881. return NT_SUCCESS(m.ReturnValue);
  882. }
  883. #endif //!defined(BUILD_WOW6432)
  884. #if !defined(BUILD_WOW64)
  885. BOOL
  886. APIENTRY
  887. ReadConsoleOutputCharacterA(
  888. HANDLE hConsoleOutput,
  889. LPSTR lpCharacter,
  890. DWORD nLength,
  891. COORD dwReadCoord,
  892. LPDWORD lpNumberOfCharsRead
  893. )
  894. /*++
  895. Parameters:
  896. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  897. that is to be read. The handle must have been created with
  898. GENERIC_READ access.
  899. lpCharacter - Supplies the address of a buffer to receive the character
  900. string read from the screen buffer.
  901. nLength - Size of lpCharacter buffer in characters.
  902. dwReadCoord - Screen buffer coordinates of string to read.
  903. read data.
  904. lpNumberOfCharsRead - Pointer to number of chars read.
  905. Return Value:
  906. TRUE - The operation was successful.
  907. FALSE/NULL - The operation failed.
  908. Extended error status is available using GetLastError.
  909. --*/
  910. {
  911. return ReadConsoleOutputString(hConsoleOutput,
  912. lpCharacter,
  913. nLength,
  914. sizeof(CHAR),
  915. CONSOLE_ASCII,
  916. dwReadCoord,
  917. lpNumberOfCharsRead
  918. );
  919. }
  920. BOOL
  921. APIENTRY
  922. ReadConsoleOutputCharacterW(
  923. HANDLE hConsoleOutput,
  924. LPWSTR lpCharacter,
  925. DWORD nLength,
  926. COORD dwReadCoord,
  927. LPDWORD lpNumberOfCharsRead
  928. )
  929. {
  930. return ReadConsoleOutputString(hConsoleOutput,
  931. lpCharacter,
  932. nLength,
  933. sizeof(WCHAR),
  934. CONSOLE_REAL_UNICODE,
  935. dwReadCoord,
  936. lpNumberOfCharsRead
  937. );
  938. }
  939. BOOL
  940. APIENTRY
  941. ReadConsoleOutputAttribute(
  942. HANDLE hConsoleOutput,
  943. LPWORD lpAttribute,
  944. DWORD nLength,
  945. COORD dwReadCoord,
  946. LPDWORD lpNumberOfAttrsRead
  947. )
  948. /*++
  949. Parameters:
  950. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  951. that is to be read. The handle must have been created with
  952. GENERIC_READ access.
  953. lpAttribute - Supplies the address of a buffer to receive the attribute
  954. string read from the screen buffer.
  955. nLength - Size of lpAttribute buffer in bytes.
  956. dwReadCoord - Screen buffer coordinates of string to read.
  957. read data.
  958. lpNumberOfAttrsRead - Pointer to number of attrs read.
  959. Return Value:
  960. TRUE - The operation was successful.
  961. FALSE/NULL - The operation failed.
  962. Extended error status is available using GetLastError.
  963. --*/
  964. {
  965. return ReadConsoleOutputString(hConsoleOutput,
  966. lpAttribute,
  967. nLength,
  968. sizeof(WORD),
  969. CONSOLE_ATTRIBUTE,
  970. dwReadCoord,
  971. lpNumberOfAttrsRead
  972. );
  973. }
  974. #endif //!defined(BUILD_WOW64)
  975. #if !defined(BUILD_WOW6432)
  976. BOOL
  977. APIENTRY
  978. WriteConsoleOutputString(
  979. IN HANDLE hConsoleOutput,
  980. IN CONST VOID *lpString,
  981. IN DWORD nLength,
  982. IN DWORD nSize,
  983. IN DWORD fFlags,
  984. IN COORD dwWriteCoord,
  985. OUT LPDWORD lpNumberOfElementsWritten
  986. )
  987. /*++
  988. Parameters:
  989. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  990. that is to be written. The handle must have been created with
  991. GENERIC_WRITE access.
  992. lpString - Supplies the address of a buffer containing the character
  993. or attribute string to write to the screen buffer.
  994. nLength - Length of string to write, in elements.
  995. nSize - Size of element to read.
  996. fFlags - flag indicating what type of string to copy
  997. dwWriteCoord - Screen buffer coordinates to write the string to.
  998. lpNumberOfElementsWritten - Pointer to number of elements written.
  999. Return Value:
  1000. TRUE - The operation was successful.
  1001. FALSE/NULL - The operation failed.
  1002. Extended error status is available using GetLastError.
  1003. --*/
  1004. {
  1005. PCSR_CAPTURE_HEADER CaptureBuffer;
  1006. CONSOLE_API_MSG m;
  1007. PCONSOLE_WRITECONSOLEOUTPUTSTRING_MSG a = &m.u.WriteConsoleOutputString;
  1008. ULONG DataLength;
  1009. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  1010. a->OutputHandle = hConsoleOutput;
  1011. a->NumRecords = nLength;
  1012. a->StringType = fFlags;
  1013. a->WriteCoord = dwWriteCoord;
  1014. //
  1015. // for speed in the case where the string is small, we have a buffer
  1016. // in the msg we pass to the server. this means we don't have to
  1017. // allocate a capture buffer.
  1018. //
  1019. DataLength = nLength*nSize;
  1020. if (DataLength > sizeof(a->String)) {
  1021. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  1022. DataLength
  1023. );
  1024. if (CaptureBuffer == NULL) {
  1025. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  1026. return FALSE;
  1027. }
  1028. CsrCaptureMessageBuffer( CaptureBuffer,
  1029. (PCHAR) lpString,
  1030. DataLength,
  1031. (PVOID *) &a->BufPtr
  1032. );
  1033. }
  1034. else {
  1035. a->BufPtr = a->String;
  1036. CaptureBuffer = NULL;
  1037. try {
  1038. RtlCopyMemory(a->BufPtr, lpString, DataLength);
  1039. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1040. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1041. return FALSE;
  1042. }
  1043. }
  1044. CsrClientCallServer( (PCSR_API_MSG)&m,
  1045. CaptureBuffer,
  1046. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  1047. ConsolepWriteConsoleOutputString
  1048. ),
  1049. sizeof( *a )
  1050. );
  1051. if (CaptureBuffer != NULL) {
  1052. CsrFreeCaptureBuffer( CaptureBuffer );
  1053. }
  1054. try {
  1055. *lpNumberOfElementsWritten = a->NumRecords;
  1056. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1057. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1058. return FALSE;
  1059. }
  1060. if (!NT_SUCCESS(m.ReturnValue)) {
  1061. SET_LAST_NT_ERROR(m.ReturnValue);
  1062. return FALSE;
  1063. }
  1064. else {
  1065. return TRUE;
  1066. }
  1067. }
  1068. #endif //!defined(BUILD_WOW6432)
  1069. #if !defined(BUILD_WOW64)
  1070. BOOL
  1071. APIENTRY
  1072. WriteConsoleOutputCharacterA(
  1073. HANDLE hConsoleOutput,
  1074. LPCSTR lpCharacter,
  1075. DWORD nLength,
  1076. COORD dwWriteCoord,
  1077. LPDWORD lpNumberOfCharsWritten
  1078. )
  1079. /*++
  1080. Parameters:
  1081. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1082. that is to be written. The handle must have been created with
  1083. GENERIC_WRITE access.
  1084. lpCharacter - Supplies the address of a buffer containing the character
  1085. string to write to the screen buffer.
  1086. nLength - Length of string to write, in characters.
  1087. dwWriteCoord - Screen buffer coordinates to write the string to.
  1088. lpNumberOfCharsWritten - Pointer to number of chars written.
  1089. Return Value:
  1090. TRUE - The operation was successful.
  1091. FALSE/NULL - The operation failed.
  1092. Extended error status is available using GetLastError.
  1093. --*/
  1094. {
  1095. return WriteConsoleOutputString(hConsoleOutput,
  1096. lpCharacter,
  1097. nLength,
  1098. sizeof(CHAR),
  1099. CONSOLE_ASCII,
  1100. dwWriteCoord,
  1101. lpNumberOfCharsWritten
  1102. );
  1103. }
  1104. BOOL
  1105. APIENTRY
  1106. WriteConsoleOutputCharacterW(
  1107. HANDLE hConsoleOutput,
  1108. LPCWSTR lpCharacter,
  1109. DWORD nLength,
  1110. COORD dwWriteCoord,
  1111. LPDWORD lpNumberOfCharsWritten
  1112. )
  1113. {
  1114. return WriteConsoleOutputString(hConsoleOutput,
  1115. lpCharacter,
  1116. nLength,
  1117. sizeof(WCHAR),
  1118. CONSOLE_REAL_UNICODE,
  1119. dwWriteCoord,
  1120. lpNumberOfCharsWritten
  1121. );
  1122. }
  1123. BOOL
  1124. APIENTRY
  1125. WriteConsoleOutputAttribute(
  1126. HANDLE hConsoleOutput,
  1127. CONST WORD *lpAttribute,
  1128. DWORD nLength,
  1129. COORD dwWriteCoord,
  1130. LPDWORD lpNumberOfAttrsWritten
  1131. )
  1132. /*++
  1133. Parameters:
  1134. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1135. that is to be written. The handle must have been created with
  1136. GENERIC_WRITE access.
  1137. lpAttribute - Supplies the address of a buffer containing the attribute
  1138. string to write to the screen buffer.
  1139. nLength - Length of string to write.
  1140. dwWriteCoord - Screen buffer coordinates to write the string to.
  1141. lpNumberOfAttrsWritten - Pointer to number of attrs written.
  1142. Return Value:
  1143. TRUE - The operation was successful.
  1144. FALSE/NULL - The operation failed.
  1145. Extended error status is available using GetLastError.
  1146. --*/
  1147. {
  1148. return WriteConsoleOutputString(hConsoleOutput,
  1149. lpAttribute,
  1150. nLength,
  1151. sizeof(WORD),
  1152. CONSOLE_ATTRIBUTE,
  1153. dwWriteCoord,
  1154. lpNumberOfAttrsWritten
  1155. );
  1156. }
  1157. #endif //!defined(BUILD_WOW64)
  1158. #if !defined(BUILD_WOW6432)
  1159. BOOL
  1160. APIENTRY
  1161. FillConsoleOutput(
  1162. IN HANDLE hConsoleOutput,
  1163. IN WORD Element,
  1164. IN DWORD nLength,
  1165. IN DWORD fFlags,
  1166. IN COORD dwWriteCoord,
  1167. OUT LPDWORD lpNumberOfElementsWritten
  1168. )
  1169. /*++
  1170. Parameters:
  1171. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1172. that is to be written. The handle must have been created with
  1173. GENERIC_WRITE access.
  1174. Element - The attribute or character to write.
  1175. nLength - Number of times to write the element.
  1176. fFlags - flag indicating what type of element to write.
  1177. dwWriteCoord - Screen buffer coordinates to write the element to.
  1178. lpNumberOfElementsWritten - Pointer to number of elements written.
  1179. Return Value:
  1180. TRUE - The operation was successful.
  1181. FALSE/NULL - The operation failed.
  1182. Extended error status is available using GetLastError.
  1183. --*/
  1184. {
  1185. CONSOLE_API_MSG m;
  1186. PCONSOLE_FILLCONSOLEOUTPUT_MSG a = &m.u.FillConsoleOutput;
  1187. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  1188. a->OutputHandle = hConsoleOutput;
  1189. a->Length = nLength;
  1190. a->ElementType = fFlags;
  1191. a->Element = Element;
  1192. a->WriteCoord = dwWriteCoord;
  1193. CsrClientCallServer( (PCSR_API_MSG)&m,
  1194. NULL,
  1195. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  1196. ConsolepFillConsoleOutput
  1197. ),
  1198. sizeof( *a )
  1199. );
  1200. try {
  1201. *lpNumberOfElementsWritten = a->Length;
  1202. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1203. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1204. return FALSE;
  1205. }
  1206. if (!NT_SUCCESS(m.ReturnValue)) {
  1207. SET_LAST_NT_ERROR(m.ReturnValue);
  1208. return FALSE;
  1209. }
  1210. else {
  1211. return TRUE;
  1212. }
  1213. }
  1214. #endif //!defined(BUILD_WOW6432)
  1215. #if !defined(BUILD_WOW64)
  1216. BOOL
  1217. APIENTRY
  1218. FillConsoleOutputCharacterA(
  1219. HANDLE hConsoleOutput,
  1220. CHAR cCharacter,
  1221. DWORD nLength,
  1222. COORD dwWriteCoord,
  1223. LPDWORD lpNumberOfCharsWritten
  1224. )
  1225. /*++
  1226. Parameters:
  1227. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1228. that is to be written. The handle must have been created with
  1229. GENERIC_WRITE access.
  1230. cCharacter - Supplies the ASCII character to write to the screen buffer.
  1231. nLength - Number of times to write the character.
  1232. dwWriteCoord - Screen buffer coordinates to begin writing the character
  1233. to.
  1234. lpNumberOfCharsWritten - Pointer to number of chars written.
  1235. Return Value:
  1236. TRUE - The operation was successful.
  1237. FALSE/NULL - The operation failed.
  1238. Extended error status is available using GetLastError.
  1239. --*/
  1240. {
  1241. return FillConsoleOutput(hConsoleOutput,
  1242. (USHORT) cCharacter,
  1243. nLength,
  1244. CONSOLE_ASCII,
  1245. dwWriteCoord,
  1246. lpNumberOfCharsWritten
  1247. );
  1248. }
  1249. BOOL
  1250. APIENTRY
  1251. FillConsoleOutputCharacterW(
  1252. HANDLE hConsoleOutput,
  1253. WCHAR cCharacter,
  1254. DWORD nLength,
  1255. COORD dwWriteCoord,
  1256. LPDWORD lpNumberOfCharsWritten
  1257. )
  1258. /*++
  1259. Parameters:
  1260. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1261. that is to be written. The handle must have been created with
  1262. GENERIC_WRITE access.
  1263. cCharacter - Supplies the ASCII character to write to the screen buffer.
  1264. nLength - Number of times to write the character.
  1265. dwWriteCoord - Screen buffer coordinates to begin writing the character
  1266. to.
  1267. lpNumberOfCharsWritten - Pointer to number of chars written.
  1268. Return Value:
  1269. TRUE - The operation was successful.
  1270. FALSE/NULL - The operation failed.
  1271. Extended error status is available using GetLastError.
  1272. --*/
  1273. {
  1274. return FillConsoleOutput(hConsoleOutput,
  1275. (USHORT) cCharacter,
  1276. nLength,
  1277. CONSOLE_REAL_UNICODE,
  1278. dwWriteCoord,
  1279. lpNumberOfCharsWritten
  1280. );
  1281. }
  1282. BOOL
  1283. APIENTRY
  1284. FillConsoleOutputAttribute(
  1285. HANDLE hConsoleOutput,
  1286. WORD wAttribute,
  1287. DWORD nLength,
  1288. COORD dwWriteCoord,
  1289. LPDWORD lpNumberOfAttrsWritten
  1290. )
  1291. /*++
  1292. Parameters:
  1293. hConsoleOutput - Supplies an open handle to the screen buffer (CONOUT$)
  1294. that is to be written. The handle must have been created with
  1295. GENERIC_WRITE access.
  1296. wAttribute - Supplies the attribute to write to the screen buffer.
  1297. nLength - Number of times to write the attribute.
  1298. dwWriteCoord - Screen buffer coordinates to begin writing the attribute
  1299. to.
  1300. lpNumberOfAttrsWritten - Pointer to number of attrs written.
  1301. Return Value:
  1302. TRUE - The operation was successful.
  1303. FALSE/NULL - The operation failed.
  1304. Extended error status is available using GetLastError.
  1305. --*/
  1306. {
  1307. return FillConsoleOutput(hConsoleOutput,
  1308. wAttribute,
  1309. nLength,
  1310. CONSOLE_ATTRIBUTE,
  1311. dwWriteCoord,
  1312. lpNumberOfAttrsWritten
  1313. );
  1314. }
  1315. #endif //!defined(BUILD_WOW64)
  1316. #if !defined(BUILD_WOW6432)
  1317. HANDLE
  1318. WINAPI
  1319. CreateConsoleScreenBuffer(
  1320. IN DWORD dwDesiredAccess,
  1321. IN DWORD dwShareMode,
  1322. IN CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
  1323. IN DWORD dwFlags,
  1324. IN PVOID lpScreenBufferData OPTIONAL
  1325. )
  1326. {
  1327. CONSOLE_API_MSG m;
  1328. PCONSOLE_CREATESCREENBUFFER_MSG a = &m.u.CreateConsoleScreenBuffer;
  1329. PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo;
  1330. PCSR_CAPTURE_HEADER CaptureBuffer=NULL;
  1331. if (dwDesiredAccess & ~VALID_ACCESSES ||
  1332. dwShareMode & ~VALID_SHARE_ACCESSES ||
  1333. (dwFlags != CONSOLE_TEXTMODE_BUFFER &&
  1334. dwFlags != CONSOLE_GRAPHICS_BUFFER)) {
  1335. SET_LAST_ERROR(ERROR_INVALID_PARAMETER);
  1336. return INVALID_HANDLE_VALUE;
  1337. }
  1338. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  1339. a->DesiredAccess = dwDesiredAccess;
  1340. if (ARGUMENT_PRESENT(lpSecurityAttributes)) {
  1341. a->InheritHandle = lpSecurityAttributes->bInheritHandle;
  1342. }
  1343. else {
  1344. a->InheritHandle = FALSE;
  1345. }
  1346. a->ShareMode = dwShareMode;
  1347. a->Flags = dwFlags;
  1348. if (dwFlags == CONSOLE_GRAPHICS_BUFFER) {
  1349. if (a->InheritHandle || lpScreenBufferData == NULL) {
  1350. SET_LAST_ERROR(ERROR_INVALID_PARAMETER);
  1351. return INVALID_HANDLE_VALUE;
  1352. }
  1353. GraphicsBufferInfo = lpScreenBufferData;
  1354. try {
  1355. a->GraphicsBufferInfo = *GraphicsBufferInfo;
  1356. CaptureBuffer = CsrAllocateCaptureBuffer( 1,
  1357. a->GraphicsBufferInfo.dwBitMapInfoLength
  1358. );
  1359. if (CaptureBuffer == NULL) {
  1360. SET_LAST_ERROR(ERROR_NOT_ENOUGH_MEMORY);
  1361. return INVALID_HANDLE_VALUE;
  1362. }
  1363. CsrCaptureMessageBuffer( CaptureBuffer,
  1364. (PCHAR) GraphicsBufferInfo->lpBitMapInfo,
  1365. a->GraphicsBufferInfo.dwBitMapInfoLength,
  1366. (PVOID *) &a->GraphicsBufferInfo.lpBitMapInfo
  1367. );
  1368. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1369. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1370. return INVALID_HANDLE_VALUE;
  1371. }
  1372. }
  1373. CsrClientCallServer( (PCSR_API_MSG)&m,
  1374. CaptureBuffer,
  1375. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  1376. ConsolepCreateScreenBuffer
  1377. ),
  1378. sizeof( *a )
  1379. );
  1380. if (CaptureBuffer != NULL) {
  1381. CsrFreeCaptureBuffer( CaptureBuffer );
  1382. }
  1383. if (!NT_SUCCESS(m.ReturnValue)) {
  1384. SET_LAST_NT_ERROR(m.ReturnValue);
  1385. return INVALID_HANDLE_VALUE;
  1386. }
  1387. else {
  1388. if (dwFlags == CONSOLE_GRAPHICS_BUFFER) {
  1389. try {
  1390. GraphicsBufferInfo->hMutex = a->hMutex;
  1391. GraphicsBufferInfo->lpBitMap = a->lpBitmap;
  1392. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1393. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1394. return INVALID_HANDLE_VALUE;
  1395. }
  1396. }
  1397. return a->Handle;
  1398. }
  1399. }
  1400. BOOL
  1401. WINAPI
  1402. InvalidateConsoleDIBits(
  1403. IN HANDLE hConsoleOutput,
  1404. IN PSMALL_RECT lpRect
  1405. )
  1406. /*++
  1407. Parameters:
  1408. hConsoleHandle - Supplies a console input or output handle.
  1409. lpRect - the region that needs to be updated to the screen.
  1410. Return Value:
  1411. TRUE - The operation was successful.
  1412. FALSE/NULL - The operation failed. Extended error status is available
  1413. using GetLastError.
  1414. --*/
  1415. {
  1416. CONSOLE_API_MSG m;
  1417. PCONSOLE_INVALIDATERECT_MSG a = &m.u.InvalidateConsoleBitmapRect;
  1418. a->ConsoleHandle = GET_CONSOLE_HANDLE;
  1419. a->OutputHandle = hConsoleOutput;
  1420. try {
  1421. a->Rect = *lpRect;
  1422. } except( EXCEPTION_EXECUTE_HANDLER ) {
  1423. SET_LAST_ERROR(ERROR_INVALID_ACCESS);
  1424. return ERROR_INVALID_ACCESS;
  1425. }
  1426. CsrClientCallServer( (PCSR_API_MSG)&m,
  1427. NULL,
  1428. CSR_MAKE_API_NUMBER( CONSRV_SERVERDLL_INDEX,
  1429. ConsolepInvalidateBitmapRect
  1430. ),
  1431. sizeof( *a )
  1432. );
  1433. if (NT_SUCCESS( m.ReturnValue )) {
  1434. return TRUE;
  1435. } else {
  1436. SET_LAST_NT_ERROR (m.ReturnValue);
  1437. return FALSE;
  1438. }
  1439. }
  1440. #endif //!defined(BUILD_WOW6432)