KERNEL32.GetConsoleWindow implemented
authorEmanuele Aliberti <ea@iol.it>
Thu, 19 Jun 2003 19:38:26 +0000 (19:38 +0000)
committerEmanuele Aliberti <ea@iol.it>
Thu, 19 Jun 2003 19:38:26 +0000 (19:38 +0000)
KERNEL32.GetConsoleHardwareState implemented (undoc;incompatible)
KERNEL32.SetConsoleHardwareState implemented (undoc;incompatible)

Console window's handle is actually not returned because csrss does not create a window for each allocated console.

HardwareState is undocumented. Only size of the returned/set data is the same as NT's.

svn path=/trunk/; revision=4930

reactos/include/csrss/csrss.h
reactos/lib/kernel32/kernel32.def
reactos/lib/kernel32/kernel32.edf
reactos/lib/kernel32/misc/console.c
reactos/subsys/csrss/api.h
reactos/subsys/csrss/api/conio.c

index c1e59c7..13d428a 100644 (file)
@@ -368,6 +368,26 @@ typedef struct
   HANDLE Handle;
 } CSRSS_DUPLICATE_HANDLE_REPLY, *PCSRSS_DUPLICATE_HANDLE_REPLY;
 
+#define CONSOLE_HARDWARE_STATE_GET 0
+#define CONSOLE_HARDWARE_STATE_SET 1
+
+#define CONSOLE_HARDWARE_STATE_GDI_MANAGED 0
+#define CONSOLE_HARDWARE_STATE_DIRECT      1
+
+typedef struct
+{
+  HANDLE ConsoleHandle;
+  DWORD SetGet; // 0=get; 1=set
+  DWORD State;
+
+} CSRSS_CONSOLE_HARDWARE_STATE, *PCSRSS_CONSOLE_HARDWARE_STATE;
+
+typedef struct
+{
+  HANDLE ConsoleHandle;
+  HWND   WindowHandle;
+} CSRSS_CONSOLE_WINDOW, *PCSRSS_CONSOLE_WINDOW;
+
 #define CSRSS_MAX_WRITE_CONSOLE_REQUEST       \
       (MAX_MESSAGE_DATA - sizeof(ULONG) - sizeof(CSRSS_WRITE_CONSOLE_REQUEST))
 
@@ -427,6 +447,8 @@ typedef struct
 #define CSRSS_CLOSE_HANDLE                  (0x26)
 #define CSRSS_VERIFY_HANDLE                 (0x27)
 #define CSRSS_DUPLICATE_HANDLE             (0x28)
+#define CSRSS_SETGET_CONSOLE_HW_STATE       (0x29)
+#define CSRSS_GET_CONSOLE_WINDOW            (0x2A)
 
 /* Keep in sync with definition below. */
 #define CSRSS_REQUEST_HEADER_SIZE (sizeof(LPC_MESSAGE) + sizeof(ULONG))
@@ -473,6 +495,8 @@ typedef struct
     CSRSS_CLOSE_HANDLE_REQUEST CloseHandleRequest;
     CSRSS_VERIFY_HANDLE_REQUEST VerifyHandleRequest;
     CSRSS_DUPLICATE_HANDLE_REQUEST DuplicateHandleRequest;
+    CSRSS_CONSOLE_HARDWARE_STATE ConsoleHardwareStateRequest;
+    CSRSS_CONSOLE_WINDOW ConsoleWindowRequest;
   } Data;
 } CSRSS_API_REQUEST, *PCSRSS_API_REQUEST;
 
@@ -506,6 +530,8 @@ typedef struct
     CSRSS_GET_INPUT_HANDLE_REPLY GetInputHandleReply;
     CSRSS_GET_OUTPUT_HANDLE_REPLY GetOutputHandleReply;
     CSRSS_DUPLICATE_HANDLE_REPLY DuplicateHandleReply;
+    CSRSS_CONSOLE_HARDWARE_STATE ConsoleHardwareStateReply;
+    CSRSS_CONSOLE_WINDOW ConsoleWindowReply;
   } Data;
 } CSRSS_API_REPLY, *PCSRSS_API_REPLY;
 
index 9187a90..39e5a19 100644 (file)
@@ -238,6 +238,7 @@ GetConsoleScreenBufferInfo@8
 GetConsoleSelectionInfo@4
 GetConsoleTitleA@8
 GetConsoleTitleW@8
+GetConsoleWindow@0
 GetCurrencyFormatA@24
 GetCurrencyFormatW@24
 GetCurrentConsoleFont@12
index 3b4b1d2..afd19d4 100644 (file)
@@ -1,4 +1,4 @@
-; $Id: kernel32.edf,v 1.24 2003/05/29 00:36:41 hyperion Exp $
+; $Id: kernel32.edf,v 1.25 2003/06/19 19:38:26 ea Exp $
 ;
 ; kernel32.edf
 ;
@@ -242,6 +242,7 @@ GetConsoleScreenBufferInfo=GetConsoleScreenBufferInfo@8
 GetConsoleSelectionInfo=GetConsoleSelectionInfo@4
 GetConsoleTitleA=GetConsoleTitleA@8
 GetConsoleTitleW=GetConsoleTitleW@8
+GetConsoleWindow=GetConsoleWindow@0
 GetCurrencyFormatA=GetCurrencyFormatA@24
 GetCurrencyFormatW=GetCurrencyFormatW@24
 GetCurrentConsoleFont=GetCurrentConsoleFont@12
index 1b0fef7..a5c6da0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.57 2003/05/16 20:33:15 ea Exp $
+/* $Id: console.c,v 1.58 2003/06/19 19:38:26 ea Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
@@ -305,15 +305,32 @@ GetConsoleFontSize(HANDLE hConsoleOutput,
 }
 
 DWORD STDCALL
-GetConsoleHardwareState (DWORD Unknown0,
-                        DWORD  Unknown1,
-                        DWORD  Unknown2)
+GetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        PDWORD State)
      /*
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return 0;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+
+  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
+  Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
+
+  Status = CsrClientCallServer(& Request,
+                              & Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  *State = Reply.Data.ConsoleHardwareStateReply.State;
+  return TRUE;  
 }
 
 DWORD STDCALL
@@ -457,15 +474,32 @@ SetConsoleFont (DWORD     Unknown0,
 }
 
 WINBOOL STDCALL
-SetConsoleHardwareState (DWORD Unknown0,
-                        DWORD  Unknown1,
-                        DWORD  Unknown2)
+SetConsoleHardwareState (HANDLE        hConsole,
+                        DWORD  Flags,
+                        DWORD  State)
      /*
       * Undocumented
       */
 {
-  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-  return FALSE;
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+
+  Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
+  Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
+  Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
+  Request.Data.ConsoleHardwareStateRequest.State = State;
+
+  Status = CsrClientCallServer(& Request,
+                              & Reply,
+                              sizeof(CSRSS_API_REQUEST),
+                              sizeof(CSRSS_API_REPLY));
+  if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus(Status);
+    return FALSE;
+  }
+  return TRUE;  
 }
 
 WINBOOL STDCALL
@@ -2186,7 +2220,7 @@ RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
     {
       for (i = 0; i < NrCtrlHandlers; i++)
        {
-         if (CtrlHandlers[i] == HandlerRoutine)
+         if ((PHANDLER_ROUTINE) CtrlHandlers[i] == HandlerRoutine)
            {
              CtrlHandlers[i] = CtrlHandlers[NrCtrlHandlers - 1];
              NrCtrlHandlers--;
@@ -2656,4 +2690,31 @@ AttachConsole(DWORD dwProcessId)
    return FALSE;
 }
 
+/*--------------------------------------------------------------
+ *     GetConsoleWindow/0
+ */
+HWND STDCALL
+GetConsoleWindow (VOID)
+{
+  CSRSS_API_REQUEST Request;
+  CSRSS_API_REPLY   Reply;
+  NTSTATUS          Status;
+   
+  Request.Data.ConsoleWindowRequest.ConsoleHandle =
+    OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
+  if (INVALID_HANDLE_VALUE == Request.Data.ConsoleWindowRequest.ConsoleHandle)
+  {
+    return (HWND) NULL;
+  }
+  Request.Type = CSRSS_GET_CONSOLE_WINDOW;
+  Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
+  if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
+  {
+    SetLastErrorByStatus (Status);
+    return (HWND) NULL;
+  }
+  return Reply.Data.ConsoleWindowReply.WindowHandle;
+}
+
+
 /* EOF */
index 53d29bf..0d3d4cb 100644 (file)
@@ -66,11 +66,13 @@ typedef struct CSRSS_CONSOLE_t
    WORD Mode;                            /* Console mode flags */
    WORD EchoCount;                       /* count of chars to echo, in line buffered mode */
    UNICODE_STRING Title;                 /* Title of console */
-   struct {                            /* active code pages */
+   struct {                             /* active code pages */
           UINT Input;
           UINT Output;
    } CodePageId;
-   BOOL EarlyReturn;                   /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */
+   BOOL EarlyReturn;                     /* wake client and return data, even if we are in line buffered mode, and we don't have a complete line */
+   DWORD HardwareState;                  /* _GDI_MANAGED, _DIRECT */
+   HWND hWindow;
 } CSRSS_CONSOLE, *PCSRSS_CONSOLE;
 
 typedef struct _CSRSS_PROCESS_DATA
@@ -137,6 +139,8 @@ CSR_API(CsrGetOutputHandle);
 CSR_API(CsrCloseHandle);
 CSR_API(CsrVerifyHandle);
 CSR_API(CsrDuplicateHandle);
+CSR_API(CsrHardwareStateProperty);
+CSR_API(CsrGetConsoleWindow);
 
 /* print.c */
 VOID STDCALL DisplayString(LPCWSTR lpwString);
index 019970e..38abe19 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: conio.c,v 1.47 2003/03/26 22:10:43 hbirr Exp $
+/* $Id: conio.c,v 1.48 2003/06/19 19:38:26 ea Exp $
  *
  * reactos/subsys/csrss/api/conio.c
  *
@@ -757,6 +757,9 @@ NTSTATUS STDCALL CsrInitConsole(PCSRSS_CONSOLE Console)
        RtlFreeHeap( CsrssApiHeap, 0, Console->ActiveBuffer );
        return Status;
      }
+  /* Create the GDI Window to be used in windowed mode */
+  /* FIXME: create window; now write NULL */
+  Console->hWindow = (HWND) NULL;
   /* add a reference count because the buffer is tied to the console */
   Console->ActiveBuffer->Header.ReferenceCount++;
   /* make console active, and insert into console list */
@@ -2443,4 +2446,120 @@ CSR_API(CsrWriteConsoleInput)
    return Reply->Status;
 }
 
+/**********************************************************************
+ *     HardwareStateProperty
+ *
+ *     DESCRIPTION
+ *             Set/Get the value of the HardwareState and switch
+ *             between direct video buffer ouput and GDI windowed
+ *             output.
+ *     ARGUMENTS
+ *             Client hands us a CSRSS_CONSOLE_HARDWARE_STATE
+ *             object. We use the same object to reply.
+ *     NOTE
+ *             ConsoleHwState has the correct size to be compatible
+ *             with NT's, but values are not.
+ */
+static NTSTATUS FASTCALL SetConsoleHardwareState (PCSRSS_CONSOLE Console, DWORD ConsoleHwState)
+{
+   if ( (CONSOLE_HARDWARE_STATE_GDI_MANAGED == ConsoleHwState)
+      ||(CONSOLE_HARDWARE_STATE_DIRECT == ConsoleHwState))
+   {
+      if (Console->HardwareState != ConsoleHwState)
+      {
+        /* TODO: implement switching from full screen to windowed mode */
+        /* TODO: or back; now simply store the hardware state */
+         Console->HardwareState = ConsoleHwState;
+      }
+      return STATUS_SUCCESS;   
+   }
+   return STATUS_INVALID_PARAMETER_3; // Client: (handle, set_get, [mode])
+}
+
+CSR_API(CsrHardwareStateProperty)
+{
+   PCSRSS_CONSOLE Console;
+   NTSTATUS       Status;
+   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+   LOCK;
+   
+   Status = CsrGetObject (
+                  ProcessData,
+                  Request->Data.ConsoleHardwareStateRequest.ConsoleHandle,
+                  (Object_t**) & Console
+                  );
+   if (!NT_SUCCESS(Status))
+   {
+      Reply->Status = Status;
+   }
+   else
+   {
+      if(Console->Header.Type != CSRSS_CONSOLE_MAGIC)
+      {
+         Reply->Status = STATUS_INVALID_HANDLE;
+      }
+      else
+      {
+         switch (Request->Data.ConsoleHardwareStateRequest.SetGet)
+         {
+         case CONSOLE_HARDWARE_STATE_GET:
+            Reply->Data.ConsoleHardwareStateReply.State = Console->HardwareState;
+            break;
+      
+         case CONSOLE_HARDWARE_STATE_SET:
+            Reply->Status = SetConsoleHardwareState (Console, Request->Data.ConsoleHardwareStateRequest.State);
+            break;
+
+         default:
+            Reply->Status = STATUS_INVALID_PARAMETER_2; // Client: (handle, [set_get], mode)
+            break;
+         }
+      }
+   }
+
+   UNLOCK;
+
+   return Reply->Status;
+}
+
+CSR_API(CsrGetConsoleWindow)
+{
+   PCSRSS_CONSOLE Console;
+   NTSTATUS       Status;
+   Reply->Header.MessageSize = sizeof(CSRSS_API_REPLY);
+   Reply->Header.DataSize = sizeof(CSRSS_API_REPLY) - sizeof(LPC_MESSAGE);
+
+   LOCK;
+   
+   Status = CsrGetObject (
+                  ProcessData,
+                  Request->Data.ConsoleWindowRequest.ConsoleHandle,
+                  (Object_t**) & Console
+                  );
+   if (!NT_SUCCESS(Status))
+   {
+      Reply->Status = Status;
+   }
+   else
+   {
+      if(Console->Header.Type != CSRSS_CONSOLE_MAGIC)
+      {
+         Reply->Status = STATUS_INVALID_HANDLE;
+      }
+      else
+      {
+        // Is this GDI handle valid in the client's context?
+        Reply->Data.ConsoleWindowReply.WindowHandle = Console->hWindow;
+      }
+   }
+
+   UNLOCK;
+
+   return Reply->Status;
+}
+
 /* EOF */