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