[KERNEL32][CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 20 Apr 2014 14:39:38 +0000 (14:39 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 20 Apr 2014 14:39:38 +0000 (14:39 +0000)
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

reactos/dll/win32/kernel32/client/console/console.c
reactos/dll/win32/kernel32/client/handle.c
reactos/dll/win32/kernel32/include/console.h
reactos/include/reactos/subsys/win/conmsg.h
reactos/win32ss/user/winsrv/consrv/handle.c

index e99b1be..1a250a1 100644 (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
  */
index 885ea88..5024f5f 100644 (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,
index a7e69e7..8edb349 100644 (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);
 
index b6481a9..a208d3e 100644 (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;
index 6ad1cdf..b79fe52 100644 (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)