[KERNEL32][CONSRV]

Implement console part of Get/SetHandleInformation, needed by msvcrt / cmd.exe (at least the windows version) and other console apps...

svn path=/trunk/; revision=62843
This commit is contained in:
Hermès Bélusca-Maïto 2014-04-20 14:39:38 +00:00
parent cd9c73cf39
commit 9a08d0b7dc
5 changed files with 180 additions and 14 deletions

View file

@ -308,6 +308,67 @@ DuplicateConsoleHandle(HANDLE hConsole,
}
/*
* @implemented
*/
BOOL
WINAPI
GetConsoleHandleInformation(IN HANDLE hHandle,
OUT LPDWORD lpdwFlags)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &ApiMessage.Data.GetHandleInfoRequest;
GetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
GetHandleInfoRequest->Handle = hHandle;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHandleInformation),
sizeof(*GetHandleInfoRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
*lpdwFlags = GetHandleInfoRequest->Flags;
return TRUE;
}
/*
* @implemented
*/
BOOL
WINAPI
SetConsoleHandleInformation(IN HANDLE hHandle,
IN DWORD dwMask,
IN DWORD dwFlags)
{
CONSOLE_API_MESSAGE ApiMessage;
PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &ApiMessage.Data.SetHandleInfoRequest;
SetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
SetHandleInfoRequest->Handle = hHandle;
SetHandleInfoRequest->Mask = dwMask;
SetHandleInfoRequest->Flags = dwFlags;
CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
NULL,
CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHandleInformation),
sizeof(*SetHandleInfoRequest));
if (!NT_SUCCESS(ApiMessage.Status))
{
BaseSetLastNTError(ApiMessage.Status);
return FALSE;
}
return TRUE;
}
/*
* @implemented
*/

View file

@ -50,10 +50,7 @@ GetHandleInformation(IN HANDLE hObject,
if (IsConsoleHandle(hObject))
{
/* FIXME: GetConsoleHandleInformation required */
UNIMPLEMENTED;
BaseSetLastNTError(STATUS_NOT_IMPLEMENTED);
return FALSE;
return GetConsoleHandleInformation(hObject, lpdwFlags);
}
Status = NtQueryObject(hObject,
@ -91,10 +88,7 @@ SetHandleInformation(IN HANDLE hObject,
if (IsConsoleHandle(hObject))
{
/* FIXME: SetConsoleHandleInformation required */
UNIMPLEMENTED;
BaseSetLastNTError(STATUS_NOT_IMPLEMENTED);
return FALSE;
return SetConsoleHandleInformation(hObject, dwMask, dwFlags);
}
Status = NtQueryObject(hObject,

View file

@ -38,6 +38,15 @@ DuplicateConsoleHandle(HANDLE hConsole,
BOOL bInheritHandle,
DWORD dwOptions);
BOOL WINAPI
GetConsoleHandleInformation(IN HANDLE hHandle,
OUT LPDWORD lpdwFlags);
BOOL WINAPI
SetConsoleHandleInformation(IN HANDLE hHandle,
IN DWORD dwMask,
IN DWORD dwFlags);
BOOL WINAPI
VerifyConsoleIoHandle(HANDLE Handle);

View file

@ -547,6 +547,21 @@ typedef struct
HANDLE TargetHandle;
} CONSOLE_DUPLICATEHANDLE, *PCONSOLE_DUPLICATEHANDLE;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE Handle;
DWORD Flags;
} CONSOLE_GETHANDLEINFO, *PCONSOLE_GETHANDLEINFO;
typedef struct
{
HANDLE ConsoleHandle;
HANDLE Handle;
DWORD Mask;
DWORD Flags;
} CONSOLE_SETHANDLEINFO, *PCONSOLE_SETHANDLEINFO;
/*
* Type of handles.
*/
@ -748,6 +763,8 @@ typedef struct _CONSOLE_API_MESSAGE
CONSOLE_CLOSEHANDLE CloseHandleRequest;
CONSOLE_VERIFYHANDLE VerifyHandleRequest;
CONSOLE_DUPLICATEHANDLE DuplicateHandleRequest;
CONSOLE_GETHANDLEINFO GetHandleInfoRequest;
CONSOLE_SETHANDLEINFO SetHandleInfoRequest;
/* Cursor */
CONSOLE_SHOWCURSOR ShowCursorRequest;

View file

@ -377,7 +377,6 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
HANDLE Handle)
{
ULONG Index = HandleToULong(Handle) >> 2;
PCONSOLE_IO_OBJECT Object;
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
@ -386,7 +385,7 @@ ConSrvRemoveObject(PCONSOLE_PROCESS_DATA ProcessData,
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
if (Index >= ProcessData->HandleTableSize ||
(Object = ProcessData->HandleTable[Index].Object) == NULL)
ProcessData->HandleTable[Index].Object == NULL)
{
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
return STATUS_INVALID_HANDLE;
@ -814,14 +813,100 @@ Quit:
CSR_API(SrvGetHandleInformation)
{
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetHandleInfoRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
HANDLE Handle = GetHandleInfoRequest->Handle;
ULONG Index = HandleToULong(Handle) >> 2;
PCONSOLE_IO_HANDLE Entry;
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Can't get console\n");
return Status;
}
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
ASSERT(ProcessData->HandleTable);
// ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
if (!IsConsoleHandle(Handle) ||
Index >= ProcessData->HandleTableSize ||
(Entry = &ProcessData->HandleTable[Index])->Object == NULL)
{
Status = STATUS_INVALID_HANDLE;
goto Quit;
}
/*
* Retrieve the handle information flags. The console server
* doesn't support HANDLE_FLAG_PROTECT_FROM_CLOSE.
*/
GetHandleInfoRequest->Flags = 0;
if (Entry->Inheritable) GetHandleInfoRequest->Flags |= HANDLE_FLAG_INHERIT;
Status = STATUS_SUCCESS;
Quit:
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvSetHandleInformation)
{
DPRINT1("%s not yet implemented\n", __FUNCTION__);
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.SetHandleInfoRequest;
PCONSOLE_PROCESS_DATA ProcessData = ConsoleGetPerProcessData(CsrGetClientThread()->Process);
PCONSOLE Console;
HANDLE Handle = SetHandleInfoRequest->Handle;
ULONG Index = HandleToULong(Handle) >> 2;
PCONSOLE_IO_HANDLE Entry;
Status = ConSrvGetConsole(ProcessData, &Console, TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Can't get console\n");
return Status;
}
RtlEnterCriticalSection(&ProcessData->HandleTableLock);
ASSERT(ProcessData->HandleTable);
// ASSERT( (ProcessData->HandleTable == NULL && ProcessData->HandleTableSize == 0) ||
// (ProcessData->HandleTable != NULL && ProcessData->HandleTableSize != 0) );
if (!IsConsoleHandle(Handle) ||
Index >= ProcessData->HandleTableSize ||
(Entry = &ProcessData->HandleTable[Index])->Object == NULL)
{
Status = STATUS_INVALID_HANDLE;
goto Quit;
}
/*
* Modify the handle information flags. The console server
* doesn't support HANDLE_FLAG_PROTECT_FROM_CLOSE.
*/
if (SetHandleInfoRequest->Mask & HANDLE_FLAG_INHERIT)
{
Entry->Inheritable = ((SetHandleInfoRequest->Flags & HANDLE_FLAG_INHERIT) != 0);
}
Status = STATUS_SUCCESS;
Quit:
RtlLeaveCriticalSection(&ProcessData->HandleTableLock);
ConSrvReleaseConsole(Console, TRUE);
return Status;
}
CSR_API(SrvCloseHandle)