[try 2] Move console input/output codepages to server

Kirill K. Smirnov lich at math.spbu.ru
Mon Apr 23 11:33:16 CDT 2007


The codepage is a property of console, not a process having the console.
The same console may be shared between several processes, e.g. cmd and chcp.
This patch allows native windows chcp utility work properly and make some 
kernel32 tests pass.
If passed codepage is invalid then SetLastError(ERROR_INVALID_PARAMETER);

I did not update server protocol version in previous attempt, now it should be 
OK.
-------------- next part --------------
diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c
index 66bc796..6ffa79f 100644
--- a/dlls/kernel32/console.c
+++ b/dlls/kernel32/console.c
@@ -55,9 +55,6 @@ #include "kernel_private.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(console);
 
-static UINT console_input_codepage;
-static UINT console_output_codepage;
-
 static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
 static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
 
@@ -141,12 +138,19 @@ HWND WINAPI GetConsoleWindow(VOID)
  */
 UINT WINAPI GetConsoleCP(VOID)
 {
-    if (!console_input_codepage) 
+    BOOL ret;
+    UINT codepage = GetOEMCP(); /* default value */
+
+    SERVER_START_REQ(get_console_input_info)
     {
-        console_input_codepage = GetOEMCP();
-	TRACE("%u\n", console_input_codepage);
+        req->handle = 0;
+        ret = !wine_server_call_err( req );
+        if (ret && reply->codepage)
+            codepage = reply->codepage;
     }
-    return console_input_codepage;
+    SERVER_END_REQ;
+
+    return codepage;
 }
 
 
@@ -155,9 +159,24 @@ UINT WINAPI GetConsoleCP(VOID)
  */
 BOOL WINAPI SetConsoleCP(UINT cp)
 {
-    if (!IsValidCodePage( cp )) return FALSE;
-    console_input_codepage = cp;
-    return TRUE;
+    BOOL ret;
+
+    if (!IsValidCodePage( cp ))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    SERVER_START_REQ( set_console_input_info )
+    {
+        req->handle    = 0;
+        req->mask      = SET_CONSOLE_INPUT_INFO_CODEPAGE;
+        req->codepage  = cp;
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+
+    return ret;
 }
 
 
@@ -166,12 +185,19 @@ BOOL WINAPI SetConsoleCP(UINT cp)
  */
 UINT WINAPI GetConsoleOutputCP(VOID)
 {
-    if (!console_output_codepage)
+    BOOL ret;
+    UINT codepage = GetOEMCP(); /* default value */
+
+    SERVER_START_REQ(get_console_output_info)
     {
-        console_output_codepage = GetOEMCP();
-	TRACE("%u\n", console_output_codepage);
+        req->handle = console_handle_unmap(GetStdHandle(STD_OUTPUT_HANDLE));
+        ret = !wine_server_call_err( req );
+        if (ret && reply->codepage)
+            codepage = reply->codepage;
     }
-    return console_output_codepage;
+    SERVER_END_REQ;
+
+    return codepage;
 }
 
 
@@ -187,9 +213,24 @@ UINT WINAPI GetConsoleOutputCP(VOID)
  */
 BOOL WINAPI SetConsoleOutputCP(UINT cp)
 {
-    if (!IsValidCodePage( cp )) return FALSE;
-    console_output_codepage = cp;
-    return TRUE;
+    BOOL ret;
+
+    if (!IsValidCodePage( cp ))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    SERVER_START_REQ( set_console_output_info )
+    {
+        req->handle    = console_handle_unmap(GetStdHandle(STD_OUTPUT_HANDLE));
+        req->mask      = SET_CONSOLE_OUTPUT_INFO_CODEPAGE;
+        req->codepage  = cp;
+        ret = !wine_server_call_err( req );
+    }
+    SERVER_END_REQ;
+
+    return ret;
 }
 
 
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index 5a1c721..b913c27 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -1378,6 +1378,7 @@ struct set_console_input_info_request
     int          history_mode;
     int          history_size;
     int          edition_mode;
+    unsigned int codepage;
     /* VARARG(title,unicode_str); */
 };
 struct set_console_input_info_reply
@@ -1389,6 +1390,7 @@ #define SET_CONSOLE_INPUT_INFO_TITLE    
 #define SET_CONSOLE_INPUT_INFO_HISTORY_MODE     0x04
 #define SET_CONSOLE_INPUT_INFO_HISTORY_SIZE     0x08
 #define SET_CONSOLE_INPUT_INFO_EDITION_MODE     0x10
+#define SET_CONSOLE_INPUT_INFO_CODEPAGE         0x20
 
 
 
@@ -1404,6 +1406,7 @@ struct get_console_input_info_reply
     int          history_size;
     int          history_index;
     int          edition_mode;
+    unsigned int codepage;
     /* VARARG(title,unicode_str); */
 };
 
@@ -1471,6 +1474,7 @@ struct set_console_output_info_request
     short int    win_bottom;
     short int    max_width;
     short int    max_height;
+    unsigned int codepage;
 };
 struct set_console_output_info_reply
 {
@@ -1482,6 +1486,7 @@ #define SET_CONSOLE_OUTPUT_INFO_SIZE    
 #define SET_CONSOLE_OUTPUT_INFO_ATTR            0x08
 #define SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW  0x10
 #define SET_CONSOLE_OUTPUT_INFO_MAX_SIZE        0x20
+#define SET_CONSOLE_OUTPUT_INFO_CODEPAGE        0x40
 
 
 
@@ -1506,6 +1511,7 @@ struct get_console_output_info_reply
     short int    win_bottom;
     short int    max_width;
     short int    max_height;
+    unsigned int codepage;
 };
 
 
@@ -4626,6 +4632,6 @@ union generic_reply
     struct allocate_locally_unique_id_reply allocate_locally_unique_id_reply;
 };
 
-#define SERVER_PROTOCOL_VERSION 299
+#define SERVER_PROTOCOL_VERSION 300
 
 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/console.c b/server/console.c
index cb34cb3..9058cd5 100644
--- a/server/console.c
+++ b/server/console.c
@@ -111,6 +111,7 @@ struct screen_buffer
     unsigned short        attr;          /* default attribute for screen buffer */
     rectangle_t           win;           /* current visible window on the screen buffer *
 					  * as seen in wineconsole */
+    unsigned int          codepage;      /* console output codepage */
 };
 
 static void screen_buffer_dump( struct object *obj, int verbose );
@@ -255,6 +256,7 @@ static struct object *create_console_inp
     console_input->history_index = 0;
     console_input->history_mode  = 0;
     console_input->edition_mode  = 0;
+    console_input->codepage      = 0;
     console_input->event         = create_event( NULL, NULL, 0, 1, 0 );
 
     if (!console_input->history || !console_input->evt)
@@ -286,6 +288,7 @@ static struct screen_buffer *create_cons
     screen_buffer->win.right      = screen_buffer->max_width - 1;
     screen_buffer->win.top        = 0;
     screen_buffer->win.bottom     = screen_buffer->max_height - 1;
+    screen_buffer->codepage       = 0;
 
     list_add_head( &screen_buffer_list, &screen_buffer->entry );
 
@@ -680,6 +683,10 @@ static int set_console_input_info( const
     {
         console->edition_mode = req->edition_mode;
     }
+    if (req->mask & SET_CONSOLE_INPUT_INFO_CODEPAGE)
+    {
+        console->codepage = req->codepage;
+    }
     release_object( console );
     return 1;
  error:
@@ -890,6 +897,10 @@ static int set_console_output_info( stru
 	screen_buffer->max_width  = req->max_width;
 	screen_buffer->max_height = req->max_height;
     }
+    if (req->mask & SET_CONSOLE_OUTPUT_INFO_CODEPAGE)
+    {
+        screen_buffer->codepage = req->codepage;
+    }
 
     return 1;
 }
@@ -1372,6 +1383,7 @@ DECL_HANDLER(get_console_input_info)
     reply->history_size  = console->history_size;
     reply->history_index = console->history_index;
     reply->edition_mode  = console->edition_mode;
+    reply->codepage      = console->codepage;
 
     release_object( console );
 }
@@ -1482,6 +1494,7 @@ DECL_HANDLER(get_console_output_info)
         reply->win_bottom     = screen_buffer->win.bottom;
         reply->max_width      = screen_buffer->max_width;
         reply->max_height     = screen_buffer->max_height;
+        reply->codepage       = screen_buffer->codepage;
         release_object( screen_buffer );
     }
 }
diff --git a/server/console.h b/server/console.h
index 3864ee9..4093351 100644
--- a/server/console.h
+++ b/server/console.h
@@ -42,6 +42,7 @@ struct console_input
     int                          history_index; /* number of used entries in history array */
     int                          history_mode;  /* mode of history (non zero means remove doubled strings */
     int                          edition_mode;  /* index to edition mode flavors */
+    unsigned int                 codepage;      /* console input codepage */
     struct event                *event;         /* event to wait on for input queue */
 };
 


More information about the wine-patches mailing list