ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

console.c
Go to the documentation of this file.
00001 /* $Id: console.c 55081 2012-01-22 22:27:08Z gadamopoulos $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            dll/win32/kernel32/misc/console.c
00006  * PURPOSE:         Win32 server console functions
00007  * PROGRAMMER:      James Tabor
00008  *            <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
00009  * UPDATE HISTORY:
00010  *    199901?? ??    Created
00011  *    19990204 EA    SetConsoleTitleA
00012  *      19990306 EA    Stubs
00013  */
00014 
00015 /* INCLUDES ******************************************************************/
00016 
00017 #include <k32.h>
00018 
00019 #define NDEBUG
00020 #include <debug.h>
00021 
00022 extern RTL_CRITICAL_SECTION ConsoleLock;
00023 extern BOOL ConsoleInitialized;
00024 extern BOOL WINAPI IsDebuggerPresent(VOID);
00025 
00026 /* GLOBALS *******************************************************************/
00027 
00028 PHANDLER_ROUTINE InitialHandler[1];
00029 PHANDLER_ROUTINE* CtrlHandlers;
00030 ULONG NrCtrlHandlers;
00031 ULONG NrAllocatedHandlers;
00032 
00033 #define INPUTEXENAME_BUFLEN 256
00034 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
00035 
00036 /* Default Console Control Handler *******************************************/
00037 
00038 BOOL
00039 WINAPI
00040 DefaultConsoleCtrlHandler(DWORD Event)
00041 {
00042     DPRINT("Default handler called: %lx\n", Event);
00043     switch(Event)
00044     {
00045         case CTRL_C_EVENT:
00046             DPRINT("Ctrl-C Event\n");
00047             break;
00048 
00049         case CTRL_BREAK_EVENT:
00050             DPRINT("Ctrl-Break Event\n");
00051             break;
00052 
00053         case CTRL_SHUTDOWN_EVENT:
00054             DPRINT("Ctrl Shutdown Event\n");
00055             break;
00056 
00057         case CTRL_CLOSE_EVENT:
00058             DPRINT("Ctrl Close Event\n");
00059             break;
00060 
00061         case CTRL_LOGOFF_EVENT:
00062             DPRINT("Ctrl Logoff Event\n");
00063             break;
00064     }
00065 
00066     ExitProcess(CONTROL_C_EXIT);
00067     return TRUE;
00068 }
00069 
00070 __declspec(noreturn)
00071 VOID
00072 CALLBACK
00073 ConsoleControlDispatcher(DWORD CodeAndFlag)
00074 {
00075     DWORD nExitCode = 0;
00076     DWORD nCode = CodeAndFlag & MAXLONG;
00077     UINT i;
00078     EXCEPTION_RECORD erException;
00079     
00080     DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
00081     SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
00082 
00083     switch(nCode)
00084     {
00085         case CTRL_C_EVENT:
00086         case CTRL_BREAK_EVENT:
00087         {
00088             if (IsDebuggerPresent())
00089             {
00090                 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
00091                                              DBG_CONTROL_C : DBG_CONTROL_BREAK);
00092                 erException.ExceptionFlags = 0;
00093                 erException.ExceptionRecord = NULL;
00094                 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
00095                 erException.NumberParameters = 0;
00096                 
00097                 _SEH2_TRY
00098                 {
00099                     RtlRaiseException(&erException);
00100                 }
00101                 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00102                 {
00103                     RtlEnterCriticalSection(&ConsoleLock);
00104                     
00105                     if ((nCode != CTRL_C_EVENT) ||
00106                         (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
00107                     {
00108                         for (i = NrCtrlHandlers; i > 0; i--)
00109                         {
00110                             if (CtrlHandlers[i - 1](nCode)) break;
00111                         }
00112                     }
00113                     
00114                     RtlLeaveCriticalSection(&ConsoleLock);
00115                 }
00116                 _SEH2_END;
00117                 
00118                 ExitThread(0);
00119             }
00120             
00121             break;
00122         }
00123 
00124         case CTRL_CLOSE_EVENT:
00125         case CTRL_LOGOFF_EVENT:
00126         case CTRL_SHUTDOWN_EVENT:
00127             break;
00128             
00129         case 3:
00130         
00131             ExitThread(0);
00132             break;
00133         
00134         case 4:
00135         
00136             ExitProcess(CONTROL_C_EXIT);
00137             break;
00138 
00139         default:
00140         
00141             ASSERT(FALSE);
00142             break;
00143     }
00144     
00145     ASSERT(ConsoleInitialized);
00146     
00147     RtlEnterCriticalSection(&ConsoleLock);
00148     nExitCode = 0;
00149     if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
00150     {
00151         for (i = NrCtrlHandlers; i > 0; i--)
00152         {
00153             if ((i == 1) &&
00154                 (CodeAndFlag & MINLONG) &&
00155                 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
00156             {
00157                 DPRINT("Skipping system/service apps\n");
00158                 break;
00159             }
00160 
00161             if (CtrlHandlers[i - 1](nCode))
00162             {
00163                 switch(nCode)
00164                 {
00165                     case CTRL_CLOSE_EVENT:
00166                     case CTRL_LOGOFF_EVENT:
00167                     case CTRL_SHUTDOWN_EVENT:
00168                     case 3:
00169                         nExitCode = CodeAndFlag;
00170                         break;
00171                 }
00172                 break;
00173             }
00174         }
00175     }
00176     
00177     RtlLeaveCriticalSection(&ConsoleLock);
00178     ExitThread(nExitCode);
00179 }
00180 
00181 /* Get the size needed to copy a string to a capture buffer, including alignment */
00182 static ULONG
00183 IntStringSize(LPCVOID String,
00184               BOOL Unicode)
00185 {
00186     ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
00187     return (Size + 3) & -4;
00188 }
00189 
00190 /* Copy a string to a capture buffer */
00191 static VOID
00192 IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
00193                         LPCVOID String,
00194                         BOOL Unicode,
00195                         PUNICODE_STRING RequestString)
00196 {
00197     ULONG Size;
00198     if (Unicode)
00199     {
00200         Size = wcslen(String) * sizeof(WCHAR);
00201         CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer);
00202     }
00203     else
00204     {
00205         Size = strlen(String);
00206         CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer);
00207         Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR))
00208                * sizeof(WCHAR);
00209     }
00210     RequestString->Length = RequestString->MaximumLength = Size;
00211 }
00212 
00213 /* FUNCTIONS *****************************************************************/
00214 
00215 /*
00216  * @implemented
00217  */
00218 BOOL
00219 WINAPI
00220 AddConsoleAliasA(LPCSTR lpSource,
00221                  LPCSTR lpTarget,
00222                  LPCSTR lpExeName)
00223 {
00224     LPWSTR lpSourceW = NULL;
00225     LPWSTR lpTargetW = NULL;
00226     LPWSTR lpExeNameW = NULL;
00227     BOOL bRetVal;
00228 
00229     if (lpSource)
00230         BasepAnsiStringToHeapUnicodeString(lpSource, (LPWSTR*) &lpSourceW);
00231     if (lpTarget)
00232         BasepAnsiStringToHeapUnicodeString(lpTarget, (LPWSTR*) &lpTargetW);
00233     if (lpExeName)
00234         BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
00235 
00236     bRetVal = AddConsoleAliasW(lpSourceW, lpTargetW, lpExeNameW);
00237 
00238     /* Clean up */
00239     if (lpSourceW)
00240         RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpSourceW);
00241     if (lpTargetW)
00242         RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpTargetW);
00243     if (lpExeNameW)
00244         RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
00245 
00246     return bRetVal;
00247 }
00248 
00249 
00250 /*
00251  * @unimplemented
00252  */
00253 BOOL
00254 WINAPI
00255 AddConsoleAliasW(LPCWSTR lpSource,
00256                  LPCWSTR lpTarget,
00257                  LPCWSTR lpExeName)
00258 {
00259     PCSR_API_MESSAGE Request;
00260     ULONG CsrRequest;
00261     NTSTATUS Status;
00262     ULONG SourceLength;
00263     ULONG TargetLength = 0;
00264     ULONG ExeLength;
00265     ULONG Size;
00266     ULONG RequestLength;
00267     WCHAR * Ptr;
00268 
00269     DPRINT("AddConsoleAliasW enterd with lpSource %S lpTarget %S lpExeName %S\n", lpSource, lpTarget, lpExeName);
00270 
00271     ExeLength = wcslen(lpExeName) + 1;
00272     SourceLength = wcslen(lpSource)+ 1;
00273     if (lpTarget)
00274         TargetLength = wcslen(lpTarget) + 1;
00275 
00276     Size = (ExeLength + SourceLength + TargetLength) * sizeof(WCHAR);
00277     RequestLength = sizeof(CSR_API_MESSAGE) + Size;
00278 
00279     Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RequestLength);
00280     Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE));
00281 
00282     wcscpy(Ptr, lpSource);
00283     Request->Data.AddConsoleAlias.SourceLength = SourceLength;
00284     Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + SourceLength * sizeof(WCHAR));
00285 
00286     wcscpy(Ptr, lpExeName);
00287     Request->Data.AddConsoleAlias.ExeLength = ExeLength;
00288     Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + (ExeLength + SourceLength)* sizeof(WCHAR));
00289 
00290     if (lpTarget) /* target can be optional */
00291         wcscpy(Ptr, lpTarget);
00292 
00293     Request->Data.AddConsoleAlias.TargetLength = TargetLength;
00294 
00295     CsrRequest = MAKE_CSR_API(ADD_CONSOLE_ALIAS, CSR_CONSOLE);
00296     Status = CsrClientCallServer(Request,
00297                                  NULL,
00298                                  CsrRequest,
00299                                  RequestLength);
00300 
00301     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
00302     {
00303         BaseSetLastNTError(Status);
00304         RtlFreeHeap(GetProcessHeap(), 0, Request);
00305         return FALSE;
00306     }
00307 
00308     RtlFreeHeap(GetProcessHeap(), 0, Request);
00309     return TRUE;
00310 }
00311 
00312 
00313 /*
00314  * @unimplemented (Undocumented)
00315  */
00316 BOOL
00317 WINAPI
00318 ConsoleMenuControl(HANDLE hConsole,
00319                    DWORD Unknown1,
00320                    DWORD Unknown2)
00321 {
00322     DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
00323     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00324     return FALSE;
00325 }
00326 
00327 
00328 /*
00329  * @implemented
00330  */
00331 HANDLE
00332 WINAPI
00333 DuplicateConsoleHandle(HANDLE hConsole,
00334                        DWORD dwDesiredAccess,
00335                        BOOL bInheritHandle,
00336                        DWORD dwOptions)
00337 {
00338     CSR_API_MESSAGE Request;
00339     ULONG CsrRequest;
00340     NTSTATUS Status;
00341 
00342     if (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
00343         || (!(dwOptions & DUPLICATE_SAME_ACCESS)
00344         && dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)))
00345     {
00346         SetLastError (ERROR_INVALID_PARAMETER);
00347         return INVALID_HANDLE_VALUE;
00348     }
00349 
00350     CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
00351     Request.Data.DuplicateHandleRequest.Handle = hConsole;
00352     Request.Data.DuplicateHandleRequest.Access = dwDesiredAccess;
00353     Request.Data.DuplicateHandleRequest.Inheritable = bInheritHandle;
00354     Request.Data.DuplicateHandleRequest.Options = dwOptions;
00355 
00356     Status = CsrClientCallServer(&Request,
00357                                  NULL,
00358                                  CsrRequest,
00359                                  sizeof(CSR_API_MESSAGE));
00360     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
00361     {
00362         BaseSetLastNTError(Status);
00363         return INVALID_HANDLE_VALUE;
00364     }
00365 
00366     return Request.Data.DuplicateHandleRequest.Handle;
00367 }
00368 
00369 
00370 static BOOL
00371 IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode)
00372 {
00373     CSR_API_MESSAGE Request;
00374     PCSR_CAPTURE_BUFFER CaptureBuffer;
00375     ULONG CsrRequest = MAKE_CSR_API(EXPUNGE_COMMAND_HISTORY, CSR_CONSOLE);
00376     NTSTATUS Status;
00377 
00378     if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
00379     {
00380         SetLastError(ERROR_INVALID_PARAMETER);
00381         return FALSE;
00382     }
00383 
00384     CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
00385     if (!CaptureBuffer)
00386     {
00387         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
00388         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00389         return FALSE;
00390     }
00391     IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
00392                             &Request.Data.ExpungeCommandHistory.ExeName);
00393     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
00394     CsrFreeCaptureBuffer(CaptureBuffer);
00395     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00396     {
00397         BaseSetLastNTError(Status);
00398         return FALSE;
00399     }
00400     return TRUE;
00401 }
00402 
00403 /*
00404  * @implemented (Undocumented)
00405  */
00406 BOOL
00407 WINAPI
00408 ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName)
00409 {
00410     return IntExpungeConsoleCommandHistory(lpExeName, TRUE);
00411 }
00412 
00413 /*
00414  * @implemented (Undocumented)
00415  */
00416 BOOL
00417 WINAPI
00418 ExpungeConsoleCommandHistoryA(LPCSTR lpExeName)
00419 {
00420     return IntExpungeConsoleCommandHistory(lpExeName, FALSE);
00421 }
00422 
00423 
00424 /*
00425  * @implemented
00426  */
00427 DWORD
00428 WINAPI
00429 GetConsoleAliasW(LPWSTR lpSource,
00430                  LPWSTR lpTargetBuffer,
00431                  DWORD TargetBufferLength,
00432                  LPWSTR lpExeName)
00433 {
00434     PCSR_API_MESSAGE Request;
00435     PCSR_CAPTURE_BUFFER CaptureBuffer;
00436     ULONG CsrRequest;
00437     NTSTATUS Status;
00438     ULONG Size;
00439     ULONG ExeLength;
00440     ULONG SourceLength;
00441     ULONG RequestLength;
00442     WCHAR * Ptr;
00443 
00444     DPRINT("GetConsoleAliasW entered lpSource %S lpExeName %S\n", lpSource, lpExeName);
00445 
00446     if (lpTargetBuffer == NULL)
00447     {
00448         SetLastError(ERROR_INVALID_PARAMETER);
00449         return 0;
00450     }
00451 
00452     CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIAS, CSR_CONSOLE);
00453 
00454     ExeLength = wcslen(lpExeName) + 1;
00455     SourceLength = wcslen(lpSource) + 1;
00456 
00457     Size = (ExeLength + SourceLength) * sizeof(WCHAR);
00458 
00459     RequestLength = Size + sizeof(CSR_API_MESSAGE);
00460     Request = RtlAllocateHeap(GetProcessHeap(), 0, RequestLength);
00461     if (Request == NULL)
00462     {
00463         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00464         return 0;
00465     }
00466 
00467     CaptureBuffer = CsrAllocateCaptureBuffer(1, TargetBufferLength);
00468     if (!CaptureBuffer)
00469     {
00470         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
00471         RtlFreeHeap(GetProcessHeap(), 0, Request);
00472         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00473         return 0;
00474     }
00475 
00476     Request->Data.GetConsoleAlias.TargetBuffer = NULL;
00477 
00478     CsrCaptureMessageBuffer(CaptureBuffer,
00479                             NULL,
00480                             TargetBufferLength,
00481                             (PVOID*)&Request->Data.GetConsoleAlias.TargetBuffer);
00482 
00483     Request->Data.GetConsoleAlias.TargetBufferLength = TargetBufferLength;
00484 
00485     Ptr = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
00486     wcscpy(Ptr, lpSource);
00487     Ptr += SourceLength;
00488     wcscpy(Ptr, lpExeName);
00489 
00490     Request->Data.GetConsoleAlias.ExeLength = ExeLength;
00491     Request->Data.GetConsoleAlias.SourceLength = SourceLength;
00492 
00493     Status = CsrClientCallServer(Request,
00494                                  CaptureBuffer,
00495                                  CsrRequest,
00496                                  sizeof(CSR_API_MESSAGE) + Size);
00497 
00498     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
00499     {
00500         RtlFreeHeap(GetProcessHeap(), 0, Request);
00501         CsrFreeCaptureBuffer(CaptureBuffer);
00502         BaseSetLastNTError(Status);
00503         return 0;
00504     }
00505 
00506     wcscpy(lpTargetBuffer, Request->Data.GetConsoleAlias.TargetBuffer);
00507     RtlFreeHeap(GetProcessHeap(), 0, Request);
00508     CsrFreeCaptureBuffer(CaptureBuffer);
00509 
00510     return Request->Data.GetConsoleAlias.BytesWritten;
00511 }
00512 
00513 
00514 /*
00515  * @implemented
00516  */
00517 DWORD
00518 WINAPI
00519 GetConsoleAliasA(LPSTR lpSource,
00520                  LPSTR lpTargetBuffer,
00521                  DWORD TargetBufferLength,
00522                  LPSTR lpExeName)
00523 {
00524     LPWSTR lpwSource;
00525     LPWSTR lpwExeName;
00526     LPWSTR lpwTargetBuffer;
00527     UINT dwSourceSize;
00528     UINT dwExeNameSize;
00529     UINT dwResult;
00530 
00531     DPRINT("GetConsoleAliasA entered\n");
00532 
00533     if (lpTargetBuffer == NULL)
00534     {
00535         SetLastError(ERROR_INVALID_PARAMETER);
00536         return 0;
00537     }
00538 
00539     dwSourceSize = (strlen(lpSource)+1) * sizeof(WCHAR);
00540     lpwSource = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceSize);
00541     if (lpwSource == NULL)
00542     {
00543         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00544         return 0;
00545     }
00546     MultiByteToWideChar(CP_ACP, 0, lpSource, -1, lpwSource, dwSourceSize);
00547 
00548     dwExeNameSize = (strlen(lpExeName)+1) * sizeof(WCHAR);
00549     lpwExeName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwExeNameSize);
00550     if (lpwExeName == NULL)
00551     {
00552         HeapFree(GetProcessHeap(), 0, lpwSource);
00553         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00554         return 0;
00555     }
00556     MultiByteToWideChar(CP_ACP, 0, lpExeName, -1, lpwExeName, dwExeNameSize);
00557 
00558     lpwTargetBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, TargetBufferLength * sizeof(WCHAR));
00559     if (lpwTargetBuffer == NULL)
00560     {
00561         HeapFree(GetProcessHeap(), 0, lpwSource);
00562         HeapFree(GetProcessHeap(), 0, lpwExeName);
00563         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00564         return 0;
00565     }
00566 
00567     dwResult = GetConsoleAliasW(lpwSource, lpwTargetBuffer, TargetBufferLength * sizeof(WCHAR), lpwExeName);
00568 
00569     HeapFree(GetProcessHeap(), 0, lpwSource);
00570     HeapFree(GetProcessHeap(), 0, lpwExeName);
00571 
00572     if (dwResult)
00573         dwResult = WideCharToMultiByte(CP_ACP, 0, lpwTargetBuffer, dwResult / sizeof(WCHAR), lpTargetBuffer, TargetBufferLength, NULL, NULL);
00574 
00575     HeapFree(GetProcessHeap(), 0, lpwTargetBuffer);
00576 
00577     return dwResult;
00578 }
00579 
00580 
00581 /*
00582  * @implemented
00583  */
00584 DWORD
00585 WINAPI
00586 GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
00587                      DWORD ExeNameBufferLength)
00588 {
00589     CSR_API_MESSAGE Request;
00590     PCSR_CAPTURE_BUFFER CaptureBuffer;
00591     ULONG CsrRequest;
00592     NTSTATUS Status;
00593 
00594     DPRINT("GetConsoleAliasExesW entered\n");
00595 
00596     CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
00597     if (!CaptureBuffer)
00598     {
00599         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
00600         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00601         return 0;
00602     }
00603 
00604     CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES, CSR_CONSOLE);
00605     CsrAllocateMessagePointer(CaptureBuffer,
00606                               ExeNameBufferLength,
00607                               (PVOID*)&Request.Data.GetConsoleAliasesExes.ExeNames);
00608     Request.Data.GetConsoleAliasesExes.Length = ExeNameBufferLength;
00609 
00610     Status = CsrClientCallServer(&Request,
00611                                  CaptureBuffer,
00612                                  CsrRequest,
00613                                  sizeof(CSR_API_MESSAGE));
00614 
00615     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00616     {
00617         BaseSetLastNTError(Status);
00618         CsrFreeCaptureBuffer(CaptureBuffer);
00619         return 0;
00620     }
00621 
00622     memcpy(lpExeNameBuffer,
00623            Request.Data.GetConsoleAliasesExes.ExeNames,
00624            Request.Data.GetConsoleAliasesExes.BytesWritten);
00625 
00626     CsrFreeCaptureBuffer(CaptureBuffer);
00627     return Request.Data.GetConsoleAliasesExes.BytesWritten;
00628 }
00629 
00630 
00631 /*
00632  * @implemented
00633  */
00634 DWORD
00635 WINAPI
00636 GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
00637                      DWORD ExeNameBufferLength)
00638 {
00639     LPWSTR lpwExeNameBuffer;
00640     DWORD dwResult;
00641 
00642     DPRINT("GetConsoleAliasExesA entered\n");
00643 
00644     lpwExeNameBuffer = HeapAlloc(GetProcessHeap(), 0, ExeNameBufferLength * sizeof(WCHAR));
00645 
00646     dwResult = GetConsoleAliasExesW(lpwExeNameBuffer, ExeNameBufferLength * sizeof(WCHAR));
00647 
00648     if (dwResult)
00649         dwResult = WideCharToMultiByte(CP_ACP, 0, lpwExeNameBuffer, dwResult / sizeof(WCHAR), lpExeNameBuffer, ExeNameBufferLength, NULL, NULL);
00650 
00651     HeapFree(GetProcessHeap(), 0, lpwExeNameBuffer);
00652     return dwResult;
00653 }
00654 
00655 /*
00656  * @implemented
00657  */
00658 DWORD
00659 WINAPI
00660 GetConsoleAliasExesLengthW(VOID)
00661 {
00662     CSR_API_MESSAGE Request;
00663     ULONG CsrRequest;
00664     NTSTATUS Status;
00665 
00666     DPRINT("GetConsoleAliasExesLengthW entered\n");
00667 
00668     CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CSR_CONSOLE);
00669     Request.Data.GetConsoleAliasesExesLength.Length = 0;
00670 
00671 
00672     Status = CsrClientCallServer(&Request,
00673                                  NULL,
00674                                  CsrRequest,
00675                                  sizeof(CSR_API_MESSAGE));
00676 
00677     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00678     {
00679         BaseSetLastNTError(Status);
00680         return 0;
00681     }
00682 
00683     return Request.Data.GetConsoleAliasesExesLength.Length;
00684 }
00685 
00686 /*
00687  * @implemented
00688  */
00689 DWORD
00690 WINAPI
00691 GetConsoleAliasExesLengthA(VOID)
00692 {
00693     DWORD dwLength;
00694 
00695     DPRINT("GetConsoleAliasExesLengthA entered\n");
00696 
00697     dwLength = GetConsoleAliasExesLengthW();
00698 
00699     if (dwLength)
00700         dwLength /= sizeof(WCHAR);
00701 
00702     return dwLength;
00703 }
00704 
00705 
00706 /*
00707  * @implemented
00708  */
00709 DWORD
00710 WINAPI
00711 GetConsoleAliasesW(LPWSTR AliasBuffer,
00712                    DWORD AliasBufferLength,
00713                    LPWSTR ExeName)
00714 {
00715     CSR_API_MESSAGE Request;
00716     ULONG CsrRequest;
00717     NTSTATUS Status;
00718     DWORD dwLength;
00719 
00720     DPRINT("GetConsoleAliasesW entered\n");
00721 
00722     dwLength = GetConsoleAliasesLengthW(ExeName);
00723     if (!dwLength || dwLength > AliasBufferLength)
00724         return 0;
00725 
00726     CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES, CSR_CONSOLE);
00727     Request.Data.GetAllConsoleAlias.AliasBuffer = AliasBuffer;
00728     Request.Data.GetAllConsoleAlias.AliasBufferLength = AliasBufferLength;
00729     Request.Data.GetAllConsoleAlias.lpExeName = ExeName;
00730 
00731     Status = CsrClientCallServer(&Request,
00732                                  NULL,
00733                                  CsrRequest,
00734                                  sizeof(CSR_API_MESSAGE));
00735 
00736     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00737     {
00738         BaseSetLastNTError(Status);
00739         return 0;
00740     }
00741 
00742     return Request.Data.GetAllConsoleAlias.BytesWritten / sizeof(WCHAR);
00743 }
00744 
00745 
00746 /*
00747  * @implemented
00748  */
00749 DWORD
00750 WINAPI
00751 GetConsoleAliasesA(LPSTR AliasBuffer,
00752                    DWORD AliasBufferLength,
00753                    LPSTR ExeName)
00754 {
00755     DWORD dwRetVal = 0;
00756     LPWSTR lpwExeName = NULL;
00757     LPWSTR lpwAliasBuffer;
00758 
00759     DPRINT("GetConsoleAliasesA entered\n");
00760 
00761     if (ExeName)
00762         BasepAnsiStringToHeapUnicodeString(ExeName, (LPWSTR*) &lpwExeName);
00763 
00764     lpwAliasBuffer = HeapAlloc(GetProcessHeap(), 0, AliasBufferLength * sizeof(WCHAR));
00765 
00766     dwRetVal = GetConsoleAliasesW(lpwAliasBuffer, AliasBufferLength, lpwExeName);
00767 
00768     if (lpwExeName)
00769         RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpwExeName);
00770 
00771     if (dwRetVal)
00772         dwRetVal = WideCharToMultiByte(CP_ACP, 0, lpwAliasBuffer, dwRetVal, AliasBuffer, AliasBufferLength, NULL, NULL);
00773 
00774     HeapFree(GetProcessHeap(), 0, lpwAliasBuffer);
00775     return dwRetVal;
00776 }
00777 
00778 
00779 /*
00780  * @implemented
00781  */
00782 DWORD
00783 WINAPI
00784 GetConsoleAliasesLengthW(LPWSTR lpExeName)
00785 {
00786     CSR_API_MESSAGE Request;
00787     ULONG CsrRequest;
00788     NTSTATUS Status;
00789 
00790     DPRINT("GetConsoleAliasesLengthW entered\n");
00791 
00792     CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CSR_CONSOLE);
00793     Request.Data.GetAllConsoleAliasesLength.lpExeName = lpExeName;
00794     Request.Data.GetAllConsoleAliasesLength.Length = 0;
00795 
00796     Status = CsrClientCallServer(&Request,
00797                                  NULL,
00798                                  CsrRequest,
00799                                  sizeof(CSR_API_MESSAGE));
00800 
00801     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00802     {
00803         BaseSetLastNTError(Status);
00804         return 0;
00805     }
00806 
00807     return Request.Data.GetAllConsoleAliasesLength.Length;
00808 }
00809 
00810 
00811 /*
00812  * @implemented
00813  */
00814 DWORD
00815 WINAPI
00816 GetConsoleAliasesLengthA(LPSTR lpExeName)
00817 {
00818     DWORD dwRetVal = 0;
00819     LPWSTR lpExeNameW = NULL;
00820 
00821     if (lpExeName)
00822         BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
00823 
00824     dwRetVal = GetConsoleAliasesLengthW(lpExeNameW);
00825     if (dwRetVal)
00826         dwRetVal /= sizeof(WCHAR);
00827 
00828     /* Clean up */
00829     if (lpExeNameW)
00830         RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
00831 
00832     return dwRetVal;
00833 }
00834 
00835 
00836 static DWORD
00837 IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode)
00838 {
00839     CSR_API_MESSAGE Request;
00840     PCSR_CAPTURE_BUFFER CaptureBuffer;
00841     ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY, CSR_CONSOLE);
00842     NTSTATUS Status;
00843     DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR));
00844 
00845     if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
00846     {
00847         SetLastError(ERROR_INVALID_PARAMETER);
00848         return 0;
00849     }
00850 
00851     CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
00852                                                 HistoryLength);
00853     if (!CaptureBuffer)
00854     {
00855         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
00856         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00857         return 0;
00858     }
00859     IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
00860                             &Request.Data.GetCommandHistory.ExeName);
00861     Request.Data.GetCommandHistory.Length = HistoryLength;
00862     CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
00863                               (PVOID*)&Request.Data.GetCommandHistory.History);
00864 
00865     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
00866     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00867     {
00868         CsrFreeCaptureBuffer(CaptureBuffer);
00869         BaseSetLastNTError(Status);
00870         return 0;
00871     }
00872 
00873     if (bUnicode)
00874     {
00875         memcpy(lpHistory,
00876                Request.Data.GetCommandHistory.History,
00877                Request.Data.GetCommandHistory.Length);
00878     }
00879     else
00880     {
00881         WideCharToMultiByte(CP_ACP, 0,
00882                             Request.Data.GetCommandHistory.History,
00883                             Request.Data.GetCommandHistory.Length / sizeof(WCHAR),
00884                             lpHistory,
00885                             cbHistory,
00886                             NULL, NULL);
00887     }
00888     CsrFreeCaptureBuffer(CaptureBuffer);
00889     return Request.Data.GetCommandHistory.Length;
00890 }
00891 
00892 /*
00893  * @implemented (Undocumented)
00894  */
00895 DWORD
00896 WINAPI
00897 GetConsoleCommandHistoryW(LPWSTR lpHistory,
00898                           DWORD cbHistory,
00899                           LPCWSTR lpExeName)
00900 {
00901     return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE);
00902 }
00903 
00904 /*
00905  * @implemented (Undocumented)
00906  */
00907 DWORD
00908 WINAPI
00909 GetConsoleCommandHistoryA(LPSTR lpHistory,
00910                           DWORD cbHistory,
00911                           LPCSTR lpExeName)
00912 {
00913     return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE);
00914 }
00915 
00916 
00917 static DWORD
00918 IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
00919 {
00920     CSR_API_MESSAGE Request;
00921     PCSR_CAPTURE_BUFFER CaptureBuffer;
00922     ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY_LENGTH, CSR_CONSOLE);
00923     NTSTATUS Status;
00924 
00925     if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
00926     {
00927         SetLastError(ERROR_INVALID_PARAMETER);
00928         return 0;
00929     }
00930 
00931     CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
00932     if (!CaptureBuffer)
00933     {
00934         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
00935         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
00936         return 0;
00937     }
00938     IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
00939                             &Request.Data.GetCommandHistoryLength.ExeName);
00940     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
00941     CsrFreeCaptureBuffer(CaptureBuffer);
00942     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
00943     {
00944         BaseSetLastNTError(Status);
00945         return 0;
00946     }
00947     return Request.Data.GetCommandHistoryLength.Length;
00948 }
00949 
00950 /*
00951  * @implemented (Undocumented)
00952  */
00953 DWORD
00954 WINAPI
00955 GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName)
00956 {
00957     return IntGetConsoleCommandHistoryLength(lpExeName, TRUE);
00958 }
00959 
00960 /*
00961  * @implemented (Undocumented)
00962  */
00963 DWORD
00964 WINAPI
00965 GetConsoleCommandHistoryLengthA(LPCSTR lpExeName)
00966 {
00967     return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR);
00968 }
00969 
00970 
00971 /*
00972  * @unimplemented
00973  */
00974 INT
00975 WINAPI
00976 GetConsoleDisplayMode(LPDWORD lpdwMode)
00977      /*
00978       * FUNCTION: Get the console display mode
00979       * ARGUMENTS:
00980       *      lpdwMode - Address of variable that receives the current value
00981       *                 of display mode
00982       * STATUS: Undocumented
00983       */
00984 {
00985     DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
00986     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
00987     return 0;
00988 }
00989 
00990 
00991 /*
00992  * @unimplemented (Undocumented)
00993  */
00994 DWORD
00995 WINAPI
00996 GetConsoleFontInfo(DWORD Unknown0,
00997                    DWORD Unknown1,
00998                    DWORD Unknown2,
00999                    DWORD Unknown3)
01000 {
01001     DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
01002     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01003     return 0;
01004 }
01005 
01006 
01007 /*
01008  * @unimplemented
01009  */
01010 COORD
01011 WINAPI
01012 GetConsoleFontSize(HANDLE hConsoleOutput,
01013                    DWORD nFont)
01014 {
01015     COORD Empty = {0, 0};
01016     DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
01017     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01018     return Empty;
01019 }
01020 
01021 
01022 /*
01023  * @implemented (Undocumented)
01024  */
01025 DWORD
01026 WINAPI
01027 GetConsoleHardwareState(HANDLE hConsole,
01028                         DWORD Flags,
01029                         PDWORD State)
01030 {
01031     CSR_API_MESSAGE Request;
01032     ULONG CsrRequest;
01033     NTSTATUS Status;
01034 
01035     CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
01036     Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
01037     Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
01038 
01039     Status = CsrClientCallServer(&Request,
01040                                  NULL,
01041                                  CsrRequest,
01042                                  sizeof(CSR_API_MESSAGE));
01043     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01044     {
01045         BaseSetLastNTError(Status);
01046         return FALSE;
01047     }
01048 
01049     *State = Request.Data.ConsoleHardwareStateRequest.State;
01050     return TRUE;
01051 }
01052 
01053 
01054 /*
01055  * @implemented (Undocumented)
01056  */
01057 HANDLE
01058 WINAPI
01059 GetConsoleInputWaitHandle(VOID)
01060 {
01061     CSR_API_MESSAGE Request;
01062     ULONG CsrRequest;
01063     NTSTATUS Status;
01064 
01065     CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
01066 
01067     Status = CsrClientCallServer(&Request,
01068                                  NULL,
01069                                  CsrRequest,
01070                                  sizeof(CSR_API_MESSAGE));
01071     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01072     {
01073         BaseSetLastNTError(Status);
01074         return 0;
01075     }
01076 
01077     return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
01078 }
01079 
01080 
01081 /*
01082  * @unimplemented
01083  */
01084 INT
01085 WINAPI
01086 GetCurrentConsoleFont(HANDLE hConsoleOutput,
01087                       BOOL bMaximumWindow,
01088                       PCONSOLE_FONT_INFO lpConsoleCurrentFont)
01089 {
01090     DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
01091     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01092     return 0;
01093 }
01094 
01095 
01096 /*
01097  * @unimplemented (Undocumented)
01098  */
01099 ULONG
01100 WINAPI
01101 GetNumberOfConsoleFonts(VOID)
01102 {
01103     DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
01104     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01105     return 1; /* FIXME: call csrss.exe */
01106 }
01107 
01108 
01109 /*
01110  * @unimplemented (Undocumented)
01111  */
01112 DWORD
01113 WINAPI
01114 InvalidateConsoleDIBits(DWORD Unknown0,
01115                         DWORD Unknown1)
01116 {
01117     DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
01118     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01119     return 0;
01120 }
01121 
01122 
01123 /*
01124  * @unimplemented (Undocumented)
01125  */
01126 HANDLE
01127 WINAPI
01128 OpenConsoleW(LPCWSTR wsName,
01129              DWORD dwDesiredAccess,
01130              BOOL bInheritHandle,
01131              DWORD dwShareMode)
01132 {
01133     CSR_API_MESSAGE Request;
01134     ULONG CsrRequest;
01135     NTSTATUS Status = STATUS_SUCCESS;
01136 
01137     if (wsName && 0 == _wcsicmp(wsName, L"CONIN$"))
01138     {
01139         CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
01140     }
01141     else if (wsName && 0 == _wcsicmp(wsName, L"CONOUT$"))
01142     {
01143         CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
01144     }
01145     else
01146     {
01147         SetLastError(ERROR_INVALID_PARAMETER);
01148         return(INVALID_HANDLE_VALUE);
01149     }
01150 
01151     if (dwDesiredAccess & ~(GENERIC_READ|GENERIC_WRITE))
01152     {
01153         SetLastError(ERROR_INVALID_PARAMETER);
01154         return(INVALID_HANDLE_VALUE);
01155     }
01156 
01157     if (dwShareMode & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))
01158     {
01159         SetLastError(ERROR_INVALID_PARAMETER);
01160         return(INVALID_HANDLE_VALUE);
01161     }
01162 
01163     /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
01164     Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
01165     Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
01166     Request.Data.GetInputHandleRequest.ShareMode = dwShareMode;
01167 
01168     Status = CsrClientCallServer(&Request,
01169                                  NULL,
01170                                  CsrRequest,
01171                                  sizeof(CSR_API_MESSAGE));
01172     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01173     {
01174         BaseSetLastNTError(Status);
01175         return INVALID_HANDLE_VALUE;
01176     }
01177 
01178     return Request.Data.GetInputHandleRequest.Handle;
01179 }
01180 
01181 
01182 /*
01183  * @unimplemented (Undocumented)
01184  */
01185 BOOL
01186 WINAPI
01187 SetConsoleCursor(DWORD Unknown0,
01188                  DWORD Unknown1)
01189 {
01190     DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
01191     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01192     return FALSE;
01193 }
01194 
01195 
01196 /*
01197  * @unimplemented
01198  */
01199 BOOL
01200 WINAPI
01201 SetConsoleDisplayMode(HANDLE hOut,
01202                       DWORD dwNewMode,
01203                       PCOORD lpdwOldMode)
01204      /*
01205       * FUNCTION: Set the console display mode.
01206       * ARGUMENTS:
01207       *       hOut - Standard output handle.
01208       *       dwNewMode - New mode.
01209       *       lpdwOldMode - Address of a variable that receives the old mode.
01210       */
01211 {
01212     DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
01213     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01214     return FALSE;
01215 }
01216 
01217 
01218 /*
01219  * @unimplemented (Undocumented)
01220  */
01221 BOOL
01222 WINAPI
01223 SetConsoleFont(DWORD Unknown0,
01224                DWORD Unknown1)
01225 {
01226     DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
01227     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01228     return FALSE;
01229 }
01230 
01231 
01232 /*
01233  * @implemented (Undocumented)
01234  */
01235 BOOL
01236 WINAPI
01237 SetConsoleHardwareState(HANDLE hConsole,
01238                         DWORD Flags,
01239                         DWORD State)
01240 {
01241     CSR_API_MESSAGE Request;
01242     ULONG CsrRequest;
01243     NTSTATUS Status;
01244 
01245     CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
01246     Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
01247     Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
01248     Request.Data.ConsoleHardwareStateRequest.State = State;
01249 
01250     Status = CsrClientCallServer(&Request,
01251                                  NULL,
01252                                  CsrRequest,
01253                                  sizeof(CSR_API_MESSAGE));
01254     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01255     {
01256         BaseSetLastNTError(Status);
01257         return FALSE;
01258     }
01259 
01260     return TRUE;
01261 }
01262 
01263 
01264 /*
01265  * @unimplemented (Undocumented)
01266  */
01267 BOOL
01268 WINAPI
01269 SetConsoleKeyShortcuts(DWORD Unknown0,
01270                        DWORD Unknown1,
01271                        DWORD Unknown2,
01272                        DWORD Unknown3)
01273 {
01274     DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
01275     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01276     return FALSE;
01277 }
01278 
01279 
01280 /*
01281  * @unimplemented (Undocumented)
01282  */
01283 BOOL
01284 WINAPI
01285 SetConsoleMaximumWindowSize(DWORD Unknown0,
01286                             DWORD Unknown1)
01287 {
01288     DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
01289     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01290     return FALSE;
01291 }
01292 
01293 
01294 /*
01295  * @unimplemented (Undocumented)
01296  */
01297 BOOL
01298 WINAPI
01299 SetConsoleMenuClose(DWORD Unknown0)
01300 {
01301     DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
01302     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01303     return FALSE;
01304 }
01305 
01306 
01307 static BOOL
01308 IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
01309                               LPCVOID lpExeName,
01310                               BOOL bUnicode)
01311 {
01312     CSR_API_MESSAGE Request;
01313     PCSR_CAPTURE_BUFFER CaptureBuffer;
01314     ULONG CsrRequest = MAKE_CSR_API(SET_HISTORY_NUMBER_COMMANDS, CSR_CONSOLE);
01315     NTSTATUS Status;
01316 
01317     if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
01318     {
01319         SetLastError(ERROR_INVALID_PARAMETER);
01320         return FALSE;
01321     }
01322 
01323     CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
01324     if (!CaptureBuffer)
01325     {
01326         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
01327         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01328         return FALSE;
01329     }
01330     IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
01331                             &Request.Data.SetHistoryNumberCommands.ExeName);
01332     Request.Data.SetHistoryNumberCommands.NumCommands = dwNumCommands;
01333     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
01334     CsrFreeCaptureBuffer(CaptureBuffer);
01335     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01336     {
01337         BaseSetLastNTError(Status);
01338         return FALSE;
01339     }
01340     return TRUE;
01341 }
01342 
01343 /*
01344  * @implemented (Undocumented)
01345  */
01346 BOOL
01347 WINAPI
01348 SetConsoleNumberOfCommandsA(DWORD dwNumCommands,
01349                             LPCWSTR lpExeName)
01350 {
01351     return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE);
01352 }
01353 
01354 /*
01355  * @implemented (Undocumented)
01356  */
01357 BOOL
01358 WINAPI
01359 SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
01360                             LPCSTR lpExeName)
01361 {
01362     return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE);
01363 }
01364 
01365 
01366 /*
01367  * @unimplemented (Undocumented)
01368  */
01369 BOOL
01370 WINAPI
01371 SetConsolePalette(DWORD Unknown0,
01372                   DWORD Unknown1,
01373                   DWORD Unknown2)
01374 {
01375     DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
01376     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01377     return FALSE;
01378 }
01379 
01380 /*
01381  * @unimplemented (Undocumented)
01382  */
01383 DWORD
01384 WINAPI
01385 ShowConsoleCursor(DWORD Unknown0,
01386                   DWORD Unknown1)
01387 {
01388     DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
01389     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01390     return 0;
01391 }
01392 
01393 
01394 /*
01395  * FUNCTION: Checks whether the given handle is a valid console handle.
01396  * ARGUMENTS:
01397  *      Handle - Handle to be checked
01398  * RETURNS:
01399  *      TRUE: Handle is a valid console handle
01400  *      FALSE: Handle is not a valid console handle.
01401  * STATUS: Officially undocumented
01402  *
01403  * @implemented
01404  */
01405 BOOL
01406 WINAPI
01407 VerifyConsoleIoHandle(HANDLE Handle)
01408 {
01409     CSR_API_MESSAGE Request;
01410     ULONG CsrRequest;
01411     NTSTATUS Status;
01412 
01413     CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
01414     Request.Data.VerifyHandleRequest.Handle = Handle;
01415 
01416     Status = CsrClientCallServer(&Request,
01417                                  NULL,
01418                                  CsrRequest,
01419                                  sizeof(CSR_API_MESSAGE));
01420     if (!NT_SUCCESS(Status))
01421     {
01422         BaseSetLastNTError(Status);
01423         return FALSE;
01424     }
01425 
01426     return (BOOL)NT_SUCCESS(Request.Status);
01427 }
01428 
01429 
01430 /*
01431  * @unimplemented
01432  */
01433 DWORD
01434 WINAPI
01435 WriteConsoleInputVDMA(DWORD Unknown0,
01436                       DWORD Unknown1,
01437                       DWORD Unknown2,
01438                       DWORD Unknown3)
01439 {
01440     DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
01441     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01442     return 0;
01443 }
01444 
01445 
01446 /*
01447  * @unimplemented
01448  */
01449 DWORD
01450 WINAPI
01451 WriteConsoleInputVDMW(DWORD Unknown0,
01452                       DWORD Unknown1,
01453                       DWORD Unknown2,
01454                       DWORD Unknown3)
01455 {
01456     DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
01457     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01458     return 0;
01459 }
01460 
01461 
01462 /*
01463  * @implemented (Undocumented)
01464  */
01465 BOOL
01466 WINAPI
01467 CloseConsoleHandle(HANDLE Handle)
01468 {
01469     CSR_API_MESSAGE Request;
01470     ULONG CsrRequest;
01471     NTSTATUS Status;
01472 
01473     CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
01474     Request.Data.CloseHandleRequest.Handle = Handle;
01475 
01476     Status = CsrClientCallServer(&Request,
01477                                  NULL,
01478                                  CsrRequest,
01479                                  sizeof(CSR_API_MESSAGE));
01480     if (!NT_SUCCESS(Status))
01481     {
01482         BaseSetLastNTError(Status);
01483         return FALSE;
01484     }
01485 
01486     return TRUE;
01487 }
01488 
01489 /*
01490  * @implemented
01491  */
01492 HANDLE
01493 WINAPI
01494 GetStdHandle(DWORD nStdHandle)
01495      /*
01496       * FUNCTION: Get a handle for the standard input, standard output
01497       * and a standard error device.
01498       * ARGUMENTS:
01499       *       nStdHandle - Specifies the device for which to return the handle.
01500       * RETURNS: If the function succeeds, the return value is the handle
01501       * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
01502       */
01503 {
01504     PRTL_USER_PROCESS_PARAMETERS Ppb;
01505 
01506     Ppb = NtCurrentPeb()->ProcessParameters;
01507     switch (nStdHandle)
01508     {
01509         case STD_INPUT_HANDLE:
01510             return Ppb->StandardInput;
01511 
01512         case STD_OUTPUT_HANDLE:
01513             return Ppb->StandardOutput;
01514 
01515         case STD_ERROR_HANDLE:
01516             return Ppb->StandardError;
01517     }
01518 
01519     SetLastError (ERROR_INVALID_PARAMETER);
01520     return INVALID_HANDLE_VALUE;
01521 }
01522 
01523 
01524 /*
01525  * @implemented
01526  */
01527 BOOL
01528 WINAPI
01529 SetStdHandle(DWORD nStdHandle,
01530              HANDLE hHandle)
01531      /*
01532       * FUNCTION: Set the handle for the standard input, standard output or
01533       * the standard error device.
01534       * ARGUMENTS:
01535       *        nStdHandle - Specifies the handle to be set.
01536       *        hHandle - The handle to set.
01537       * RETURNS: TRUE if the function succeeds, FALSE otherwise.
01538       */
01539 {
01540     PRTL_USER_PROCESS_PARAMETERS Ppb;
01541 
01542     /* no need to check if hHandle == INVALID_HANDLE_VALUE */
01543 
01544     Ppb = NtCurrentPeb()->ProcessParameters;
01545 
01546     switch (nStdHandle)
01547     {
01548         case STD_INPUT_HANDLE:
01549             Ppb->StandardInput = hHandle;
01550             return TRUE;
01551 
01552         case STD_OUTPUT_HANDLE:
01553             Ppb->StandardOutput = hHandle;
01554             return TRUE;
01555 
01556         case STD_ERROR_HANDLE:
01557             Ppb->StandardError = hHandle;
01558             return TRUE;
01559     }
01560 
01561     /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
01562     SetLastError(ERROR_INVALID_HANDLE);
01563     return FALSE;
01564 }
01565 
01566 
01567 static
01568 BOOL
01569 IntWriteConsole(HANDLE hConsoleOutput,
01570                 PVOID lpBuffer,
01571                 DWORD nNumberOfCharsToWrite,
01572                 LPDWORD lpNumberOfCharsWritten,
01573                 LPVOID lpReserved,
01574                 BOOL bUnicode)
01575 {
01576     PCSR_API_MESSAGE Request;
01577     ULONG CsrRequest;
01578     NTSTATUS Status;
01579     USHORT nChars;
01580     ULONG SizeBytes, CharSize;
01581     DWORD Written = 0;
01582 
01583     CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
01584     Request = RtlAllocateHeap(RtlGetProcessHeap(),
01585                               0,
01586                               max(sizeof(CSR_API_MESSAGE),
01587                               CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
01588                               CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
01589     if (Request == NULL)
01590     {
01591         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01592         return FALSE;
01593     }
01594 
01595     CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
01596 
01597     while (nNumberOfCharsToWrite > 0)
01598     {
01599         Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
01600         Request->Data.WriteConsoleRequest.Unicode = bUnicode;
01601 
01602         nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
01603         Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
01604 
01605         SizeBytes = nChars * CharSize;
01606 
01607         memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
01608 
01609         Status = CsrClientCallServer(Request,
01610                                      NULL,
01611                                      CsrRequest,
01612                                      max(sizeof(CSR_API_MESSAGE),
01613                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
01614 
01615         if (Status == STATUS_PENDING)
01616         {
01617             WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
01618             CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
01619             continue;
01620         }
01621         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
01622         {
01623             RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
01624             BaseSetLastNTError(Status);
01625             return FALSE;
01626         }
01627 
01628         nNumberOfCharsToWrite -= nChars;
01629         lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
01630         Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
01631     }
01632 
01633     if (lpNumberOfCharsWritten != NULL)
01634     {
01635         *lpNumberOfCharsWritten = Written;
01636     }
01637     RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
01638 
01639     return TRUE;
01640 }
01641 
01642 
01643 /*--------------------------------------------------------------
01644  *    WriteConsoleA
01645  *
01646  * @implemented
01647  */
01648 BOOL
01649 WINAPI
01650 WriteConsoleA(HANDLE hConsoleOutput,
01651               CONST VOID *lpBuffer,
01652               DWORD nNumberOfCharsToWrite,
01653               LPDWORD lpNumberOfCharsWritten,
01654               LPVOID lpReserved)
01655 {
01656     return IntWriteConsole(hConsoleOutput,
01657                            (PVOID)lpBuffer,
01658                            nNumberOfCharsToWrite,
01659                            lpNumberOfCharsWritten,
01660                            lpReserved,
01661                            FALSE);
01662 }
01663 
01664 
01665 /*--------------------------------------------------------------
01666  *    WriteConsoleW
01667  *
01668  * @implemented
01669  */
01670 BOOL
01671 WINAPI
01672 WriteConsoleW(HANDLE hConsoleOutput,
01673               CONST VOID *lpBuffer,
01674               DWORD nNumberOfCharsToWrite,
01675               LPDWORD lpNumberOfCharsWritten,
01676               LPVOID lpReserved)
01677 {
01678     return IntWriteConsole(hConsoleOutput,
01679                            (PVOID)lpBuffer,
01680                            nNumberOfCharsToWrite,
01681                            lpNumberOfCharsWritten,
01682                            lpReserved,
01683                            TRUE);
01684 }
01685 
01686 
01687 static
01688 BOOL
01689 IntReadConsole(HANDLE hConsoleInput,
01690                PVOID lpBuffer,
01691                DWORD nNumberOfCharsToRead,
01692                LPDWORD lpNumberOfCharsRead,
01693                PCONSOLE_READCONSOLE_CONTROL pInputControl,
01694                BOOL bUnicode)
01695 {
01696     CSR_API_MESSAGE Request;
01697     PCSR_CAPTURE_BUFFER CaptureBuffer;
01698     ULONG CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
01699     NTSTATUS Status = STATUS_SUCCESS;
01700     ULONG CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
01701 
01702     CaptureBuffer = CsrAllocateCaptureBuffer(1, nNumberOfCharsToRead * CharSize);
01703     if (CaptureBuffer == NULL)
01704     {
01705         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
01706         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01707         return FALSE;
01708     }
01709 
01710     CsrAllocateMessagePointer(CaptureBuffer,
01711                               nNumberOfCharsToRead * CharSize,
01712                               &Request.Data.ReadConsoleRequest.Buffer);
01713 
01714     Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
01715     Request.Data.ReadConsoleRequest.Unicode = bUnicode;
01716     Request.Data.ReadConsoleRequest.NrCharactersToRead = (WORD)nNumberOfCharsToRead;
01717     Request.Data.ReadConsoleRequest.NrCharactersRead = 0;
01718     Request.Data.ReadConsoleRequest.CtrlWakeupMask = 0;
01719     if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
01720     {
01721         Request.Data.ReadConsoleRequest.NrCharactersRead = pInputControl->nInitialChars;
01722         memcpy(Request.Data.ReadConsoleRequest.Buffer,
01723                lpBuffer,
01724                pInputControl->nInitialChars * sizeof(WCHAR));
01725         Request.Data.ReadConsoleRequest.CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
01726     }
01727 
01728     do
01729     {
01730         if (Status == STATUS_PENDING)
01731         {
01732             Status = NtWaitForSingleObject(Request.Data.ReadConsoleRequest.EventHandle,
01733                                            FALSE,
01734                                            0);
01735             if (!NT_SUCCESS(Status))
01736             {
01737                 DPRINT1("Wait for console input failed!\n");
01738                 break;
01739             }
01740         }
01741 
01742         Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
01743         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01744         {
01745             DPRINT1("CSR returned error in ReadConsole\n");
01746             CsrFreeCaptureBuffer(CaptureBuffer);
01747             BaseSetLastNTError(Status);
01748             return FALSE;
01749         }
01750     }
01751     while (Status == STATUS_PENDING);
01752 
01753     memcpy(lpBuffer,
01754            Request.Data.ReadConsoleRequest.Buffer,
01755            Request.Data.ReadConsoleRequest.NrCharactersRead * CharSize);
01756 
01757     if (lpNumberOfCharsRead != NULL)
01758         *lpNumberOfCharsRead = Request.Data.ReadConsoleRequest.NrCharactersRead;
01759 
01760     if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
01761         pInputControl->dwControlKeyState = Request.Data.ReadConsoleRequest.ControlKeyState;
01762 
01763     CsrFreeCaptureBuffer(CaptureBuffer);
01764 
01765     return TRUE;
01766 }
01767 
01768 
01769 /*--------------------------------------------------------------
01770  *    ReadConsoleA
01771  *
01772  * @implemented
01773  */
01774 BOOL
01775 WINAPI
01776 ReadConsoleA(HANDLE hConsoleInput,
01777              LPVOID lpBuffer,
01778              DWORD nNumberOfCharsToRead,
01779              LPDWORD lpNumberOfCharsRead,
01780              PCONSOLE_READCONSOLE_CONTROL pInputControl)
01781 {
01782     return IntReadConsole(hConsoleInput,
01783                           lpBuffer,
01784                           nNumberOfCharsToRead,
01785                           lpNumberOfCharsRead,
01786                           NULL,
01787                           FALSE);
01788 }
01789 
01790 
01791 /*--------------------------------------------------------------
01792  *    ReadConsoleW
01793  *
01794  * @implemented
01795  */
01796 BOOL
01797 WINAPI
01798 ReadConsoleW(HANDLE hConsoleInput,
01799              LPVOID lpBuffer,
01800              DWORD nNumberOfCharsToRead,
01801              LPDWORD lpNumberOfCharsRead,
01802              PCONSOLE_READCONSOLE_CONTROL pInputControl)
01803 {
01804     return IntReadConsole(hConsoleInput,
01805                           lpBuffer,
01806                           nNumberOfCharsToRead,
01807                           lpNumberOfCharsRead,
01808                           pInputControl,
01809                           TRUE);
01810 }
01811 
01812 
01813 /*--------------------------------------------------------------
01814  *    AllocConsole
01815  *
01816  * @implemented
01817  */
01818 BOOL
01819 WINAPI
01820 AllocConsole(VOID)
01821 {
01822     CSR_API_MESSAGE Request;
01823     ULONG CsrRequest;
01824     NTSTATUS Status;
01825     HANDLE hStdError;
01826     STARTUPINFO si;
01827 
01828     if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
01829     {
01830         DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
01831         BaseSetLastNTError (STATUS_OBJECT_NAME_EXISTS);
01832         return FALSE;
01833     }
01834 
01835     GetStartupInfo(&si);
01836 
01837     Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
01838     Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
01839     Request.Data.AllocConsoleRequest.ShowCmd = si.wShowWindow;
01840 
01841     CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
01842 
01843     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
01844     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01845     {
01846         BaseSetLastNTError(Status);
01847         return FALSE;
01848     }
01849 
01850     NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
01851 
01852     SetStdHandle(STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle);
01853     SetStdHandle(STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle);
01854 
01855     hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
01856                                        0,
01857                                        TRUE,
01858                                        DUPLICATE_SAME_ACCESS);
01859 
01860     SetStdHandle(STD_ERROR_HANDLE, hStdError);
01861     return TRUE;
01862 }
01863 
01864 
01865 /*--------------------------------------------------------------
01866  *    FreeConsole
01867  *
01868  * @implemented
01869  */
01870 BOOL
01871 WINAPI
01872 FreeConsole(VOID)
01873 {
01874     // AG: I'm not sure if this is correct (what happens to std handles?)
01875     // but I just tried to reverse what AllocConsole() does...
01876 
01877     CSR_API_MESSAGE Request;
01878     ULONG CsrRequest;
01879     NTSTATUS Status;
01880 
01881     CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
01882 
01883     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
01884     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01885     {
01886         BaseSetLastNTError(Status);
01887         return FALSE;
01888     }
01889 
01890     NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
01891     return TRUE;
01892 }
01893 
01894 
01895 /*--------------------------------------------------------------
01896  *    GetConsoleScreenBufferInfo
01897  *
01898  * @implemented
01899  */
01900 BOOL
01901 WINAPI
01902 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
01903                            PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
01904 {
01905     CSR_API_MESSAGE Request;
01906     ULONG CsrRequest;
01907     NTSTATUS Status;
01908 
01909     CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
01910     Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
01911 
01912     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
01913     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01914     {
01915         BaseSetLastNTError(Status);
01916         return FALSE;
01917     }
01918     *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
01919     return TRUE;
01920 }
01921 
01922 
01923 /*--------------------------------------------------------------
01924  *    SetConsoleCursorPosition
01925  *
01926  * @implemented
01927  */
01928 BOOL
01929 WINAPI
01930 SetConsoleCursorPosition(HANDLE hConsoleOutput,
01931                          COORD dwCursorPosition)
01932 {
01933     CSR_API_MESSAGE Request;
01934     ULONG CsrRequest;
01935     NTSTATUS Status;
01936 
01937     CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
01938     Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
01939     Request.Data.SetCursorRequest.Position = dwCursorPosition;
01940 
01941     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
01942     if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01943     {
01944         BaseSetLastNTError(Status);
01945         return FALSE;
01946     }
01947 
01948     return TRUE;
01949 }
01950 
01951 
01952 static
01953 BOOL
01954 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
01955                               PVOID cCharacter,
01956                               DWORD nLength,
01957                               COORD dwWriteCoord,
01958                               LPDWORD lpNumberOfCharsWritten,
01959                               BOOL bUnicode)
01960 {
01961     CSR_API_MESSAGE Request;
01962     ULONG CsrRequest;
01963     NTSTATUS Status;
01964 
01965     CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
01966     Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
01967     Request.Data.FillOutputRequest.Unicode = bUnicode;
01968 
01969     if(bUnicode)
01970         Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
01971     else
01972         Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
01973 
01974     Request.Data.FillOutputRequest.Position = dwWriteCoord;
01975     Request.Data.FillOutputRequest.Length = (WORD)nLength;
01976 
01977     Status = CsrClientCallServer(&Request,
01978                                  NULL,
01979                                  CsrRequest,
01980                                  sizeof(CSR_API_MESSAGE));
01981 
01982     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
01983     {
01984         BaseSetLastNTError(Status);
01985         return FALSE;
01986     }
01987 
01988     if(lpNumberOfCharsWritten != NULL)
01989     {
01990         *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
01991     }
01992 
01993     return TRUE;
01994 }
01995 
01996 /*--------------------------------------------------------------
01997  *    FillConsoleOutputCharacterA
01998  *
01999  * @implemented
02000  */
02001 BOOL
02002 WINAPI
02003 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
02004                             CHAR cCharacter,
02005                             DWORD nLength,
02006                             COORD dwWriteCoord,
02007                             LPDWORD lpNumberOfCharsWritten)
02008 {
02009     return IntFillConsoleOutputCharacter(hConsoleOutput,
02010                                          &cCharacter,
02011                                          nLength,
02012                                          dwWriteCoord,
02013                                          lpNumberOfCharsWritten,
02014                                          FALSE);
02015 }
02016 
02017 
02018 /*--------------------------------------------------------------
02019  *    FillConsoleOutputCharacterW
02020  *
02021  * @implemented
02022  */
02023 BOOL
02024 WINAPI
02025 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
02026                             WCHAR cCharacter,
02027                             DWORD nLength,
02028                             COORD dwWriteCoord,
02029                             LPDWORD lpNumberOfCharsWritten)
02030 {
02031     return IntFillConsoleOutputCharacter(hConsoleOutput,
02032                                          &cCharacter,
02033                                          nLength,
02034                                          dwWriteCoord,
02035                                          lpNumberOfCharsWritten,
02036                                          TRUE);
02037 }
02038 
02039 
02040 static
02041 BOOL
02042 IntPeekConsoleInput(HANDLE hConsoleInput,
02043                     PINPUT_RECORD lpBuffer,
02044                     DWORD nLength,
02045                     LPDWORD lpNumberOfEventsRead,
02046                     BOOL bUnicode)
02047 {
02048     CSR_API_MESSAGE Request;
02049     ULONG CsrRequest;
02050     PCSR_CAPTURE_BUFFER CaptureBuffer;
02051     ULONG Size;
02052 
02053     if (lpBuffer == NULL)
02054     {
02055         SetLastError(ERROR_INVALID_PARAMETER);
02056         return FALSE;
02057     }
02058 
02059     Size = nLength * sizeof(INPUT_RECORD);
02060 
02061     /* Allocate a Capture Buffer */
02062     DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
02063     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
02064     if (CaptureBuffer == NULL)
02065     {
02066         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
02067         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02068         return FALSE;
02069     }
02070 
02071     /* Allocate space in the Buffer */
02072     CsrCaptureMessageBuffer(CaptureBuffer,
02073                             NULL,
02074                             Size,
02075                             (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
02076 
02077     /* Set up the data to send to the Console Server */
02078     CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
02079     Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
02080     Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
02081     Request.Data.PeekConsoleInputRequest.Length = nLength;
02082 
02083     /* Call the server */
02084     CsrClientCallServer(&Request,
02085                         CaptureBuffer,
02086                         CsrRequest,
02087                         sizeof(CSR_API_MESSAGE));
02088     DPRINT("Server returned: %x\n", Request.Status);
02089 
02090     /* Check for success*/
02091     if (NT_SUCCESS(Request.Status))
02092     {
02093         /* Return the number of events read */
02094         DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
02095         *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
02096 
02097         /* Copy into the buffer */
02098         DPRINT("Copying to buffer\n");
02099         RtlCopyMemory(lpBuffer,
02100                       Request.Data.PeekConsoleInputRequest.InputRecord,
02101                       sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
02102     }
02103     else
02104     {
02105         /* Error out */
02106        *lpNumberOfEventsRead = 0;
02107        BaseSetLastNTError(Request.Status);
02108     }
02109 
02110     /* Release the capture buffer */
02111     CsrFreeCaptureBuffer(CaptureBuffer);
02112 
02113     /* Return TRUE or FALSE */
02114     return NT_SUCCESS(Request.Status);
02115 }
02116 
02117 /*--------------------------------------------------------------
02118  *     PeekConsoleInputA
02119  *
02120  * @implemented
02121  */
02122 BOOL
02123 WINAPI
02124 PeekConsoleInputA(HANDLE hConsoleInput,
02125                   PINPUT_RECORD lpBuffer,
02126                   DWORD nLength,
02127                   LPDWORD lpNumberOfEventsRead)
02128 {
02129     return IntPeekConsoleInput(hConsoleInput,
02130                                lpBuffer,
02131                                nLength,
02132                                lpNumberOfEventsRead,
02133                                FALSE);
02134 }
02135 
02136 
02137 /*--------------------------------------------------------------
02138  *     PeekConsoleInputW
02139  *
02140  * @implemented
02141  */
02142 BOOL
02143 WINAPI
02144 PeekConsoleInputW(HANDLE hConsoleInput,
02145                   PINPUT_RECORD lpBuffer,
02146                   DWORD nLength,
02147                   LPDWORD lpNumberOfEventsRead)
02148 {
02149     return IntPeekConsoleInput(hConsoleInput,
02150                                lpBuffer, nLength,
02151                                lpNumberOfEventsRead,
02152                                TRUE);
02153 }
02154 
02155 
02156 static
02157 BOOL
02158 IntReadConsoleInput(HANDLE hConsoleInput,
02159                     PINPUT_RECORD lpBuffer,
02160                     DWORD nLength,
02161                     LPDWORD lpNumberOfEventsRead,
02162                     BOOL bUnicode)
02163 {
02164     CSR_API_MESSAGE Request;
02165     ULONG CsrRequest;
02166     ULONG Read;
02167     NTSTATUS Status;
02168 
02169     CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
02170     Read = 0;
02171 
02172     while (nLength > 0)
02173     {
02174         Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
02175         Request.Data.ReadInputRequest.Unicode = bUnicode;
02176 
02177         Status = CsrClientCallServer(&Request,
02178                                      NULL,
02179                                      CsrRequest,
02180                                      sizeof(CSR_API_MESSAGE));
02181         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
02182         {
02183             if (Read == 0)
02184             {
02185                 /* we couldn't read a single record, fail */
02186                 BaseSetLastNTError(Status);
02187                 return FALSE;
02188             }
02189             else
02190             {
02191                 /* FIXME - fail gracefully in case we already read at least one record? */
02192                 break;
02193             }
02194         }
02195         else if (Status == STATUS_PENDING)
02196         {
02197             if (Read == 0)
02198             {
02199                 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
02200                 if (!NT_SUCCESS(Status))
02201                 {
02202                     BaseSetLastNTError(Status);
02203                     break;
02204                 }
02205             }
02206             else
02207             {
02208                 /* nothing more to read (waiting for more input??), let's just bail */
02209                 break;
02210             }
02211         }
02212         else
02213         {
02214             lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
02215             nLength--;
02216 
02217             if (!Request.Data.ReadInputRequest.MoreEvents)
02218             {
02219                 /* nothing more to read, bail */
02220                 break;
02221             }
02222         }
02223     }
02224 
02225     if (lpNumberOfEventsRead != NULL)
02226     {
02227         *lpNumberOfEventsRead = Read;
02228     }
02229 
02230     return (Read > 0);
02231 }
02232 
02233 
02234 /*--------------------------------------------------------------
02235  *     ReadConsoleInputA
02236  *
02237  * @implemented
02238  */
02239 BOOL
02240 WINAPI
02241 ReadConsoleInputA(HANDLE hConsoleInput,
02242                   PINPUT_RECORD lpBuffer,
02243                   DWORD nLength,
02244                   LPDWORD lpNumberOfEventsRead)
02245 {
02246     return IntReadConsoleInput(hConsoleInput,
02247                                lpBuffer,
02248                                nLength,
02249                                lpNumberOfEventsRead,
02250                                FALSE);
02251 }
02252 
02253 
02254 /*--------------------------------------------------------------
02255  *     ReadConsoleInputW
02256  *
02257  * @implemented
02258  */
02259 BOOL
02260 WINAPI
02261 ReadConsoleInputW(HANDLE hConsoleInput,
02262                   PINPUT_RECORD lpBuffer,
02263                   DWORD nLength,
02264                   LPDWORD lpNumberOfEventsRead)
02265 {
02266     return IntReadConsoleInput(hConsoleInput,
02267                                lpBuffer,
02268                                nLength,
02269                                lpNumberOfEventsRead,
02270                                TRUE);
02271 }
02272 
02273 
02274 static
02275 BOOL
02276 IntWriteConsoleInput(HANDLE hConsoleInput,
02277                      PINPUT_RECORD lpBuffer,
02278                      DWORD nLength,
02279                      LPDWORD lpNumberOfEventsWritten,
02280                      BOOL bUnicode)
02281 {
02282     CSR_API_MESSAGE Request;
02283     ULONG CsrRequest;
02284     PCSR_CAPTURE_BUFFER CaptureBuffer;
02285     DWORD Size;
02286 
02287     if (lpBuffer == NULL)
02288     {
02289         SetLastError(ERROR_INVALID_PARAMETER);
02290         return FALSE;
02291     }
02292 
02293     Size = nLength * sizeof(INPUT_RECORD);
02294 
02295     /* Allocate a Capture Buffer */
02296     DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
02297     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
02298     if (CaptureBuffer == NULL)
02299     {
02300         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
02301         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02302         return FALSE;
02303     }
02304 
02305     /* Allocate space in the Buffer */
02306     CsrCaptureMessageBuffer(CaptureBuffer,
02307                             lpBuffer,
02308                             Size,
02309                             (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
02310 
02311     /* Set up the data to send to the Console Server */
02312     CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
02313     Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
02314     Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
02315     Request.Data.WriteConsoleInputRequest.Length = nLength;
02316 
02317     /* Call the server */
02318     CsrClientCallServer(&Request,
02319                         CaptureBuffer,
02320                         CsrRequest,
02321                         sizeof(CSR_API_MESSAGE));
02322     DPRINT("Server returned: %x\n", Request.Status);
02323 
02324     /* Check for success*/
02325     if (NT_SUCCESS(Request.Status))
02326     {
02327         /* Return the number of events read */
02328         DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
02329         *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
02330     }
02331     else
02332     {
02333         /* Error out */
02334         *lpNumberOfEventsWritten = 0;
02335         BaseSetLastNTError(Request.Status);
02336     }
02337 
02338     /* Release the capture buffer */
02339     CsrFreeCaptureBuffer(CaptureBuffer);
02340 
02341     /* Return TRUE or FALSE */
02342     return NT_SUCCESS(Request.Status);
02343 }
02344 
02345 
02346 /*--------------------------------------------------------------
02347  *     WriteConsoleInputA
02348  *
02349  * @implemented
02350  */
02351 BOOL
02352 WINAPI
02353 WriteConsoleInputA(HANDLE hConsoleInput,
02354                    CONST INPUT_RECORD *lpBuffer,
02355                    DWORD nLength,
02356                    LPDWORD lpNumberOfEventsWritten)
02357 {
02358     return IntWriteConsoleInput(hConsoleInput,
02359                                 (PINPUT_RECORD)lpBuffer,
02360                                 nLength,
02361                                 lpNumberOfEventsWritten,
02362                                 FALSE);
02363 }
02364 
02365 
02366 /*--------------------------------------------------------------
02367  *     WriteConsoleInputW
02368  *
02369  * @implemented
02370  */
02371 BOOL
02372 WINAPI
02373 WriteConsoleInputW(HANDLE hConsoleInput,
02374                    CONST INPUT_RECORD *lpBuffer,
02375                    DWORD nLength,
02376                    LPDWORD lpNumberOfEventsWritten)
02377 {
02378     return IntWriteConsoleInput(hConsoleInput,
02379                                 (PINPUT_RECORD)lpBuffer,
02380                                 nLength,
02381                                 lpNumberOfEventsWritten,
02382                                 TRUE);
02383 }
02384 
02385 
02386 static
02387 BOOL
02388 IntReadConsoleOutput(HANDLE hConsoleOutput,
02389                      PCHAR_INFO lpBuffer,
02390                      COORD dwBufferSize,
02391                      COORD dwBufferCoord,
02392                      PSMALL_RECT lpReadRegion,
02393                      BOOL bUnicode)
02394 {
02395     CSR_API_MESSAGE Request;
02396     ULONG CsrRequest;
02397     PCSR_CAPTURE_BUFFER CaptureBuffer;
02398     DWORD Size, SizeX, SizeY;
02399 
02400     if (lpBuffer == NULL)
02401     {
02402         SetLastError(ERROR_INVALID_PARAMETER);
02403         return FALSE;
02404     }
02405 
02406     Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
02407 
02408     /* Allocate a Capture Buffer */
02409     DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
02410     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
02411     if (CaptureBuffer == NULL)
02412     {
02413         DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
02414         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02415         return FALSE;
02416     }
02417 
02418     /* Allocate space in the Buffer */
02419     CsrCaptureMessageBuffer(CaptureBuffer,
02420                             NULL,
02421                             Size,
02422                             (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
02423 
02424     /* Set up the data to send to the Console Server */
02425     CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
02426     Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
02427     Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
02428     Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
02429     Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
02430     Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
02431 
02432     /* Call the server */
02433     CsrClientCallServer(&Request,
02434                         CaptureBuffer,
02435                         CsrRequest,
02436                         sizeof(CSR_API_MESSAGE));
02437     DPRINT("Server returned: %x\n", Request.Status);
02438 
02439     /* Check for success*/
02440     if (NT_SUCCESS(Request.Status))
02441     {
02442         /* Copy into the buffer */
02443         DPRINT("Copying to buffer\n");
02444         SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
02445                 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
02446         SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
02447                 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
02448         RtlCopyMemory(lpBuffer,
02449                       Request.Data.ReadConsoleOutputRequest.CharInfo,
02450                       sizeof(CHAR_INFO) * SizeX * SizeY);
02451     }
02452     else
02453     {
02454         /* Error out */
02455         BaseSetLastNTError(Request.Status);
02456     }
02457 
02458     /* Return the read region */
02459     DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
02460     *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
02461 
02462     /* Release the capture buffer */
02463     CsrFreeCaptureBuffer(CaptureBuffer);
02464 
02465     /* Return TRUE or FALSE */
02466     return NT_SUCCESS(Request.Status);
02467 }
02468 
02469 /*--------------------------------------------------------------
02470  *     ReadConsoleOutputA
02471  *
02472  * @implemented
02473  */
02474 BOOL
02475 WINAPI
02476 ReadConsoleOutputA(HANDLE hConsoleOutput,
02477                    PCHAR_INFO lpBuffer,
02478                    COORD dwBufferSize,
02479                    COORD dwBufferCoord,
02480                    PSMALL_RECT lpReadRegion)
02481 {
02482     return IntReadConsoleOutput(hConsoleOutput,
02483                                 lpBuffer,
02484                                 dwBufferSize,
02485                                 dwBufferCoord,
02486                                 lpReadRegion,
02487                                 FALSE);
02488 }
02489 
02490 
02491 /*--------------------------------------------------------------
02492  *     ReadConsoleOutputW
02493  *
02494  * @implemented
02495  */
02496 BOOL
02497 WINAPI
02498 ReadConsoleOutputW(HANDLE hConsoleOutput,
02499                    PCHAR_INFO lpBuffer,
02500                    COORD dwBufferSize,
02501                    COORD dwBufferCoord,
02502                    PSMALL_RECT lpReadRegion)
02503 {
02504     return IntReadConsoleOutput(hConsoleOutput,
02505                                 lpBuffer,
02506                                 dwBufferSize,
02507                                 dwBufferCoord,
02508                                 lpReadRegion,
02509                                 TRUE);
02510 }
02511 
02512 
02513 static
02514 BOOL
02515 IntWriteConsoleOutput(HANDLE hConsoleOutput,
02516                       CONST CHAR_INFO *lpBuffer,
02517                       COORD dwBufferSize,
02518                       COORD dwBufferCoord,
02519                       PSMALL_RECT lpWriteRegion,
02520                       BOOL bUnicode)
02521 {
02522     CSR_API_MESSAGE Request;
02523     ULONG CsrRequest;
02524     PCSR_CAPTURE_BUFFER CaptureBuffer;
02525     ULONG Size;
02526 
02527     Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
02528 
02529     /* Allocate a Capture Buffer */
02530     DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
02531     CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
02532     if (CaptureBuffer == NULL)
02533     {
02534         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
02535         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02536         return FALSE;
02537     }
02538 
02539     /* Allocate space in the Buffer */
02540     CsrCaptureMessageBuffer(CaptureBuffer,
02541                             NULL,
02542                             Size,
02543                             (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
02544 
02545     /* Copy from the buffer */
02546     RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
02547 
02548     /* Set up the data to send to the Console Server */
02549     CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
02550     Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
02551     Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
02552     Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
02553     Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
02554     Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
02555 
02556     /* Call the server */
02557     CsrClientCallServer(&Request,
02558                         CaptureBuffer,
02559                         CsrRequest,
02560                         sizeof(CSR_API_MESSAGE));
02561     DPRINT("Server returned: %x\n", Request.Status);
02562 
02563     /* Check for success*/
02564     if (!NT_SUCCESS(Request.Status))
02565     {
02566         /* Error out */
02567         BaseSetLastNTError(Request.Status);
02568     }
02569 
02570     /* Return the read region */
02571     DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
02572     *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
02573 
02574     /* Release the capture buffer */
02575     CsrFreeCaptureBuffer(CaptureBuffer);
02576 
02577     /* Return TRUE or FALSE */
02578     return NT_SUCCESS(Request.Status);
02579 }
02580 
02581 /*--------------------------------------------------------------
02582  *     WriteConsoleOutputA
02583  *
02584  * @implemented
02585  */
02586 BOOL
02587 WINAPI
02588 WriteConsoleOutputA(HANDLE hConsoleOutput,
02589                     CONST CHAR_INFO *lpBuffer,
02590                     COORD dwBufferSize,
02591                     COORD dwBufferCoord,
02592                     PSMALL_RECT lpWriteRegion)
02593 {
02594     return IntWriteConsoleOutput(hConsoleOutput,
02595                                  lpBuffer,
02596                                  dwBufferSize,
02597                                  dwBufferCoord,
02598                                  lpWriteRegion,
02599                                  FALSE);
02600 }
02601 
02602 
02603 /*--------------------------------------------------------------
02604  *     WriteConsoleOutputW
02605  *
02606  * @implemented
02607  */
02608 BOOL
02609 WINAPI
02610 WriteConsoleOutputW(HANDLE hConsoleOutput,
02611                     CONST CHAR_INFO *lpBuffer,
02612                     COORD dwBufferSize,
02613                     COORD dwBufferCoord,
02614                     PSMALL_RECT lpWriteRegion)
02615 {
02616     return IntWriteConsoleOutput(hConsoleOutput,
02617                                  lpBuffer,
02618                                  dwBufferSize,
02619                                  dwBufferCoord,
02620                                  lpWriteRegion,
02621                                  TRUE);
02622 }
02623 
02624 
02625 static
02626 BOOL
02627 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
02628                               PVOID lpCharacter,
02629                               DWORD nLength,
02630                               COORD dwReadCoord,
02631                               LPDWORD lpNumberOfCharsRead,
02632                               BOOL bUnicode)
02633 {
02634     PCSR_API_MESSAGE Request;
02635     ULONG CsrRequest;
02636     NTSTATUS Status;
02637     ULONG SizeBytes, CharSize;
02638     DWORD CharsRead = 0;
02639 
02640     CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
02641 
02642     nLength = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize);
02643     SizeBytes = nLength * CharSize;
02644 
02645     Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
02646                               max(sizeof(CSR_API_MESSAGE),
02647                               CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
02648     if (Request == NULL)
02649     {
02650         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02651         return FALSE;
02652     }
02653 
02654     CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
02655     Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
02656 
02657     while (nLength > 0)
02658     {
02659         DWORD BytesRead;
02660 
02661         Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
02662         Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
02663         Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = nLength;
02664         SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
02665 
02666         Status = CsrClientCallServer(Request,
02667                                      NULL,
02668                                      CsrRequest,
02669                                      max(sizeof(CSR_API_MESSAGE),
02670                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
02671         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
02672         {
02673             RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02674             BaseSetLastNTError(Status);
02675             break;
02676         }
02677 
02678         BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
02679         memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
02680         lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
02681         CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
02682         nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
02683 
02684         Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
02685     }
02686 
02687     if (lpNumberOfCharsRead != NULL)
02688     {
02689         *lpNumberOfCharsRead = CharsRead;
02690     }
02691 
02692     RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02693 
02694     return TRUE;
02695 }
02696 
02697 
02698 /*--------------------------------------------------------------
02699  *     ReadConsoleOutputCharacterA
02700  *
02701  * @implemented
02702  */
02703 BOOL
02704 WINAPI
02705 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
02706                             LPSTR lpCharacter,
02707                             DWORD nLength,
02708                             COORD dwReadCoord,
02709                             LPDWORD lpNumberOfCharsRead)
02710 {
02711     return IntReadConsoleOutputCharacter(hConsoleOutput,
02712                                          (PVOID)lpCharacter,
02713                                          nLength,
02714                                          dwReadCoord,
02715                                          lpNumberOfCharsRead,
02716                                          FALSE);
02717 }
02718 
02719 
02720 /*--------------------------------------------------------------
02721  *      ReadConsoleOutputCharacterW
02722  *
02723  * @implemented
02724  */
02725 BOOL
02726 WINAPI
02727 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
02728                             LPWSTR lpCharacter,
02729                             DWORD nLength,
02730                             COORD dwReadCoord,
02731                             LPDWORD lpNumberOfCharsRead)
02732 {
02733     return IntReadConsoleOutputCharacter(hConsoleOutput,
02734                                          (PVOID)lpCharacter,
02735                                          nLength,
02736                                          dwReadCoord,
02737                                          lpNumberOfCharsRead,
02738                                          TRUE);
02739 }
02740 
02741 
02742 /*--------------------------------------------------------------
02743  *     ReadConsoleOutputAttribute
02744  *
02745  * @implemented
02746  */
02747 BOOL
02748 WINAPI
02749 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
02750                            LPWORD lpAttribute,
02751                            DWORD nLength,
02752                            COORD dwReadCoord,
02753                            LPDWORD lpNumberOfAttrsRead)
02754 {
02755     PCSR_API_MESSAGE Request;
02756     ULONG CsrRequest;
02757     NTSTATUS Status;
02758     DWORD Size;
02759 
02760     if (lpNumberOfAttrsRead != NULL)
02761         *lpNumberOfAttrsRead = nLength;
02762 
02763     Request = RtlAllocateHeap(RtlGetProcessHeap(),
02764                               0,
02765                               max(sizeof(CSR_API_MESSAGE),
02766                               CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
02767                                   + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
02768     if (Request == NULL)
02769     {
02770         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02771         return FALSE;
02772     }
02773 
02774     CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
02775 
02776     while (nLength != 0)
02777     {
02778         Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
02779         Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
02780 
02781         if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
02782             Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
02783         else
02784             Size = nLength;
02785 
02786         Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
02787 
02788         Status = CsrClientCallServer(Request,
02789                                      NULL,
02790                                      CsrRequest,
02791                                      max(sizeof(CSR_API_MESSAGE),
02792                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
02793         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
02794         {
02795             RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02796             BaseSetLastNTError(Status);
02797             return FALSE;
02798         }
02799 
02800         memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
02801         lpAttribute += Size;
02802         nLength -= Size;
02803         Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
02804     }
02805 
02806     RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02807 
02808     return TRUE;
02809 }
02810 
02811 
02812 static
02813 BOOL
02814 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
02815                                PVOID lpCharacter,
02816                                DWORD nLength,
02817                                COORD dwWriteCoord,
02818                                LPDWORD lpNumberOfCharsWritten,
02819                                BOOL bUnicode)
02820 {
02821     PCSR_API_MESSAGE Request;
02822     ULONG CsrRequest;
02823     NTSTATUS Status;
02824     ULONG CharSize, nChars;
02825     //ULONG SizeBytes;
02826     DWORD Written = 0;
02827 
02828     CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
02829 
02830     nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
02831     //SizeBytes = nChars * CharSize;
02832 
02833     Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
02834                               max(sizeof(CSR_API_MESSAGE),
02835                               CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
02836                                 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
02837     if (Request == NULL)
02838     {
02839         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02840         return FALSE;
02841     }
02842 
02843     CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
02844     Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
02845 
02846     while (nLength > 0)
02847     {
02848         DWORD BytesWrite;
02849 
02850         Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
02851         Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
02852         Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
02853         BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
02854 
02855         memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
02856 
02857         Status = CsrClientCallServer(Request,
02858                                      NULL,
02859                                      CsrRequest,
02860                                      max(sizeof(CSR_API_MESSAGE),
02861                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
02862 
02863         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
02864         {
02865             RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02866             BaseSetLastNTError(Status);
02867             return FALSE;
02868         }
02869 
02870         nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
02871         lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
02872         Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
02873 
02874         Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
02875     }
02876 
02877     if (lpNumberOfCharsWritten != NULL)
02878     {
02879         *lpNumberOfCharsWritten = Written;
02880     }
02881 
02882     RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02883 
02884     return TRUE;
02885 }
02886 
02887 
02888 /*--------------------------------------------------------------
02889  *     WriteConsoleOutputCharacterA
02890  *
02891  * @implemented
02892  */
02893 BOOL
02894 WINAPI
02895 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
02896                              LPCSTR lpCharacter,
02897                              DWORD nLength,
02898                              COORD dwWriteCoord,
02899                              LPDWORD lpNumberOfCharsWritten)
02900 {
02901     return IntWriteConsoleOutputCharacter(hConsoleOutput,
02902                                           (PVOID)lpCharacter,
02903                                           nLength,
02904                                           dwWriteCoord,
02905                                           lpNumberOfCharsWritten,
02906                                           FALSE);
02907 }
02908 
02909 
02910 /*--------------------------------------------------------------
02911  *     WriteConsoleOutputCharacterW
02912  *
02913  * @implemented
02914  */
02915 BOOL
02916 WINAPI
02917 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
02918                              LPCWSTR lpCharacter,
02919                              DWORD nLength,
02920                              COORD dwWriteCoord,
02921                              LPDWORD lpNumberOfCharsWritten)
02922 {
02923     return IntWriteConsoleOutputCharacter(hConsoleOutput,
02924                                           (PVOID)lpCharacter,
02925                                           nLength,
02926                                           dwWriteCoord,
02927                                           lpNumberOfCharsWritten,
02928                                           TRUE);
02929 }
02930 
02931 
02932 /*--------------------------------------------------------------
02933  *     WriteConsoleOutputAttribute
02934  *
02935  * @implemented
02936  */
02937 BOOL
02938 WINAPI
02939 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
02940                             CONST WORD *lpAttribute,
02941                             DWORD nLength,
02942                             COORD dwWriteCoord,
02943                             LPDWORD lpNumberOfAttrsWritten)
02944 {
02945     PCSR_API_MESSAGE Request;
02946     ULONG CsrRequest;
02947     NTSTATUS Status;
02948     WORD Size;
02949 
02950     Request = RtlAllocateHeap(RtlGetProcessHeap(),
02951                               0,
02952                               max(sizeof(CSR_API_MESSAGE),
02953                               CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
02954                                 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
02955     if (Request == NULL)
02956     {
02957         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
02958         return FALSE;
02959     }
02960 
02961     CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
02962     Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
02963 
02964     if (lpNumberOfAttrsWritten)
02965         *lpNumberOfAttrsWritten = nLength;
02966     while (nLength)
02967     {
02968         Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
02969         Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
02970         Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
02971         memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
02972 
02973         Status = CsrClientCallServer(Request,
02974                                      NULL,
02975                                      CsrRequest,
02976                                      max(sizeof(CSR_API_MESSAGE),
02977                                      CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
02978 
02979         if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
02980         {
02981             RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02982             BaseSetLastNTError (Status);
02983             return FALSE;
02984         }
02985         nLength -= Size;
02986         lpAttribute += Size;
02987         Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
02988     }
02989 
02990     RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
02991 
02992     return TRUE;
02993 }
02994 
02995 
02996 /*--------------------------------------------------------------
02997  *     FillConsoleOutputAttribute
02998  *
02999  * @implemented
03000  */
03001 BOOL
03002 WINAPI
03003 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
03004                            WORD wAttribute,
03005                            DWORD nLength,
03006                            COORD dwWriteCoord,
03007                            LPDWORD lpNumberOfAttrsWritten)
03008 {
03009     CSR_API_MESSAGE Request;
03010     ULONG CsrRequest;
03011     NTSTATUS Status;
03012 
03013     CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
03014     Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
03015     Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
03016     Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
03017     Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
03018 
03019     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03020     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03021     {
03022         BaseSetLastNTError ( Status );
03023         return FALSE;
03024     }
03025 
03026     if (lpNumberOfAttrsWritten)
03027         *lpNumberOfAttrsWritten = nLength;
03028 
03029     return TRUE;
03030 }
03031 
03032 
03033 /*--------------------------------------------------------------
03034  *     GetConsoleMode
03035  *
03036  * @implemented
03037  */
03038 BOOL
03039 WINAPI
03040 GetConsoleMode(HANDLE hConsoleHandle,
03041                LPDWORD lpMode)
03042 {
03043     CSR_API_MESSAGE Request;
03044     ULONG CsrRequest;
03045     NTSTATUS Status;
03046 
03047     CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
03048     Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
03049 
03050     Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
03051     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03052     {
03053         BaseSetLastNTError ( Status );
03054         return FALSE;
03055     }
03056     *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
03057 
03058     return TRUE;
03059 }
03060 
03061 
03062 /*--------------------------------------------------------------
03063  *     GetNumberOfConsoleInputEvents
03064  *
03065  * @implemented
03066  */
03067 BOOL
03068 WINAPI
03069 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
03070                               LPDWORD lpNumberOfEvents)
03071 {
03072     CSR_API_MESSAGE Request;
03073     ULONG CsrRequest;
03074     NTSTATUS Status;
03075 
03076     if (lpNumberOfEvents == NULL)
03077     {
03078         SetLastError(ERROR_INVALID_PARAMETER);
03079         return FALSE;
03080     }
03081 
03082     CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
03083     Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
03084 
03085     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03086     if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03087     {
03088         BaseSetLastNTError(Status);
03089         return FALSE;
03090     }
03091 
03092     *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
03093 
03094     return TRUE;
03095 }
03096 
03097 
03098 /*--------------------------------------------------------------
03099  *     GetLargestConsoleWindowSize
03100  *
03101  * @unimplemented
03102  */
03103 COORD
03104 WINAPI
03105 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
03106 {
03107     COORD Coord = {80,25};
03108     DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
03109     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
03110     return Coord;
03111 }
03112 
03113 
03114 /*--------------------------------------------------------------
03115  *    GetConsoleCursorInfo
03116  *
03117  * @implemented
03118  */
03119 BOOL
03120 WINAPI
03121 GetConsoleCursorInfo(HANDLE hConsoleOutput,
03122                      PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
03123 {
03124     CSR_API_MESSAGE Request;
03125     ULONG CsrRequest;
03126     NTSTATUS Status;
03127 
03128     if (!lpConsoleCursorInfo)
03129     {
03130         if (!hConsoleOutput)
03131             SetLastError(ERROR_INVALID_HANDLE);
03132         else
03133             SetLastError(ERROR_INVALID_ACCESS);
03134 
03135         return FALSE;
03136     }
03137 
03138     CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
03139     Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
03140 
03141     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03142 
03143     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03144     {
03145         BaseSetLastNTError(Status);
03146         return FALSE;
03147     }
03148     *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
03149 
03150     return TRUE;
03151 }
03152 
03153 
03154 /*--------------------------------------------------------------
03155  *     GetNumberOfConsoleMouseButtons
03156  *
03157  * @unimplemented
03158  */
03159 BOOL
03160 WINAPI
03161 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
03162 {
03163     DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
03164     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
03165     return FALSE;
03166 }
03167 
03168 
03169 /*--------------------------------------------------------------
03170  *     SetConsoleMode
03171  *
03172  * @implemented
03173  */
03174 BOOL
03175 WINAPI
03176 SetConsoleMode(HANDLE hConsoleHandle,
03177                DWORD dwMode)
03178 {
03179     CSR_API_MESSAGE Request;
03180     ULONG CsrRequest;
03181     NTSTATUS Status;
03182 
03183     CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
03184     Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
03185     Request.Data.SetConsoleModeRequest.Mode = dwMode;
03186 
03187     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03188     if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03189     {
03190         BaseSetLastNTError ( Status );
03191         return FALSE;
03192     }
03193 
03194     return TRUE;
03195 }
03196 
03197 
03198 /*--------------------------------------------------------------
03199  *     SetConsoleActiveScreenBuffer
03200  *
03201  * @implemented
03202  */
03203 BOOL
03204 WINAPI
03205 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
03206 {
03207     CSR_API_MESSAGE Request;
03208     ULONG CsrRequest;
03209     NTSTATUS Status;
03210 
03211     CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
03212     Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
03213 
03214     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03215     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03216     {
03217         BaseSetLastNTError(Status);
03218         return FALSE;
03219     }
03220 
03221     return TRUE;
03222 }
03223 
03224 
03225 /*--------------------------------------------------------------
03226  *     FlushConsoleInputBuffer
03227  *
03228  * @implemented
03229  */
03230 BOOL
03231 WINAPI
03232 FlushConsoleInputBuffer(HANDLE hConsoleInput)
03233 {
03234     CSR_API_MESSAGE Request;
03235     ULONG CsrRequest;
03236     NTSTATUS Status;
03237 
03238     CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
03239     Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
03240 
03241     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03242     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03243     {
03244         BaseSetLastNTError(Status);
03245         return FALSE;
03246     }
03247 
03248     return TRUE;
03249 }
03250 
03251 
03252 /*--------------------------------------------------------------
03253  *     SetConsoleScreenBufferSize
03254  *
03255  * @implemented
03256  */
03257 BOOL
03258 WINAPI
03259 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
03260                            COORD dwSize)
03261 {
03262     CSR_API_MESSAGE Request;
03263     ULONG CsrRequest;
03264     NTSTATUS Status;
03265 
03266     CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE);
03267     Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
03268     Request.Data.SetScreenBufferSize.Size = dwSize;
03269 
03270     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03271     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03272     {
03273         BaseSetLastNTError(Status);
03274         return FALSE;
03275     }
03276 
03277     return TRUE;
03278 }
03279 
03280 /*--------------------------------------------------------------
03281  *     SetConsoleCursorInfo
03282  *
03283  * @implemented
03284  */
03285 BOOL
03286 WINAPI
03287 SetConsoleCursorInfo(HANDLE hConsoleOutput,
03288                      CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
03289 {
03290     CSR_API_MESSAGE Request;
03291     ULONG CsrRequest;
03292     NTSTATUS Status;
03293 
03294     CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
03295     Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
03296     Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
03297 
03298     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03299     if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03300     {
03301         BaseSetLastNTError(Status);
03302         return FALSE;
03303     }
03304 
03305     return TRUE;
03306 }
03307 
03308 
03309 static
03310 BOOL
03311 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
03312                              const SMALL_RECT *lpScrollRectangle,
03313                              const SMALL_RECT *lpClipRectangle,
03314                              COORD dwDestinationOrigin,
03315                              const CHAR_INFO *lpFill,
03316                              BOOL bUnicode)
03317 {
03318     CSR_API_MESSAGE Request;
03319     ULONG CsrRequest;
03320     NTSTATUS Status;
03321 
03322     CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
03323     Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
03324     Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
03325     Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
03326 
03327     if (lpClipRectangle != NULL)
03328     {
03329         Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
03330         Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
03331     }
03332     else
03333     {
03334         Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
03335     }
03336 
03337     Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
03338     Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
03339 
03340     Status = CsrClientCallServer(&Request,
03341                                  NULL,
03342                                  CsrRequest,
03343                                  sizeof(CSR_API_MESSAGE));
03344 
03345     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03346     {
03347         BaseSetLastNTError(Status);
03348         return FALSE;
03349     }
03350 
03351     return TRUE;
03352 }
03353 
03354 
03355 /*--------------------------------------------------------------
03356  *    ScrollConsoleScreenBufferA
03357  *
03358  * @implemented
03359  */
03360 BOOL
03361 WINAPI
03362 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
03363                            CONST SMALL_RECT *lpScrollRectangle,
03364                            CONST SMALL_RECT *lpClipRectangle,
03365                            COORD dwDestinationOrigin,
03366                            CONST CHAR_INFO *lpFill)
03367 {
03368     return IntScrollConsoleScreenBuffer(hConsoleOutput,
03369                                         (PSMALL_RECT)lpScrollRectangle,
03370                                         (PSMALL_RECT)lpClipRectangle,
03371                                         dwDestinationOrigin,
03372                                         (PCHAR_INFO)lpFill,
03373                                         FALSE);
03374 }
03375 
03376 
03377 /*--------------------------------------------------------------
03378  *     ScrollConsoleScreenBufferW
03379  *
03380  * @implemented
03381  */
03382 BOOL
03383 WINAPI
03384 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
03385                            CONST SMALL_RECT *lpScrollRectangle,
03386                            CONST SMALL_RECT *lpClipRectangle,
03387                            COORD dwDestinationOrigin,
03388                            CONST CHAR_INFO *lpFill)
03389 {
03390     return IntScrollConsoleScreenBuffer(hConsoleOutput,
03391                                         lpScrollRectangle,
03392                                         lpClipRectangle,
03393                                         dwDestinationOrigin,
03394                                         lpFill,
03395                                         TRUE);
03396 }
03397 
03398 
03399 /*--------------------------------------------------------------
03400  *     SetConsoleWindowInfo
03401  *
03402  * @unimplemented
03403  */
03404 BOOL
03405 WINAPI
03406 SetConsoleWindowInfo(HANDLE hConsoleOutput,
03407                      BOOL bAbsolute,
03408                      CONST SMALL_RECT *lpConsoleWindow)
03409 {
03410     DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
03411     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
03412     return FALSE;
03413 }
03414 
03415 
03416 /*--------------------------------------------------------------
03417  *      SetConsoleTextAttribute
03418  *
03419  * @implemented
03420  */
03421 BOOL
03422 WINAPI
03423 SetConsoleTextAttribute(HANDLE hConsoleOutput,
03424                         WORD wAttributes)
03425 {
03426     CSR_API_MESSAGE Request;
03427     ULONG CsrRequest;
03428     NTSTATUS Status;
03429 
03430     CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
03431     Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
03432     Request.Data.SetAttribRequest.Attrib = wAttributes;
03433 
03434     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03435     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03436     {
03437         BaseSetLastNTError(Status);
03438         return FALSE;
03439     }
03440 
03441     return TRUE;
03442 }
03443 
03444 
03445 static
03446 BOOL
03447 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
03448 {
03449     PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
03450 
03451     if (HandlerRoutine == NULL)
03452     {
03453         NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
03454         return TRUE;
03455     }
03456     
03457     if (NrCtrlHandlers == NrAllocatedHandlers)
03458     {
03459         NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
03460                                           0,
03461                                           (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
03462         if (NewCtrlHandlers == NULL)   
03463         {
03464             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03465             return FALSE;
03466         }
03467         
03468         memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
03469         
03470         if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
03471         
03472         CtrlHandlers = NewCtrlHandlers;
03473         NrAllocatedHandlers += 4;
03474     }
03475     
03476     ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
03477 
03478     CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
03479     return TRUE;
03480 }
03481 
03482 
03483 static
03484 BOOL
03485 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
03486 {
03487     ULONG i;
03488 
03489     if (HandlerRoutine == NULL)
03490     {
03491         NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
03492         return TRUE;
03493     }
03494 
03495     for (i = 0; i < NrCtrlHandlers; i++)
03496     {
03497         if (CtrlHandlers[i] == HandlerRoutine)
03498         {
03499             if (i < (NrCtrlHandlers - 1))
03500             {
03501                 memmove(&CtrlHandlers[i],
03502                         &CtrlHandlers[i+1],
03503                         (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
03504             }
03505 
03506             NrCtrlHandlers--;
03507             return TRUE;
03508         }
03509     }
03510 
03511     SetLastError(ERROR_INVALID_PARAMETER);
03512     return FALSE;
03513 }
03514 
03515 
03516 /*
03517  * @implemented
03518  */
03519 BOOL
03520 WINAPI
03521 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
03522                       BOOL Add)
03523 {
03524     BOOL Ret;
03525 
03526     RtlEnterCriticalSection(&BaseDllDirectoryLock);
03527     if (Add)
03528     {
03529         Ret = AddConsoleCtrlHandler(HandlerRoutine);
03530     }
03531     else
03532     {
03533         Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
03534     }
03535 
03536     RtlLeaveCriticalSection(&BaseDllDirectoryLock);
03537     return(Ret);
03538 }
03539 
03540 
03541 /*--------------------------------------------------------------
03542  *     GenerateConsoleCtrlEvent
03543  *
03544  * @implemented
03545  */
03546 BOOL
03547 WINAPI
03548 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
03549                          DWORD dwProcessGroupId)
03550 {
03551     CSR_API_MESSAGE Request;
03552     ULONG CsrRequest;
03553     NTSTATUS Status;
03554 
03555     if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
03556     {
03557         SetLastError(ERROR_INVALID_PARAMETER);
03558         return FALSE;
03559     }
03560 
03561     CsrRequest = MAKE_CSR_API(GENERATE_CTRL_EVENT, CSR_CONSOLE);
03562     Request.Data.GenerateCtrlEvent.Event = dwCtrlEvent;
03563     Request.Data.GenerateCtrlEvent.ProcessGroup = dwProcessGroupId;
03564 
03565     Status = CsrClientCallServer(&Request,
03566                                  NULL,
03567                                  CsrRequest,
03568                                  sizeof(CSR_API_MESSAGE));
03569     if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
03570     {
03571         BaseSetLastNTError(Status);
03572         return FALSE;
03573     }
03574 
03575     return TRUE;
03576 }
03577 
03578 
03579 static DWORD
03580 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
03581 {
03582     CSR_API_MESSAGE Request;
03583     PCSR_CAPTURE_BUFFER CaptureBuffer;
03584     ULONG CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
03585     NTSTATUS Status;
03586 
03587     if (nSize == 0)
03588         return 0;
03589 
03590     Request.Data.GetTitleRequest.Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
03591     CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.GetTitleRequest.Length);
03592     if (CaptureBuffer == NULL)
03593     {
03594         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
03595         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03596         return 0;
03597     }
03598 
03599     CsrAllocateMessagePointer(CaptureBuffer,
03600                               Request.Data.GetTitleRequest.Length,
03601                               (PVOID*)&Request.Data.GetTitleRequest.Title);
03602 
03603     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
03604     if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
03605     {
03606         CsrFreeCaptureBuffer(CaptureBuffer);
03607         BaseSetLastNTError(Status);
03608         return 0;
03609     }
03610 
03611     if (bUnicode)
03612     {
03613         if (nSize >= sizeof(WCHAR))
03614             wcscpy((LPWSTR)lpConsoleTitle, Request.Data.GetTitleRequest.Title);
03615     }
03616     else
03617     {
03618         if (nSize < Request.Data.GetTitleRequest.Length / sizeof(WCHAR) ||
03619             !WideCharToMultiByte(CP_ACP, // ANSI code page
03620                                  0, // performance and mapping flags
03621                                  Request.Data.GetTitleRequest.Title, // address of wide-character string
03622                                  -1, // number of characters in string
03623                                  (LPSTR)lpConsoleTitle, // address of buffer for new string
03624                                  nSize, // size of buffer
03625                                  NULL, // FAST
03626                                  NULL))
03627         {
03628             /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
03629             *(LPSTR)lpConsoleTitle = '\0';
03630             Request.Data.GetTitleRequest.Length = 0;
03631         }
03632     }
03633     CsrFreeCaptureBuffer(CaptureBuffer);
03634 
03635     return Request.Data.GetTitleRequest.Length / sizeof(WCHAR);
03636 }
03637 
03638 /*--------------------------------------------------------------
03639  *    GetConsoleTitleW
03640  *
03641  * @implemented
03642  */
03643 DWORD
03644 WINAPI
03645 GetConsoleTitleW(LPWSTR lpConsoleTitle,
03646                  DWORD nSize)
03647 {
03648     return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
03649 }
03650 
03651 /*--------------------------------------------------------------
03652  *     GetConsoleTitleA
03653  *
03654  *     19990306 EA
03655  *
03656  * @implemented
03657  */
03658 DWORD
03659 WINAPI
03660 GetConsoleTitleA(LPSTR lpConsoleTitle,
03661                  DWORD nSize)
03662 {
03663     return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
03664 }
03665 
03666 
03667 /*--------------------------------------------------------------
03668  *    SetConsoleTitleW
03669  *
03670  * @implemented
03671  */
03672 BOOL
03673 WINAPI
03674 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
03675 {
03676     CSR_API_MESSAGE Request;
03677     PCSR_CAPTURE_BUFFER CaptureBuffer;
03678     ULONG CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
03679     NTSTATUS Status;
03680 
03681     Request.Data.SetTitleRequest.Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
03682 
03683     CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.SetTitleRequest.Length);
03684     if (CaptureBuffer == NULL)
03685     {
03686         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
03687         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03688         return FALSE;
03689     }
03690 
03691     CsrCaptureMessageBuffer(CaptureBuffer,
03692                             (PVOID)lpConsoleTitle,
03693                             Request.Data.SetTitleRequest.Length,
03694                             (PVOID*)&Request.Data.SetTitleRequest.Title);
03695 
03696     Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
03697     CsrFreeCaptureBuffer(CaptureBuffer);
03698     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03699     {
03700         BaseSetLastNTError(Status);
03701         return FALSE;
03702     }
03703 
03704     return TRUE;
03705 }
03706 
03707 
03708 /*--------------------------------------------------------------
03709  *    SetConsoleTitleA
03710  *
03711  *     19990204 EA    Added
03712  *
03713  * @implemented
03714  */
03715 BOOL
03716 WINAPI
03717 SetConsoleTitleA(LPCSTR lpConsoleTitle)
03718 {
03719     ULONG Length = strlen(lpConsoleTitle) + 1;
03720     LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
03721     BOOL Ret;
03722     if (!WideTitle)
03723     {
03724         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03725         return FALSE;
03726     }
03727     MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
03728     Ret = SetConsoleTitleW(WideTitle);
03729     HeapFree(GetProcessHeap(), 0, WideTitle);
03730     return Ret;
03731 }
03732 
03733 
03734 /*--------------------------------------------------------------
03735  *    CreateConsoleScreenBuffer
03736  *
03737  * @implemented
03738  */
03739 HANDLE
03740 WINAPI
03741 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
03742                           DWORD dwShareMode,
03743                           CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
03744                           DWORD dwFlags,
03745                           LPVOID lpScreenBufferData)
03746 {
03747     CSR_API_MESSAGE Request;
03748     ULONG CsrRequest;
03749     NTSTATUS Status;
03750 
03751     if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)
03752         || dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)
03753         || dwFlags != CONSOLE_TEXTMODE_BUFFER)
03754     {
03755         SetLastError(ERROR_INVALID_PARAMETER);
03756         return INVALID_HANDLE_VALUE;
03757     }
03758 
03759     Request.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
03760     Request.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
03761     Request.Data.CreateScreenBufferRequest.Inheritable =
03762         lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE;
03763 
03764     CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
03765     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03766     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03767     {
03768         BaseSetLastNTError(Status);
03769         return INVALID_HANDLE_VALUE;
03770     }
03771     return Request.Data.CreateScreenBufferRequest.OutputHandle;
03772 }
03773 
03774 
03775 /*--------------------------------------------------------------
03776  *    GetConsoleCP
03777  *
03778  * @implemented
03779  */
03780 UINT
03781 WINAPI
03782 GetConsoleCP(VOID)
03783 {
03784     CSR_API_MESSAGE Request;
03785     ULONG CsrRequest;
03786     NTSTATUS Status;
03787 
03788     CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
03789     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03790     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03791     {
03792         BaseSetLastNTError (Status);
03793         return 0;
03794     }
03795 
03796     return Request.Data.GetConsoleCodePage.CodePage;
03797 }
03798 
03799 
03800 /*--------------------------------------------------------------
03801  *    SetConsoleCP
03802  *
03803  * @implemented
03804  */
03805 BOOL
03806 WINAPI
03807 SetConsoleCP(UINT wCodePageID)
03808 {
03809     CSR_API_MESSAGE Request;
03810     ULONG CsrRequest;
03811     NTSTATUS Status;
03812 
03813     CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
03814     Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
03815 
03816     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03817     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03818     {
03819         BaseSetLastNTError(Status);
03820     }
03821 
03822     return NT_SUCCESS(Status);
03823 }
03824 
03825 
03826 /*--------------------------------------------------------------
03827  *    GetConsoleOutputCP
03828  *
03829  * @implemented
03830  */
03831 UINT
03832 WINAPI
03833 GetConsoleOutputCP(VOID)
03834 {
03835     CSR_API_MESSAGE Request;
03836     ULONG CsrRequest;
03837     NTSTATUS Status;
03838 
03839     CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
03840     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03841     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03842     {
03843         BaseSetLastNTError (Status);
03844         return 0;
03845     }
03846 
03847     return Request.Data.GetConsoleOutputCodePage.CodePage;
03848 }
03849 
03850 
03851 /*--------------------------------------------------------------
03852  *    SetConsoleOutputCP
03853  *
03854  * @implemented
03855  */
03856 BOOL
03857 WINAPI
03858 SetConsoleOutputCP(UINT wCodePageID)
03859 {
03860     CSR_API_MESSAGE Request;
03861     ULONG CsrRequest;
03862     NTSTATUS Status;
03863 
03864     CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
03865     Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
03866     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03867     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03868     {
03869         BaseSetLastNTError(Status);
03870     }
03871 
03872     return NT_SUCCESS(Status);
03873 }
03874 
03875 
03876 /*--------------------------------------------------------------
03877  *     GetConsoleProcessList
03878  *
03879  * @implemented
03880  */
03881 DWORD
03882 WINAPI
03883 GetConsoleProcessList(LPDWORD lpdwProcessList,
03884                       DWORD dwProcessCount)
03885 {
03886     PCSR_CAPTURE_BUFFER CaptureBuffer;
03887     CSR_API_MESSAGE Request;
03888     ULONG CsrRequest;
03889     ULONG nProcesses;
03890     NTSTATUS Status;
03891 
03892     if (lpdwProcessList == NULL || dwProcessCount == 0)
03893     {
03894         SetLastError(ERROR_INVALID_PARAMETER);
03895         return 0;
03896     }
03897 
03898     CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
03899     if (CaptureBuffer == NULL)
03900     {
03901         DPRINT1("CsrAllocateCaptureBuffer failed!\n");
03902         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
03903         return FALSE;
03904     }
03905 
03906     CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
03907     Request.Data.GetProcessListRequest.nMaxIds = dwProcessCount;
03908     CsrAllocateMessagePointer(CaptureBuffer,
03909                               dwProcessCount * sizeof(DWORD),
03910                               (PVOID*)&Request.Data.GetProcessListRequest.ProcessId);
03911 
03912     Status = CsrClientCallServer(&Request,
03913                                  CaptureBuffer,
03914                                  CsrRequest,
03915                                  sizeof(CSR_API_MESSAGE));
03916     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03917     {
03918         BaseSetLastNTError (Status);
03919         nProcesses = 0;
03920     }
03921     else
03922     {
03923         nProcesses = Request.Data.GetProcessListRequest.nProcessIdsTotal;
03924         if (dwProcessCount >= nProcesses)
03925         {
03926             memcpy(lpdwProcessList, Request.Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
03927         }
03928     }
03929 
03930     CsrFreeCaptureBuffer(CaptureBuffer);
03931     return nProcesses;
03932 }
03933 
03934 
03935 
03936 /*--------------------------------------------------------------
03937  *     GetConsoleSelectionInfo
03938  *
03939  * @implemented
03940  */
03941 BOOL
03942 WINAPI
03943 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
03944 {
03945     CSR_API_MESSAGE Request;
03946     ULONG CsrRequest = MAKE_CSR_API(GET_CONSOLE_SELECTION_INFO, CSR_CONSOLE);
03947     NTSTATUS Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03948     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
03949     {
03950         BaseSetLastNTError(Status);
03951         return FALSE;
03952     }
03953 
03954     *lpConsoleSelectionInfo = Request.Data.GetConsoleSelectionInfo.Info;
03955     return TRUE;
03956 }
03957 
03958 
03959 
03960 /*--------------------------------------------------------------
03961  *     AttachConsole
03962  *
03963  * @unimplemented
03964  */
03965 BOOL
03966 WINAPI
03967 AttachConsole(DWORD dwProcessId)
03968 {
03969     DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
03970     return TRUE;
03971 }
03972 
03973 /*--------------------------------------------------------------
03974  *     GetConsoleWindow
03975  *
03976  * @implemented
03977  */
03978 HWND
03979 WINAPI
03980 GetConsoleWindow(VOID)
03981 {
03982     CSR_API_MESSAGE Request;
03983     ULONG CsrRequest;
03984     NTSTATUS Status;
03985 
03986     CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
03987     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
03988     if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
03989     {
03990         BaseSetLastNTError(Status);
03991         return (HWND) NULL;
03992     }
03993 
03994     return Request.Data.GetConsoleWindowRequest.WindowHandle;
03995 }
03996 
03997 
03998 /*--------------------------------------------------------------
03999  *     SetConsoleIcon
04000  *
04001  * @implemented
04002  */
04003 BOOL
04004 WINAPI
04005 SetConsoleIcon(HICON hicon)
04006 {
04007     CSR_API_MESSAGE Request;
04008     ULONG CsrRequest;
04009     NTSTATUS Status;
04010 
04011     CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
04012     Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
04013 
04014     Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
04015     if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
04016     {
04017         BaseSetLastNTError(Status);
04018         return FALSE;
04019     }
04020 
04021     return NT_SUCCESS(Status);
04022 }
04023 
04024 
04025 /******************************************************************************
04026  * \name SetConsoleInputExeNameW
04027  * \brief Sets the console input file name from a unicode string.
04028  * \param lpInputExeName Pointer to a unicode string with the name.
04029  * \return TRUE if successful, FALSE if unsuccsedful.
04030  * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
04031  *          the function fails and sets last error to ERROR_INVALID_PARAMETER.
04032  */
04033 BOOL
04034 WINAPI
04035 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
04036 {
04037     int lenName;
04038 
04039     if (!lpInputExeName
04040         || (lenName = lstrlenW(lpInputExeName)) == 0
04041         || lenName > INPUTEXENAME_BUFLEN - 1)
04042     {
04043         /* Fail if string is empty or too long */
04044         SetLastError(ERROR_INVALID_PARAMETER);
04045         return FALSE;
04046     }
04047 
04048     RtlEnterCriticalSection(&ConsoleLock);
04049     _SEH2_TRY
04050     {
04051         RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
04052         InputExeName[lenName] = L'\0';
04053     }
04054     _SEH2_FINALLY
04055     {
04056         RtlLeaveCriticalSection(&ConsoleLock);
04057     }
04058     _SEH2_END;
04059 
04060     return TRUE;
04061 }
04062 
04063 
04064 /******************************************************************************
04065  * \name SetConsoleInputExeNameA
04066  * \brief Sets the console input file name from an ansi string.
04067  * \param lpInputExeName Pointer to an ansi string with the name.
04068  * \return TRUE if successful, FALSE if unsuccsedful.
04069  * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
04070  *          the function fails and sets last error to ERROR_INVALID_PARAMETER.
04071  */
04072 BOOL
04073 WINAPI
04074 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
04075 {
04076     WCHAR Buffer[INPUTEXENAME_BUFLEN];
04077     ANSI_STRING InputExeNameA;
04078     UNICODE_STRING InputExeNameU;
04079     NTSTATUS Status;
04080     BOOL Ret;
04081 
04082     RtlInitAnsiString(&InputExeNameA, lpInputExeName);
04083 
04084     if(InputExeNameA.Length == 0 || 
04085        InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
04086     {
04087         /* Fail if string is empty or too long */
04088         SetLastError(ERROR_INVALID_PARAMETER);
04089         return FALSE;
04090     }
04091 
04092     InputExeNameU.Buffer = Buffer;
04093     InputExeNameU.MaximumLength = sizeof(Buffer);
04094     InputExeNameU.Length = 0;
04095     Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
04096     if(NT_SUCCESS(Status))
04097     {
04098         Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
04099     }
04100     else
04101     {
04102         BaseSetLastNTError(Status);
04103         Ret = FALSE;
04104     }
04105 
04106     return Ret;
04107 }
04108 
04109 
04110 /******************************************************************************
04111  * \name GetConsoleInputExeNameW
04112  * \brief Retrieves the console input file name as unicode string.
04113  * \param nBufferLength Length of the buffer in WCHARs.
04114  *        Specify 0 to recieve the needed buffer length.
04115  * \param lpBuffer Pointer to a buffer that recieves the string.
04116  * \return Needed buffer size if \p nBufferLength is 0.
04117  *         Otherwise 1 if successful, 2 if buffer is too small.
04118  * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
04119  *          is not big enough.
04120  */
04121 DWORD
04122 WINAPI
04123 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
04124 {
04125     int lenName = lstrlenW(InputExeName);
04126 
04127     if (nBufferLength == 0)
04128     {
04129         /* Buffer size is requested, return it */
04130         return lenName + 1;
04131     }
04132 
04133     if(lenName + 1 > nBufferLength)
04134     {
04135         /* Buffer is not large enough! */
04136         SetLastError(ERROR_BUFFER_OVERFLOW);
04137         return 2;
04138     }
04139 
04140     RtlEnterCriticalSection(&ConsoleLock);
04141     _SEH2_TRY
04142     {
04143         RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
04144         lpBuffer[lenName] = '\0';
04145     }
04146     _SEH2_FINALLY
04147     {
04148         RtlLeaveCriticalSection(&ConsoleLock);
04149     }
04150     _SEH2_END;
04151 
04152     /* Success, return 1 */
04153     return 1;
04154 }
04155 
04156 
04157 /******************************************************************************
04158  * \name GetConsoleInputExeNameA
04159  * \brief Retrieves the console input file name as ansi string.
04160  * \param nBufferLength Length of the buffer in CHARs.
04161  * \param lpBuffer Pointer to a buffer that recieves the string.
04162  * \return 1 if successful, 2 if buffer is too small.
04163  * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
04164  *          is not big enough. The buffer recieves as much characters as fit.
04165  */
04166 DWORD
04167 WINAPI
04168 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
04169 {
04170     WCHAR Buffer[INPUTEXENAME_BUFLEN];
04171     DWORD Ret;
04172     UNICODE_STRING BufferU;
04173     ANSI_STRING BufferA;
04174 
04175     /* Get the unicode name */
04176     Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
04177 
04178     /* Initialize strings for conversion */
04179     RtlInitUnicodeString(&BufferU, Buffer);
04180     BufferA.Length = 0;
04181     BufferA.MaximumLength = nBufferLength;
04182     BufferA.Buffer = lpBuffer;
04183 
04184     /* Convert unicode name to ansi, copying as much chars as fit */
04185     RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
04186 
04187     /* Error handling */
04188     if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
04189     {
04190         SetLastError(ERROR_BUFFER_OVERFLOW);
04191         return 2;
04192     }
04193 
04194     return Ret;
04195 }
04196 
04197 BOOL
04198 WINAPI
04199 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
04200 {
04201     STUB;
04202     return FALSE;
04203 }
04204 
04205 BOOL
04206 WINAPI
04207 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
04208 {
04209     STUB;
04210     return FALSE;
04211 }
04212 
04213 BOOL
04214 WINAPI
04215 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
04216 {
04217     STUB;
04218     return FALSE;
04219 }
04220 
04221 
04222 BOOL
04223 WINAPI
04224 ReadConsoleInputExA(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
04225 {
04226     STUB;
04227     return FALSE;
04228 }
04229 
04230 BOOL
04231 WINAPI
04232 ReadConsoleInputExW(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
04233 {
04234     STUB;
04235     return FALSE;
04236 }
04237 
04238 BOOL
04239 WINAPI
04240 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
04241 {
04242     STUB;
04243     return FALSE;
04244 }
04245 
04246 BOOL
04247 WINAPI
04248 RegisterConsoleOS2(BOOL bUnknown)
04249 {
04250     STUB;
04251     return FALSE;
04252 }
04253 
04254 BOOL
04255 WINAPI
04256 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
04257 {
04258     STUB;
04259     return FALSE;
04260 }
04261 
04262 BOOL
04263 WINAPI
04264 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
04265 {
04266     STUB;
04267     return FALSE;
04268 }
04269 
04270 BOOL
04271 WINAPI
04272 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
04273 {
04274     STUB;
04275     return FALSE;
04276 }
04277 
04278 BOOL
04279 WINAPI
04280 SetConsoleOS2OemFormat(BOOL bUnknown)
04281 {
04282     STUB;
04283     return FALSE;
04284 }
04285 
04286 BOOL
04287 WINAPI
04288 UnregisterConsoleIME(VOID)
04289 {
04290     STUB;
04291     return FALSE;
04292 }
04293 
04294 
04295 /*
04296  * @unimplemented
04297  */
04298 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
04299 {
04300     STUB;
04301     return 0;
04302 }
04303 
04304 /*
04305  * @unimplemented
04306  */
04307 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
04308 {
04309     STUB;
04310     return 0;
04311 }
04312 
04313 /*
04314  * @unimplemented
04315  */
04316 BOOL
04317 WINAPI
04318 SetLastConsoleEventActive(VOID)
04319 {
04320     STUB;
04321     return FALSE;
04322 }
04323 
04324 /*
04325  * @unimplemented
04326  */
04327 BOOL
04328 WINAPI
04329 SetConsoleCommandHistoryMode(IN DWORD dwMode)
04330 {
04331     STUB;
04332     return FALSE;
04333 }
04334 
04335 
04336 /* EOF */

Generated on Sun May 27 2012 04:16:56 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.