diff --git a/reactos/dll/win32/kernel32/client/console/console.c b/reactos/dll/win32/kernel32/client/console/console.c index e99b1be5cd5..1a250a10b8e 100644 --- a/reactos/dll/win32/kernel32/client/console/console.c +++ b/reactos/dll/win32/kernel32/client/console/console.c @@ -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 */ diff --git a/reactos/dll/win32/kernel32/client/handle.c b/reactos/dll/win32/kernel32/client/handle.c index 885ea8808cc..5024f5fef94 100644 --- a/reactos/dll/win32/kernel32/client/handle.c +++ b/reactos/dll/win32/kernel32/client/handle.c @@ -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, diff --git a/reactos/dll/win32/kernel32/include/console.h b/reactos/dll/win32/kernel32/include/console.h index a7e69e727f3..8edb3493964 100644 --- a/reactos/dll/win32/kernel32/include/console.h +++ b/reactos/dll/win32/kernel32/include/console.h @@ -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); diff --git a/reactos/include/reactos/subsys/win/conmsg.h b/reactos/include/reactos/subsys/win/conmsg.h index b6481a9ff06..a208d3e0cac 100644 --- a/reactos/include/reactos/subsys/win/conmsg.h +++ b/reactos/include/reactos/subsys/win/conmsg.h @@ -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; diff --git a/reactos/win32ss/user/winsrv/consrv/handle.c b/reactos/win32ss/user/winsrv/consrv/handle.c index 6ad1cdf8789..b79fe527e7a 100644 --- a/reactos/win32ss/user/winsrv/consrv/handle.c +++ b/reactos/win32ss/user/winsrv/consrv/handle.c @@ -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)