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