[KERNEL32][CONSRV]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 6 Aug 2014 21:01:23 +0000 (21:01 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Wed, 6 Aug 2014 21:01:23 +0000 (21:01 +0000)
- Fix FreeConsole API.
- Implement undocumented GetConsoleKeyboardLayoutNameA/W API (same usage as GetKeyboardLayoutName), needed for ConEmu.
  See some examples here: http://www.opensource.apple.com/source/vim/vim-44/src/os_win32.c , and there: https://bitbucket.org/jaroslav/lswitcher/src/700bab23f294814235812c5cb07710bd380b1862/lswitch.c

CORE-7931 #comment ConsolepFree fixed in revision 63820.

svn path=/branches/condrv_restructure/; revision=63820

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

index 7ce38ad..fe4a084 100644 (file)
@@ -1076,24 +1076,37 @@ BOOL
 WINAPI
 FreeConsole(VOID)
 {
-    // AG: I'm not sure if this is correct (what happens to std handles?)
-    // but I just tried to reverse what AllocConsole() does...
-
-    NTSTATUS Status;
     CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest;
+    HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
 
-    Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
-                                 NULL,
-                                 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
-                                 sizeof(CONSOLE_FREECONSOLE));
-    if (!NT_SUCCESS(Status))
+    /* We must have a non-trivial handle to close */
+    if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle)
     {
-        BaseSetLastNTError(Status);
+        SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
+    /* Set up the data to send to the Console Server */
+    FreeConsoleRequest->ConsoleHandle = ConsoleHandle;
+
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
+                        sizeof(*FreeConsoleRequest));
+
+    /* Check for success */
+    if (!NT_SUCCESS(ApiMessage.Status))
+    {
+        BaseSetLastNTError(ApiMessage.Status);
+        return FALSE;
+    }
+
+    /* Reset the console handle */
     NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
 
+    /* Close the associated input handle */
     CloseHandle(InputWaitHandle);
     InputWaitHandle = INVALID_HANDLE_VALUE;
 
@@ -1311,7 +1324,7 @@ GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
         BaseSetLastNTError(ApiMessage.Status);
     }
 
-    DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
+    DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
     return GetLargestWindowSizeRequest->Size;
 }
 
@@ -2602,22 +2615,67 @@ UnregisterConsoleIME(VOID)
 }
 
 
+BOOL
+IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName,
+                                IN BOOL bAnsi)
+{
+    CONSOLE_API_MESSAGE ApiMessage;
+    PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest;
+
+    /* Set up the data to send to the Console Server */
+    GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+    GetKbdLayoutNameRequest->Ansi          = bAnsi;
+
+    /* Call the server */
+    CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+                        NULL,
+                        CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName),
+                        sizeof(*GetKbdLayoutNameRequest));
+
+    /* Check for success */
+    if (!NT_SUCCESS(ApiMessage.Status))
+    {
+        BaseSetLastNTError(ApiMessage.Status);
+        return FALSE;
+    }
+
+    /* Retrieve the results */
+    _SEH2_TRY
+    {
+        /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */
+        if (bAnsi)
+            strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
+        else
+            wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastError(ERROR_INVALID_ACCESS);
+        _SEH2_YIELD(return FALSE);
+    }
+    _SEH2_END;
+
+    return TRUE;
+}
+
 /*
- * @unimplemented
+ * @implemented (undocumented)
  */
-BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
+BOOL
+WINAPI
+GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName)
 {
-    STUB;
-    return 0;
+    return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE);
 }
 
 /*
- * @unimplemented
+ * @implemented (undocumented)
  */
-BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
+BOOL
+WINAPI
+GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName)
 {
-    STUB;
-    return 0;
+    return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE);
 }
 
 /*
index 56870f4..a11d0bf 100644 (file)
@@ -164,6 +164,7 @@ typedef struct _CONSOLE_START_INFO
     DWORD dwHotKey;
     DWORD dwStartupFlags;
     CONSOLE_PROPERTIES;
+
     BOOLEAN ConsoleNeeded; // Used for GUI apps only.
     LPTHREAD_START_ROUTINE CtrlDispatcher;
     LPTHREAD_START_ROUTINE ImeDispatcher;
@@ -281,7 +282,7 @@ typedef struct
 
 typedef struct
 {
-    ULONG Dummy;
+    HANDLE ConsoleHandle;
 } CONSOLE_FREECONSOLE, *PCONSOLE_FREECONSOLE;
 
 typedef struct
@@ -793,6 +794,13 @@ typedef struct
     HANDLE EventHandle;
 } CONSOLE_SETINPUTOUTPUTCP, *PCONSOLE_SETINPUTOUTPUTCP;
 
+typedef struct
+{
+    HANDLE ConsoleHandle;
+    CHAR   LayoutBuffer[KL_NAMELENGTH * sizeof(WCHAR)]; // Can hold up to 9 wchars
+    BOOL   Ansi;
+} CONSOLE_GETKBDLAYOUTNAME, *PCONSOLE_GETKBDLAYOUTNAME;
+
 typedef struct _CONSOLE_API_MESSAGE
 {
     PORT_MESSAGE Header;
@@ -886,9 +894,10 @@ typedef struct _CONSOLE_API_MESSAGE
         CONSOLE_SETHISTORYNUMBERCOMMANDS SetHistoryNumberCommandsRequest;
         CONSOLE_SETHISTORYMODE SetHistoryModeRequest;
 
-        /* Input and Output Code Pages */
+        /* Input and Output Code Pages; keyboard */
         CONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest;
         CONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest;
+        CONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest;
     } Data;
 } CONSOLE_API_MESSAGE, *PCONSOLE_API_MESSAGE;
 
index b4f0d4f..fb0ddf7 100644 (file)
@@ -999,8 +999,21 @@ CSR_API(SrvSetConsoleKeyShortcuts)
 
 CSR_API(SrvGetConsoleKeyboardLayoutName)
 {
-    DPRINT1("%s not yet implemented\n", __FUNCTION__);
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &((PCONSOLE_API_MESSAGE)ApiMessage)->Data.GetKbdLayoutNameRequest;
+    PCONSOLE Console;
+
+    Status = ConSrvGetConsole(ConsoleGetPerProcessData(CsrGetClientThread()->Process), &Console, TRUE);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Retrieve the keyboard layout name of the system */
+    if (GetKbdLayoutNameRequest->Ansi)
+        GetKeyboardLayoutNameA((PCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
+    else
+        GetKeyboardLayoutNameW((PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer);
+
+    ConSrvReleaseConsole(Console, TRUE);
+    return STATUS_SUCCESS;
 }
 
 CSR_API(SrvGetConsoleCharType)