[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