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