- Returns TRUE in AttachConsole (like in Wine)
[reactos.git] / reactos / dll / win32 / kernel32 / misc / console.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/console.c
6 * PURPOSE: Win32 server console functions
7 * PROGRAMMER: James Tabor
8 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
9 * UPDATE HISTORY:
10 * 199901?? ?? Created
11 * 19990204 EA SetConsoleTitleA
12 * 19990306 EA Stubs
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 #include <k32.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22 extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
23 extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
24 extern RTL_CRITICAL_SECTION ConsoleLock;
25 extern BOOL ConsoleInitialized;
26 extern BOOL WINAPI IsDebuggerPresent(VOID);
27
28 /* GLOBALS *******************************************************************/
29
30 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
31 static ULONG NrCtrlHandlers = 0;
32 #define INPUTEXENAME_BUFLEN 256
33 static WCHAR InputExeName[INPUTEXENAME_BUFLEN] = L"";
34
35 /* Default Console Control Handler *******************************************/
36
37 BOOL
38 WINAPI
39 DefaultConsoleCtrlHandler(DWORD Event)
40 {
41 switch(Event)
42 {
43 case CTRL_C_EVENT:
44 DPRINT("Ctrl-C Event\n");
45 break;
46
47 case CTRL_BREAK_EVENT:
48 DPRINT("Ctrl-Break Event\n");
49 break;
50
51 case CTRL_SHUTDOWN_EVENT:
52 DPRINT("Ctrl Shutdown Event\n");
53 break;
54
55 case CTRL_CLOSE_EVENT:
56 DPRINT("Ctrl Close Event\n");
57 break;
58
59 case CTRL_LOGOFF_EVENT:
60 DPRINT("Ctrl Logoff Event\n");
61 break;
62 }
63
64 ExitProcess(0);
65 return TRUE;
66 }
67
68
69 __declspec(noreturn)
70 VOID
71 CALLBACK
72 ConsoleControlDispatcher(DWORD CodeAndFlag)
73 {
74 DWORD nExitCode = 0;
75 DWORD nCode = CodeAndFlag & MAXLONG;
76 UINT i;
77
78 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
79
80 switch(nCode)
81 {
82 case CTRL_C_EVENT:
83 case CTRL_BREAK_EVENT:
84 {
85 if(IsDebuggerPresent())
86 {
87 EXCEPTION_RECORD erException;
88 erException.ExceptionCode =
89 (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
90 erException.ExceptionFlags = 0;
91 erException.ExceptionRecord = NULL;
92 erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
93 erException.NumberParameters = 0;
94 RtlRaiseException(&erException);
95 }
96
97 if (!ConsoleInitialized) ExitThread(0);
98 RtlEnterCriticalSection(&ConsoleLock);
99
100 if (!(nCode == CTRL_C_EVENT &&
101 NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
102 {
103 for(i = NrCtrlHandlers; i > 0; -- i)
104 if(CtrlHandlers[i - 1](nCode)) break;
105 }
106 RtlLeaveCriticalSection(&ConsoleLock);
107 ExitThread(0);
108 }
109
110 case CTRL_CLOSE_EVENT:
111 case CTRL_LOGOFF_EVENT:
112 case CTRL_SHUTDOWN_EVENT:
113 break;
114
115 default: ExitThread(0);
116 }
117
118 if (!ConsoleInitialized) ExitThread(0);
119 RtlEnterCriticalSection(&ConsoleLock);
120
121 if (!(nCode == CTRL_C_EVENT &&
122 NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
123 {
124 i = NrCtrlHandlers;
125 while (i > 0)
126 {
127 if (i == 1 && (CodeAndFlag & MINLONG) &&
128 (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
129 break;
130
131 if (CtrlHandlers[i - 1](nCode))
132 {
133 switch(nCode)
134 {
135 case CTRL_CLOSE_EVENT:
136 case CTRL_LOGOFF_EVENT:
137 case CTRL_SHUTDOWN_EVENT:
138 nExitCode = CodeAndFlag;
139 }
140 break;
141 }
142 --i;
143 }
144 }
145 RtlLeaveCriticalSection(&ConsoleLock);
146 ExitThread(nExitCode);
147 }
148
149
150 /* FUNCTIONS *****************************************************************/
151
152 /*
153 * @implemented
154 */
155 BOOL
156 WINAPI
157 AddConsoleAliasA(LPCSTR lpSource,
158 LPCSTR lpTarget,
159 LPCSTR lpExeName)
160 {
161 LPWSTR lpSourceW = NULL;
162 LPWSTR lpTargetW = NULL;
163 LPWSTR lpExeNameW = NULL;
164 BOOL bRetVal;
165
166 if (lpSource)
167 BasepAnsiStringToHeapUnicodeString(lpSource, (LPWSTR*) &lpSourceW);
168 if (lpTarget)
169 BasepAnsiStringToHeapUnicodeString(lpTarget, (LPWSTR*) &lpTargetW);
170 if (lpExeName)
171 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
172
173 bRetVal = AddConsoleAliasW(lpSourceW, lpTargetW, lpExeNameW);
174
175 /* Clean up */
176 if (lpSourceW)
177 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpSourceW);
178 if (lpTargetW)
179 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpTargetW);
180 if (lpExeNameW)
181 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
182
183 return bRetVal;
184 }
185
186
187 /*
188 * @unimplemented
189 */
190 BOOL
191 WINAPI
192 AddConsoleAliasW(LPCWSTR lpSource,
193 LPCWSTR lpTarget,
194 LPCWSTR lpExeName)
195 {
196 PCSR_API_MESSAGE Request;
197 ULONG CsrRequest;
198 NTSTATUS Status;
199 ULONG SourceLength;
200 ULONG TargetLength = 0;
201 ULONG ExeLength;
202 ULONG Size;
203 ULONG RequestLength;
204 WCHAR * Ptr;
205
206 DPRINT("AddConsoleAliasW enterd with lpSource %S lpTarget %S lpExeName %S\n", lpSource, lpTarget, lpExeName);
207
208 ExeLength = wcslen(lpExeName) + 1;
209 SourceLength = wcslen(lpSource)+ 1;
210 if (lpTarget)
211 TargetLength = wcslen(lpTarget) + 1;
212
213 Size = (ExeLength + SourceLength + TargetLength) * sizeof(WCHAR);
214 RequestLength = sizeof(CSR_API_MESSAGE) + Size;
215
216 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RequestLength);
217 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE));
218
219 wcscpy(Ptr, lpSource);
220 Request->Data.AddConsoleAlias.SourceLength = SourceLength;
221 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + SourceLength * sizeof(WCHAR));
222
223 wcscpy(Ptr, lpExeName);
224 Request->Data.AddConsoleAlias.ExeLength = ExeLength;
225 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + (ExeLength + SourceLength)* sizeof(WCHAR));
226
227 if (lpTarget) /* target can be optional */
228 wcscpy(Ptr, lpTarget);
229
230 Request->Data.AddConsoleAlias.TargetLength = TargetLength;
231
232 CsrRequest = MAKE_CSR_API(ADD_CONSOLE_ALIAS, CSR_CONSOLE);
233 Status = CsrClientCallServer(Request,
234 NULL,
235 CsrRequest,
236 RequestLength);
237
238 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
239 {
240 SetLastErrorByStatus(Status);
241 RtlFreeHeap(GetProcessHeap(), 0, Request);
242 return FALSE;
243 }
244
245 RtlFreeHeap(GetProcessHeap(), 0, Request);
246 return TRUE;
247 }
248
249
250 /*
251 * @unimplemented (Undocumented)
252 */
253 BOOL
254 WINAPI
255 ConsoleMenuControl(HANDLE hConsole,
256 DWORD Unknown1,
257 DWORD Unknown2)
258 {
259 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
260 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
261 return FALSE;
262 }
263
264
265 /*
266 * @implemented
267 */
268 HANDLE
269 WINAPI
270 DuplicateConsoleHandle(HANDLE hConsole,
271 DWORD dwDesiredAccess,
272 BOOL bInheritHandle,
273 DWORD dwOptions)
274 {
275 CSR_API_MESSAGE Request;
276 ULONG CsrRequest;
277 NTSTATUS Status;
278
279 if (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
280 || (!(dwOptions & DUPLICATE_SAME_ACCESS)
281 && dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)))
282 {
283 SetLastError (ERROR_INVALID_PARAMETER);
284 return INVALID_HANDLE_VALUE;
285 }
286
287 CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
288 Request.Data.DuplicateHandleRequest.Handle = hConsole;
289 Request.Data.DuplicateHandleRequest.Access = dwDesiredAccess;
290 Request.Data.DuplicateHandleRequest.Inheritable = bInheritHandle;
291 Request.Data.DuplicateHandleRequest.Options = dwOptions;
292
293 Status = CsrClientCallServer(&Request,
294 NULL,
295 CsrRequest,
296 sizeof(CSR_API_MESSAGE));
297 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
298 {
299 SetLastErrorByStatus(Status);
300 return INVALID_HANDLE_VALUE;
301 }
302
303 return Request.Data.DuplicateHandleRequest.Handle;
304 }
305
306
307 /*
308 * @unimplemented (Undocumented)
309 */
310 DWORD
311 WINAPI
312 ExpungeConsoleCommandHistoryW(DWORD Unknown0)
313 {
314 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316 return 0;
317 }
318
319
320 /*
321 * @unimplemented (Undocumented)
322 */
323 DWORD
324 WINAPI
325 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
326 {
327 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
328 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
329 return 0;
330 }
331
332
333 /*
334 * @implemented
335 */
336 DWORD
337 WINAPI
338 GetConsoleAliasW(LPWSTR lpSource,
339 LPWSTR lpTargetBuffer,
340 DWORD TargetBufferLength,
341 LPWSTR lpExeName)
342 {
343 PCSR_API_MESSAGE Request;
344 PCSR_CAPTURE_BUFFER CaptureBuffer;
345 ULONG CsrRequest;
346 NTSTATUS Status;
347 ULONG Size;
348 ULONG ExeLength;
349 ULONG SourceLength;
350 ULONG RequestLength;
351 WCHAR * Ptr;
352
353 DPRINT("GetConsoleAliasW entered lpSource %S lpExeName %S\n", lpSource, lpExeName);
354
355 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIAS, CSR_CONSOLE);
356
357 ExeLength = wcslen(lpExeName) + 1;
358 SourceLength = wcslen(lpSource) + 1;
359
360 Size = (ExeLength + SourceLength) * sizeof(WCHAR);
361
362 RequestLength = Size + sizeof(CSR_API_MESSAGE);
363 Request = RtlAllocateHeap(GetProcessHeap(), 0, RequestLength);
364
365 CaptureBuffer = CsrAllocateCaptureBuffer(1, TargetBufferLength);
366 if (!CaptureBuffer)
367 {
368 RtlFreeHeap(GetProcessHeap(), 0, Request);
369 return 0;
370 }
371
372 Request->Data.GetConsoleAlias.TargetBuffer = NULL;
373
374 CsrCaptureMessageBuffer(CaptureBuffer,
375 NULL,
376 TargetBufferLength,
377 (PVOID*)&Request->Data.GetConsoleAlias.TargetBuffer);
378
379 Request->Data.GetConsoleAlias.TargetBufferLength = TargetBufferLength;
380
381 Ptr = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
382 wcscpy(Ptr, lpSource);
383 Ptr += SourceLength;
384 wcscpy(Ptr, lpExeName);
385
386 Request->Data.GetConsoleAlias.ExeLength = ExeLength;
387 Request->Data.GetConsoleAlias.SourceLength = SourceLength;
388
389 Status = CsrClientCallServer(Request,
390 CaptureBuffer,
391 CsrRequest,
392 sizeof(CSR_API_MESSAGE) + Size);
393
394 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
395 {
396 RtlFreeHeap(GetProcessHeap(), 0, Request);
397 CsrFreeCaptureBuffer(CaptureBuffer);
398 SetLastErrorByStatus(Status);
399 return 0;
400 }
401
402 wcscpy(lpTargetBuffer, Request->Data.GetConsoleAlias.TargetBuffer);
403 RtlFreeHeap(GetProcessHeap(), 0, Request);
404 CsrFreeCaptureBuffer(CaptureBuffer);
405
406 return Request->Data.GetConsoleAlias.BytesWritten;
407 }
408
409
410 /*
411 * @implemented
412 */
413 DWORD
414 WINAPI
415 GetConsoleAliasA(LPSTR lpSource,
416 LPSTR lpTargetBuffer,
417 DWORD TargetBufferLength,
418 LPSTR lpExeName)
419 {
420 LPWSTR lpwSource;
421 LPWSTR lpwExeName;
422 LPWSTR lpwTargetBuffer;
423 UINT dwSourceSize;
424 UINT dwExeNameSize;
425 UINT dwResult;
426
427 DPRINT("GetConsoleAliasA entered\n");
428
429 dwSourceSize = (strlen(lpSource)+1) * sizeof(WCHAR);
430 lpwSource = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceSize);
431 MultiByteToWideChar(CP_ACP, 0, lpSource, -1, lpwSource, dwSourceSize);
432
433 dwExeNameSize = (strlen(lpExeName)+1) * sizeof(WCHAR);
434 lpwExeName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwExeNameSize);
435 MultiByteToWideChar(CP_ACP, 0, lpExeName, -1, lpwExeName, dwExeNameSize);
436
437 lpwTargetBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, TargetBufferLength * sizeof(WCHAR));
438
439 dwResult = GetConsoleAliasW(lpwSource, lpwTargetBuffer, TargetBufferLength * sizeof(WCHAR), lpwExeName);
440
441 HeapFree(GetProcessHeap(), 0, lpwSource);
442 HeapFree(GetProcessHeap(), 0, lpwExeName);
443
444 if (dwResult)
445 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwTargetBuffer, dwResult / sizeof(WCHAR), lpTargetBuffer, TargetBufferLength, NULL, NULL);
446
447 HeapFree(GetProcessHeap(), 0, lpwTargetBuffer);
448
449 return dwResult;
450 }
451
452
453 /*
454 * @implemented
455 */
456 DWORD
457 WINAPI
458 GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
459 DWORD ExeNameBufferLength)
460 {
461 CSR_API_MESSAGE Request;
462 PCSR_CAPTURE_BUFFER CaptureBuffer;
463 ULONG CsrRequest;
464 NTSTATUS Status;
465
466 DPRINT("GetConsoleAliasExesW entered\n");
467
468 CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
469 if (!CaptureBuffer)
470 {
471 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
472 return 0;
473 }
474
475 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES, CSR_CONSOLE);
476 CsrAllocateMessagePointer(CaptureBuffer,
477 ExeNameBufferLength,
478 (PVOID*)&Request.Data.GetConsoleAliasesExes.ExeNames);
479 Request.Data.GetConsoleAliasesExes.Length = ExeNameBufferLength;
480
481 Status = CsrClientCallServer(&Request,
482 CaptureBuffer,
483 CsrRequest,
484 sizeof(CSR_API_MESSAGE));
485
486 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
487 {
488 SetLastErrorByStatus(Status);
489 CsrFreeCaptureBuffer(CaptureBuffer);
490 return 0;
491 }
492
493 memcpy(lpExeNameBuffer,
494 Request.Data.GetConsoleAliasesExes.ExeNames,
495 Request.Data.GetConsoleAliasesExes.BytesWritten);
496
497 CsrFreeCaptureBuffer(CaptureBuffer);
498 return Request.Data.GetConsoleAliasesExes.BytesWritten;
499 }
500
501
502 /*
503 * @implemented
504 */
505 DWORD
506 WINAPI
507 GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
508 DWORD ExeNameBufferLength)
509 {
510 LPWSTR lpwExeNameBuffer;
511 DWORD dwResult;
512
513 DPRINT("GetConsoleAliasExesA entered\n");
514
515 lpwExeNameBuffer = HeapAlloc(GetProcessHeap(), 0, ExeNameBufferLength * sizeof(WCHAR));
516
517 dwResult = GetConsoleAliasExesW(lpwExeNameBuffer, ExeNameBufferLength * sizeof(WCHAR));
518
519 if (dwResult)
520 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwExeNameBuffer, dwResult / sizeof(WCHAR), lpExeNameBuffer, ExeNameBufferLength, NULL, NULL);
521
522 HeapFree(GetProcessHeap(), 0, lpwExeNameBuffer);
523 return dwResult;
524 }
525
526 /*
527 * @implemented
528 */
529 DWORD
530 WINAPI
531 GetConsoleAliasExesLengthW(VOID)
532 {
533 CSR_API_MESSAGE Request;
534 ULONG CsrRequest;
535 NTSTATUS Status;
536
537 DPRINT("GetConsoleAliasExesLengthW entered\n");
538
539 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CSR_CONSOLE);
540 Request.Data.GetConsoleAliasesExesLength.Length = 0;
541
542
543 Status = CsrClientCallServer(&Request,
544 NULL,
545 CsrRequest,
546 sizeof(CSR_API_MESSAGE));
547
548 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
549 {
550 SetLastErrorByStatus(Status);
551 return 0;
552 }
553
554 return Request.Data.GetConsoleAliasesExesLength.Length;
555 }
556
557 /*
558 * @implemented
559 */
560 DWORD
561 WINAPI
562 GetConsoleAliasExesLengthA(VOID)
563 {
564 DWORD dwLength;
565
566 DPRINT("GetConsoleAliasExesLengthA entered\n");
567
568 dwLength = GetConsoleAliasExesLengthW();
569
570 if (dwLength)
571 dwLength /= sizeof(WCHAR);
572
573 return dwLength;
574 }
575
576
577 /*
578 * @implemented
579 */
580 DWORD
581 WINAPI
582 GetConsoleAliasesW(LPWSTR AliasBuffer,
583 DWORD AliasBufferLength,
584 LPWSTR ExeName)
585 {
586 CSR_API_MESSAGE Request;
587 ULONG CsrRequest;
588 NTSTATUS Status;
589 DWORD dwLength;
590
591 DPRINT("GetConsoleAliasesW entered\n");
592
593 dwLength = GetConsoleAliasesLengthW(ExeName);
594 if (!dwLength || dwLength > AliasBufferLength)
595 return 0;
596
597 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES, CSR_CONSOLE);
598 Request.Data.GetAllConsoleAlias.AliasBuffer = AliasBuffer;
599 Request.Data.GetAllConsoleAlias.AliasBufferLength = AliasBufferLength;
600 Request.Data.GetAllConsoleAlias.lpExeName = ExeName;
601
602 Status = CsrClientCallServer(&Request,
603 NULL,
604 CsrRequest,
605 sizeof(CSR_API_MESSAGE));
606
607 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
608 {
609 SetLastErrorByStatus(Status);
610 return 0;
611 }
612
613 return Request.Data.GetAllConsoleAlias.BytesWritten / sizeof(WCHAR);
614 }
615
616
617 /*
618 * @implemented
619 */
620 DWORD
621 WINAPI
622 GetConsoleAliasesA(LPSTR AliasBuffer,
623 DWORD AliasBufferLength,
624 LPSTR ExeName)
625 {
626 DWORD dwRetVal = 0;
627 LPWSTR lpwExeName = NULL;
628 LPWSTR lpwAliasBuffer;
629
630 DPRINT("GetConsoleAliasesA entered\n");
631
632 if (ExeName)
633 BasepAnsiStringToHeapUnicodeString(ExeName, (LPWSTR*) &lpwExeName);
634
635 lpwAliasBuffer = HeapAlloc(GetProcessHeap(), 0, AliasBufferLength * sizeof(WCHAR));
636
637 dwRetVal = GetConsoleAliasesW(lpwAliasBuffer, AliasBufferLength, lpwExeName);
638
639 if (lpwExeName)
640 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpwExeName);
641
642 if (dwRetVal)
643 dwRetVal = WideCharToMultiByte(CP_ACP, 0, lpwAliasBuffer, dwRetVal, AliasBuffer, AliasBufferLength, NULL, NULL);
644
645 HeapFree(GetProcessHeap(), 0, lpwAliasBuffer);
646 return dwRetVal;
647 }
648
649
650 /*
651 * @implemented
652 */
653 DWORD
654 WINAPI
655 GetConsoleAliasesLengthW(LPWSTR lpExeName)
656 {
657 CSR_API_MESSAGE Request;
658 ULONG CsrRequest;
659 NTSTATUS Status;
660
661 DPRINT("GetConsoleAliasesLengthW entered\n");
662
663 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CSR_CONSOLE);
664 Request.Data.GetAllConsoleAliasesLength.lpExeName = lpExeName;
665 Request.Data.GetAllConsoleAliasesLength.Length = 0;
666
667 Status = CsrClientCallServer(&Request,
668 NULL,
669 CsrRequest,
670 sizeof(CSR_API_MESSAGE));
671
672 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
673 {
674 SetLastErrorByStatus(Status);
675 return 0;
676 }
677
678 return Request.Data.GetAllConsoleAliasesLength.Length;
679 }
680
681
682 /*
683 * @implemented
684 */
685 DWORD
686 WINAPI
687 GetConsoleAliasesLengthA(LPSTR lpExeName)
688 {
689 DWORD dwRetVal = 0;
690 LPWSTR lpExeNameW = NULL;
691
692 if (lpExeName)
693 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
694
695 dwRetVal = GetConsoleAliasesLengthW(lpExeNameW);
696 if (dwRetVal)
697 dwRetVal /= sizeof(WCHAR);
698
699 /* Clean up */
700 if (lpExeNameW)
701 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
702
703 return dwRetVal;
704 }
705
706
707 /*
708 * @unimplemented (Undocumented)
709 */
710 DWORD
711 WINAPI
712 GetConsoleCommandHistoryW(DWORD Unknown0,
713 DWORD Unknown1,
714 DWORD Unknown2)
715 {
716 DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
717 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
718 return 0;
719 }
720
721
722 /*
723 * @unimplemented (Undocumented)
724 */
725 DWORD
726 WINAPI
727 GetConsoleCommandHistoryA(DWORD Unknown0,
728 DWORD Unknown1,
729 DWORD Unknown2)
730 {
731 DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
732 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
733 return 0;
734 }
735
736
737 /*
738 * @unimplemented (Undocumented)
739 */
740 DWORD
741 WINAPI
742 GetConsoleCommandHistoryLengthW(DWORD Unknown0)
743 {
744 DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
745 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
746 return 0;
747 }
748
749
750 /*
751 * @unimplemented (Undocumented)
752 */
753 DWORD
754 WINAPI
755 GetConsoleCommandHistoryLengthA(DWORD Unknown0)
756 {
757 DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
758 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
759 return 0;
760 }
761
762 /*
763 * @unimplemented
764 */
765 INT
766 WINAPI
767 GetConsoleDisplayMode(LPDWORD lpdwMode)
768 /*
769 * FUNCTION: Get the console display mode
770 * ARGUMENTS:
771 * lpdwMode - Address of variable that receives the current value
772 * of display mode
773 * STATUS: Undocumented
774 */
775 {
776 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
778 return 0;
779 }
780
781
782 /*
783 * @unimplemented (Undocumented)
784 */
785 DWORD
786 WINAPI
787 GetConsoleFontInfo(DWORD Unknown0,
788 DWORD Unknown1,
789 DWORD Unknown2,
790 DWORD Unknown3)
791 {
792 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
793 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
794 return 0;
795 }
796
797
798 /*
799 * @unimplemented
800 */
801 COORD
802 WINAPI
803 GetConsoleFontSize(HANDLE hConsoleOutput,
804 DWORD nFont)
805 {
806 COORD Empty = {0, 0};
807 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
808 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
809 return Empty;
810 }
811
812
813 /*
814 * @implemented (Undocumented)
815 */
816 DWORD
817 WINAPI
818 GetConsoleHardwareState(HANDLE hConsole,
819 DWORD Flags,
820 PDWORD State)
821 {
822 CSR_API_MESSAGE Request;
823 ULONG CsrRequest;
824 NTSTATUS Status;
825
826 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
827 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
828 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
829
830 Status = CsrClientCallServer(&Request,
831 NULL,
832 CsrRequest,
833 sizeof(CSR_API_MESSAGE));
834 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
835 {
836 SetLastErrorByStatus(Status);
837 return FALSE;
838 }
839
840 *State = Request.Data.ConsoleHardwareStateRequest.State;
841 return TRUE;
842 }
843
844
845 /*
846 * @implemented (Undocumented)
847 */
848 HANDLE
849 WINAPI
850 GetConsoleInputWaitHandle(VOID)
851 {
852 CSR_API_MESSAGE Request;
853 ULONG CsrRequest;
854 NTSTATUS Status;
855
856 CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
857
858 Status = CsrClientCallServer(&Request,
859 NULL,
860 CsrRequest,
861 sizeof(CSR_API_MESSAGE));
862 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
863 {
864 SetLastErrorByStatus(Status);
865 return 0;
866 }
867
868 return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
869 }
870
871
872 /*
873 * @unimplemented
874 */
875 INT
876 WINAPI
877 GetCurrentConsoleFont(HANDLE hConsoleOutput,
878 BOOL bMaximumWindow,
879 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
880 {
881 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
882 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
883 return 0;
884 }
885
886
887 /*
888 * @unimplemented (Undocumented)
889 */
890 ULONG
891 WINAPI
892 GetNumberOfConsoleFonts(VOID)
893 {
894 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
895 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
896 return 1; /* FIXME: call csrss.exe */
897 }
898
899
900 /*
901 * @unimplemented (Undocumented)
902 */
903 DWORD
904 WINAPI
905 InvalidateConsoleDIBits(DWORD Unknown0,
906 DWORD Unknown1)
907 {
908 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
909 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
910 return 0;
911 }
912
913
914 /*
915 * @unimplemented (Undocumented)
916 */
917 HANDLE
918 WINAPI
919 OpenConsoleW(LPCWSTR wsName,
920 DWORD dwDesiredAccess,
921 BOOL bInheritHandle,
922 DWORD dwShareMode)
923 {
924 CSR_API_MESSAGE Request;
925 ULONG CsrRequest;
926 NTSTATUS Status = STATUS_SUCCESS;
927
928 if (0 == _wcsicmp(wsName, L"CONIN$"))
929 {
930 CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
931 }
932 else if (0 == _wcsicmp(wsName, L"CONOUT$"))
933 {
934 CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
935 }
936 else
937 {
938 SetLastError(ERROR_INVALID_PARAMETER);
939 return(INVALID_HANDLE_VALUE);
940 }
941
942 if (dwDesiredAccess & ~(GENERIC_READ|GENERIC_WRITE))
943 {
944 SetLastError(ERROR_INVALID_PARAMETER);
945 return(INVALID_HANDLE_VALUE);
946 }
947
948 if (dwShareMode & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))
949 {
950 SetLastError(ERROR_INVALID_PARAMETER);
951 return(INVALID_HANDLE_VALUE);
952 }
953
954 /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
955 Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
956 Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
957
958 Status = CsrClientCallServer(&Request,
959 NULL,
960 CsrRequest,
961 sizeof(CSR_API_MESSAGE));
962 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
963 {
964 SetLastErrorByStatus(Status);
965 return INVALID_HANDLE_VALUE;
966 }
967
968 return Request.Data.GetInputHandleRequest.InputHandle;
969 }
970
971
972 /*
973 * @unimplemented (Undocumented)
974 */
975 BOOL
976 WINAPI
977 SetConsoleCommandHistoryMode(DWORD dwMode)
978 {
979 DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
980 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
981 return FALSE;
982 }
983
984
985 /*
986 * @unimplemented (Undocumented)
987 */
988 BOOL
989 WINAPI
990 SetConsoleCursor(DWORD Unknown0,
991 DWORD Unknown1)
992 {
993 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
994 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
995 return FALSE;
996 }
997
998
999 /*
1000 * @unimplemented
1001 */
1002 BOOL
1003 WINAPI
1004 SetConsoleDisplayMode(HANDLE hOut,
1005 DWORD dwNewMode,
1006 PCOORD lpdwOldMode)
1007 /*
1008 * FUNCTION: Set the console display mode.
1009 * ARGUMENTS:
1010 * hOut - Standard output handle.
1011 * dwNewMode - New mode.
1012 * lpdwOldMode - Address of a variable that receives the old mode.
1013 */
1014 {
1015 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
1016 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1017 return FALSE;
1018 }
1019
1020
1021 /*
1022 * @unimplemented (Undocumented)
1023 */
1024 BOOL
1025 WINAPI
1026 SetConsoleFont(DWORD Unknown0,
1027 DWORD Unknown1)
1028 {
1029 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1030 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1031 return FALSE;
1032 }
1033
1034
1035 /*
1036 * @implemented (Undocumented)
1037 */
1038 BOOL
1039 WINAPI
1040 SetConsoleHardwareState(HANDLE hConsole,
1041 DWORD Flags,
1042 DWORD State)
1043 {
1044 CSR_API_MESSAGE Request;
1045 ULONG CsrRequest;
1046 NTSTATUS Status;
1047
1048 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
1049 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
1050 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
1051 Request.Data.ConsoleHardwareStateRequest.State = State;
1052
1053 Status = CsrClientCallServer(&Request,
1054 NULL,
1055 CsrRequest,
1056 sizeof(CSR_API_MESSAGE));
1057 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1058 {
1059 SetLastErrorByStatus(Status);
1060 return FALSE;
1061 }
1062
1063 return TRUE;
1064 }
1065
1066
1067 /*
1068 * @unimplemented (Undocumented)
1069 */
1070 BOOL
1071 WINAPI
1072 SetConsoleKeyShortcuts(DWORD Unknown0,
1073 DWORD Unknown1,
1074 DWORD Unknown2,
1075 DWORD Unknown3)
1076 {
1077 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1078 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1079 return FALSE;
1080 }
1081
1082
1083 /*
1084 * @unimplemented (Undocumented)
1085 */
1086 BOOL
1087 WINAPI
1088 SetConsoleMaximumWindowSize(DWORD Unknown0,
1089 DWORD Unknown1)
1090 {
1091 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1092 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1093 return FALSE;
1094 }
1095
1096
1097 /*
1098 * @unimplemented (Undocumented)
1099 */
1100 BOOL
1101 WINAPI
1102 SetConsoleMenuClose(DWORD Unknown0)
1103 {
1104 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
1105 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1106 return FALSE;
1107 }
1108
1109
1110 /*
1111 * @unimplemented (Undocumented)
1112 */
1113 BOOL
1114 WINAPI
1115 SetConsoleNumberOfCommandsA(DWORD Unknown0,
1116 DWORD Unknown1)
1117 {
1118 DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1119 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1120 return FALSE;
1121 }
1122
1123
1124 /*
1125 * @unimplemented (Undocumented)
1126 */
1127 BOOL
1128 WINAPI
1129 SetConsoleNumberOfCommandsW(DWORD Unknown0,
1130 DWORD Unknown1)
1131 {
1132 DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1133 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1134 return FALSE;
1135 }
1136
1137
1138 /*
1139 * @unimplemented (Undocumented)
1140 */
1141 BOOL
1142 WINAPI
1143 SetConsolePalette(DWORD Unknown0,
1144 DWORD Unknown1,
1145 DWORD Unknown2)
1146 {
1147 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
1148 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1149 return FALSE;
1150 }
1151
1152
1153 /*
1154 * @unimplemented (Undocumented)
1155 */
1156 BOOL
1157 WINAPI
1158 SetLastConsoleEventActive(VOID)
1159 {
1160 DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
1161 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1162 return FALSE;
1163 }
1164
1165
1166 /*
1167 * @unimplemented (Undocumented)
1168 */
1169 DWORD
1170 WINAPI
1171 ShowConsoleCursor(DWORD Unknown0,
1172 DWORD Unknown1)
1173 {
1174 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1175 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1176 return 0;
1177 }
1178
1179
1180 /*
1181 * FUNCTION: Checks whether the given handle is a valid console handle.
1182 * ARGUMENTS:
1183 * Handle - Handle to be checked
1184 * RETURNS:
1185 * TRUE: Handle is a valid console handle
1186 * FALSE: Handle is not a valid console handle.
1187 * STATUS: Officially undocumented
1188 *
1189 * @implemented
1190 */
1191 BOOL
1192 WINAPI
1193 VerifyConsoleIoHandle(HANDLE Handle)
1194 {
1195 CSR_API_MESSAGE Request;
1196 ULONG CsrRequest;
1197 NTSTATUS Status;
1198
1199 CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
1200 Request.Data.VerifyHandleRequest.Handle = Handle;
1201
1202 Status = CsrClientCallServer(&Request,
1203 NULL,
1204 CsrRequest,
1205 sizeof(CSR_API_MESSAGE));
1206 if (!NT_SUCCESS(Status))
1207 {
1208 SetLastErrorByStatus(Status);
1209 return FALSE;
1210 }
1211
1212 return (BOOL)NT_SUCCESS(Request.Status);
1213 }
1214
1215
1216 /*
1217 * @unimplemented
1218 */
1219 DWORD
1220 WINAPI
1221 WriteConsoleInputVDMA(DWORD Unknown0,
1222 DWORD Unknown1,
1223 DWORD Unknown2,
1224 DWORD Unknown3)
1225 {
1226 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1227 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1228 return 0;
1229 }
1230
1231
1232 /*
1233 * @unimplemented
1234 */
1235 DWORD
1236 WINAPI
1237 WriteConsoleInputVDMW(DWORD Unknown0,
1238 DWORD Unknown1,
1239 DWORD Unknown2,
1240 DWORD Unknown3)
1241 {
1242 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1243 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1244 return 0;
1245 }
1246
1247
1248 /*
1249 * @implemented (Undocumented)
1250 */
1251 BOOL
1252 WINAPI
1253 CloseConsoleHandle(HANDLE Handle)
1254 {
1255 CSR_API_MESSAGE Request;
1256 ULONG CsrRequest;
1257 NTSTATUS Status;
1258
1259 CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
1260 Request.Data.CloseHandleRequest.Handle = Handle;
1261
1262 Status = CsrClientCallServer(&Request,
1263 NULL,
1264 CsrRequest,
1265 sizeof(CSR_API_MESSAGE));
1266 if (!NT_SUCCESS(Status))
1267 {
1268 SetLastErrorByStatus(Status);
1269 return FALSE;
1270 }
1271
1272 return TRUE;
1273 }
1274
1275 /*
1276 * @implemented
1277 */
1278 HANDLE
1279 WINAPI
1280 GetStdHandle(DWORD nStdHandle)
1281 /*
1282 * FUNCTION: Get a handle for the standard input, standard output
1283 * and a standard error device.
1284 * ARGUMENTS:
1285 * nStdHandle - Specifies the device for which to return the handle.
1286 * RETURNS: If the function succeeds, the return value is the handle
1287 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1288 */
1289 {
1290 PRTL_USER_PROCESS_PARAMETERS Ppb;
1291
1292 Ppb = NtCurrentPeb()->ProcessParameters;
1293 switch (nStdHandle)
1294 {
1295 case STD_INPUT_HANDLE:
1296 return Ppb->StandardInput;
1297
1298 case STD_OUTPUT_HANDLE:
1299 return Ppb->StandardOutput;
1300
1301 case STD_ERROR_HANDLE:
1302 return Ppb->StandardError;
1303 }
1304
1305 SetLastError (ERROR_INVALID_PARAMETER);
1306 return INVALID_HANDLE_VALUE;
1307 }
1308
1309
1310 /*
1311 * @implemented
1312 */
1313 BOOL
1314 WINAPI
1315 SetStdHandle(DWORD nStdHandle,
1316 HANDLE hHandle)
1317 /*
1318 * FUNCTION: Set the handle for the standard input, standard output or
1319 * the standard error device.
1320 * ARGUMENTS:
1321 * nStdHandle - Specifies the handle to be set.
1322 * hHandle - The handle to set.
1323 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1324 */
1325 {
1326 PRTL_USER_PROCESS_PARAMETERS Ppb;
1327
1328 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1329
1330 Ppb = NtCurrentPeb()->ProcessParameters;
1331
1332 switch (nStdHandle)
1333 {
1334 case STD_INPUT_HANDLE:
1335 Ppb->StandardInput = hHandle;
1336 return TRUE;
1337
1338 case STD_OUTPUT_HANDLE:
1339 Ppb->StandardOutput = hHandle;
1340 return TRUE;
1341
1342 case STD_ERROR_HANDLE:
1343 Ppb->StandardError = hHandle;
1344 return TRUE;
1345 }
1346
1347 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1348 SetLastError(ERROR_INVALID_HANDLE);
1349 return FALSE;
1350 }
1351
1352
1353 static
1354 BOOL
1355 IntWriteConsole(HANDLE hConsoleOutput,
1356 PVOID lpBuffer,
1357 DWORD nNumberOfCharsToWrite,
1358 LPDWORD lpNumberOfCharsWritten,
1359 LPVOID lpReserved,
1360 BOOL bUnicode)
1361 {
1362 PCSR_API_MESSAGE Request;
1363 ULONG CsrRequest;
1364 NTSTATUS Status;
1365 USHORT nChars;
1366 ULONG SizeBytes, CharSize;
1367 DWORD Written = 0;
1368
1369 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1370 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1371 0,
1372 max(sizeof(CSR_API_MESSAGE),
1373 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
1374 CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
1375 if (Request == NULL)
1376 {
1377 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1378 return FALSE;
1379 }
1380
1381 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
1382
1383 while (nNumberOfCharsToWrite > 0)
1384 {
1385 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1386 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1387
1388 nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1389 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1390
1391 SizeBytes = nChars * CharSize;
1392
1393 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1394
1395 Status = CsrClientCallServer(Request,
1396 NULL,
1397 CsrRequest,
1398 max(sizeof(CSR_API_MESSAGE),
1399 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1400
1401 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1402 {
1403 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1404 SetLastErrorByStatus(Status);
1405 return FALSE;
1406 }
1407
1408 nNumberOfCharsToWrite -= nChars;
1409 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1410 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1411 }
1412
1413 if (lpNumberOfCharsWritten != NULL)
1414 {
1415 *lpNumberOfCharsWritten = Written;
1416 }
1417 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1418
1419 return TRUE;
1420 }
1421
1422
1423 /*--------------------------------------------------------------
1424 * WriteConsoleA
1425 *
1426 * @implemented
1427 */
1428 BOOL
1429 WINAPI
1430 WriteConsoleA(HANDLE hConsoleOutput,
1431 CONST VOID *lpBuffer,
1432 DWORD nNumberOfCharsToWrite,
1433 LPDWORD lpNumberOfCharsWritten,
1434 LPVOID lpReserved)
1435 {
1436 return IntWriteConsole(hConsoleOutput,
1437 (PVOID)lpBuffer,
1438 nNumberOfCharsToWrite,
1439 lpNumberOfCharsWritten,
1440 lpReserved,
1441 FALSE);
1442 }
1443
1444
1445 /*--------------------------------------------------------------
1446 * WriteConsoleW
1447 *
1448 * @implemented
1449 */
1450 BOOL
1451 WINAPI
1452 WriteConsoleW(HANDLE hConsoleOutput,
1453 CONST VOID *lpBuffer,
1454 DWORD nNumberOfCharsToWrite,
1455 LPDWORD lpNumberOfCharsWritten,
1456 LPVOID lpReserved)
1457 {
1458 return IntWriteConsole(hConsoleOutput,
1459 (PVOID)lpBuffer,
1460 nNumberOfCharsToWrite,
1461 lpNumberOfCharsWritten,
1462 lpReserved,
1463 TRUE);
1464 }
1465
1466
1467 static
1468 BOOL
1469 IntReadConsole(HANDLE hConsoleInput,
1470 PVOID lpBuffer,
1471 DWORD nNumberOfCharsToRead,
1472 LPDWORD lpNumberOfCharsRead,
1473 PCONSOLE_READCONSOLE_CONTROL lpReserved,
1474 BOOL bUnicode)
1475 {
1476 PCSR_API_MESSAGE Request;
1477 ULONG CsrRequest;
1478 NTSTATUS Status;
1479 ULONG CharSize, CharsRead = 0;
1480
1481 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1482 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1483 0,
1484 max(sizeof(CSR_API_MESSAGE),
1485 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + min(nNumberOfCharsToRead,
1486 CSRSS_MAX_READ_CONSOLE / CharSize) * CharSize));
1487 if (Request == NULL)
1488 {
1489 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1490 return FALSE;
1491 }
1492
1493 Request->Status = STATUS_SUCCESS;
1494 CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1495
1496 do
1497 {
1498 if (Request->Status == STATUS_PENDING)
1499 {
1500 Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle,
1501 FALSE,
1502 0);
1503 if (!NT_SUCCESS(Status))
1504 {
1505 DPRINT1("Wait for console input failed!\n");
1506 break;
1507 }
1508 }
1509
1510 Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1511 Request->Data.ReadConsoleRequest.Unicode = bUnicode;
1512 Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
1513 Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead;
1514
1515 Status = CsrClientCallServer(Request,
1516 NULL,
1517 CsrRequest,
1518 max(sizeof(CSR_API_MESSAGE),
1519 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1520 + Request->Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
1521
1522 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1523 {
1524 DPRINT1("CSR returned error in ReadConsole\n");
1525 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1526 SetLastErrorByStatus(Status);
1527 return FALSE;
1528 }
1529
1530 nNumberOfCharsToRead -= Request->Data.ReadConsoleRequest.NrCharactersRead;
1531 memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
1532 Request->Data.ReadConsoleRequest.Buffer,
1533 Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1534 CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead;
1535
1536 if (Request->Status == STATUS_NOTIFY_CLEANUP)
1537 {
1538 if(CharsRead > 0)
1539 {
1540 CharsRead--;
1541 nNumberOfCharsToRead++;
1542 }
1543 Request->Status = STATUS_PENDING;
1544 }
1545 }
1546 while (Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
1547
1548 if (lpNumberOfCharsRead != NULL)
1549 {
1550 *lpNumberOfCharsRead = CharsRead;
1551 }
1552
1553 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1554
1555 return TRUE;
1556 }
1557
1558
1559 /*--------------------------------------------------------------
1560 * ReadConsoleA
1561 *
1562 * @implemented
1563 */
1564 BOOL
1565 WINAPI
1566 ReadConsoleA(HANDLE hConsoleInput,
1567 LPVOID lpBuffer,
1568 DWORD nNumberOfCharsToRead,
1569 LPDWORD lpNumberOfCharsRead,
1570 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1571 {
1572 return IntReadConsole(hConsoleInput,
1573 lpBuffer,
1574 nNumberOfCharsToRead,
1575 lpNumberOfCharsRead,
1576 pInputControl,
1577 FALSE);
1578 }
1579
1580
1581 /*--------------------------------------------------------------
1582 * ReadConsoleW
1583 *
1584 * @implemented
1585 */
1586 BOOL
1587 WINAPI
1588 ReadConsoleW(HANDLE hConsoleInput,
1589 LPVOID lpBuffer,
1590 DWORD nNumberOfCharsToRead,
1591 LPDWORD lpNumberOfCharsRead,
1592 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1593 {
1594 return IntReadConsole(hConsoleInput,
1595 lpBuffer,
1596 nNumberOfCharsToRead,
1597 lpNumberOfCharsRead,
1598 pInputControl,
1599 TRUE);
1600 }
1601
1602
1603 /*--------------------------------------------------------------
1604 * AllocConsole
1605 *
1606 * @implemented
1607 */
1608 BOOL
1609 WINAPI
1610 AllocConsole(VOID)
1611 {
1612 CSR_API_MESSAGE Request;
1613 ULONG CsrRequest;
1614 NTSTATUS Status;
1615 HANDLE hStdError;
1616
1617 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1618 {
1619 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1620 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1621 return FALSE;
1622 }
1623
1624 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1625 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1626
1627 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1628
1629 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1630 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1631 {
1632 SetLastErrorByStatus(Status);
1633 return FALSE;
1634 }
1635
1636 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1637
1638 SetStdHandle(STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle);
1639 SetStdHandle(STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle);
1640
1641 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1642 0,
1643 TRUE,
1644 DUPLICATE_SAME_ACCESS);
1645
1646 SetStdHandle(STD_ERROR_HANDLE, hStdError);
1647 return TRUE;
1648 }
1649
1650
1651 /*--------------------------------------------------------------
1652 * FreeConsole
1653 *
1654 * @implemented
1655 */
1656 BOOL
1657 WINAPI
1658 FreeConsole(VOID)
1659 {
1660 // AG: I'm not sure if this is correct (what happens to std handles?)
1661 // but I just tried to reverse what AllocConsole() does...
1662
1663 CSR_API_MESSAGE Request;
1664 ULONG CsrRequest;
1665 NTSTATUS Status;
1666
1667 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1668
1669 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1670 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1671 {
1672 SetLastErrorByStatus(Status);
1673 return FALSE;
1674 }
1675
1676 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1677 return TRUE;
1678 }
1679
1680
1681 /*--------------------------------------------------------------
1682 * GetConsoleScreenBufferInfo
1683 *
1684 * @implemented
1685 */
1686 BOOL
1687 WINAPI
1688 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1689 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1690 {
1691 CSR_API_MESSAGE Request;
1692 ULONG CsrRequest;
1693 NTSTATUS Status;
1694
1695 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1696 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1697
1698 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1699 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1700 {
1701 SetLastErrorByStatus(Status);
1702 return FALSE;
1703 }
1704 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1705 return TRUE;
1706 }
1707
1708
1709 /*--------------------------------------------------------------
1710 * SetConsoleCursorPosition
1711 *
1712 * @implemented
1713 */
1714 BOOL
1715 WINAPI
1716 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1717 COORD dwCursorPosition)
1718 {
1719 CSR_API_MESSAGE Request;
1720 ULONG CsrRequest;
1721 NTSTATUS Status;
1722
1723 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1724 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1725 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1726
1727 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1728 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1729 {
1730 SetLastErrorByStatus(Status);
1731 return FALSE;
1732 }
1733
1734 return TRUE;
1735 }
1736
1737
1738 static
1739 BOOL
1740 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1741 PVOID cCharacter,
1742 DWORD nLength,
1743 COORD dwWriteCoord,
1744 LPDWORD lpNumberOfCharsWritten,
1745 BOOL bUnicode)
1746 {
1747 CSR_API_MESSAGE Request;
1748 ULONG CsrRequest;
1749 NTSTATUS Status;
1750
1751 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1752 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1753 Request.Data.FillOutputRequest.Unicode = bUnicode;
1754
1755 if(bUnicode)
1756 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1757 else
1758 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1759
1760 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1761 Request.Data.FillOutputRequest.Length = (WORD)nLength;
1762
1763 Status = CsrClientCallServer(&Request,
1764 NULL,
1765 CsrRequest,
1766 sizeof(CSR_API_MESSAGE));
1767
1768 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1769 {
1770 SetLastErrorByStatus(Status);
1771 return FALSE;
1772 }
1773
1774 if(lpNumberOfCharsWritten != NULL)
1775 {
1776 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1777 }
1778
1779 return TRUE;
1780 }
1781
1782 /*--------------------------------------------------------------
1783 * FillConsoleOutputCharacterA
1784 *
1785 * @implemented
1786 */
1787 BOOL
1788 WINAPI
1789 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
1790 CHAR cCharacter,
1791 DWORD nLength,
1792 COORD dwWriteCoord,
1793 LPDWORD lpNumberOfCharsWritten)
1794 {
1795 return IntFillConsoleOutputCharacter(hConsoleOutput,
1796 &cCharacter,
1797 nLength,
1798 dwWriteCoord,
1799 lpNumberOfCharsWritten,
1800 FALSE);
1801 }
1802
1803
1804 /*--------------------------------------------------------------
1805 * FillConsoleOutputCharacterW
1806 *
1807 * @implemented
1808 */
1809 BOOL
1810 WINAPI
1811 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
1812 WCHAR cCharacter,
1813 DWORD nLength,
1814 COORD dwWriteCoord,
1815 LPDWORD lpNumberOfCharsWritten)
1816 {
1817 return IntFillConsoleOutputCharacter(hConsoleOutput,
1818 &cCharacter,
1819 nLength,
1820 dwWriteCoord,
1821 lpNumberOfCharsWritten,
1822 TRUE);
1823 }
1824
1825
1826 static
1827 BOOL
1828 IntPeekConsoleInput(HANDLE hConsoleInput,
1829 PINPUT_RECORD lpBuffer,
1830 DWORD nLength,
1831 LPDWORD lpNumberOfEventsRead,
1832 BOOL bUnicode)
1833 {
1834 CSR_API_MESSAGE Request;
1835 ULONG CsrRequest;
1836 PCSR_CAPTURE_BUFFER CaptureBuffer;
1837 NTSTATUS Status;
1838 ULONG Size;
1839
1840 if (lpBuffer == NULL)
1841 {
1842 SetLastError(ERROR_INVALID_PARAMETER);
1843 return FALSE;
1844 }
1845
1846 Size = nLength * sizeof(INPUT_RECORD);
1847
1848 /* Allocate a Capture Buffer */
1849 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
1850 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1851
1852 /* Allocate space in the Buffer */
1853 CsrCaptureMessageBuffer(CaptureBuffer,
1854 NULL,
1855 Size,
1856 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
1857
1858 /* Set up the data to send to the Console Server */
1859 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
1860 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1861 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
1862 Request.Data.PeekConsoleInputRequest.Length = nLength;
1863
1864 /* Call the server */
1865 Status = CsrClientCallServer(&Request,
1866 CaptureBuffer,
1867 CsrRequest,
1868 sizeof(CSR_API_MESSAGE));
1869 DPRINT("Server returned: %x\n", Request.Status);
1870
1871 /* Check for success*/
1872 if (NT_SUCCESS(Request.Status))
1873 {
1874 /* Return the number of events read */
1875 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
1876 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
1877
1878 /* Copy into the buffer */
1879 DPRINT("Copying to buffer\n");
1880 RtlCopyMemory(lpBuffer,
1881 Request.Data.PeekConsoleInputRequest.InputRecord,
1882 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
1883 }
1884 else
1885 {
1886 /* Error out */
1887 *lpNumberOfEventsRead = 0;
1888 SetLastErrorByStatus(Request.Status);
1889 }
1890
1891 /* Release the capture buffer */
1892 CsrFreeCaptureBuffer(CaptureBuffer);
1893
1894 /* Return TRUE or FALSE */
1895 return NT_SUCCESS(Request.Status);
1896 }
1897
1898 /*--------------------------------------------------------------
1899 * PeekConsoleInputA
1900 *
1901 * @implemented
1902 */
1903 BOOL
1904 WINAPI
1905 PeekConsoleInputA(HANDLE hConsoleInput,
1906 PINPUT_RECORD lpBuffer,
1907 DWORD nLength,
1908 LPDWORD lpNumberOfEventsRead)
1909 {
1910 return IntPeekConsoleInput(hConsoleInput,
1911 lpBuffer,
1912 nLength,
1913 lpNumberOfEventsRead,
1914 FALSE);
1915 }
1916
1917
1918 /*--------------------------------------------------------------
1919 * PeekConsoleInputW
1920 *
1921 * @implemented
1922 */
1923 BOOL
1924 WINAPI
1925 PeekConsoleInputW(HANDLE hConsoleInput,
1926 PINPUT_RECORD lpBuffer,
1927 DWORD nLength,
1928 LPDWORD lpNumberOfEventsRead)
1929 {
1930 return IntPeekConsoleInput(hConsoleInput,
1931 lpBuffer, nLength,
1932 lpNumberOfEventsRead,
1933 TRUE);
1934 }
1935
1936
1937 static
1938 BOOL
1939 IntReadConsoleInput(HANDLE hConsoleInput,
1940 PINPUT_RECORD lpBuffer,
1941 DWORD nLength,
1942 LPDWORD lpNumberOfEventsRead,
1943 BOOL bUnicode)
1944 {
1945 CSR_API_MESSAGE Request;
1946 ULONG CsrRequest;
1947 ULONG Read;
1948 NTSTATUS Status;
1949
1950 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
1951 Read = 0;
1952
1953 while (nLength > 0)
1954 {
1955 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1956 Request.Data.ReadInputRequest.Unicode = bUnicode;
1957
1958 Status = CsrClientCallServer(&Request,
1959 NULL,
1960 CsrRequest,
1961 sizeof(CSR_API_MESSAGE));
1962 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1963 {
1964 if (Read == 0)
1965 {
1966 /* we couldn't read a single record, fail */
1967 SetLastErrorByStatus(Status);
1968 return FALSE;
1969 }
1970 else
1971 {
1972 /* FIXME - fail gracefully in case we already read at least one record? */
1973 break;
1974 }
1975 }
1976 else if (Status == STATUS_PENDING)
1977 {
1978 if (Read == 0)
1979 {
1980 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
1981 if (!NT_SUCCESS(Status))
1982 {
1983 SetLastErrorByStatus(Status);
1984 break;
1985 }
1986 }
1987 else
1988 {
1989 /* nothing more to read (waiting for more input??), let's just bail */
1990 break;
1991 }
1992 }
1993 else
1994 {
1995 lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
1996 nLength--;
1997
1998 if (!Request.Data.ReadInputRequest.MoreEvents)
1999 {
2000 /* nothing more to read, bail */
2001 break;
2002 }
2003 }
2004 }
2005
2006 if (lpNumberOfEventsRead != NULL)
2007 {
2008 *lpNumberOfEventsRead = Read;
2009 }
2010
2011 return (Read > 0);
2012 }
2013
2014
2015 /*--------------------------------------------------------------
2016 * ReadConsoleInputA
2017 *
2018 * @implemented
2019 */
2020 BOOL
2021 WINAPI
2022 ReadConsoleInputA(HANDLE hConsoleInput,
2023 PINPUT_RECORD lpBuffer,
2024 DWORD nLength,
2025 LPDWORD lpNumberOfEventsRead)
2026 {
2027 return IntReadConsoleInput(hConsoleInput,
2028 lpBuffer,
2029 nLength,
2030 lpNumberOfEventsRead,
2031 FALSE);
2032 }
2033
2034
2035 /*--------------------------------------------------------------
2036 * ReadConsoleInputW
2037 *
2038 * @implemented
2039 */
2040 BOOL
2041 WINAPI
2042 ReadConsoleInputW(HANDLE hConsoleInput,
2043 PINPUT_RECORD lpBuffer,
2044 DWORD nLength,
2045 LPDWORD lpNumberOfEventsRead)
2046 {
2047 return IntReadConsoleInput(hConsoleInput,
2048 lpBuffer,
2049 nLength,
2050 lpNumberOfEventsRead,
2051 TRUE);
2052 }
2053
2054
2055 static
2056 BOOL
2057 IntWriteConsoleInput(HANDLE hConsoleInput,
2058 PINPUT_RECORD lpBuffer,
2059 DWORD nLength,
2060 LPDWORD lpNumberOfEventsWritten,
2061 BOOL bUnicode)
2062 {
2063 CSR_API_MESSAGE Request;
2064 ULONG CsrRequest;
2065 PCSR_CAPTURE_BUFFER CaptureBuffer;
2066 NTSTATUS Status;
2067 DWORD Size;
2068
2069 if (lpBuffer == NULL)
2070 {
2071 SetLastError(ERROR_INVALID_PARAMETER);
2072 return FALSE;
2073 }
2074
2075 Size = nLength * sizeof(INPUT_RECORD);
2076
2077 /* Allocate a Capture Buffer */
2078 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
2079 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2080
2081 /* Allocate space in the Buffer */
2082 CsrCaptureMessageBuffer(CaptureBuffer,
2083 lpBuffer,
2084 Size,
2085 (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
2086
2087 /* Set up the data to send to the Console Server */
2088 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
2089 Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
2090 Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
2091 Request.Data.WriteConsoleInputRequest.Length = nLength;
2092
2093 /* Call the server */
2094 Status = CsrClientCallServer(&Request,
2095 CaptureBuffer,
2096 CsrRequest,
2097 sizeof(CSR_API_MESSAGE));
2098 DPRINT("Server returned: %x\n", Request.Status);
2099
2100 /* Check for success*/
2101 if (NT_SUCCESS(Request.Status))
2102 {
2103 /* Return the number of events read */
2104 DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
2105 *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
2106 }
2107 else
2108 {
2109 /* Error out */
2110 *lpNumberOfEventsWritten = 0;
2111 SetLastErrorByStatus(Request.Status);
2112 }
2113
2114 /* Release the capture buffer */
2115 CsrFreeCaptureBuffer(CaptureBuffer);
2116
2117 /* Return TRUE or FALSE */
2118 return NT_SUCCESS(Request.Status);
2119 }
2120
2121
2122 /*--------------------------------------------------------------
2123 * WriteConsoleInputA
2124 *
2125 * @implemented
2126 */
2127 BOOL
2128 WINAPI
2129 WriteConsoleInputA(HANDLE hConsoleInput,
2130 CONST INPUT_RECORD *lpBuffer,
2131 DWORD nLength,
2132 LPDWORD lpNumberOfEventsWritten)
2133 {
2134 return IntWriteConsoleInput(hConsoleInput,
2135 (PINPUT_RECORD)lpBuffer,
2136 nLength,
2137 lpNumberOfEventsWritten,
2138 FALSE);
2139 }
2140
2141
2142 /*--------------------------------------------------------------
2143 * WriteConsoleInputW
2144 *
2145 * @implemented
2146 */
2147 BOOL
2148 WINAPI
2149 WriteConsoleInputW(HANDLE hConsoleInput,
2150 CONST INPUT_RECORD *lpBuffer,
2151 DWORD nLength,
2152 LPDWORD lpNumberOfEventsWritten)
2153 {
2154 return IntWriteConsoleInput(hConsoleInput,
2155 (PINPUT_RECORD)lpBuffer,
2156 nLength,
2157 lpNumberOfEventsWritten,
2158 TRUE);
2159 }
2160
2161
2162 static
2163 BOOL
2164 IntReadConsoleOutput(HANDLE hConsoleOutput,
2165 PCHAR_INFO lpBuffer,
2166 COORD dwBufferSize,
2167 COORD dwBufferCoord,
2168 PSMALL_RECT lpReadRegion,
2169 BOOL bUnicode)
2170 {
2171 CSR_API_MESSAGE Request;
2172 ULONG CsrRequest;
2173 PCSR_CAPTURE_BUFFER CaptureBuffer;
2174 NTSTATUS Status;
2175 DWORD Size, SizeX, SizeY;
2176
2177 if (lpBuffer == NULL)
2178 {
2179 SetLastError(ERROR_INVALID_PARAMETER);
2180 return FALSE;
2181 }
2182
2183 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
2184
2185 /* Allocate a Capture Buffer */
2186 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
2187 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2188
2189 /* Allocate space in the Buffer */
2190 CsrCaptureMessageBuffer(CaptureBuffer,
2191 NULL,
2192 Size,
2193 (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
2194
2195 /* Set up the data to send to the Console Server */
2196 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
2197 Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2198 Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
2199 Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
2200 Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
2201 Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
2202
2203 /* Call the server */
2204 Status = CsrClientCallServer(&Request,
2205 CaptureBuffer,
2206 CsrRequest,
2207 sizeof(CSR_API_MESSAGE));
2208 DPRINT("Server returned: %x\n", Request.Status);
2209
2210 /* Check for success*/
2211 if (NT_SUCCESS(Request.Status))
2212 {
2213 /* Copy into the buffer */
2214 DPRINT("Copying to buffer\n");
2215 SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
2216 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
2217 SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
2218 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
2219 RtlCopyMemory(lpBuffer,
2220 Request.Data.ReadConsoleOutputRequest.CharInfo,
2221 sizeof(CHAR_INFO) * SizeX * SizeY);
2222 }
2223 else
2224 {
2225 /* Error out */
2226 SetLastErrorByStatus(Request.Status);
2227 }
2228
2229 /* Return the read region */
2230 DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
2231 *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
2232
2233 /* Release the capture buffer */
2234 CsrFreeCaptureBuffer(CaptureBuffer);
2235
2236 /* Return TRUE or FALSE */
2237 return NT_SUCCESS(Request.Status);
2238 }
2239
2240 /*--------------------------------------------------------------
2241 * ReadConsoleOutputA
2242 *
2243 * @implemented
2244 */
2245 BOOL
2246 WINAPI
2247 ReadConsoleOutputA(HANDLE hConsoleOutput,
2248 PCHAR_INFO lpBuffer,
2249 COORD dwBufferSize,
2250 COORD dwBufferCoord,
2251 PSMALL_RECT lpReadRegion)
2252 {
2253 return IntReadConsoleOutput(hConsoleOutput,
2254 lpBuffer,
2255 dwBufferSize,
2256 dwBufferCoord,
2257 lpReadRegion,
2258 FALSE);
2259 }
2260
2261
2262 /*--------------------------------------------------------------
2263 * ReadConsoleOutputW
2264 *
2265 * @implemented
2266 */
2267 BOOL
2268 WINAPI
2269 ReadConsoleOutputW(HANDLE hConsoleOutput,
2270 PCHAR_INFO lpBuffer,
2271 COORD dwBufferSize,
2272 COORD dwBufferCoord,
2273 PSMALL_RECT lpReadRegion)
2274 {
2275 return IntReadConsoleOutput(hConsoleOutput,
2276 lpBuffer,
2277 dwBufferSize,
2278 dwBufferCoord,
2279 lpReadRegion,
2280 TRUE);
2281 }
2282
2283
2284 static
2285 BOOL
2286 IntWriteConsoleOutput(HANDLE hConsoleOutput,
2287 CONST CHAR_INFO *lpBuffer,
2288 COORD dwBufferSize,
2289 COORD dwBufferCoord,
2290 PSMALL_RECT lpWriteRegion,
2291 BOOL bUnicode)
2292 {
2293 CSR_API_MESSAGE Request;
2294 ULONG CsrRequest;
2295 PCSR_CAPTURE_BUFFER CaptureBuffer;
2296 NTSTATUS Status;
2297 ULONG Size;
2298
2299 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
2300
2301 /* Allocate a Capture Buffer */
2302 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
2303 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2304
2305 /* Allocate space in the Buffer */
2306 CsrCaptureMessageBuffer(CaptureBuffer,
2307 NULL,
2308 Size,
2309 (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
2310
2311 /* Copy from the buffer */
2312 RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
2313
2314 /* Set up the data to send to the Console Server */
2315 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
2316 Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2317 Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
2318 Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
2319 Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
2320 Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
2321
2322 /* Call the server */
2323 Status = CsrClientCallServer(&Request,
2324 CaptureBuffer,
2325 CsrRequest,
2326 sizeof(CSR_API_MESSAGE));
2327 DPRINT("Server returned: %x\n", Request.Status);
2328
2329 /* Check for success*/
2330 if (!NT_SUCCESS(Request.Status))
2331 {
2332 /* Error out */
2333 SetLastErrorByStatus(Request.Status);
2334 }
2335
2336 /* Return the read region */
2337 DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
2338 *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
2339
2340 /* Release the capture buffer */
2341 CsrFreeCaptureBuffer(CaptureBuffer);
2342
2343 /* Return TRUE or FALSE */
2344 return NT_SUCCESS(Request.Status);
2345 }
2346
2347 /*--------------------------------------------------------------
2348 * WriteConsoleOutputA
2349 *
2350 * @implemented
2351 */
2352 BOOL
2353 WINAPI
2354 WriteConsoleOutputA(HANDLE hConsoleOutput,
2355 CONST CHAR_INFO *lpBuffer,
2356 COORD dwBufferSize,
2357 COORD dwBufferCoord,
2358 PSMALL_RECT lpWriteRegion)
2359 {
2360 return IntWriteConsoleOutput(hConsoleOutput,
2361 lpBuffer,
2362 dwBufferSize,
2363 dwBufferCoord,
2364 lpWriteRegion,
2365 FALSE);
2366 }
2367
2368
2369 /*--------------------------------------------------------------
2370 * WriteConsoleOutputW
2371 *
2372 * @implemented
2373 */
2374 BOOL
2375 WINAPI
2376 WriteConsoleOutputW(HANDLE hConsoleOutput,
2377 CONST CHAR_INFO *lpBuffer,
2378 COORD dwBufferSize,
2379 COORD dwBufferCoord,
2380 PSMALL_RECT lpWriteRegion)
2381 {
2382 return IntWriteConsoleOutput(hConsoleOutput,
2383 lpBuffer,
2384 dwBufferSize,
2385 dwBufferCoord,
2386 lpWriteRegion,
2387 TRUE);
2388 }
2389
2390
2391 static
2392 BOOL
2393 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
2394 PVOID lpCharacter,
2395 DWORD nLength,
2396 COORD dwReadCoord,
2397 LPDWORD lpNumberOfCharsRead,
2398 BOOL bUnicode)
2399 {
2400 PCSR_API_MESSAGE Request;
2401 ULONG CsrRequest;
2402 NTSTATUS Status;
2403 ULONG nChars, SizeBytes, CharSize;
2404 DWORD CharsRead = 0;
2405
2406 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2407
2408 nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) / CharSize;
2409 SizeBytes = nChars * CharSize;
2410
2411 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2412 max(sizeof(CSR_API_MESSAGE),
2413 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)
2414 + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2415 if (Request == NULL)
2416 {
2417 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2418 return FALSE;
2419 }
2420
2421 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2422 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
2423
2424 while (nLength > 0)
2425 {
2426 DWORD BytesRead;
2427
2428 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2429 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
2430 Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
2431 SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
2432
2433 Status = CsrClientCallServer(Request,
2434 NULL,
2435 CsrRequest,
2436 max(sizeof(CSR_API_MESSAGE),
2437 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
2438 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2439 {
2440 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2441 SetLastErrorByStatus(Status);
2442 break;
2443 }
2444
2445 BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
2446 memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
2447 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
2448 CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2449 nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2450
2451 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
2452 }
2453
2454 if (lpNumberOfCharsRead != NULL)
2455 {
2456 *lpNumberOfCharsRead = CharsRead;
2457 }
2458
2459 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2460
2461 return TRUE;
2462 }
2463
2464
2465 /*--------------------------------------------------------------
2466 * ReadConsoleOutputCharacterA
2467 *
2468 * @implemented
2469 */
2470 BOOL
2471 WINAPI
2472 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
2473 LPSTR lpCharacter,
2474 DWORD nLength,
2475 COORD dwReadCoord,
2476 LPDWORD lpNumberOfCharsRead)
2477 {
2478 return IntReadConsoleOutputCharacter(hConsoleOutput,
2479 (PVOID)lpCharacter,
2480 nLength,
2481 dwReadCoord,
2482 lpNumberOfCharsRead,
2483 FALSE);
2484 }
2485
2486
2487 /*--------------------------------------------------------------
2488 * ReadConsoleOutputCharacterW
2489 *
2490 * @implemented
2491 */
2492 BOOL
2493 WINAPI
2494 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
2495 LPWSTR lpCharacter,
2496 DWORD nLength,
2497 COORD dwReadCoord,
2498 LPDWORD lpNumberOfCharsRead)
2499 {
2500 return IntReadConsoleOutputCharacter(hConsoleOutput,
2501 (PVOID)lpCharacter,
2502 nLength,
2503 dwReadCoord,
2504 lpNumberOfCharsRead,
2505 TRUE);
2506 }
2507
2508
2509 /*--------------------------------------------------------------
2510 * ReadConsoleOutputAttribute
2511 *
2512 * @implemented
2513 */
2514 BOOL
2515 WINAPI
2516 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
2517 LPWORD lpAttribute,
2518 DWORD nLength,
2519 COORD dwReadCoord,
2520 LPDWORD lpNumberOfAttrsRead)
2521 {
2522 PCSR_API_MESSAGE Request;
2523 ULONG CsrRequest;
2524 NTSTATUS Status;
2525 DWORD Size;
2526
2527 if (lpNumberOfAttrsRead != NULL)
2528 *lpNumberOfAttrsRead = nLength;
2529
2530 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2531 0,
2532 max(sizeof(CSR_API_MESSAGE),
2533 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
2534 + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2535 if (Request == NULL)
2536 {
2537 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2538 return FALSE;
2539 }
2540
2541 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2542
2543 while (nLength != 0)
2544 {
2545 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2546 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2547
2548 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2549 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2550 else
2551 Size = nLength;
2552
2553 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2554
2555 Status = CsrClientCallServer(Request,
2556 NULL,
2557 CsrRequest,
2558 max(sizeof(CSR_API_MESSAGE),
2559 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2560 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2561 {
2562 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2563 SetLastErrorByStatus(Status);
2564 return FALSE;
2565 }
2566
2567 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2568 lpAttribute += Size;
2569 nLength -= Size;
2570 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2571 }
2572
2573 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2574
2575 return TRUE;
2576 }
2577
2578
2579 static
2580 BOOL
2581 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2582 PVOID lpCharacter,
2583 DWORD nLength,
2584 COORD dwWriteCoord,
2585 LPDWORD lpNumberOfCharsWritten,
2586 BOOL bUnicode)
2587 {
2588 PCSR_API_MESSAGE Request;
2589 ULONG CsrRequest;
2590 NTSTATUS Status;
2591 ULONG SizeBytes, CharSize, nChars;
2592 DWORD Written = 0;
2593
2594 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2595
2596 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2597 SizeBytes = nChars * CharSize;
2598
2599 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2600 max(sizeof(CSR_API_MESSAGE),
2601 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2602 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2603 if (Request == NULL)
2604 {
2605 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2606 return FALSE;
2607 }
2608
2609 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2610 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2611
2612 while (nLength > 0)
2613 {
2614 DWORD BytesWrite;
2615
2616 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2617 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2618 Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
2619 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2620
2621 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2622
2623 Status = CsrClientCallServer(Request,
2624 NULL,
2625 CsrRequest,
2626 max(sizeof(CSR_API_MESSAGE),
2627 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2628
2629 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2630 {
2631 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2632 SetLastErrorByStatus(Status);
2633 return FALSE;
2634 }
2635
2636 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2637 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2638 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2639
2640 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2641 }
2642
2643 if (lpNumberOfCharsWritten != NULL)
2644 {
2645 *lpNumberOfCharsWritten = Written;
2646 }
2647
2648 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2649
2650 return TRUE;
2651 }
2652
2653
2654 /*--------------------------------------------------------------
2655 * WriteConsoleOutputCharacterA
2656 *
2657 * @implemented
2658 */
2659 BOOL
2660 WINAPI
2661 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2662 LPCSTR lpCharacter,
2663 DWORD nLength,
2664 COORD dwWriteCoord,
2665 LPDWORD lpNumberOfCharsWritten)
2666 {
2667 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2668 (PVOID)lpCharacter,
2669 nLength,
2670 dwWriteCoord,
2671 lpNumberOfCharsWritten,
2672 FALSE);
2673 }
2674
2675
2676 /*--------------------------------------------------------------
2677 * WriteConsoleOutputCharacterW
2678 *
2679 * @implemented
2680 */
2681 BOOL
2682 WINAPI
2683 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2684 LPCWSTR lpCharacter,
2685 DWORD nLength,
2686 COORD dwWriteCoord,
2687 LPDWORD lpNumberOfCharsWritten)
2688 {
2689 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2690 (PVOID)lpCharacter,
2691 nLength,
2692 dwWriteCoord,
2693 lpNumberOfCharsWritten,
2694 TRUE);
2695 }
2696
2697
2698 /*--------------------------------------------------------------
2699 * WriteConsoleOutputAttribute
2700 *
2701 * @implemented
2702 */
2703 BOOL
2704 WINAPI
2705 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
2706 CONST WORD *lpAttribute,
2707 DWORD nLength,
2708 COORD dwWriteCoord,
2709 LPDWORD lpNumberOfAttrsWritten)
2710 {
2711 PCSR_API_MESSAGE Request;
2712 ULONG CsrRequest;
2713 NTSTATUS Status;
2714 WORD Size;
2715
2716 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2717 0,
2718 max(sizeof(CSR_API_MESSAGE),
2719 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2720 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2721 if (Request == NULL)
2722 {
2723 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2724 return FALSE;
2725 }
2726
2727 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2728 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2729
2730 if (lpNumberOfAttrsWritten)
2731 *lpNumberOfAttrsWritten = nLength;
2732 while (nLength)
2733 {
2734 Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2735 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2736 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2737 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2738
2739 Status = CsrClientCallServer(Request,
2740 NULL,
2741 CsrRequest,
2742 max(sizeof(CSR_API_MESSAGE),
2743 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2744
2745 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2746 {
2747 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2748 SetLastErrorByStatus (Status);
2749 return FALSE;
2750 }
2751 nLength -= Size;
2752 lpAttribute += Size;
2753 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2754 }
2755
2756 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2757
2758 return TRUE;
2759 }
2760
2761
2762 /*--------------------------------------------------------------
2763 * FillConsoleOutputAttribute
2764 *
2765 * @implemented
2766 */
2767 BOOL
2768 WINAPI
2769 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
2770 WORD wAttribute,
2771 DWORD nLength,
2772 COORD dwWriteCoord,
2773 LPDWORD lpNumberOfAttrsWritten)
2774 {
2775 CSR_API_MESSAGE Request;
2776 ULONG CsrRequest;
2777 NTSTATUS Status;
2778
2779 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2780 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2781 Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
2782 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2783 Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
2784
2785 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2786 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2787 {
2788 SetLastErrorByStatus ( Status );
2789 return FALSE;
2790 }
2791
2792 if (lpNumberOfAttrsWritten)
2793 *lpNumberOfAttrsWritten = nLength;
2794
2795 return TRUE;
2796 }
2797
2798
2799 /*--------------------------------------------------------------
2800 * GetConsoleMode
2801 *
2802 * @implemented
2803 */
2804 BOOL
2805 WINAPI
2806 GetConsoleMode(HANDLE hConsoleHandle,
2807 LPDWORD lpMode)
2808 {
2809 CSR_API_MESSAGE Request;
2810 ULONG CsrRequest;
2811 NTSTATUS Status;
2812
2813 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
2814 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2815
2816 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2817 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2818 {
2819 SetLastErrorByStatus ( Status );
2820 return FALSE;
2821 }
2822 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
2823
2824 return TRUE;
2825 }
2826
2827
2828 /*--------------------------------------------------------------
2829 * GetNumberOfConsoleInputEvents
2830 *
2831 * @implemented
2832 */
2833 BOOL
2834 WINAPI
2835 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
2836 LPDWORD lpNumberOfEvents)
2837 {
2838 CSR_API_MESSAGE Request;
2839 ULONG CsrRequest;
2840 NTSTATUS Status;
2841
2842 if (lpNumberOfEvents == NULL)
2843 {
2844 SetLastError(ERROR_INVALID_PARAMETER);
2845 return FALSE;
2846 }
2847
2848 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
2849 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2850
2851 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2852 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2853 {
2854 SetLastErrorByStatus(Status);
2855 return FALSE;
2856 }
2857
2858 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
2859
2860 return TRUE;
2861 }
2862
2863
2864 /*--------------------------------------------------------------
2865 * GetLargestConsoleWindowSize
2866 *
2867 * @unimplemented
2868 */
2869 COORD
2870 WINAPI
2871 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
2872 {
2873 COORD Coord = {80,25};
2874 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
2875 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2876 return Coord;
2877 }
2878
2879
2880 /*--------------------------------------------------------------
2881 * GetConsoleCursorInfo
2882 *
2883 * @implemented
2884 */
2885 BOOL
2886 WINAPI
2887 GetConsoleCursorInfo(HANDLE hConsoleOutput,
2888 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
2889 {
2890 CSR_API_MESSAGE Request;
2891 ULONG CsrRequest;
2892 NTSTATUS Status;
2893
2894 if (!lpConsoleCursorInfo)
2895 {
2896 if (!hConsoleOutput)
2897 SetLastError(ERROR_INVALID_HANDLE);
2898 else
2899 SetLastError(ERROR_INVALID_ACCESS);
2900
2901 return FALSE;
2902 }
2903
2904 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
2905 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2906
2907 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2908
2909 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2910 {
2911 SetLastErrorByStatus(Status);
2912 return FALSE;
2913 }
2914 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
2915
2916 return TRUE;
2917 }
2918
2919
2920 /*--------------------------------------------------------------
2921 * GetNumberOfConsoleMouseButtons
2922 *
2923 * @unimplemented
2924 */
2925 BOOL
2926 WINAPI
2927 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
2928 {
2929 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
2930 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2931 return FALSE;
2932 }
2933
2934
2935 /*--------------------------------------------------------------
2936 * SetConsoleMode
2937 *
2938 * @implemented
2939 */
2940 BOOL
2941 WINAPI
2942 SetConsoleMode(HANDLE hConsoleHandle,
2943 DWORD dwMode)
2944 {
2945 CSR_API_MESSAGE Request;
2946 ULONG CsrRequest;
2947 NTSTATUS Status;
2948
2949 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
2950 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2951 Request.Data.SetConsoleModeRequest.Mode = dwMode;
2952
2953 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2954 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2955 {
2956 SetLastErrorByStatus ( Status );
2957 return FALSE;
2958 }
2959
2960 return TRUE;
2961 }
2962
2963
2964 /*--------------------------------------------------------------
2965 * SetConsoleActiveScreenBuffer
2966 *
2967 * @implemented
2968 */
2969 BOOL
2970 WINAPI
2971 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
2972 {
2973 CSR_API_MESSAGE Request;
2974 ULONG CsrRequest;
2975 NTSTATUS Status;
2976
2977 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
2978 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
2979
2980 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2981 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2982 {
2983 SetLastErrorByStatus(Status);
2984 return FALSE;
2985 }
2986
2987 return TRUE;
2988 }
2989
2990
2991 /*--------------------------------------------------------------
2992 * FlushConsoleInputBuffer
2993 *
2994 * @implemented
2995 */
2996 BOOL
2997 WINAPI
2998 FlushConsoleInputBuffer(HANDLE hConsoleInput)
2999 {
3000 CSR_API_MESSAGE Request;
3001 ULONG CsrRequest;
3002 NTSTATUS Status;
3003
3004 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
3005 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
3006
3007 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3008 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3009 {
3010 SetLastErrorByStatus(Status);
3011 return FALSE;
3012 }
3013
3014 return TRUE;
3015 }
3016
3017
3018 /*--------------------------------------------------------------
3019 * SetConsoleScreenBufferSize
3020 *
3021 * @unimplemented
3022 */
3023 BOOL
3024 WINAPI
3025 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
3026 COORD dwSize)
3027 {
3028 DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
3029 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3030 return FALSE;
3031 }
3032
3033 /*--------------------------------------------------------------
3034 * SetConsoleCursorInfo
3035 *
3036 * @implemented
3037 */
3038 BOOL
3039 WINAPI
3040 SetConsoleCursorInfo(HANDLE hConsoleOutput,
3041 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
3042 {
3043 CSR_API_MESSAGE Request;
3044 ULONG CsrRequest;
3045 NTSTATUS Status;
3046
3047 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
3048 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3049 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
3050
3051 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3052 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3053 {
3054 SetLastErrorByStatus(Status);
3055 return FALSE;
3056 }
3057
3058 return TRUE;
3059 }
3060
3061
3062 static
3063 BOOL
3064 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
3065 const SMALL_RECT *lpScrollRectangle,
3066 const SMALL_RECT *lpClipRectangle,
3067 COORD dwDestinationOrigin,
3068 const CHAR_INFO *lpFill,
3069 BOOL bUnicode)
3070 {
3071 CSR_API_MESSAGE Request;
3072 ULONG CsrRequest;
3073 NTSTATUS Status;
3074
3075 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
3076 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
3077 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
3078 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
3079
3080 if (lpClipRectangle != NULL)
3081 {
3082 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
3083 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
3084 }
3085 else
3086 {
3087 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
3088 }
3089
3090 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
3091 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
3092
3093 Status = CsrClientCallServer(&Request,
3094 NULL,
3095 CsrRequest,
3096 sizeof(CSR_API_MESSAGE));
3097
3098 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3099 {
3100 SetLastErrorByStatus(Status);
3101 return FALSE;
3102 }
3103
3104 return TRUE;
3105 }
3106
3107
3108 /*--------------------------------------------------------------
3109 * ScrollConsoleScreenBufferA
3110 *
3111 * @implemented
3112 */
3113 BOOL
3114 WINAPI
3115 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
3116 CONST SMALL_RECT *lpScrollRectangle,
3117 CONST SMALL_RECT *lpClipRectangle,
3118 COORD dwDestinationOrigin,
3119 CONST CHAR_INFO *lpFill)
3120 {
3121 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3122 (PSMALL_RECT)lpScrollRectangle,
3123 (PSMALL_RECT)lpClipRectangle,
3124 dwDestinationOrigin,
3125 (PCHAR_INFO)lpFill,
3126 FALSE);
3127 }
3128
3129
3130 /*--------------------------------------------------------------
3131 * ScrollConsoleScreenBufferW
3132 *
3133 * @implemented
3134 */
3135 BOOL
3136 WINAPI
3137 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
3138 CONST SMALL_RECT *lpScrollRectangle,
3139 CONST SMALL_RECT *lpClipRectangle,
3140 COORD dwDestinationOrigin,
3141 CONST CHAR_INFO *lpFill)
3142 {
3143 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3144 lpScrollRectangle,
3145 lpClipRectangle,
3146 dwDestinationOrigin,
3147 lpFill,
3148 TRUE);
3149 }
3150
3151
3152 /*--------------------------------------------------------------
3153 * SetConsoleWindowInfo
3154 *
3155 * @unimplemented
3156 */
3157 BOOL
3158 WINAPI
3159 SetConsoleWindowInfo(HANDLE hConsoleOutput,
3160 BOOL bAbsolute,
3161 CONST SMALL_RECT *lpConsoleWindow)
3162 {
3163 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
3164 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3165 return FALSE;
3166 }
3167
3168
3169 /*--------------------------------------------------------------
3170 * SetConsoleTextAttribute
3171 *
3172 * @implemented
3173 */
3174 BOOL
3175 WINAPI
3176 SetConsoleTextAttribute(HANDLE hConsoleOutput,
3177 WORD wAttributes)
3178 {
3179 CSR_API_MESSAGE Request;
3180 ULONG CsrRequest;
3181 NTSTATUS Status;
3182
3183 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
3184 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
3185 Request.Data.SetAttribRequest.Attrib = wAttributes;
3186
3187 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3188 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3189 {
3190 SetLastErrorByStatus(Status);
3191 return FALSE;
3192 }
3193
3194 return TRUE;
3195 }
3196
3197
3198 static
3199 BOOL
3200 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3201 {
3202 if (HandlerRoutine == NULL)
3203 {
3204 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
3205 return(TRUE);
3206 }
3207 else
3208 {
3209 NrCtrlHandlers++;
3210 if (CtrlHandlers == NULL)
3211 {
3212 CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
3213 HEAP_ZERO_MEMORY,
3214 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
3215 }
3216 else
3217 {
3218 CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(),
3219 HEAP_ZERO_MEMORY,
3220 (PVOID)CtrlHandlers,
3221 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
3222 }
3223
3224 if (CtrlHandlers == NULL)
3225 {
3226 NrCtrlHandlers = 0;
3227 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3228 return FALSE;
3229 }
3230
3231 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
3232 return TRUE;
3233 }
3234 }
3235
3236
3237 static
3238 BOOL
3239 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3240 {
3241 ULONG i;
3242
3243 if (HandlerRoutine == NULL)
3244 {
3245 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
3246 return(TRUE);
3247 }
3248 else
3249 {
3250 for (i = 0; i < NrCtrlHandlers; i++)
3251 {
3252 if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
3253 {
3254 NrCtrlHandlers--;
3255 memmove(CtrlHandlers + i,
3256 CtrlHandlers + i + 1,
3257 (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
3258
3259 CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(),
3260 HEAP_ZERO_MEMORY,
3261 (PVOID)CtrlHandlers,
3262 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
3263 return(TRUE);
3264 }
3265 }
3266 }
3267
3268 SetLastError(ERROR_INVALID_PARAMETER);
3269 return(FALSE);
3270 }
3271
3272
3273 /*
3274 * @implemented
3275 */
3276 BOOL
3277 WINAPI
3278 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
3279 BOOL Add)
3280 {
3281 BOOL Ret;
3282
3283 RtlEnterCriticalSection(&DllLock);
3284 if (Add)
3285 {
3286 Ret = AddConsoleCtrlHandler(HandlerRoutine);
3287 }
3288 else
3289 {
3290 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
3291 }
3292
3293 RtlLeaveCriticalSection(&DllLock);
3294 return(Ret);
3295 }
3296
3297
3298 /*--------------------------------------------------------------
3299 * GenerateConsoleCtrlEvent
3300 *
3301 * @implemented
3302 */
3303 BOOL
3304 WINAPI
3305 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
3306 DWORD dwProcessGroupId)
3307 {
3308 CSR_API_MESSAGE Request;
3309 ULONG CsrRequest;
3310 NTSTATUS Status;
3311
3312 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
3313 {
3314 SetLastError(ERROR_INVALID_PARAMETER);
3315 return FALSE;
3316 }
3317
3318 CsrRequest = MAKE_CSR_API(GENERATE_CTRL_EVENT, CSR_CONSOLE);
3319 Request.Data.GenerateCtrlEvent.Event = dwCtrlEvent;
3320 Request.Data.GenerateCtrlEvent.ProcessGroup = dwProcessGroupId;
3321
3322 Status = CsrClientCallServer(&Request,
3323 NULL,
3324 CsrRequest,
3325 sizeof(CSR_API_MESSAGE));
3326 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
3327 {
3328 SetLastErrorByStatus(Status);
3329 return FALSE;
3330 }
3331
3332 return TRUE;
3333 }
3334
3335
3336 /*--------------------------------------------------------------
3337 * GetConsoleTitleW
3338 *
3339 * @implemented
3340 */
3341 DWORD
3342 WINAPI
3343 GetConsoleTitleW(LPWSTR lpConsoleTitle,
3344 DWORD nSize)
3345 {
3346 PCSR_API_MESSAGE Request;
3347 ULONG CsrRequest;
3348 NTSTATUS Status;
3349
3350 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3351 0,
3352 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3353 if (Request == NULL)
3354 {
3355 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3356 return FALSE;
3357 }
3358
3359 CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
3360
3361 Status = CsrClientCallServer(Request,
3362 NULL,
3363 CsrRequest,
3364 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3365 if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status)))
3366 {
3367 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3368 SetLastErrorByStatus(Status);
3369 return 0;
3370 }
3371
3372 if (nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length)
3373 {
3374 nSize--;
3375 }
3376 else
3377 {
3378 nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
3379 }
3380 memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR));
3381 lpConsoleTitle[nSize] = L'\0';
3382
3383 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3384
3385 return nSize;
3386 }
3387
3388
3389 /*--------------------------------------------------------------
3390 * GetConsoleTitleA
3391 *
3392 * 19990306 EA
3393 *
3394 * @implemented
3395 */
3396 DWORD
3397 WINAPI
3398 GetConsoleTitleA(LPSTR lpConsoleTitle,
3399 DWORD nSize)
3400 {
3401 WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1];
3402 DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1;
3403 DWORD nWritten;
3404
3405 if (!lpConsoleTitle || !nSize) return 0;
3406 nWideTitle = GetConsoleTitleW((LPWSTR) WideTitle, nWideTitle);
3407 if (!nWideTitle) return 0;
3408
3409 if ((nWritten = WideCharToMultiByte(CP_ACP, // ANSI code page
3410 0, // performance and mapping flags
3411 (LPWSTR) WideTitle, // address of wide-character string
3412 nWideTitle, // number of characters in string
3413 lpConsoleTitle, // address of buffer for new string
3414 nSize - 1, // size of buffer
3415 NULL, // FAST
3416 NULL))) // FAST
3417 {
3418 lpConsoleTitle[nWritten] = '\0';
3419 return nWritten;
3420 }
3421
3422 return 0;
3423 }
3424
3425
3426 /*--------------------------------------------------------------
3427 * SetConsoleTitleW
3428 *
3429 * @implemented
3430 */
3431 BOOL
3432 WINAPI
3433 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
3434 {
3435 PCSR_API_MESSAGE Request;
3436 ULONG CsrRequest;
3437 NTSTATUS Status;
3438 unsigned int c;
3439
3440 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3441 max(sizeof(CSR_API_MESSAGE),
3442 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3443 min(wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3444 if (Request == NULL)
3445 {
3446 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3447 return FALSE;
3448 }
3449
3450 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3451
3452 for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++)
3453 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3454
3455 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3456 Status = CsrClientCallServer(Request,
3457 NULL,
3458 CsrRequest,
3459 max(sizeof(CSR_API_MESSAGE),
3460 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3461 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3462 {
3463 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3464 SetLastErrorByStatus(Status);
3465 return(FALSE);
3466 }
3467
3468 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3469
3470 return TRUE;
3471 }
3472
3473
3474 /*--------------------------------------------------------------
3475 * SetConsoleTitleA
3476 *
3477 * 19990204 EA Added
3478 *
3479 * @implemented
3480 */
3481 BOOL
3482 WINAPI
3483 SetConsoleTitleA(LPCSTR lpConsoleTitle)
3484 {
3485 PCSR_API_MESSAGE Request;
3486 ULONG CsrRequest;
3487 NTSTATUS Status;
3488 unsigned int c;
3489
3490 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3491 0,
3492 max(sizeof(CSR_API_MESSAGE),
3493 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3494 min(strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3495 if (Request == NULL)
3496 {
3497 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3498 return FALSE;
3499 }
3500
3501 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3502
3503 for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++)
3504 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3505
3506 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3507 Status = CsrClientCallServer(Request,
3508 NULL,
3509 CsrRequest,
3510 max(sizeof(CSR_API_MESSAGE),
3511 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3512 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3513 {
3514 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3515 SetLastErrorByStatus(Status);
3516 return(FALSE);
3517 }
3518
3519 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3520
3521 return TRUE;
3522 }
3523
3524
3525 /*--------------------------------------------------------------
3526 * CreateConsoleScreenBuffer
3527 *
3528 * @implemented
3529 */
3530 HANDLE
3531 WINAPI
3532 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
3533 DWORD dwShareMode,
3534 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3535 DWORD dwFlags,
3536 LPVOID lpScreenBufferData)
3537 {
3538 CSR_API_MESSAGE Request;
3539 ULONG CsrRequest;
3540 NTSTATUS Status;
3541
3542 if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)
3543 || dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)
3544 || dwFlags != CONSOLE_TEXTMODE_BUFFER)
3545 {
3546 SetLastError(ERROR_INVALID_PARAMETER);
3547 return INVALID_HANDLE_VALUE;
3548 }
3549
3550 Request.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
3551 Request.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
3552 Request.Data.CreateScreenBufferRequest.Inheritable =
3553 lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE;
3554
3555 CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
3556 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3557 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3558 {
3559 SetLastErrorByStatus(Status);
3560 return INVALID_HANDLE_VALUE;
3561 }
3562 return Request.Data.CreateScreenBufferRequest.OutputHandle;
3563 }
3564
3565
3566 /*--------------------------------------------------------------
3567 * GetConsoleCP
3568 *
3569 * @implemented
3570 */
3571 UINT
3572 WINAPI
3573 GetConsoleCP(VOID)
3574 {
3575 CSR_API_MESSAGE Request;
3576 ULONG CsrRequest;
3577 NTSTATUS Status;
3578
3579 CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
3580 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3581 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3582 {
3583 SetLastErrorByStatus (Status);
3584 return 0;
3585 }
3586
3587 return Request.Data.GetConsoleCodePage.CodePage;
3588 }
3589
3590
3591 /*--------------------------------------------------------------
3592 * SetConsoleCP
3593 *
3594 * @implemented
3595 */
3596 BOOL
3597 WINAPI
3598 SetConsoleCP(UINT wCodePageID)
3599 {
3600 CSR_API_MESSAGE Request;
3601 ULONG CsrRequest;
3602 NTSTATUS Status;
3603
3604 CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
3605 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3606
3607 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3608 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3609 {
3610 SetLastErrorByStatus(Status);
3611 }
3612
3613 return NT_SUCCESS(Status);
3614 }
3615
3616
3617 /*--------------------------------------------------------------
3618 * GetConsoleOutputCP
3619 *
3620 * @implemented
3621 */
3622 UINT
3623 WINAPI
3624 GetConsoleOutputCP(VOID)
3625 {
3626 CSR_API_MESSAGE Request;
3627 ULONG CsrRequest;
3628 NTSTATUS Status;
3629
3630 CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3631 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3632 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3633 {
3634 SetLastErrorByStatus (Status);
3635 return 0;
3636 }
3637
3638 return Request.Data.GetConsoleOutputCodePage.CodePage;
3639 }
3640
3641
3642 /*--------------------------------------------------------------
3643 * SetConsoleOutputCP
3644 *
3645 * @implemented
3646 */
3647 BOOL
3648 WINAPI
3649 SetConsoleOutputCP(UINT wCodePageID)
3650 {
3651 CSR_API_MESSAGE Request;
3652 ULONG CsrRequest;
3653 NTSTATUS Status;
3654
3655 CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3656 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3657 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3658 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3659 {
3660 SetLastErrorByStatus(Status);
3661 }
3662
3663 return NT_SUCCESS(Status);
3664 }
3665
3666
3667 /*--------------------------------------------------------------
3668 * GetConsoleProcessList
3669 *
3670 * @implemented
3671 */
3672 DWORD
3673 WINAPI
3674 GetConsoleProcessList(LPDWORD lpdwProcessList,
3675 DWORD dwProcessCount)
3676 {
3677 PCSR_API_MESSAGE Request;
3678 ULONG CsrRequest;
3679 ULONG nProcesses;
3680 NTSTATUS Status;
3681
3682 if (lpdwProcessList == NULL || dwProcessCount == 0)
3683 {
3684 SetLastError(ERROR_INVALID_PARAMETER);
3685 return 0;
3686 }
3687
3688 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3689 0,
3690 max(sizeof(CSR_API_MESSAGE),
3691 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3692 + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
3693 if (Request == NULL)
3694 {
3695 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3696 return FALSE;
3697 }
3698
3699 CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
3700 Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
3701
3702 Status = CsrClientCallServer(Request,
3703 NULL,
3704 CsrRequest,
3705 max(sizeof(CSR_API_MESSAGE),
3706 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3707 + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
3708 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3709 {
3710 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3711 SetLastErrorByStatus (Status);
3712 nProcesses = 0;
3713 }
3714 else
3715 {
3716 nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
3717 if (dwProcessCount >= nProcesses)
3718 {
3719 memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
3720 }
3721 }
3722
3723 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3724
3725 return nProcesses;
3726 }
3727
3728
3729
3730 /*--------------------------------------------------------------
3731 * GetConsoleSelectionInfo
3732 *
3733 * @unimplemented
3734 */
3735 BOOL
3736 WINAPI
3737 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3738 {
3739 DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
3740 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3741 return FALSE;
3742 }
3743
3744
3745
3746 /*--------------------------------------------------------------
3747 * AttachConsole
3748 *
3749 * @unimplemented
3750 */
3751 BOOL
3752 WINAPI
3753 AttachConsole(DWORD dwProcessId)
3754 {
3755 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
3756 return TRUE;
3757 }
3758
3759 /*--------------------------------------------------------------
3760 * GetConsoleWindow
3761 *
3762 * @implemented
3763 */
3764 HWND
3765 WINAPI
3766 GetConsoleWindow(VOID)
3767 {
3768 CSR_API_MESSAGE Request;
3769 ULONG CsrRequest;
3770 NTSTATUS Status;
3771
3772 CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
3773 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3774 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
3775 {
3776 SetLastErrorByStatus(Status);
3777 return (HWND) NULL;
3778 }
3779
3780 return Request.Data.GetConsoleWindowRequest.WindowHandle;
3781 }
3782
3783
3784 /*--------------------------------------------------------------
3785 * SetConsoleIcon
3786 *
3787 * @implemented
3788 */
3789 BOOL
3790 WINAPI
3791 SetConsoleIcon(HICON hicon)
3792 {
3793 CSR_API_MESSAGE Request;
3794 ULONG CsrRequest;
3795 NTSTATUS Status;
3796
3797 CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
3798 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3799
3800 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3801 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3802 {
3803 SetLastErrorByStatus(Status);
3804 return FALSE;
3805 }
3806
3807 return NT_SUCCESS(Status);
3808 }
3809
3810
3811 /******************************************************************************
3812 * \name SetConsoleInputExeNameW
3813 * \brief Sets the console input file name from a unicode string.
3814 * \param lpInputExeName Pointer to a unicode string with the name.
3815 * \return TRUE if successful, FALSE if unsuccsedful.
3816 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
3817 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
3818 */
3819 BOOL
3820 WINAPI
3821 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
3822 {
3823 int lenName;
3824
3825 if (!lpInputExeName
3826 || (lenName = lstrlenW(lpInputExeName)) == 0
3827 || lenName > INPUTEXENAME_BUFLEN - 1)
3828 {
3829 /* Fail if string is empty or too long */
3830 SetLastError(ERROR_INVALID_PARAMETER);
3831 return FALSE;
3832 }
3833
3834 RtlEnterCriticalSection(&ConsoleLock);
3835 _SEH2_TRY
3836 {
3837 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
3838 InputExeName[lenName] = L'\0';
3839 }
3840 _SEH2_FINALLY
3841 {
3842 RtlLeaveCriticalSection(&ConsoleLock);
3843 }
3844 _SEH2_END;
3845
3846 return TRUE;
3847 }
3848
3849
3850 /******************************************************************************
3851 * \name SetConsoleInputExeNameA
3852 * \brief Sets the console input file name from an ansi string.
3853 * \param lpInputExeName Pointer to an ansi string with the name.
3854 * \return TRUE if successful, FALSE if unsuccsedful.
3855 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
3856 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
3857 */
3858 BOOL
3859 WINAPI
3860 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
3861 {
3862 WCHAR Buffer[INPUTEXENAME_BUFLEN];
3863 ANSI_STRING InputExeNameA;
3864 UNICODE_STRING InputExeNameU;
3865 NTSTATUS Status;
3866 BOOL Ret;
3867
3868 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
3869
3870 if(InputExeNameA.Length == 0 ||
3871 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
3872 {
3873 /* Fail if string is empty or too long */
3874 SetLastError(ERROR_INVALID_PARAMETER);
3875 return FALSE;
3876 }
3877
3878 InputExeNameU.Buffer = Buffer;
3879 InputExeNameU.MaximumLength = sizeof(Buffer);
3880 InputExeNameU.Length = 0;
3881 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
3882 if(NT_SUCCESS(Status))
3883 {
3884 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
3885 }
3886 else
3887 {
3888 SetLastErrorByStatus(Status);
3889 Ret = FALSE;
3890 }
3891
3892 return Ret;
3893 }
3894
3895
3896 /******************************************************************************
3897 * \name GetConsoleInputExeNameW
3898 * \brief Retrieves the console input file name as unicode string.
3899 * \param nBufferLength Length of the buffer in WCHARs.
3900 * Specify 0 to recieve the needed buffer length.
3901 * \param lpBuffer Pointer to a buffer that recieves the string.
3902 * \return Needed buffer size if \p nBufferLength is 0.
3903 * Otherwise 1 if successful, 2 if buffer is too small.
3904 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
3905 * is not big enough.
3906 */
3907 DWORD
3908 WINAPI
3909 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
3910 {
3911 int lenName = lstrlenW(InputExeName);
3912
3913 if (nBufferLength == 0)
3914 {
3915 /* Buffer size is requested, return it */
3916 return lenName + 1;
3917 }
3918
3919 if(lenName + 1 > nBufferLength)
3920 {
3921 /* Buffer is not large enough! */
3922 SetLastError(ERROR_BUFFER_OVERFLOW);
3923 return 2;
3924 }
3925
3926 RtlEnterCriticalSection(&ConsoleLock);
3927 _SEH2_TRY
3928 {
3929 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
3930 lpBuffer[lenName] = '\0';
3931 }
3932 _SEH2_FINALLY
3933 {
3934 RtlLeaveCriticalSection(&ConsoleLock);
3935 }
3936 _SEH2_END;
3937
3938 /* Success, return 1 */
3939 return 1;
3940 }
3941
3942
3943 /******************************************************************************
3944 * \name GetConsoleInputExeNameA
3945 * \brief Retrieves the console input file name as ansi string.
3946 * \param nBufferLength Length of the buffer in CHARs.
3947 * \param lpBuffer Pointer to a buffer that recieves the string.
3948 * \return 1 if successful, 2 if buffer is too small.
3949 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
3950 * is not big enough. The buffer recieves as much characters as fit.
3951 */
3952 DWORD
3953 WINAPI
3954 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
3955 {
3956 WCHAR Buffer[INPUTEXENAME_BUFLEN];
3957 DWORD Ret;
3958 UNICODE_STRING BufferU;
3959 ANSI_STRING BufferA;
3960
3961 /* Get the unicode name */
3962 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
3963
3964 /* Initialize strings for conversion */
3965 RtlInitUnicodeString(&BufferU, Buffer);
3966 BufferA.Length = 0;
3967 BufferA.MaximumLength = nBufferLength;
3968 BufferA.Buffer = lpBuffer;
3969
3970 /* Convert unicode name to ansi, copying as much chars as fit */
3971 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
3972
3973 /* Error handling */
3974 if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
3975 {
3976 SetLastError(ERROR_BUFFER_OVERFLOW);
3977 return 2;
3978 }
3979
3980 return Ret;
3981 }
3982
3983
3984 /*--------------------------------------------------------------
3985 * GetConsoleHistoryInfo
3986 *
3987 * @unimplemented
3988 */
3989 BOOL
3990 WINAPI
3991 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
3992 {
3993 DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
3994 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3995 return FALSE;
3996 }
3997
3998
3999 /*--------------------------------------------------------------
4000 * SetConsoleHistoryInfo
4001 *
4002 * @unimplemented
4003 */
4004 BOOL
4005 WINAPI
4006 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
4007 {
4008 DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
4009 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4010 return FALSE;
4011 }
4012
4013
4014 /*--------------------------------------------------------------
4015 * GetConsoleOriginalTitleW
4016 *
4017 * @unimplemented
4018 */
4019 DWORD
4020 WINAPI
4021 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
4022 IN DWORD nSize)
4023 {
4024 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4025 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4026 return 0;
4027 }
4028
4029
4030 /*--------------------------------------------------------------
4031 * GetConsoleOriginalTitleA
4032 *
4033 * @unimplemented
4034 */
4035 DWORD
4036 WINAPI
4037 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
4038 IN DWORD nSize)
4039 {
4040 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4041 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4042 return 0;
4043 }
4044
4045
4046 /*--------------------------------------------------------------
4047 * GetConsoleScreenBufferInfoEx
4048 *
4049 * @unimplemented
4050 */
4051 BOOL
4052 WINAPI
4053 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4054 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4055 {
4056 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4057 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4058 return FALSE;
4059 }
4060
4061
4062 /*--------------------------------------------------------------
4063 * SetConsoleScreenBufferInfoEx
4064 *
4065 * @unimplemented
4066 */
4067 BOOL
4068 WINAPI
4069 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4070 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4071 {
4072 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4073 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4074 return FALSE;
4075 }
4076
4077
4078 /*--------------------------------------------------------------
4079 * GetCurrentConsoleFontEx
4080 *
4081 * @unimplemented
4082 */
4083 BOOL
4084 WINAPI
4085 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
4086 IN BOOL bMaximumWindow,
4087 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
4088 {
4089 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
4090 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4091 return FALSE;
4092 }
4093
4094 /* EOF */