return FALSE;
}
-BOOL STDCALL
+HANDLE STDCALL
DuplicateConsoleHandle (HANDLE hConsole,
- DWORD Unknown1,
- DWORD Unknown2,
- DWORD Unknown3)
- /*
- * Undocumented
- */
+ DWORD dwDesiredAccess,
+ BOOL bInheritHandle,
+ DWORD dwOptions)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return FALSE;
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
+ if (IsConsoleHandle (hConsole) == FALSE)
+ {
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return INVALID_HANDLE_VALUE;
+ }
+
+ Request.Type = CSRSS_DUPLICATE_HANDLE;
+ Request.Data.DuplicateHandleRequest.Handle = hConsole;
+ Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
+ Status = CsrClientCallServer(&Request,
+ &Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY));
+ if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
+ {
+ SetLastErrorByStatus(Status);
+ return INVALID_HANDLE_VALUE;
+ }
+ return Reply.Data.DuplicateHandleReply.Handle;
}
DWORD STDCALL
return 0;
}
-DWORD STDCALL
-VerifyConsoleIoHandle (DWORD Unknown0)
- /*
- * Undocumented
- */
+
+/*
+ * FUNCTION: Checks whether the given handle is a valid console handle.
+ * ARGUMENTS:
+ * Handle - Handle to be checked
+ * RETURNS:
+ * TRUE: Handle is a valid console handle
+ * FALSE: Handle is not a valid console handle.
+ * STATUS: Officially undocumented
+ */
+BOOL STDCALL
+VerifyConsoleIoHandle(HANDLE Handle)
{
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
+ Request.Type = CSRSS_VERIFY_HANDLE;
+ Request.Data.VerifyHandleRequest.Handle = Handle;
+ Status = CsrClientCallServer(&Request,
+ &Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return (BOOL)NT_SUCCESS(Reply.Status);
}
+
DWORD STDCALL
WriteConsoleInputVDMA (DWORD Unknown0,
DWORD Unknown1,
return 0;
}
-WINBOOL STDCALL
+WINBOOL STDCALL
CloseConsoleHandle(HANDLE Handle)
/*
* Undocumented
*/
{
+ CSRSS_API_REQUEST Request;
+ CSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+
if (IsConsoleHandle (Handle) == FALSE)
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
- /* FIXME: call CSRSS */
- return TRUE/*FALSE*/;
+
+ Request.Type = CSRSS_CLOSE_HANDLE;
+ Request.Data.CloseHandleRequest.Handle = Handle;
+ Status = CsrClientCallServer(&Request,
+ &Reply,
+ sizeof(CSRSS_API_REQUEST),
+ sizeof(CSRSS_API_REPLY));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return TRUE;
}
+
BOOLEAN STDCALL
IsConsoleHandle(HANDLE Handle)
{
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
-
- Ppb = NtCurrentPeb()->ProcessParameters;
+
+ Ppb = NtCurrentPeb()->ProcessParameters;
switch (nStdHandle)
{
- case STD_INPUT_HANDLE: return Ppb->hStdInput;
- case STD_OUTPUT_HANDLE: return Ppb->hStdOutput;
- case STD_ERROR_HANDLE: return Ppb->hStdError;
+ case STD_INPUT_HANDLE:
+ return Ppb->hStdInput;
+
+ case STD_OUTPUT_HANDLE:
+ return Ppb->hStdOutput;
+
+ case STD_ERROR_HANDLE:
+ return Ppb->hStdError;
}
+
SetLastError (ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
*/
{
PRTL_USER_PROCESS_PARAMETERS Ppb;
-
+
Ppb = NtCurrentPeb()->ProcessParameters;
-
+
/* More checking needed? */
if (hHandle == INVALID_HANDLE_VALUE)
{
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
-
+
SetLastError(ERROR_SUCCESS); /* OK */
+
switch (nStdHandle)
{
- case STD_INPUT_HANDLE:
- Ppb->hStdInput = hHandle;
- return TRUE;
- case STD_OUTPUT_HANDLE:
- Ppb->hStdOutput = hHandle;
- return TRUE;
- case STD_ERROR_HANDLE:
- Ppb->hStdError = hHandle;
- return TRUE;
+ case STD_INPUT_HANDLE:
+ Ppb->hStdInput = hHandle;
+ return TRUE;
+
+ case STD_OUTPUT_HANDLE:
+ Ppb->hStdOutput = hHandle;
+ return TRUE;
+
+ case STD_ERROR_HANDLE:
+ Ppb->hStdError = hHandle;
+ return TRUE;
}
+
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
NTSTATUS Status;
USHORT Size;
ULONG MessageSize;
-
+
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) +
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
-
+
Request->Type = CSRSS_WRITE_CONSOLE;
Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
if (lpNumberOfCharsWritten != NULL)
Size = nNumberOfCharsToWrite;
}
Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
-
+
memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
MessageSize = CSRSS_REQUEST_HEADER_SIZE +
&Reply,
MessageSize,
sizeof(CSRSS_API_REPLY));
-
+
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
{
RtlFreeHeap(GetProcessHeap(), 0, Request);
nNumberOfCharsToWrite -= Size;
lpBuffer += Size;
}
+
RtlFreeHeap(GetProcessHeap(), 0, Request);
+
return TRUE;
}
CSRSS_API_REQUEST Request;
CSRSS_API_REPLY Reply;
NTSTATUS Status;
+ HANDLE hStdError;
Request.Type = CSRSS_ALLOC_CONSOLE;
Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
}
SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
- SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
+ hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
+ 0,
+ TRUE,
+ DUPLICATE_SAME_ACCESS);
+ SetStdHandle( STD_ERROR_HANDLE, hStdError );
return TRUE;
}
/*--------------------------------------------------------------
* GetConsoleTitleW
*/
-#define MAX_CONSOLE_TITLE_LENGTH 80
WINBASEAPI
DWORD
DWORD nSize
)
{
- union {
- CSRSS_API_REQUEST quest;
- CSRSS_API_REPLY ply;
- } Re;
- NTSTATUS Status;
-
- /* Marshall data */
- Re.quest.Type = CSRSS_GET_TITLE;
- Re.quest.Data.GetTitleRequest.ConsoleHandle =
- GetStdHandle (STD_INPUT_HANDLE);
-
- /* Call CSRSS */
- Status = CsrClientCallServer (
- & Re.quest,
- & Re.ply,
- (sizeof (CSRSS_GET_TITLE_REQUEST) +
- sizeof (LPC_MESSAGE) +
- sizeof (ULONG)),
- sizeof (CSRSS_API_REPLY)
- );
- if ( !NT_SUCCESS(Status)
- || !NT_SUCCESS (Status = Re.ply.Status)
- )
- {
- SetLastErrorByStatus (Status);
- return (0);
- }
+ CSRSS_API_REQUEST Request;
+ PCSRSS_API_REPLY Reply;
+ NTSTATUS Status;
+ HANDLE hConsole;
- /* Convert size in characters to size in bytes */
- nSize = sizeof (WCHAR) * nSize;
+ hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hConsole == INVALID_HANDLE_VALUE)
+ {
+ return 0;
+ }
- /* Unmarshall data */
- if (nSize < Re.ply.Data.GetTitleReply.Length)
- {
- DbgPrint ("%s: ret=%d\n", __FUNCTION__, Re.ply.Data.GetTitleReply.Length);
- nSize /= sizeof (WCHAR);
- if (nSize > 1)
- {
- wcsncpy (
- lpConsoleTitle,
- Re.ply.Data.GetTitleReply.Title,
- (nSize - 1)
- );
- /* Add null */
- lpConsoleTitle [nSize --] = L'\0';
- }
- }
- else
- {
- nSize = Re.ply.Data.GetTitleReply.Length / sizeof (WCHAR);
- wcscpy (lpConsoleTitle, Re.ply.Data.GetTitleReply.Title);
- }
+ Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+ if(Reply == NULL)
+ {
+ CloseHandle(hConsole);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
- return nSize;
+ Request.Type = CSRSS_GET_TITLE;
+ Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
+
+ Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
+ CloseHandle(hConsole);
+ if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
+ {
+ SetLastErrorByStatus(Status);
+ RtlFreeHeap(GetProcessHeap(), 0, Reply);
+ return 0;
+ }
+
+ if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
+ {
+ wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
+ lpConsoleTitle[nSize--] = L'\0';
+ }
+ else
+ {
+ nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
+ wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
+ lpConsoleTitle[nSize] = L'\0';
+ }
+
+ RtlFreeHeap(GetProcessHeap(), 0, Reply);
+ return nSize;
}
DWORD nSize
)
{
- wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
+ wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
DWORD nWideTitle = sizeof WideTitle;
-// DWORD nWritten;
+ DWORD nWritten;
if (!lpConsoleTitle || !nSize) return 0;
nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
if (!nWideTitle) return 0;
-#if 0
+
if ( (nWritten = WideCharToMultiByte(
CP_ACP, // ANSI code page
0, // performance and mapping flags
lpConsoleTitle[nWritten] = '\0';
return nWritten;
}
-#endif
+
return 0;
}
CSRSS_API_REPLY Reply;
NTSTATUS Status;
unsigned int c;
+ HANDLE hConsole;
+
+ hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hConsole == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL)
{
+ CloseHandle(hConsole);
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
Request->Type = CSRSS_SET_TITLE;
- Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE );
+ Request->Data.SetTitleRequest.Console = hConsole;
for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
Request->Data.SetTitleRequest.Length = c;
Status = CsrClientCallServer(Request,
&Reply,
- sizeof(CSRSS_SET_TITLE_REQUEST) +
- c +
- sizeof( LPC_MESSAGE ) +
- sizeof( ULONG ),
+ sizeof(CSRSS_API_REQUEST) +
+ c * sizeof(WCHAR),
sizeof(CSRSS_API_REPLY));
-
+ CloseHandle(hConsole);
if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
{
RtlFreeHeap( GetProcessHeap(), 0, Request );
CSRSS_API_REPLY Reply;
NTSTATUS Status;
unsigned int c;
+ HANDLE hConsole;
+
+ hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hConsole == INVALID_HANDLE_VALUE)
+ {
+ return FALSE;
+ }
Request = RtlAllocateHeap(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
if (Request == NULL)
{
+ CloseHandle(hConsole);
SetLastError(ERROR_OUTOFMEMORY);
return(FALSE);
}
Request->Type = CSRSS_SET_TITLE;
- Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE );
+ Request->Data.SetTitleRequest.Console = hConsole;
for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
Request->Data.SetTitleRequest.Length = c;
Status = CsrClientCallServer(Request,
&Reply,
- sizeof(CSRSS_SET_TITLE_REQUEST) +
- c +
- sizeof( LPC_MESSAGE ) +
- sizeof( ULONG ),
+ sizeof(CSRSS_API_REQUEST) +
+ c * sizeof(WCHAR),
sizeof(CSRSS_API_REPLY));
-
+ CloseHandle(hConsole);
if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
{
RtlFreeHeap( GetProcessHeap(), 0, Request );