diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index ee9bfdeb471..2f850df5b6d 100644 --- a/dlls/advapi32/registry.c +++ b/dlls/advapi32/registry.c @@ -1220,14 +1220,14 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) goto done; } - SERVER_START_VAR_REQ( load_registry, len ) + SERVER_START_REQ( load_registry ) { req->hkey = hkey; req->file = file; - memcpy( server_data_ptr(req), subkey, len ); - ret = RtlNtStatusToDosError( SERVER_CALL() ); + wine_server_add_data( req, subkey, len ); + ret = RtlNtStatusToDosError( wine_server_call(req) ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; CloseHandle( file ); done: @@ -1241,6 +1241,7 @@ LONG WINAPI RegLoadKeyW( HKEY hkey, LPCWSTR subkey, LPCWSTR filename ) */ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) { + WCHAR buffer[MAX_PATH]; HANDLE file; DWORD ret, len, err = GetLastError(); @@ -1249,8 +1250,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) if (!filename || !*filename) return ERROR_INVALID_PARAMETER; if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER; - len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR); - if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER; + if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH ))) + return ERROR_INVALID_PARAMETER; if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE) @@ -1259,15 +1260,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) goto done; } - SERVER_START_VAR_REQ( load_registry, len ) + SERVER_START_REQ( load_registry ) { req->hkey = hkey; req->file = file; - MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), - server_data_ptr(req), len/sizeof(WCHAR) ); - ret = RtlNtStatusToDosError( SERVER_CALL() ); + wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); + ret = RtlNtStatusToDosError( wine_server_call(req) ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; CloseHandle( file ); done: @@ -1315,7 +1315,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) { req->hkey = hkey; req->file = handle; - ret = RtlNtStatusToDosError( SERVER_CALL() ); + ret = RtlNtStatusToDosError( wine_server_call( req ) ); } SERVER_END_REQ; diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 0ea6a7c3dc4..b818bf61683 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -9,6 +9,7 @@ IMPORTS = ntdll C_SRCS = \ comm.c \ + console.c \ debugger.c \ format_msg.c \ kernel_main.c \ diff --git a/dlls/kernel/comm.c b/dlls/kernel/comm.c index 2079193b6c5..95c6c094aae 100644 --- a/dlls/kernel/comm.c +++ b/dlls/kernel/comm.c @@ -379,7 +379,7 @@ static BOOL COMM_SetCommError(HANDLE handle, DWORD error) req->handle = handle; req->flags = SERIALINFO_SET_ERROR; req->commerror = error; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -395,8 +395,8 @@ static BOOL COMM_GetCommError(HANDLE handle, LPDWORD lperror) SERVER_START_REQ( get_serial_info ) { req->handle = handle; - ret = !SERVER_CALL_ERR(); - *lperror = req->commerror; + ret = !wine_server_call_err( req ); + *lperror = reply->commerror; } SERVER_END_REQ; @@ -748,9 +748,9 @@ BOOL WINAPI GetCommMask( SERVER_START_REQ( get_serial_info ) { req->handle = handle; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - if (evtmask) *evtmask = req->eventmask; + if (evtmask) *evtmask = reply->eventmask; } } SERVER_END_REQ; @@ -781,7 +781,7 @@ BOOL WINAPI SetCommMask( req->handle = handle; req->flags = SERIALINFO_SET_MASK; req->eventmask = evtmask; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1347,13 +1347,13 @@ BOOL WINAPI GetCommTimeouts( SERVER_START_REQ( get_serial_info ) { req->handle = hComm; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - lptimeouts->ReadIntervalTimeout = req->readinterval; - lptimeouts->ReadTotalTimeoutMultiplier = req->readmult; - lptimeouts->ReadTotalTimeoutConstant = req->readconst; - lptimeouts->WriteTotalTimeoutMultiplier = req->writemult; - lptimeouts->WriteTotalTimeoutConstant = req->writeconst; + lptimeouts->ReadIntervalTimeout = reply->readinterval; + lptimeouts->ReadTotalTimeoutMultiplier = reply->readmult; + lptimeouts->ReadTotalTimeoutConstant = reply->readconst; + lptimeouts->WriteTotalTimeoutMultiplier = reply->writemult; + lptimeouts->WriteTotalTimeoutConstant = reply->writeconst; } } SERVER_END_REQ; @@ -1401,7 +1401,7 @@ BOOL WINAPI SetCommTimeouts( req->readconst = lptimeouts->ReadTotalTimeoutConstant ; req->writemult = lptimeouts->WriteTotalTimeoutMultiplier ; req->writeconst = lptimeouts->WriteTotalTimeoutConstant ; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; if (!ret) return FALSE; @@ -1562,7 +1562,7 @@ static BOOL COMM_WaitCommEvent( req->count = 0; req->type = ASYNC_TYPE_WAIT; - ret=SERVER_CALL_ERR(); + ret=wine_server_call_err( req ); } SERVER_END_REQ; diff --git a/dlls/kernel/console.c b/dlls/kernel/console.c new file mode 100644 index 00000000000..14517d12a1e --- /dev/null +++ b/dlls/kernel/console.c @@ -0,0 +1,806 @@ +/* + * Win32 kernel functions + * + * Copyright 1995 Martin von Loewis and Cameron Heide + * Copyright 1997 Karl Garrison + * Copyright 1998 John Richardson + * Copyright 1998 Marcus Meissner + * Copyright 2001 Eric Pouech + * Copyright 2001 Alexandre Julliard + */ + +/* Reference applications: + * - IDA (interactive disassembler) full version 3.75. Works. + * - LYNX/W32. Works mostly, some keys crash it. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "winbase.h" +#include "winnls.h" +#include "winerror.h" +#include "wincon.h" +#include "wine/server.h" +#include "wine/exception.h" +#include "wine/unicode.h" +#include "debugtools.h" + +DEFAULT_DEBUG_CHANNEL(console); + + +static UINT console_input_codepage; +static UINT console_output_codepage; + +/* map input records to Ascii */ +static void input_records_WtoA( INPUT_RECORD *buffer, int count ) +{ + int i; + char ch; + + for (i = 0; i < count; i++) + { + if (buffer[i].EventType != KEY_EVENT) continue; + WideCharToMultiByte( GetConsoleCP(), 0, + &buffer[i].Event.KeyEvent.uChar.UnicodeChar, 1, &ch, 1, NULL, NULL ); + buffer[i].Event.KeyEvent.uChar.AsciiChar = ch; + } +} + +/* map input records to Unicode */ +static void input_records_AtoW( INPUT_RECORD *buffer, int count ) +{ + int i; + WCHAR ch; + + for (i = 0; i < count; i++) + { + if (buffer[i].EventType != KEY_EVENT) continue; + MultiByteToWideChar( GetConsoleCP(), 0, + &buffer[i].Event.KeyEvent.uChar.AsciiChar, 1, &ch, 1 ); + buffer[i].Event.KeyEvent.uChar.UnicodeChar = ch; + } +} + +/* map char infos to Ascii */ +static void char_info_WtoA( CHAR_INFO *buffer, int count ) +{ + char ch; + + while (count-- > 0) + { + WideCharToMultiByte( GetConsoleOutputCP(), 0, &buffer->Char.UnicodeChar, 1, + &ch, 1, NULL, NULL ); + buffer->Char.AsciiChar = ch; + buffer++; + } +} + +/* map char infos to Unicode */ +static void char_info_AtoW( CHAR_INFO *buffer, int count ) +{ + WCHAR ch; + + while (count-- > 0) + { + MultiByteToWideChar( GetConsoleOutputCP(), 0, &buffer->Char.AsciiChar, 1, &ch, 1 ); + buffer->Char.UnicodeChar = ch; + buffer++; + } +} + + +/****************************************************************************** + * GetConsoleCP [KERNEL32.@] Returns the OEM code page for the console + * + * RETURNS + * Code page code + */ +UINT WINAPI GetConsoleCP(VOID) +{ + if (!console_input_codepage) console_input_codepage = GetOEMCP(); + return console_input_codepage; +} + + +/****************************************************************************** + * SetConsoleCP [KERNEL32.@] + */ +BOOL WINAPI SetConsoleCP(UINT cp) +{ + if (!IsValidCodePage( cp )) return FALSE; + console_input_codepage = cp; + return TRUE; +} + + +/*********************************************************************** + * GetConsoleOutputCP (KERNEL32.@) + */ +UINT WINAPI GetConsoleOutputCP(VOID) +{ + if (!console_output_codepage) console_output_codepage = GetOEMCP(); + return console_output_codepage; +} + + +/****************************************************************************** + * SetConsoleOutputCP [KERNEL32.@] Set the output codepage used by the console + * + * PARAMS + * cp [I] code page to set + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI SetConsoleOutputCP(UINT cp) +{ + if (!IsValidCodePage( cp )) return FALSE; + console_output_codepage = cp; + return TRUE; +} + + +/****************************************************************************** + * WriteConsoleInputA [KERNEL32.@] + */ +BOOL WINAPI WriteConsoleInputA( HANDLE handle, const INPUT_RECORD *buffer, + DWORD count, LPDWORD written ) +{ + INPUT_RECORD *recW; + BOOL ret; + + if (!(recW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*recW) ))) return FALSE; + memcpy( recW, buffer, count ); + input_records_AtoW( recW, count ); + ret = WriteConsoleInputW( handle, recW, count, written ); + HeapFree( GetProcessHeap(), 0, recW ); + return ret; +} + + +/****************************************************************************** + * WriteConsoleInputW [KERNEL32.@] + */ +BOOL WINAPI WriteConsoleInputW( HANDLE handle, const INPUT_RECORD *buffer, + DWORD count, LPDWORD written ) +{ + BOOL ret; + + TRACE("(%d,%p,%ld,%p)\n", handle, buffer, count, written); + + if (written) *written = 0; + SERVER_START_REQ( write_console_input ) + { + req->handle = handle; + wine_server_add_data( req, buffer, count * sizeof(INPUT_RECORD) ); + if ((ret = !wine_server_call_err( req ))) + { + if (written) *written = reply->written; + } + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** + * WriteConsoleOutputA (KERNEL32.@) + */ +BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput, const CHAR_INFO *lpBuffer, + COORD size, COORD coord, LPSMALL_RECT region ) +{ + int y; + BOOL ret; + COORD new_size, new_coord; + CHAR_INFO *ciw; + + new_size.X = min( region->Right - region->Left + 1, size.X - coord.X ); + new_size.Y = min( region->Bottom - region->Top + 1, size.Y - coord.Y ); + + if (new_size.X <= 0 || new_size.Y <= 0) + { + region->Bottom = region->Top + new_size.Y - 1; + region->Right = region->Left + new_size.X - 1; + return TRUE; + } + + /* only copy the useful rectangle */ + if (!(ciw = HeapAlloc( GetProcessHeap(), 0, sizeof(CHAR_INFO) * new_size.X * new_size.Y ))) + return FALSE; + for (y = 0; y < new_size.Y; y++) + { + memcpy( &ciw[y * new_size.X], &lpBuffer[(y + coord.Y) * size.X + coord.X], + new_size.X * sizeof(CHAR_INFO) ); + char_info_AtoW( ciw, new_size.X ); + } + new_coord.X = new_coord.Y = 0; + ret = WriteConsoleOutputW( hConsoleOutput, ciw, new_size, new_coord, region ); + if (ciw) HeapFree( GetProcessHeap(), 0, ciw ); + return ret; +} + + +/*********************************************************************** + * WriteConsoleOutputW (KERNEL32.@) + */ +BOOL WINAPI WriteConsoleOutputW( HANDLE hConsoleOutput, const CHAR_INFO *lpBuffer, + COORD size, COORD coord, LPSMALL_RECT region ) +{ + int width, height, y; + BOOL ret = TRUE; + + TRACE("(%x,%p,(%d,%d),(%d,%d),(%d,%dx%d,%d)\n", + hConsoleOutput, lpBuffer, size.X, size.Y, coord.X, coord.Y, + region->Left, region->Top, region->Right, region->Bottom); + + width = min( region->Right - region->Left + 1, size.X - coord.X ); + height = min( region->Bottom - region->Top + 1, size.Y - coord.Y ); + + if (width > 0 && height > 0) + { + for (y = 0; y < height; y++) + { + SERVER_START_REQ( write_console_output ) + { + req->handle = hConsoleOutput; + req->x = region->Left; + req->y = region->Top + y; + req->mode = CHAR_INFO_MODE_TEXTATTR; + req->wrap = FALSE; + wine_server_add_data( req, &lpBuffer[(y + coord.Y) * size.X + coord.X], + width * sizeof(CHAR_INFO)); + if ((ret = !wine_server_call_err( req ))) + { + width = min( width, reply->width - region->Left ); + height = min( height, reply->height - region->Top ); + } + } + SERVER_END_REQ; + if (!ret) break; + } + } + region->Bottom = region->Top + height - 1; + region->Right = region->Left + width - 1; + return ret; +} + + +/****************************************************************************** + * WriteConsoleOutputCharacterA [KERNEL32.@] Copies character to consecutive + * cells in the console screen buffer + * + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * str [I] Pointer to buffer with chars to write + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumCharsWritten [O] Pointer to number of cells written + */ +BOOL WINAPI WriteConsoleOutputCharacterA( HANDLE hConsoleOutput, LPCSTR str, DWORD length, + COORD coord, LPDWORD lpNumCharsWritten ) +{ + BOOL ret; + LPWSTR strW; + DWORD lenW; + + TRACE("(%d,%s,%ld,%dx%d,%p)\n", hConsoleOutput, + debugstr_an(str, length), length, coord.X, coord.Y, lpNumCharsWritten); + + lenW = MultiByteToWideChar( GetConsoleOutputCP(), 0, str, length, NULL, 0 ); + + if (lpNumCharsWritten) *lpNumCharsWritten = 0; + + if (!(strW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) ))) return FALSE; + MultiByteToWideChar( GetConsoleOutputCP(), 0, str, length, strW, lenW ); + + ret = WriteConsoleOutputCharacterW( hConsoleOutput, strW, lenW, coord, lpNumCharsWritten ); + HeapFree( GetProcessHeap(), 0, strW ); + return ret; +} + + +/****************************************************************************** + * WriteConsoleOutputAttribute [KERNEL32.@] Sets attributes for some cells in + * the console screen buffer + * + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * attr [I] Pointer to buffer with write attributes + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumAttrsWritten [O] Pointer to number of cells written + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +BOOL WINAPI WriteConsoleOutputAttribute( HANDLE hConsoleOutput, CONST WORD *attr, DWORD length, + COORD coord, LPDWORD lpNumAttrsWritten ) +{ + BOOL ret; + + TRACE("(%d,%p,%ld,%dx%d,%p)\n", hConsoleOutput,attr,length,coord.X,coord.Y,lpNumAttrsWritten); + + SERVER_START_REQ( write_console_output ) + { + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_ATTR; + req->wrap = TRUE; + wine_server_add_data( req, attr, length * sizeof(WORD) ); + if ((ret = !wine_server_call_err( req ))) + { + if (lpNumAttrsWritten) *lpNumAttrsWritten = reply->written; + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * FillConsoleOutputCharacterA [KERNEL32.@] + * + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * ch [I] Character to write + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumCharsWritten [O] Pointer to number of cells written + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI FillConsoleOutputCharacterA( HANDLE hConsoleOutput, CHAR ch, DWORD length, + COORD coord, LPDWORD lpNumCharsWritten ) +{ + WCHAR wch; + + MultiByteToWideChar( GetConsoleOutputCP(), 0, &ch, 1, &wch, 1 ); + return FillConsoleOutputCharacterW(hConsoleOutput, wch, length, coord, lpNumCharsWritten); +} + + +/****************************************************************************** + * FillConsoleOutputCharacterW [KERNEL32.@] Writes characters to console + * + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * ch [I] Character to write + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumCharsWritten [O] Pointer to number of cells written + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI FillConsoleOutputCharacterW( HANDLE hConsoleOutput, WCHAR ch, DWORD length, + COORD coord, LPDWORD lpNumCharsWritten) +{ + BOOL ret; + + TRACE("(%d,%s,%ld,(%dx%d),%p)\n", + hConsoleOutput, debugstr_wn(&ch, 1), length, coord.X, coord.Y, lpNumCharsWritten); + + SERVER_START_REQ( fill_console_output ) + { + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_TEXT; + req->wrap = TRUE; + req->data.ch = ch; + req->count = length; + if ((ret = !wine_server_call_err( req ))) + { + if (lpNumCharsWritten) *lpNumCharsWritten = reply->written; + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * FillConsoleOutputAttribute [KERNEL32.@] Sets attributes for console + * + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * attr [I] Color attribute to write + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumAttrsWritten [O] Pointer to number of cells written + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI FillConsoleOutputAttribute( HANDLE hConsoleOutput, WORD attr, DWORD length, + COORD coord, LPDWORD lpNumAttrsWritten ) +{ + BOOL ret; + + TRACE("(%d,%d,%ld,(%dx%d),%p)\n", + hConsoleOutput, attr, length, coord.X, coord.Y, lpNumAttrsWritten); + + SERVER_START_REQ( fill_console_output ) + { + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_ATTR; + req->wrap = TRUE; + req->data.attr = attr; + req->count = length; + if ((ret = !wine_server_call_err( req ))) + { + if (lpNumAttrsWritten) *lpNumAttrsWritten = reply->written; + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * ReadConsoleOutputCharacterA [KERNEL32.@] + * + */ +BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE hConsoleOutput, LPSTR lpstr, DWORD count, + COORD coord, LPDWORD read_count) +{ + DWORD read; + BOOL ret; + LPWSTR wptr = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)); + + if (read_count) *read_count = 0; + if (!wptr) return FALSE; + + if ((ret = ReadConsoleOutputCharacterW( hConsoleOutput, wptr, count, coord, &read ))) + { + read = WideCharToMultiByte( GetConsoleOutputCP(), 0, wptr, read, lpstr, count, NULL, NULL); + if (read_count) *read_count = read; + } + HeapFree( GetProcessHeap(), 0, wptr ); + return ret; +} + + +/****************************************************************************** + * ReadConsoleOutputCharacterW [KERNEL32.@] + * + */ +BOOL WINAPI ReadConsoleOutputCharacterW( HANDLE hConsoleOutput, LPWSTR buffer, DWORD count, + COORD coord, LPDWORD read_count ) +{ + BOOL ret; + + TRACE( "(%d,%p,%ld,%dx%d,%p)\n", hConsoleOutput, buffer, count, coord.X, coord.Y, read_count ); + + SERVER_START_REQ( read_console_output ) + { + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_TEXT; + req->wrap = TRUE; + wine_server_set_reply( req, buffer, count * sizeof(WCHAR) ); + if ((ret = !wine_server_call_err( req ))) + { + if (read_count) *read_count = wine_server_reply_size(reply) / sizeof(WCHAR); + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * ReadConsoleOutputAttribute [KERNEL32.@] + */ +BOOL WINAPI ReadConsoleOutputAttribute(HANDLE hConsoleOutput, LPWORD lpAttribute, DWORD length, + COORD coord, LPDWORD read_count) +{ + BOOL ret; + + TRACE("(%d,%p,%ld,%dx%d,%p)\n", + hConsoleOutput, lpAttribute, length, coord.X, coord.Y, read_count); + + SERVER_START_REQ( read_console_output ) + { + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_ATTR; + req->wrap = TRUE; + wine_server_set_reply( req, lpAttribute, length * sizeof(WORD) ); + if ((ret = !wine_server_call_err( req ))) + { + if (read_count) *read_count = wine_server_reply_size(reply) / sizeof(WORD); + } + } + SERVER_END_REQ; + return ret; +} + + +/****************************************************************************** + * ReadConsoleOutputA [KERNEL32.@] + * + */ +BOOL WINAPI ReadConsoleOutputA( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD size, + COORD coord, LPSMALL_RECT region ) +{ + BOOL ret; + int y; + + ret = ReadConsoleOutputW( hConsoleOutput, lpBuffer, size, coord, region ); + if (ret && region->Right >= region->Left) + { + for (y = 0; y <= region->Bottom - region->Top; y++) + { + char_info_WtoA( &lpBuffer[(coord.Y + y) * size.X + coord.X], + region->Right - region->Left + 1 ); + } + } + return ret; +} + + +/****************************************************************************** + * ReadConsoleOutputW [KERNEL32.@] + * + * NOTE: The NT4 (sp5) kernel crashes on me if size is (0,0). I don't + * think we need to be *that* compatible. -- AJ + */ +BOOL WINAPI ReadConsoleOutputW( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD size, + COORD coord, LPSMALL_RECT region ) +{ + int width, height, y; + BOOL ret = TRUE; + + width = min( region->Right - region->Left + 1, size.X - coord.X ); + height = min( region->Bottom - region->Top + 1, size.Y - coord.Y ); + + if (width > 0 && height > 0) + { + for (y = 0; y < height; y++) + { + SERVER_START_REQ( read_console_output ) + { + req->handle = hConsoleOutput; + req->x = region->Left; + req->y = region->Top + y; + req->mode = CHAR_INFO_MODE_TEXTATTR; + req->wrap = FALSE; + wine_server_set_reply( req, &lpBuffer[(y+coord.Y) * size.X + coord.X], + width * sizeof(CHAR_INFO) ); + if ((ret = !wine_server_call_err( req ))) + { + width = min( width, reply->width - region->Left ); + height = min( height, reply->height - region->Top ); + } + } + SERVER_END_REQ; + if (!ret) break; + } + } + region->Bottom = region->Top + height - 1; + region->Right = region->Left + width - 1; + return ret; +} + + +/****************************************************************************** + * ReadConsoleInputA [KERNEL32.@] Reads data from a console + * + * PARAMS + * handle [I] Handle to console input buffer + * buffer [O] Address of buffer for read data + * count [I] Number of records to read + * pRead [O] Address of number of records read + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI ReadConsoleInputA( HANDLE handle, LPINPUT_RECORD buffer, DWORD count, LPDWORD pRead ) +{ + DWORD read; + + if (!ReadConsoleInputW( handle, buffer, count, &read )) return FALSE; + input_records_WtoA( buffer, read ); + if (pRead) *pRead = read; + return TRUE; +} + + +/*********************************************************************** + * PeekConsoleInputA (KERNEL32.@) + * + * Gets 'count' first events (or less) from input queue. + */ +BOOL WINAPI PeekConsoleInputA( HANDLE handle, LPINPUT_RECORD buffer, DWORD count, LPDWORD pRead ) +{ + DWORD read; + + if (!PeekConsoleInputW( handle, buffer, count, &read )) return FALSE; + input_records_WtoA( buffer, read ); + if (pRead) *pRead = read; + return TRUE; +} + + +/*********************************************************************** + * PeekConsoleInputW (KERNEL32.@) + */ +BOOL WINAPI PeekConsoleInputW( HANDLE handle, LPINPUT_RECORD buffer, DWORD count, LPDWORD read ) +{ + BOOL ret; + SERVER_START_REQ( read_console_input ) + { + req->handle = handle; + req->flush = FALSE; + wine_server_set_reply( req, buffer, count * sizeof(INPUT_RECORD) ); + if ((ret = !wine_server_call_err( req ))) + { + if (read) *read = count ? reply->read : 0; + } + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** + * GetNumberOfConsoleInputEvents (KERNEL32.@) + */ +BOOL WINAPI GetNumberOfConsoleInputEvents( HANDLE handle, LPDWORD nrofevents ) +{ + BOOL ret; + SERVER_START_REQ( read_console_input ) + { + req->handle = handle; + req->flush = FALSE; + if ((ret = !wine_server_call_err( req ))) + { + if (nrofevents) *nrofevents = reply->read; + } + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** + * FlushConsoleInputBuffer (KERNEL32.@) + */ +BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle ) +{ + BOOL ret; + SERVER_START_REQ( read_console_input ) + { + req->handle = handle; + req->flush = TRUE; + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** + * SetConsoleTitleA (KERNEL32.@) + */ +BOOL WINAPI SetConsoleTitleA( LPCSTR title ) +{ + LPWSTR titleW; + BOOL ret; + + DWORD len = MultiByteToWideChar( GetConsoleOutputCP(), 0, title, -1, NULL, 0 ); + if (!(titleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)))) return FALSE; + MultiByteToWideChar( GetConsoleOutputCP(), 0, title, -1, titleW, len ); + ret = SetConsoleTitleW(titleW); + HeapFree(GetProcessHeap(), 0, titleW); + return ret; +} + + +/*********************************************************************** + * GetConsoleTitleA (KERNEL32.@) + */ +DWORD WINAPI GetConsoleTitleA(LPSTR title, DWORD size) +{ + WCHAR *ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * size); + DWORD ret; + + if (!ptr) return 0; + ret = GetConsoleTitleW( ptr, size ); + if (ret) + { + WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr, ret + 1, title, size, NULL, NULL); + ret = strlen(title); + } + return ret; +} + + +/****************************************************************************** + * GetConsoleTitleW [KERNEL32.@] Retrieves title string for console + * + * PARAMS + * title [O] Address of buffer for title + * size [I] Size of buffer + * + * RETURNS + * Success: Length of string copied + * Failure: 0 + */ +DWORD WINAPI GetConsoleTitleW(LPWSTR title, DWORD size) +{ + DWORD ret = 0; + + SERVER_START_REQ( get_console_input_info ) + { + req->handle = 0; + wine_server_set_reply( req, title, (size-1) * sizeof(WCHAR) ); + if (!wine_server_call_err( req )) + { + ret = wine_server_reply_size(reply) / sizeof(WCHAR); + title[ret] = 0; + } + } + SERVER_END_REQ; + return ret; +} + + +/*********************************************************************** + * GetLargestConsoleWindowSize (KERNEL32.@) + * + * NOTE + * This should return a COORD, but calling convention for returning + * structures is different between Windows and gcc on i386. + * + * VERSION: [i386] + */ +#ifdef __i386__ +#undef GetLargestConsoleWindowSize +DWORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) +{ + COORD c; + c.X = 80; + c.Y = 24; + return *(DWORD *)&c; +} +#endif /* defined(__i386__) */ + + +/*********************************************************************** + * GetLargestConsoleWindowSize (KERNEL32.@) + * + * NOTE + * This should return a COORD, but calling convention for returning + * structures is different between Windows and gcc on i386. + * + * VERSION: [!i386] + */ +#ifndef __i386__ +COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) +{ + COORD c; + c.X = 80; + c.Y = 24; + return c; +} +#endif /* defined(__i386__) */ diff --git a/dlls/kernel/debugger.c b/dlls/kernel/debugger.c index 0fdd3823d5b..fbe8ff6aba6 100644 --- a/dlls/kernel/debugger.c +++ b/dlls/kernel/debugger.c @@ -36,78 +36,78 @@ BOOL WINAPI WaitForDebugEvent( for (;;) { HANDLE wait = 0; - debug_event_t *data; - SERVER_START_VAR_REQ( wait_debug_event, sizeof(*data) ) + debug_event_t data; + SERVER_START_REQ( wait_debug_event ) { req->get_handle = (timeout != 0); - if (!(ret = !SERVER_CALL_ERR())) goto done; + wine_server_set_reply( req, &data, sizeof(data) ); + if (!(ret = !wine_server_call_err( req ))) goto done; - if (!server_data_size(req)) /* timeout */ + if (!wine_server_reply_size(reply)) /* timeout */ { - wait = req->wait; + wait = reply->wait; ret = FALSE; goto done; } - data = server_data_ptr(req); - event->dwDebugEventCode = data->code; - event->dwProcessId = (DWORD)req->pid; - event->dwThreadId = (DWORD)req->tid; - switch(data->code) + event->dwDebugEventCode = data.code; + event->dwProcessId = (DWORD)reply->pid; + event->dwThreadId = (DWORD)reply->tid; + switch(data.code) { case EXCEPTION_DEBUG_EVENT: - event->u.Exception.ExceptionRecord = data->info.exception.record; - event->u.Exception.dwFirstChance = data->info.exception.first; + event->u.Exception.ExceptionRecord = data.info.exception.record; + event->u.Exception.dwFirstChance = data.info.exception.first; break; case CREATE_THREAD_DEBUG_EVENT: - event->u.CreateThread.hThread = data->info.create_thread.handle; - event->u.CreateThread.lpThreadLocalBase = data->info.create_thread.teb; - event->u.CreateThread.lpStartAddress = data->info.create_thread.start; + event->u.CreateThread.hThread = data.info.create_thread.handle; + event->u.CreateThread.lpThreadLocalBase = data.info.create_thread.teb; + event->u.CreateThread.lpStartAddress = data.info.create_thread.start; break; case CREATE_PROCESS_DEBUG_EVENT: - event->u.CreateProcessInfo.hFile = data->info.create_process.file; - event->u.CreateProcessInfo.hProcess = data->info.create_process.process; - event->u.CreateProcessInfo.hThread = data->info.create_process.thread; - event->u.CreateProcessInfo.lpBaseOfImage = data->info.create_process.base; - event->u.CreateProcessInfo.dwDebugInfoFileOffset = data->info.create_process.dbg_offset; - event->u.CreateProcessInfo.nDebugInfoSize = data->info.create_process.dbg_size; - event->u.CreateProcessInfo.lpThreadLocalBase = data->info.create_process.teb; - event->u.CreateProcessInfo.lpStartAddress = data->info.create_process.start; - event->u.CreateProcessInfo.lpImageName = data->info.create_process.name; - event->u.CreateProcessInfo.fUnicode = data->info.create_process.unicode; - if (data->info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; + event->u.CreateProcessInfo.hFile = data.info.create_process.file; + event->u.CreateProcessInfo.hProcess = data.info.create_process.process; + event->u.CreateProcessInfo.hThread = data.info.create_process.thread; + event->u.CreateProcessInfo.lpBaseOfImage = data.info.create_process.base; + event->u.CreateProcessInfo.dwDebugInfoFileOffset = data.info.create_process.dbg_offset; + event->u.CreateProcessInfo.nDebugInfoSize = data.info.create_process.dbg_size; + event->u.CreateProcessInfo.lpThreadLocalBase = data.info.create_process.teb; + event->u.CreateProcessInfo.lpStartAddress = data.info.create_process.start; + event->u.CreateProcessInfo.lpImageName = data.info.create_process.name; + event->u.CreateProcessInfo.fUnicode = data.info.create_process.unicode; + if (data.info.create_process.file == -1) event->u.CreateProcessInfo.hFile = 0; break; case EXIT_THREAD_DEBUG_EVENT: - event->u.ExitThread.dwExitCode = data->info.exit.exit_code; + event->u.ExitThread.dwExitCode = data.info.exit.exit_code; break; case EXIT_PROCESS_DEBUG_EVENT: - event->u.ExitProcess.dwExitCode = data->info.exit.exit_code; + event->u.ExitProcess.dwExitCode = data.info.exit.exit_code; break; case LOAD_DLL_DEBUG_EVENT: - event->u.LoadDll.hFile = data->info.load_dll.handle; - event->u.LoadDll.lpBaseOfDll = data->info.load_dll.base; - event->u.LoadDll.dwDebugInfoFileOffset = data->info.load_dll.dbg_offset; - event->u.LoadDll.nDebugInfoSize = data->info.load_dll.dbg_size; - event->u.LoadDll.lpImageName = data->info.load_dll.name; - event->u.LoadDll.fUnicode = data->info.load_dll.unicode; - if (data->info.load_dll.handle == -1) event->u.LoadDll.hFile = 0; + event->u.LoadDll.hFile = data.info.load_dll.handle; + event->u.LoadDll.lpBaseOfDll = data.info.load_dll.base; + event->u.LoadDll.dwDebugInfoFileOffset = data.info.load_dll.dbg_offset; + event->u.LoadDll.nDebugInfoSize = data.info.load_dll.dbg_size; + event->u.LoadDll.lpImageName = data.info.load_dll.name; + event->u.LoadDll.fUnicode = data.info.load_dll.unicode; + if (data.info.load_dll.handle == -1) event->u.LoadDll.hFile = 0; break; case UNLOAD_DLL_DEBUG_EVENT: - event->u.UnloadDll.lpBaseOfDll = data->info.unload_dll.base; + event->u.UnloadDll.lpBaseOfDll = data.info.unload_dll.base; break; case OUTPUT_DEBUG_STRING_EVENT: - event->u.DebugString.lpDebugStringData = data->info.output_string.string; - event->u.DebugString.fUnicode = data->info.output_string.unicode; - event->u.DebugString.nDebugStringLength = data->info.output_string.length; + event->u.DebugString.lpDebugStringData = data.info.output_string.string; + event->u.DebugString.fUnicode = data.info.output_string.unicode; + event->u.DebugString.nDebugStringLength = data.info.output_string.length; break; case RIP_EVENT: - event->u.RipInfo.dwError = data->info.rip_info.error; - event->u.RipInfo.dwType = data->info.rip_info.type; + event->u.RipInfo.dwError = data.info.rip_info.error; + event->u.RipInfo.dwType = data.info.rip_info.type; break; } done: /* nothing */ ; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (ret) return TRUE; if (!wait) break; res = WaitForSingleObject( wait, timeout ); @@ -140,7 +140,7 @@ BOOL WINAPI ContinueDebugEvent( req->pid = (void *)pid; req->tid = (void *)tid; req->status = status; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -163,7 +163,7 @@ BOOL WINAPI DebugActiveProcess( SERVER_START_REQ( debug_process ) { req->pid = (void *)pid; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -184,7 +184,7 @@ void WINAPI OutputDebugStringA( req->string = (void *)str; req->unicode = 0; req->length = strlen(str) + 1; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; WARN("%s\n", str); @@ -205,7 +205,7 @@ void WINAPI OutputDebugStringW( req->string = (void *)str; req->unicode = 1; req->length = (lstrlenW(str) + 1) * sizeof(WCHAR); - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; WARN("%s\n", debugstr_w(str)); @@ -278,7 +278,7 @@ BOOL WINAPI IsDebuggerPresent(void) SERVER_START_REQ( get_process_info ) { req->handle = GetCurrentProcess(); - if (!SERVER_CALL_ERR()) ret = req->debugged; + if (!wine_server_call_err( req )) ret = reply->debugged; } SERVER_END_REQ; return ret; diff --git a/dlls/kernel/sync.c b/dlls/kernel/sync.c index 5fe788a9dbb..4d746428572 100644 --- a/dlls/kernel/sync.c +++ b/dlls/kernel/sync.c @@ -30,25 +30,16 @@ DEFAULT_DEBUG_CHANNEL(win32); HANDLE WINAPI CreateEventA( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, BOOL initial_state, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return CreateEventW( sa, manual_reset, initial_state, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_event, len * sizeof(WCHAR) ) - { - req->manual_reset = manual_reset; - req->initial_state = initial_state; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return CreateEventW( sa, manual_reset, initial_state, buffer ); } @@ -74,17 +65,17 @@ HANDLE WINAPI CreateEventW( SECURITY_ATTRIBUTES *sa, BOOL manual_reset, SetLastError( ERROR_INVALID_PARAMETER); return 0; } - SERVER_START_VAR_REQ( create_event, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_event ) { req->manual_reset = manual_reset; req->initial_state = initial_state; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -103,23 +94,16 @@ HANDLE WINAPI WIN16_CreateEvent( BOOL manual_reset, BOOL initial_state ) */ HANDLE WINAPI OpenEventA( DWORD access, BOOL inherit, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenEventW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_event, len * sizeof(WCHAR) ) - { - req->access = access; - req->inherit = inherit; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return OpenEventW( access, inherit, buffer ); } @@ -135,15 +119,15 @@ HANDLE WINAPI OpenEventW( DWORD access, BOOL inherit, LPCWSTR name ) SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_event, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_event ) { req->access = access; req->inherit = inherit; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -160,7 +144,7 @@ static BOOL EVENT_Operation( HANDLE handle, enum event_op op ) { req->handle = handle; req->op = op; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -248,24 +232,16 @@ VOID WINAPI VWin32_EventSet(HANDLE event) */ HANDLE WINAPI CreateMutexA( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return CreateMutexW( sa, owner, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_mutex, len * sizeof(WCHAR) ) - { - req->owned = owner; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return CreateMutexW( sa, owner, buffer ); } @@ -281,47 +257,35 @@ HANDLE WINAPI CreateMutexW( SECURITY_ATTRIBUTES *sa, BOOL owner, LPCWSTR name ) SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_mutex, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_mutex ) { req->owned = owner; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } -/* - * Mutexes - */ - - /*********************************************************************** * OpenMutexA (KERNEL32.@) */ HANDLE WINAPI OpenMutexA( DWORD access, BOOL inherit, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenMutexW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_mutex, len * sizeof(WCHAR) ) - { - req->access = access; - req->inherit = inherit; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return OpenMutexW( access, inherit, buffer ); } @@ -337,15 +301,15 @@ HANDLE WINAPI OpenMutexW( DWORD access, BOOL inherit, LPCWSTR name ) SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_mutex, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_mutex ) { req->access = access; req->inherit = inherit; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -359,7 +323,7 @@ BOOL WINAPI ReleaseMutex( HANDLE handle ) SERVER_START_REQ( release_mutex ) { req->handle = handle; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -376,34 +340,16 @@ BOOL WINAPI ReleaseMutex( HANDLE handle ) */ HANDLE WINAPI CreateSemaphoreA( SECURITY_ATTRIBUTES *sa, LONG initial, LONG max, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; + WCHAR buffer[MAX_PATH]; - /* Check parameters */ + if (!name) return CreateSemaphoreW( sa, initial, max, NULL ); - if ((max <= 0) || (initial < 0) || (initial > max)) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; - } - if (len >= MAX_PATH) + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - - SERVER_START_VAR_REQ( create_semaphore, len * sizeof(WCHAR) ) - { - req->initial = (unsigned int)initial; - req->max = (unsigned int)max; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return CreateSemaphoreW( sa, initial, max, buffer ); } @@ -429,17 +375,17 @@ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, return 0; } - SERVER_START_VAR_REQ( create_semaphore, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_semaphore ) { req->initial = (unsigned int)initial; req->max = (unsigned int)max; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -449,23 +395,16 @@ HANDLE WINAPI CreateSemaphoreW( SECURITY_ATTRIBUTES *sa, LONG initial, */ HANDLE WINAPI OpenSemaphoreA( DWORD access, BOOL inherit, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenSemaphoreW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_semaphore, len * sizeof(WCHAR) ) - { - req->access = access; - req->inherit = inherit; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return OpenSemaphoreW( access, inherit, buffer ); } @@ -481,15 +420,15 @@ HANDLE WINAPI OpenSemaphoreW( DWORD access, BOOL inherit, LPCWSTR name ) SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_semaphore, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_semaphore ) { req->access = access; req->inherit = inherit; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -518,35 +457,18 @@ HANDLE WINAPI CreateNamedPipeA( LPCSTR name, DWORD dwOpenMode, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES attr ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; + WCHAR buffer[MAX_PATH]; - TRACE("(%s, %#08lx, %#08lx, %ld, %ld, %ld, %ld, %p): stub\n", - debugstr_a(name), dwOpenMode, dwPipeMode, nMaxInstances, - nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr ); + if (!name) return CreateNamedPipeW( NULL, dwOpenMode, dwPipeMode, nMaxInstances, + nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr ); - if (len >= MAX_PATH) + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) ) - { - req->openmode = dwOpenMode; - req->pipemode = dwPipeMode; - req->maxinstances = nMaxInstances; - req->outsize = nOutBufferSize; - req->insize = nInBufferSize; - req->timeout = nDefaultTimeOut; - - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - TRACE("Returned %d\n",ret); - return ret; + return CreateNamedPipeW( buffer, dwOpenMode, dwPipeMode, nMaxInstances, + nOutBufferSize, nInBufferSize, nDefaultTimeOut, attr ); } @@ -570,7 +492,7 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode, SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_named_pipe, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_named_pipe ) { req->openmode = dwOpenMode; req->pipemode = dwPipeMode; @@ -578,13 +500,12 @@ HANDLE WINAPI CreateNamedPipeW( LPCWSTR name, DWORD dwOpenMode, req->outsize = nOutBufferSize; req->insize = nInBufferSize; req->timeout = nDefaultTimeOut; - - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -613,99 +534,40 @@ static void SYNC_CompletePipeOverlapped (LPOVERLAPPED overlapped, DWORD result) SetEvent(overlapped->hEvent); } -/*********************************************************************** - * WaitNamedPipeA (KERNEL32.@) - */ -static BOOL SYNC_WaitNamedPipeA (LPCSTR name, DWORD nTimeOut, LPOVERLAPPED overlapped) -{ - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - BOOL ret; - - if (len >= MAX_PATH) - { - SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return FALSE; - } - - SERVER_START_VAR_REQ( wait_named_pipe, len * sizeof(WCHAR) ) - { - req->timeout = nTimeOut; - req->overlapped = overlapped; - req->func = SYNC_CompletePipeOverlapped; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - ret = !SERVER_CALL_ERR(); - } - SERVER_END_REQ; - - return ret; -} /*********************************************************************** * WaitNamedPipeA (KERNEL32.@) */ BOOL WINAPI WaitNamedPipeA (LPCSTR name, DWORD nTimeOut) { - BOOL ret; - OVERLAPPED ov; + WCHAR buffer[MAX_PATH]; - TRACE("%s 0x%08lx\n",debugstr_a(name),nTimeOut); + if (!name) return WaitNamedPipeW( NULL, nTimeOut ); - memset(&ov,0,sizeof ov); - ov.hEvent = CreateEventA( NULL, 0, 0, NULL ); - if (!ov.hEvent) - return FALSE; - - /* expect to fail with STATUS_PENDING */ - ret = SYNC_WaitNamedPipeA(name, nTimeOut, &ov); - if(ret) - { - if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE)) - { - SetLastError(ov.Internal); - ret = (ov.Internal==STATUS_SUCCESS); - } - } - - CloseHandle(ov.hEvent); - return ret; -} - - -/*********************************************************************** - * WaitNamedPipeW (KERNEL32.@) - */ -static BOOL SYNC_WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut, LPOVERLAPPED overlapped) -{ - DWORD len = name ? strlenW(name) : 0; - BOOL ret; - - if (len >= MAX_PATH) + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); - return FALSE; + return 0; } - - SERVER_START_VAR_REQ( wait_named_pipe, len * sizeof(WCHAR) ) - { - req->timeout = nTimeOut; - req->overlapped = overlapped; - req->func = SYNC_CompletePipeOverlapped; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - ret = !SERVER_CALL_ERR(); - } - SERVER_END_REQ; - - return ret; + return WaitNamedPipeW( buffer, nTimeOut ); } + /*********************************************************************** * WaitNamedPipeW (KERNEL32.@) */ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut) { + DWORD len = name ? strlenW(name) : 0; BOOL ret; OVERLAPPED ov; + if (len >= MAX_PATH) + { + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + return FALSE; + } + TRACE("%s 0x%08lx\n",debugstr_w(name),nTimeOut); memset(&ov,0,sizeof ov); @@ -713,7 +575,16 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut) if (!ov.hEvent) return FALSE; - ret = SYNC_WaitNamedPipeW(name, nTimeOut, &ov); + SERVER_START_REQ( wait_named_pipe ) + { + req->timeout = nTimeOut; + req->overlapped = &ov; + req->func = SYNC_CompletePipeOverlapped; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + if(ret) { if (WAIT_OBJECT_0==WaitForSingleObject(ov.hEvent,INFINITE)) @@ -722,9 +593,7 @@ BOOL WINAPI WaitNamedPipeW (LPCWSTR name, DWORD nTimeOut) ret = (ov.Internal==STATUS_SUCCESS); } } - CloseHandle(ov.hEvent); - return ret; } @@ -746,7 +615,7 @@ static BOOL SYNC_ConnectNamedPipe(HANDLE hPipe, LPOVERLAPPED overlapped) req->handle = hPipe; req->overlapped = overlapped; req->func = SYNC_CompletePipeOverlapped; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -798,7 +667,7 @@ BOOL WINAPI DisconnectNamedPipe(HANDLE hPipe) SERVER_START_REQ( disconnect_named_pipe ) { req->handle = hPipe; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -835,15 +704,11 @@ BOOL WINAPI GetNamedPipeInfo( SERVER_START_REQ( get_named_pipe_info ) { req->handle = hNamedPipe; - ret = !SERVER_CALL_ERR(); - if(lpFlags) - *lpFlags = req->flags; - if(lpOutputBufferSize) - *lpOutputBufferSize = req->outsize; - if(lpInputBufferSize) - *lpInputBufferSize = req->outsize; - if(lpMaxInstances) - *lpMaxInstances = req->maxinstances; + ret = !wine_server_call_err( req ); + if(lpFlags) *lpFlags = reply->flags; + if(lpOutputBufferSize) *lpOutputBufferSize = reply->outsize; + if(lpInputBufferSize) *lpInputBufferSize = reply->outsize; + if(lpMaxInstances) *lpMaxInstances = reply->maxinstances; } SERVER_END_REQ; diff --git a/dlls/kernel/toolhelp.c b/dlls/kernel/toolhelp.c index ed9ddb83e7e..7c1dc712935 100644 --- a/dlls/kernel/toolhelp.c +++ b/dlls/kernel/toolhelp.c @@ -206,8 +206,8 @@ HANDLE WINAPI CreateToolhelp32Snapshot( DWORD flags, DWORD process ) req->flags = flags & ~TH32CS_INHERIT; req->inherit = (flags & TH32CS_INHERIT) != 0; req->pid = (void *)process; - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } SERVER_END_REQ; if (!ret) ret = INVALID_HANDLE_VALUE; @@ -234,13 +234,13 @@ static BOOL TOOLHELP_Thread32Next( HANDLE handle, LPTHREADENTRY32 lpte, BOOL fir { req->handle = handle; req->reset = first; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - lpte->cntUsage = req->count; - lpte->th32ThreadID = (DWORD)req->tid; - lpte->th32OwnerProcessID = (DWORD)req->pid; - lpte->tpBasePri = req->base_pri; - lpte->tpDeltaPri = req->delta_pri; + lpte->cntUsage = reply->count; + lpte->th32ThreadID = (DWORD)reply->tid; + lpte->th32OwnerProcessID = (DWORD)reply->pid; + lpte->tpBasePri = reply->base_pri; + lpte->tpDeltaPri = reply->delta_pri; lpte->dwFlags = 0; /* SDK: "reserved; do not use" */ } } @@ -287,15 +287,15 @@ static BOOL TOOLHELP_Process32Next( HANDLE handle, LPPROCESSENTRY32 lppe, BOOL f { req->handle = handle; req->reset = first; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - lppe->cntUsage = req->count; - lppe->th32ProcessID = (DWORD)req->pid; + lppe->cntUsage = reply->count; + lppe->th32ProcessID = (DWORD)reply->pid; lppe->th32DefaultHeapID = 0; /* FIXME */ lppe->th32ModuleID = 0; /* FIXME */ - lppe->cntThreads = req->threads; + lppe->cntThreads = reply->threads; lppe->th32ParentProcessID = 0; /* FIXME */ - lppe->pcPriClassBase = req->priority; + lppe->pcPriClassBase = reply->priority; lppe->dwFlags = -1; /* FIXME */ lppe->szExeFile[0] = 0; /* FIXME */ } @@ -345,15 +345,15 @@ static BOOL TOOLHELP_Module32Next( HANDLE handle, LPMODULEENTRY32 lpme, BOOL fir { req->handle = handle; req->reset = first; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { lpme->th32ModuleID = 0; /* toolhelp internal id, never used */ - lpme->th32ProcessID = (DWORD)req->pid; + lpme->th32ProcessID = (DWORD)reply->pid; lpme->GlblcntUsage = 0; /* FIXME */ - lpme->ProccntUsage = 0; /* FIXME */ - lpme->modBaseAddr = req->base; + lpme->ProccntUsage = 0; /* FIXME */ + lpme->modBaseAddr = reply->base; lpme->modBaseSize = 0; /* FIXME */ - lpme->hModule = (DWORD)req->base; + lpme->hModule = (DWORD)reply->base; lpme->szModule[0] = 0; /* FIXME */ lpme->szExePath[0] = 0; /* FIXME */ } diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c index 90927ad68b2..a59e30bce8e 100644 --- a/dlls/ntdll/exception.c +++ b/dlls/ntdll/exception.c @@ -115,29 +115,28 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c int ret; HANDLE handle = 0; - SERVER_START_VAR_REQ( queue_exception_event, sizeof(*rec)+sizeof(*context) ) + SERVER_START_REQ( queue_exception_event ) { - CONTEXT *context_ptr = server_data_ptr(req); - EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1); req->first = first_chance; - *rec_ptr = *rec; - *context_ptr = *context; - if (!SERVER_CALL()) handle = req->handle; + wine_server_add_data( req, context, sizeof(*context) ); + wine_server_add_data( req, rec, sizeof(*rec) ); + if (!wine_server_call( req )) handle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!handle) return 0; /* no debugger present or other error */ /* No need to wait on the handle since the process gets suspended * once the event is passed to the debugger, so when we get back * here the event has been continued already. */ - SERVER_START_VAR_REQ( get_exception_status, sizeof(*context) ) + SERVER_START_REQ( get_exception_status ) { req->handle = handle; - if (!SERVER_CALL()) *context = *(CONTEXT *)server_data_ptr(req); - ret = req->status; + wine_server_set_reply( req, context, sizeof(*context) ); + wine_server_call( req ); + ret = reply->status; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; NtClose( handle ); return ret; } diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 46f1a107d19..73a4abe8b2f 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -82,8 +82,8 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code ) { req->handle = handle; req->exit_code = exit_code; - ret = SERVER_CALL(); - self = !ret && req->self; + ret = wine_server_call( req ); + self = !ret && reply->self; } SERVER_END_REQ; if (self) exit( exit_code ); @@ -159,9 +159,9 @@ NTSTATUS WINAPI NtTerminateThread( HANDLE handle, LONG exit_code ) { req->handle = handle; req->exit_code = exit_code; - ret = SERVER_CALL(); - self = !ret && req->self; - last = req->last; + ret = wine_server_call( req ); + self = !ret && reply->self; + last = reply->last; } SERVER_END_REQ; diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index bd088f3f99d..2cc319b1b84 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -1033,6 +1033,4 @@ debug_channels (aspi atom cdrom console ddraw debug delayhlp dll dosfs dosmem @ cdecl __wine_get_wmain_args(ptr) __wine_get_wmain_args # Server interface -@ cdecl -norelay wine_server_call(ptr long) wine_server_call -@ cdecl -norelay wine_server_alloc_req(ptr long) wine_server_alloc_req -@ cdecl -norelay __wine_server_exception_handler(ptr ptr ptr ptr) __wine_server_exception_handler +@ cdecl -norelay wine_server_call(ptr) wine_server_call diff --git a/dlls/ntdll/om.c b/dlls/ntdll/om.c index 9a573b9c116..437d2b6be10 100644 --- a/dlls/ntdll/om.c +++ b/dlls/ntdll/om.c @@ -222,8 +222,8 @@ NTSTATUS WINAPI NtClose( HANDLE Handle ) SERVER_START_REQ( close_handle ) { req->handle = Handle; - ret = SERVER_CALL(); - if (!ret && req->fd != -1) close( req->fd ); + ret = wine_server_call( req ); + if (!ret && reply->fd != -1) close( reply->fd ); } SERVER_END_REQ; return ret; diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c index 5dc307daea0..f271c0f71a7 100644 --- a/dlls/ntdll/reg.c +++ b/dlls/ntdll/reg.c @@ -35,39 +35,29 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT PULONG dispos ) { NTSTATUS ret; - DWORD len = attr->ObjectName->Length; TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName), debugstr_us(class), options, access, retkey ); - if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; - len += sizeof(WCHAR); /* for storing name length */ - if (class) - { - len += class->Length; - if (len > REQUEST_MAX_VAR_SIZE) return STATUS_BUFFER_OVERFLOW; - } + if (attr->ObjectName->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; if (!retkey) return STATUS_INVALID_PARAMETER; - SERVER_START_VAR_REQ( create_key, len ) + SERVER_START_REQ( create_key ) { - WCHAR *data = server_data_ptr(req); - req->parent = attr->RootDirectory; req->access = access; req->options = options; req->modif = 0; - - *data++ = attr->ObjectName->Length; - memcpy( data, attr->ObjectName->Buffer, attr->ObjectName->Length ); - if (class) memcpy( (char *)data + attr->ObjectName->Length, class->Buffer, class->Length ); - if (!(ret = SERVER_CALL())) + req->namelen = attr->ObjectName->Length; + wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length ); + if (class) wine_server_add_data( req, class->Buffer, class->Length ); + if (!(ret = wine_server_call( req ))) { - *retkey = req->hkey; - if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY; + *retkey = reply->hkey; + if (dispos) *dispos = reply->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; TRACE("<- 0x%04x\n", *retkey); return ret; } @@ -92,15 +82,15 @@ NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTR if (len > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; if (!retkey) return STATUS_INVALID_PARAMETER; - SERVER_START_VAR_REQ( open_key, len ) + SERVER_START_REQ( open_key ) { req->parent = attr->RootDirectory; req->access = access; - memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); - ret = SERVER_CALL(); - *retkey = req->hkey; + wine_server_add_data( req, attr->ObjectName->Buffer, len ); + ret = wine_server_call( req ); + *retkey = reply->hkey; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; TRACE("<- 0x%04x\n", *retkey); return ret; } @@ -119,7 +109,7 @@ NTSTATUS WINAPI NtDeleteKey( HANDLE hkey ) SERVER_START_REQ( delete_key ) { req->hkey = hkey; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } SERVER_END_REQ; return ret; @@ -137,102 +127,101 @@ NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name ) TRACE( "(0x%x,%s)\n", hkey, debugstr_us(name) ); if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; - SERVER_START_VAR_REQ( delete_key_value, name->Length ) + SERVER_START_REQ( delete_key_value ) { req->hkey = hkey; - memcpy( server_data_ptr(req), name->Buffer, name->Length ); - ret = SERVER_CALL(); + wine_server_add_data( req, name->Buffer, name->Length ); + ret = wine_server_call( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } /****************************************************************************** - * fill_key_info + * enumerate_key * - * Helper function for NtQueryKey and NtEnumerateKey + * Implementation of NtQueryKey and NtEnumerateKey */ -static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWORD length, - DWORD *result_len, const struct enum_key_request *req ) -{ - WCHAR *name_ptr = server_data_ptr(req); - int name_size = *name_ptr++; - WCHAR *class_ptr = (WCHAR *)((char *)name_ptr + name_size); - int class_size = server_data_size(req) - sizeof(WCHAR) - name_size; - int fixed_size; - LARGE_INTEGER modif; +static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS info_class, + void *info, DWORD length, DWORD *result_len ) - RtlSecondsSince1970ToTime( req->modif, (FILETIME *)&modif ); +{ + NTSTATUS ret; + void *data_ptr; + size_t fixed_size; switch(info_class) { - case KeyBasicInformation: - { - KEY_BASIC_INFORMATION keyinfo; - fixed_size = (char *)keyinfo.Name - (char *)&keyinfo; - keyinfo.LastWriteTime = modif; - keyinfo.TitleIndex = 0; - keyinfo.NameLength = name_size; - memcpy( info, &keyinfo, min( length, fixed_size ) ); - class_size = 0; - } - break; - case KeyFullInformation: - { - KEY_FULL_INFORMATION keyinfo; - fixed_size = (char *)keyinfo.Class - (char *)&keyinfo; - keyinfo.LastWriteTime = modif; - keyinfo.TitleIndex = 0; - keyinfo.ClassLength = class_size; - keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1; - keyinfo.SubKeys = req->subkeys; - keyinfo.MaxNameLen = req->max_subkey; - keyinfo.MaxClassLen = req->max_class; - keyinfo.Values = req->values; - keyinfo.MaxValueNameLen = req->max_value; - keyinfo.MaxValueDataLen = req->max_data; - memcpy( info, &keyinfo, min( length, fixed_size ) ); - name_size = 0; - } - break; - case KeyNodeInformation: - { - KEY_NODE_INFORMATION keyinfo; - fixed_size = (char *)keyinfo.Name - (char *)&keyinfo; - keyinfo.LastWriteTime = modif; - keyinfo.TitleIndex = 0; - keyinfo.ClassLength = class_size; - keyinfo.ClassOffset = fixed_size + name_size; - if (!keyinfo.ClassLength || keyinfo.ClassOffset > length) keyinfo.ClassOffset = -1; - keyinfo.NameLength = name_size; - memcpy( info, &keyinfo, min( length, fixed_size ) ); - } - break; + case KeyBasicInformation: data_ptr = ((KEY_BASIC_INFORMATION *)info)->Name; break; + case KeyFullInformation: data_ptr = ((KEY_FULL_INFORMATION *)info)->Class; break; + case KeyNodeInformation: data_ptr = ((KEY_NODE_INFORMATION *)info)->Name; break; default: - FIXME("Information class not implemented\n"); + FIXME( "Information class %d not implemented\n", info_class ); return STATUS_INVALID_PARAMETER; } + fixed_size = (char *)data_ptr - (char *)info; - *result_len = fixed_size + name_size + class_size; - if (length <= fixed_size) return STATUS_BUFFER_OVERFLOW; - length -= fixed_size; - - /* copy the name */ - if (name_size) + SERVER_START_REQ( enum_key ) { - memcpy( (char *)info + fixed_size, name_ptr, min(length,name_size) ); - if (length < name_size) return STATUS_BUFFER_OVERFLOW; - length -= name_size; - } + req->hkey = handle; + req->index = index; + req->info_class = info_class; + if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size ); + if (!(ret = wine_server_call( req ))) + { + LARGE_INTEGER modif; - /* copy the class */ - if (class_size) - { - memcpy( (char *)info + fixed_size + name_size, class_ptr, min(length,class_size) ); - if (length < class_size) return STATUS_BUFFER_OVERFLOW; + RtlSecondsSince1970ToTime( reply->modif, (FILETIME *)&modif ); + + switch(info_class) + { + case KeyBasicInformation: + { + KEY_BASIC_INFORMATION keyinfo; + fixed_size = (char *)keyinfo.Name - (char *)&keyinfo; + keyinfo.LastWriteTime = modif; + keyinfo.TitleIndex = 0; + keyinfo.NameLength = reply->namelen; + memcpy( info, &keyinfo, min( length, fixed_size ) ); + } + break; + case KeyFullInformation: + { + KEY_FULL_INFORMATION keyinfo; + fixed_size = (char *)keyinfo.Class - (char *)&keyinfo; + keyinfo.LastWriteTime = modif; + keyinfo.TitleIndex = 0; + keyinfo.ClassLength = wine_server_reply_size(reply); + keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1; + keyinfo.SubKeys = reply->subkeys; + keyinfo.MaxNameLen = reply->max_subkey; + keyinfo.MaxClassLen = reply->max_class; + keyinfo.Values = reply->values; + keyinfo.MaxValueNameLen = reply->max_value; + keyinfo.MaxValueDataLen = reply->max_data; + memcpy( info, &keyinfo, min( length, fixed_size ) ); + } + break; + case KeyNodeInformation: + { + KEY_NODE_INFORMATION keyinfo; + fixed_size = (char *)keyinfo.Name - (char *)&keyinfo; + keyinfo.LastWriteTime = modif; + keyinfo.TitleIndex = 0; + keyinfo.ClassLength = max( 0, wine_server_reply_size(reply) - reply->namelen ); + keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size + reply->namelen : -1; + keyinfo.NameLength = reply->namelen; + memcpy( info, &keyinfo, min( length, fixed_size ) ); + } + break; + } + *result_len = fixed_size + reply->total; + if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW; + } } - return STATUS_SUCCESS; + SERVER_END_REQ; + return ret; } @@ -247,23 +236,9 @@ static NTSTATUS fill_key_info( KEY_INFORMATION_CLASS info_class, void *info, DWO NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class, void *info, DWORD length, DWORD *result_len ) { - NTSTATUS ret; - /* -1 means query key, so avoid it here */ if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES; - - SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE ) - { - req->hkey = handle; - req->index = index; - req->full = (info_class == KeyFullInformation); - if (!(ret = SERVER_CALL())) - { - ret = fill_key_info( info_class, info, length, result_len, req ); - } - } - SERVER_END_VAR_REQ; - return ret; + return enumerate_key( handle, index, info_class, info, length, result_len ); } @@ -274,20 +249,7 @@ NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLAS NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class, void *info, DWORD length, DWORD *result_len ) { - NTSTATUS ret; - - SERVER_START_VAR_REQ( enum_key, REQUEST_MAX_VAR_SIZE ) - { - req->hkey = handle; - req->index = -1; - req->full = (info_class == KeyFullInformation); - if (!(ret = SERVER_CALL())) - { - ret = fill_key_info( info_class, info, length, result_len, req ); - } - } - SERVER_END_VAR_REQ; - return ret; + return enumerate_key( handle, -1, info_class, info, length, result_len ); } @@ -344,98 +306,39 @@ NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index, void *info, DWORD length, DWORD *result_len ) { NTSTATUS ret; - UCHAR *data_ptr; - WCHAR *name_ptr; - int fixed_size = 0, name_len = 0, data_len = 0, offset = 0, type = 0, total_len = 0; + void *ptr; + size_t fixed_size; TRACE( "(0x%x,%lu,%d,%p,%ld)\n", handle, index, info_class, info, length ); /* compute the length we want to retrieve */ switch(info_class) { - case KeyValueBasicInformation: - name_ptr = ((KEY_VALUE_BASIC_INFORMATION *)info)->Name; - data_ptr = NULL; - fixed_size = (char *)name_ptr - (char *)info; - break; - case KeyValueFullInformation: - name_ptr = ((KEY_VALUE_FULL_INFORMATION *)info)->Name; - data_ptr = (UCHAR *)name_ptr; - fixed_size = (char *)name_ptr - (char *)info; - break; - case KeyValuePartialInformation: - name_ptr = NULL; - data_ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data; - fixed_size = (char *)data_ptr - (char *)info; - break; + case KeyValueBasicInformation: ptr = ((KEY_VALUE_BASIC_INFORMATION *)info)->Name; break; + case KeyValueFullInformation: ptr = ((KEY_VALUE_FULL_INFORMATION *)info)->Name; break; + case KeyValuePartialInformation: ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data; break; default: FIXME( "Information class %d not implemented\n", info_class ); return STATUS_INVALID_PARAMETER; } - if (length > fixed_size) data_len = length - fixed_size; + fixed_size = (char *)ptr - (char *)info; - do + SERVER_START_REQ( enum_key_value ) { - size_t reqlen = data_len + sizeof(WCHAR); - if (name_ptr && !offset) reqlen += MAX_PATH*sizeof(WCHAR); - reqlen = min( reqlen, REQUEST_MAX_VAR_SIZE ); - - SERVER_START_VAR_REQ( enum_key_value, reqlen ) + req->hkey = handle; + req->index = index; + req->info_class = info_class; + if (length > fixed_size) wine_server_set_reply( req, ptr, length - fixed_size ); + if (!(ret = wine_server_call( req ))) { - req->hkey = handle; - req->index = index; - req->offset = offset; - - if (!(ret = SERVER_CALL())) - { - size_t size = server_data_size(req) - sizeof(WCHAR); - WCHAR *name = server_data_ptr(req); - if (!offset) /* name is only present on the first request */ - { - name_len = *name++; - size -= name_len; - if (name_ptr) - { - if (name_len > data_len) /* overflow */ - { - memcpy( name_ptr, name, data_len ); - data_len = 0; - ret = STATUS_BUFFER_OVERFLOW; - } - else - { - memcpy( name_ptr, name, name_len ); - data_len -= name_len; - if (data_ptr) data_ptr += name_len; - } - } - name += name_len / sizeof(WCHAR); - } - else name++; /* skip 0 length */ - - if (data_ptr) - { - size = min( size, data_len ); - memcpy( data_ptr + offset, name, size ); - offset += size; - data_len -= size; - } - type = req->type; - total_len = req->len; - } + copy_key_value_info( info_class, info, length, reply->type, reply->namelen, + wine_server_reply_size(reply) - reply->namelen ); + *result_len = fixed_size + reply->total; + if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW; } - SERVER_END_VAR_REQ; - if (ret) return ret; - } while (data_len && data_ptr && offset < total_len); - - *result_len = total_len + fixed_size + (name_ptr ? name_len : 0); - - if (data_ptr && offset < total_len) ret = STATUS_BUFFER_OVERFLOW; - if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW; - - copy_key_value_info( info_class, info, length, type, name_len, total_len ); + } + SERVER_END_REQ; return ret; - } @@ -452,7 +355,7 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, { NTSTATUS ret; UCHAR *data_ptr; - int fixed_size = 0, data_len = 0, offset = 0, type = 0, total_len = 0; + int fixed_size = 0; TRACE( "(0x%x,%s,%d,%p,%ld)\n", handle, debugstr_us(name), info_class, info, length ); @@ -477,45 +380,21 @@ NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name, FIXME( "Information class %d not implemented\n", info_class ); return STATUS_INVALID_PARAMETER; } - if (data_ptr && length > fixed_size) data_len = length - fixed_size; - do + SERVER_START_REQ( get_key_value ) { - size_t reqlen = min( data_len, REQUEST_MAX_VAR_SIZE ); - reqlen = max( reqlen, name->Length + sizeof(WCHAR) ); - - SERVER_START_VAR_REQ( get_key_value, reqlen ) + req->hkey = handle; + wine_server_add_data( req, name->Buffer, name->Length ); + if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size ); + if (!(ret = wine_server_call( req ))) { - WCHAR *nameptr = server_data_ptr(req); - - req->hkey = handle; - req->offset = offset; - *nameptr++ = name->Length; - memcpy( nameptr, name->Buffer, name->Length ); - - if (!(ret = SERVER_CALL())) - { - size_t size = min( server_data_size(req), data_len ); - type = req->type; - total_len = req->len; - if (size) - { - memcpy( data_ptr + offset, server_data_ptr(req), size ); - offset += size; - data_len -= size; - } - } + copy_key_value_info( info_class, info, length, reply->type, + 0, wine_server_reply_size(reply) ); + *result_len = fixed_size + reply->total; + if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW; } - SERVER_END_VAR_REQ; - if (ret) return ret; - } while (data_len && offset < total_len); - - *result_len = total_len + fixed_size; - - if (offset < total_len) ret = STATUS_BUFFER_OVERFLOW; - if (length < fixed_size) ret = STATUS_BUFFER_OVERFLOW; - - copy_key_value_info( info_class, info, length, type, 0, total_len ); + } + SERVER_END_REQ; return ret; } @@ -651,36 +530,21 @@ NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG Ti ULONG type, const void *data, ULONG count ) { NTSTATUS ret; - ULONG namelen, pos; TRACE( "(0x%x,%s,%ld,%p,%ld)\n", hkey, debugstr_us(name), type, data, count ); if (name->Length > MAX_NAME_LENGTH) return STATUS_BUFFER_OVERFLOW; - namelen = name->Length + sizeof(WCHAR); /* for storing length */ - pos = 0; - - do + SERVER_START_REQ( set_key_value ) { - ULONG len = count - pos; - if (len > REQUEST_MAX_VAR_SIZE - namelen) len = REQUEST_MAX_VAR_SIZE - namelen; - - SERVER_START_VAR_REQ( set_key_value, namelen + len ) - { - WCHAR *name_ptr = server_data_ptr(req); - - req->hkey = hkey; - req->type = type; - req->total = count; - req->offset = pos; - *name_ptr++ = name->Length; - memcpy( name_ptr, name->Buffer, name->Length ); - memcpy( (char *)name_ptr + name->Length, (char *)data + pos, len ); - pos += len; - ret = SERVER_CALL(); - } - SERVER_END_VAR_REQ; - } while (!ret && pos < count); + req->hkey = hkey; + req->type = type; + req->namelen = name->Length; + wine_server_add_data( req, name->Buffer, name->Length ); + wine_server_add_data( req, data, count ); + ret = wine_server_call( req ); + } + SERVER_END_REQ; return ret; } diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c index 57a7bd4cb22..37d8b629c09 100644 --- a/dlls/ntdll/sync.c +++ b/dlls/ntdll/sync.c @@ -36,16 +36,16 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT PHANDLE SemaphoreHandle, if ((MaximumCount <= 0) || (InitialCount > MaximumCount)) return STATUS_INVALID_PARAMETER; - SERVER_START_VAR_REQ( create_semaphore, len ) + SERVER_START_REQ( create_semaphore ) { req->initial = InitialCount; req->max = MaximumCount; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); - if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); - ret = SERVER_CALL(); - *SemaphoreHandle = req->handle; + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + ret = wine_server_call( req ); + *SemaphoreHandle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -59,15 +59,15 @@ NTSTATUS WINAPI NtOpenSemaphore( OUT PHANDLE SemaphoreHandle, DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - SERVER_START_VAR_REQ( open_semaphore, len ) + SERVER_START_REQ( open_semaphore ) { req->access = access; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); - if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); - ret = SERVER_CALL(); - *SemaphoreHandle = req->handle; + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + ret = wine_server_call( req ); + *SemaphoreHandle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -96,9 +96,9 @@ NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous { req->handle = handle; req->count = count; - if (!(ret = SERVER_CALL())) + if (!(ret = wine_server_call( req ))) { - if (previous) *previous = req->prev_count; + if (previous) *previous = reply->prev_count; } } SERVER_END_REQ; @@ -123,16 +123,16 @@ NTSTATUS WINAPI NtCreateEvent( DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - SERVER_START_VAR_REQ( create_event, len ) + SERVER_START_REQ( create_event ) { req->manual_reset = ManualReset; req->initial_state = InitialState; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); - if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); - ret = SERVER_CALL(); - *EventHandle = req->handle; + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + ret = wine_server_call( req ); + *EventHandle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -148,15 +148,15 @@ NTSTATUS WINAPI NtOpenEvent( DWORD len = attr && attr->ObjectName ? attr->ObjectName->Length : 0; NTSTATUS ret; - SERVER_START_VAR_REQ( open_event, len ) + SERVER_START_REQ( open_event ) { req->access = DesiredAccess; req->inherit = attr && (attr->Attributes & OBJ_INHERIT); - if (len) memcpy( server_data_ptr(req), attr->ObjectName->Buffer, len ); - ret = SERVER_CALL(); - *EventHandle = req->handle; + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len ); + ret = wine_server_call( req ); + *EventHandle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -175,7 +175,7 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) { req->handle = handle; req->op = SET_EVENT; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } SERVER_END_REQ; return ret; @@ -195,7 +195,7 @@ NTSTATUS WINAPI NtResetEvent( HANDLE handle, PULONG NumberOfThreadsReleased ) { req->handle = handle; req->op = RESET_EVENT; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } SERVER_END_REQ; return ret; @@ -226,7 +226,7 @@ NTSTATUS WINAPI NtPulseEvent( HANDLE handle, PULONG PulseCount ) { req->handle = handle; req->op = PULSE_EVENT; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } SERVER_END_REQ; return ret; diff --git a/dlls/user/message.c b/dlls/user/message.c index e5e38a2eec2..c22285e2d30 100644 --- a/dlls/user/message.c +++ b/dlls/user/message.c @@ -200,26 +200,6 @@ inline static int is_unicode_message( UINT message ) #undef SET -/* compute the total size of the packed data */ -inline static size_t get_data_total_size( const struct packed_message *data ) -{ - int i; - size_t total = 0; - for (i = 0; i < data->count; i++) total += data->size[i]; - return total; -} - -/* copy all the data of a packed message into a single dest buffer */ -inline static void copy_all_data( void *dest, const struct packed_message *data ) -{ - int i; - for (i = 0; i < data->count; i++) - { - memcpy( dest, data->data[i], data->size[i] ); - dest = (char *)dest + data->size[i]; - } -} - /* add a data field to a packed message */ inline static void push_data( struct packed_message *data, const void *ptr, size_t size ) { @@ -1032,7 +1012,7 @@ static void unpack_reply( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, static void reply_message( struct received_message_info *info, LRESULT result, BOOL remove ) { struct packed_message data; - int replied = info->flags & ISMEX_REPLIED; + int i, replied = info->flags & ISMEX_REPLIED; if (info->flags & ISMEX_NOTIFY) return; /* notify messages don't get replies */ if (!remove && replied) return; /* replied already */ @@ -1044,34 +1024,14 @@ static void reply_message( struct received_message_info *info, LRESULT result, B { pack_reply( info->msg.hwnd, info->msg.message, info->msg.wParam, info->msg.lParam, result, &data ); - if (data.count) - { - size_t total = get_data_total_size( &data ); - - if (total > REQUEST_MAX_VAR_SIZE) - { - FIXME( "inter-process msg data size %d not supported yet, expect trouble\n", - total ); - total = REQUEST_MAX_VAR_SIZE; - } - - SERVER_START_VAR_REQ( reply_message, total ) - { - req->result = result; - req->remove = remove; - copy_all_data( server_data_ptr(req), &data ); - SERVER_CALL(); - } - SERVER_END_VAR_REQ; - return; - } } SERVER_START_REQ( reply_message ) { req->result = result; req->remove = remove; - SERVER_CALL(); + for (i = 0; i < data.count; i++) wine_server_add_data( req, data.data[i], data.size[i] ); + wine_server_call( req ); } SERVER_END_REQ; } @@ -1170,7 +1130,6 @@ static LRESULT call_window_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpar */ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) { - BOOL ret; LRESULT result; ULONG_PTR extra_info = 0; MESSAGEQUEUE *queue = QUEUE_Current(); @@ -1180,41 +1139,44 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) for (;;) { + NTSTATUS res; void *buffer = NULL; - size_t size = 0; + size_t size = 0, buffer_size = 0; - SERVER_START_VAR_REQ( get_message, REQUEST_MAX_VAR_SIZE ) + do /* loop while buffer is too small */ { - req->flags = flags; - req->get_win = hwnd; - req->get_first = first; - req->get_last = last; - if ((ret = !SERVER_CALL())) + if (buffer_size && !(buffer = HeapAlloc( GetProcessHeap(), 0, buffer_size ))) + return FALSE; + SERVER_START_REQ( get_message ) { - info.type = req->type; - info.msg.hwnd = req->win; - info.msg.message = req->msg; - info.msg.wParam = req->wparam; - info.msg.lParam = req->lparam; - info.msg.time = req->time; - info.msg.pt.x = req->x; - info.msg.pt.y = req->y; - extra_info = req->info; - - if ((size = server_data_size(req))) + req->flags = flags; + req->get_win = hwnd; + req->get_first = first; + req->get_last = last; + if (buffer_size) wine_server_set_reply( req, buffer, buffer_size ); + if (!(res = wine_server_call( req ))) { - if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size ))) - { - ERR("out of memory for message data\n"); - ret = FALSE; - } - else memcpy( buffer, server_data_ptr(req), size ); + size = wine_server_reply_size( reply ); + info.type = reply->type; + info.msg.hwnd = reply->win; + info.msg.message = reply->msg; + info.msg.wParam = reply->wparam; + info.msg.lParam = reply->lparam; + info.msg.time = reply->time; + info.msg.pt.x = reply->x; + info.msg.pt.y = reply->y; + extra_info = reply->info; + } + else + { + if (buffer) HeapFree( GetProcessHeap(), 0, buffer ); + buffer_size = reply->total; } } - } - SERVER_END_VAR_REQ; + SERVER_END_REQ; + } while (res == STATUS_BUFFER_OVERFLOW); - if (!ret) return FALSE; /* no message available */ + if (res) return FALSE; TRACE( "got type %d msg %x hwnd %x wp %x lp %lx\n", info.type, info.msg.message, info.msg.hwnd, info.msg.wParam, info.msg.lParam ); @@ -1241,26 +1203,27 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) info.msg.wParam, info.msg.lParam, size ); /* ignore it */ reply_message( &info, 0, TRUE ); - continue; + goto next; } break; case MSG_HARDWARE_RAW: if (!MSG_process_raw_hardware_message( &info.msg, extra_info, hwnd, first, last, flags & GET_MSG_REMOVE )) - continue; + goto next; /* fall through */ case MSG_HARDWARE_COOKED: if (!MSG_process_cooked_hardware_message( &info.msg, extra_info, flags & GET_MSG_REMOVE )) { flags |= GET_MSG_REMOVE_LAST; - continue; + goto next; } queue->GetMessagePosVal = MAKELONG( info.msg.pt.x, info.msg.pt.y ); /* fall through */ case MSG_POSTED: queue->GetMessageExtraInfoVal = extra_info; *msg = info.msg; + if (buffer) HeapFree( GetProcessHeap(), 0, buffer ); return TRUE; } @@ -1271,7 +1234,7 @@ BOOL MSG_peek_message( MSG *msg, HWND hwnd, UINT first, UINT last, int flags ) info.msg.lParam, (info.type != MSG_ASCII) ); reply_message( &info, result, TRUE ); queue->receive_info = old_info; - + next: if (buffer) HeapFree( GetProcessHeap(), 0, buffer ); } } @@ -1298,10 +1261,10 @@ static void wait_message_reply( UINT flags ) req->wake_mask = (flags & SMTO_BLOCK) ? 0 : QS_SENDMESSAGE; req->changed_mask = QS_SMRESULT | req->wake_mask; req->skip_wait = 1; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - wake_bits = req->wake_bits; - changed_bits = req->changed_bits; + wake_bits = reply->wake_bits; + changed_bits = reply->changed_bits; } } SERVER_END_REQ; @@ -1338,8 +1301,9 @@ static void wait_message_reply( UINT flags ) static BOOL put_message_in_queue( DWORD dest_tid, const struct send_message_info *info, size_t *reply_size ) { + struct packed_message data; unsigned int res; - int timeout = -1; + int i, timeout = -1; if (info->type != MSG_NOTIFY && info->type != MSG_CALLBACK && @@ -1347,47 +1311,17 @@ static BOOL put_message_in_queue( DWORD dest_tid, const struct send_message_info info->timeout != INFINITE) timeout = info->timeout; + data.count = 0; if (info->type == MSG_OTHER_PROCESS) { - struct packed_message data; *reply_size = pack_message( info->hwnd, info->msg, info->wparam, info->lparam, &data ); - if (data.count == -1) { WARN( "cannot pack message %x\n", info->msg ); return FALSE; } - - if (data.size[0]) /* need to send extra data along with the message */ - { - size_t total = get_data_total_size( &data ); - - if (total > REQUEST_MAX_VAR_SIZE) - { - FIXME( "inter-process msg data size %d not supported yet, expect trouble\n", - total ); - total = REQUEST_MAX_VAR_SIZE; - } - - SERVER_START_VAR_REQ( send_message, total ) - { - req->id = (void *)dest_tid; - req->type = MSG_OTHER_PROCESS; - req->win = info->hwnd; - req->msg = info->msg; - req->wparam = info->wparam; - req->lparam = info->lparam; - req->time = GetCurrentTime(); - req->timeout = timeout; - copy_all_data( server_data_ptr(req), &data ); - res = SERVER_CALL(); - } - SERVER_END_VAR_REQ; - goto done; - } } - /* no extra data, or not inter-process message */ SERVER_START_REQ( send_message ) { req->id = (void *)dest_tid; @@ -1398,19 +1332,17 @@ static BOOL put_message_in_queue( DWORD dest_tid, const struct send_message_info req->lparam = info->lparam; req->time = GetCurrentTime(); req->timeout = timeout; - res = SERVER_CALL(); + for (i = 0; i < data.count; i++) wine_server_add_data( req, data.data[i], data.size[i] ); + if ((res = wine_server_call( req ))) + { + if (res == STATUS_INVALID_PARAMETER) + /* FIXME: find a STATUS_ value for this one */ + SetLastError( ERROR_INVALID_THREAD_ID ); + else + SetLastError( RtlNtStatusToDosError(res) ); + } } SERVER_END_REQ; - - done: - if (res) - { - if (res == STATUS_INVALID_PARAMETER) - /* FIXME: find a STATUS_ value for this one */ - SetLastError( ERROR_INVALID_THREAD_ID ); - else - SetLastError( RtlNtStatusToDosError(res) ); - } return !res; } @@ -1424,35 +1356,28 @@ static LRESULT retrieve_reply( const struct send_message_info *info, size_t reply_size, LRESULT *result ) { NTSTATUS status; + void *reply_data = NULL; if (reply_size) { - if (reply_size > REQUEST_MAX_VAR_SIZE) + if (!(reply_data = HeapAlloc( GetProcessHeap(), 0, reply_size ))) { - WARN( "reply_size %d too large, reply may be truncated\n", reply_size ); - reply_size = REQUEST_MAX_VAR_SIZE; + WARN( "no memory for reply %d bytes, will be truncated\n", reply_size ); + reply_size = 0; } - SERVER_START_VAR_REQ( get_message_reply, reply_size ) - { - req->cancel = 1; - if (!(status = SERVER_CALL())) - { - *result = req->result; - unpack_reply( info->hwnd, info->msg, info->wparam, info->lparam, - server_data_ptr(req), server_data_size(req) ); - } - } - SERVER_END_VAR_REQ; } - else + SERVER_START_REQ( get_message_reply ) { - SERVER_START_REQ( get_message_reply ) - { - req->cancel = 1; - if (!(status = SERVER_CALL())) *result = req->result; - } - SERVER_END_REQ; + req->cancel = 1; + if (reply_size) wine_server_set_reply( req, reply_data, reply_size ); + if (!(status = wine_server_call( req ))) *result = reply->result; + reply_size = wine_server_reply_size( reply ); } + SERVER_END_REQ; + if (!status && reply_size) + unpack_reply( info->hwnd, info->msg, info->wparam, info->lparam, reply_data, reply_size ); + + if (reply_data) HeapFree( GetProcessHeap(), 0, reply_data ); TRACE( "hwnd %x msg %x (%s) wp %x lp %lx got reply %lx (err=%ld)\n", info->hwnd, info->msg, SPY_GetMsgName(info->msg, info->hwnd), info->wparam, @@ -1955,10 +1880,10 @@ BOOL WINAPI GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT last ) req->wake_mask = QS_SENDMESSAGE; req->changed_mask = mask; req->skip_wait = 1; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - wake_bits = req->wake_bits; - changed_bits = req->changed_bits; + wake_bits = reply->wake_bits; + changed_bits = reply->changed_bits; } } SERVER_END_REQ; diff --git a/dlls/user/property.c b/dlls/user/property.c index a3d32ec42bb..be2d8f615ef 100644 --- a/dlls/user/property.c +++ b/dlls/user/property.c @@ -24,24 +24,30 @@ */ static property_data_t *get_properties( HWND hwnd, int *count ) { - property_data_t *ret = NULL; + property_data_t *data; + int total = 32; - SERVER_START_VAR_REQ( get_window_properties, REQUEST_MAX_VAR_SIZE ) + while (total) { - req->window = hwnd; - if (!SERVER_CALL()) + int res = 0; + if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break; + *count = 0; + SERVER_START_REQ( get_window_properties ) { - size_t size = server_data_size(req); - if (size) - { - property_data_t *data = server_data_ptr(req); - if ((ret = HeapAlloc( GetProcessHeap(), 0, size ))) memcpy( ret, data, size ); - *count = size / sizeof(*data); - } + req->window = hwnd; + wine_server_add_data( req, data, total * sizeof(*data) ); + if (!wine_server_call( req )) res = reply->total; } + SERVER_END_REQ; + if (res && res <= total) + { + *count = res; + return data; + } + HeapFree( GetProcessHeap(), 0, data ); + total = res; /* restart with larger buffer */ } - SERVER_END_VAR_REQ; - return ret; + return NULL; } @@ -102,7 +108,7 @@ HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str ) { req->window = hwnd; req->atom = atom; - if (!SERVER_CALL_ERR()) ret = req->handle; + if (!wine_server_call_err( req )) ret = reply->handle; } SERVER_END_REQ; return ret; @@ -124,7 +130,7 @@ HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str ) { req->window = hwnd; req->atom = atom; - if (!SERVER_CALL_ERR()) ret = req->handle; + if (!wine_server_call_err( req )) ret = reply->handle; } SERVER_END_REQ; return ret; @@ -148,7 +154,7 @@ BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle ) req->atom = atom; req->string = (HIWORD(str) != 0); req->handle = handle; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -174,7 +180,7 @@ BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle ) req->atom = atom; req->string = (HIWORD(str) != 0); req->handle = handle; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -217,7 +223,7 @@ HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str ) { req->window = hwnd; req->atom = atom; - if (!SERVER_CALL_ERR()) ret = req->handle; + if (!wine_server_call_err( req )) ret = reply->handle; } SERVER_END_REQ; diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c index 12b761cca0e..78b65c2b119 100644 --- a/dlls/winsock/socket.c +++ b/dlls/winsock/socket.c @@ -233,7 +233,7 @@ static void _enable_event(SOCKET s, unsigned int event, req->mask = event; req->sstate = sstate; req->cstate = cstate; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } @@ -247,8 +247,8 @@ static int _is_blocking(SOCKET s) req->service = FALSE; req->s_event = 0; req->c_event = 0; - SERVER_CALL(); - ret = (req->state & FD_WINE_NONBLOCKING) == 0; + wine_server_call( req ); + ret = (reply->state & FD_WINE_NONBLOCKING) == 0; } SERVER_END_REQ; return ret; @@ -263,8 +263,8 @@ static unsigned int _get_sock_mask(SOCKET s) req->service = FALSE; req->s_event = 0; req->c_event = 0; - SERVER_CALL(); - ret = req->mask; + wine_server_call( req ); + ret = reply->mask; } SERVER_END_REQ; return ret; @@ -279,18 +279,19 @@ static void _sync_sock_state(SOCKET s) static int _get_sock_error(SOCKET s, unsigned int bit) { - int ret; - SERVER_START_VAR_REQ( get_socket_event, FD_MAX_EVENTS*sizeof(int) ) + int events[FD_MAX_EVENTS]; + + SERVER_START_REQ( get_socket_event ) { req->handle = s; req->service = FALSE; req->s_event = 0; req->c_event = 0; - SERVER_CALL(); - ret = *((int *)server_data_ptr(req) + bit); + wine_server_set_reply( req, events, sizeof(events) ); + wine_server_call( req ); } - SERVER_END_VAR_REQ; - return ret; + SERVER_END_REQ; + return events[bit]; } static void WINSOCK_DeleteIData(void) @@ -900,8 +901,8 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, req->lhandle = s; req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->inherit = TRUE; - set_error( SERVER_CALL() ); - as = (SOCKET)req->handle; + set_error( wine_server_call( req ) ); + as = (SOCKET)reply->handle; } SERVER_END_REQ; if (as) @@ -2318,8 +2319,8 @@ SOCKET WINAPI WS_socket(int af, int type, int protocol) req->protocol = protocol; req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; req->inherit = TRUE; - set_error( SERVER_CALL() ); - ret = (SOCKET)req->handle; + set_error( wine_server_call( req ) ); + ret = (SOCKET)reply->handle; } SERVER_END_REQ; if (ret) @@ -2718,19 +2719,16 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp TRACE("%08x, hEvent %08x, lpEvent %08x\n", s, hEvent, (unsigned)lpEvent ); - SERVER_START_VAR_REQ( get_socket_event, sizeof(lpEvent->iErrorCode) ) + SERVER_START_REQ( get_socket_event ) { req->handle = s; req->service = TRUE; req->s_event = 0; req->c_event = hEvent; - if (!(ret = SERVER_CALL())) - { - lpEvent->lNetworkEvents = req->pmask & req->mask; - memcpy(lpEvent->iErrorCode, server_data_ptr(req), server_data_size(req) ); - } + wine_server_set_reply( req, lpEvent->iErrorCode, sizeof(lpEvent->iErrorCode) ); + if (!(ret = wine_server_call(req))) lpEvent->lNetworkEvents = reply->pmask & reply->mask; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!ret) return 0; SetLastError(WSAEINVAL); return SOCKET_ERROR; @@ -2750,7 +2748,7 @@ int WINAPI WSAEventSelect(SOCKET s, WSAEVENT hEvent, LONG lEvent) req->handle = s; req->mask = lEvent; req->event = hEvent; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } SERVER_END_REQ; if (!ret) return 0; @@ -2769,17 +2767,17 @@ VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr ) TRACE("socket %08x, event %08x\n", info->sock, info->event); SetLastError(0); - SERVER_START_VAR_REQ( get_socket_event, sizeof(errors) ) + SERVER_START_REQ( get_socket_event ) { req->handle = info->sock; req->service = TRUE; req->s_event = info->event; /* <== avoid race conditions */ req->c_event = info->event; - set_error( SERVER_CALL() ); - pmask = req->pmask; - memcpy( errors, server_data_ptr(req), server_data_size(req) ); + wine_server_set_reply( req, errors, sizeof(errors) ); + set_error( wine_server_call(req) ); + pmask = reply->pmask; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if ( (GetLastError() == WSAENOTSOCK) || (GetLastError() == WSAEINVAL) ) { /* orphaned event (socket closed or something) */ diff --git a/files/change.c b/files/change.c index 774a3dee4c5..1137cbbfea2 100644 --- a/files/change.c +++ b/files/change.c @@ -36,7 +36,7 @@ HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtre { req->subtree = bWatchSubtree; req->filter = dwNotifyFilter; - if (!SERVER_CALL_ERR()) ret = req->handle; + if (!wine_server_call_err( req )) ret = reply->handle; } SERVER_END_REQ; return ret; diff --git a/files/dos_fs.c b/files/dos_fs.c index 497cc1bc19e..d62cc926502 100644 --- a/files/dos_fs.c +++ b/files/dos_fs.c @@ -690,11 +690,11 @@ const DOS_DEVICE *DOSFS_GetDeviceByHandle( HFILE hFile ) SERVER_START_REQ( get_file_info ) { req->handle = hFile; - if (!SERVER_CALL() && (req->type == FILE_TYPE_UNKNOWN)) + if (!wine_server_call( req ) && (reply->type == FILE_TYPE_UNKNOWN)) { - if ((req->attr >= 0) && - (req->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) - ret = &DOSFS_Devices[req->attr]; + if ((reply->attr >= 0) && + (reply->attr < sizeof(DOSFS_Devices)/sizeof(DOSFS_Devices[0]))) + ret = &DOSFS_Devices[reply->attr]; } } SERVER_END_REQ; @@ -709,7 +709,6 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes, { HANDLE ret; char devname[40]; - size_t len; TRACE_(file)("%s %lx %lx\n", name, access, attributes); @@ -719,19 +718,18 @@ static HANDLE DOSFS_CreateCommPort(LPCSTR name, DWORD access, DWORD attributes, TRACE("opening %s as %s\n", devname, name); - len = strlen(devname); - SERVER_START_VAR_REQ( create_serial, len ) + SERVER_START_REQ( create_serial ) { req->access = access; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->attributes = attributes; req->sharing = FILE_SHARE_READ|FILE_SHARE_WRITE; - memcpy( server_data_ptr(req), devname, len ); + wine_server_add_data( req, devname, strlen(devname) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if(!ret) ERR("Couldn't open device '%s' ! (check permissions)\n",devname); diff --git a/files/file.c b/files/file.c index 42f69e7509f..3ceb98e2f3d 100644 --- a/files/file.c +++ b/files/file.c @@ -193,8 +193,8 @@ HANDLE FILE_DupUnixHandle( int fd, DWORD access, BOOL inherit ) req->access = access; req->inherit = inherit; req->fd = fd; - SERVER_CALL(); - ret = req->handle; + wine_server_call( req ); + ret = reply->handle; } SERVER_END_REQ; return ret; @@ -217,11 +217,11 @@ int FILE_GetUnixHandleType( HANDLE handle, DWORD access, DWORD *type ) { req->handle = handle; req->access = access; - if (!(ret = SERVER_CALL_ERR())) + if (!(ret = wine_server_call_err( req ))) { - fd = req->fd; + fd = reply->fd; } - if (type) *type = req->type; + if (type) *type = reply->type; } SERVER_END_REQ; if (ret) return -1; @@ -267,8 +267,8 @@ static HANDLE FILE_OpenConsole( BOOL output, DWORD access, DWORD sharing, LPSECU req->share = sharing; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } SERVER_END_REQ; return ret; @@ -286,52 +286,44 @@ HANDLE FILE_CreateFile( LPCSTR filename, DWORD access, DWORD sharing, DWORD attributes, HANDLE template, BOOL fail_read_only, UINT drive_type ) { - DWORD err; + unsigned int err; HANDLE ret; - size_t len = strlen(filename); - if (len > REQUEST_MAX_VAR_SIZE) + for (;;) { - FIXME("filename '%s' too long\n", filename ); - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; - } - - restart: - SERVER_START_VAR_REQ( create_file, len ) - { - req->access = access; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - req->sharing = sharing; - req->create = creation; - req->attrs = attributes; - req->drive_type = drive_type; - memcpy( server_data_ptr(req), filename, len ); - SetLastError(0); - err = SERVER_CALL(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - - /* If write access failed, retry without GENERIC_WRITE */ - - if (!ret && !fail_read_only && (access & GENERIC_WRITE)) - { - if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED)) + SERVER_START_REQ( create_file ) { - TRACE("Write access failed for file '%s', trying without " - "write access\n", filename); - access &= ~GENERIC_WRITE; - goto restart; + req->access = access; + req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); + req->sharing = sharing; + req->create = creation; + req->attrs = attributes; + req->drive_type = drive_type; + wine_server_add_data( req, filename, strlen(filename) ); + SetLastError(0); + err = wine_server_call( req ); + ret = reply->handle; } + SERVER_END_REQ; + + /* If write access failed, retry without GENERIC_WRITE */ + + if (!ret && !fail_read_only && (access & GENERIC_WRITE)) + { + if ((err == STATUS_MEDIA_WRITE_PROTECTED) || (err == STATUS_ACCESS_DENIED)) + { + TRACE("Write access failed for file '%s', trying without " + "write access\n", filename); + access &= ~GENERIC_WRITE; + continue; + } + } + + if (err) SetLastError( RtlNtStatusToDosError(err) ); + + if (!ret) WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError()); + return ret; } - - if (err) SetLastError( RtlNtStatusToDosError(err) ); - - if (!ret) - WARN("Unable to create file '%s' (GLE %ld)\n", filename, GetLastError()); - - return ret; } @@ -350,8 +342,8 @@ HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->id = client_id; SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } SERVER_END_REQ; return ret; @@ -359,26 +351,24 @@ HANDLE FILE_CreateDevice( int client_id, DWORD access, LPSECURITY_ATTRIBUTES sa static HANDLE FILE_OpenPipe(LPCSTR name, DWORD access) { + WCHAR buffer[MAX_PATH]; HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; + DWORD len = 0; - TRACE("name %s access %lx\n",name,access); - - if (len >= MAX_PATH) + if (name && !(len = MultiByteToWideChar( CP_ACP, 0, name, strlen(name), buffer, MAX_PATH ))) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_named_pipe, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_named_pipe ) { req->access = access; - - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; TRACE("Returned %d\n",ret); return ret; } @@ -610,32 +600,31 @@ DWORD WINAPI GetFileInformationByHandle( HANDLE hFile, SERVER_START_REQ( get_file_info ) { req->handle = hFile; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - /* FIXME: which file types are supported ? - * Serial ports (FILE_TYPE_CHAR) are not, - * and MSDN also says that pipes are not supported. - * FILE_TYPE_REMOTE seems to be supported according to - * MSDN q234741.txt */ - if ((req->type == FILE_TYPE_DISK) - || (req->type == FILE_TYPE_REMOTE)) - { - RtlSecondsSince1970ToTime( req->write_time, &info->ftCreationTime ); - RtlSecondsSince1970ToTime( req->write_time, &info->ftLastWriteTime ); - RtlSecondsSince1970ToTime( req->access_time, &info->ftLastAccessTime ); - info->dwFileAttributes = req->attr; - info->dwVolumeSerialNumber = req->serial; - info->nFileSizeHigh = req->size_high; - info->nFileSizeLow = req->size_low; - info->nNumberOfLinks = req->links; - info->nFileIndexHigh = req->index_high; - info->nFileIndexLow = req->index_low; - } - else - { - SetLastError(ERROR_NOT_SUPPORTED); - ret = 0; - } + /* FIXME: which file types are supported ? + * Serial ports (FILE_TYPE_CHAR) are not, + * and MSDN also says that pipes are not supported. + * FILE_TYPE_REMOTE seems to be supported according to + * MSDN q234741.txt */ + if ((reply->type == FILE_TYPE_DISK) || (reply->type == FILE_TYPE_REMOTE)) + { + RtlSecondsSince1970ToTime( reply->write_time, &info->ftCreationTime ); + RtlSecondsSince1970ToTime( reply->write_time, &info->ftLastWriteTime ); + RtlSecondsSince1970ToTime( reply->access_time, &info->ftLastAccessTime ); + info->dwFileAttributes = reply->attr; + info->dwVolumeSerialNumber = reply->serial; + info->nFileSizeHigh = reply->size_high; + info->nFileSizeLow = reply->size_low; + info->nNumberOfLinks = reply->links; + info->nFileIndexHigh = reply->index_high; + info->nFileIndexLow = reply->index_low; + } + else + { + SetLastError(ERROR_NOT_SUPPORTED); + ret = 0; + } } } SERVER_END_REQ; @@ -1354,9 +1343,9 @@ static BOOL FILE_GetTimeout(HANDLE hFile, DWORD txcount, DWORD type, int *timeou req->count = txcount; req->type = type; req->file_handle = hFile; - ret = SERVER_CALL(); + ret = wine_server_call( req ); if(timeout) - *timeout = req->timeout; + *timeout = reply->timeout; } SERVER_END_REQ; return !ret; @@ -1785,10 +1774,10 @@ DWORD WINAPI SetFilePointer( HANDLE hFile, LONG distance, LONG *highword, /* FIXME: assumes 1:1 mapping between Windows and Unix seek constants */ req->whence = method; SetLastError( 0 ); - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { - ret = req->new_low; - if (highword) *highword = req->new_high; + ret = reply->new_low; + if (highword) *highword = reply->new_high; } } SERVER_END_REQ; @@ -1940,7 +1929,7 @@ BOOL WINAPI FlushFileBuffers( HANDLE hFile ) SERVER_START_REQ( flush_file ) { req->handle = hFile; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1956,7 +1945,7 @@ BOOL WINAPI SetEndOfFile( HANDLE hFile ) SERVER_START_REQ( truncate_file ) { req->handle = hFile; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -2029,7 +2018,7 @@ DWORD WINAPI GetFileType( HANDLE hFile ) SERVER_START_REQ( get_file_info ) { req->handle = hFile; - if (!SERVER_CALL_ERR()) ret = req->type; + if (!wine_server_call_err( req )) ret = reply->type; } SERVER_END_REQ; return ret; @@ -2350,7 +2339,7 @@ BOOL WINAPI SetFileTime( HANDLE hFile, RtlTimeToSecondsSince1970( lpLastWriteTime, (DWORD *)&req->write_time ); else req->write_time = 0; /* FIXME */ - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -2371,7 +2360,7 @@ BOOL WINAPI LockFile( HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHig req->offset_high = dwFileOffsetHigh; req->count_low = nNumberOfBytesToLockLow; req->count_high = nNumberOfBytesToLockHigh; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -2422,7 +2411,7 @@ BOOL WINAPI UnlockFile( HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetH req->offset_high = dwFileOffsetHigh; req->count_low = nNumberOfBytesToUnlockLow; req->count_high = nNumberOfBytesToUnlockHigh; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; diff --git a/include/thread.h b/include/thread.h index 7a15948e9f0..2107056394a 100644 --- a/include/thread.h +++ b/include/thread.h @@ -90,9 +90,7 @@ typedef struct _TEB /* The following are Wine-specific fields (NT: GDI stuff) */ DWORD cleanup; /* --3 1fc Cleanup service handle */ - void *buffer; /* --3 200 Buffer shared with server */ - unsigned int buffer_pos; /* --3 204 Buffer current position */ - unsigned int buffer_size; /* --3 208 Buffer size */ + DWORD unused[3]; /* --3 200 Was server buffer */ int request_fd; /* --3 20c fd for sending server requests */ int reply_fd; /* --3 210 fd for receiving server replies */ int wait_fd[2]; /* --3 214 fd for sleeping server requests */ diff --git a/include/winbase.h b/include/winbase.h index f88012225dd..9355baff064 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1609,7 +1609,7 @@ BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR); BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); #define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct) -BOOL WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD); +BOOL WINAPI WriteProcessMemory(HANDLE,LPVOID,LPCVOID,DWORD,LPDWORD); BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR); BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR); #define WriteProfileString WINELIB_NAME_AW(WriteProfileString) diff --git a/include/wincon.h b/include/wincon.h index 233acda2005..e98b2c1d0b1 100644 --- a/include/wincon.h +++ b/include/wincon.h @@ -177,10 +177,8 @@ HANDLE WINAPI CreateConsoleScreenBuffer( DWORD dwDesiredAccess, DWORD dwShareMod LPVOID lpScreenBufferData); BOOL WINAPI FillConsoleOutputAttribute( HANDLE hConsoleOutput, WORD wAttribute, DWORD nLength, COORD dwCoord, LPDWORD lpNumAttrsWritten); -BOOL WINAPI FillConsoleOutputCharacterA( HANDLE hConsoleOutput, BYTE cCharacter, DWORD nLength, - COORD dwCoord, LPDWORD lpNumCharsWritten); -BOOL WINAPI FillConsoleOutputCharacterW( HANDLE hConsoleOutput, WCHAR cCharacter, DWORD nLength, - COORD dwCoord, LPDWORD lpNumCharsWritten); +BOOL WINAPI FillConsoleOutputCharacterA(HANDLE,CHAR,DWORD,COORD,LPDWORD); +BOOL WINAPI FillConsoleOutputCharacterW(HANDLE,WCHAR,DWORD,COORD,LPDWORD); #define FillConsoleOutputCharacter WINELIB_NAME_AW(FillConsoleOutputCharacter) BOOL WINAPI FlushConsoleInputBuffer( HANDLE handle); BOOL WINAPI FreeConsole(VOID); @@ -242,13 +240,11 @@ BOOL WINAPI SetConsoleWindowInfo( HANDLE hcon, BOOL bAbsolute, LPSMALL_RECT wi BOOL WINAPI WriteConsoleA(HANDLE,CONST VOID *,DWORD,LPDWORD,LPVOID); BOOL WINAPI WriteConsoleW(HANDLE, CONST VOID *lpBuffer, DWORD,LPDWORD,LPVOID); #define WriteConsole WINELIB_NAME_AW(WriteConsole) -BOOL WINAPI WriteConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD ); -BOOL WINAPI WriteConsoleInputW( HANDLE handle, INPUT_RECORD *buffer, DWORD, LPDWORD ); +BOOL WINAPI WriteConsoleInputA(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD); +BOOL WINAPI WriteConsoleInputW(HANDLE,const INPUT_RECORD *,DWORD,LPDWORD); #define WriteConsoleInput WINELIB_NAME_AW(WriteConsoleInput) -BOOL WINAPI WriteConsoleOutputA( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion); -BOOL WINAPI WriteConsoleOutputW( HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion); +BOOL WINAPI WriteConsoleOutputA(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT); +BOOL WINAPI WriteConsoleOutputW(HANDLE,const CHAR_INFO*,COORD,COORD,LPSMALL_RECT); #define WriteConsoleOutput WINELIB_NAME_AW(WriteConsoleOutput) BOOL WINAPI WriteConsoleOutputAttribute(HANDLE,CONST WORD *,DWORD,COORD,LPDWORD); BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,LPDWORD); diff --git a/include/wine/server.h b/include/wine/server.h index 6bc18c557f4..b6d8cdbb163 100644 --- a/include/wine/server.h +++ b/include/wine/server.h @@ -14,83 +14,90 @@ /* client communication functions */ -extern unsigned int wine_server_call( union generic_request *req, size_t size ); -extern void server_protocol_error( const char *err, ... ) WINE_NORETURN; -extern void server_protocol_perror( const char *err ) WINE_NORETURN; -extern void wine_server_alloc_req( union generic_request *req, size_t size ); +struct __server_iovec +{ + const void *ptr; + unsigned int size; +}; + +#define __SERVER_MAX_DATA 4 + +struct __server_request_info +{ + union + { + union generic_request req; /* request structure */ + union generic_reply reply; /* reply structure */ + } u; + size_t size; /* size of request structure */ + unsigned int data_count; /* count of request data pointers */ + void *reply_data; /* reply data pointer */ + struct __server_iovec data[__SERVER_MAX_DATA]; /* request variable size data */ +}; + +extern unsigned int wine_server_call( void *req_ptr ); extern void wine_server_send_fd( int fd ); extern int wine_server_recv_fd( handle_t handle ); -extern const char *get_config_dir(void); /* do a server call and set the last error code */ -inline static unsigned int __server_call_err( union generic_request *req, size_t size ) +inline static unsigned int wine_server_call_err( void *req_ptr ) { - unsigned int res = wine_server_call( req, size ); + unsigned int res = wine_server_call( req_ptr ); if (res) SetLastError( RtlNtStatusToDosError(res) ); return res; } -/* get a pointer to the variable part of the request */ -inline static void *server_data_ptr( const void *req ) +/* get the size of the variable part of the returned reply */ +inline static size_t wine_server_reply_size( const void *reply ) { - return (char *)NtCurrentTeb()->buffer + ((struct request_header *)req)->var_offset; + return ((struct reply_header *)reply)->reply_size; } -/* get the size of the variable part of the request */ -inline static size_t server_data_size( const void *req ) +/* add some data to be sent along with the request */ +inline static void wine_server_add_data( void *req_ptr, const void *ptr, unsigned int size ) { - return ((struct request_header *)req)->var_size; + struct __server_request_info * const req = req_ptr; + if (size) + { + req->data[req->data_count].ptr = ptr; + req->data[req->data_count++].size = size; + req->u.req.request_header.request_size += size; + } } - -/* exception support for server calls */ - -extern DWORD __wine_server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame, - CONTEXT *context, EXCEPTION_FRAME **pdispatcher ); - -struct __server_exception_frame +/* set the pointer and max size for the reply var data */ +inline static void wine_server_set_reply( void *req_ptr, void *ptr, unsigned int max_size ) { - EXCEPTION_FRAME frame; - unsigned int buffer_pos; /* saved buffer position */ -}; + struct __server_request_info * const req = req_ptr; + req->reply_data = ptr; + req->u.req.request_header.reply_size = max_size; +} /* macros for server requests */ #define SERVER_START_REQ(type) \ do { \ - union generic_request __req; \ - struct type##_request * const req = &__req.type; \ - __req.header.req = REQ_##type; \ - __req.header.var_size = 0; \ + struct __server_request_info __req; \ + struct type##_request * const req = &__req.u.req.type##_request; \ + const struct type##_reply * const reply = &__req.u.reply.type##_reply; \ + __req.u.req.request_header.req = REQ_##type; \ + __req.u.req.request_header.request_size = 0; \ + __req.u.req.request_header.reply_size = 0; \ + __req.size = sizeof(*req); \ + __req.data_count = 0; \ + (void)reply; \ do #define SERVER_END_REQ \ while(0); \ } while(0) -#define SERVER_START_VAR_REQ(type,size) \ - do { \ - struct __server_exception_frame __f; \ - union generic_request __req; \ - struct type##_request * const req = &__req.type; \ - __f.frame.Handler = __wine_server_exception_handler; \ - __f.buffer_pos = NtCurrentTeb()->buffer_pos; \ - __wine_push_frame( &__f.frame ); \ - __req.header.req = REQ_##type; \ - wine_server_alloc_req( &__req, (size) ); \ - do - -#define SERVER_END_VAR_REQ \ - while(0); \ - NtCurrentTeb()->buffer_pos = __f.buffer_pos; \ - __wine_pop_frame( &__f.frame ); \ - } while(0) - -#define SERVER_CALL() (wine_server_call( &__req, sizeof(*req) )) -#define SERVER_CALL_ERR() (__server_call_err( &__req, sizeof(*req) )) - +/* non-exported functions */ +extern void server_protocol_error( const char *err, ... ) WINE_NORETURN; +extern void server_protocol_perror( const char *err ) WINE_NORETURN; +extern const char *get_config_dir(void); extern void CLIENT_InitServer(void); extern void CLIENT_InitThread(void); extern void CLIENT_BootDone( int debug_level ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 94f40d6927d..58cac3faf8c 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -14,17 +14,15 @@ struct request_header { - int req; - unsigned short var_offset; - unsigned short var_size; - unsigned int error; + int req; + size_t request_size; + size_t reply_size; }; struct reply_header { - unsigned int error; - unsigned short var_offset; - unsigned short var_size; + unsigned int error; + size_t reply_size; }; @@ -149,6 +147,13 @@ typedef struct } rectangle_t; +typedef struct +{ + WCHAR ch; + unsigned short attr; +} char_info_t; + + @@ -164,6 +169,10 @@ struct new_process_request handle_t hstderr; int cmd_show; /* VARARG(filename,string); */ +}; +struct new_process_reply +{ + struct reply_header __header; handle_t info; }; @@ -175,6 +184,10 @@ struct get_new_process_info_request handle_t info; int pinherit; int tinherit; +}; +struct get_new_process_info_reply +{ + struct reply_header __header; void* pid; handle_t phandle; void* tid; @@ -190,6 +203,10 @@ struct new_thread_request int suspend; int inherit; int request_fd; +}; +struct new_thread_reply +{ + struct reply_header __header; void* tid; handle_t handle; }; @@ -201,6 +218,10 @@ struct boot_done_request struct request_header __header; int debug_level; }; +struct boot_done_reply +{ + struct reply_header __header; +}; @@ -209,6 +230,10 @@ struct init_process_request struct request_header __header; void* ldt_copy; int ppid; +}; +struct init_process_reply +{ + struct reply_header __header; int create_flags; int start_flags; unsigned int server_start; @@ -230,6 +255,10 @@ struct init_process_done_request void* name; handle_t exe_file; int gui; +}; +struct init_process_done_reply +{ + struct reply_header __header; int debugged; }; @@ -243,6 +272,10 @@ struct init_thread_request void* entry; int reply_fd; int wait_fd; +}; +struct init_thread_reply +{ + struct reply_header __header; void* pid; void* tid; int boot; @@ -251,21 +284,15 @@ struct init_thread_request -struct set_thread_buffer_request -{ - struct request_header __header; - int fd; - unsigned int offset; - unsigned int size; -}; - - - struct terminate_process_request { struct request_header __header; handle_t handle; int exit_code; +}; +struct terminate_process_reply +{ + struct reply_header __header; int self; }; @@ -276,6 +303,10 @@ struct terminate_thread_request struct request_header __header; handle_t handle; int exit_code; +}; +struct terminate_thread_reply +{ + struct reply_header __header; int self; int last; }; @@ -286,6 +317,10 @@ struct get_process_info_request { struct request_header __header; handle_t handle; +}; +struct get_process_info_reply +{ + struct reply_header __header; void* pid; int debugged; int exit_code; @@ -304,6 +339,10 @@ struct set_process_info_request int priority; int affinity; }; +struct set_process_info_reply +{ + struct reply_header __header; +}; #define SET_PROCESS_INFO_PRIORITY 0x01 #define SET_PROCESS_INFO_AFFINITY 0x02 @@ -314,6 +353,10 @@ struct get_thread_info_request struct request_header __header; handle_t handle; void* tid_in; +}; +struct get_thread_info_reply +{ + struct reply_header __header; void* tid; void* teb; int exit_code; @@ -330,6 +373,10 @@ struct set_thread_info_request int priority; int affinity; }; +struct set_thread_info_reply +{ + struct reply_header __header; +}; #define SET_THREAD_INFO_PRIORITY 0x01 #define SET_THREAD_INFO_AFFINITY 0x02 @@ -339,6 +386,10 @@ struct suspend_thread_request { struct request_header __header; handle_t handle; +}; +struct suspend_thread_reply +{ + struct reply_header __header; int count; }; @@ -348,6 +399,10 @@ struct resume_thread_request { struct request_header __header; handle_t handle; +}; +struct resume_thread_reply +{ + struct reply_header __header; int count; }; @@ -362,6 +417,10 @@ struct load_dll_request int dbg_size; void* name; }; +struct load_dll_reply +{ + struct reply_header __header; +}; @@ -370,6 +429,10 @@ struct unload_dll_request struct request_header __header; void* base; }; +struct unload_dll_reply +{ + struct reply_header __header; +}; @@ -381,6 +444,10 @@ struct queue_apc_request void* func; void* param; }; +struct queue_apc_reply +{ + struct reply_header __header; +}; @@ -388,6 +455,10 @@ struct get_apc_request { struct request_header __header; int alertable; +}; +struct get_apc_reply +{ + struct reply_header __header; void* func; int type; /* VARARG(args,ptrs); */ @@ -400,6 +471,10 @@ struct close_handle_request { struct request_header __header; handle_t handle; +}; +struct close_handle_reply +{ + struct reply_header __header; int fd; }; @@ -412,6 +487,10 @@ struct set_handle_info_request int flags; int mask; int fd; +}; +struct set_handle_info_reply +{ + struct reply_header __header; int old_flags; int cur_fd; }; @@ -427,6 +506,10 @@ struct dup_handle_request unsigned int access; int inherit; int options; +}; +struct dup_handle_reply +{ + struct reply_header __header; handle_t handle; int fd; }; @@ -442,6 +525,10 @@ struct open_process_request void* pid; unsigned int access; int inherit; +}; +struct open_process_reply +{ + struct reply_header __header; handle_t handle; }; @@ -456,6 +543,10 @@ struct select_request int usec; /* VARARG(handles,handles); */ }; +struct select_reply +{ + struct reply_header __header; +}; #define SELECT_ALL 1 #define SELECT_ALERTABLE 2 #define SELECT_INTERRUPTIBLE 4 @@ -470,6 +561,10 @@ struct create_event_request int initial_state; int inherit; /* VARARG(name,unicode_str); */ +}; +struct create_event_reply +{ + struct reply_header __header; handle_t handle; }; @@ -480,6 +575,10 @@ struct event_op_request handle_t handle; int op; }; +struct event_op_reply +{ + struct reply_header __header; +}; enum event_op { PULSE_EVENT, SET_EVENT, RESET_EVENT }; @@ -490,6 +589,10 @@ struct open_event_request unsigned int access; int inherit; /* VARARG(name,unicode_str); */ +}; +struct open_event_reply +{ + struct reply_header __header; handle_t handle; }; @@ -501,6 +604,10 @@ struct create_mutex_request int owned; int inherit; /* VARARG(name,unicode_str); */ +}; +struct create_mutex_reply +{ + struct reply_header __header; handle_t handle; }; @@ -511,6 +618,10 @@ struct release_mutex_request struct request_header __header; handle_t handle; }; +struct release_mutex_reply +{ + struct reply_header __header; +}; @@ -520,6 +631,10 @@ struct open_mutex_request unsigned int access; int inherit; /* VARARG(name,unicode_str); */ +}; +struct open_mutex_reply +{ + struct reply_header __header; handle_t handle; }; @@ -532,6 +647,10 @@ struct create_semaphore_request unsigned int max; int inherit; /* VARARG(name,unicode_str); */ +}; +struct create_semaphore_reply +{ + struct reply_header __header; handle_t handle; }; @@ -542,6 +661,10 @@ struct release_semaphore_request struct request_header __header; handle_t handle; unsigned int count; +}; +struct release_semaphore_reply +{ + struct reply_header __header; unsigned int prev_count; }; @@ -553,6 +676,10 @@ struct open_semaphore_request unsigned int access; int inherit; /* VARARG(name,unicode_str); */ +}; +struct open_semaphore_reply +{ + struct reply_header __header; handle_t handle; }; @@ -568,6 +695,10 @@ struct create_file_request unsigned int attrs; int drive_type; /* VARARG(filename,string); */ +}; +struct create_file_reply +{ + struct reply_header __header; handle_t handle; }; @@ -579,6 +710,10 @@ struct alloc_file_handle_request unsigned int access; int inherit; int fd; +}; +struct alloc_file_handle_reply +{ + struct reply_header __header; handle_t handle; }; @@ -589,6 +724,10 @@ struct get_handle_fd_request struct request_header __header; handle_t handle; unsigned int access; +}; +struct get_handle_fd_reply +{ + struct reply_header __header; int fd; int type; }; @@ -607,6 +746,10 @@ struct set_file_pointer_request int low; int high; int whence; +}; +struct set_file_pointer_reply +{ + struct reply_header __header; int new_low; int new_high; }; @@ -618,6 +761,10 @@ struct truncate_file_request struct request_header __header; handle_t handle; }; +struct truncate_file_reply +{ + struct reply_header __header; +}; @@ -628,6 +775,10 @@ struct set_file_time_request time_t access_time; time_t write_time; }; +struct set_file_time_reply +{ + struct reply_header __header; +}; @@ -636,6 +787,10 @@ struct flush_file_request struct request_header __header; handle_t handle; }; +struct flush_file_reply +{ + struct reply_header __header; +}; @@ -643,6 +798,10 @@ struct get_file_info_request { struct request_header __header; handle_t handle; +}; +struct get_file_info_reply +{ + struct reply_header __header; int type; int attr; time_t access_time; @@ -666,6 +825,10 @@ struct lock_file_request unsigned int count_low; unsigned int count_high; }; +struct lock_file_reply +{ + struct reply_header __header; +}; @@ -678,6 +841,10 @@ struct unlock_file_request unsigned int count_low; unsigned int count_high; }; +struct unlock_file_reply +{ + struct reply_header __header; +}; @@ -685,6 +852,10 @@ struct create_pipe_request { struct request_header __header; int inherit; +}; +struct create_pipe_reply +{ + struct reply_header __header; handle_t handle_read; handle_t handle_write; }; @@ -699,6 +870,10 @@ struct create_socket_request int family; int type; int protocol; +}; +struct create_socket_reply +{ + struct reply_header __header; handle_t handle; }; @@ -710,6 +885,10 @@ struct accept_socket_request handle_t lhandle; unsigned int access; int inherit; +}; +struct accept_socket_reply +{ + struct reply_header __header; handle_t handle; }; @@ -722,6 +901,10 @@ struct set_socket_event_request unsigned int mask; handle_t event; }; +struct set_socket_event_reply +{ + struct reply_header __header; +}; @@ -732,6 +915,10 @@ struct get_socket_event_request int service; handle_t s_event; handle_t c_event; +}; +struct get_socket_event_reply +{ + struct reply_header __header; unsigned int mask; unsigned int pmask; unsigned int state; @@ -748,6 +935,10 @@ struct enable_socket_event_request unsigned int sstate; unsigned int cstate; }; +struct enable_socket_event_reply +{ + struct reply_header __header; +}; @@ -757,6 +948,10 @@ struct alloc_console_request unsigned int access; int inherit; void* pid; +}; +struct alloc_console_reply +{ + struct reply_header __header; handle_t handle_in; handle_t event; }; @@ -767,6 +962,10 @@ struct free_console_request { struct request_header __header; }; +struct free_console_reply +{ + struct reply_header __header; +}; #define CONSOLE_RENDERER_NONE_EVENT 0x00 @@ -818,6 +1017,10 @@ struct get_console_renderer_events_request { struct request_header __header; handle_t handle; +}; +struct get_console_renderer_events_reply +{ + struct reply_header __header; /* VARARG(data,bytes); */ }; @@ -831,6 +1034,10 @@ struct open_console_request unsigned int access; int inherit; int share; +}; +struct open_console_reply +{ + struct reply_header __header; handle_t handle; }; @@ -840,6 +1047,10 @@ struct get_console_mode_request { struct request_header __header; handle_t handle; +}; +struct get_console_mode_reply +{ + struct reply_header __header; int mode; }; @@ -851,6 +1062,10 @@ struct set_console_mode_request handle_t handle; int mode; }; +struct set_console_mode_reply +{ + struct reply_header __header; +}; @@ -864,6 +1079,10 @@ struct set_console_input_info_request int history_size; /* VARARG(title,unicode_str); */ }; +struct set_console_input_info_reply +{ + struct reply_header __header; +}; #define SET_CONSOLE_INPUT_INFO_ACTIVE_SB 0x01 #define SET_CONSOLE_INPUT_INFO_TITLE 0x02 #define SET_CONSOLE_INPUT_INFO_HISTORY_MODE 0x04 @@ -875,6 +1094,10 @@ struct get_console_input_info_request { struct request_header __header; handle_t handle; +}; +struct get_console_input_info_reply +{ + struct reply_header __header; int history_mode; int history_size; int history_index; @@ -889,6 +1112,10 @@ struct append_console_input_history_request handle_t handle; /* VARARG(line,unicode_str); */ }; +struct append_console_input_history_reply +{ + struct reply_header __header; +}; @@ -897,6 +1124,11 @@ struct get_console_input_history_request struct request_header __header; handle_t handle; int index; +}; +struct get_console_input_history_reply +{ + struct reply_header __header; + int total; /* VARARG(line,unicode_str); */ }; @@ -909,6 +1141,10 @@ struct create_console_output_request int access; int share; int inherit; +}; +struct create_console_output_reply +{ + struct reply_header __header; handle_t handle_out; }; @@ -933,6 +1169,10 @@ struct set_console_output_info_request short int max_width; short int max_height; }; +struct set_console_output_info_reply +{ + struct reply_header __header; +}; #define SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM 0x01 #define SET_CONSOLE_OUTPUT_INFO_CURSOR_POS 0x02 #define SET_CONSOLE_OUTPUT_INFO_SIZE 0x04 @@ -946,6 +1186,10 @@ struct get_console_output_info_request { struct request_header __header; handle_t handle; +}; +struct get_console_output_info_reply +{ + struct reply_header __header; short int cursor_size; short int cursor_visible; short int cursor_x; @@ -967,6 +1211,10 @@ struct write_console_input_request struct request_header __header; handle_t handle; /* VARARG(rec,input_records); */ +}; +struct write_console_input_reply +{ + struct reply_header __header; int written; }; @@ -977,6 +1225,10 @@ struct read_console_input_request struct request_header __header; handle_t handle; int flush; +}; +struct read_console_input_reply +{ + struct reply_header __header; int read; /* VARARG(rec,input_records); */ }; @@ -987,18 +1239,45 @@ struct write_console_output_request { struct request_header __header; handle_t handle; + int x; + int y; int mode; - - short int x; - short int y; + int wrap; /* VARARG(data,bytes); */ +}; +struct write_console_output_reply +{ + struct reply_header __header; + int written; + int width; + int height; +}; +enum char_info_mode +{ + CHAR_INFO_MODE_TEXT, + CHAR_INFO_MODE_ATTR, + CHAR_INFO_MODE_TEXTATTR, + CHAR_INFO_MODE_TEXTSTDATTR +}; + + + +struct fill_console_output_request +{ + struct request_header __header; + handle_t handle; + int x; + int y; + int mode; + int count; + int wrap; + char_info_t data; +}; +struct fill_console_output_reply +{ + struct reply_header __header; int written; }; -#define WRITE_CONSOLE_MODE_TEXT 0x00 -#define WRITE_CONSOLE_MODE_ATTR 0x01 -#define WRITE_CONSOLE_MODE_TEXTATTR 0x02 -#define WRITE_CONSOLE_MODE_TEXTSTDATTR 0x03 -#define WRITE_CONSOLE_MODE_UNIFORM 0x04 @@ -1006,12 +1285,16 @@ struct read_console_output_request { struct request_header __header; handle_t handle; - short int x; - short int y; - short int w; - short int h; - short int eff_w; - short int eff_h; + int x; + int y; + int mode; + int wrap; +}; +struct read_console_output_reply +{ + struct reply_header __header; + int width; + int height; /* VARARG(data,bytes); */ }; @@ -1027,6 +1310,10 @@ struct move_console_output_request short int w; short int h; }; +struct move_console_output_reply +{ + struct reply_header __header; +}; @@ -1035,6 +1322,10 @@ struct create_change_notification_request struct request_header __header; int subtree; int filter; +}; +struct create_change_notification_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1049,6 +1340,10 @@ struct create_mapping_request int inherit; handle_t file_handle; /* VARARG(name,unicode_str); */ +}; +struct create_mapping_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1069,6 +1364,10 @@ struct open_mapping_request unsigned int access; int inherit; /* VARARG(name,unicode_str); */ +}; +struct open_mapping_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1078,6 +1377,10 @@ struct get_mapping_info_request { struct request_header __header; handle_t handle; +}; +struct get_mapping_info_reply +{ + struct reply_header __header; int size_high; int size_low; int protect; @@ -1096,6 +1399,10 @@ struct create_device_request unsigned int access; int inherit; int id; +}; +struct create_device_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1107,6 +1414,10 @@ struct create_snapshot_request int inherit; int flags; void* pid; +}; +struct create_snapshot_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1117,6 +1428,10 @@ struct next_process_request struct request_header __header; handle_t handle; int reset; +}; +struct next_process_reply +{ + struct reply_header __header; int count; void* pid; int threads; @@ -1130,6 +1445,10 @@ struct next_thread_request struct request_header __header; handle_t handle; int reset; +}; +struct next_thread_reply +{ + struct reply_header __header; int count; void* pid; void* tid; @@ -1144,6 +1463,10 @@ struct next_module_request struct request_header __header; handle_t handle; int reset; +}; +struct next_module_reply +{ + struct reply_header __header; void* pid; void* base; }; @@ -1154,6 +1477,10 @@ struct wait_debug_event_request { struct request_header __header; int get_handle; +}; +struct wait_debug_event_reply +{ + struct reply_header __header; void* pid; void* tid; handle_t wait; @@ -1167,6 +1494,10 @@ struct queue_exception_event_request struct request_header __header; int first; /* VARARG(record,exc_event); */ +}; +struct queue_exception_event_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1176,6 +1507,10 @@ struct get_exception_status_request { struct request_header __header; handle_t handle; +}; +struct get_exception_status_reply +{ + struct reply_header __header; int status; /* VARARG(context,context); */ }; @@ -1189,6 +1524,10 @@ struct output_debug_string_request int unicode; int length; }; +struct output_debug_string_reply +{ + struct reply_header __header; +}; @@ -1199,6 +1538,10 @@ struct continue_debug_event_request void* tid; int status; }; +struct continue_debug_event_reply +{ + struct reply_header __header; +}; @@ -1207,6 +1550,10 @@ struct debug_process_request struct request_header __header; void* pid; }; +struct debug_process_reply +{ + struct reply_header __header; +}; @@ -1215,7 +1562,10 @@ struct read_process_memory_request struct request_header __header; handle_t handle; void* addr; - int len; +}; +struct read_process_memory_reply +{ + struct reply_header __header; /* VARARG(data,bytes); */ }; @@ -1226,11 +1576,14 @@ struct write_process_memory_request struct request_header __header; handle_t handle; void* addr; - int len; unsigned int first_mask; unsigned int last_mask; /* VARARG(data,bytes); */ }; +struct write_process_memory_reply +{ + struct reply_header __header; +}; @@ -1241,8 +1594,13 @@ struct create_key_request unsigned int access; unsigned int options; time_t modif; - /* VARARG(name,unicode_len_str); */ + size_t namelen; + /* VARARG(name,unicode_str,namelen); */ /* VARARG(class,unicode_str); */ +}; +struct create_key_reply +{ + struct reply_header __header; handle_t hkey; int created; }; @@ -1254,6 +1612,10 @@ struct open_key_request handle_t parent; unsigned int access; /* VARARG(name,unicode_str); */ +}; +struct open_key_reply +{ + struct reply_header __header; handle_t hkey; }; @@ -1264,6 +1626,10 @@ struct delete_key_request struct request_header __header; handle_t hkey; }; +struct delete_key_reply +{ + struct reply_header __header; +}; @@ -1272,7 +1638,11 @@ struct enum_key_request struct request_header __header; handle_t hkey; int index; - int full; + int info_class; +}; +struct enum_key_reply +{ + struct reply_header __header; int subkeys; int max_subkey; int max_class; @@ -1280,7 +1650,9 @@ struct enum_key_request int max_value; int max_data; time_t modif; - /* VARARG(name,unicode_len_str); */ + size_t total; + size_t namelen; + /* VARARG(name,unicode_str,namelen); */ /* VARARG(class,unicode_str); */ }; @@ -1291,11 +1663,14 @@ struct set_key_value_request struct request_header __header; handle_t hkey; int type; - unsigned int total; - unsigned int offset; - /* VARARG(name,unicode_len_str); */ + size_t namelen; + /* VARARG(name,unicode_str,namelen); */ /* VARARG(data,bytes); */ }; +struct set_key_value_reply +{ + struct reply_header __header; +}; @@ -1303,10 +1678,13 @@ struct get_key_value_request { struct request_header __header; handle_t hkey; - unsigned int offset; - /* VARARG(name,unicode_len_str); */ + /* VARARG(name,unicode_str); */ +}; +struct get_key_value_reply +{ + struct reply_header __header; int type; - int len; + size_t total; /* VARARG(data,bytes); */ }; @@ -1317,10 +1695,15 @@ struct enum_key_value_request struct request_header __header; handle_t hkey; int index; - unsigned int offset; + int info_class; +}; +struct enum_key_value_reply +{ + struct reply_header __header; int type; - int len; - /* VARARG(name,unicode_len_str); */ + size_t total; + size_t namelen; + /* VARARG(name,unicode_str,namelen); */ /* VARARG(data,bytes); */ }; @@ -1332,6 +1715,10 @@ struct delete_key_value_request handle_t hkey; /* VARARG(name,unicode_str); */ }; +struct delete_key_value_reply +{ + struct reply_header __header; +}; @@ -1342,6 +1729,10 @@ struct load_registry_request handle_t file; /* VARARG(name,unicode_str); */ }; +struct load_registry_reply +{ + struct reply_header __header; +}; @@ -1351,6 +1742,10 @@ struct save_registry_request handle_t hkey; handle_t file; }; +struct save_registry_reply +{ + struct reply_header __header; +}; @@ -1360,6 +1755,10 @@ struct save_registry_atexit_request handle_t hkey; /* VARARG(file,string); */ }; +struct save_registry_atexit_reply +{ + struct reply_header __header; +}; @@ -1370,6 +1769,10 @@ struct set_registry_levels_request int saving; int period; }; +struct set_registry_levels_reply +{ + struct reply_header __header; +}; @@ -1379,6 +1782,10 @@ struct create_timer_request int inherit; int manual; /* VARARG(name,unicode_str); */ +}; +struct create_timer_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1390,6 +1797,10 @@ struct open_timer_request unsigned int access; int inherit; /* VARARG(name,unicode_str); */ +}; +struct open_timer_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1404,6 +1815,10 @@ struct set_timer_request void* callback; void* arg; }; +struct set_timer_reply +{ + struct reply_header __header; +}; struct cancel_timer_request @@ -1411,6 +1826,10 @@ struct cancel_timer_request struct request_header __header; handle_t handle; }; +struct cancel_timer_reply +{ + struct reply_header __header; +}; @@ -1419,6 +1838,10 @@ struct get_thread_context_request struct request_header __header; handle_t handle; unsigned int flags; +}; +struct get_thread_context_reply +{ + struct reply_header __header; /* VARARG(context,context); */ }; @@ -1431,6 +1854,10 @@ struct set_thread_context_request unsigned int flags; /* VARARG(context,context); */ }; +struct set_thread_context_reply +{ + struct reply_header __header; +}; @@ -1439,6 +1866,10 @@ struct get_selector_entry_request struct request_header __header; handle_t handle; int entry; +}; +struct get_selector_entry_reply +{ + struct reply_header __header; unsigned int base; unsigned int limit; unsigned char flags; @@ -1451,6 +1882,10 @@ struct add_atom_request struct request_header __header; int local; /* VARARG(name,unicode_str); */ +}; +struct add_atom_reply +{ + struct reply_header __header; atom_t atom; }; @@ -1462,6 +1897,10 @@ struct delete_atom_request atom_t atom; int local; }; +struct delete_atom_reply +{ + struct reply_header __header; +}; @@ -1470,6 +1909,10 @@ struct find_atom_request struct request_header __header; int local; /* VARARG(name,unicode_str); */ +}; +struct find_atom_reply +{ + struct reply_header __header; atom_t atom; }; @@ -1480,6 +1923,10 @@ struct get_atom_name_request struct request_header __header; atom_t atom; int local; +}; +struct get_atom_name_reply +{ + struct reply_header __header; int count; /* VARARG(name,unicode_str); */ }; @@ -1491,12 +1938,20 @@ struct init_atom_table_request struct request_header __header; int entries; }; +struct init_atom_table_reply +{ + struct reply_header __header; +}; struct get_msg_queue_request { struct request_header __header; +}; +struct get_msg_queue_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1508,6 +1963,10 @@ struct set_queue_mask_request unsigned int wake_mask; unsigned int changed_mask; int skip_wait; +}; +struct set_queue_mask_reply +{ + struct reply_header __header; unsigned int wake_bits; unsigned int changed_bits; }; @@ -1518,6 +1977,10 @@ struct get_queue_status_request { struct request_header __header; int clear; +}; +struct get_queue_status_reply +{ + struct reply_header __header; unsigned int wake_bits; unsigned int changed_bits; }; @@ -1529,6 +1992,10 @@ struct wait_input_idle_request struct request_header __header; handle_t handle; int timeout; +}; +struct wait_input_idle_reply +{ + struct reply_header __header; handle_t event; }; @@ -1550,6 +2017,10 @@ struct send_message_request int timeout; /* VARARG(data,bytes); */ }; +struct send_message_reply +{ + struct reply_header __header; +}; enum message_type { @@ -1572,6 +2043,10 @@ struct get_message_request user_handle_t get_win; unsigned int get_first; unsigned int get_last; +}; +struct get_message_reply +{ + struct reply_header __header; int type; user_handle_t win; unsigned int msg; @@ -1581,6 +2056,7 @@ struct get_message_request int y; unsigned int time; unsigned int info; + size_t total; /* VARARG(data,bytes); */ }; #define GET_MSG_REMOVE 1 @@ -1595,6 +2071,10 @@ struct reply_message_request int remove; /* VARARG(data,bytes); */ }; +struct reply_message_reply +{ + struct reply_header __header; +}; @@ -1602,6 +2082,10 @@ struct get_message_reply_request { struct request_header __header; int cancel; +}; +struct get_message_reply_reply +{ + struct reply_header __header; unsigned int result; /* VARARG(data,bytes); */ }; @@ -1617,6 +2101,10 @@ struct set_win_timer_request unsigned int rate; unsigned int lparam; }; +struct set_win_timer_reply +{ + struct reply_header __header; +}; @@ -1627,6 +2115,10 @@ struct kill_win_timer_request unsigned int msg; unsigned int id; }; +struct kill_win_timer_reply +{ + struct reply_header __header; +}; @@ -1638,6 +2130,10 @@ struct create_serial_request unsigned int attributes; unsigned int sharing; /* VARARG(name,string); */ +}; +struct create_serial_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1647,6 +2143,10 @@ struct get_serial_info_request { struct request_header __header; handle_t handle; +}; +struct get_serial_info_reply +{ + struct reply_header __header; unsigned int readinterval; unsigned int readconst; unsigned int readmult; @@ -1671,6 +2171,10 @@ struct set_serial_info_request unsigned int eventmask; unsigned int commerror; }; +struct set_serial_info_reply +{ + struct reply_header __header; +}; #define SERIALINFO_SET_TIMEOUTS 0x01 #define SERIALINFO_SET_MASK 0x02 #define SERIALINFO_SET_ERROR 0x04 @@ -1683,6 +2187,10 @@ struct create_async_request handle_t file_handle; int count; int type; +}; +struct create_async_reply +{ + struct reply_header __header; int timeout; }; #define ASYNC_TYPE_READ 0x01 @@ -1701,6 +2209,10 @@ struct create_named_pipe_request unsigned int insize; unsigned int timeout; /* VARARG(filename,string); */ +}; +struct create_named_pipe_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1711,6 +2223,10 @@ struct open_named_pipe_request struct request_header __header; unsigned int access; /* VARARG(filename,string); */ +}; +struct open_named_pipe_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1723,6 +2239,10 @@ struct connect_named_pipe_request void* overlapped; void* func; }; +struct connect_named_pipe_reply +{ + struct reply_header __header; +}; @@ -1734,6 +2254,10 @@ struct wait_named_pipe_request void* func; /* VARARG(filename,string); */ }; +struct wait_named_pipe_reply +{ + struct reply_header __header; +}; @@ -1742,12 +2266,20 @@ struct disconnect_named_pipe_request struct request_header __header; handle_t handle; }; +struct disconnect_named_pipe_reply +{ + struct reply_header __header; +}; struct get_named_pipe_info_request { struct request_header __header; handle_t handle; +}; +struct get_named_pipe_info_reply +{ + struct reply_header __header; unsigned int flags; unsigned int maxinstances; unsigned int outsize; @@ -1762,6 +2294,10 @@ struct create_window_request user_handle_t parent; user_handle_t owner; atom_t atom; +}; +struct create_window_reply +{ + struct reply_header __header; user_handle_t handle; }; @@ -1773,6 +2309,10 @@ struct link_window_request user_handle_t handle; user_handle_t parent; user_handle_t previous; +}; +struct link_window_reply +{ + struct reply_header __header; user_handle_t full_parent; }; @@ -1783,6 +2323,10 @@ struct destroy_window_request struct request_header __header; user_handle_t handle; }; +struct destroy_window_reply +{ + struct reply_header __header; +}; @@ -1791,6 +2335,10 @@ struct set_window_owner_request struct request_header __header; user_handle_t handle; user_handle_t owner; +}; +struct set_window_owner_reply +{ + struct reply_header __header; user_handle_t full_owner; }; @@ -1800,6 +2348,10 @@ struct get_window_info_request { struct request_header __header; user_handle_t handle; +}; +struct get_window_info_reply +{ + struct reply_header __header; user_handle_t full_handle; void* pid; void* tid; @@ -1818,6 +2370,10 @@ struct set_window_info_request unsigned int id; void* instance; void* user_data; +}; +struct set_window_info_reply +{ + struct reply_header __header; unsigned int old_style; unsigned int old_ex_style; unsigned int old_id; @@ -1836,6 +2392,10 @@ struct get_window_parents_request { struct request_header __header; user_handle_t handle; +}; +struct get_window_parents_reply +{ + struct reply_header __header; int count; /* VARARG(parents,user_handles); */ }; @@ -1848,6 +2408,10 @@ struct get_window_children_request user_handle_t parent; atom_t atom; void* tid; +}; +struct get_window_children_reply +{ + struct reply_header __header; int count; /* VARARG(children,user_handles); */ }; @@ -1858,6 +2422,10 @@ struct get_window_tree_request { struct request_header __header; user_handle_t handle; +}; +struct get_window_tree_reply +{ + struct reply_header __header; user_handle_t parent; user_handle_t owner; user_handle_t next_sibling; @@ -1876,6 +2444,10 @@ struct set_window_rectangles_request rectangle_t window; rectangle_t client; }; +struct set_window_rectangles_reply +{ + struct reply_header __header; +}; @@ -1883,6 +2455,10 @@ struct get_window_rectangles_request { struct request_header __header; user_handle_t handle; +}; +struct get_window_rectangles_reply +{ + struct reply_header __header; rectangle_t window; rectangle_t client; }; @@ -1893,6 +2469,10 @@ struct get_window_text_request { struct request_header __header; user_handle_t handle; +}; +struct get_window_text_reply +{ + struct reply_header __header; /* VARARG(text,unicode_str); */ }; @@ -1904,6 +2484,10 @@ struct set_window_text_request user_handle_t handle; /* VARARG(text,unicode_str); */ }; +struct set_window_text_reply +{ + struct reply_header __header; +}; @@ -1913,6 +2497,10 @@ struct inc_window_paint_count_request user_handle_t handle; int incr; }; +struct inc_window_paint_count_reply +{ + struct reply_header __header; +}; @@ -1921,6 +2509,10 @@ struct get_windows_offset_request struct request_header __header; user_handle_t from; user_handle_t to; +}; +struct get_windows_offset_reply +{ + struct reply_header __header; int x; int y; }; @@ -1935,6 +2527,10 @@ struct set_window_property_request int string; handle_t handle; }; +struct set_window_property_reply +{ + struct reply_header __header; +}; @@ -1943,6 +2539,10 @@ struct remove_window_property_request struct request_header __header; user_handle_t window; atom_t atom; +}; +struct remove_window_property_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1953,6 +2553,10 @@ struct get_window_property_request struct request_header __header; user_handle_t window; atom_t atom; +}; +struct get_window_property_reply +{ + struct reply_header __header; handle_t handle; }; @@ -1962,6 +2566,11 @@ struct get_window_properties_request { struct request_header __header; user_handle_t window; +}; +struct get_window_properties_reply +{ + struct reply_header __header; + int total; /* VARARG(props,properties); */ }; @@ -1975,7 +2584,6 @@ enum request REQ_init_process, REQ_init_process_done, REQ_init_thread, - REQ_set_thread_buffer, REQ_terminate_process, REQ_terminate_thread, REQ_get_process_info, @@ -2034,6 +2642,7 @@ enum request REQ_write_console_input, REQ_read_console_input, REQ_write_console_output, + REQ_fill_console_output, REQ_read_console_output, REQ_move_console_output, REQ_create_change_notification, @@ -2122,157 +2731,310 @@ enum request union generic_request { struct request_max_size max_size; - struct request_header header; - struct new_process_request new_process; - struct get_new_process_info_request get_new_process_info; - struct new_thread_request new_thread; - struct boot_done_request boot_done; - struct init_process_request init_process; - struct init_process_done_request init_process_done; - struct init_thread_request init_thread; - struct set_thread_buffer_request set_thread_buffer; - struct terminate_process_request terminate_process; - struct terminate_thread_request terminate_thread; - struct get_process_info_request get_process_info; - struct set_process_info_request set_process_info; - struct get_thread_info_request get_thread_info; - struct set_thread_info_request set_thread_info; - struct suspend_thread_request suspend_thread; - struct resume_thread_request resume_thread; - struct load_dll_request load_dll; - struct unload_dll_request unload_dll; - struct queue_apc_request queue_apc; - struct get_apc_request get_apc; - struct close_handle_request close_handle; - struct set_handle_info_request set_handle_info; - struct dup_handle_request dup_handle; - struct open_process_request open_process; - struct select_request select; - struct create_event_request create_event; - struct event_op_request event_op; - struct open_event_request open_event; - struct create_mutex_request create_mutex; - struct release_mutex_request release_mutex; - struct open_mutex_request open_mutex; - struct create_semaphore_request create_semaphore; - struct release_semaphore_request release_semaphore; - struct open_semaphore_request open_semaphore; - struct create_file_request create_file; - struct alloc_file_handle_request alloc_file_handle; - struct get_handle_fd_request get_handle_fd; - struct set_file_pointer_request set_file_pointer; - struct truncate_file_request truncate_file; - struct set_file_time_request set_file_time; - struct flush_file_request flush_file; - struct get_file_info_request get_file_info; - struct lock_file_request lock_file; - struct unlock_file_request unlock_file; - struct create_pipe_request create_pipe; - struct create_socket_request create_socket; - struct accept_socket_request accept_socket; - struct set_socket_event_request set_socket_event; - struct get_socket_event_request get_socket_event; - struct enable_socket_event_request enable_socket_event; - struct alloc_console_request alloc_console; - struct free_console_request free_console; - struct get_console_renderer_events_request get_console_renderer_events; - struct open_console_request open_console; - struct get_console_mode_request get_console_mode; - struct set_console_mode_request set_console_mode; - struct set_console_input_info_request set_console_input_info; - struct get_console_input_info_request get_console_input_info; - struct append_console_input_history_request append_console_input_history; - struct get_console_input_history_request get_console_input_history; - struct create_console_output_request create_console_output; - struct set_console_output_info_request set_console_output_info; - struct get_console_output_info_request get_console_output_info; - struct write_console_input_request write_console_input; - struct read_console_input_request read_console_input; - struct write_console_output_request write_console_output; - struct read_console_output_request read_console_output; - struct move_console_output_request move_console_output; - struct create_change_notification_request create_change_notification; - struct create_mapping_request create_mapping; - struct open_mapping_request open_mapping; - struct get_mapping_info_request get_mapping_info; - struct create_device_request create_device; - struct create_snapshot_request create_snapshot; - struct next_process_request next_process; - struct next_thread_request next_thread; - struct next_module_request next_module; - struct wait_debug_event_request wait_debug_event; - struct queue_exception_event_request queue_exception_event; - struct get_exception_status_request get_exception_status; - struct output_debug_string_request output_debug_string; - struct continue_debug_event_request continue_debug_event; - struct debug_process_request debug_process; - struct read_process_memory_request read_process_memory; - struct write_process_memory_request write_process_memory; - struct create_key_request create_key; - struct open_key_request open_key; - struct delete_key_request delete_key; - struct enum_key_request enum_key; - struct set_key_value_request set_key_value; - struct get_key_value_request get_key_value; - struct enum_key_value_request enum_key_value; - struct delete_key_value_request delete_key_value; - struct load_registry_request load_registry; - struct save_registry_request save_registry; - struct save_registry_atexit_request save_registry_atexit; - struct set_registry_levels_request set_registry_levels; - struct create_timer_request create_timer; - struct open_timer_request open_timer; - struct set_timer_request set_timer; - struct cancel_timer_request cancel_timer; - struct get_thread_context_request get_thread_context; - struct set_thread_context_request set_thread_context; - struct get_selector_entry_request get_selector_entry; - struct add_atom_request add_atom; - struct delete_atom_request delete_atom; - struct find_atom_request find_atom; - struct get_atom_name_request get_atom_name; - struct init_atom_table_request init_atom_table; - struct get_msg_queue_request get_msg_queue; - struct set_queue_mask_request set_queue_mask; - struct get_queue_status_request get_queue_status; - struct wait_input_idle_request wait_input_idle; - struct send_message_request send_message; - struct get_message_request get_message; - struct reply_message_request reply_message; - struct get_message_reply_request get_message_reply; - struct set_win_timer_request set_win_timer; - struct kill_win_timer_request kill_win_timer; - struct create_serial_request create_serial; - struct get_serial_info_request get_serial_info; - struct set_serial_info_request set_serial_info; - struct create_async_request create_async; - struct create_named_pipe_request create_named_pipe; - struct open_named_pipe_request open_named_pipe; - struct connect_named_pipe_request connect_named_pipe; - struct wait_named_pipe_request wait_named_pipe; - struct disconnect_named_pipe_request disconnect_named_pipe; - struct get_named_pipe_info_request get_named_pipe_info; - struct create_window_request create_window; - struct link_window_request link_window; - struct destroy_window_request destroy_window; - struct set_window_owner_request set_window_owner; - struct get_window_info_request get_window_info; - struct set_window_info_request set_window_info; - struct get_window_parents_request get_window_parents; - struct get_window_children_request get_window_children; - struct get_window_tree_request get_window_tree; - struct set_window_rectangles_request set_window_rectangles; - struct get_window_rectangles_request get_window_rectangles; - struct get_window_text_request get_window_text; - struct set_window_text_request set_window_text; - struct inc_window_paint_count_request inc_window_paint_count; - struct get_windows_offset_request get_windows_offset; - struct set_window_property_request set_window_property; - struct remove_window_property_request remove_window_property; - struct get_window_property_request get_window_property; - struct get_window_properties_request get_window_properties; + struct request_header request_header; + struct new_process_request new_process_request; + struct get_new_process_info_request get_new_process_info_request; + struct new_thread_request new_thread_request; + struct boot_done_request boot_done_request; + struct init_process_request init_process_request; + struct init_process_done_request init_process_done_request; + struct init_thread_request init_thread_request; + struct terminate_process_request terminate_process_request; + struct terminate_thread_request terminate_thread_request; + struct get_process_info_request get_process_info_request; + struct set_process_info_request set_process_info_request; + struct get_thread_info_request get_thread_info_request; + struct set_thread_info_request set_thread_info_request; + struct suspend_thread_request suspend_thread_request; + struct resume_thread_request resume_thread_request; + struct load_dll_request load_dll_request; + struct unload_dll_request unload_dll_request; + struct queue_apc_request queue_apc_request; + struct get_apc_request get_apc_request; + struct close_handle_request close_handle_request; + struct set_handle_info_request set_handle_info_request; + struct dup_handle_request dup_handle_request; + struct open_process_request open_process_request; + struct select_request select_request; + struct create_event_request create_event_request; + struct event_op_request event_op_request; + struct open_event_request open_event_request; + struct create_mutex_request create_mutex_request; + struct release_mutex_request release_mutex_request; + struct open_mutex_request open_mutex_request; + struct create_semaphore_request create_semaphore_request; + struct release_semaphore_request release_semaphore_request; + struct open_semaphore_request open_semaphore_request; + struct create_file_request create_file_request; + struct alloc_file_handle_request alloc_file_handle_request; + struct get_handle_fd_request get_handle_fd_request; + struct set_file_pointer_request set_file_pointer_request; + struct truncate_file_request truncate_file_request; + struct set_file_time_request set_file_time_request; + struct flush_file_request flush_file_request; + struct get_file_info_request get_file_info_request; + struct lock_file_request lock_file_request; + struct unlock_file_request unlock_file_request; + struct create_pipe_request create_pipe_request; + struct create_socket_request create_socket_request; + struct accept_socket_request accept_socket_request; + struct set_socket_event_request set_socket_event_request; + struct get_socket_event_request get_socket_event_request; + struct enable_socket_event_request enable_socket_event_request; + struct alloc_console_request alloc_console_request; + struct free_console_request free_console_request; + struct get_console_renderer_events_request get_console_renderer_events_request; + struct open_console_request open_console_request; + struct get_console_mode_request get_console_mode_request; + struct set_console_mode_request set_console_mode_request; + struct set_console_input_info_request set_console_input_info_request; + struct get_console_input_info_request get_console_input_info_request; + struct append_console_input_history_request append_console_input_history_request; + struct get_console_input_history_request get_console_input_history_request; + struct create_console_output_request create_console_output_request; + struct set_console_output_info_request set_console_output_info_request; + struct get_console_output_info_request get_console_output_info_request; + struct write_console_input_request write_console_input_request; + struct read_console_input_request read_console_input_request; + struct write_console_output_request write_console_output_request; + struct fill_console_output_request fill_console_output_request; + struct read_console_output_request read_console_output_request; + struct move_console_output_request move_console_output_request; + struct create_change_notification_request create_change_notification_request; + struct create_mapping_request create_mapping_request; + struct open_mapping_request open_mapping_request; + struct get_mapping_info_request get_mapping_info_request; + struct create_device_request create_device_request; + struct create_snapshot_request create_snapshot_request; + struct next_process_request next_process_request; + struct next_thread_request next_thread_request; + struct next_module_request next_module_request; + struct wait_debug_event_request wait_debug_event_request; + struct queue_exception_event_request queue_exception_event_request; + struct get_exception_status_request get_exception_status_request; + struct output_debug_string_request output_debug_string_request; + struct continue_debug_event_request continue_debug_event_request; + struct debug_process_request debug_process_request; + struct read_process_memory_request read_process_memory_request; + struct write_process_memory_request write_process_memory_request; + struct create_key_request create_key_request; + struct open_key_request open_key_request; + struct delete_key_request delete_key_request; + struct enum_key_request enum_key_request; + struct set_key_value_request set_key_value_request; + struct get_key_value_request get_key_value_request; + struct enum_key_value_request enum_key_value_request; + struct delete_key_value_request delete_key_value_request; + struct load_registry_request load_registry_request; + struct save_registry_request save_registry_request; + struct save_registry_atexit_request save_registry_atexit_request; + struct set_registry_levels_request set_registry_levels_request; + struct create_timer_request create_timer_request; + struct open_timer_request open_timer_request; + struct set_timer_request set_timer_request; + struct cancel_timer_request cancel_timer_request; + struct get_thread_context_request get_thread_context_request; + struct set_thread_context_request set_thread_context_request; + struct get_selector_entry_request get_selector_entry_request; + struct add_atom_request add_atom_request; + struct delete_atom_request delete_atom_request; + struct find_atom_request find_atom_request; + struct get_atom_name_request get_atom_name_request; + struct init_atom_table_request init_atom_table_request; + struct get_msg_queue_request get_msg_queue_request; + struct set_queue_mask_request set_queue_mask_request; + struct get_queue_status_request get_queue_status_request; + struct wait_input_idle_request wait_input_idle_request; + struct send_message_request send_message_request; + struct get_message_request get_message_request; + struct reply_message_request reply_message_request; + struct get_message_reply_request get_message_reply_request; + struct set_win_timer_request set_win_timer_request; + struct kill_win_timer_request kill_win_timer_request; + struct create_serial_request create_serial_request; + struct get_serial_info_request get_serial_info_request; + struct set_serial_info_request set_serial_info_request; + struct create_async_request create_async_request; + struct create_named_pipe_request create_named_pipe_request; + struct open_named_pipe_request open_named_pipe_request; + struct connect_named_pipe_request connect_named_pipe_request; + struct wait_named_pipe_request wait_named_pipe_request; + struct disconnect_named_pipe_request disconnect_named_pipe_request; + struct get_named_pipe_info_request get_named_pipe_info_request; + struct create_window_request create_window_request; + struct link_window_request link_window_request; + struct destroy_window_request destroy_window_request; + struct set_window_owner_request set_window_owner_request; + struct get_window_info_request get_window_info_request; + struct set_window_info_request set_window_info_request; + struct get_window_parents_request get_window_parents_request; + struct get_window_children_request get_window_children_request; + struct get_window_tree_request get_window_tree_request; + struct set_window_rectangles_request set_window_rectangles_request; + struct get_window_rectangles_request get_window_rectangles_request; + struct get_window_text_request get_window_text_request; + struct set_window_text_request set_window_text_request; + struct inc_window_paint_count_request inc_window_paint_count_request; + struct get_windows_offset_request get_windows_offset_request; + struct set_window_property_request set_window_property_request; + struct remove_window_property_request remove_window_property_request; + struct get_window_property_request get_window_property_request; + struct get_window_properties_request get_window_properties_request; +}; +union generic_reply +{ + struct request_max_size max_size; + struct reply_header reply_header; + struct new_process_reply new_process_reply; + struct get_new_process_info_reply get_new_process_info_reply; + struct new_thread_reply new_thread_reply; + struct boot_done_reply boot_done_reply; + struct init_process_reply init_process_reply; + struct init_process_done_reply init_process_done_reply; + struct init_thread_reply init_thread_reply; + struct terminate_process_reply terminate_process_reply; + struct terminate_thread_reply terminate_thread_reply; + struct get_process_info_reply get_process_info_reply; + struct set_process_info_reply set_process_info_reply; + struct get_thread_info_reply get_thread_info_reply; + struct set_thread_info_reply set_thread_info_reply; + struct suspend_thread_reply suspend_thread_reply; + struct resume_thread_reply resume_thread_reply; + struct load_dll_reply load_dll_reply; + struct unload_dll_reply unload_dll_reply; + struct queue_apc_reply queue_apc_reply; + struct get_apc_reply get_apc_reply; + struct close_handle_reply close_handle_reply; + struct set_handle_info_reply set_handle_info_reply; + struct dup_handle_reply dup_handle_reply; + struct open_process_reply open_process_reply; + struct select_reply select_reply; + struct create_event_reply create_event_reply; + struct event_op_reply event_op_reply; + struct open_event_reply open_event_reply; + struct create_mutex_reply create_mutex_reply; + struct release_mutex_reply release_mutex_reply; + struct open_mutex_reply open_mutex_reply; + struct create_semaphore_reply create_semaphore_reply; + struct release_semaphore_reply release_semaphore_reply; + struct open_semaphore_reply open_semaphore_reply; + struct create_file_reply create_file_reply; + struct alloc_file_handle_reply alloc_file_handle_reply; + struct get_handle_fd_reply get_handle_fd_reply; + struct set_file_pointer_reply set_file_pointer_reply; + struct truncate_file_reply truncate_file_reply; + struct set_file_time_reply set_file_time_reply; + struct flush_file_reply flush_file_reply; + struct get_file_info_reply get_file_info_reply; + struct lock_file_reply lock_file_reply; + struct unlock_file_reply unlock_file_reply; + struct create_pipe_reply create_pipe_reply; + struct create_socket_reply create_socket_reply; + struct accept_socket_reply accept_socket_reply; + struct set_socket_event_reply set_socket_event_reply; + struct get_socket_event_reply get_socket_event_reply; + struct enable_socket_event_reply enable_socket_event_reply; + struct alloc_console_reply alloc_console_reply; + struct free_console_reply free_console_reply; + struct get_console_renderer_events_reply get_console_renderer_events_reply; + struct open_console_reply open_console_reply; + struct get_console_mode_reply get_console_mode_reply; + struct set_console_mode_reply set_console_mode_reply; + struct set_console_input_info_reply set_console_input_info_reply; + struct get_console_input_info_reply get_console_input_info_reply; + struct append_console_input_history_reply append_console_input_history_reply; + struct get_console_input_history_reply get_console_input_history_reply; + struct create_console_output_reply create_console_output_reply; + struct set_console_output_info_reply set_console_output_info_reply; + struct get_console_output_info_reply get_console_output_info_reply; + struct write_console_input_reply write_console_input_reply; + struct read_console_input_reply read_console_input_reply; + struct write_console_output_reply write_console_output_reply; + struct fill_console_output_reply fill_console_output_reply; + struct read_console_output_reply read_console_output_reply; + struct move_console_output_reply move_console_output_reply; + struct create_change_notification_reply create_change_notification_reply; + struct create_mapping_reply create_mapping_reply; + struct open_mapping_reply open_mapping_reply; + struct get_mapping_info_reply get_mapping_info_reply; + struct create_device_reply create_device_reply; + struct create_snapshot_reply create_snapshot_reply; + struct next_process_reply next_process_reply; + struct next_thread_reply next_thread_reply; + struct next_module_reply next_module_reply; + struct wait_debug_event_reply wait_debug_event_reply; + struct queue_exception_event_reply queue_exception_event_reply; + struct get_exception_status_reply get_exception_status_reply; + struct output_debug_string_reply output_debug_string_reply; + struct continue_debug_event_reply continue_debug_event_reply; + struct debug_process_reply debug_process_reply; + struct read_process_memory_reply read_process_memory_reply; + struct write_process_memory_reply write_process_memory_reply; + struct create_key_reply create_key_reply; + struct open_key_reply open_key_reply; + struct delete_key_reply delete_key_reply; + struct enum_key_reply enum_key_reply; + struct set_key_value_reply set_key_value_reply; + struct get_key_value_reply get_key_value_reply; + struct enum_key_value_reply enum_key_value_reply; + struct delete_key_value_reply delete_key_value_reply; + struct load_registry_reply load_registry_reply; + struct save_registry_reply save_registry_reply; + struct save_registry_atexit_reply save_registry_atexit_reply; + struct set_registry_levels_reply set_registry_levels_reply; + struct create_timer_reply create_timer_reply; + struct open_timer_reply open_timer_reply; + struct set_timer_reply set_timer_reply; + struct cancel_timer_reply cancel_timer_reply; + struct get_thread_context_reply get_thread_context_reply; + struct set_thread_context_reply set_thread_context_reply; + struct get_selector_entry_reply get_selector_entry_reply; + struct add_atom_reply add_atom_reply; + struct delete_atom_reply delete_atom_reply; + struct find_atom_reply find_atom_reply; + struct get_atom_name_reply get_atom_name_reply; + struct init_atom_table_reply init_atom_table_reply; + struct get_msg_queue_reply get_msg_queue_reply; + struct set_queue_mask_reply set_queue_mask_reply; + struct get_queue_status_reply get_queue_status_reply; + struct wait_input_idle_reply wait_input_idle_reply; + struct send_message_reply send_message_reply; + struct get_message_reply get_message_reply; + struct reply_message_reply reply_message_reply; + struct get_message_reply_reply get_message_reply_reply; + struct set_win_timer_reply set_win_timer_reply; + struct kill_win_timer_reply kill_win_timer_reply; + struct create_serial_reply create_serial_reply; + struct get_serial_info_reply get_serial_info_reply; + struct set_serial_info_reply set_serial_info_reply; + struct create_async_reply create_async_reply; + struct create_named_pipe_reply create_named_pipe_reply; + struct open_named_pipe_reply open_named_pipe_reply; + struct connect_named_pipe_reply connect_named_pipe_reply; + struct wait_named_pipe_reply wait_named_pipe_reply; + struct disconnect_named_pipe_reply disconnect_named_pipe_reply; + struct get_named_pipe_info_reply get_named_pipe_info_reply; + struct create_window_reply create_window_reply; + struct link_window_reply link_window_reply; + struct destroy_window_reply destroy_window_reply; + struct set_window_owner_reply set_window_owner_reply; + struct get_window_info_reply get_window_info_reply; + struct set_window_info_reply set_window_info_reply; + struct get_window_parents_reply get_window_parents_reply; + struct get_window_children_reply get_window_children_reply; + struct get_window_tree_reply get_window_tree_reply; + struct set_window_rectangles_reply set_window_rectangles_reply; + struct get_window_rectangles_reply get_window_rectangles_reply; + struct get_window_text_reply get_window_text_reply; + struct set_window_text_reply set_window_text_reply; + struct inc_window_paint_count_reply inc_window_paint_count_reply; + struct get_windows_offset_reply get_windows_offset_reply; + struct set_window_property_reply set_window_property_reply; + struct remove_window_property_reply remove_window_property_reply; + struct get_window_property_reply get_window_property_reply; + struct get_window_properties_reply get_window_properties_reply; }; -#define SERVER_PROTOCOL_VERSION 65 +#define SERVER_PROTOCOL_VERSION 66 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/loader/module.c b/loader/module.c index fa6fc0fe31b..c507a4c4fba 100644 --- a/loader/module.c +++ b/loader/module.c @@ -1693,7 +1693,7 @@ BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) SERVER_START_REQ( unload_dll ) { req->base = (void *)wm->module; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; MODULE_FlushModrefs(); diff --git a/loader/pe_image.c b/loader/pe_image.c index 52629b788ec..6136a40831c 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c @@ -681,7 +681,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, req->dbg_offset = nt->FileHeader.PointerToSymbolTable; req->dbg_size = nt->FileHeader.NumberOfSymbols; req->name = &wm->filename; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } diff --git a/memory/atom.c b/memory/atom.c index ef2feb40bf4..033eb4c4167 100644 --- a/memory/atom.c +++ b/memory/atom.c @@ -409,7 +409,7 @@ BOOL WINAPI InitAtomTable( DWORD entries ) SERVER_START_REQ( init_atom_table ) { req->entries = entries; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -421,19 +421,21 @@ static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local ) ATOM atom = 0; if (!ATOM_IsIntAtomA( str, &atom )) { - DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 ); - if (len > MAX_ATOM_LEN) + WCHAR buffer[MAX_ATOM_LEN]; + + DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN ); + if (!len) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - SERVER_START_VAR_REQ( add_atom, len * sizeof(WCHAR) ) + SERVER_START_REQ( add_atom ) { - MultiByteToWideChar( CP_ACP, 0, str, strlen(str), server_data_ptr(req), len ); + wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); req->local = local; - if (!SERVER_CALL_ERR()) atom = req->atom; + if (!wine_server_call_err(req)) atom = reply->atom; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom ); return atom; @@ -482,13 +484,13 @@ static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local ) SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - SERVER_START_VAR_REQ( add_atom, len * sizeof(WCHAR) ) + SERVER_START_REQ( add_atom ) { - memcpy( server_data_ptr(req), str, len * sizeof(WCHAR) ); req->local = local; - if (!SERVER_CALL_ERR()) atom = req->atom; + wine_server_add_data( req, str, len * sizeof(WCHAR) ); + if (!wine_server_call_err(req)) atom = reply->atom; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom ); return atom; @@ -523,7 +525,7 @@ static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local) { req->atom = atom; req->local = local; - if (!SERVER_CALL_ERR()) atom = 0; + if (!wine_server_call_err( req )) atom = 0; } SERVER_END_REQ; } @@ -566,19 +568,21 @@ static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local ) ATOM atom = 0; if (!ATOM_IsIntAtomA( str, &atom )) { - DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), NULL, 0 ); - if (len > MAX_ATOM_LEN) + WCHAR buffer[MAX_ATOM_LEN]; + + DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN ); + if (!len) { SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - SERVER_START_VAR_REQ( find_atom, len * sizeof(WCHAR) ) + SERVER_START_REQ( find_atom ) { - MultiByteToWideChar( CP_ACP, 0, str, strlen(str), server_data_ptr(req), len ); req->local = local; - if (!SERVER_CALL_ERR()) atom = req->atom; + wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); + if (!wine_server_call_err(req)) atom = reply->atom; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_a(str), atom ); return atom; @@ -626,13 +630,13 @@ static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local ) SetLastError( ERROR_INVALID_PARAMETER ); return 0; } - SERVER_START_VAR_REQ( find_atom, len * sizeof(WCHAR) ) + SERVER_START_REQ( find_atom ) { - memcpy( server_data_ptr(req), str, len * sizeof(WCHAR) ); + wine_server_add_data( req, str, len * sizeof(WCHAR) ); req->local = local; - if (!SERVER_CALL_ERR()) atom = req->atom; + if (!wine_server_call_err( req )) atom = reply->atom; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugres_w(str), atom ); return atom; @@ -679,21 +683,24 @@ static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local ) } else { + WCHAR full_name[MAX_ATOM_LEN]; + len = 0; - SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) ) + SERVER_START_REQ( get_atom_name ) { req->atom = atom; req->local = local; - if (!SERVER_CALL_ERR()) + wine_server_set_reply( req, full_name, sizeof(full_name) ); + if (!wine_server_call_err( req )) { - len = WideCharToMultiByte( CP_ACP, 0, server_data_ptr(req), - server_data_size(req) / sizeof(WCHAR), + len = WideCharToMultiByte( CP_ACP, 0, full_name, + wine_server_reply_size(reply) / sizeof(WCHAR), buffer, count - 1, NULL, NULL ); if (!len) len = count; /* overflow */ else buffer[len] = 0; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } if (len && count <= len) @@ -765,20 +772,23 @@ static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local ) } else { + WCHAR full_name[MAX_ATOM_LEN]; + len = 0; - SERVER_START_VAR_REQ( get_atom_name, MAX_ATOM_LEN * sizeof(WCHAR) ) + SERVER_START_REQ( get_atom_name ) { req->atom = atom; req->local = local; - if (!SERVER_CALL_ERR()) + wine_server_set_reply( req, full_name, sizeof(full_name) ); + if (!wine_server_call_err( req )) { - len = server_data_size(req) / sizeof(WCHAR); + len = wine_server_reply_size(reply) / sizeof(WCHAR); if (count > len) count = len + 1; - memcpy( buffer, server_data_ptr(req), (count-1) * sizeof(WCHAR) ); + memcpy( buffer, full_name, (count-1) * sizeof(WCHAR) ); buffer[count-1] = 0; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!len) return 0; } if (count <= len) diff --git a/memory/registry.c b/memory/registry.c index 5aecc07eb49..bef72d81d7c 100644 --- a/memory/registry.c +++ b/memory/registry.c @@ -606,6 +606,7 @@ DWORD WINAPI RegDeleteValueA( HKEY hkey, LPCSTR name ) LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) { HANDLE file; + WCHAR buffer[MAX_PATH]; DWORD ret, len, err = GetLastError(); TRACE( "(%x,%s,%s)\n", hkey, debugstr_a(subkey), debugstr_a(filename) ); @@ -613,8 +614,8 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) if (!filename || !*filename) return ERROR_INVALID_PARAMETER; if (!subkey || !*subkey) return ERROR_INVALID_PARAMETER; - len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), NULL, 0 ) * sizeof(WCHAR); - if (len > MAX_PATH*sizeof(WCHAR)) return ERROR_INVALID_PARAMETER; + if (!(len = MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), buffer, MAX_PATH ))) + return ERROR_INVALID_PARAMETER; if ((file = CreateFileA( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 )) == INVALID_HANDLE_VALUE) @@ -623,15 +624,14 @@ LONG WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) goto done; } - SERVER_START_VAR_REQ( load_registry, len ) + SERVER_START_REQ( load_registry ) { req->hkey = hkey; req->file = file; - MultiByteToWideChar( CP_ACP, 0, subkey, strlen(subkey), - server_data_ptr(req), len/sizeof(WCHAR) ); - ret = RtlNtStatusToDosError( SERVER_CALL() ); + wine_server_add_data( req, buffer, len * sizeof(WCHAR) ); + ret = RtlNtStatusToDosError( wine_server_call(req) ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; CloseHandle( file ); done: @@ -679,7 +679,7 @@ LONG WINAPI RegSaveKeyA( HKEY hkey, LPCSTR file, LPSECURITY_ATTRIBUTES sa ) { req->hkey = hkey; req->file = handle; - ret = RtlNtStatusToDosError( SERVER_CALL() ); + ret = RtlNtStatusToDosError( wine_server_call( req ) ); } SERVER_END_REQ; diff --git a/memory/selector.c b/memory/selector.c index c3f9d2a04fc..c3ce3132c24 100644 --- a/memory/selector.c +++ b/memory/selector.c @@ -594,18 +594,18 @@ BOOL WINAPI GetThreadSelectorEntry( HANDLE hthread, DWORD sel, LPLDT_ENTRY ldten { req->handle = hthread; req->entry = sel >> __AHSHIFT; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - if (!(req->flags & WINE_LDT_FLAGS_ALLOCATED)) + if (!(reply->flags & WINE_LDT_FLAGS_ALLOCATED)) { SetLastError( ERROR_MR_MID_NOT_FOUND ); /* sic */ ret = FALSE; } else { - wine_ldt_set_base( ldtent, (void *)req->base ); - wine_ldt_set_limit( ldtent, req->limit ); - wine_ldt_set_flags( ldtent, req->flags ); + wine_ldt_set_base( ldtent, (void *)reply->base ); + wine_ldt_set_limit( ldtent, reply->limit ); + wine_ldt_set_flags( ldtent, reply->flags ); } } } diff --git a/memory/virtual.c b/memory/virtual.c index 22346746d1d..f52aab5f587 100644 --- a/memory/virtual.c +++ b/memory/virtual.c @@ -1360,50 +1360,16 @@ HANDLE WINAPI CreateFileMappingA( DWORD size_low, /* [in] Low-order 32 bits of object size */ LPCSTR name /* [in] Name of file-mapping object */ ) { - HANDLE ret; - BYTE vprot; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; + WCHAR buffer[MAX_PATH]; - /* Check parameters */ + if (!name) return CreateFileMappingW( hFile, sa, protect, size_high, size_low, NULL ); - TRACE("(%x,%p,%08lx,%08lx%08lx,%s)\n", - hFile, sa, protect, size_high, size_low, debugstr_a(name) ); - - if (len > MAX_PATH) + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - vprot = VIRTUAL_GetProt( protect ); - if (protect & SEC_RESERVE) - { - if (hFile != INVALID_HANDLE_VALUE) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return 0; - } - } - else vprot |= VPROT_COMMITTED; - if (protect & SEC_NOCACHE) vprot |= VPROT_NOCACHE; - if (protect & SEC_IMAGE) vprot |= VPROT_IMAGE; - - /* Create the server object */ - - if (hFile == INVALID_HANDLE_VALUE) hFile = 0; - SERVER_START_VAR_REQ( create_mapping, len * sizeof(WCHAR) ) - { - req->file_handle = hFile; - req->size_high = size_high; - req->size_low = size_low; - req->protect = vprot; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return CreateFileMappingW( hFile, sa, protect, size_high, size_low, buffer ); } @@ -1446,19 +1412,19 @@ HANDLE WINAPI CreateFileMappingW( HANDLE hFile, LPSECURITY_ATTRIBUTES sa, /* Create the server object */ if (hFile == INVALID_HANDLE_VALUE) hFile = 0; - SERVER_START_VAR_REQ( create_mapping, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_mapping ) { req->file_handle = hFile; req->size_high = size_high; req->size_low = size_low; req->protect = vprot; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -1476,23 +1442,16 @@ HANDLE WINAPI OpenFileMappingA( BOOL inherit, /* [in] Inherit flag */ LPCSTR name ) /* [in] Name of file-mapping object */ { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len > MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenFileMappingW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) ) - { - req->access = access; - req->inherit = inherit; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return OpenFileMappingW( access, inherit, buffer ); } @@ -1504,20 +1463,20 @@ HANDLE WINAPI OpenFileMappingW( DWORD access, BOOL inherit, LPCWSTR name) { HANDLE ret; DWORD len = name ? strlenW(name) : 0; - if (len > MAX_PATH) + if (len >= MAX_PATH) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_mapping, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_mapping ) { req->access = access; req->inherit = inherit; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -1580,16 +1539,16 @@ LPVOID WINAPI MapViewOfFileEx( SERVER_START_REQ( get_mapping_info ) { req->handle = handle; - res = SERVER_CALL_ERR(); - prot = req->protect; - base = req->base; - size_low = req->size_low; - size_high = req->size_high; - header_size = req->header_size; - shared_file = req->shared_file; - shared_size = req->shared_size; - removable = (req->drive_type == DRIVE_REMOVABLE || - req->drive_type == DRIVE_CDROM); + res = wine_server_call_err( req ); + prot = reply->protect; + base = reply->base; + size_low = reply->size_low; + size_high = reply->size_high; + header_size = reply->header_size; + shared_file = reply->shared_file; + shared_size = reply->shared_size; + removable = (reply->drive_type == DRIVE_REMOVABLE || + reply->drive_type == DRIVE_CDROM); } SERVER_END_REQ; if (res) goto error; diff --git a/misc/options.c b/misc/options.c index dad6779630b..639c9e6ea14 100644 --- a/misc/options.c +++ b/misc/options.c @@ -38,10 +38,6 @@ const char *full_argv0; /* the full path of argv[0] (if known) */ static char *inherit_str; /* options to pass to child processes */ -static int app_argc; /* argc/argv to pass to application */ -static char **app_argv; -static WCHAR **app_wargv; - static void out_of_memory(void) WINE_NORETURN; static void out_of_memory(void) { @@ -340,55 +336,4 @@ void OPTIONS_ParseOptions( char *argv[] ) OPTIONS_Usage(); } } - - /* count the resulting arguments */ - app_argv = argv; - app_argc = 0; - while (argv[app_argc]) app_argc++; -} - - -/*********************************************************************** - * __wine_get_main_args (NTDLL.@) - * - * Return the argc/argv that the application should see. - * Used by the startup code generated in the .spec.c file. - */ -int __wine_get_main_args( char ***argv ) -{ - *argv = app_argv; - return app_argc; -} - - -/*********************************************************************** - * __wine_get_wmain_args (NTDLL.@) - * - * Same as __wine_get_main_args but for Unicode. - */ -int __wine_get_wmain_args( WCHAR ***argv ) -{ - if (!app_wargv) - { - int i; - WCHAR *p; - DWORD total = 0; - - for (i = 0; i < app_argc; i++) - total += MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, NULL, 0 ); - - app_wargv = HeapAlloc( GetProcessHeap(), 0, - total * sizeof(WCHAR) + (app_argc + 1) * sizeof(*app_wargv) ); - p = (WCHAR *)(app_wargv + app_argc + 1); - for (i = 0; i < app_argc; i++) - { - DWORD len = MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, p, total ); - app_wargv[i] = p; - p += len; - total -= len; - } - app_wargv[app_argc] = NULL; - } - *argv = app_wargv; - return app_argc; } diff --git a/misc/registry.c b/misc/registry.c index 818cd6567f8..4cfed5d000b 100644 --- a/misc/registry.c +++ b/misc/registry.c @@ -1004,7 +1004,7 @@ static void _set_registry_levels(int level,int saving,int period) req->current = level; req->saving = saving; req->period = period; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } @@ -1013,19 +1013,15 @@ static void _set_registry_levels(int level,int saving,int period) static void _save_at_exit(HKEY hkey,LPCSTR path) { LPCSTR confdir = get_config_dir(); - size_t len = strlen(confdir) + strlen(path) + 2; - if (len > REQUEST_MAX_VAR_SIZE) { - ERR( "config dir '%s' too long\n", confdir ); - return; - } - SERVER_START_VAR_REQ( save_registry_atexit, len ) + SERVER_START_REQ( save_registry_atexit ) { - sprintf( server_data_ptr(req), "%s/%s", confdir, path ); req->hkey = hkey; - SERVER_CALL(); + wine_server_add_data( req, confdir, strlen(confdir) ); + wine_server_add_data( req, path, strlen(path)+1 ); + wine_server_call( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } /* configure save files and start the periodic saving timer [Internal] */ @@ -1042,9 +1038,9 @@ static void _init_registry_saving( HKEY hkey_users_default ) if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1)) { - _save_at_exit(HKEY_CURRENT_USER,SAVE_LOCAL_REGBRANCH_CURRENT_USER ); - _save_at_exit(HKEY_LOCAL_MACHINE,SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE); - _save_at_exit(hkey_users_default,SAVE_LOCAL_REGBRANCH_USER_DEFAULT); + _save_at_exit(HKEY_CURRENT_USER,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER ); + _save_at_exit(HKEY_LOCAL_MACHINE,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE); + _save_at_exit(hkey_users_default,"/" SAVE_LOCAL_REGBRANCH_USER_DEFAULT); } } @@ -1190,7 +1186,7 @@ static void load_wine_registry(HKEY hkey,LPCSTR fn) { req->hkey = hkey; req->file = file; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; CloseHandle( file ); diff --git a/msdos/vga.c b/msdos/vga.c index ae64af2d11a..8175fa138cb 100644 --- a/msdos/vga.c +++ b/msdos/vga.c @@ -352,7 +352,8 @@ void CALLBACK VGA_Poll( ULONG_PTR arg ) ch[X].Attributes = *dat++; } dest.Left=0; dest.Right=Width+1; - WriteConsoleOutputA(con, ch, siz, off, &dest); + FIXME("output commented out for now, should be moved to winedos.dll\n"); + /*WriteConsoleOutputA(con, ch, siz, off, &dest);*/ } } vga_refresh=1; diff --git a/programs/wineconsole/wineconsole.c b/programs/wineconsole/wineconsole.c index 44f400b5094..879c7a8de2f 100644 --- a/programs/wineconsole/wineconsole.c +++ b/programs/wineconsole/wineconsole.c @@ -5,7 +5,8 @@ */ #include -#include +#include "wine/server.h" +#include "wine/unicode.h" #include "winecon_private.h" static int trace_level = 1; @@ -35,34 +36,20 @@ void XTracer(int level, const char* format, ...) * * updates the local copy of cells (band to update) */ -void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) +void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) { - int step; - int j, nr; - - step = REQUEST_MAX_VAR_SIZE / (data->sb_width * 4); - - for (j = upd_tp; j <= upd_bm; j += step) + SERVER_START_REQ( read_console_output ) { - nr = min(step, upd_bm - j + 1); - SERVER_START_VAR_REQ( read_console_output, 4 * nr * data->sb_width ) - { - req->handle = (handle_t)data->hConOut; - req->x = 0; - req->y = j; - req->w = data->sb_width; - req->h = nr; - if (!SERVER_CALL_ERR()) - { - if (data->sb_width != req->eff_w || nr != req->eff_h) - Trace(0, "pb here... wrong eff_w %d/%d or eff_h %d/%d\n", - req->eff_w, data->sb_width, req->eff_h, nr); - memcpy(&data->cells[j * data->sb_width], server_data_ptr(req), - 4 * nr * data->sb_width); - } - } - SERVER_END_VAR_REQ; + req->handle = (handle_t)data->hConOut; + req->x = 0; + req->y = upd_tp; + req->mode = CHAR_INFO_MODE_TEXTATTR; + req->wrap = TRUE; + wine_server_set_reply( req, &data->cells[upd_tp * data->sb_width], + (upd_bm-upd_tp+1) * data->sb_width * sizeof(CHAR_INFO) ); + wine_server_call( req ); } + SERVER_END_REQ; data->fnRefresh(data, upd_tp, upd_bm); } @@ -71,19 +58,17 @@ void WINECON_FetchCells(struct inner_data* data, int upd_tp, int upd_bm) * * Inform server that visible window on sb has changed */ -void WINECON_NotifyWindowChange(struct inner_data* data) +void WINECON_NotifyWindowChange(struct inner_data* data) { SERVER_START_REQ( set_console_output_info ) { - req->handle = (handle_t)data->hConOut; - req->win_left = data->win_pos.X; - req->win_top = data->win_pos.Y; - req->win_right = data->win_pos.X + data->win_width - 1; - req->win_bottom = data->win_pos.Y + data->win_height - 1; - req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW; - if (!SERVER_CALL_ERR()) - { - } + req->handle = (handle_t)data->hConOut; + req->win_left = data->win_pos.X; + req->win_top = data->win_pos.Y; + req->win_right = data->win_pos.X + data->win_width - 1; + req->win_bottom = data->win_pos.Y + data->win_height - 1; + req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW; + wine_server_call( req ); } SERVER_END_REQ; } @@ -100,7 +85,7 @@ int WINECON_GetHistorySize(HANDLE hConIn) SERVER_START_REQ(get_console_input_info) { req->handle = (handle_t)hConIn; - if (!SERVER_CALL_ERR()) ret = req->history_size; + if (!wine_server_call_err( req )) ret = reply->history_size; } SERVER_END_REQ; return ret; @@ -120,7 +105,7 @@ BOOL WINECON_SetHistorySize(HANDLE hConIn, int size) req->handle = (handle_t)hConIn; req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_SIZE; req->history_size = size; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -139,7 +124,7 @@ int WINECON_GetHistoryMode(HANDLE hConIn) SERVER_START_REQ(get_console_input_info) { req->handle = (handle_t)hConIn; - if (!SERVER_CALL_ERR()) ret = req->history_mode; + if (!wine_server_call_err( req )) ret = reply->history_mode; } SERVER_END_REQ; return ret; @@ -159,7 +144,7 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode) req->handle = (handle_t)hConIn; req->mask = SET_CONSOLE_INPUT_INFO_HISTORY_MODE; req->history_mode = mode; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -170,22 +155,23 @@ BOOL WINECON_SetHistoryMode(HANDLE hConIn, int mode) * * */ -BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len) +BOOL WINECON_GetConsoleTitle(HANDLE hConIn, WCHAR* buffer, size_t len) { - BOOL ret; - DWORD size = 0; + BOOL ret; - SERVER_START_VAR_REQ(get_console_input_info, sizeof(buffer)) + if (len < sizeof(WCHAR)) return FALSE; + + SERVER_START_REQ( get_console_input_info ) { - req->handle = (handle_t)hConIn; - if ((ret = !SERVER_CALL_ERR())) + req->handle = (handle_t)hConIn; + wine_server_set_reply( req, buffer, len - sizeof(WCHAR) ); + if ((ret = !wine_server_call_err( req ))) { - size = min(len - sizeof(WCHAR), server_data_size(req)); - memcpy(buffer, server_data_ptr(req), size); - buffer[size / sizeof(WCHAR)] = 0; + len = wine_server_reply_size( reply ); + buffer[len / sizeof(WCHAR)] = 0; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -200,18 +186,14 @@ int WINECON_GrabChanges(struct inner_data* data) int i, num; HANDLE h; - SERVER_START_VAR_REQ( get_console_renderer_events, sizeof(evts) ) + SERVER_START_REQ( get_console_renderer_events ) { - req->handle = (handle_t)data->hSynchro; - if (!SERVER_CALL_ERR()) - { - num = server_data_size(req); - memcpy(evts, server_data_ptr(req), num); - num /= sizeof(evts[0]); - } - else num = 0; + wine_server_set_reply( req, evts, sizeof(evts) ); + req->handle = (handle_t)data->hSynchro; + if (!wine_server_call_err( req )) num = wine_server_reply_size(reply) / sizeof(evts[0]); + else num = 0; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!num) {Trace(0, "hmm renderer signaled but no events available\n"); return 1;} /* FIXME: should do some event compression here (cursor pos, update) */ @@ -230,7 +212,7 @@ int WINECON_GrabChanges(struct inner_data* data) req->access = GENERIC_READ | GENERIC_WRITE; req->share = FILE_SHARE_READ | FILE_SHARE_WRITE; req->inherit = FALSE; - h = SERVER_CALL_ERR() ? 0 : (HANDLE)req->handle; + h = wine_server_call_err( req ) ? 0 : (HANDLE)reply->handle; } SERVER_END_REQ; Trace(1, " active(%d)", (int)h); @@ -340,7 +322,6 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) struct inner_data* data = NULL; DWORD ret; WCHAR szTitle[] = {'W','i','n','e',' ','c','o','n','s','o','l','e',0}; - size_t len; data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*data)); if (!data) return 0; @@ -355,24 +336,21 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) req->access = GENERIC_READ | GENERIC_WRITE; req->inherit = FALSE; req->pid = pid; - ret = !SERVER_CALL_ERR(); - data->hConIn = (HANDLE)req->handle_in; - data->hSynchro = (HANDLE)req->event; + ret = !wine_server_call_err( req ); + data->hConIn = (HANDLE)reply->handle_in; + data->hSynchro = (HANDLE)reply->event; } SERVER_END_REQ; if (!ret) goto error; - len = lstrlenW(szTitle) * sizeof(WCHAR); - len = min(len, REQUEST_MAX_VAR_SIZE); - - SERVER_START_VAR_REQ(set_console_input_info, len) + SERVER_START_REQ( set_console_input_info ) { - req->handle = (handle_t)data->hConIn; + req->handle = (handle_t)data->hConIn; req->mask = SET_CONSOLE_INPUT_INFO_TITLE; - memcpy(server_data_ptr(req), szTitle, len); - ret = !SERVER_CALL_ERR(); + wine_server_add_data( req, szTitle, strlenW(szTitle) * sizeof(WCHAR) ); + ret = !wine_server_call_err( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (ret) { @@ -382,7 +360,7 @@ static struct inner_data* WINECON_Init(HINSTANCE hInst, void* pid) req->access = GENERIC_WRITE|GENERIC_READ; req->share = FILE_SHARE_READ|FILE_SHARE_WRITE; req->inherit = FALSE; - data->hConOut = (HANDLE)(SERVER_CALL_ERR() ? 0 : req->handle_out); + data->hConOut = (HANDLE)(wine_server_call_err( req ) ? 0 : reply->handle_out); } SERVER_END_REQ; if (data->hConOut) return data; diff --git a/scheduler/client.c b/scheduler/client.c index a8cb4dd3e71..9fe5fd51661 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -113,69 +113,60 @@ void server_protocol_perror( const char *err ) } -/*********************************************************************** - * __wine_server_exception_handler (NTDLL.@) - */ -DWORD __wine_server_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_FRAME *frame, - CONTEXT *context, EXCEPTION_FRAME **pdispatcher ) -{ - struct __server_exception_frame *server_frame = (struct __server_exception_frame *)frame; - if ((record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) - NtCurrentTeb()->buffer_pos = server_frame->buffer_pos; - return ExceptionContinueSearch; -} - - -/*********************************************************************** - * wine_server_alloc_req (NTDLL.@) - */ -void wine_server_alloc_req( union generic_request *req, size_t size ) -{ - unsigned int pos = NtCurrentTeb()->buffer_pos; - - assert( size <= REQUEST_MAX_VAR_SIZE ); - - if (pos + size > NtCurrentTeb()->buffer_size) - server_protocol_error( "buffer overflow %d bytes\n", - pos + size - NtCurrentTeb()->buffer_pos ); - - NtCurrentTeb()->buffer_pos = pos + size; - req->header.var_offset = pos; - req->header.var_size = size; -} - - /*********************************************************************** * send_request * * Send a request to the server. */ -static void send_request( union generic_request *request ) +static void send_request( const struct __server_request_info *req ) { - int ret; + int i, ret; + + if (!req->u.req.request_header.request_size) + { + if ((ret = write( NtCurrentTeb()->request_fd, &req->u.req, + sizeof(req->u.req) )) == sizeof(req->u.req)) return; + + } + else + { + struct iovec vec[__SERVER_MAX_DATA+1]; + + vec[0].iov_base = (void *)&req->u.req; + vec[0].iov_len = sizeof(req->u.req); + for (i = 0; i < req->data_count; i++) + { + vec[i+1].iov_base = (void *)req->data[i].ptr; + vec[i+1].iov_len = req->data[i].size; + } + if ((ret = writev( NtCurrentTeb()->request_fd, vec, i+1 )) == + req->u.req.request_header.request_size + sizeof(req->u.req)) return; + } - if ((ret = write( NtCurrentTeb()->request_fd, request, sizeof(*request) )) == sizeof(*request)) - return; if (ret >= 0) server_protocol_error( "partial write %d\n", ret ); if (errno == EPIPE) SYSDEPS_ExitThread(0); server_protocol_perror( "sendmsg" ); } + /*********************************************************************** - * wait_reply + * read_reply_data * - * Wait for a reply from the server. + * Read data from the reply buffer; helper for wait_reply. */ -static void wait_reply( union generic_request *req ) +static void read_reply_data( void *buffer, size_t size ) { int ret; for (;;) { - if ((ret = read( NtCurrentTeb()->reply_fd, req, sizeof(*req) )) == sizeof(*req)) - return; + if ((ret = read( NtCurrentTeb()->reply_fd, buffer, size )) > 0) + { + if (!(size -= ret)) return; + buffer = (char *)buffer + ret; + continue; + } if (!ret) break; - if (ret > 0) server_protocol_error( "partial read %d\n", ret ); if (errno == EINTR) continue; if (errno == EPIPE) break; server_protocol_perror("read"); @@ -185,21 +176,35 @@ static void wait_reply( union generic_request *req ) } +/*********************************************************************** + * wait_reply + * + * Wait for a reply from the server. + */ +inline static void wait_reply( struct __server_request_info *req ) +{ + read_reply_data( &req->u.reply, sizeof(req->u.reply) ); + if (req->u.reply.reply_header.reply_size) + read_reply_data( req->reply_data, req->u.reply.reply_header.reply_size ); +} + + /*********************************************************************** * wine_server_call (NTDLL.@) * * Perform a server call. */ -unsigned int wine_server_call( union generic_request *req, size_t size ) +unsigned int wine_server_call( void *req_ptr ) { + struct __server_request_info * const req = req_ptr; sigset_t old_set; - memset( (char *)req + size, 0, sizeof(*req) - size ); + memset( (char *)&req->u.req + req->size, 0, sizeof(req->u.req) - req->size ); sigprocmask( SIG_BLOCK, &block_set, &old_set ); send_request( req ); wait_reply( req ); sigprocmask( SIG_SETMASK, &old_set, NULL ); - return req->header.error; + return req->u.reply.reply_header.error; } @@ -331,13 +336,13 @@ int wine_server_recv_fd( handle_t handle ) req->flags = 0; req->mask = 0; req->fd = fd; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - if (req->cur_fd != fd) + if (reply->cur_fd != fd) { /* someone was here before us */ close( fd ); - fd = req->cur_fd; + fd = reply->cur_fd; } } else @@ -596,47 +601,6 @@ void CLIENT_InitServer(void) } -/*********************************************************************** - * set_request_buffer - */ -inline static void set_request_buffer(void) -{ - char *name; - int fd, ret; - unsigned int offset, size; - - /* create a temporary file */ - do - { - if (!(name = tmpnam(NULL))) server_protocol_perror( "tmpnam" ); - fd = open( name, O_CREAT | O_EXCL | O_RDWR, 0600 ); - } while ((fd == -1) && (errno == EEXIST)); - - if (fd == -1) server_protocol_perror( "create" ); - unlink( name ); - - wine_server_send_fd( fd ); - - SERVER_START_REQ( set_thread_buffer ) - { - req->fd = fd; - ret = SERVER_CALL(); - offset = req->offset; - size = req->size; - } - SERVER_END_REQ; - if (ret) server_protocol_error( "set_thread_buffer failed with status %x\n", ret ); - - if ((NtCurrentTeb()->buffer = mmap( 0, size, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, offset )) == (void*)-1) - server_protocol_perror( "mmap" ); - - close( fd ); - NtCurrentTeb()->buffer_pos = 0; - NtCurrentTeb()->buffer_size = size; -} - - /*********************************************************************** * CLIENT_InitThread * @@ -670,11 +634,11 @@ void CLIENT_InitThread(void) req->entry = teb->entry_point; req->reply_fd = reply_pipe[1]; req->wait_fd = teb->wait_fd[1]; - ret = SERVER_CALL(); - teb->pid = req->pid; - teb->tid = req->tid; - version = req->version; - if (req->boot) boot_thread_id = teb->tid; + ret = wine_server_call( req ); + teb->pid = reply->pid; + teb->tid = reply->tid; + version = reply->version; + if (reply->boot) boot_thread_id = teb->tid; else if (boot_thread_id == teb->tid) boot_thread_id = 0; close( reply_pipe[1] ); } @@ -688,7 +652,6 @@ void CLIENT_InitThread(void) "Or maybe the wrong wineserver is still running?\n", version, SERVER_PROTOCOL_VERSION, (version > SERVER_PROTOCOL_VERSION) ? "wine" : "wineserver" ); - set_request_buffer(); } @@ -702,7 +665,7 @@ void CLIENT_BootDone( int debug_level ) SERVER_START_REQ( boot_done ) { req->debug_level = debug_level; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } diff --git a/scheduler/handle.c b/scheduler/handle.c index ea42da5e238..a9f7aa99d73 100644 --- a/scheduler/handle.c +++ b/scheduler/handle.c @@ -46,8 +46,8 @@ BOOL WINAPI GetHandleInformation( HANDLE handle, LPDWORD flags ) req->flags = 0; req->mask = 0; req->fd = -1; - ret = !SERVER_CALL_ERR(); - if (ret && flags) *flags = req->old_flags; + ret = !wine_server_call_err( req ); + if (ret && flags) *flags = reply->old_flags; } SERVER_END_REQ; return ret; @@ -66,7 +66,7 @@ BOOL WINAPI SetHandleInformation( HANDLE handle, DWORD mask, DWORD flags ) req->flags = flags; req->mask = mask; req->fd = -1; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -90,11 +90,11 @@ BOOL WINAPI DuplicateHandle( HANDLE source_process, HANDLE source, req->inherit = inherit; req->options = options; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); if (ret) { - if (dest) *dest = req->handle; - if (req->fd != -1) close( req->fd ); + if (dest) *dest = reply->handle; + if (reply->fd != -1) close( reply->fd ); } } SERVER_END_REQ; diff --git a/scheduler/pipe.c b/scheduler/pipe.c index 58162038d3f..1332460dd88 100644 --- a/scheduler/pipe.c +++ b/scheduler/pipe.c @@ -20,10 +20,10 @@ BOOL WINAPI CreatePipe( PHANDLE hReadPipe, PHANDLE hWritePipe, SERVER_START_REQ( create_pipe ) { req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - *hReadPipe = req->handle_read; - *hWritePipe = req->handle_write; + *hReadPipe = reply->handle_read; + *hWritePipe = reply->handle_write; } } SERVER_END_REQ; diff --git a/scheduler/process.c b/scheduler/process.c index 755dd396cda..3577ee59dd0 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -92,7 +92,9 @@ PDB current_process; #define PDB32_FILE_APIS_OEM 0x0040 /* File APIs are OEM */ #define PDB32_WIN32S_PROC 0x8000 /* Win32s process */ -static char **main_exe_argv; +static int app_argc; /* argc/argv seen by the application */ +static char **app_argv; +static WCHAR **app_wargv; static char main_exe_name[MAX_PATH]; static char *main_exe_name_ptr = main_exe_name; static HANDLE main_exe_file; @@ -229,7 +231,7 @@ static BOOL process_init( char *argv[] ) /* store the program name */ argv0 = argv[0]; - main_exe_argv = argv; + app_argv = argv; /* Fill the initial process structure */ current_process.exit_code = STILL_ACTIVE; @@ -243,26 +245,26 @@ static BOOL process_init( char *argv[] ) CLIENT_InitServer(); /* Retrieve startup info from the server */ - SERVER_START_VAR_REQ( init_process, sizeof(main_exe_name)-1 ) + SERVER_START_REQ( init_process ) { req->ldt_copy = &wine_ldt_copy; req->ppid = getppid(); - if ((ret = !SERVER_CALL_ERR())) + wine_server_set_reply( req, main_exe_name, sizeof(main_exe_name)-1 ); + if ((ret = !wine_server_call_err( req ))) { - size_t len = server_data_size( req ); - memcpy( main_exe_name, server_data_ptr(req), len ); + size_t len = wine_server_reply_size( reply ); main_exe_name[len] = 0; - main_exe_file = req->exe_file; - create_flags = req->create_flags; - current_startupinfo.dwFlags = req->start_flags; - server_startticks = req->server_start; - current_startupinfo.wShowWindow = req->cmd_show; - current_startupinfo.hStdInput = req->hstdin; - current_startupinfo.hStdOutput = req->hstdout; - current_startupinfo.hStdError = req->hstderr; + main_exe_file = reply->exe_file; + create_flags = reply->create_flags; + current_startupinfo.dwFlags = reply->start_flags; + server_startticks = reply->server_start; + current_startupinfo.wShowWindow = reply->cmd_show; + current_startupinfo.hStdInput = reply->hstdin; + current_startupinfo.hStdOutput = reply->hstdout; + current_startupinfo.hStdError = reply->hstderr; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!ret) return FALSE; /* Create the process heap */ @@ -295,6 +297,8 @@ static BOOL process_init( char *argv[] ) /* Parse command line arguments */ OPTIONS_ParseOptions( argv ); + app_argc = 0; + while (argv[app_argc]) app_argc++; ret = MAIN_MainInit(); @@ -345,8 +349,8 @@ static void start_process(void) req->name = &main_exe_name_ptr; req->exe_file = main_file; req->gui = !console_app; - SERVER_CALL(); - debugged = req->debugged; + wine_server_call( req ); + debugged = reply->debugged; } SERVER_END_REQ; @@ -464,19 +468,20 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win /* Initialize everything */ if (!process_init( argv )) exit(1); - if (open_winelib_app( argv )) goto found; /* try to open argv[0] as a winelib app */ + if (open_winelib_app( app_argv )) goto found; /* try to open argv[0] as a winelib app */ - main_exe_argv = ++argv; /* remove argv[0] (wine itself) */ + app_argv++; /* remove argv[0] (wine itself) */ + app_argc--; if (!main_exe_name[0]) { - if (!argv[0]) OPTIONS_Usage(); + if (!app_argv[0]) OPTIONS_Usage(); /* open the exe file */ - if (!SearchPathA( NULL, argv[0], ".exe", sizeof(main_exe_name), main_exe_name, NULL ) && - !SearchPathA( NULL, argv[0], NULL, sizeof(main_exe_name), main_exe_name, NULL )) + if (!SearchPathA( NULL, app_argv[0], ".exe", sizeof(main_exe_name), main_exe_name, NULL) && + !SearchPathA( NULL, app_argv[0], NULL, sizeof(main_exe_name), main_exe_name, NULL)) { - MESSAGE( "%s: cannot find '%s'\n", argv0, argv[0] ); + MESSAGE( "%s: cannot find '%s'\n", argv0, app_argv[0] ); goto error; } } @@ -510,7 +515,7 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win found: /* build command line */ - if (!ENV_BuildCommandLine( main_exe_argv )) goto error; + if (!ENV_BuildCommandLine( app_argv )) goto error; /* create 32-bit module for main exe */ if (!(current_process.module = BUILTIN32_LoadExeModule( current_process.module ))) goto error; @@ -527,6 +532,52 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win } +/*********************************************************************** + * __wine_get_main_args (NTDLL.@) + * + * Return the argc/argv that the application should see. + * Used by the startup code generated in the .spec.c file. + */ +int __wine_get_main_args( char ***argv ) +{ + *argv = app_argv; + return app_argc; +} + + +/*********************************************************************** + * __wine_get_wmain_args (NTDLL.@) + * + * Same as __wine_get_main_args but for Unicode. + */ +int __wine_get_wmain_args( WCHAR ***argv ) +{ + if (!app_wargv) + { + int i; + WCHAR *p; + DWORD total = 0; + + for (i = 0; i < app_argc; i++) + total += MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, NULL, 0 ); + + app_wargv = HeapAlloc( GetProcessHeap(), 0, + total * sizeof(WCHAR) + (app_argc + 1) * sizeof(*app_wargv) ); + p = (WCHAR *)(app_wargv + app_argc + 1); + for (i = 0; i < app_argc; i++) + { + DWORD len = MultiByteToWideChar( CP_ACP, 0, app_argv[i], -1, p, total ); + app_wargv[i] = p; + p += len; + total -= len; + } + app_wargv[app_argc] = NULL; + } + *argv = app_wargv; + return app_argc; +} + + /*********************************************************************** * build_argv * @@ -820,8 +871,10 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, /* create the process on the server side */ - SERVER_START_VAR_REQ( new_process, MAX_PATH ) + SERVER_START_REQ( new_process ) { + char buf[MAX_PATH]; + req->inherit_all = inherit; req->create_flags = flags; req->start_flags = startup->dwFlags; @@ -845,17 +898,19 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, unixfilename = filename; if (DOSFS_GetFullName( filename, TRUE, &full_name )) unixfilename = full_name.long_name; - lstrcpynA( server_data_ptr(req), unixfilename, MAX_PATH ); + wine_server_add_data( req, unixfilename, strlen(unixfilename) ); } else /* new wine process */ { - if (!GetLongPathNameA( filename, server_data_ptr(req), MAX_PATH )) - lstrcpynA( server_data_ptr(req), filename, MAX_PATH ); + if (GetLongPathNameA( filename, buf, MAX_PATH )) + wine_server_add_data( req, buf, strlen(buf) ); + else + wine_server_add_data( req, filename, strlen(filename) ); } - ret = !SERVER_CALL_ERR(); - process_info = req->info; + ret = !wine_server_call_err( req ); + process_info = reply->info; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!ret) return FALSE; /* fork and execute */ @@ -876,13 +931,13 @@ BOOL PROCESS_Create( HANDLE hFile, LPCSTR filename, LPSTR cmd_line, LPCSTR env, req->info = process_info; req->pinherit = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle); req->tinherit = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle); - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - info->dwProcessId = (DWORD)req->pid; - info->dwThreadId = (DWORD)req->tid; - info->hProcess = req->phandle; - info->hThread = req->thandle; - load_done_evt = req->event; + info->dwProcessId = (DWORD)reply->pid; + info->dwThreadId = (DWORD)reply->tid; + info->hProcess = reply->phandle; + info->hThread = reply->thandle; + load_done_evt = reply->event; } } SERVER_END_REQ; @@ -924,7 +979,7 @@ void WINAPI ExitProcess( DWORD status ) /* send the exit code to the server */ req->handle = GetCurrentProcess(); req->exit_code = status; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; exit( status ); @@ -1084,7 +1139,7 @@ HANDLE WINAPI OpenProcess( DWORD access, BOOL inherit, DWORD id ) req->pid = (void *)id; req->access = access; req->inherit = inherit; - if (!SERVER_CALL_ERR()) ret = req->handle; + if (!wine_server_call_err( req )) ret = reply->handle; } SERVER_END_REQ; return ret; @@ -1099,7 +1154,7 @@ DWORD WINAPI MapProcessHandle( HANDLE handle ) SERVER_START_REQ( get_process_info ) { req->handle = handle; - if (!SERVER_CALL_ERR()) ret = (DWORD)req->pid; + if (!wine_server_call_err( req )) ret = (DWORD)reply->pid; } SERVER_END_REQ; return ret; @@ -1116,7 +1171,7 @@ BOOL WINAPI SetPriorityClass( HANDLE hprocess, DWORD priorityclass ) req->handle = hprocess; req->priority = priorityclass; req->mask = SET_PROCESS_INFO_PRIORITY; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1132,7 +1187,7 @@ DWORD WINAPI GetPriorityClass(HANDLE hprocess) SERVER_START_REQ( get_process_info ) { req->handle = hprocess; - if (!SERVER_CALL_ERR()) ret = req->priority; + if (!wine_server_call_err( req )) ret = reply->priority; } SERVER_END_REQ; return ret; @@ -1150,7 +1205,7 @@ BOOL WINAPI SetProcessAffinityMask( HANDLE hProcess, DWORD affmask ) req->handle = hProcess; req->affinity = affmask; req->mask = SET_PROCESS_INFO_AFFINITY; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1167,10 +1222,10 @@ BOOL WINAPI GetProcessAffinityMask( HANDLE hProcess, SERVER_START_REQ( get_process_info ) { req->handle = hProcess; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { - if (lpProcessAffinityMask) *lpProcessAffinityMask = req->process_affinity; - if (lpSystemAffinityMask) *lpSystemAffinityMask = req->system_affinity; + if (lpProcessAffinityMask) *lpProcessAffinityMask = reply->process_affinity; + if (lpSystemAffinityMask) *lpSystemAffinityMask = reply->system_affinity; ret = TRUE; } } @@ -1289,62 +1344,36 @@ BOOL WINAPI SetProcessPriorityBoost(HANDLE hprocess,BOOL disableboost) BOOL WINAPI ReadProcessMemory( HANDLE process, LPCVOID addr, LPVOID buffer, DWORD size, LPDWORD bytes_read ) { - unsigned int offset = (unsigned int)addr % sizeof(int); - unsigned int pos = 0, len, max; - int res; + DWORD res; - if (bytes_read) *bytes_read = size; - - /* first time, read total length to check for permissions */ - len = (size + offset + sizeof(int) - 1) / sizeof(int); - max = min( REQUEST_MAX_VAR_SIZE, len * sizeof(int) ); - - for (;;) + SERVER_START_REQ( read_process_memory ) { - SERVER_START_VAR_REQ( read_process_memory, max ) - { - req->handle = process; - req->addr = (char *)addr + pos - offset; - req->len = len; - if (!(res = SERVER_CALL_ERR())) - { - size_t result = server_data_size( req ); - if (result > size + offset) result = size + offset; - memcpy( (char *)buffer + pos, server_data_ptr(req) + offset, result - offset ); - size -= result - offset; - pos += result - offset; - } - } - SERVER_END_VAR_REQ; - if (res) - { - if (bytes_read) *bytes_read = 0; - return FALSE; - } - if (!size) return TRUE; - max = min( REQUEST_MAX_VAR_SIZE, size ); - len = (max + sizeof(int) - 1) / sizeof(int); - offset = 0; + req->handle = process; + req->addr = (void *)addr; + wine_server_set_reply( req, buffer, size ); + if ((res = wine_server_call_err( req ))) size = 0; } + SERVER_END_REQ; + if (bytes_read) *bytes_read = size; + return !res; } /*********************************************************************** * WriteProcessMemory (KERNEL32.@) */ -BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPVOID buffer, DWORD size, +BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPCVOID buffer, DWORD size, LPDWORD bytes_written ) { - unsigned int first_offset, last_offset; - unsigned int pos = 0, len, max, first_mask, last_mask; - int res; + static const int zero; + unsigned int first_offset, last_offset, first_mask, last_mask; + DWORD res; if (!size) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } - if (bytes_written) *bytes_written = size; /* compute the mask for the first int */ first_mask = ~0; @@ -1356,44 +1385,26 @@ BOOL WINAPI WriteProcessMemory( HANDLE process, LPVOID addr, LPVOID buffer, DWOR last_mask = 0; memset( &last_mask, 0xff, last_offset ? last_offset : sizeof(int) ); - /* for the first request, use the total length */ - len = (size + first_offset + sizeof(int) - 1) / sizeof(int); - max = min( REQUEST_MAX_VAR_SIZE, len * sizeof(int) ); - - for (;;) + SERVER_START_REQ( write_process_memory ) { - SERVER_START_VAR_REQ( write_process_memory, max ) - { - req->handle = process; - req->addr = (char *)addr - first_offset + pos; - req->len = len; - req->first_mask = (!pos) ? first_mask : ~0; - if (size + first_offset <= max) /* last round */ - { - req->last_mask = last_mask; - max = size + first_offset; - } - else req->last_mask = ~0; + req->handle = process; + req->addr = (char *)addr - first_offset; + req->first_mask = first_mask; + req->last_mask = last_mask; + if (first_offset) wine_server_add_data( req, &zero, first_offset ); + wine_server_add_data( req, buffer, size ); + if (last_offset) wine_server_add_data( req, &zero, sizeof(int) - last_offset ); - memcpy( (char *)server_data_ptr(req) + first_offset, (char *)buffer + pos, - max - first_offset ); - if (!(res = SERVER_CALL_ERR())) - { - pos += max - first_offset; - size -= max - first_offset; - } - } - SERVER_END_VAR_REQ; - if (res) - { - if (bytes_written) *bytes_written = 0; - return FALSE; - } - if (!size) return TRUE; - first_offset = 0; - len = min( size + sizeof(int) - 1, REQUEST_MAX_VAR_SIZE ) / sizeof(int); - max = len * sizeof(int); + if ((res = wine_server_call_err( req ))) size = 0; } + SERVER_END_REQ; + if (bytes_written) *bytes_written = size; + { + char dummy[32]; + DWORD read; + ReadProcessMemory( process, addr, dummy, sizeof(dummy), &read ); + } + return !res; } @@ -1427,8 +1438,8 @@ BOOL WINAPI GetExitCodeProcess( SERVER_START_REQ( get_process_info ) { req->handle = hProcess; - ret = !SERVER_CALL_ERR(); - if (ret && lpExitCode) *lpExitCode = req->exit_code; + ret = !wine_server_call_err( req ); + if (ret && lpExitCode) *lpExitCode = reply->exit_code; } SERVER_END_REQ; return ret; diff --git a/scheduler/synchro.c b/scheduler/synchro.c index 5bb83ffc311..5220f0e2858 100644 --- a/scheduler/synchro.c +++ b/scheduler/synchro.c @@ -226,17 +226,17 @@ static void call_apcs( BOOL alertable ) for (;;) { int type = APC_NONE; - SERVER_START_VAR_REQ( get_apc, sizeof(args) ) + SERVER_START_REQ( get_apc ) { req->alertable = alertable; - if (!SERVER_CALL()) + wine_server_set_reply( req, args, sizeof(args) ); + if (!wine_server_call( req )) { - type = req->type; - proc = req->func; - memcpy( args, server_data_ptr(req), server_data_size(req) ); + type = reply->type; + proc = reply->func; } } - SERVER_END_VAR_REQ; + SERVER_END_REQ; switch(type) { @@ -315,7 +315,7 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout, BOOL alertable ) { - int i, ret, cookie; + int ret, cookie; struct timeval tv; if (count > MAXIMUM_WAIT_OBJECTS) @@ -329,23 +329,21 @@ DWORD WINAPI WaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, for (;;) { - SERVER_START_VAR_REQ( select, count * sizeof(int) ) + SERVER_START_REQ( select ) { - int *data = server_data_ptr( req ); - req->flags = SELECT_INTERRUPTIBLE; req->cookie = &cookie; req->sec = tv.tv_sec; req->usec = tv.tv_usec; - for (i = 0; i < count; i++) data[i] = handles[i]; + wine_server_add_data( req, handles, count * sizeof(HANDLE) ); if (wait_all) req->flags |= SELECT_ALL; if (alertable) req->flags |= SELECT_ALERTABLE; if (timeout != INFINITE) req->flags |= SELECT_TIMEOUT; - ret = SERVER_CALL(); + ret = wine_server_call( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (ret == STATUS_PENDING) ret = wait_reply( &cookie ); if (ret != STATUS_USER_APC) break; call_apcs( alertable ); diff --git a/scheduler/thread.c b/scheduler/thread.c index e3cf2cdaeef..860df592a67 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -51,7 +51,7 @@ TEB *THREAD_IdToTEB( DWORD id ) { req->handle = 0; req->tid_in = (void *)id; - if (!SERVER_CALL()) ret = req->teb; + if (!wine_server_call( req )) ret = reply->teb; } SERVER_END_REQ; @@ -112,7 +112,6 @@ static void CALLBACK THREAD_FreeTEB( TEB *teb ) close( teb->wait_fd[1] ); if (teb->stack_sel) FreeSelector16( teb->stack_sel ); FreeSelector16( teb->teb_sel ); - if (teb->buffer) munmap( (void *)teb->buffer, teb->buffer_size ); if (teb->debug_info) HeapFree( GetProcessHeap(), 0, teb->debug_info ); VirtualFree( teb->stack_base, 0, MEM_RELEASE ); } @@ -298,10 +297,10 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack, req->suspend = ((flags & CREATE_SUSPENDED) != 0); req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); req->request_fd = request_pipe[0]; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { - handle = req->handle; - tid = req->tid; + handle = reply->handle; + tid = reply->tid; } close( request_pipe[0] ); } @@ -370,8 +369,8 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */ /* send the exit code to the server */ req->handle = GetCurrentThread(); req->exit_code = code; - SERVER_CALL(); - last = req->last; + wine_server_call( req ); + last = reply->last; } SERVER_END_REQ; @@ -400,14 +399,14 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread const CONTEXT *context ) /* [in] Address of context structure */ { BOOL ret; - SERVER_START_VAR_REQ( set_thread_context, sizeof(*context) ) + SERVER_START_REQ( set_thread_context ) { req->handle = handle; req->flags = context->ContextFlags; - memcpy( server_data_ptr(req), context, sizeof(*context) ); - ret = !SERVER_CALL_ERR(); + wine_server_add_data( req, context, sizeof(*context) ); + ret = !wine_server_call_err( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -423,15 +422,15 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with CONTEXT *context ) /* [out] Address of context structure */ { BOOL ret; - SERVER_START_VAR_REQ( get_thread_context, sizeof(*context) ) + SERVER_START_REQ( get_thread_context ) { req->handle = handle; req->flags = context->ContextFlags; - memcpy( server_data_ptr(req), context, sizeof(*context) ); - if ((ret = !SERVER_CALL_ERR())) - memcpy( context, server_data_ptr(req), sizeof(*context) ); + wine_server_add_data( req, context, sizeof(*context) ); + wine_server_set_reply( req, context, sizeof(*context) ); + ret = !wine_server_call_err( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -451,7 +450,7 @@ INT WINAPI GetThreadPriority( { req->handle = hthread; req->tid_in = 0; - if (!SERVER_CALL_ERR()) ret = req->priority; + if (!wine_server_call_err( req )) ret = reply->priority; } SERVER_END_REQ; return ret; @@ -475,7 +474,7 @@ BOOL WINAPI SetThreadPriority( req->handle = hthread; req->priority = priority; req->mask = SET_THREAD_INFO_PRIORITY; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -529,7 +528,7 @@ DWORD WINAPI SetThreadAffinityMask( HANDLE hThread, DWORD dwThreadAffinityMask ) req->handle = hThread; req->affinity = dwThreadAffinityMask; req->mask = SET_THREAD_INFO_AFFINITY; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); /* FIXME: should return previous value */ } SERVER_END_REQ; @@ -571,8 +570,8 @@ BOOL WINAPI GetExitCodeThread( { req->handle = hthread; req->tid_in = 0; - ret = !SERVER_CALL_ERR(); - if (ret && exitcode) *exitcode = req->exit_code; + ret = !wine_server_call_err( req ); + if (ret && exitcode) *exitcode = reply->exit_code; } SERVER_END_REQ; return ret; @@ -597,7 +596,7 @@ DWORD WINAPI ResumeThread( SERVER_START_REQ( resume_thread ) { req->handle = hthread; - if (!SERVER_CALL_ERR()) ret = req->count; + if (!wine_server_call_err( req )) ret = reply->count; } SERVER_END_REQ; return ret; @@ -618,7 +617,7 @@ DWORD WINAPI SuspendThread( SERVER_START_REQ( suspend_thread ) { req->handle = hthread; - if (!SERVER_CALL_ERR()) ret = req->count; + if (!wine_server_call_err( req )) ret = reply->count; } SERVER_END_REQ; return ret; @@ -637,7 +636,7 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) req->user = 1; req->func = func; req->param = (void *)data; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; diff --git a/scheduler/timer.c b/scheduler/timer.c index 1fec1117bf3..2763f934ac8 100644 --- a/scheduler/timer.c +++ b/scheduler/timer.c @@ -18,24 +18,16 @@ */ HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return CreateWaitableTimerW( sa, manual, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) ) - { - req->manual = manual; - req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return CreateWaitableTimerW( sa, manual, buffer ); } @@ -51,16 +43,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( create_timer, len * sizeof(WCHAR) ) + SERVER_START_REQ( create_timer ) { req->manual = manual; req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); + wine_server_add_data( req, name, len * sizeof(WCHAR) ); SetLastError(0); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -70,23 +62,16 @@ HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWST */ HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name ) { - HANDLE ret; - DWORD len = name ? MultiByteToWideChar( CP_ACP, 0, name, strlen(name), NULL, 0 ) : 0; - if (len >= MAX_PATH) + WCHAR buffer[MAX_PATH]; + + if (!name) return OpenWaitableTimerW( access, inherit, NULL ); + + if (!MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, MAX_PATH )) { SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) ) - { - req->access = access; - req->inherit = inherit; - if (len) MultiByteToWideChar( CP_ACP, 0, name, strlen(name), server_data_ptr(req), len ); - SERVER_CALL_ERR(); - ret = req->handle; - } - SERVER_END_VAR_REQ; - return ret; + return OpenWaitableTimerW( access, inherit, buffer ); } @@ -102,15 +87,15 @@ HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name ) SetLastError( ERROR_FILENAME_EXCED_RANGE ); return 0; } - SERVER_START_VAR_REQ( open_timer, len * sizeof(WCHAR) ) + SERVER_START_REQ( open_timer ) { req->access = access; req->inherit = inherit; - memcpy( server_data_ptr(req), name, len * sizeof(WCHAR) ); - SERVER_CALL_ERR(); - ret = req->handle; + wine_server_add_data( req, name, len * sizeof(WCHAR) ); + wine_server_call_err( req ); + ret = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -150,7 +135,7 @@ BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG per req->callback = callback; req->arg = arg; if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */ - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -166,7 +151,7 @@ BOOL WINAPI CancelWaitableTimer( HANDLE handle ) SERVER_START_REQ( cancel_timer ) { req->handle = handle; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; diff --git a/server/async.c b/server/async.c index bcb5714a61c..5e160004e05 100644 --- a/server/async.c +++ b/server/async.c @@ -28,7 +28,7 @@ DECL_HANDLER(create_async) /* FIXME: check if this object is allowed to do overlapped I/O */ /* FIXME: this should be a function pointer */ - req->timeout = get_serial_async_timeout(obj,req->type,req->count); + reply->timeout = get_serial_async_timeout(obj,req->type,req->count); release_object(obj); } diff --git a/server/atom.c b/server/atom.c index a0e0e4b7022..7d0b52cd0fb 100644 --- a/server/atom.c +++ b/server/atom.c @@ -65,11 +65,14 @@ static const struct object_ops atom_table_ops = static struct atom_table *global_table; -/* copy an atom name to a temporary area */ -static const WCHAR *copy_name( const WCHAR *str, size_t len ) +/* copy an atom name from the request to a temporary area */ +static const WCHAR *copy_request_name(void) { static WCHAR buffer[MAX_ATOM_LEN+1]; + const WCHAR *str = get_req_data(); + size_t len = get_req_data_size(); + if (len > MAX_ATOM_LEN*sizeof(WCHAR)) { set_error( STATUS_INVALID_PARAMETER ); @@ -267,27 +270,6 @@ static atom_t find_atom( struct atom_table *table, const WCHAR *str ) return 0; } -/* get an atom name and refcount*/ -static size_t get_atom_name( struct atom_table *table, atom_t atom, - WCHAR *str, size_t maxsize, int *count ) -{ - size_t len = 0; - struct atom_entry *entry = get_atom_entry( table, atom ); - *count = -1; - if (entry) - { - *count = entry->count; - len = strlenW( entry->str ) * sizeof(WCHAR); - if (len <= maxsize) memcpy( str, entry->str, len ); - else - { - set_error( STATUS_BUFFER_OVERFLOW ); - len = 0; - } - } - return len; -} - /* increment the ref count of a global atom; used for window properties */ int grab_global_atom( atom_t atom ) { @@ -310,8 +292,8 @@ DECL_HANDLER(add_atom) if (!*table_ptr) *table_ptr = create_table(0); if (*table_ptr) { - const WCHAR *name = copy_name( get_req_data(req), get_req_data_size(req) ); - if (name) req->atom = add_atom( *table_ptr, name ); + const WCHAR *name = copy_request_name(); + if (name) reply->atom = add_atom( *table_ptr, name ); } } @@ -324,18 +306,26 @@ DECL_HANDLER(delete_atom) /* find a global atom */ DECL_HANDLER(find_atom) { - const WCHAR *name = copy_name( get_req_data(req), get_req_data_size(req) ); + const WCHAR *name = copy_request_name(); if (name) - req->atom = find_atom( req->local ? current->process->atom_table : global_table, name ); + reply->atom = find_atom( req->local ? current->process->atom_table : global_table, name ); } /* get global atom name */ DECL_HANDLER(get_atom_name) { - WCHAR *name = get_req_data(req); - size_t size = get_atom_name( req->local ? current->process->atom_table : global_table, - req->atom, name, get_req_data_size(req), &req->count ); - set_req_data_size( req, size ); + struct atom_entry *entry; + size_t len = 0; + + reply->count = -1; + if ((entry = get_atom_entry( req->local ? current->process->atom_table : global_table, + req->atom ))) + { + reply->count = entry->count; + len = strlenW( entry->str ) * sizeof(WCHAR); + if (len <= get_reply_max_size()) set_reply_data( entry->str, len ); + else set_error( STATUS_BUFFER_OVERFLOW ); + } } /* init the process atom table */ diff --git a/server/change.c b/server/change.c index 4dd0dcb04a5..1162b6a7e96 100644 --- a/server/change.c +++ b/server/change.c @@ -72,11 +72,11 @@ DECL_HANDLER(create_change_notification) { struct change *change; - req->handle = 0; + reply->handle = 0; if ((change = create_change_notification( req->subtree, req->filter ))) { - req->handle = alloc_handle( current->process, change, - STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 ); + reply->handle = alloc_handle( current->process, change, + STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE, 0 ); release_object( change ); } } diff --git a/server/console.c b/server/console.c index bd6dd39e869..4ea264e3757 100644 --- a/server/console.c +++ b/server/console.c @@ -13,10 +13,6 @@ #include #include -#include "winnt.h" -#include "winbase.h" -#include "wincon.h" - #include "handle.h" #include "process.h" #include "request.h" @@ -29,7 +25,7 @@ static void console_input_destroy( struct object *obj ); static int console_input_signaled( struct object *obj, struct thread *thread ); /* common routine */ -static int console_get_file_info( struct object *obj, struct get_file_info_request *req ); +static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply ); static const struct object_ops console_input_ops = { @@ -78,19 +74,21 @@ static const struct object_ops console_input_events_ops = struct screen_buffer { struct object obj; /* object header */ - int mode; /* output mode */ - struct console_input *input; /* associated console input */ struct screen_buffer *next; /* linked list of all screen buffers */ - short int cursor_size; /* size of cursor (percentage filled) */ - short int cursor_visible;/* cursor visibility flag */ - COORD cursor; /* position of cursor */ - short int width; /* size (w-h) of the screen buffer */ - short int height; - short int max_width; /* size (w-h) of the window given font size */ - short int max_height; - unsigned *data; /* the data for each cell - a width x height matrix */ + struct screen_buffer *prev; + struct console_input *input; /* associated console input */ + int mode; /* output mode */ + int cursor_size; /* size of cursor (percentage filled) */ + int cursor_visible;/* cursor visibility flag */ + int cursor_x; /* position of cursor */ + int cursor_y; /* position of cursor */ + int width; /* size (w-h) of the screen buffer */ + int height; + int max_width; /* size (w-h) of the window given font size */ + int max_height; + char_info_t *data; /* the data for each cell - a width x height matrix */ unsigned short attr; /* default attribute for screen buffer */ - SMALL_RECT win; /* current visible window on the screen buffer * + rectangle_t win; /* current visible window on the screen buffer * * as seen in wineconsole */ }; @@ -115,6 +113,8 @@ static const struct object_ops screen_buffer_ops = static struct screen_buffer *screen_buffer_list; +static const char_info_t empty_char_info = { ' ', 0x00f0 }; /* white on black space */ + /* dumps the renderer events of a console */ static void console_input_events_dump( struct object *obj, int verbose ) { @@ -132,20 +132,18 @@ static void console_input_events_destroy( struct object *obj ) free( evts->events ); } -/* the rendere events list is signaled when it's not empty */ -static int console_input_events_signaled( struct object *obj, struct thread *thread ) +/* the renderer events list is signaled when it's not empty */ +static int console_input_events_signaled( struct object *obj, struct thread *thread ) { struct console_input_events *evts = (struct console_input_events *)obj; assert( obj->ops == &console_input_events_ops ); - return evts->num_used ? 1 : 0; + return (evts->num_used != 0); } /* add an event to the console's renderer events list */ static void console_input_events_append( struct console_input_events* evts, struct console_renderer_event* evt) { - if (!evt) return; - /* to be done even when the renderer generates the events ? */ if (evts->num_used == evts->num_alloc) { @@ -158,25 +156,18 @@ static void console_input_events_append( struct console_input_events* evts, } /* retrieves events from the console's renderer events list */ -static size_t console_input_events_get( struct console_input_events* evts, - struct console_renderer_event* evt, size_t num ) +static void console_input_events_get( struct console_input_events* evts ) { - if (num % sizeof(*evt) != 0) - { - set_error( STATUS_INVALID_PARAMETER ); - return 0; - } - num /= sizeof(*evt); - if (num > evts->num_used) - num = evts->num_used; - memcpy( evt, evts->events, num * sizeof(*evt) ); + size_t num = get_reply_max_size() / sizeof(evts->events[0]); + + if (num > evts->num_used) num = evts->num_used; + set_reply_data( evts->events, num * sizeof(evts->events[0]) ); if (num < evts->num_used) { - memmove( &evts->events[0], &evts->events[num], - (evts->num_used - num) * sizeof(*evt) ); + memmove( &evts->events[0], &evts->events[num], + (evts->num_used - num) * sizeof(evts->events[0]) ); } evts->num_used -= num; - return num * sizeof(struct console_renderer_event); } static struct console_input_events *create_console_input_events(void) @@ -216,7 +207,7 @@ static struct object *create_console_input( struct process* renderer ) return &console_input->obj; } -static struct object *create_console_output( struct console_input *console_input ) +static struct screen_buffer *create_console_output( struct console_input *console_input ) { struct screen_buffer *screen_buffer; struct console_renderer_event evt; @@ -231,23 +222,31 @@ static struct object *create_console_output( struct console_input *console_input screen_buffer->height = 150; screen_buffer->max_width = 80; screen_buffer->max_height = 25; - screen_buffer->data = malloc( 4 * screen_buffer->width * screen_buffer->height ); - /* fill the buffer with white on black spaces */ - for (i = 0; i < screen_buffer->width * screen_buffer->height; i++) - { - screen_buffer->data[i] = 0x00F00020; - } - screen_buffer->cursor.X = 0; - screen_buffer->cursor.Y = 0; + screen_buffer->cursor_x = 0; + screen_buffer->cursor_y = 0; screen_buffer->attr = 0xF0; - screen_buffer->win.Left = 0; - 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->win.left = 0; + 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->next = screen_buffer_list; + if ((screen_buffer->next = screen_buffer_list)) screen_buffer->next->prev = screen_buffer; + screen_buffer->prev = NULL; screen_buffer_list = screen_buffer; + if (!(screen_buffer->data = malloc( screen_buffer->width * screen_buffer->height * + sizeof(*screen_buffer->data) ))) + { + release_object( screen_buffer ); + return NULL; + } + /* clear the first row */ + for (i = 0; i < screen_buffer->width; i++) screen_buffer->data[i] = empty_char_info; + /* and copy it to all other rows */ + for (i = 1; i < screen_buffer->height; i++) + memcpy( &screen_buffer->data[i * screen_buffer->width], screen_buffer->data, + screen_buffer->width * sizeof(char_info_t) ); + if (!console_input->active) { console_input->active = (struct screen_buffer*)grab_object( screen_buffer ); @@ -262,10 +261,10 @@ static struct object *create_console_output( struct console_input *console_input console_input_events_append( console_input->evt, &evt ); evt.event = CONSOLE_RENDERER_DISPLAY_EVENT; - evt.u.display.left = screen_buffer->win.Left; - evt.u.display.top = screen_buffer->win.Top; - evt.u.display.width = screen_buffer->win.Right - screen_buffer->win.Left + 1; - evt.u.display.height = screen_buffer->win.Bottom - screen_buffer->win.Top + 1; + evt.u.display.left = screen_buffer->win.left; + evt.u.display.top = screen_buffer->win.top; + evt.u.display.width = screen_buffer->win.right - screen_buffer->win.left + 1; + evt.u.display.height = screen_buffer->win.bottom - screen_buffer->win.top + 1; console_input_events_append( console_input->evt, &evt ); evt.event = CONSOLE_RENDERER_UPDATE_EVENT; @@ -279,12 +278,11 @@ static struct object *create_console_output( struct console_input *console_input console_input_events_append( console_input->evt, &evt ); evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; - evt.u.cursor_pos.x = screen_buffer->cursor.X; - evt.u.cursor_pos.y = screen_buffer->cursor.Y; + evt.u.cursor_pos.x = screen_buffer->cursor_x; + evt.u.cursor_pos.y = screen_buffer->cursor_y; console_input_events_append( console_input->evt, &evt ); } - - return &screen_buffer->obj; + return screen_buffer; } /* free the console for this process */ @@ -411,11 +409,12 @@ static int set_console_mode( handle_t handle, int mode ) } /* add input events to a console input queue */ -static int write_console_input( struct console_input* console, int count, INPUT_RECORD *records ) +static int write_console_input( struct console_input* console, int count, + const INPUT_RECORD *records ) { INPUT_RECORD *new_rec; - assert(count); + if (!count) return 0; if (!(new_rec = realloc( console->records, (console->recnum + count) * sizeof(INPUT_RECORD) ))) { @@ -433,7 +432,7 @@ static int write_console_input( struct console_input* console, int count, INPUT_ } /* retrieve a pointer to the console input records */ -static int read_console_input( handle_t handle, int count, INPUT_RECORD *rec, int flush ) +static int read_console_input( handle_t handle, int count, int flush ) { struct console_input *console; @@ -450,13 +449,13 @@ static int read_console_input( handle_t handle, int count, INPUT_RECORD *rec, in else { if (count > console->recnum) count = console->recnum; - memcpy( rec, console->records, count * sizeof(INPUT_RECORD) ); + set_reply_data( console->records, count * sizeof(INPUT_RECORD) ); } if (flush) { int i; for (i = count; i < console->recnum; i++) - ((INPUT_RECORD*)console->records)[i-count] = ((INPUT_RECORD*)console->records)[i]; + console->records[i-count] = console->records[i]; if ((console->recnum -= count) > 0) { INPUT_RECORD *new_rec = realloc( console->records, @@ -474,7 +473,7 @@ static int read_console_input( handle_t handle, int count, INPUT_RECORD *rec, in } /* set misc console input information */ -static int set_console_input_info( struct set_console_input_info_request *req, +static int set_console_input_info( const struct set_console_input_info_request *req, const WCHAR *title, size_t len ) { struct console_input *console; @@ -557,9 +556,61 @@ static int set_console_input_info( struct set_console_input_info_request *req, return 0; } +/* resize a screen buffer */ +static int change_screen_buffer_size( struct screen_buffer *screen_buffer, + int new_width, int new_height ) +{ + int i, old_width, old_height, copy_width, copy_height; + char_info_t *new_data; + + if (!(new_data = malloc( new_width * new_height * sizeof(*new_data) ))) + { + set_error( STATUS_NO_MEMORY ); + return 0; + } + old_width = screen_buffer->width; + old_height = screen_buffer->height; + copy_width = min( old_width, new_width ); + copy_height = min( old_height, new_height ); + + /* copy all the rows */ + for (i = 0; i < copy_height; i++) + { + memcpy( &new_data[i * new_width], &screen_buffer->data[i * old_width], + copy_width * sizeof(char_info_t) ); + } + + /* clear the end of each row */ + if (new_width > old_width) + { + /* fill first row */ + for (i = old_width; i < new_width; i++) new_data[i] = empty_char_info; + /* and blast it to the other rows */ + for (i = 1; i < copy_height; i++) + memcpy( &new_data[i * new_width + old_width], &new_data[old_width], + (new_width - old_width) * sizeof(char_info_t) ); + } + + /* clear remaining rows */ + if (new_height > old_height) + { + /* fill first row */ + for (i = 0; i < new_width; i++) new_data[old_height * new_width + i] = empty_char_info; + /* and blast it to the other rows */ + for (i = old_height+1; i < new_height; i++) + memcpy( &new_data[i * new_width], &new_data[old_height * new_width], + new_width * sizeof(char_info_t) ); + } + free( screen_buffer->data ); + screen_buffer->data = new_data; + screen_buffer->width = new_width; + screen_buffer->height = new_height; + return 1; +} + /* set misc screen buffer information */ -static int set_console_output_info( struct screen_buffer *screen_buffer, - struct set_console_output_info_request *req ) +static int set_console_output_info( struct screen_buffer *screen_buffer, + const struct set_console_output_info_request *req ) { struct console_renderer_event evt; @@ -589,10 +640,10 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, set_error( STATUS_INVALID_PARAMETER ); return 0; } - if (screen_buffer->cursor.X != req->cursor_x || screen_buffer->cursor.Y != req->cursor_y) + if (screen_buffer->cursor_x != req->cursor_x || screen_buffer->cursor_y != req->cursor_y) { - screen_buffer->cursor.X = req->cursor_x; - screen_buffer->cursor.Y = req->cursor_y; + screen_buffer->cursor_x = req->cursor_x; + screen_buffer->cursor_y = req->cursor_y; evt.event = CONSOLE_RENDERER_CURSOR_POS_EVENT; evt.u.cursor_pos.x = req->cursor_x; evt.u.cursor_pos.y = req->cursor_y; @@ -601,26 +652,9 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, } if (req->mask & SET_CONSOLE_OUTPUT_INFO_SIZE) { - int i, j; - /* FIXME: there are also some basic minimum and max size to deal with */ - unsigned* new_data = mem_alloc( 4 * req->width * req->height ); + /* FIXME: there are also some basic minimum and max size to deal with */ + if (!change_screen_buffer_size( screen_buffer, req->width, req->height )) return 0; - if (!new_data) return 0; - - /* fill the buffer with either the old buffer content or white on black spaces */ - for (j = 0; j < req->height; j++) - { - for (i = 0; i < req->width; i++) - { - new_data[j * req->width + i] = - (i < screen_buffer->width && j < screen_buffer->height) ? - screen_buffer->data[j * screen_buffer->width + i] : 0x00F00020; - } - } - free( screen_buffer->data ); - screen_buffer->data = new_data; - screen_buffer->width = req->width; - screen_buffer->height = req->height; evt.event = CONSOLE_RENDERER_SB_RESIZE_EVENT; evt.u.resize.width = req->width; evt.u.resize.height = req->height; @@ -650,13 +684,13 @@ static int set_console_output_info( struct screen_buffer *screen_buffer, set_error( STATUS_INVALID_PARAMETER ); return 0; } - if (screen_buffer->win.Left != req->win_left || screen_buffer->win.Top != req->win_top || - screen_buffer->win.Right != req->win_right || screen_buffer->win.Bottom != req->win_bottom) + if (screen_buffer->win.left != req->win_left || screen_buffer->win.top != req->win_top || + screen_buffer->win.right != req->win_right || screen_buffer->win.bottom != req->win_bottom) { - screen_buffer->win.Left = req->win_left; - screen_buffer->win.Top = req->win_top; - screen_buffer->win.Right = req->win_right; - screen_buffer->win.Bottom = req->win_bottom; + screen_buffer->win.left = req->win_left; + screen_buffer->win.top = req->win_top; + screen_buffer->win.right = req->win_right; + screen_buffer->win.bottom = req->win_bottom; evt.event = CONSOLE_RENDERER_DISPLAY_EVENT; evt.u.display.left = req->win_left; evt.u.display.top = req->win_top; @@ -725,18 +759,16 @@ static void console_input_append_hist( struct console_input* console, const WCHA } /* returns a line from the cachde */ -static int console_input_get_hist( struct console_input* console, WCHAR* buf, size_t len, int index ) +static size_t console_input_get_hist( struct console_input *console, int index ) { - int ret; + size_t ret = 0; - /* FIXME: don't use len yet */ - if (!console || index >= console->history_index) + if (index >= console->history_index) set_error( STATUS_INVALID_PARAMETER ); + else { - set_error( STATUS_INVALID_PARAMETER ); - return 0; + ret = strlenW( console->history[index] ) * sizeof(WCHAR); + set_reply_data( console->history[index], min( ret, get_reply_max_size() )); } - ret = strlenW(console->history[index]); - memcpy( buf, console->history[index], ret * sizeof(WCHAR) ); /* FIXME should use len */ return ret; } @@ -749,20 +781,20 @@ static void console_input_dump( struct object *obj, int verbose ) console->active, console->evt ); } -static int console_get_file_info( struct object *obj, struct get_file_info_request *req ) +static int console_get_file_info( struct object *obj, struct get_file_info_reply *reply ) { - if (req) + if (reply) { - req->type = FILE_TYPE_CHAR; - req->attr = 0; - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_CHAR; + reply->attr = 0; + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } return FD_TYPE_CONSOLE; } @@ -803,113 +835,193 @@ static void screen_buffer_dump( struct object *obj, int verbose ) static void screen_buffer_destroy( struct object *obj ) { - struct screen_buffer* screen_buffer = (struct screen_buffer *)obj; - struct screen_buffer** psb; + struct screen_buffer *screen_buffer = (struct screen_buffer *)obj; assert( obj->ops == &screen_buffer_ops ); - for (psb = &screen_buffer_list; *psb; *psb = (*psb)->next) - { - if (*psb == screen_buffer) - { - *psb = screen_buffer->next; - break; - } - } + if (screen_buffer->next) screen_buffer->next->prev = screen_buffer->prev; + if (screen_buffer->prev) screen_buffer->prev->next = screen_buffer->next; + else screen_buffer_list = screen_buffer->next; + if (screen_buffer->input && screen_buffer->input->active == screen_buffer) { struct screen_buffer* sb; for (sb = screen_buffer_list; sb && sb->input != screen_buffer->input; sb = sb->next); screen_buffer->input->active = sb; } + if (screen_buffer->data) free( screen_buffer->data ); } /* write data into a screen buffer */ -static int write_console_output( struct screen_buffer *screen_buffer, size_t size, - const unsigned char* data, int mode, short int x, short int y ) +static int write_console_output( struct screen_buffer *screen_buffer, size_t size, + const void* data, enum char_info_mode mode, + int x, int y, int wrap ) { - int uniform = mode & WRITE_CONSOLE_MODE_UNIFORM; - unsigned *ptr; - unsigned i, inc; - int len; + int i; + char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x; - mode &= ~WRITE_CONSOLE_MODE_UNIFORM; + if (y >= screen_buffer->height) return 0; - if (mode < 0 || mode > 3) + if (wrap) + end = screen_buffer->data + screen_buffer->height * screen_buffer->width; + else + end = screen_buffer->data + (y+1) * screen_buffer->width; + + switch(mode) { - set_error(STATUS_INVALID_PARAMETER); - return 0; + case CHAR_INFO_MODE_TEXT: + { + const WCHAR *ptr = data; + for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->ch = ptr[i]; + } + break; + case CHAR_INFO_MODE_ATTR: + { + const unsigned short *ptr = data; + for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) dest->attr = ptr[i]; + } + break; + case CHAR_INFO_MODE_TEXTATTR: + { + const char_info_t *ptr = data; + for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) *dest = ptr[i]; + } + break; + case CHAR_INFO_MODE_TEXTSTDATTR: + { + const WCHAR *ptr = data; + for (i = 0; i < size/sizeof(*ptr) && dest < end; dest++, i++) + { + dest->ch = ptr[i]; + dest->attr = screen_buffer->attr; + } + } + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return 0; } - /* set destination pointer and increment */ - ptr = screen_buffer->data + (y * screen_buffer->width + x); - if (mode == WRITE_CONSOLE_MODE_ATTR) ptr = (unsigned*)((char*)ptr + 2); - inc = (mode == WRITE_CONSOLE_MODE_TEXTATTR) ? 4 : 2; - len = size / inc; - - /* crop if needed */ - if (x + len > screen_buffer->width) len = screen_buffer->width - x; - - for (i = 0; i < len; i++) + if (i && screen_buffer == screen_buffer->input->active) { - if (mode == WRITE_CONSOLE_MODE_TEXTSTDATTR) - { - memcpy( (char*)ptr + 2, &screen_buffer->attr, 2 ); - } - memcpy( ptr++, data, inc ); - if (!uniform) data += inc; + struct console_renderer_event evt; + evt.event = CONSOLE_RENDERER_UPDATE_EVENT; + evt.u.update.top = y; + evt.u.update.bottom = (y * screen_buffer->width + x + i - 1) / screen_buffer->width; + console_input_events_append( screen_buffer->input->evt, &evt ); + } + return i; +} + +/* fill a screen buffer with uniform data */ +static int fill_console_output( struct screen_buffer *screen_buffer, char_info_t data, + enum char_info_mode mode, int x, int y, int count, int wrap ) +{ + int i; + char_info_t *end, *dest = screen_buffer->data + y * screen_buffer->width + x; + + if (y >= screen_buffer->height) return 0; + + if (wrap) + end = screen_buffer->data + screen_buffer->height * screen_buffer->width; + else + end = screen_buffer->data + (y+1) * screen_buffer->width; + + if (count > end - dest) count = end - dest; + + switch(mode) + { + case CHAR_INFO_MODE_TEXT: + for (i = 0; i < count; i++) dest[i].ch = data.ch; + break; + case CHAR_INFO_MODE_ATTR: + for (i = 0; i < count; i++) dest[i].attr = data.attr; + break; + case CHAR_INFO_MODE_TEXTATTR: + for (i = 0; i < count; i++) dest[i] = data; + break; + case CHAR_INFO_MODE_TEXTSTDATTR: + for (i = 0; i < count; i++) + { + dest[i].ch = data.ch; + dest[i].attr = screen_buffer->attr; + } + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return 0; } - if (len && screen_buffer == screen_buffer->input->active) + if (count && screen_buffer == screen_buffer->input->active) { - int y2; - struct console_renderer_event evt; - - y2 = (y * screen_buffer->width + x + len - 1) / screen_buffer->width; - - evt.event = CONSOLE_RENDERER_UPDATE_EVENT; - evt.u.update.top = y; - evt.u.update.bottom = y2; - console_input_events_append( screen_buffer->input->evt, &evt ); + struct console_renderer_event evt; + evt.event = CONSOLE_RENDERER_UPDATE_EVENT; + evt.u.update.top = y; + evt.u.update.bottom = (y * screen_buffer->width + x + count - 1) / screen_buffer->width; + console_input_events_append( screen_buffer->input->evt, &evt ); } - return len; + return i; } /* read data from a screen buffer */ -static int read_console_output( struct screen_buffer *screen_buffer, size_t size, void* data, - short int x, short int y, short int w, short int h, - short int* eff_w, short int* eff_h ) +static void read_console_output( struct screen_buffer *screen_buffer, int x, int y, + enum char_info_mode mode, int wrap ) { - int j; + int i; + char_info_t *end, *src = screen_buffer->data + y * screen_buffer->width + x; - if (size < w * h * 4 || x >= screen_buffer->width || y >= screen_buffer->height) - { - set_error(STATUS_INVALID_PARAMETER); - return 0; - } + if (y >= screen_buffer->height) return; - *eff_w = w; - *eff_h = h; - if (x + w > screen_buffer->width) *eff_w = screen_buffer->width - x; - if (y + h > screen_buffer->height) *eff_h = screen_buffer->height - y; + if (wrap) + end = screen_buffer->data + screen_buffer->height * screen_buffer->width; + else + end = screen_buffer->data + (y+1) * screen_buffer->width; - for (j = 0; j < *eff_h; j++) + switch(mode) { - memcpy( (char*)data + 4 * j * w, &screen_buffer->data[(y + j) * screen_buffer->width + x], - *eff_w * 4 ); + case CHAR_INFO_MODE_TEXT: + { + WCHAR *data; + int count = min( end - src, get_reply_max_size() / sizeof(*data) ); + if ((data = set_reply_data_size( count * sizeof(*data) ))) + { + for (i = 0; i < count; i++) data[i] = src[i].ch; + } + } + break; + case CHAR_INFO_MODE_ATTR: + { + unsigned short *data; + int count = min( end - src, get_reply_max_size() / sizeof(*data) ); + if ((data = set_reply_data_size( count * sizeof(*data) ))) + { + for (i = 0; i < count; i++) data[i] = src[i].attr; + } + } + break; + case CHAR_INFO_MODE_TEXTATTR: + { + char_info_t *data; + int count = min( end - src, get_reply_max_size() / sizeof(*data) ); + if ((data = set_reply_data_size( count * sizeof(*data) ))) + { + for (i = 0; i < count; i++) data[i] = src[i]; + } + } + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + break; } - - return *eff_w * *eff_h; } /* scroll parts of a screen buffer */ -static void scroll_console_output( handle_t handle, short int xsrc, short int ysrc, - short int xdst, short int ydst, short int w, short int h ) +static void scroll_console_output( handle_t handle, int xsrc, int ysrc, int xdst, int ydst, + int w, int h ) { struct screen_buffer *screen_buffer; int j; - unsigned* psrc; - unsigned* pdst; + char_info_t *psrc, *pdst; struct console_renderer_event evt; if (!(screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, handle, @@ -934,7 +1046,7 @@ static void scroll_console_output( handle_t handle, short int xsrc, short int ys for (j = h; j > 0; j--) { - memcpy(pdst, psrc, w * 4); + memcpy(pdst, psrc, w * sizeof(*pdst) ); pdst -= screen_buffer->width; psrc -= screen_buffer->width; } @@ -949,7 +1061,7 @@ static void scroll_console_output( handle_t handle, short int xsrc, short int ys /* we use memmove here because when psrc and pdst are the same, * copies are done on the same row, so the dst and src blocks * can overlap */ - memmove( pdst, psrc, w * 4 ); + memmove( pdst, psrc, w * sizeof(*pdst) ); pdst += screen_buffer->width; psrc += screen_buffer->width; } @@ -976,35 +1088,35 @@ DECL_HANDLER(alloc_console) process = (req->pid) ? get_process_from_id( req->pid ) : (struct process *)grab_object( renderer->parent ); - req->handle_in = 0; - req->event = 0; + reply->handle_in = 0; + reply->event = 0; if (!process) return; if (process != renderer && process->console) - { - set_error( STATUS_ACCESS_DENIED ); - goto the_end; + { + set_error( STATUS_ACCESS_DENIED ); + goto the_end; } if ((console = (struct console_input*)create_console_input( renderer ))) { - if ((in = alloc_handle( renderer, console, req->access, req->inherit ))) - { - if ((evt = alloc_handle( renderer, console->evt, - SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, FALSE ))) - { - if (process != renderer) - { - process->console = (struct console_input*)grab_object( console ); - console->num_proc++; - } - req->handle_in = in; - req->event = evt; - release_object( console ); - goto the_end; - } - close_handle( renderer, in, NULL ); - } - free_console( process ); + if ((in = alloc_handle( renderer, console, req->access, req->inherit ))) + { + if ((evt = alloc_handle( renderer, console->evt, + SYNCHRONIZE|GENERIC_READ|GENERIC_WRITE, FALSE ))) + { + if (process != renderer) + { + process->console = (struct console_input*)grab_object( console ); + console->num_proc++; + } + reply->handle_in = in; + reply->event = evt; + release_object( console ); + goto the_end; + } + close_handle( renderer, in, NULL ); + } + free_console( process ); } the_end: release_object( process ); @@ -1019,14 +1131,12 @@ DECL_HANDLER(free_console) /* let the renderer peek the events it's waiting on */ DECL_HANDLER(get_console_renderer_events) { - struct console_input_events* evt; - size_t len = 0; + struct console_input_events *evt; evt = (struct console_input_events *)get_handle_obj( current->process, req->handle, - GENERIC_WRITE, &console_input_events_ops ); + GENERIC_WRITE, &console_input_events_ops ); if (!evt) return; - len = console_input_events_get( evt, get_req_data(req), get_req_data_size(req) ); - set_req_data_size( req, len ); + console_input_events_get( evt ); release_object( evt ); } @@ -1035,70 +1145,66 @@ DECL_HANDLER(open_console) { struct object *obj = NULL; - req->handle = 0; + reply->handle = 0; switch (req->from) { - case 0: - if (current->process->console && current->process->console->renderer) - obj = grab_object( (struct object*)current->process->console ); - break; - case 1: - if (current->process->console && current->process->console->renderer && - current->process->console->active) - obj = grab_object( (struct object*)current->process->console->active ); - break; + case 0: + if (current->process->console && current->process->console->renderer) + obj = grab_object( (struct object*)current->process->console ); + break; + case 1: + if (current->process->console && current->process->console->renderer && + current->process->console->active) + obj = grab_object( (struct object*)current->process->console->active ); + break; default: - if ((obj = get_handle_obj( current->process, (handle_t)req->from, - GENERIC_READ|GENERIC_WRITE, &console_input_ops ))) - { - struct console_input* console = (struct console_input*)obj; - obj = (console->active) ? grab_object( console->active ) : NULL; - release_object( console ); - } - break; + if ((obj = get_handle_obj( current->process, (handle_t)req->from, + GENERIC_READ|GENERIC_WRITE, &console_input_ops ))) + { + struct console_input* console = (struct console_input*)obj; + obj = (console->active) ? grab_object( console->active ) : NULL; + release_object( console ); + } + break; } /* FIXME: req->share is not used (as in screen buffer creation) */ if (obj) { - req->handle = alloc_handle( current->process, obj, req->access, req->inherit ); - release_object( obj ); + reply->handle = alloc_handle( current->process, obj, req->access, req->inherit ); + release_object( obj ); } - if (!req->handle && !get_error()) set_error( STATUS_ACCESS_DENIED ); + else if (!get_error()) set_error( STATUS_ACCESS_DENIED ); } /* set info about a console input */ DECL_HANDLER(set_console_input_info) { - set_console_input_info( req, get_req_data(req), get_req_data_size(req) ); + set_console_input_info( req, get_req_data(), get_req_data_size() ); } /* get info about a console (output only) */ DECL_HANDLER(get_console_input_info) { - struct console_input *console = 0; + struct console_input *console; - set_req_data_size( req, 0 ); if (!(console = console_input_get( req->handle, GENERIC_READ ))) return; - if (console->title) { - size_t len = strlenW( console->title ) * sizeof(WCHAR); - if (len > get_req_data_size(req)) len = get_req_data_size(req); - memcpy( get_req_data(req), console->title, len ); - set_req_data_size( req, len ); + size_t len = strlenW( console->title ) * sizeof(WCHAR); + if (len > get_reply_max_size()) len = get_reply_max_size(); + set_reply_data( console->title, len ); } - req->history_mode = console->history_mode; - req->history_size = console->history_size; - req->history_index = console->history_index; - + reply->history_mode = console->history_mode; + reply->history_size = console->history_size; + reply->history_index = console->history_index; release_object( console ); } /* get a console mode (input or output) */ DECL_HANDLER(get_console_mode) { - req->mode = get_console_mode( req->handle ); + reply->mode = get_console_mode( req->handle ); } /* set a console mode (input or output) */ @@ -1112,47 +1218,39 @@ DECL_HANDLER(write_console_input) { struct console_input *console; - req->written = 0; + reply->written = 0; if (!(console = (struct console_input *)get_handle_obj( current->process, req->handle, GENERIC_WRITE, &console_input_ops ))) return; - - req->written = write_console_input( console, get_req_data_size(req) / sizeof(INPUT_RECORD), - get_req_data(req) ); + reply->written = write_console_input( console, get_req_data_size() / sizeof(INPUT_RECORD), + get_req_data() ); release_object( console ); } /* fetch input records from a console input queue */ DECL_HANDLER(read_console_input) { - size_t size = get_req_data_size(req) / sizeof(INPUT_RECORD); - int res = read_console_input( req->handle, size, get_req_data(req), req->flush ); - /* if size was 0 we didn't fetch anything */ - if (size) set_req_data_size( req, res * sizeof(INPUT_RECORD) ); - req->read = res; + int count = get_reply_max_size() / sizeof(INPUT_RECORD); + reply->read = read_console_input( req->handle, count, req->flush ); } /* appends a string to console's history */ DECL_HANDLER(append_console_input_history) { - struct console_input* console; + struct console_input *console; if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return; - console_input_append_hist( console, get_req_data(req), - get_req_data_size(req) / sizeof(WCHAR) ); + console_input_append_hist( console, get_req_data(), get_req_data_size() / sizeof(WCHAR) ); release_object( console ); } /* appends a string to console's history */ DECL_HANDLER(get_console_input_history) { - struct console_input* console; - int len; + struct console_input *console; if (!(console = console_input_get( req->handle, GENERIC_WRITE ))) return; - - len = console_input_get_hist( console, get_req_data(req), 0 /* FIXME */, req->index ); - set_req_data_size( req, len * sizeof(WCHAR)); + reply->total = console_input_get_hist( console, req->index ); release_object( console ); } @@ -1164,14 +1262,14 @@ DECL_HANDLER(create_console_output) if (!(console = console_input_get( req->handle_in, GENERIC_WRITE))) return; - screen_buffer = (struct screen_buffer*)create_console_output( console ); + screen_buffer = create_console_output( console ); if (screen_buffer) { - /* FIXME: should store sharing and test it when opening the CONOUT$ device - * see file.c on how this could be done - */ - req->handle_out = alloc_handle( current->process, screen_buffer, req->access, req->inherit ); - release_object( screen_buffer ); + /* FIXME: should store sharing and test it when opening the CONOUT$ device + * see file.c on how this could be done */ + reply->handle_out = alloc_handle( current->process, screen_buffer, + req->access, req->inherit ); + release_object( screen_buffer ); } release_object( console ); } @@ -1179,79 +1277,84 @@ DECL_HANDLER(create_console_output) /* set info about a console screen buffer */ DECL_HANDLER(set_console_output_info) { - struct screen_buffer *screen_buffer; + struct screen_buffer *screen_buffer; - if (!(screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, - GENERIC_WRITE, &screen_buffer_ops ))) - return; - - set_console_output_info( screen_buffer, req ); - release_object( screen_buffer ); + if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, + GENERIC_WRITE, &screen_buffer_ops))) + { + set_console_output_info( screen_buffer, req ); + release_object( screen_buffer ); + } } /* get info about a console screen buffer */ DECL_HANDLER(get_console_output_info) { struct screen_buffer *screen_buffer; - size_t len = 0; if ((screen_buffer = (struct screen_buffer *)get_handle_obj( current->process, req->handle, - GENERIC_READ, &screen_buffer_ops ))) + GENERIC_READ, &screen_buffer_ops))) { - req->cursor_size = screen_buffer->cursor_size; - req->cursor_visible = screen_buffer->cursor_visible; - req->cursor_x = screen_buffer->cursor.X; - req->cursor_y = screen_buffer->cursor.Y; - req->width = screen_buffer->width; - req->height = screen_buffer->height; - req->attr = screen_buffer->attr; - req->win_left = screen_buffer->win.Left; - req->win_top = screen_buffer->win.Top; - req->win_right = screen_buffer->win.Right; - req->win_bottom = screen_buffer->win.Bottom; - req->max_width = screen_buffer->max_width; - req->max_height = screen_buffer->max_height; - + reply->cursor_size = screen_buffer->cursor_size; + reply->cursor_visible = screen_buffer->cursor_visible; + reply->cursor_x = screen_buffer->cursor_x; + reply->cursor_y = screen_buffer->cursor_y; + reply->width = screen_buffer->width; + reply->height = screen_buffer->height; + reply->attr = screen_buffer->attr; + reply->win_left = screen_buffer->win.left; + reply->win_top = screen_buffer->win.top; + reply->win_right = screen_buffer->win.right; + reply->win_bottom = screen_buffer->win.bottom; + reply->max_width = screen_buffer->max_width; + reply->max_height = screen_buffer->max_height; release_object( screen_buffer ); } - set_req_data_size( req, len ); } /* read data (chars & attrs) from a screen buffer */ DECL_HANDLER(read_console_output) { - struct screen_buffer *screen_buffer; - size_t size = get_req_data_size(req); - int res; + struct screen_buffer *screen_buffer; - if (!(screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, - GENERIC_READ, &screen_buffer_ops ))) - return; - - res = read_console_output( screen_buffer, size, get_req_data(req), - req->x, req->y, req->w, req->h, &req->eff_w, &req->eff_h); - /* if size was 0 we didn't fetch anything */ - if (size) set_req_data_size( req, res * 4 ); - release_object( screen_buffer ); + if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, + GENERIC_READ, &screen_buffer_ops ))) + { + read_console_output( screen_buffer, req->x, req->y, req->mode, req->wrap ); + reply->width = screen_buffer->width; + reply->height = screen_buffer->height; + release_object( screen_buffer ); + } } /* write data (char and/or attrs) to a screen buffer */ DECL_HANDLER(write_console_output) { - struct screen_buffer *screen_buffer; - size_t size = get_req_data_size(req); - int res; + struct screen_buffer *screen_buffer; - if (!(screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, - GENERIC_WRITE, &screen_buffer_ops ))) - return; + if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, + GENERIC_WRITE, &screen_buffer_ops))) + { + reply->written = write_console_output( screen_buffer, get_req_data_size(), get_req_data(), + req->mode, req->x, req->y, req->wrap ); + reply->width = screen_buffer->width; + reply->height = screen_buffer->height; + release_object( screen_buffer ); + } +} - res = write_console_output( screen_buffer, size, get_req_data(req), req->mode, req->x, req->y ); +/* fill a screen buffer with constant data (chars and/or attributes) */ +DECL_HANDLER(fill_console_output) +{ + struct screen_buffer *screen_buffer; - /* if size was 0 we didn't fetch anything */ - if (size) set_req_data_size( req, res ); - req->written = res; - release_object( screen_buffer ); + if ((screen_buffer = (struct screen_buffer*)get_handle_obj( current->process, req->handle, + GENERIC_WRITE, &screen_buffer_ops))) + { + reply->written = fill_console_output( screen_buffer, req->data, req->mode, + req->x, req->y, req->count, req->wrap ); + release_object( screen_buffer ); + } } /* move a rect of data in a screen buffer */ diff --git a/server/console.h b/server/console.h index 88999a15bbb..bde68ec3c50 100644 --- a/server/console.h +++ b/server/console.h @@ -7,6 +7,8 @@ #ifndef __WINE_SERVER_CONSOLE_H #define __WINE_SERVER_CONSOLE_H +#include "wincon.h" + struct screen_buffer; struct console_input_events; @@ -18,7 +20,7 @@ struct console_input int mode; /* input mode */ struct screen_buffer *active; /* active screen buffer */ int recnum; /* number of input records */ - void *records; /* input records */ + INPUT_RECORD *records; /* input records */ struct console_input_events *evt; /* synchronization event with renderer */ WCHAR *title; /* console title */ WCHAR **history; /* lines history */ diff --git a/server/context_i386.c b/server/context_i386.c index 874d1dd4151..d72c89d8729 100644 --- a/server/context_i386.c +++ b/server/context_i386.c @@ -144,7 +144,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE /* set a thread context */ -static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) +static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context ) { int pid = thread->unix_pid; if (flags & CONTEXT_FULL) @@ -195,7 +195,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE /* we can use context->FloatSave directly as it is using the */ /* correct structure (the same as fsave/frstor) */ if (ptrace( PTRACE_SETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error; - context->FloatSave.Cr0NpxState = 0; /* FIXME */ } return; error: @@ -256,7 +255,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE /* set a thread context */ -static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) +static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context ) { int pid = thread->unix_pid; if (flags & CONTEXT_FULL) @@ -303,7 +302,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE /* we can use context->FloatSave directly as it is using the */ /* correct structure (the same as fsave/frstor) */ if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error; - context->FloatSave.Cr0NpxState = 0; /* FIXME */ } return; error: @@ -365,7 +363,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE /* set a thread context */ -static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) +static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context ) { int pid = thread->unix_pid; if (flags & CONTEXT_FULL) @@ -412,7 +410,6 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE /* we can use context->FloatSave directly as it is using the */ /* correct structure (the same as fsave/frstor) */ if (ptrace( PTRACE_SETFPREGS, pid, 0, (int) &context->FloatSave ) == -1) goto error; - context->FloatSave.Cr0NpxState = 0; /* FIXME */ } return; error: @@ -425,7 +422,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE /* copy a context structure according to the flags */ -static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) +static void copy_context( CONTEXT *to, const CONTEXT *from, int flags ) { if (flags & CONTEXT_CONTROL) { @@ -486,27 +483,34 @@ int get_thread_single_step( struct thread *thread ) DECL_HANDLER(get_thread_context) { struct thread *thread; + void *data; int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */ - if (get_req_data_size(req) < sizeof(CONTEXT)) + if (get_reply_max_size() < sizeof(CONTEXT)) { set_error( STATUS_INVALID_PARAMETER ); return; } - if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) + if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return; + + if ((data = set_reply_data_size( sizeof(CONTEXT) ))) { + /* copy incoming context into reply */ + memset( data, 0, sizeof(CONTEXT) ); + memcpy( data, get_req_data(), min( get_req_data_size(), sizeof(CONTEXT) )); + if (thread->context) /* thread is inside an exception event */ { - copy_context( get_req_data(req), thread->context, flags ); + copy_context( data, thread->context, flags ); flags &= CONTEXT_DEBUG_REGISTERS; } if (flags && suspend_for_ptrace( thread )) { - get_thread_context( thread, flags, get_req_data(req) ); + get_thread_context( thread, flags, data ); resume_thread( thread ); } - release_object( thread ); } + release_object( thread ); } @@ -516,7 +520,7 @@ DECL_HANDLER(set_thread_context) struct thread *thread; int flags = req->flags & ~CONTEXT_i386; /* get rid of CPU id */ - if (get_req_data_size(req) < sizeof(CONTEXT)) + if (get_req_data_size() < sizeof(CONTEXT)) { set_error( STATUS_INVALID_PARAMETER ); return; @@ -525,12 +529,12 @@ DECL_HANDLER(set_thread_context) { if (thread->context) /* thread is inside an exception event */ { - copy_context( thread->context, get_req_data(req), flags ); + copy_context( thread->context, get_req_data(), flags ); flags &= CONTEXT_DEBUG_REGISTERS; } if (flags && suspend_for_ptrace( thread )) { - set_thread_context( thread, flags, get_req_data(req) ); + set_thread_context( thread, flags, get_req_data() ); resume_thread( thread ); } release_object( thread ); diff --git a/server/context_sparc.c b/server/context_sparc.c index d8d6b79787c..d8de535f590 100644 --- a/server/context_sparc.c +++ b/server/context_sparc.c @@ -78,7 +78,7 @@ static void get_thread_context( struct thread *thread, unsigned int flags, CONTE /* set a thread context */ -static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context ) +static void set_thread_context( struct thread *thread, unsigned int flags, const CONTEXT *context ) { /* FIXME */ } @@ -89,7 +89,7 @@ static void set_thread_context( struct thread *thread, unsigned int flags, CONTE /* copy a context structure according to the flags */ -static void copy_context( CONTEXT *to, CONTEXT *from, int flags ) +static void copy_context( CONTEXT *to, const CONTEXT *from, int flags ) { if (flags & CONTEXT_CONTROL) { @@ -164,27 +164,30 @@ int get_thread_single_step( struct thread *thread ) DECL_HANDLER(get_thread_context) { struct thread *thread; + void *data; int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */ - if (get_req_data_size(req) < sizeof(CONTEXT)) + if (get_reply_max_size() < sizeof(CONTEXT)) { set_error( STATUS_INVALID_PARAMETER ); return; } - if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) + if (!(thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT ))) return; + + if ((data = set_reply_data_size( sizeof(CONTEXT) ))) { if (thread->context) /* thread is inside an exception event */ { - copy_context( get_req_data(req), thread->context, flags ); + copy_context( data, thread->context, flags ); flags = 0; } if (flags && suspend_for_ptrace( thread )) { - get_thread_context( thread, flags, get_req_data(req) ); + get_thread_context( thread, flags, data ); resume_thread( thread ); } - release_object( thread ); } + release_object( thread ); } @@ -194,7 +197,7 @@ DECL_HANDLER(set_thread_context) struct thread *thread; int flags = req->flags & ~CONTEXT_SPARC; /* get rid of CPU id */ - if (get_req_data_size(req) < sizeof(CONTEXT)) + if (get_req_data_size() < sizeof(CONTEXT)) { set_error( STATUS_INVALID_PARAMETER ); return; @@ -203,12 +206,12 @@ DECL_HANDLER(set_thread_context) { if (thread->context) /* thread is inside an exception event */ { - copy_context( thread->context, get_req_data(req), flags ); + copy_context( thread->context, get_req_data(), flags ); flags = 0; } if (flags && suspend_for_ptrace( thread )) { - set_thread_context( thread, flags, get_req_data(req) ); + set_thread_context( thread, flags, get_req_data() ); resume_thread( thread ); } release_object( thread ); diff --git a/server/debugger.c b/server/debugger.c index 09b4240cab4..d4ea49d0c5a 100644 --- a/server/debugger.c +++ b/server/debugger.c @@ -353,7 +353,7 @@ static int continue_debug_event( struct process *process, struct thread *thread, /* alloc a debug event for a debugger */ static struct debug_event *alloc_debug_event( struct thread *thread, int code, - void *arg, CONTEXT *context ) + void *arg, const CONTEXT *context ) { struct thread *debugger = thread->process->debugger; struct debug_event *event; @@ -498,25 +498,23 @@ DECL_HANDLER(wait_debug_event) set_error( STATUS_INVALID_HANDLE ); return; } - req->wait = 0; + reply->wait = 0; if ((event = find_event_to_send( debug_ctx ))) { - size_t size = get_req_data_size(req); + size_t size = get_reply_max_size(); event->state = EVENT_SENT; event->sender->debug_event = event; - req->pid = event->sender->process; - req->tid = event->sender; + reply->pid = event->sender->process; + reply->tid = event->sender; if (size > sizeof(debug_event_t)) size = sizeof(debug_event_t); - memcpy( get_req_data(req), &event->data, size ); - set_req_data_size( req, size ); + set_reply_data( &event->data, size ); } else /* no event ready */ { - req->pid = 0; - req->tid = 0; - set_req_data_size( req, 0 ); + reply->pid = 0; + reply->tid = 0; if (req->get_handle) - req->wait = alloc_handle( current->process, debug_ctx, SYNCHRONIZE, FALSE ); + reply->wait = alloc_handle( current->process, debug_ctx, SYNCHRONIZE, FALSE ); } } @@ -562,15 +560,15 @@ DECL_HANDLER(debug_process) /* queue an exception event */ DECL_HANDLER(queue_exception_event) { - req->handle = 0; + reply->handle = 0; if (current->process->debugger) { struct debug_event_exception data; struct debug_event *event; - CONTEXT *context = get_req_data( req ); + const CONTEXT *context = get_req_data(); EXCEPTION_RECORD *rec = (EXCEPTION_RECORD *)(context + 1); - if (get_req_data_size( req ) < sizeof(*rec) + sizeof(*context)) + if (get_req_data_size() < sizeof(*rec) + sizeof(*context)) { set_error( STATUS_INVALID_PARAMETER ); return; @@ -579,7 +577,7 @@ DECL_HANDLER(queue_exception_event) data.first = req->first; if ((event = alloc_debug_event( current, EXCEPTION_DEBUG_EVENT, &data, context ))) { - if ((req->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE ))) + if ((reply->handle = alloc_handle( current->process, event, SYNCHRONIZE, FALSE ))) { link_event( event ); suspend_process( current->process ); @@ -593,26 +591,24 @@ DECL_HANDLER(queue_exception_event) DECL_HANDLER(get_exception_status) { struct debug_event *event; - size_t size = 0; - req->status = 0; + reply->status = 0; if ((event = (struct debug_event *)get_handle_obj( current->process, req->handle, 0, &debug_event_ops ))) { if (event->state == EVENT_CONTINUED) { - req->status = event->status; + reply->status = event->status; if (current->context == &event->context) { - size = min( sizeof(CONTEXT), get_req_data_size(req) ); - memcpy( get_req_data(req), &event->context, size ); + size_t size = min( sizeof(CONTEXT), get_reply_max_size() ); + set_reply_data( &event->context, size ); current->context = NULL; } } else set_error( STATUS_PENDING ); release_object( event ); } - set_req_data_size( req, size ); } /* send an output string to the debugger */ diff --git a/server/device.c b/server/device.c index 80c6af59d22..6c37c19c303 100644 --- a/server/device.c +++ b/server/device.c @@ -29,7 +29,7 @@ struct device }; static void device_dump( struct object *obj, int verbose ); -static int device_get_info( struct object *obj, struct get_file_info_request *req ); +static int device_get_info( struct object *obj, struct get_file_info_reply *reply ); static const struct object_ops device_ops = { @@ -64,23 +64,23 @@ static void device_dump( struct object *obj, int verbose ) fprintf( stderr, "Device id=%08x\n", dev->id ); } -static int device_get_info( struct object *obj, struct get_file_info_request *req ) +static int device_get_info( struct object *obj, struct get_file_info_reply *reply ) { struct device *dev = (struct device *)obj; assert( obj->ops == &device_ops ); - if (req) + if (reply) { - req->type = FILE_TYPE_UNKNOWN; - req->attr = dev->id; /* hack! */ - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_UNKNOWN; + reply->attr = dev->id; /* hack! */ + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } return FD_TYPE_DEFAULT; } @@ -90,10 +90,10 @@ DECL_HANDLER(create_device) { struct device *dev; - req->handle = 0; + reply->handle = 0; if ((dev = create_device( req->id ))) { - req->handle = alloc_handle( current->process, dev, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, dev, req->access, req->inherit ); release_object( dev ); } } diff --git a/server/event.c b/server/event.c index b7652fb8616..7318aef1791 100644 --- a/server/event.c +++ b/server/event.c @@ -115,11 +115,11 @@ DECL_HANDLER(create_event) { struct event *event; - req->handle = 0; - if ((event = create_event( get_req_data(req), get_req_data_size(req), + reply->handle = 0; + if ((event = create_event( get_req_data(), get_req_data_size(), req->manual_reset, req->initial_state ))) { - req->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, event, EVENT_ALL_ACCESS, req->inherit ); release_object( event ); } } @@ -127,8 +127,8 @@ DECL_HANDLER(create_event) /* open a handle to an event */ DECL_HANDLER(open_event) { - req->handle = open_object( get_req_data(req), get_req_data_size(req), - &event_ops, req->access, req->inherit ); + reply->handle = open_object( get_req_data(), get_req_data_size(), + &event_ops, req->access, req->inherit ); } /* do an event operation */ diff --git a/server/file.c b/server/file.c index 6dde94cdd53..ae9033c1dcf 100644 --- a/server/file.c +++ b/server/file.c @@ -49,7 +49,7 @@ static void file_dump( struct object *obj, int verbose ); static int file_get_poll_events( struct object *obj ); static int file_get_fd( struct object *obj ); static int file_flush( struct object *obj ); -static int file_get_info( struct object *obj, struct get_file_info_request *req ); +static int file_get_info( struct object *obj, struct get_file_info_reply *reply ); static void file_destroy( struct object *obj ); static const struct object_ops file_ops = @@ -271,13 +271,13 @@ static int file_flush( struct object *obj ) return ret; } -static int file_get_info( struct object *obj, struct get_file_info_request *req ) +static int file_get_info( struct object *obj, struct get_file_info_reply *reply ) { struct stat st; struct file *file = (struct file *)obj; assert( obj->ops == &file_ops ); - if (req) + if (reply) { if (fstat( file->obj.fd, &st ) == -1) { @@ -285,27 +285,27 @@ static int file_get_info( struct object *obj, struct get_file_info_request *req return FD_TYPE_INVALID; } if (S_ISCHR(st.st_mode) || S_ISFIFO(st.st_mode) || - S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) req->type = FILE_TYPE_CHAR; - else req->type = FILE_TYPE_DISK; - if (S_ISDIR(st.st_mode)) req->attr = FILE_ATTRIBUTE_DIRECTORY; - else req->attr = FILE_ATTRIBUTE_ARCHIVE; - if (!(st.st_mode & S_IWUSR)) req->attr |= FILE_ATTRIBUTE_READONLY; - req->access_time = st.st_atime; - req->write_time = st.st_mtime; + S_ISSOCK(st.st_mode) || isatty(file->obj.fd)) reply->type = FILE_TYPE_CHAR; + else reply->type = FILE_TYPE_DISK; + if (S_ISDIR(st.st_mode)) reply->attr = FILE_ATTRIBUTE_DIRECTORY; + else reply->attr = FILE_ATTRIBUTE_ARCHIVE; + if (!(st.st_mode & S_IWUSR)) reply->attr |= FILE_ATTRIBUTE_READONLY; + reply->access_time = st.st_atime; + reply->write_time = st.st_mtime; if (S_ISDIR(st.st_mode)) { - req->size_high = 0; - req->size_low = 0; + reply->size_high = 0; + reply->size_low = 0; } else { - req->size_high = st.st_size >> 32; - req->size_low = st.st_size & 0xffffffff; + reply->size_high = st.st_size >> 32; + reply->size_low = st.st_size & 0xffffffff; } - req->links = st.st_nlink; - req->index_high = st.st_dev; - req->index_low = st.st_ino; - req->serial = 0; /* FIXME */ + reply->links = st.st_nlink; + reply->index_high = st.st_dev; + reply->index_low = st.st_ino; + reply->serial = 0; /* FIXME */ } return FD_TYPE_DEFAULT; } @@ -470,11 +470,11 @@ DECL_HANDLER(create_file) { struct file *file; - req->handle = 0; - if ((file = create_file( get_req_data(req), get_req_data_size(req), req->access, + reply->handle = 0; + if ((file = create_file( get_req_data(), get_req_data_size(), req->access, req->sharing, req->create, req->attrs, req->drive_type ))) { - req->handle = alloc_handle( current->process, file, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, file, req->access, req->inherit ); release_object( file ); } } @@ -485,7 +485,7 @@ DECL_HANDLER(alloc_file_handle) struct file *file; int fd; - req->handle = 0; + reply->handle = 0; if ((fd = thread_get_inflight_fd( current, req->fd )) == -1) { set_error( STATUS_INVALID_HANDLE ); @@ -494,7 +494,7 @@ DECL_HANDLER(alloc_file_handle) if ((file = create_file_for_fd( fd, req->access, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, DRIVE_UNKNOWN ))) { - req->handle = alloc_handle( current->process, file, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, file, req->access, req->inherit ); release_object( file ); } } @@ -504,18 +504,18 @@ DECL_HANDLER(get_handle_fd) { struct object *obj; - req->fd = -1; - req->type = FD_TYPE_INVALID; + reply->fd = -1; + reply->type = FD_TYPE_INVALID; if ((obj = get_handle_obj( current->process, req->handle, req->access, NULL ))) { int fd = get_handle_fd( current->process, req->handle, req->access ); - if (fd != -1) req->fd = fd; + if (fd != -1) reply->fd = fd; else if (!get_error()) { if ((fd = obj->ops->get_fd( obj )) != -1) send_client_fd( current->process, fd, req->handle ); } - req->type = obj->ops->get_file_info( obj, NULL ); + reply->type = obj->ops->get_file_info( obj, NULL ); release_object( obj ); } } @@ -526,8 +526,8 @@ DECL_HANDLER(set_file_pointer) int high = req->high; int low = req->low; set_file_pointer( req->handle, &low, &high, req->whence ); - req->new_low = low; - req->new_high = high; + reply->new_low = low; + reply->new_high = high; } /* truncate (or extend) a file */ @@ -561,7 +561,7 @@ DECL_HANDLER(get_file_info) if ((obj = get_handle_obj( current->process, req->handle, 0, NULL ))) { - obj->ops->get_file_info( obj, req ); + obj->ops->get_file_info( obj, reply ); release_object( obj ); } } diff --git a/server/handle.c b/server/handle.c index ac4235ffd04..f4b004f1ce6 100644 --- a/server/handle.c +++ b/server/handle.c @@ -355,7 +355,6 @@ struct object *get_handle_obj( struct process *process, handle_t handle, if (!(entry = get_handle( process, handle ))) return NULL; if ((entry->access & access) != access) { - fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access ); set_error( STATUS_ACCESS_DENIED ); return NULL; } @@ -377,7 +376,6 @@ int get_handle_fd( struct process *process, handle_t handle, unsigned int access if (!(entry = get_handle( process, handle ))) return -1; if ((entry->access & access) != access) { - fprintf( stderr, "handle %d access %08x denied (%08x)\n", handle, access, entry->access ); set_error( STATUS_ACCESS_DENIED ); return -1; } @@ -459,7 +457,7 @@ handle_t open_object( const WCHAR *name, size_t len, const struct object_ops *op /* close a handle */ DECL_HANDLER(close_handle) { - close_handle( current->process, req->handle, &req->fd ); + close_handle( current->process, req->handle, &reply->fd ); } /* set a handle information */ @@ -468,8 +466,9 @@ DECL_HANDLER(set_handle_info) int fd = req->fd; if (handle_is_global(req->handle)) fd = -1; /* no fd cache for global handles */ - req->old_flags = set_handle_info( current->process, req->handle, req->mask, req->flags, &fd ); - req->cur_fd = fd; + reply->old_flags = set_handle_info( current->process, req->handle, + req->mask, req->flags, &fd ); + reply->cur_fd = fd; } /* duplicate a handle */ @@ -477,25 +476,25 @@ DECL_HANDLER(dup_handle) { struct process *src, *dst; - req->handle = 0; - req->fd = -1; + reply->handle = 0; + reply->fd = -1; if ((src = get_process_from_handle( req->src_process, PROCESS_DUP_HANDLE ))) { if (req->options & DUP_HANDLE_MAKE_GLOBAL) { - req->handle = duplicate_handle( src, req->src_handle, NULL, - req->access, req->inherit, req->options ); + reply->handle = duplicate_handle( src, req->src_handle, NULL, + req->access, req->inherit, req->options ); } else if ((dst = get_process_from_handle( req->dst_process, PROCESS_DUP_HANDLE ))) { - req->handle = duplicate_handle( src, req->src_handle, dst, - req->access, req->inherit, req->options ); + reply->handle = duplicate_handle( src, req->src_handle, dst, + req->access, req->inherit, req->options ); release_object( dst ); } /* close the handle no matter what happened */ if (req->options & DUP_HANDLE_CLOSE_SOURCE) { - if (src == current->process) close_handle( src, req->src_handle, &req->fd ); + if (src == current->process) close_handle( src, req->src_handle, &reply->fd ); else close_handle( src, req->src_handle, NULL ); } release_object( src ); diff --git a/server/mapping.c b/server/mapping.c index fd8194a64bc..8f4508be858 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -34,7 +34,7 @@ struct mapping }; static int mapping_get_fd( struct object *obj ); -static int mapping_get_info( struct object *obj, struct get_file_info_request *req ); +static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply ); static void mapping_dump( struct object *obj, int verbose ); static void mapping_destroy( struct object *obj ); @@ -263,11 +263,11 @@ static struct object *create_mapping( int size_high, int size_low, int protect, } if (!size_high && !size_low) { - struct get_file_info_request req; + struct get_file_info_reply reply; struct object *obj = (struct object *)mapping->file; - obj->ops->get_file_info( obj, &req ); - size_high = req.size_high; - size_low = ROUND_SIZE( 0, req.size_low ); + obj->ops->get_file_info( obj, &reply ); + size_high = reply.size_high; + size_low = ROUND_SIZE( 0, reply.size_low ); } else if (!grow_file( mapping->file, size_high, size_low )) goto error; } @@ -311,14 +311,14 @@ static int mapping_get_fd( struct object *obj ) return get_mmap_fd( mapping->file ); } -static int mapping_get_info( struct object *obj, struct get_file_info_request *req ) +static int mapping_get_info( struct object *obj, struct get_file_info_reply *reply ) { struct mapping *mapping = (struct mapping *)obj; struct object *file = (struct object *)mapping->file; assert( obj->ops == &mapping_ops ); assert( file ); - return file->ops->get_file_info( file, req ); + return file->ops->get_file_info( file, reply ); } static void mapping_destroy( struct object *obj ) @@ -346,14 +346,14 @@ DECL_HANDLER(create_mapping) { struct object *obj; - req->handle = 0; + reply->handle = 0; if ((obj = create_mapping( req->size_high, req->size_low, req->protect, req->file_handle, - get_req_data(req), get_req_data_size(req) ))) + get_req_data(), get_req_data_size() ))) { int access = FILE_MAP_ALL_ACCESS; if (!(req->protect & VPROT_WRITE)) access &= ~FILE_MAP_WRITE; - req->handle = alloc_handle( current->process, obj, access, req->inherit ); + reply->handle = alloc_handle( current->process, obj, access, req->inherit ); release_object( obj ); } } @@ -361,8 +361,8 @@ DECL_HANDLER(create_mapping) /* open a handle to a mapping */ DECL_HANDLER(open_mapping) { - req->handle = open_object( get_req_data(req), get_req_data_size(req), - &mapping_ops, req->access, req->inherit ); + reply->handle = open_object( get_req_data(), get_req_data_size(), + &mapping_ops, req->access, req->inherit ); } /* get a mapping information */ @@ -373,17 +373,17 @@ DECL_HANDLER(get_mapping_info) if ((mapping = (struct mapping *)get_handle_obj( current->process, req->handle, 0, &mapping_ops ))) { - req->size_high = mapping->size_high; - req->size_low = mapping->size_low; - req->protect = mapping->protect; - req->header_size = mapping->header_size; - req->base = mapping->base; - req->shared_file = 0; - req->shared_size = mapping->shared_size; - req->drive_type = get_file_drive_type( mapping->file ); + reply->size_high = mapping->size_high; + reply->size_low = mapping->size_low; + reply->protect = mapping->protect; + reply->header_size = mapping->header_size; + reply->base = mapping->base; + reply->shared_file = 0; + reply->shared_size = mapping->shared_size; + reply->drive_type = get_file_drive_type( mapping->file ); if (mapping->shared_file) - req->shared_file = alloc_handle( current->process, mapping->shared_file, - GENERIC_READ|GENERIC_WRITE, 0 ); + reply->shared_file = alloc_handle( current->process, mapping->shared_file, + GENERIC_READ|GENERIC_WRITE, 0 ); release_object( mapping ); } } diff --git a/server/mutex.c b/server/mutex.c index 54f90526402..ee145d94591 100644 --- a/server/mutex.c +++ b/server/mutex.c @@ -140,10 +140,10 @@ DECL_HANDLER(create_mutex) { struct mutex *mutex; - req->handle = 0; - if ((mutex = create_mutex( get_req_data(req), get_req_data_size(req), req->owned ))) + reply->handle = 0; + if ((mutex = create_mutex( get_req_data(), get_req_data_size(), req->owned ))) { - req->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, mutex, MUTEX_ALL_ACCESS, req->inherit ); release_object( mutex ); } } @@ -151,8 +151,8 @@ DECL_HANDLER(create_mutex) /* open a handle to a mutex */ DECL_HANDLER(open_mutex) { - req->handle = open_object( get_req_data(req), get_req_data_size(req), - &mutex_ops, req->access, req->inherit ); + reply->handle = open_object( get_req_data(), get_req_data_size(), + &mutex_ops, req->access, req->inherit ); } /* release a mutex */ diff --git a/server/named_pipe.c b/server/named_pipe.c index 57013d92a6e..06350396134 100644 --- a/server/named_pipe.c +++ b/server/named_pipe.c @@ -86,7 +86,7 @@ static const struct object_ops named_pipe_ops = static void pipe_user_dump( struct object *obj, int verbose ); static void pipe_user_destroy( struct object *obj); static int pipe_user_get_fd( struct object *obj ); -static int pipe_user_get_info( struct object *obj, struct get_file_info_request *req ); +static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply ); static const struct object_ops pipe_user_ops = { @@ -180,20 +180,20 @@ static int pipe_user_get_fd( struct object *obj ) return user->obj.fd; } -static int pipe_user_get_info( struct object *obj, struct get_file_info_request *req ) +static int pipe_user_get_info( struct object *obj, struct get_file_info_reply *reply ) { - if (req) + if (reply) { - req->type = FILE_TYPE_PIPE; - req->attr = 0; - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_PIPE; + reply->attr = 0; + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } return FD_TYPE_DEFAULT; } @@ -265,8 +265,8 @@ DECL_HANDLER(create_named_pipe) struct named_pipe *pipe; struct pipe_user *user; - req->handle = 0; - pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); + reply->handle = 0; + pipe = create_named_pipe( get_req_data(), get_req_data_size() ); if(!pipe) return; @@ -284,7 +284,7 @@ DECL_HANDLER(create_named_pipe) if(user) { user->state = ps_idle_server; - req->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 ); + reply->handle = alloc_handle( current->process, user, GENERIC_READ|GENERIC_WRITE, 0 ); release_object( user ); } @@ -295,8 +295,8 @@ DECL_HANDLER(open_named_pipe) { struct named_pipe *pipe; - req->handle = 0; - pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); + reply->handle = 0; + pipe = create_named_pipe( get_req_data(), get_req_data_size() ); if(!pipe) return; @@ -320,7 +320,7 @@ DECL_HANDLER(open_named_pipe) partner->other = user; user->state = ps_connected_client; user->other = partner; - req->handle = alloc_handle( current->process, user, req->access, 0 ); + reply->handle = alloc_handle( current->process, user, req->access, 0 ); release_object(user); } else @@ -378,7 +378,7 @@ DECL_HANDLER(wait_named_pipe) { struct named_pipe *pipe; - pipe = create_named_pipe( get_req_data(req), get_req_data_size(req) ); + pipe = create_named_pipe( get_req_data(), get_req_data_size() ); if( pipe ) { /* only wait if the pipe already exists */ @@ -448,10 +448,10 @@ DECL_HANDLER(get_named_pipe_info) if(!user) return; - req->flags = user->pipe->pipemode; - req->maxinstances = user->pipe->maxinstances; - req->insize = user->pipe->insize; - req->outsize = user->pipe->outsize; + reply->flags = user->pipe->pipemode; + reply->maxinstances = user->pipe->maxinstances; + reply->insize = user->pipe->insize; + reply->outsize = user->pipe->outsize; release_object(user); } diff --git a/server/object.c b/server/object.c index a6dd9082c65..10770060ea1 100644 --- a/server/object.c +++ b/server/object.c @@ -263,7 +263,7 @@ int no_flush( struct object *obj ) return 0; } -int no_get_file_info( struct object *obj, struct get_file_info_request *info ) +int no_get_file_info( struct object *obj, struct get_file_info_reply *info ) { set_error( STATUS_OBJECT_TYPE_MISMATCH ); return FD_TYPE_INVALID; diff --git a/server/object.h b/server/object.h index 09641d3f3aa..c805b51f263 100644 --- a/server/object.h +++ b/server/object.h @@ -47,7 +47,7 @@ struct object_ops /* flush the object buffers */ int (*flush)(struct object *); /* get file information */ - int (*get_file_info)(struct object *,struct get_file_info_request *); + int (*get_file_info)(struct object *,struct get_file_info_reply *); /* destroy on refcount == 0 */ void (*destroy)(struct object *); }; @@ -89,7 +89,7 @@ extern int no_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern int no_satisfied( struct object *obj, struct thread *thread ); extern int no_get_fd( struct object *obj ); extern int no_flush( struct object *obj ); -extern int no_get_file_info( struct object *obj, struct get_file_info_request *info ); +extern int no_get_file_info( struct object *obj, struct get_file_info_reply *info ); extern void no_destroy( struct object *obj ); extern int default_poll_add_queue( struct object *obj, struct wait_queue_entry *entry ); extern void default_poll_remove_queue( struct object *obj, struct wait_queue_entry *entry ); @@ -103,7 +103,7 @@ extern void dump_objects(void); extern int add_select_user( struct object *obj ); extern void remove_select_user( struct object *obj ); -extern void change_select_fd( struct object *obj, int fd ); +extern void change_select_fd( struct object *obj, int fd, int events ); extern void set_select_events( struct object *obj, int events ); extern int check_select_events( int fd, int events ); extern void select_loop(void); diff --git a/server/pipe.c b/server/pipe.c index d1b2d421aba..ddd200bbac4 100644 --- a/server/pipe.c +++ b/server/pipe.c @@ -37,7 +37,7 @@ struct pipe static void pipe_dump( struct object *obj, int verbose ); static int pipe_get_poll_events( struct object *obj ); static int pipe_get_fd( struct object *obj ); -static int pipe_get_info( struct object *obj, struct get_file_info_request *req ); +static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ); static void pipe_destroy( struct object *obj ); static const struct object_ops pipe_ops = @@ -124,20 +124,20 @@ static int pipe_get_fd( struct object *obj ) return pipe->obj.fd; } -static int pipe_get_info( struct object *obj, struct get_file_info_request *req ) +static int pipe_get_info( struct object *obj, struct get_file_info_reply *reply ) { - if (req) + if (reply) { - req->type = FILE_TYPE_PIPE; - req->attr = 0; - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_PIPE; + reply->attr = 0; + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } return FD_TYPE_DEFAULT; } @@ -171,6 +171,6 @@ DECL_HANDLER(create_pipe) release_object( obj[0] ); release_object( obj[1] ); } - req->handle_read = hread; - req->handle_write = hwrite; + reply->handle_read = hread; + reply->handle_write = hwrite; } diff --git a/server/process.c b/server/process.c index f02f5b79077..5a5241d2346 100644 --- a/server/process.c +++ b/server/process.c @@ -98,7 +98,7 @@ static const struct object_ops startup_info_ops = /* set the console and stdio handles for a newly created process */ static int set_process_console( struct process *process, struct process *parent, - struct startup_info *info, struct init_process_request *req ) + struct startup_info *info, struct init_process_reply *reply ) { if (process->create_flags & CREATE_NEW_CONSOLE) { @@ -120,35 +120,35 @@ static int set_process_console( struct process *process, struct process *parent, if (!info->inherit_all && !(info->start_flags & STARTF_USESTDHANDLES)) { /* duplicate the handle from the parent into this process */ - req->hstdin = duplicate_handle( parent, info->hstdin, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); - req->hstdout = duplicate_handle( parent, info->hstdout, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); - req->hstderr = duplicate_handle( parent, info->hstderr, process, - 0, TRUE, DUPLICATE_SAME_ACCESS ); + reply->hstdin = duplicate_handle( parent, info->hstdin, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); + reply->hstdout = duplicate_handle( parent, info->hstdout, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); + reply->hstderr = duplicate_handle( parent, info->hstderr, process, + 0, TRUE, DUPLICATE_SAME_ACCESS ); } else { - req->hstdin = info->hstdin; - req->hstdout = info->hstdout; - req->hstderr = info->hstderr; + reply->hstdin = info->hstdin; + reply->hstdout = info->hstdout; + reply->hstderr = info->hstderr; } } else { if (process->console) { - req->hstdin = alloc_handle( process, process->console, - GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 ); - req->hstdout = alloc_handle( process, process->console->active, - GENERIC_READ | GENERIC_WRITE, 1 ); - req->hstderr = alloc_handle( process, process->console->active, - GENERIC_READ | GENERIC_WRITE, 1 ); + reply->hstdin = alloc_handle( process, process->console, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 ); + reply->hstdout = alloc_handle( process, process->console->active, + GENERIC_READ | GENERIC_WRITE, 1 ); + reply->hstderr = alloc_handle( process, process->console->active, + GENERIC_READ | GENERIC_WRITE, 1 ); } else { /* no parent, let the caller decide what to do */ - req->hstdin = req->hstdout = req->hstderr = 0; + reply->hstdin = reply->hstdout = reply->hstderr = 0; } } /* some handles above may have been invalid; this is not an error */ @@ -216,7 +216,7 @@ struct thread *create_process( int fd ) } /* initialize the current process and fill in the request */ -static void init_process( int ppid, struct init_process_request *req ) +static void init_process( int ppid, struct init_process_reply *reply ) { struct process *process = current->process; struct thread *parent_thread = get_thread_from_pid( ppid ); @@ -251,16 +251,16 @@ static void init_process( int ppid, struct init_process_request *req ) if (!process->handles) return; /* retrieve the main exe file */ - req->exe_file = 0; + reply->exe_file = 0; if (parent && info->exe_file) { process->exe.file = (struct file *)grab_object( info->exe_file ); - if (!(req->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 ))) + if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 ))) return; } /* set the process console */ - if (!set_process_console( process, parent, info, req )) return; + if (!set_process_console( process, parent, info, reply )) return; if (parent) { @@ -277,23 +277,21 @@ static void init_process( int ppid, struct init_process_request *req ) if (info) { size_t size = strlen(info->filename); - if (size > get_req_data_size(req)) size = get_req_data_size(req); - req->start_flags = info->start_flags; - req->cmd_show = info->cmd_show; - memcpy( get_req_data(req), info->filename, size ); - set_req_data_size( req, size ); + if (size > get_reply_max_size()) size = get_reply_max_size(); + reply->start_flags = info->start_flags; + reply->cmd_show = info->cmd_show; + set_reply_data( info->filename, size ); info->process = (struct process *)grab_object( process ); info->thread = (struct thread *)grab_object( current ); wake_up( &info->obj, 0 ); } else { - req->start_flags = STARTF_USESTDHANDLES; - req->cmd_show = 0; - set_req_data_size( req, 0 ); + reply->start_flags = STARTF_USESTDHANDLES; + reply->cmd_show = 0; } - req->create_flags = process->create_flags; - req->server_start = server_start_ticks; + reply->create_flags = process->create_flags; + reply->server_start = server_start_ticks; } /* destroy a process when its refcount is 0 */ @@ -577,19 +575,19 @@ void kill_debugged_processes( struct thread *debugger, int exit_code ) /* get all information about a process */ -static void get_process_info( struct process *process, struct get_process_info_request *req ) +static void get_process_info( struct process *process, struct get_process_info_reply *reply ) { - req->pid = process; - req->debugged = (process->debugger != 0); - req->exit_code = process->exit_code; - req->priority = process->priority; - req->process_affinity = process->affinity; - req->system_affinity = 1; + reply->pid = process; + reply->debugged = (process->debugger != 0); + reply->exit_code = process->exit_code; + reply->priority = process->priority; + reply->process_affinity = process->affinity; + reply->system_affinity = 1; } /* set all information about a process */ static void set_process_info( struct process *process, - struct set_process_info_request *req ) + const struct set_process_info_request *req ) { if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority; @@ -601,62 +599,56 @@ static void set_process_info( struct process *process, } /* read data from a process memory space */ -/* len is the total size (in ints), max is the size we can actually store in the output buffer */ -/* we read the total size in all cases to check for permissions */ -static void read_process_memory( struct process *process, const int *addr, - size_t len, size_t max, int *dest ) +/* len is the total size (in ints) */ +static int read_process_memory( struct process *process, const int *addr, size_t len, int *dest ) { struct thread *thread = process->thread_list; - if ((unsigned int)addr % sizeof(int)) /* address must be aligned */ - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } + assert( !((unsigned int)addr % sizeof(int)) ); /* address must be aligned */ + if (!thread) /* process is dead */ { set_error( STATUS_ACCESS_DENIED ); - return; + return 0; } if (suspend_for_ptrace( thread )) { - while (len > 0 && max) + while (len > 0) { - if (read_thread_int( thread, addr++, dest++ ) == -1) goto done; - max--; + if (read_thread_int( thread, addr++, dest++ ) == -1) break; len--; } - /* check the rest for read permission */ - if (len > 0) - { - int dummy, page = get_page_size() / sizeof(int); - while (len >= page) - { - addr += page; - len -= page; - if (read_thread_int( thread, addr - 1, &dummy ) == -1) goto done; - } - if (len && (read_thread_int( thread, addr + len - 1, &dummy ) == -1)) goto done; - } - done: resume_thread( thread ); } + return !len; +} + +/* make sure we can write to the whole address range */ +/* len is the total size (in ints) */ +static int check_process_write_access( struct thread *thread, int *addr, size_t len ) +{ + int page = get_page_size() / sizeof(int); + + for (;;) + { + if (write_thread_int( thread, addr, 0, 0 ) == -1) return 0; + if (len <= page) break; + addr += page; + len -= page; + } + return (write_thread_int( thread, addr + len - 1, 0, 0 ) != -1); } /* write data to a process memory space */ /* len is the total size (in ints), max is the size we can actually read from the input buffer */ /* we check the total size for write permissions */ static void write_process_memory( struct process *process, int *addr, size_t len, - size_t max, unsigned int first_mask, - unsigned int last_mask, const int *src ) + unsigned int first_mask, unsigned int last_mask, const int *src ) { struct thread *thread = process->thread_list; - if (!len || ((unsigned int)addr % sizeof(int))) /* address must be aligned */ - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } + assert( !((unsigned int)addr % sizeof(int) )); /* address must be aligned */ + if (!thread) /* process is dead */ { set_error( STATUS_ACCESS_DENIED ); @@ -664,39 +656,28 @@ static void write_process_memory( struct process *process, int *addr, size_t len } if (suspend_for_ptrace( thread )) { + if (!check_process_write_access( thread, addr, len )) + { + set_error( STATUS_ACCESS_DENIED ); + return; + } /* first word is special */ if (len > 1) { if (write_thread_int( thread, addr++, *src++, first_mask ) == -1) goto done; len--; - max--; } else last_mask &= first_mask; - while (len > 1 && max) + while (len > 1) { if (write_thread_int( thread, addr++, *src++, ~0 ) == -1) goto done; - max--; len--; } - if (max) - { - /* last word is special too */ - if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done; - } - else - { - /* check the rest for write permission */ - int page = get_page_size() / sizeof(int); - while (len >= page) - { - addr += page; - len -= page; - if (write_thread_int( thread, addr - 1, 0, 0 ) == -1) goto done; - } - if (len && (write_thread_int( thread, addr + len - 1, 0, 0 ) == -1)) goto done; - } + /* last word is special too */ + if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done; + done: resume_thread( thread ); } @@ -747,7 +728,7 @@ struct module_snapshot *module_snap( struct process *process, int *count ) /* create a new process */ DECL_HANDLER(new_process) { - size_t len = get_req_data_size( req ); + size_t len = get_req_data_size(); struct startup_info *info; if (current->info) @@ -777,10 +758,10 @@ DECL_HANDLER(new_process) if (!(info->filename = mem_alloc( len + 1 ))) goto done; - memcpy( info->filename, get_req_data(req), len ); + memcpy( info->filename, get_req_data(), len ); info->filename[len] = 0; current->info = info; - req->info = alloc_handle( current->process, info, SYNCHRONIZE, FALSE ); + reply->info = alloc_handle( current->process, info, SYNCHRONIZE, FALSE ); done: release_object( info ); @@ -791,28 +772,28 @@ DECL_HANDLER(get_new_process_info) { struct startup_info *info; - req->event = 0; + reply->event = 0; if ((info = (struct startup_info *)get_handle_obj( current->process, req->info, 0, &startup_info_ops ))) { - req->pid = get_process_id( info->process ); - req->tid = get_thread_id( info->thread ); - req->phandle = alloc_handle( current->process, info->process, - PROCESS_ALL_ACCESS, req->pinherit ); - req->thandle = alloc_handle( current->process, info->thread, - THREAD_ALL_ACCESS, req->tinherit ); + reply->pid = get_process_id( info->process ); + reply->tid = get_thread_id( info->thread ); + reply->phandle = alloc_handle( current->process, info->process, + PROCESS_ALL_ACCESS, req->pinherit ); + reply->thandle = alloc_handle( current->process, info->thread, + THREAD_ALL_ACCESS, req->tinherit ); if (info->process->init_event) - req->event = alloc_handle( current->process, info->process->init_event, + reply->event = alloc_handle( current->process, info->process->init_event, EVENT_ALL_ACCESS, 0 ); release_object( info ); } else { - req->pid = 0; - req->tid = 0; - req->phandle = 0; - req->thandle = 0; + reply->pid = 0; + reply->tid = 0; + reply->phandle = 0; + reply->thandle = 0; } } @@ -825,7 +806,7 @@ DECL_HANDLER(init_process) return; } current->process->ldt_copy = req->ldt_copy; - init_process( req->ppid, req ); + init_process( req->ppid, reply ); } /* signal the end of the process initialization */ @@ -852,17 +833,17 @@ DECL_HANDLER(init_process_done) process->init_event = NULL; if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 ); if (current->suspend + current->process->suspend > 0) stop_thread( current ); - req->debugged = (current->process->debugger != 0); + reply->debugged = (current->process->debugger != 0); } /* open a handle to a process */ DECL_HANDLER(open_process) { struct process *process = get_process_from_id( req->pid ); - req->handle = 0; + reply->handle = 0; if (process) { - req->handle = alloc_handle( current->process, process, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, process, req->access, req->inherit ); release_object( process ); } } @@ -874,7 +855,7 @@ DECL_HANDLER(terminate_process) if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE ))) { - req->self = (current->process == process); + reply->self = (current->process == process); kill_process( process, current, req->exit_code ); release_object( process ); } @@ -887,7 +868,7 @@ DECL_HANDLER(get_process_info) if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ))) { - get_process_info( process, req ); + get_process_info( process, reply ); release_object( process ); } } @@ -908,13 +889,28 @@ DECL_HANDLER(set_process_info) DECL_HANDLER(read_process_memory) { struct process *process; + size_t len = get_reply_max_size(); - if ((process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) + if (!(process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) return; + + if (len) { - size_t maxlen = get_req_data_size(req) / sizeof(int); - read_process_memory( process, req->addr, req->len, maxlen, get_req_data(req) ); - release_object( process ); + unsigned int start_offset = (unsigned int)req->addr % sizeof(int); + unsigned int nb_ints = (len + start_offset + sizeof(int) - 1) / sizeof(int); + const int *start = (int *)((char *)req->addr - start_offset); + int *buffer = mem_alloc( nb_ints * sizeof(int) ); + if (buffer) + { + if (read_process_memory( process, start, nb_ints, buffer )) + { + /* move start of requested data to start of buffer */ + if (start_offset) memmove( buffer, (char *)buffer + start_offset, len ); + set_reply_data_ptr( buffer, len ); + } + else len = 0; + } } + release_object( process ); } /* write data to a process address space */ @@ -924,9 +920,14 @@ DECL_HANDLER(write_process_memory) if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE ))) { - size_t maxlen = get_req_data_size(req) / sizeof(int); - write_process_memory( process, req->addr, req->len, maxlen, - req->first_mask, req->last_mask, get_req_data(req) ); + size_t len = get_req_data_size(); + if ((len % sizeof(int)) || ((unsigned int)req->addr % sizeof(int))) + set_error( STATUS_INVALID_PARAMETER ); + else + { + if (len) write_process_memory( process, req->addr, len / sizeof(int), + req->first_mask, req->last_mask, get_req_data() ); + } release_object( process ); } } @@ -964,12 +965,12 @@ DECL_HANDLER(wait_input_idle) { struct process *process; - req->event = 0; + reply->event = 0; if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION ))) { if (process->idle_event && process != current->process && process->queue != current->queue) - req->event = alloc_handle( current->process, process->idle_event, - EVENT_ALL_ACCESS, 0 ); + reply->event = alloc_handle( current->process, process->idle_event, + EVENT_ALL_ACCESS, 0 ); release_object( process ); } } diff --git a/server/protocol.def b/server/protocol.def index f631297dc7b..6010dac2be1 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -16,17 +16,15 @@ struct request_header { - int req; /* request code */ - unsigned short var_offset; /* offset of the variable part of the request */ - unsigned short var_size; /* size of the variable part of the request */ - unsigned int error; /* error result */ + int req; /* request code */ + size_t request_size; /* request variable part size */ + size_t reply_size; /* reply variable part maximum size */ }; struct reply_header { - unsigned int error; /* error result */ - unsigned short var_offset; /* offset of the variable part of the request */ - unsigned short var_size; /* size of the variable part of the request */ + unsigned int error; /* error result */ + size_t reply_size; /* reply variable part size */ }; /* placeholder structure for the maximum allowed request size */ @@ -150,6 +148,13 @@ typedef struct int bottom; } rectangle_t; +/* structure for console char/attribute info */ +typedef struct +{ + WCHAR ch; + unsigned short attr; +} char_info_t; + /****************************************************************/ /* Request declarations */ @@ -244,15 +249,6 @@ typedef struct @END -/* Set the shared buffer for a thread */ -@REQ(set_thread_buffer) - int fd; /* fd to mmap as shared buffer */ -@REPLY - unsigned int offset; /* offset of buffer in file */ - unsigned int size; /* size of buffer */ -@END - - /* Terminate a process */ @REQ(terminate_process) handle_t handle; /* process handle to terminate */ @@ -819,6 +815,7 @@ struct console_renderer_event handle_t handle; /* handle to console input, or 0 for process' console */ int index; /* index to get line from */ @REPLY + int total; /* total length of line in Unicode chars */ VARARG(line,unicode_str); /* line to add */ @END @@ -900,32 +897,50 @@ struct console_renderer_event /* write data (chars and/or attributes) in a screen buffer */ @REQ(write_console_output) - handle_t handle; /* handle to the console input */ - int mode; /* 0 for text, 1, for attributes, 2 for both */ - /* bit3 (4) set if uniform pattern in data */ - short int x; /* position where to start writing */ - short int y; + handle_t handle; /* handle to the console output */ + int x; /* position where to start writing */ + int y; + int mode; /* char info (see below) */ + int wrap; /* wrap around at end of line? */ VARARG(data,bytes); /* info to write */ @REPLY - int written; /* number of bytes actually written */ + int written; /* number of char infos actually written */ + int width; /* width of screen buffer */ + int height; /* height of screen buffer */ @END -#define WRITE_CONSOLE_MODE_TEXT 0x00 -#define WRITE_CONSOLE_MODE_ATTR 0x01 -#define WRITE_CONSOLE_MODE_TEXTATTR 0x02 -#define WRITE_CONSOLE_MODE_TEXTSTDATTR 0x03 -#define WRITE_CONSOLE_MODE_UNIFORM 0x04 +enum char_info_mode +{ + CHAR_INFO_MODE_TEXT, /* characters only */ + CHAR_INFO_MODE_ATTR, /* attributes only */ + CHAR_INFO_MODE_TEXTATTR, /* both characters and attributes */ + CHAR_INFO_MODE_TEXTSTDATTR /* characters but use standard attributes */ +}; -/* read data (chars and/or attrubutes) from a screen buffer */ -@REQ(read_console_output) - handle_t handle; /* handle to the console input */ - short int x; /* position (x,y) where to start reading from */ - short int y; - short int w; /* size of area to read from (width x height) */ - short int h; +/* fill a screen buffer with constant data (chars and/or attributes) */ +@REQ(fill_console_output) + handle_t handle; /* handle to the console output */ + int x; /* position where to start writing */ + int y; + int mode; /* char info mode */ + int count; /* number to write */ + int wrap; /* wrap around at end of line? */ + char_info_t data; /* data to write */ @REPLY - short int eff_w; /* effective width read */ - short int eff_h; /* effective height read */ + int written; /* number of char infos actually written */ +@END + + +/* read data (chars and/or attributes) from a screen buffer */ +@REQ(read_console_output) + handle_t handle; /* handle to the console output */ + int x; /* position (x,y) where to start reading */ + int y; + int mode; /* char info mode */ + int wrap; /* wrap around at end of line? */ +@REPLY + int width; /* width of screen buffer */ + int height; /* height of screen buffer */ VARARG(data,bytes); @END @@ -1074,8 +1089,8 @@ struct console_renderer_event /* Retrieve the status of an exception event */ @REQ(get_exception_status) -@REPLY handle_t handle; /* handle to the queued event */ +@REPLY int status; /* event continuation status */ VARARG(context,context); /* modified thread context */ @END @@ -1106,8 +1121,7 @@ struct console_renderer_event /* Read data from a process address space */ @REQ(read_process_memory) handle_t handle; /* process handle */ - void* addr; /* addr to read from (must be int-aligned) */ - int len; /* number of ints to read */ + void* addr; /* addr to read from */ @REPLY VARARG(data,bytes); /* result data */ @END @@ -1117,10 +1131,9 @@ struct console_renderer_event @REQ(write_process_memory) handle_t handle; /* process handle */ void* addr; /* addr to write to (must be int-aligned) */ - int len; /* number of ints to write */ unsigned int first_mask; /* mask for first word */ unsigned int last_mask; /* mask for last word */ - VARARG(data,bytes); /* result data */ + VARARG(data,bytes); /* data to write */ @END @@ -1130,8 +1143,9 @@ struct console_renderer_event unsigned int access; /* desired access rights */ unsigned int options; /* creation options */ time_t modif; /* last modification time */ - VARARG(name,unicode_len_str); /* key name */ - VARARG(class,unicode_str); /* class name */ + size_t namelen; /* length of key name in bytes */ + VARARG(name,unicode_str,namelen); /* key name */ + VARARG(class,unicode_str); /* class name */ @REPLY handle_t hkey; /* handle to the created key */ int created; /* has it been newly created? */ @@ -1157,7 +1171,7 @@ struct console_renderer_event @REQ(enum_key) handle_t hkey; /* handle to registry key */ int index; /* index of subkey (or -1 for current key) */ - int full; /* return the full info? */ + int info_class; /* requested information class */ @REPLY int subkeys; /* number of subkeys */ int max_subkey; /* longest subkey name */ @@ -1166,8 +1180,10 @@ struct console_renderer_event int max_value; /* longest value name */ int max_data; /* longest value data */ time_t modif; /* last modification time */ - VARARG(name,unicode_len_str); /* key name */ - VARARG(class,unicode_str); /* class name */ + size_t total; /* total length needed for full name and class */ + size_t namelen; /* length of key name in bytes */ + VARARG(name,unicode_str,namelen); /* key name */ + VARARG(class,unicode_str); /* class name */ @END @@ -1175,21 +1191,19 @@ struct console_renderer_event @REQ(set_key_value) handle_t hkey; /* handle to registry key */ int type; /* value type */ - unsigned int total; /* total value len */ - unsigned int offset; /* offset for setting data */ - VARARG(name,unicode_len_str); /* value name */ - VARARG(data,bytes); /* value data */ + size_t namelen; /* length of value name in bytes */ + VARARG(name,unicode_str,namelen); /* value name */ + VARARG(data,bytes); /* value data */ @END /* Retrieve the value of a registry key */ @REQ(get_key_value) handle_t hkey; /* handle to registry key */ - unsigned int offset; /* offset for getting data */ - VARARG(name,unicode_len_str); /* value name */ + VARARG(name,unicode_str); /* value name */ @REPLY int type; /* value type */ - int len; /* value data len */ + size_t total; /* total length needed for data */ VARARG(data,bytes); /* value data */ @END @@ -1198,12 +1212,13 @@ struct console_renderer_event @REQ(enum_key_value) handle_t hkey; /* handle to registry key */ int index; /* value index */ - unsigned int offset; /* offset for getting data */ + int info_class; /* requested information class */ @REPLY int type; /* value type */ - int len; /* value data len */ - VARARG(name,unicode_len_str); /* value name */ - VARARG(data,bytes); /* value data */ + size_t total; /* total length needed for full name and data */ + size_t namelen; /* length of value name in bytes */ + VARARG(name,unicode_str,namelen); /* value name */ + VARARG(data,bytes); /* value data */ @END @@ -1429,6 +1444,7 @@ enum message_type int y; /* y position */ unsigned int time; /* message time */ unsigned int info; /* extra info */ + size_t total; /* total size of extra data */ VARARG(data,bytes); /* message data for sent messages */ @END #define GET_MSG_REMOVE 1 /* remove the message */ @@ -1765,5 +1781,6 @@ enum message_type @REQ(get_window_properties) user_handle_t window; /* handle to the window */ @REPLY + int total; /* total number of properties */ VARARG(props,properties); /* list of properties */ @END diff --git a/server/queue.c b/server/queue.c index b72f31ca516..87e85a0fa6a 100644 --- a/server/queue.c +++ b/server/queue.c @@ -330,10 +330,29 @@ static struct message_result *alloc_message_result( struct msg_queue *send_queue } /* receive a message, removing it from the sent queue */ -static void receive_message( struct msg_queue *queue, struct message *msg ) +static void receive_message( struct msg_queue *queue, struct message *msg, + struct get_message_reply *reply ) { struct message_result *result = msg->result; + reply->total = msg->data_size; + if (msg->data_size > get_reply_max_size()) + { + set_error( STATUS_BUFFER_OVERFLOW ); + return; + } + reply->type = msg->type; + reply->win = msg->win; + reply->msg = msg->msg; + reply->wparam = msg->wparam; + reply->lparam = msg->lparam; + reply->x = msg->x; + reply->y = msg->y; + reply->time = msg->time; + reply->info = msg->info; + + if (msg->data) set_reply_data_ptr( msg->data, msg->data_size ); + unlink_message( &queue->msg_list[SEND_MESSAGE], msg ); /* put the result on the receiver result stack */ if (result) @@ -341,14 +360,13 @@ static void receive_message( struct msg_queue *queue, struct message *msg ) result->recv_next = queue->recv_result; queue->recv_result = result; } - if (msg->data) free( msg->data ); free( msg ); if (!queue->msg_list[SEND_MESSAGE].first) clear_queue_bits( queue, QS_SENDMESSAGE ); } /* set the result of the current received message */ static void reply_message( struct msg_queue *queue, unsigned int result, - unsigned int error, int remove, void *data, size_t len ) + unsigned int error, int remove, const void *data, size_t len ) { struct message_result *res = queue->recv_result; @@ -656,8 +674,8 @@ DECL_HANDLER(get_msg_queue) { struct msg_queue *queue = get_current_queue(); - req->handle = 0; - if (queue) req->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 ); + reply->handle = 0; + if (queue) reply->handle = alloc_handle( current->process, queue, SYNCHRONIZE, 0 ); } @@ -670,8 +688,8 @@ DECL_HANDLER(set_queue_mask) { queue->wake_mask = req->wake_mask; queue->changed_mask = req->changed_mask; - req->wake_bits = queue->wake_bits; - req->changed_bits = queue->changed_bits; + reply->wake_bits = queue->wake_bits; + reply->changed_bits = queue->changed_bits; if (is_signaled( queue )) { /* if skip wait is set, do what would have been done in the subsequent wait */ @@ -688,11 +706,11 @@ DECL_HANDLER(get_queue_status) struct msg_queue *queue = current->queue; if (queue) { - req->wake_bits = queue->wake_bits; - req->changed_bits = queue->changed_bits; + reply->wake_bits = queue->wake_bits; + reply->changed_bits = queue->changed_bits; if (req->clear) queue->changed_bits = 0; } - else req->wake_bits = req->changed_bits = 0; + else reply->wake_bits = reply->changed_bits = 0; } @@ -731,8 +749,8 @@ DECL_HANDLER(send_message) switch(msg->type) { case MSG_OTHER_PROCESS: - msg->data_size = get_req_data_size(req); - if (msg->data_size && !(msg->data = memdup( get_req_data(req), msg->data_size ))) + msg->data_size = get_req_data_size(); + if (msg->data_size && !(msg->data = memdup( get_req_data(), msg->data_size ))) { free( msg ); break; @@ -779,31 +797,26 @@ DECL_HANDLER(send_message) release_object( thread ); } -/* store a message contents into the request buffer; helper for get_message */ -inline static void put_req_message( struct get_message_request *req, const struct message *msg ) -{ - int len = min( get_req_data_size(req), msg->data_size ); - - req->type = msg->type; - req->win = msg->win; - req->msg = msg->msg; - req->wparam = msg->wparam; - req->lparam = msg->lparam; - req->x = msg->x; - req->y = msg->y; - req->time = msg->time; - req->info = msg->info; - if (len) memcpy( get_req_data(req), msg->data, len ); - set_req_data_size( req, len ); -} - /* return a message to the application, removing it from the queue if needed */ -static void return_message_to_app( struct msg_queue *queue, struct get_message_request *req, +static void return_message_to_app( struct msg_queue *queue, int flags, + struct get_message_reply *reply, struct message *msg, enum message_kind kind ) { - put_req_message( req, msg ); + assert( !msg->data_size ); /* posted messages can't have data */ + + reply->type = msg->type; + reply->win = msg->win; + reply->msg = msg->msg; + reply->wparam = msg->wparam; + reply->lparam = msg->lparam; + reply->x = msg->x; + reply->y = msg->y; + reply->time = msg->time; + reply->info = msg->info; + reply->total = 0; + /* raw messages always get removed */ - if ((msg->type == MSG_HARDWARE_RAW) || (req->flags & GET_MSG_REMOVE)) + if ((msg->type == MSG_HARDWARE_RAW) || (flags & GET_MSG_REMOVE)) { queue->last_msg = NULL; remove_queue_message( queue, msg, kind ); @@ -843,20 +856,14 @@ DECL_HANDLER(get_message) struct msg_queue *queue = get_current_queue(); user_handle_t get_win = get_user_full_handle( req->get_win ); - if (!queue) - { - set_req_data_size( req, 0 ); - return; - } + if (!queue) return; /* first check for sent messages */ if ((msg = queue->msg_list[SEND_MESSAGE].first)) { - put_req_message( req, msg ); - receive_message( queue, msg ); + receive_message( queue, msg, reply ); return; } - set_req_data_size( req, 0 ); /* only sent messages can have data */ if (req->flags & GET_MSG_SENT_ONLY) goto done; /* nothing else to check */ /* if requested, remove the last returned but not yet removed message */ @@ -871,7 +878,7 @@ DECL_HANDLER(get_message) if ((msg = find_matching_message( &queue->msg_list[POST_MESSAGE], get_win, req->get_first, req->get_last ))) { - return_message_to_app( queue, req, msg, POST_MESSAGE ); + return_message_to_app( queue, req->flags, reply, msg, POST_MESSAGE ); return; } @@ -879,30 +886,30 @@ DECL_HANDLER(get_message) if ((msg = find_matching_message( &queue->msg_list[COOKED_HW_MESSAGE], get_win, req->get_first, req->get_last ))) { - return_message_to_app( queue, req, msg, COOKED_HW_MESSAGE ); + return_message_to_app( queue, req->flags, reply, msg, COOKED_HW_MESSAGE ); return; } /* then check for any raw hardware message */ if ((msg = queue->msg_list[RAW_HW_MESSAGE].first)) { - return_message_to_app( queue, req, msg, RAW_HW_MESSAGE ); + return_message_to_app( queue, req->flags, reply, msg, RAW_HW_MESSAGE ); return; } /* now check for WM_PAINT */ if (queue->paint_count && (WM_PAINT >= req->get_first) && (WM_PAINT <= req->get_last) && - (req->win = find_window_to_repaint( get_win, current ))) + (reply->win = find_window_to_repaint( get_win, current ))) { - req->type = MSG_POSTED; - req->msg = WM_PAINT; - req->wparam = 0; - req->lparam = 0; - req->x = 0; - req->y = 0; - req->time = get_tick_count(); - req->info = 0; + reply->type = MSG_POSTED; + reply->msg = WM_PAINT; + reply->wparam = 0; + reply->lparam = 0; + reply->x = 0; + reply->y = 0; + reply->time = get_tick_count(); + reply->info = 0; return; } @@ -910,15 +917,15 @@ DECL_HANDLER(get_message) if ((timer = find_expired_timer( queue, get_win, req->get_first, req->get_last, (req->flags & GET_MSG_REMOVE) ))) { - req->type = MSG_POSTED; - req->win = timer->win; - req->msg = timer->msg; - req->wparam = timer->id; - req->lparam = timer->lparam; - req->x = 0; - req->y = 0; - req->time = get_tick_count(); - req->info = 0; + reply->type = MSG_POSTED; + reply->win = timer->win; + reply->msg = timer->msg; + reply->wparam = timer->id; + reply->lparam = timer->lparam; + reply->x = 0; + reply->y = 0; + reply->time = get_tick_count(); + reply->info = 0; return; } @@ -932,7 +939,7 @@ DECL_HANDLER(reply_message) { if (current->queue && current->queue->recv_result) reply_message( current->queue, req->result, 0, req->remove, - get_req_data(req), get_req_data_size(req) ); + get_req_data(), get_req_data_size() ); else set_error( STATUS_ACCESS_DENIED ); } @@ -942,26 +949,24 @@ DECL_HANDLER(reply_message) DECL_HANDLER(get_message_reply) { struct msg_queue *queue = current->queue; - size_t data_len = 0; if (queue) { struct message_result *result = queue->send_result; set_error( STATUS_PENDING ); - req->result = 0; + reply->result = 0; if (result && (result->replied || req->cancel)) { if (result->replied) { - req->result = result->result; + reply->result = result->result; set_error( result->error ); if (result->data) { - data_len = min( result->data_size, get_req_data_size(req) ); - memcpy( get_req_data(req), result->data, data_len ); - free( result->data ); + size_t data_len = min( result->data_size, get_reply_max_size() ); + set_reply_data_ptr( result->data, data_len ); result->data = NULL; result->data_size = 0; } @@ -974,7 +979,6 @@ DECL_HANDLER(get_message_reply) } } else set_error( STATUS_ACCESS_DENIED ); - set_req_data_size( req, data_len ); } diff --git a/server/registry.c b/server/registry.c index 961f441606a..f8e82f4fc4a 100644 --- a/server/registry.c +++ b/server/registry.c @@ -29,7 +29,7 @@ #include "winbase.h" #include "winreg.h" #include "winnt.h" /* registry definitions */ - +#include "ntddk.h" /* a registry key */ struct key @@ -285,7 +285,7 @@ static void key_destroy( struct object *obj ) } } -/* duplicate a key path from the request buffer */ +/* duplicate a key path */ /* returns a pointer to a static buffer, so only useable once per request */ static WCHAR *copy_path( const WCHAR *path, size_t len, int skip_root ) { @@ -303,17 +303,17 @@ static WCHAR *copy_path( const WCHAR *path, size_t len, int skip_root ) return buffer; } -/* copy a path from the request buffer, in cases where the length is stored in front of the path */ -static WCHAR *copy_req_path( void *req, size_t *len, int skip_root ) +/* copy a path from the request buffer */ +static WCHAR *copy_req_path( size_t len, int skip_root ) { - const WCHAR *name_ptr = get_req_data(req); - if ((*len = sizeof(WCHAR) + *name_ptr++) > get_req_data_size(req)) + const WCHAR *name_ptr = get_req_data(); + if (len > get_req_data_size()) { fatal_protocol_error( current, "copy_req_path: invalid length %d/%d\n", - *len, get_req_data_size(req) ); + len, get_req_data_size() ); return NULL; } - return copy_path( name_ptr, *len - sizeof(WCHAR), skip_root ); + return copy_path( name_ptr, len, skip_root ); } /* return the next token in a given path */ @@ -564,26 +564,39 @@ static struct key *create_key( struct key *key, WCHAR *name, WCHAR *class, } /* query information about a key or a subkey */ -static size_t enum_key( struct key *key, int index, struct enum_key_request *req ) +static void enum_key( struct key *key, int index, int info_class, struct enum_key_reply *reply ) { int i; size_t len, namelen, classlen; int max_subkey = 0, max_class = 0; int max_value = 0, max_data = 0; - WCHAR *data = get_req_data(req); + WCHAR *data; if (index != -1) /* -1 means use the specified key directly */ { if ((index < 0) || (index > key->last_subkey)) { set_error( STATUS_NO_MORE_ENTRIES ); - return 0; + return; } key = key->subkeys[index]; } - if (req->full) + namelen = strlenW(key->name) * sizeof(WCHAR); + classlen = key->class ? strlenW(key->class) * sizeof(WCHAR) : 0; + + switch(info_class) { + case KeyBasicInformation: + classlen = 0; /* only return the name */ + /* fall through */ + case KeyNodeInformation: + reply->max_subkey = 0; + reply->max_class = 0; + reply->max_value = 0; + reply->max_data = 0; + break; + case KeyFullInformation: for (i = 0; i <= key->last_subkey; i++) { struct key *subkey = key->subkeys[i]; @@ -600,43 +613,37 @@ static size_t enum_key( struct key *key, int index, struct enum_key_request *req len = key->values[i].len; if (len > max_data) max_data = len; } - req->max_subkey = max_subkey; - req->max_class = max_class; - req->max_value = max_value; - req->max_data = max_data; + reply->max_subkey = max_subkey; + reply->max_class = max_class; + reply->max_value = max_value; + reply->max_data = max_data; + namelen = 0; /* only return the class */ + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return; } - else + reply->subkeys = key->last_subkey + 1; + reply->values = key->last_value + 1; + reply->modif = key->modif; + reply->total = namelen + classlen; + + len = min( reply->total, get_reply_max_size() ); + if (len && (data = set_reply_data_size( len ))) { - req->max_subkey = 0; - req->max_class = 0; - req->max_value = 0; - req->max_data = 0; + if (len > namelen) + { + reply->namelen = namelen; + memcpy( data, key->name, namelen ); + memcpy( (char *)data + namelen, key->class, len - namelen ); + } + else + { + reply->namelen = len; + memcpy( data, key->name, len ); + } } - req->subkeys = key->last_subkey + 1; - req->values = key->last_value + 1; - req->modif = key->modif; - - namelen = strlenW(key->name) * sizeof(WCHAR); - classlen = key->class ? strlenW(key->class) * sizeof(WCHAR) : 0; - - len = namelen + classlen + sizeof(WCHAR); - if (len > get_req_data_size(req)) - { - len = get_req_data_size(req); - if (len < sizeof(WCHAR)) return 0; - } - - *data++ = namelen; - len -= sizeof(WCHAR); - if (len > namelen) - { - memcpy( data, key->name, namelen ); - memcpy( (char *)data + namelen, key->class, min(classlen,len-namelen) ); - } - else memcpy( data, key->name, len ); - if (debug_level > 1) dump_operation( key, NULL, "Enum" ); - return len + sizeof(WCHAR); } /* delete a key and its values */ @@ -743,43 +750,13 @@ static struct key_value *insert_value( struct key *key, const WCHAR *name ) } /* set a key value */ -static void set_value( struct key *key, WCHAR *name, int type, unsigned int total_len, - unsigned int offset, unsigned int data_len, const void *data ) +static void set_value( struct key *key, WCHAR *name, int type, const void *data, size_t len ) { struct key_value *value; void *ptr = NULL; - if (data_len + offset > total_len) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - - if (offset) /* adding data to an existing value */ - { - int index; - if (!(value = find_value( key, name, &index ))) - { - set_error( STATUS_OBJECT_NAME_NOT_FOUND ); - return; - } - if (value->len != total_len) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - memcpy( (char *)value->data + offset, data, data_len ); - if (debug_level > 1) dump_operation( key, value, "Set" ); - return; - } - /* first copy the data */ - if (total_len) - { - if (!(ptr = mem_alloc( total_len ))) return; - memcpy( ptr, data, data_len ); - if (data_len < total_len) memset( (char *)ptr + data_len, 0, total_len - data_len ); - } + if (len && !(ptr = memdup( data, len ))) return; if (!(value = insert_value( key, name ))) { @@ -788,30 +765,23 @@ static void set_value( struct key *key, WCHAR *name, int type, unsigned int tota } if (value->data) free( value->data ); /* already existing, free previous data */ value->type = type; - value->len = total_len; + value->len = len; value->data = ptr; touch_key( key ); if (debug_level > 1) dump_operation( key, value, "Set" ); } /* get a key value */ -static size_t get_value( struct key *key, const WCHAR *name, unsigned int offset, - unsigned int maxlen, int *type, int *len, void *data ) +static void get_value( struct key *key, const WCHAR *name, int *type, int *len ) { struct key_value *value; int index; - size_t ret = 0; if ((value = find_value( key, name, &index ))) { *type = value->type; *len = value->len; - if (value->data && offset < value->len) - { - if (maxlen > value->len - offset) maxlen = value->len - offset; - memcpy( data, (char *)value->data + offset, maxlen ); - ret = maxlen; - } + if (value->data) set_reply_data( value->data, min( value->len, get_reply_max_size() )); if (debug_level > 1) dump_operation( key, value, "Get" ); } else @@ -819,54 +789,57 @@ static size_t get_value( struct key *key, const WCHAR *name, unsigned int offset *type = -1; set_error( STATUS_OBJECT_NAME_NOT_FOUND ); } - return ret; } /* enumerate a key value */ -static size_t enum_value( struct key *key, int i, unsigned int offset, - unsigned int maxlen, int *type, int *len, void *data ) +static void enum_value( struct key *key, int i, int info_class, struct enum_key_value_reply *reply ) { struct key_value *value; - size_t ret = 0; if (i < 0 || i > key->last_value) set_error( STATUS_NO_MORE_ENTRIES ); else { - WCHAR *name_ptr = data; + void *data; + size_t namelen, maxlen; + value = &key->values[i]; - *type = value->type; - *len = value->len; + reply->type = value->type; + namelen = strlenW( value->name ) * sizeof(WCHAR); - if (maxlen >= sizeof(WCHAR)) + switch(info_class) { - size_t name_len = 0; + case KeyValueBasicInformation: + reply->total = namelen; + break; + case KeyValueFullInformation: + reply->total = namelen + value->len; + break; + case KeyValuePartialInformation: + reply->total = value->len; + namelen = 0; + break; + default: + set_error( STATUS_INVALID_PARAMETER ); + return; + } - /* copy the name only the first time (offset==0), - * otherwise store an empty name in the buffer - */ - maxlen -= sizeof(WCHAR); - ret += sizeof(WCHAR); - if (!offset) + maxlen = min( reply->total, get_reply_max_size() ); + if (maxlen && ((data = set_reply_data_size( maxlen )))) + { + if (maxlen > namelen) { - name_len = strlenW( value->name ) * sizeof(WCHAR); - if (name_len > maxlen) name_len = maxlen; + reply->namelen = namelen; + memcpy( data, value->name, namelen ); + memcpy( (char *)data + namelen, value->data, maxlen - namelen ); } - *name_ptr++ = name_len; - memcpy( name_ptr, value->name, name_len ); - maxlen -= name_len; - ret += name_len; - data = (char *)name_ptr + name_len; - - if (value->data && offset < value->len) + else { - if (maxlen > value->len - offset) maxlen = value->len - offset; - memcpy( data, (char *)value->data + offset, maxlen ); - ret += maxlen; + reply->namelen = maxlen; + memcpy( data, value->name, maxlen ); } } if (debug_level > 1) dump_operation( key, value, "Enum" ); } - return ret; } /* delete a value */ @@ -1585,31 +1558,30 @@ DECL_HANDLER(create_key) struct key *key = NULL, *parent; unsigned int access = req->access; WCHAR *name, *class; - size_t len; if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS; /* FIXME: needs general solution */ - req->hkey = 0; - if (!(name = copy_req_path( req, &len, !req->parent ))) return; + reply->hkey = 0; + if (!(name = copy_req_path( req->namelen, !req->parent ))) return; if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ ))) { - if (len == get_req_data_size(req)) /* no class specified */ + if (req->namelen == get_req_data_size()) /* no class specified */ { - key = create_key( parent, name, NULL, req->options, req->modif, &req->created ); + key = create_key( parent, name, NULL, req->options, req->modif, &reply->created ); } else { - const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data(req) + len); + const WCHAR *class_ptr = (WCHAR *)((char *)get_req_data() + req->namelen); - if ((class = req_strdupW( req, class_ptr, get_req_data_size(req) - len ))) + if ((class = req_strdupW( req, class_ptr, get_req_data_size() - req->namelen ))) { key = create_key( parent, name, class, req->options, - req->modif, &req->created ); + req->modif, &reply->created ); free( class ); } } if (key) { - req->hkey = alloc_handle( current->process, key, access, 0 ); + reply->hkey = alloc_handle( current->process, key, access, 0 ); release_object( key ); } release_object( parent ); @@ -1623,13 +1595,13 @@ DECL_HANDLER(open_key) unsigned int access = req->access; if (access & MAXIMUM_ALLOWED) access = KEY_ALL_ACCESS; /* FIXME: needs general solution */ - req->hkey = 0; + reply->hkey = 0; if ((parent = get_hkey_obj( req->parent, 0 /*FIXME*/ ))) { - WCHAR *name = copy_path( get_req_data(req), get_req_data_size(req), !req->parent ); + WCHAR *name = copy_path( get_req_data(), get_req_data_size(), !req->parent ); if (name && (key = open_key( parent, name ))) { - req->hkey = alloc_handle( current->process, key, access, 0 ); + reply->hkey = alloc_handle( current->process, key, access, 0 ); release_object( key ); } release_object( parent ); @@ -1652,15 +1624,13 @@ DECL_HANDLER(delete_key) DECL_HANDLER(enum_key) { struct key *key; - size_t len = 0; if ((key = get_hkey_obj( req->hkey, req->index == -1 ? KEY_QUERY_VALUE : KEY_ENUMERATE_SUB_KEYS ))) { - len = enum_key( key, req->index, req ); + enum_key( key, req->index, req->info_class, reply ); release_object( key ); } - set_req_data_size( req, len ); } /* set a value of a registry key */ @@ -1668,15 +1638,14 @@ DECL_HANDLER(set_key_value) { struct key *key; WCHAR *name; - size_t len; - if (!(name = copy_req_path( req, &len, 0 ))) return; + if (!(name = copy_req_path( req->namelen, 0 ))) return; if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE ))) { - size_t datalen = get_req_data_size(req) - len; - const char *data = (char *)get_req_data(req) + len; + size_t datalen = get_req_data_size() - req->namelen; + const char *data = (char *)get_req_data() + req->namelen; - set_value( key, name, req->type, req->total, req->offset, datalen, data ); + set_value( key, name, req->type, data, datalen ); release_object( key ); } } @@ -1686,33 +1655,26 @@ DECL_HANDLER(get_key_value) { struct key *key; WCHAR *name; - size_t len = 0, tmp; - req->len = 0; - if (!(name = copy_req_path( req, &tmp, 0 ))) return; + reply->total = 0; + if (!(name = copy_path( get_req_data(), get_req_data_size(), 0 ))) return; if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE ))) { - len = get_value( key, name, req->offset, get_req_data_size(req), - &req->type, &req->len, get_req_data(req) ); + get_value( key, name, &reply->type, &reply->total ); release_object( key ); } - set_req_data_size( req, len ); } /* enumerate the value of a registry key */ DECL_HANDLER(enum_key_value) { struct key *key; - size_t len = 0; - req->len = 0; if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE ))) { - len = enum_value( key, req->index, req->offset, get_req_data_size(req), - &req->type, &req->len, get_req_data(req) ); + enum_value( key, req->index, req->info_class, reply ); release_object( key ); } - set_req_data_size( req, len ); } /* delete a value of a registry key */ @@ -1723,7 +1685,7 @@ DECL_HANDLER(delete_key_value) if ((key = get_hkey_obj( req->hkey, KEY_SET_VALUE ))) { - if ((name = req_strdupW( req, get_req_data(req), get_req_data_size(req) ))) + if ((name = req_strdupW( req, get_req_data(), get_req_data_size() ))) { delete_value( key, name ); free( name ); @@ -1786,7 +1748,7 @@ DECL_HANDLER(save_registry_atexit) if ((key = get_hkey_obj( req->hkey, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS ))) { - register_branch_for_saving( key, get_req_data(req), get_req_data_size(req) ); + register_branch_for_saving( key, get_req_data(), get_req_data_size() ); release_object( key ); } } diff --git a/server/request.c b/server/request.c index ba420a04ddf..9f2b8ad5e49 100644 --- a/server/request.c +++ b/server/request.c @@ -142,31 +142,105 @@ void fatal_perror( const char *err, ... ) exit(1); } -/* call a request handler */ -static inline void call_req_handler( struct thread *thread, union generic_request *request ) +/* allocate the reply data */ +void *set_reply_data_size( size_t size ) { - enum request req = request->header.req; + assert( size <= get_reply_max_size() ); + if (size && !(current->reply_data = mem_alloc( size ))) size = 0; + current->reply_size = size; + return current->reply_data; +} - current = thread; - clear_error(); +/* write the remaining part of the reply */ +void write_reply( struct thread *thread ) +{ + int ret; - if (debug_level) trace_request( thread, request ); - - if (request->header.var_size) + if ((ret = write( thread->reply_fd, + (char *)thread->reply_data + thread->reply_size - thread->reply_towrite, + thread->reply_towrite )) >= 0) { - if ((unsigned int)request->header.var_offset + - request->header.var_size > MAX_REQUEST_LENGTH) + if (!(thread->reply_towrite -= ret)) { - fatal_protocol_error( current, "bad request offset/size %d/%d\n", - request->header.var_offset, request->header.var_size ); + free( thread->reply_data ); + thread->reply_data = NULL; + /* sent everything, can go back to waiting for requests */ + change_select_fd( &thread->obj, thread->request_fd, POLLIN ); + } + return; + } + if (errno == EPIPE) + kill_thread( thread, 0 ); /* normal death */ + else if (errno != EWOULDBLOCK && errno != EAGAIN) + fatal_protocol_perror( thread, "reply write" ); +} + +/* send a reply to the current thread */ +static void send_reply( union generic_reply *reply ) +{ + int ret; + + if (!current->reply_size) + { + if ((ret = write( current->reply_fd, reply, sizeof(*reply) )) != sizeof(*reply)) goto error; + } + else + { + struct iovec vec[2]; + + vec[0].iov_base = reply; + vec[0].iov_len = sizeof(*reply); + vec[1].iov_base = current->reply_data; + vec[1].iov_len = current->reply_size; + + if ((ret = writev( current->reply_fd, vec, 2 )) < sizeof(*reply)) goto error; + + if ((current->reply_towrite = current->reply_size - (ret - sizeof(*reply)))) + { + /* couldn't write it all, wait for POLLOUT */ + change_select_fd( ¤t->obj, current->reply_fd, POLLOUT ); return; } } + if (current->reply_data) + { + free( current->reply_data ); + current->reply_data = NULL; + } + return; + + error: + if (ret >= 0) + fatal_protocol_error( current, "partial write %d\n", ret ); + else if (errno == EPIPE) + kill_thread( current, 0 ); /* normal death */ + else + fatal_protocol_perror( current, "reply write" ); +} + +/* call a request handler */ +static void call_req_handler( struct thread *thread ) +{ + union generic_reply reply; + enum request req = thread->req.request_header.req; + + current = thread; + current->reply_size = 0; + clear_error(); + memset( &reply, 0, sizeof(reply) ); + + if (debug_level) trace_request(); if (req < REQ_NB_REQUESTS) { - req_handlers[req]( request ); - if (current) send_reply( current, request ); + req_handlers[req]( ¤t->req, &reply ); + if (current) + { + reply.reply_header.error = current->error; + reply.reply_header.reply_size = current->reply_size; + if (debug_level) trace_reply( req, &reply ); + send_reply( &reply ); + } current = NULL; return; } @@ -176,14 +250,39 @@ static inline void call_req_handler( struct thread *thread, union generic_reques /* read a request from a thread */ void read_request( struct thread *thread ) { - union generic_request req; int ret; - if ((ret = read( thread->obj.fd, &req, sizeof(req) )) == sizeof(req)) + if (!thread->req_toread) /* no pending request */ { - call_req_handler( thread, &req ); - return; + if ((ret = read( thread->obj.fd, &thread->req, + sizeof(thread->req) )) != sizeof(thread->req)) goto error; + if (!(thread->req_toread = thread->req.request_header.request_size)) + { + /* no data, handle request at once */ + call_req_handler( thread ); + return; + } + if (!(thread->req_data = malloc( thread->req_toread ))) + fatal_protocol_error( thread, "no memory for %d bytes request\n", thread->req_toread ); } + + /* read the variable sized data */ + for (;;) + { + ret = read( thread->obj.fd, ((char *)thread->req_data + + thread->req.request_header.request_size - thread->req_toread), + thread->req_toread ); + if (ret <= 0) break; + if (!(thread->req_toread -= ret)) + { + call_req_handler( thread ); + free( thread->req_data ); + thread->req_data = NULL; + return; + } + } + +error: if (!ret) /* closed pipe */ kill_thread( thread, 0 ); else if (ret > 0) @@ -192,26 +291,6 @@ void read_request( struct thread *thread ) fatal_protocol_perror( thread, "read" ); } -/* send a reply to a thread */ -void send_reply( struct thread *thread, union generic_request *request ) -{ - int ret; - - if (debug_level) trace_reply( thread, request ); - - request->header.error = thread->error; - - if ((ret = write( thread->reply_fd, request, sizeof(*request) )) != sizeof(*request)) - { - if (ret >= 0) - fatal_protocol_error( thread, "partial write %d\n", ret ); - else if (errno == EPIPE) - kill_thread( thread, 0 ); /* normal death */ - else - fatal_protocol_perror( thread, "reply write" ); - } -} - /* receive a file descriptor on the process socket */ int receive_fd( struct process *process ) { @@ -439,6 +518,7 @@ void open_master_socket(void) /* make sure no request is larger than the maximum size */ assert( sizeof(union generic_request) == sizeof(struct request_max_size) ); + assert( sizeof(union generic_reply) == sizeof(struct request_max_size) ); create_server_dir(); if ((fd = socket( AF_UNIX, SOCK_STREAM, 0 )) == -1) fatal_perror( "socket" ); diff --git a/server/request.h b/server/request.h index 58666416e07..b1409aae054 100644 --- a/server/request.h +++ b/server/request.h @@ -7,6 +7,8 @@ #ifndef __WINE_SERVER_REQUEST_H #define __WINE_SERVER_REQUEST_H +#include + #include "thread.h" #include "wine/server_protocol.h" @@ -14,7 +16,8 @@ #define MAX_REQUEST_LENGTH 8192 /* request handler definition */ -#define DECL_HANDLER(name) void req_##name( struct name##_request *req ) +#define DECL_HANDLER(name) \ + void req_##name( const struct name##_request *req, struct name##_reply *reply ) /* request functions */ @@ -33,36 +36,54 @@ extern void fatal_perror( const char *err, ... ); #endif extern const char *get_config_dir(void); +extern void *set_reply_data_size( size_t size ); extern int receive_fd( struct process *process ); extern int send_client_fd( struct process *process, int fd, handle_t handle ); extern void read_request( struct thread *thread ); -extern void send_reply( struct thread *thread, union generic_request *request ); +extern void write_reply( struct thread *thread ); extern unsigned int get_tick_count(void); extern void open_master_socket(void); extern void close_master_socket(void); extern void lock_master_socket( int locked ); -extern void trace_request( struct thread *thread, const union generic_request *request ); -extern void trace_reply( struct thread *thread, const union generic_request *request ); +extern void trace_request(void); +extern void trace_reply( enum request req, const union generic_reply *reply ); /* get the request vararg data */ -inline static void *get_req_data( const void *req ) +inline static const void *get_req_data(void) { - return (char *)current->buffer + ((struct request_header *)req)->var_offset; + return current->req_data; } /* get the request vararg size */ -inline static size_t get_req_data_size( const void *req ) +inline static size_t get_req_data_size(void) { - return ((struct request_header *)req)->var_size; + return current->req.request_header.request_size; } -/* set the request vararg size */ -inline static void set_req_data_size( const void *req, size_t size ) +/* get the reply maximum vararg size */ +inline static size_t get_reply_max_size(void) { - ((struct request_header *)req)->var_size = size; + return current->req.request_header.reply_size; } +/* allocate and fill the reply data */ +inline static void *set_reply_data( const void *data, size_t size ) +{ + void *ret = set_reply_data_size( size ); + if (ret) memcpy( ret, data, size ); + return ret; +} + +/* set the reply data pointer directly (will be freed by request code) */ +inline static void set_reply_data_ptr( void *data, size_t size ) +{ + assert( size <= get_reply_max_size() ); + current->reply_size = size; + current->reply_data = data; +} + + /* Everything below this line is generated automatically by tools/make_requests */ /* ### make_requests begin ### */ @@ -73,7 +94,6 @@ DECL_HANDLER(boot_done); DECL_HANDLER(init_process); DECL_HANDLER(init_process_done); DECL_HANDLER(init_thread); -DECL_HANDLER(set_thread_buffer); DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_thread); DECL_HANDLER(get_process_info); @@ -132,6 +152,7 @@ DECL_HANDLER(get_console_output_info); DECL_HANDLER(write_console_input); DECL_HANDLER(read_console_input); DECL_HANDLER(write_console_output); +DECL_HANDLER(fill_console_output); DECL_HANDLER(read_console_output); DECL_HANDLER(move_console_output); DECL_HANDLER(create_change_notification); @@ -217,7 +238,7 @@ DECL_HANDLER(get_window_properties); #ifdef WANT_REQUEST_HANDLERS -typedef void (*req_handler)( void *req ); +typedef void (*req_handler)( const void *req, void *reply ); static const req_handler req_handlers[REQ_NB_REQUESTS] = { (req_handler)req_new_process, @@ -227,7 +248,6 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_init_process, (req_handler)req_init_process_done, (req_handler)req_init_thread, - (req_handler)req_set_thread_buffer, (req_handler)req_terminate_process, (req_handler)req_terminate_thread, (req_handler)req_get_process_info, @@ -286,6 +306,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_write_console_input, (req_handler)req_read_console_input, (req_handler)req_write_console_output, + (req_handler)req_fill_console_output, (req_handler)req_read_console_output, (req_handler)req_move_console_output, (req_handler)req_create_change_notification, diff --git a/server/select.c b/server/select.c index 2e0b7a8aec6..a51feaaa79c 100644 --- a/server/select.c +++ b/server/select.c @@ -97,13 +97,13 @@ void remove_select_user( struct object *obj ) active_users--; } -/* change the fd of an object (the old fd is closed) */ -void change_select_fd( struct object *obj, int fd ) +/* change the fd and events of an object */ +void change_select_fd( struct object *obj, int fd, int events ) { int user = obj->select; assert( poll_users[user] == obj ); pollfd[user].fd = fd; - close( obj->fd ); + pollfd[user].events = events; obj->fd = fd; } diff --git a/server/semaphore.c b/server/semaphore.c index 48444146928..022fc738383 100644 --- a/server/semaphore.c +++ b/server/semaphore.c @@ -123,11 +123,11 @@ DECL_HANDLER(create_semaphore) { struct semaphore *sem; - req->handle = 0; - if ((sem = create_semaphore( get_req_data(req), get_req_data_size(req), + reply->handle = 0; + if ((sem = create_semaphore( get_req_data(), get_req_data_size(), req->initial, req->max ))) { - req->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, sem, SEMAPHORE_ALL_ACCESS, req->inherit ); release_object( sem ); } } @@ -135,12 +135,12 @@ DECL_HANDLER(create_semaphore) /* open a handle to a semaphore */ DECL_HANDLER(open_semaphore) { - req->handle = open_object( get_req_data(req), get_req_data_size(req), - &semaphore_ops, req->access, req->inherit ); + reply->handle = open_object( get_req_data(), get_req_data_size(), + &semaphore_ops, req->access, req->inherit ); } /* release a semaphore */ DECL_HANDLER(release_semaphore) { - req->prev_count = release_semaphore( req->handle, req->count ); + reply->prev_count = release_semaphore( req->handle, req->count ); } diff --git a/server/serial.c b/server/serial.c index c16ccd78e9a..da682bfeac4 100644 --- a/server/serial.c +++ b/server/serial.c @@ -37,7 +37,7 @@ static void serial_dump( struct object *obj, int verbose ); static int serial_get_fd( struct object *obj ); -static int serial_get_info( struct object *obj, struct get_file_info_request *req ); +static int serial_get_info( struct object *obj, struct get_file_info_reply *reply ); static int serial_get_poll_events( struct object *obj ); struct serial @@ -165,23 +165,23 @@ static int serial_get_fd( struct object *obj ) return serial->obj.fd; } -static int serial_get_info( struct object *obj, struct get_file_info_request *req ) +static int serial_get_info( struct object *obj, struct get_file_info_reply *reply ) { struct serial *serial = (struct serial *) obj; assert( obj->ops == &serial_ops ); - if (req) + if (reply) { - req->type = FILE_TYPE_CHAR; - req->attr = 0; - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_CHAR; + reply->attr = 0; + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } if(serial->attrib & FILE_FLAG_OVERLAPPED) @@ -215,10 +215,10 @@ DECL_HANDLER(create_serial) { struct serial *serial; - req->handle = 0; - if ((serial = create_serial( get_req_data(req), get_req_data_size(req), req->access, req->attributes ))) + reply->handle = 0; + if ((serial = create_serial( get_req_data(), get_req_data_size(), req->access, req->attributes ))) { - req->handle = alloc_handle( current->process, serial, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, serial, req->access, req->inherit ); release_object( serial ); } } @@ -230,17 +230,17 @@ DECL_HANDLER(get_serial_info) if ((serial = get_serial_obj( current->process, req->handle, 0 ))) { /* timeouts */ - req->readinterval = serial->readinterval; - req->readconst = serial->readconst; - req->readmult = serial->readmult; - req->writeconst = serial->writeconst; - req->writemult = serial->writemult; + reply->readinterval = serial->readinterval; + reply->readconst = serial->readconst; + reply->readmult = serial->readmult; + reply->writeconst = serial->writeconst; + reply->writemult = serial->writemult; /* event mask */ - req->eventmask = serial->eventmask; + reply->eventmask = serial->eventmask; /* comm port error status */ - req->commerror = serial->commerror; + reply->commerror = serial->commerror; release_object( serial ); } diff --git a/server/snapshot.c b/server/snapshot.c index 48654fa1101..1d73873e899 100644 --- a/server/snapshot.c +++ b/server/snapshot.c @@ -94,7 +94,7 @@ static struct snapshot *create_snapshot( void *pid, int flags ) } /* get the next process in the snapshot */ -static int snapshot_next_process( struct snapshot *snapshot, struct next_process_request *req ) +static int snapshot_next_process( struct snapshot *snapshot, struct next_process_reply *reply ) { struct process_snapshot *ptr; @@ -103,22 +103,21 @@ static int snapshot_next_process( struct snapshot *snapshot, struct next_process set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ return 0; } - if (req->reset) snapshot->process_pos = 0; - else if (snapshot->process_pos >= snapshot->process_count) + if (snapshot->process_pos >= snapshot->process_count) { set_error( STATUS_NO_MORE_FILES ); return 0; } ptr = &snapshot->processes[snapshot->process_pos++]; - req->count = ptr->count; - req->pid = get_process_id( ptr->process ); - req->threads = ptr->threads; - req->priority = ptr->priority; + reply->count = ptr->count; + reply->pid = get_process_id( ptr->process ); + reply->threads = ptr->threads; + reply->priority = ptr->priority; return 1; } /* get the next thread in the snapshot */ -static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_request *req ) +static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_reply *reply ) { struct thread_snapshot *ptr; @@ -127,23 +126,22 @@ static int snapshot_next_thread( struct snapshot *snapshot, struct next_thread_r set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ return 0; } - if (req->reset) snapshot->thread_pos = 0; - else if (snapshot->thread_pos >= snapshot->thread_count) + if (snapshot->thread_pos >= snapshot->thread_count) { set_error( STATUS_NO_MORE_FILES ); return 0; } ptr = &snapshot->threads[snapshot->thread_pos++]; - req->count = ptr->count; - req->pid = get_process_id( ptr->thread->process ); - req->tid = get_thread_id( ptr->thread ); - req->base_pri = ptr->priority; - req->delta_pri = 0; /* FIXME */ + reply->count = ptr->count; + reply->pid = get_process_id( ptr->thread->process ); + reply->tid = get_thread_id( ptr->thread ); + reply->base_pri = ptr->priority; + reply->delta_pri = 0; /* FIXME */ return 1; } /* get the next module in the snapshot */ -static int snapshot_next_module( struct snapshot *snapshot, struct next_module_request *req ) +static int snapshot_next_module( struct snapshot *snapshot, struct next_module_reply *reply ) { struct module_snapshot *ptr; @@ -152,15 +150,14 @@ static int snapshot_next_module( struct snapshot *snapshot, struct next_module_r set_error( STATUS_INVALID_PARAMETER ); /* FIXME */ return 0; } - if (req->reset) snapshot->module_pos = 0; - else if (snapshot->module_pos >= snapshot->module_count) + if (snapshot->module_pos >= snapshot->module_count) { set_error( STATUS_NO_MORE_FILES ); return 0; } ptr = &snapshot->modules[snapshot->module_pos++]; - req->pid = get_process_id( snapshot->process ); - req->base = ptr->base; + reply->pid = get_process_id( snapshot->process ); + reply->base = ptr->base; return 1; } @@ -198,10 +195,10 @@ DECL_HANDLER(create_snapshot) { struct snapshot *snapshot; - req->handle = 0; + reply->handle = 0; if ((snapshot = create_snapshot( req->pid, req->flags ))) { - req->handle = alloc_handle( current->process, snapshot, 0, req->inherit ); + reply->handle = alloc_handle( current->process, snapshot, 0, req->inherit ); release_object( snapshot ); } } @@ -214,7 +211,8 @@ DECL_HANDLER(next_process) if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, 0, &snapshot_ops ))) { - snapshot_next_process( snapshot, req ); + if (req->reset) snapshot->process_pos = 0; + snapshot_next_process( snapshot, reply ); release_object( snapshot ); } } @@ -227,7 +225,8 @@ DECL_HANDLER(next_thread) if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, 0, &snapshot_ops ))) { - snapshot_next_thread( snapshot, req ); + if (req->reset) snapshot->thread_pos = 0; + snapshot_next_thread( snapshot, reply ); release_object( snapshot ); } } @@ -240,7 +239,8 @@ DECL_HANDLER(next_module) if ((snapshot = (struct snapshot *)get_handle_obj( current->process, req->handle, 0, &snapshot_ops ))) { - snapshot_next_module( snapshot, req ); + if (req->reset) snapshot->module_pos = 0; + snapshot_next_module( snapshot, reply ); release_object( snapshot ); } } diff --git a/server/sock.c b/server/sock.c index 07810559c67..a18dc6ef5ac 100644 --- a/server/sock.c +++ b/server/sock.c @@ -59,7 +59,7 @@ static int sock_signaled( struct object *obj, struct thread *thread ); static int sock_get_poll_events( struct object *obj ); static void sock_poll_event( struct object *obj, int event ); static int sock_get_fd( struct object *obj ); -static int sock_get_info( struct object *obj, struct get_file_info_request *req ); +static int sock_get_info( struct object *obj, struct get_file_info_reply *reply ); static void sock_destroy( struct object *obj ); static int sock_get_error( int err ); static void sock_set_error(void); @@ -272,20 +272,20 @@ static int sock_get_fd( struct object *obj ) return sock->obj.fd; } -static int sock_get_info( struct object *obj, struct get_file_info_request *req ) +static int sock_get_info( struct object *obj, struct get_file_info_reply *reply ) { - if (req) + if (reply) { - req->type = FILE_TYPE_PIPE; - req->attr = 0; - req->access_time = 0; - req->write_time = 0; - req->size_high = 0; - req->size_low = 0; - req->links = 0; - req->index_high = 0; - req->index_low = 0; - req->serial = 0; + reply->type = FILE_TYPE_PIPE; + reply->attr = 0; + reply->access_time = 0; + reply->write_time = 0; + reply->size_high = 0; + reply->size_low = 0; + reply->links = 0; + reply->index_high = 0; + reply->index_low = 0; + reply->serial = 0; } return FD_TYPE_DEFAULT; } @@ -461,10 +461,10 @@ DECL_HANDLER(create_socket) { struct object *obj; - req->handle = 0; + reply->handle = 0; if ((obj = create_socket( req->family, req->type, req->protocol )) != NULL) { - req->handle = alloc_handle( current->process, obj, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, obj, req->access, req->inherit ); release_object( obj ); } } @@ -474,10 +474,10 @@ DECL_HANDLER(accept_socket) { struct object *obj; - req->handle = 0; + reply->handle = 0; if ((obj = accept_socket( req->lhandle )) != NULL) { - req->handle = alloc_handle( current->process, obj, req->access, req->inherit ); + reply->handle = alloc_handle( current->process, obj, req->access, req->inherit ); release_object( obj ); } } @@ -525,34 +525,31 @@ DECL_HANDLER(set_socket_event) DECL_HANDLER(get_socket_event) { struct sock *sock; - size_t size; sock=(struct sock*)get_handle_obj(current->process,req->handle,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE,&sock_ops); if (!sock) { - req->mask = 0; - req->pmask = 0; - req->state = 0; - set_error(WSAENOTSOCK); - return; + reply->mask = 0; + reply->pmask = 0; + reply->state = 0; + set_error( WSAENOTSOCK ); + return; } - req->mask = sock->mask; - req->pmask = sock->pmask; - req->state = sock->state; - size = min( get_req_data_size(req), sizeof(sock->errors) ); - memcpy( get_req_data(req), sock->errors, size ); - set_req_data_size( req, size ); + reply->mask = sock->mask; + reply->pmask = sock->pmask; + reply->state = sock->state; + set_reply_data( sock->errors, min( get_reply_max_size(), sizeof(sock->errors) )); if (req->service) { - if (req->s_event) + handle_t s_event = req->s_event; + if (s_event) { struct event *sevent = get_event_obj(current->process, req->s_event, 0); - if (sevent == sock->event) - req->s_event = 0; + if (sevent == sock->event) s_event = 0; release_object( sevent ); } - if (!req->s_event) + if (!s_event) { if (req->c_event) { diff --git a/server/thread.c b/server/thread.c index 8382229c0da..c568750cd50 100644 --- a/server/thread.c +++ b/server/thread.c @@ -14,9 +14,6 @@ #include #include #include -#ifdef HAVE_SYS_MMAN_H -#include -#endif #include #include #include @@ -104,7 +101,10 @@ inline static void init_thread_structure( struct thread *thread ) thread->user_apc.head = NULL; thread->user_apc.tail = NULL; thread->error = 0; - thread->request_fd = NULL; + thread->req_data = NULL; + thread->req_toread = 0; + thread->reply_data = NULL; + thread->reply_towrite = 0; thread->reply_fd = -1; thread->wait_fd = -1; thread->state = RUNNING; @@ -115,7 +115,6 @@ inline static void init_thread_structure( struct thread *thread ) thread->priority = THREAD_PRIORITY_NORMAL; thread->affinity = 1; thread->suspend = 0; - thread->buffer = (void *)-1; for (i = 0; i < MAX_INFLIGHT_FDS; i++) thread->inflight[i].server = thread->inflight[i].client = -1; @@ -131,6 +130,7 @@ struct thread *create_thread( int fd, struct process *process ) init_thread_structure( thread ); thread->process = (struct process *)grab_object( process ); + thread->request_fd = fd; if (!current) current = thread; if (!booting_thread) /* first thread ever */ @@ -142,7 +142,6 @@ struct thread *create_thread( int fd, struct process *process ) if ((thread->next = first_thread) != NULL) thread->next->prev = thread; first_thread = thread; - fcntl( fd, F_SETFL, O_NONBLOCK ); set_select_events( &thread->obj, POLLIN ); /* start listening to events */ add_process_thread( thread->process, thread ); return thread; @@ -156,6 +155,7 @@ static void thread_poll_event( struct object *obj, int event ) if (event & (POLLERR | POLLHUP)) kill_thread( thread, 0 ); else if (event & POLLIN) read_request( thread ); + else if (event & POLLOUT) write_reply( thread ); } /* cleanup everything that is no longer needed by a dead thread */ @@ -166,10 +166,11 @@ static void cleanup_thread( struct thread *thread ) struct thread_apc *apc; while ((apc = thread_dequeue_apc( thread, 0 ))) free( apc ); - if (thread->buffer != (void *)-1) munmap( thread->buffer, MAX_REQUEST_LENGTH ); + if (thread->req_data) free( thread->req_data ); + if (thread->reply_data) free( thread->reply_data ); + if (thread->request_fd != -1) close( thread->request_fd ); if (thread->reply_fd != -1) close( thread->reply_fd ); if (thread->wait_fd != -1) close( thread->wait_fd ); - if (thread->request_fd) release_object( thread->request_fd ); if (thread->queue) { if (thread->process->queue == thread->queue) @@ -189,10 +190,11 @@ static void cleanup_thread( struct thread *thread ) thread->inflight[i].client = thread->inflight[i].server = -1; } } - thread->buffer = (void *)-1; + thread->req_data = NULL; + thread->reply_data = NULL; + thread->request_fd = -1; thread->reply_fd = -1; thread->wait_fd = -1; - thread->request_fd = NULL; } /* destroy a thread when its refcount is 0 */ @@ -255,7 +257,7 @@ struct thread *get_thread_from_pid( int pid ) /* set all information about a thread */ static void set_thread_info( struct thread *thread, - struct set_thread_info_request *req ) + const struct set_thread_info_request *req ) { if (req->mask & SET_THREAD_INFO_PRIORITY) thread->priority = req->priority; @@ -467,7 +469,8 @@ static void thread_timeout( void *ptr ) } /* select on a list of handles */ -static void select_on( int count, void *cookie, handle_t *handles, int flags, int sec, int usec ) +static void select_on( int count, void *cookie, const handle_t *handles, + int flags, int sec, int usec ) { int ret, i; struct object *objects[MAXIMUM_WAIT_OBJECTS]; @@ -700,6 +703,8 @@ void kill_thread( struct thread *thread, int violent_death ) remove_process_thread( thread->process, thread ); wake_up( &thread->obj, 0 ); detach_thread( thread, violent_death ? SIGTERM : 0 ); + if (thread->request_fd == thread->obj.fd) thread->request_fd = -1; + if (thread->reply_fd == thread->obj.fd) thread->reply_fd = -1; remove_select_user( &thread->obj ); cleanup_thread( thread ); release_object( thread ); @@ -746,8 +751,9 @@ DECL_HANDLER(new_thread) struct thread *thread; int request_fd = thread_get_inflight_fd( current, req->request_fd ); - if (request_fd == -1) + if (request_fd == -1 || fcntl( request_fd, F_SETFL, O_NONBLOCK ) == -1) { + if (request_fd != -1) close( request_fd ); set_error( STATUS_INVALID_HANDLE ); return; } @@ -755,9 +761,9 @@ DECL_HANDLER(new_thread) if ((thread = create_thread( request_fd, current->process ))) { if (req->suspend) thread->suspend++; - req->tid = thread; - if ((req->handle = alloc_handle( current->process, thread, - THREAD_ALL_ACCESS, req->inherit ))) + reply->tid = thread; + if ((reply->handle = alloc_handle( current->process, thread, + THREAD_ALL_ACCESS, req->inherit ))) { /* thread object will be released when the thread gets killed */ return; @@ -778,7 +784,7 @@ DECL_HANDLER(init_thread) fatal_protocol_error( current, "init_thread: already running\n" ); goto error; } - if (reply_fd == -1) + if (reply_fd == -1 || fcntl( reply_fd, F_SETFL, O_NONBLOCK ) == -1) { fatal_protocol_error( current, "bad reply fd\n" ); goto error; @@ -798,10 +804,10 @@ DECL_HANDLER(init_thread) if (current->process->running_threads > 1) generate_debug_event( current, CREATE_THREAD_DEBUG_EVENT, req->entry ); - req->pid = get_process_id( current->process ); - req->tid = get_thread_id( current ); - req->boot = (current == booting_thread); - req->version = SERVER_PROTOCOL_VERSION; + reply->pid = get_process_id( current->process ); + reply->tid = get_thread_id( current ); + reply->boot = (current == booting_thread); + reply->version = SERVER_PROTOCOL_VERSION; return; error: @@ -809,52 +815,21 @@ DECL_HANDLER(init_thread) if (wait_fd != -1) close( wait_fd ); } -/* set the shared buffer for a thread */ -DECL_HANDLER(set_thread_buffer) -{ - const unsigned int size = MAX_REQUEST_LENGTH; - const unsigned int offset = 0; - int fd = thread_get_inflight_fd( current, req->fd ); - - req->size = size; - req->offset = offset; - - if (fd != -1) - { - static const char zero; - - /* grow the file to the requested size */ - if (lseek( fd, size - 1, SEEK_SET ) != -1 && write( fd, &zero, 1 ) == 1) - { - void *buffer = mmap( 0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset ); - if (buffer == (void *)-1) file_set_error(); - else - { - if (current->buffer != (void *)-1) munmap( current->buffer, size ); - current->buffer = buffer; - } - } - else file_set_error(); - close( fd ); - } - else set_error( STATUS_INVALID_HANDLE ); -} - /* terminate a thread */ DECL_HANDLER(terminate_thread) { struct thread *thread; - req->self = 0; - req->last = 0; + reply->self = 0; + reply->last = 0; if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE ))) { thread->exit_code = req->exit_code; if (thread != current) kill_thread( thread, 1 ); else { - req->self = 1; - req->last = (thread->process->running_threads == 1); + reply->self = 1; + reply->last = (thread->process->running_threads == 1); } release_object( thread ); } @@ -871,10 +846,10 @@ DECL_HANDLER(get_thread_info) if (thread) { - req->tid = get_thread_id( thread ); - req->teb = thread->teb; - req->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE; - req->priority = thread->priority; + reply->tid = get_thread_id( thread ); + reply->teb = thread->teb; + reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE; + reply->priority = thread->priority; release_object( thread ); } } @@ -898,7 +873,7 @@ DECL_HANDLER(suspend_thread) if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) { - req->count = suspend_thread( thread, 1 ); + reply->count = suspend_thread( thread, 1 ); release_object( thread ); } } @@ -910,7 +885,7 @@ DECL_HANDLER(resume_thread) if ((thread = get_thread_from_handle( req->handle, THREAD_SUSPEND_RESUME ))) { - req->count = resume_thread( thread ); + reply->count = resume_thread( thread ); release_object( thread ); } } @@ -918,8 +893,8 @@ DECL_HANDLER(resume_thread) /* select on a handle list */ DECL_HANDLER(select) { - int count = get_req_data_size(req) / sizeof(int); - select_on( count, req->cookie, get_req_data(req), req->flags, req->sec, req->usec ); + int count = get_req_data_size() / sizeof(int); + select_on( count, req->cookie, get_req_data(), req->flags, req->sec, req->usec ); } /* queue an APC for a thread */ @@ -944,9 +919,8 @@ DECL_HANDLER(get_apc) if (!(apc = thread_dequeue_apc( current, !req->alertable ))) { /* no more APCs */ - req->func = NULL; - req->type = APC_NONE; - set_req_data_size( req, 0 ); + reply->func = NULL; + reply->type = APC_NONE; return; } /* Optimization: ignore APCs that have a NULL func; they are only used @@ -956,11 +930,10 @@ DECL_HANDLER(get_apc) free( apc ); } size = apc->nb_args * sizeof(apc->args[0]); - if (size > get_req_data_size(req)) size = get_req_data_size(req); - req->func = apc->func; - req->type = apc->type; - memcpy( get_req_data(req), apc->args, size ); - set_req_data_size( req, size ); + if (size > get_reply_max_size()) size = get_reply_max_size(); + reply->func = apc->func; + reply->type = apc->type; + set_reply_data( apc->args, size ); free( apc ); } @@ -970,7 +943,7 @@ DECL_HANDLER(get_selector_entry) struct thread *thread; if ((thread = get_thread_from_handle( req->handle, THREAD_QUERY_INFORMATION ))) { - get_selector_entry( thread, req->entry, &req->base, &req->limit, &req->flags ); + get_selector_entry( thread, req->entry, &reply->base, &reply->limit, &reply->flags ); release_object( thread ); } } diff --git a/server/thread.h b/server/thread.h index 8e88a9db562..d6e777979e3 100644 --- a/server/thread.h +++ b/server/thread.h @@ -42,35 +42,40 @@ struct inflight_fd struct thread { - struct object obj; /* object header */ - struct thread *next; /* system-wide thread list */ - struct thread *prev; - struct thread *proc_next; /* per-process thread list */ - struct thread *proc_prev; - struct process *process; - struct mutex *mutex; /* list of currently owned mutexes */ - struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */ - struct debug_event *debug_event; /* debug event being sent to debugger */ - struct msg_queue *queue; /* message queue */ - struct startup_info*info; /* startup info for child process */ - struct thread_wait *wait; /* current wait condition if sleeping */ - struct apc_queue system_apc; /* queue of system async procedure calls */ - struct apc_queue user_apc; /* queue of user async procedure calls */ - struct inflight_fd inflight[MAX_INFLIGHT_FDS]; /* fds currently in flight */ - unsigned int error; /* current error code */ - struct object *request_fd; /* fd for receiving client requests */ - int reply_fd; /* fd to send a reply to a client */ - int wait_fd; /* fd to use to wake a sleeping client */ - enum run_state state; /* running state */ - int attached; /* is thread attached with ptrace? */ - int exit_code; /* thread exit code */ - int unix_pid; /* Unix pid of client */ - CONTEXT *context; /* current context if in an exception handler */ - void *teb; /* TEB address (in client address space) */ - int priority; /* priority level */ - int affinity; /* affinity mask */ - int suspend; /* suspend count */ - void *buffer; /* buffer for communication with the client */ + struct object obj; /* object header */ + struct thread *next; /* system-wide thread list */ + struct thread *prev; + struct thread *proc_next; /* per-process thread list */ + struct thread *proc_prev; + struct process *process; + struct mutex *mutex; /* list of currently owned mutexes */ + struct debug_ctx *debug_ctx; /* debugger context if this thread is a debugger */ + struct debug_event *debug_event; /* debug event being sent to debugger */ + struct msg_queue *queue; /* message queue */ + struct startup_info *info; /* startup info for child process */ + struct thread_wait *wait; /* current wait condition if sleeping */ + struct apc_queue system_apc; /* queue of system async procedure calls */ + struct apc_queue user_apc; /* queue of user async procedure calls */ + struct inflight_fd inflight[MAX_INFLIGHT_FDS]; /* fds currently in flight */ + unsigned int error; /* current error code */ + union generic_request req; /* current request */ + void *req_data; /* variable-size data for request */ + unsigned int req_toread; /* amount of data still to read in request */ + void *reply_data; /* variable-size data for reply */ + unsigned int reply_size; /* size of reply data */ + unsigned int reply_towrite; /* amount of data still to write in reply */ + int request_fd; /* fd for receiving client requests */ + int reply_fd; /* fd to send a reply to a client */ + int wait_fd; /* fd to use to wake a sleeping client */ + enum run_state state; /* running state */ + int attached; /* is thread attached with ptrace? */ + int exit_code; /* thread exit code */ + int unix_pid; /* Unix pid of client */ + CONTEXT *context; /* current context if in an exception handler */ + void *teb; /* TEB address (in client address space) */ + int priority; /* priority level */ + int affinity; /* affinity mask */ + int suspend; /* suspend count */ }; struct thread_snapshot diff --git a/server/timer.c b/server/timer.c index a76ce414e08..fd9604af4c9 100644 --- a/server/timer.c +++ b/server/timer.c @@ -174,10 +174,10 @@ DECL_HANDLER(create_timer) { struct timer *timer; - req->handle = 0; - if ((timer = create_timer( get_req_data(req), get_req_data_size(req), req->manual ))) + reply->handle = 0; + if ((timer = create_timer( get_req_data(), get_req_data_size(), req->manual ))) { - req->handle = alloc_handle( current->process, timer, TIMER_ALL_ACCESS, req->inherit ); + reply->handle = alloc_handle( current->process, timer, TIMER_ALL_ACCESS, req->inherit ); release_object( timer ); } } @@ -185,8 +185,8 @@ DECL_HANDLER(create_timer) /* open a handle to a timer */ DECL_HANDLER(open_timer) { - req->handle = open_object( get_req_data(req), get_req_data_size(req), - &timer_ops, req->access, req->inherit ); + reply->handle = open_object( get_req_data(), get_req_data_size(), + &timer_ops, req->access, req->inherit ); } /* set a waitable timer */ diff --git a/server/trace.c b/server/trace.c index df4617a313a..f5098cb310a 100644 --- a/server/trace.c +++ b/server/trace.c @@ -18,17 +18,15 @@ #include "unicode.h" static int cur_pos; +static const void *cur_data; +static int cur_size; /* utility functions */ -static const void *get_data( const void *req ) +inline static void remove_data( size_t size ) { - return (char *)get_req_data(req) + cur_pos; -} - -static size_t get_size( const void *req ) -{ - return get_req_data_size(req) - cur_pos; + cur_data = (const char *)cur_data + size; + cur_size -= size; } static void dump_uints( const int *ptr, int len ) @@ -42,12 +40,19 @@ static void dump_uints( const int *ptr, int len ) fputc( '}', stderr ); } -static void dump_rectangle( const void *req, const rectangle_t *rect ) +static void dump_rectangle( const rectangle_t *rect ) { fprintf( stderr, "{%d,%d;%d,%d}", rect->left, rect->top, rect->right, rect->bottom ); } +static void dump_char_info( const char_info_t *info ) +{ + fprintf( stderr, "{'" ); + dump_strW( &info->ch, 1, stderr, "\'\'" ); + fprintf( stderr, "',%04x}", info->attr ); +} + static void dump_context( const CONTEXT *context ) { #ifdef __i386__ @@ -80,10 +85,10 @@ static void dump_exc_record( const EXCEPTION_RECORD *rec ) fputc( '}', stderr ); } -static size_t dump_varargs_ints( const void *req ) +static void dump_varargs_ints( size_t size ) { - const int *data = get_data(req); - size_t len = get_size(req) / sizeof(*data); + const int *data = cur_data; + size_t len = size / sizeof(*data); fputc( '{', stderr ); while (len > 0) @@ -92,13 +97,13 @@ static size_t dump_varargs_ints( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_handles( const void *req ) +static void dump_varargs_handles( size_t size ) { - const handle_t *data = get_data(req); - size_t len = get_size(req) / sizeof(*data); + const handle_t *data = cur_data; + size_t len = size / sizeof(*data); fputc( '{', stderr ); while (len > 0) @@ -107,13 +112,13 @@ static size_t dump_varargs_handles( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_ptrs( const void *req ) +static void dump_varargs_ptrs( size_t size ) { - void * const *data = get_data(req); - size_t len = get_size(req) / sizeof(*data); + void * const *data = cur_data; + size_t len = size / sizeof(*data); fputc( '{', stderr ); while (len > 0) @@ -122,13 +127,13 @@ static size_t dump_varargs_ptrs( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_user_handles( const void *req ) +static void dump_varargs_user_handles( size_t size ) { - const user_handle_t *data = get_data(req); - size_t len = get_size(req) / sizeof(*data); + const user_handle_t *data = cur_data; + size_t len = size / sizeof(*data); fputc( '{', stderr ); while (len > 0) @@ -137,13 +142,13 @@ static size_t dump_varargs_user_handles( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_bytes( const void *req ) +static void dump_varargs_bytes( size_t size ) { - const unsigned char *data = get_data(req); - size_t len = get_size(req); + const unsigned char *data = cur_data; + size_t len = size; fputc( '{', stderr ); while (len > 0) @@ -152,59 +157,48 @@ static size_t dump_varargs_bytes( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_string( const void *req ) +static void dump_varargs_string( size_t size ) { - fprintf( stderr, "\"%.*s\"", (int)get_size(req), (char *)get_data(req) ); - return get_size(req); + fprintf( stderr, "\"%.*s\"", (int)size, (char *)cur_data ); + remove_data( size ); } -static size_t dump_varargs_unicode_len_str( const void *req ) -{ - const WCHAR *str = get_data(req); - int len = *str++ + sizeof(WCHAR); - len = min( len, get_size(req) ); - fprintf( stderr, "L\"" ); - if (len >= sizeof(WCHAR)) dump_strW( str, (len / sizeof(WCHAR)) - 1, stderr, "\"\"" ); - fputc( '\"', stderr ); - return len; -} - -static size_t dump_varargs_unicode_str( const void *req ) +static void dump_varargs_unicode_str( size_t size ) { fprintf( stderr, "L\"" ); - dump_strW( get_data(req), get_size(req) / sizeof(WCHAR), stderr, "\"\"" ); + dump_strW( cur_data, size / sizeof(WCHAR), stderr, "\"\"" ); fputc( '\"', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_context( const void *req ) +static void dump_varargs_context( size_t size ) { - dump_context( get_data(req) ); - return get_size(req); + dump_context( cur_data ); + remove_data( size ); } -static size_t dump_varargs_exc_event( const void *req ) +static void dump_varargs_exc_event( size_t size ) { - const CONTEXT *ptr = get_data(req); + const CONTEXT *ptr = cur_data; fprintf( stderr, "{context=" ); dump_context( ptr ); fprintf( stderr, ",rec=" ); dump_exc_record( (EXCEPTION_RECORD *)(ptr + 1) ); fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_debug_event( const void *req ) +static void dump_varargs_debug_event( size_t size ) { - const debug_event_t *event = get_data(req); + const debug_event_t *event = cur_data; - if (!get_size(req)) + if (!size) { fprintf( stderr, "{}" ); - return 0; + return; } switch(event->code) { @@ -258,13 +252,13 @@ static size_t dump_varargs_debug_event( const void *req ) fprintf( stderr, "{code=??? (%d)}", event->code ); break; } - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_input_records( const void *req ) +static void dump_varargs_input_records( size_t size ) { - const INPUT_RECORD *rec = get_data(req); - size_t len = get_size(req) / sizeof(*rec); + const INPUT_RECORD *rec = cur_data; + size_t len = size / sizeof(*rec); fputc( '{', stderr ); while (len > 0) @@ -274,13 +268,13 @@ static size_t dump_varargs_input_records( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } -static size_t dump_varargs_properties( const void *req ) +static void dump_varargs_properties( size_t size ) { - const property_data_t *prop = get_data(req); - size_t len = get_size(req) / sizeof(*prop); + const property_data_t *prop = cur_data; + size_t len = size / sizeof(*prop); fputc( '{', stderr ); while (len > 0) @@ -291,7 +285,7 @@ static size_t dump_varargs_properties( const void *req ) if (--len) fputc( ',', stderr ); } fputc( '}', stderr ); - return get_size(req); + remove_data( size ); } typedef void (*dump_func)( const void *req ); @@ -310,10 +304,10 @@ static void dump_new_process_request( const struct new_process_request *req ) fprintf( stderr, " hstderr=%d,", req->hstderr ); fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } -static void dump_new_process_reply( const struct new_process_request *req ) +static void dump_new_process_reply( const struct new_process_reply *req ) { fprintf( stderr, " info=%d", req->info ); } @@ -325,7 +319,7 @@ static void dump_get_new_process_info_request( const struct get_new_process_info fprintf( stderr, " tinherit=%d", req->tinherit ); } -static void dump_get_new_process_info_reply( const struct get_new_process_info_request *req ) +static void dump_get_new_process_info_reply( const struct get_new_process_info_reply *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " phandle=%d,", req->phandle ); @@ -341,7 +335,7 @@ static void dump_new_thread_request( const struct new_thread_request *req ) fprintf( stderr, " request_fd=%d", req->request_fd ); } -static void dump_new_thread_reply( const struct new_thread_request *req ) +static void dump_new_thread_reply( const struct new_thread_reply *req ) { fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " handle=%d", req->handle ); @@ -358,7 +352,7 @@ static void dump_init_process_request( const struct init_process_request *req ) fprintf( stderr, " ppid=%d", req->ppid ); } -static void dump_init_process_reply( const struct init_process_request *req ) +static void dump_init_process_reply( const struct init_process_reply *req ) { fprintf( stderr, " create_flags=%d,", req->create_flags ); fprintf( stderr, " start_flags=%d,", req->start_flags ); @@ -369,7 +363,7 @@ static void dump_init_process_reply( const struct init_process_request *req ) fprintf( stderr, " hstderr=%d,", req->hstderr ); fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } static void dump_init_process_done_request( const struct init_process_done_request *req ) @@ -381,7 +375,7 @@ static void dump_init_process_done_request( const struct init_process_done_reque fprintf( stderr, " gui=%d", req->gui ); } -static void dump_init_process_done_reply( const struct init_process_done_request *req ) +static void dump_init_process_done_reply( const struct init_process_done_reply *req ) { fprintf( stderr, " debugged=%d", req->debugged ); } @@ -395,7 +389,7 @@ static void dump_init_thread_request( const struct init_thread_request *req ) fprintf( stderr, " wait_fd=%d", req->wait_fd ); } -static void dump_init_thread_reply( const struct init_thread_request *req ) +static void dump_init_thread_reply( const struct init_thread_reply *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " tid=%p,", req->tid ); @@ -403,24 +397,13 @@ static void dump_init_thread_reply( const struct init_thread_request *req ) fprintf( stderr, " version=%d", req->version ); } -static void dump_set_thread_buffer_request( const struct set_thread_buffer_request *req ) -{ - fprintf( stderr, " fd=%d", req->fd ); -} - -static void dump_set_thread_buffer_reply( const struct set_thread_buffer_request *req ) -{ - fprintf( stderr, " offset=%08x,", req->offset ); - fprintf( stderr, " size=%08x", req->size ); -} - static void dump_terminate_process_request( const struct terminate_process_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " exit_code=%d", req->exit_code ); } -static void dump_terminate_process_reply( const struct terminate_process_request *req ) +static void dump_terminate_process_reply( const struct terminate_process_reply *req ) { fprintf( stderr, " self=%d", req->self ); } @@ -431,7 +414,7 @@ static void dump_terminate_thread_request( const struct terminate_thread_request fprintf( stderr, " exit_code=%d", req->exit_code ); } -static void dump_terminate_thread_reply( const struct terminate_thread_request *req ) +static void dump_terminate_thread_reply( const struct terminate_thread_reply *req ) { fprintf( stderr, " self=%d,", req->self ); fprintf( stderr, " last=%d", req->last ); @@ -442,7 +425,7 @@ static void dump_get_process_info_request( const struct get_process_info_request fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_process_info_reply( const struct get_process_info_request *req ) +static void dump_get_process_info_reply( const struct get_process_info_reply *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " debugged=%d,", req->debugged ); @@ -466,7 +449,7 @@ static void dump_get_thread_info_request( const struct get_thread_info_request * fprintf( stderr, " tid_in=%p", req->tid_in ); } -static void dump_get_thread_info_reply( const struct get_thread_info_request *req ) +static void dump_get_thread_info_reply( const struct get_thread_info_reply *req ) { fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " teb=%p,", req->teb ); @@ -487,7 +470,7 @@ static void dump_suspend_thread_request( const struct suspend_thread_request *re fprintf( stderr, " handle=%d", req->handle ); } -static void dump_suspend_thread_reply( const struct suspend_thread_request *req ) +static void dump_suspend_thread_reply( const struct suspend_thread_reply *req ) { fprintf( stderr, " count=%d", req->count ); } @@ -497,7 +480,7 @@ static void dump_resume_thread_request( const struct resume_thread_request *req fprintf( stderr, " handle=%d", req->handle ); } -static void dump_resume_thread_reply( const struct resume_thread_request *req ) +static void dump_resume_thread_reply( const struct resume_thread_reply *req ) { fprintf( stderr, " count=%d", req->count ); } @@ -529,12 +512,12 @@ static void dump_get_apc_request( const struct get_apc_request *req ) fprintf( stderr, " alertable=%d", req->alertable ); } -static void dump_get_apc_reply( const struct get_apc_request *req ) +static void dump_get_apc_reply( const struct get_apc_reply *req ) { fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " args=" ); - cur_pos += dump_varargs_ptrs( req ); + dump_varargs_ptrs( cur_size ); } static void dump_close_handle_request( const struct close_handle_request *req ) @@ -542,7 +525,7 @@ static void dump_close_handle_request( const struct close_handle_request *req ) fprintf( stderr, " handle=%d", req->handle ); } -static void dump_close_handle_reply( const struct close_handle_request *req ) +static void dump_close_handle_reply( const struct close_handle_reply *req ) { fprintf( stderr, " fd=%d", req->fd ); } @@ -555,7 +538,7 @@ static void dump_set_handle_info_request( const struct set_handle_info_request * fprintf( stderr, " fd=%d", req->fd ); } -static void dump_set_handle_info_reply( const struct set_handle_info_request *req ) +static void dump_set_handle_info_reply( const struct set_handle_info_reply *req ) { fprintf( stderr, " old_flags=%d,", req->old_flags ); fprintf( stderr, " cur_fd=%d", req->cur_fd ); @@ -571,7 +554,7 @@ static void dump_dup_handle_request( const struct dup_handle_request *req ) fprintf( stderr, " options=%d", req->options ); } -static void dump_dup_handle_reply( const struct dup_handle_request *req ) +static void dump_dup_handle_reply( const struct dup_handle_reply *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " fd=%d", req->fd ); @@ -584,7 +567,7 @@ static void dump_open_process_request( const struct open_process_request *req ) fprintf( stderr, " inherit=%d", req->inherit ); } -static void dump_open_process_reply( const struct open_process_request *req ) +static void dump_open_process_reply( const struct open_process_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -596,7 +579,7 @@ static void dump_select_request( const struct select_request *req ) fprintf( stderr, " sec=%d,", req->sec ); fprintf( stderr, " usec=%d,", req->usec ); fprintf( stderr, " handles=" ); - cur_pos += dump_varargs_handles( req ); + dump_varargs_handles( cur_size ); } static void dump_create_event_request( const struct create_event_request *req ) @@ -605,10 +588,10 @@ static void dump_create_event_request( const struct create_event_request *req ) fprintf( stderr, " initial_state=%d,", req->initial_state ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_event_reply( const struct create_event_request *req ) +static void dump_create_event_reply( const struct create_event_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -624,10 +607,10 @@ static void dump_open_event_request( const struct open_event_request *req ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_event_reply( const struct open_event_request *req ) +static void dump_open_event_reply( const struct open_event_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -637,10 +620,10 @@ static void dump_create_mutex_request( const struct create_mutex_request *req ) fprintf( stderr, " owned=%d,", req->owned ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_mutex_reply( const struct create_mutex_request *req ) +static void dump_create_mutex_reply( const struct create_mutex_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -655,10 +638,10 @@ static void dump_open_mutex_request( const struct open_mutex_request *req ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_mutex_reply( const struct open_mutex_request *req ) +static void dump_open_mutex_reply( const struct open_mutex_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -669,10 +652,10 @@ static void dump_create_semaphore_request( const struct create_semaphore_request fprintf( stderr, " max=%08x,", req->max ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_semaphore_reply( const struct create_semaphore_request *req ) +static void dump_create_semaphore_reply( const struct create_semaphore_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -683,7 +666,7 @@ static void dump_release_semaphore_request( const struct release_semaphore_reque fprintf( stderr, " count=%08x", req->count ); } -static void dump_release_semaphore_reply( const struct release_semaphore_request *req ) +static void dump_release_semaphore_reply( const struct release_semaphore_reply *req ) { fprintf( stderr, " prev_count=%08x", req->prev_count ); } @@ -693,10 +676,10 @@ static void dump_open_semaphore_request( const struct open_semaphore_request *re fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_semaphore_reply( const struct open_semaphore_request *req ) +static void dump_open_semaphore_reply( const struct open_semaphore_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -710,10 +693,10 @@ static void dump_create_file_request( const struct create_file_request *req ) fprintf( stderr, " attrs=%08x,", req->attrs ); fprintf( stderr, " drive_type=%d,", req->drive_type ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } -static void dump_create_file_reply( const struct create_file_request *req ) +static void dump_create_file_reply( const struct create_file_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -725,7 +708,7 @@ static void dump_alloc_file_handle_request( const struct alloc_file_handle_reque fprintf( stderr, " fd=%d", req->fd ); } -static void dump_alloc_file_handle_reply( const struct alloc_file_handle_request *req ) +static void dump_alloc_file_handle_reply( const struct alloc_file_handle_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -736,7 +719,7 @@ static void dump_get_handle_fd_request( const struct get_handle_fd_request *req fprintf( stderr, " access=%08x", req->access ); } -static void dump_get_handle_fd_reply( const struct get_handle_fd_request *req ) +static void dump_get_handle_fd_reply( const struct get_handle_fd_reply *req ) { fprintf( stderr, " fd=%d,", req->fd ); fprintf( stderr, " type=%d", req->type ); @@ -750,7 +733,7 @@ static void dump_set_file_pointer_request( const struct set_file_pointer_request fprintf( stderr, " whence=%d", req->whence ); } -static void dump_set_file_pointer_reply( const struct set_file_pointer_request *req ) +static void dump_set_file_pointer_reply( const struct set_file_pointer_reply *req ) { fprintf( stderr, " new_low=%d,", req->new_low ); fprintf( stderr, " new_high=%d", req->new_high ); @@ -778,7 +761,7 @@ static void dump_get_file_info_request( const struct get_file_info_request *req fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_file_info_reply( const struct get_file_info_request *req ) +static void dump_get_file_info_reply( const struct get_file_info_reply *req ) { fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " attr=%d,", req->attr ); @@ -815,7 +798,7 @@ static void dump_create_pipe_request( const struct create_pipe_request *req ) fprintf( stderr, " inherit=%d", req->inherit ); } -static void dump_create_pipe_reply( const struct create_pipe_request *req ) +static void dump_create_pipe_reply( const struct create_pipe_reply *req ) { fprintf( stderr, " handle_read=%d,", req->handle_read ); fprintf( stderr, " handle_write=%d", req->handle_write ); @@ -830,7 +813,7 @@ static void dump_create_socket_request( const struct create_socket_request *req fprintf( stderr, " protocol=%d", req->protocol ); } -static void dump_create_socket_reply( const struct create_socket_request *req ) +static void dump_create_socket_reply( const struct create_socket_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -842,7 +825,7 @@ static void dump_accept_socket_request( const struct accept_socket_request *req fprintf( stderr, " inherit=%d", req->inherit ); } -static void dump_accept_socket_reply( const struct accept_socket_request *req ) +static void dump_accept_socket_reply( const struct accept_socket_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -862,13 +845,13 @@ static void dump_get_socket_event_request( const struct get_socket_event_request fprintf( stderr, " c_event=%d", req->c_event ); } -static void dump_get_socket_event_reply( const struct get_socket_event_request *req ) +static void dump_get_socket_event_reply( const struct get_socket_event_reply *req ) { fprintf( stderr, " mask=%08x,", req->mask ); fprintf( stderr, " pmask=%08x,", req->pmask ); fprintf( stderr, " state=%08x,", req->state ); fprintf( stderr, " errors=" ); - cur_pos += dump_varargs_ints( req ); + dump_varargs_ints( cur_size ); } static void dump_enable_socket_event_request( const struct enable_socket_event_request *req ) @@ -886,7 +869,7 @@ static void dump_alloc_console_request( const struct alloc_console_request *req fprintf( stderr, " pid=%p", req->pid ); } -static void dump_alloc_console_reply( const struct alloc_console_request *req ) +static void dump_alloc_console_reply( const struct alloc_console_reply *req ) { fprintf( stderr, " handle_in=%d,", req->handle_in ); fprintf( stderr, " event=%d", req->event ); @@ -901,10 +884,10 @@ static void dump_get_console_renderer_events_request( const struct get_console_r fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_console_renderer_events_reply( const struct get_console_renderer_events_request *req ) +static void dump_get_console_renderer_events_reply( const struct get_console_renderer_events_reply *req ) { fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_open_console_request( const struct open_console_request *req ) @@ -915,7 +898,7 @@ static void dump_open_console_request( const struct open_console_request *req ) fprintf( stderr, " share=%d", req->share ); } -static void dump_open_console_reply( const struct open_console_request *req ) +static void dump_open_console_reply( const struct open_console_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -925,7 +908,7 @@ static void dump_get_console_mode_request( const struct get_console_mode_request fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_console_mode_reply( const struct get_console_mode_request *req ) +static void dump_get_console_mode_reply( const struct get_console_mode_reply *req ) { fprintf( stderr, " mode=%d", req->mode ); } @@ -944,7 +927,7 @@ static void dump_set_console_input_info_request( const struct set_console_input_ fprintf( stderr, " history_mode=%d,", req->history_mode ); fprintf( stderr, " history_size=%d,", req->history_size ); fprintf( stderr, " title=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_get_console_input_info_request( const struct get_console_input_info_request *req ) @@ -952,20 +935,20 @@ static void dump_get_console_input_info_request( const struct get_console_input_ fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_console_input_info_reply( const struct get_console_input_info_request *req ) +static void dump_get_console_input_info_reply( const struct get_console_input_info_reply *req ) { fprintf( stderr, " history_mode=%d,", req->history_mode ); fprintf( stderr, " history_size=%d,", req->history_size ); fprintf( stderr, " history_index=%d,", req->history_index ); fprintf( stderr, " title=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_append_console_input_history_request( const struct append_console_input_history_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " line=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_get_console_input_history_request( const struct get_console_input_history_request *req ) @@ -974,10 +957,11 @@ static void dump_get_console_input_history_request( const struct get_console_inp fprintf( stderr, " index=%d", req->index ); } -static void dump_get_console_input_history_reply( const struct get_console_input_history_request *req ) +static void dump_get_console_input_history_reply( const struct get_console_input_history_reply *req ) { + fprintf( stderr, " total=%d,", req->total ); fprintf( stderr, " line=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_create_console_output_request( const struct create_console_output_request *req ) @@ -988,7 +972,7 @@ static void dump_create_console_output_request( const struct create_console_outp fprintf( stderr, " inherit=%d", req->inherit ); } -static void dump_create_console_output_reply( const struct create_console_output_request *req ) +static void dump_create_console_output_reply( const struct create_console_output_reply *req ) { fprintf( stderr, " handle_out=%d", req->handle_out ); } @@ -1017,7 +1001,7 @@ static void dump_get_console_output_info_request( const struct get_console_outpu fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_console_output_info_reply( const struct get_console_output_info_request *req ) +static void dump_get_console_output_info_reply( const struct get_console_output_info_reply *req ) { fprintf( stderr, " cursor_size=%d,", req->cursor_size ); fprintf( stderr, " cursor_visible=%d,", req->cursor_visible ); @@ -1038,10 +1022,10 @@ static void dump_write_console_input_request( const struct write_console_input_r { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " rec=" ); - cur_pos += dump_varargs_input_records( req ); + dump_varargs_input_records( cur_size ); } -static void dump_write_console_input_reply( const struct write_console_input_request *req ) +static void dump_write_console_input_reply( const struct write_console_input_reply *req ) { fprintf( stderr, " written=%d", req->written ); } @@ -1052,24 +1036,44 @@ static void dump_read_console_input_request( const struct read_console_input_req fprintf( stderr, " flush=%d", req->flush ); } -static void dump_read_console_input_reply( const struct read_console_input_request *req ) +static void dump_read_console_input_reply( const struct read_console_input_reply *req ) { fprintf( stderr, " read=%d,", req->read ); fprintf( stderr, " rec=" ); - cur_pos += dump_varargs_input_records( req ); + dump_varargs_input_records( cur_size ); } static void dump_write_console_output_request( const struct write_console_output_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); - fprintf( stderr, " mode=%d,", req->mode ); fprintf( stderr, " x=%d,", req->x ); fprintf( stderr, " y=%d,", req->y ); + fprintf( stderr, " mode=%d,", req->mode ); + fprintf( stderr, " wrap=%d,", req->wrap ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } -static void dump_write_console_output_reply( const struct write_console_output_request *req ) +static void dump_write_console_output_reply( const struct write_console_output_reply *req ) +{ + fprintf( stderr, " written=%d,", req->written ); + fprintf( stderr, " width=%d,", req->width ); + fprintf( stderr, " height=%d", req->height ); +} + +static void dump_fill_console_output_request( const struct fill_console_output_request *req ) +{ + fprintf( stderr, " handle=%d,", req->handle ); + fprintf( stderr, " x=%d,", req->x ); + fprintf( stderr, " y=%d,", req->y ); + fprintf( stderr, " mode=%d,", req->mode ); + fprintf( stderr, " count=%d,", req->count ); + fprintf( stderr, " wrap=%d,", req->wrap ); + fprintf( stderr, " data=" ); + dump_char_info( &req->data ); +} + +static void dump_fill_console_output_reply( const struct fill_console_output_reply *req ) { fprintf( stderr, " written=%d", req->written ); } @@ -1079,16 +1083,16 @@ static void dump_read_console_output_request( const struct read_console_output_r fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " x=%d,", req->x ); fprintf( stderr, " y=%d,", req->y ); - fprintf( stderr, " w=%d,", req->w ); - fprintf( stderr, " h=%d", req->h ); + fprintf( stderr, " mode=%d,", req->mode ); + fprintf( stderr, " wrap=%d", req->wrap ); } -static void dump_read_console_output_reply( const struct read_console_output_request *req ) +static void dump_read_console_output_reply( const struct read_console_output_reply *req ) { - fprintf( stderr, " eff_w=%d,", req->eff_w ); - fprintf( stderr, " eff_h=%d,", req->eff_h ); + fprintf( stderr, " width=%d,", req->width ); + fprintf( stderr, " height=%d,", req->height ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_move_console_output_request( const struct move_console_output_request *req ) @@ -1108,7 +1112,7 @@ static void dump_create_change_notification_request( const struct create_change_ fprintf( stderr, " filter=%d", req->filter ); } -static void dump_create_change_notification_reply( const struct create_change_notification_request *req ) +static void dump_create_change_notification_reply( const struct create_change_notification_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1121,10 +1125,10 @@ static void dump_create_mapping_request( const struct create_mapping_request *re fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " file_handle=%d,", req->file_handle ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_mapping_reply( const struct create_mapping_request *req ) +static void dump_create_mapping_reply( const struct create_mapping_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1134,10 +1138,10 @@ static void dump_open_mapping_request( const struct open_mapping_request *req ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_mapping_reply( const struct open_mapping_request *req ) +static void dump_open_mapping_reply( const struct open_mapping_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1147,7 +1151,7 @@ static void dump_get_mapping_info_request( const struct get_mapping_info_request fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_mapping_info_reply( const struct get_mapping_info_request *req ) +static void dump_get_mapping_info_reply( const struct get_mapping_info_reply *req ) { fprintf( stderr, " size_high=%d,", req->size_high ); fprintf( stderr, " size_low=%d,", req->size_low ); @@ -1166,7 +1170,7 @@ static void dump_create_device_request( const struct create_device_request *req fprintf( stderr, " id=%d", req->id ); } -static void dump_create_device_reply( const struct create_device_request *req ) +static void dump_create_device_reply( const struct create_device_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1178,7 +1182,7 @@ static void dump_create_snapshot_request( const struct create_snapshot_request * fprintf( stderr, " pid=%p", req->pid ); } -static void dump_create_snapshot_reply( const struct create_snapshot_request *req ) +static void dump_create_snapshot_reply( const struct create_snapshot_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1189,7 +1193,7 @@ static void dump_next_process_request( const struct next_process_request *req ) fprintf( stderr, " reset=%d", req->reset ); } -static void dump_next_process_reply( const struct next_process_request *req ) +static void dump_next_process_reply( const struct next_process_reply *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " pid=%p,", req->pid ); @@ -1203,7 +1207,7 @@ static void dump_next_thread_request( const struct next_thread_request *req ) fprintf( stderr, " reset=%d", req->reset ); } -static void dump_next_thread_reply( const struct next_thread_request *req ) +static void dump_next_thread_reply( const struct next_thread_reply *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " pid=%p,", req->pid ); @@ -1218,7 +1222,7 @@ static void dump_next_module_request( const struct next_module_request *req ) fprintf( stderr, " reset=%d", req->reset ); } -static void dump_next_module_reply( const struct next_module_request *req ) +static void dump_next_module_reply( const struct next_module_reply *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " base=%p", req->base ); @@ -1229,37 +1233,37 @@ static void dump_wait_debug_event_request( const struct wait_debug_event_request fprintf( stderr, " get_handle=%d", req->get_handle ); } -static void dump_wait_debug_event_reply( const struct wait_debug_event_request *req ) +static void dump_wait_debug_event_reply( const struct wait_debug_event_reply *req ) { fprintf( stderr, " pid=%p,", req->pid ); fprintf( stderr, " tid=%p,", req->tid ); fprintf( stderr, " wait=%d,", req->wait ); fprintf( stderr, " event=" ); - cur_pos += dump_varargs_debug_event( req ); + dump_varargs_debug_event( cur_size ); } static void dump_queue_exception_event_request( const struct queue_exception_event_request *req ) { fprintf( stderr, " first=%d,", req->first ); fprintf( stderr, " record=" ); - cur_pos += dump_varargs_exc_event( req ); + dump_varargs_exc_event( cur_size ); } -static void dump_queue_exception_event_reply( const struct queue_exception_event_request *req ) +static void dump_queue_exception_event_reply( const struct queue_exception_event_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } static void dump_get_exception_status_request( const struct get_exception_status_request *req ) { + fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_exception_status_reply( const struct get_exception_status_request *req ) +static void dump_get_exception_status_reply( const struct get_exception_status_reply *req ) { - fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " status=%d,", req->status ); fprintf( stderr, " context=" ); - cur_pos += dump_varargs_context( req ); + dump_varargs_context( cur_size ); } static void dump_output_debug_string_request( const struct output_debug_string_request *req ) @@ -1284,25 +1288,23 @@ static void dump_debug_process_request( const struct debug_process_request *req static void dump_read_process_memory_request( const struct read_process_memory_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); - fprintf( stderr, " addr=%p,", req->addr ); - fprintf( stderr, " len=%d", req->len ); + fprintf( stderr, " addr=%p", req->addr ); } -static void dump_read_process_memory_reply( const struct read_process_memory_request *req ) +static void dump_read_process_memory_reply( const struct read_process_memory_reply *req ) { fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_write_process_memory_request( const struct write_process_memory_request *req ) { fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " addr=%p,", req->addr ); - fprintf( stderr, " len=%d,", req->len ); fprintf( stderr, " first_mask=%08x,", req->first_mask ); fprintf( stderr, " last_mask=%08x,", req->last_mask ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_create_key_request( const struct create_key_request *req ) @@ -1311,14 +1313,15 @@ static void dump_create_key_request( const struct create_key_request *req ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " options=%08x,", req->options ); fprintf( stderr, " modif=%ld,", req->modif ); + fprintf( stderr, " namelen=%d,", req->namelen ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_len_str( req ); + dump_varargs_unicode_str( min(cur_size,req->namelen) ); fputc( ',', stderr ); fprintf( stderr, " class=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_key_reply( const struct create_key_request *req ) +static void dump_create_key_reply( const struct create_key_reply *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " created=%d", req->created ); @@ -1329,10 +1332,10 @@ static void dump_open_key_request( const struct open_key_request *req ) fprintf( stderr, " parent=%d,", req->parent ); fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_key_reply( const struct open_key_request *req ) +static void dump_open_key_reply( const struct open_key_reply *req ) { fprintf( stderr, " hkey=%d", req->hkey ); } @@ -1346,10 +1349,10 @@ static void dump_enum_key_request( const struct enum_key_request *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " index=%d,", req->index ); - fprintf( stderr, " full=%d", req->full ); + fprintf( stderr, " info_class=%d", req->info_class ); } -static void dump_enum_key_reply( const struct enum_key_request *req ) +static void dump_enum_key_reply( const struct enum_key_reply *req ) { fprintf( stderr, " subkeys=%d,", req->subkeys ); fprintf( stderr, " max_subkey=%d,", req->max_subkey ); @@ -1358,65 +1361,66 @@ static void dump_enum_key_reply( const struct enum_key_request *req ) fprintf( stderr, " max_value=%d,", req->max_value ); fprintf( stderr, " max_data=%d,", req->max_data ); fprintf( stderr, " modif=%ld,", req->modif ); + fprintf( stderr, " total=%d,", req->total ); + fprintf( stderr, " namelen=%d,", req->namelen ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_len_str( req ); + dump_varargs_unicode_str( min(cur_size,req->namelen) ); fputc( ',', stderr ); fprintf( stderr, " class=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_set_key_value_request( const struct set_key_value_request *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " type=%d,", req->type ); - fprintf( stderr, " total=%08x,", req->total ); - fprintf( stderr, " offset=%08x,", req->offset ); + fprintf( stderr, " namelen=%d,", req->namelen ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_len_str( req ); + dump_varargs_unicode_str( min(cur_size,req->namelen) ); fputc( ',', stderr ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_get_key_value_request( const struct get_key_value_request *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); - fprintf( stderr, " offset=%08x,", req->offset ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_len_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_get_key_value_reply( const struct get_key_value_request *req ) +static void dump_get_key_value_reply( const struct get_key_value_reply *req ) { fprintf( stderr, " type=%d,", req->type ); - fprintf( stderr, " len=%d,", req->len ); + fprintf( stderr, " total=%d,", req->total ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_enum_key_value_request( const struct enum_key_value_request *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " index=%d,", req->index ); - fprintf( stderr, " offset=%08x", req->offset ); + fprintf( stderr, " info_class=%d", req->info_class ); } -static void dump_enum_key_value_reply( const struct enum_key_value_request *req ) +static void dump_enum_key_value_reply( const struct enum_key_value_reply *req ) { fprintf( stderr, " type=%d,", req->type ); - fprintf( stderr, " len=%d,", req->len ); + fprintf( stderr, " total=%d,", req->total ); + fprintf( stderr, " namelen=%d,", req->namelen ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_len_str( req ); + dump_varargs_unicode_str( min(cur_size,req->namelen) ); fputc( ',', stderr ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_delete_key_value_request( const struct delete_key_value_request *req ) { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_load_registry_request( const struct load_registry_request *req ) @@ -1424,7 +1428,7 @@ static void dump_load_registry_request( const struct load_registry_request *req fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " file=%d,", req->file ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_save_registry_request( const struct save_registry_request *req ) @@ -1437,7 +1441,7 @@ static void dump_save_registry_atexit_request( const struct save_registry_atexit { fprintf( stderr, " hkey=%d,", req->hkey ); fprintf( stderr, " file=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } static void dump_set_registry_levels_request( const struct set_registry_levels_request *req ) @@ -1452,10 +1456,10 @@ static void dump_create_timer_request( const struct create_timer_request *req ) fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " manual=%d,", req->manual ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_create_timer_reply( const struct create_timer_request *req ) +static void dump_create_timer_reply( const struct create_timer_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1465,10 +1469,10 @@ static void dump_open_timer_request( const struct open_timer_request *req ) fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " inherit=%d,", req->inherit ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_open_timer_reply( const struct open_timer_request *req ) +static void dump_open_timer_reply( const struct open_timer_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1494,10 +1498,10 @@ static void dump_get_thread_context_request( const struct get_thread_context_req fprintf( stderr, " flags=%08x", req->flags ); } -static void dump_get_thread_context_reply( const struct get_thread_context_request *req ) +static void dump_get_thread_context_reply( const struct get_thread_context_reply *req ) { fprintf( stderr, " context=" ); - cur_pos += dump_varargs_context( req ); + dump_varargs_context( cur_size ); } static void dump_set_thread_context_request( const struct set_thread_context_request *req ) @@ -1505,7 +1509,7 @@ static void dump_set_thread_context_request( const struct set_thread_context_req fprintf( stderr, " handle=%d,", req->handle ); fprintf( stderr, " flags=%08x,", req->flags ); fprintf( stderr, " context=" ); - cur_pos += dump_varargs_context( req ); + dump_varargs_context( cur_size ); } static void dump_get_selector_entry_request( const struct get_selector_entry_request *req ) @@ -1514,7 +1518,7 @@ static void dump_get_selector_entry_request( const struct get_selector_entry_req fprintf( stderr, " entry=%d", req->entry ); } -static void dump_get_selector_entry_reply( const struct get_selector_entry_request *req ) +static void dump_get_selector_entry_reply( const struct get_selector_entry_reply *req ) { fprintf( stderr, " base=%08x,", req->base ); fprintf( stderr, " limit=%08x,", req->limit ); @@ -1525,10 +1529,10 @@ static void dump_add_atom_request( const struct add_atom_request *req ) { fprintf( stderr, " local=%d,", req->local ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_add_atom_reply( const struct add_atom_request *req ) +static void dump_add_atom_reply( const struct add_atom_reply *req ) { fprintf( stderr, " atom=%04x", req->atom ); } @@ -1543,10 +1547,10 @@ static void dump_find_atom_request( const struct find_atom_request *req ) { fprintf( stderr, " local=%d,", req->local ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } -static void dump_find_atom_reply( const struct find_atom_request *req ) +static void dump_find_atom_reply( const struct find_atom_reply *req ) { fprintf( stderr, " atom=%04x", req->atom ); } @@ -1557,11 +1561,11 @@ static void dump_get_atom_name_request( const struct get_atom_name_request *req fprintf( stderr, " local=%d", req->local ); } -static void dump_get_atom_name_reply( const struct get_atom_name_request *req ) +static void dump_get_atom_name_reply( const struct get_atom_name_reply *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_init_atom_table_request( const struct init_atom_table_request *req ) @@ -1573,7 +1577,7 @@ static void dump_get_msg_queue_request( const struct get_msg_queue_request *req { } -static void dump_get_msg_queue_reply( const struct get_msg_queue_request *req ) +static void dump_get_msg_queue_reply( const struct get_msg_queue_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1585,7 +1589,7 @@ static void dump_set_queue_mask_request( const struct set_queue_mask_request *re fprintf( stderr, " skip_wait=%d", req->skip_wait ); } -static void dump_set_queue_mask_reply( const struct set_queue_mask_request *req ) +static void dump_set_queue_mask_reply( const struct set_queue_mask_reply *req ) { fprintf( stderr, " wake_bits=%08x,", req->wake_bits ); fprintf( stderr, " changed_bits=%08x", req->changed_bits ); @@ -1596,7 +1600,7 @@ static void dump_get_queue_status_request( const struct get_queue_status_request fprintf( stderr, " clear=%d", req->clear ); } -static void dump_get_queue_status_reply( const struct get_queue_status_request *req ) +static void dump_get_queue_status_reply( const struct get_queue_status_reply *req ) { fprintf( stderr, " wake_bits=%08x,", req->wake_bits ); fprintf( stderr, " changed_bits=%08x", req->changed_bits ); @@ -1608,7 +1612,7 @@ static void dump_wait_input_idle_request( const struct wait_input_idle_request * fprintf( stderr, " timeout=%d", req->timeout ); } -static void dump_wait_input_idle_reply( const struct wait_input_idle_request *req ) +static void dump_wait_input_idle_reply( const struct wait_input_idle_reply *req ) { fprintf( stderr, " event=%d", req->event ); } @@ -1627,7 +1631,7 @@ static void dump_send_message_request( const struct send_message_request *req ) fprintf( stderr, " info=%08x,", req->info ); fprintf( stderr, " timeout=%d,", req->timeout ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_get_message_request( const struct get_message_request *req ) @@ -1638,7 +1642,7 @@ static void dump_get_message_request( const struct get_message_request *req ) fprintf( stderr, " get_last=%08x", req->get_last ); } -static void dump_get_message_reply( const struct get_message_request *req ) +static void dump_get_message_reply( const struct get_message_reply *req ) { fprintf( stderr, " type=%d,", req->type ); fprintf( stderr, " win=%08x,", req->win ); @@ -1649,8 +1653,9 @@ static void dump_get_message_reply( const struct get_message_request *req ) fprintf( stderr, " y=%d,", req->y ); fprintf( stderr, " time=%08x,", req->time ); fprintf( stderr, " info=%08x,", req->info ); + fprintf( stderr, " total=%d,", req->total ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_reply_message_request( const struct reply_message_request *req ) @@ -1658,7 +1663,7 @@ static void dump_reply_message_request( const struct reply_message_request *req fprintf( stderr, " result=%08x,", req->result ); fprintf( stderr, " remove=%d,", req->remove ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_get_message_reply_request( const struct get_message_reply_request *req ) @@ -1666,11 +1671,11 @@ static void dump_get_message_reply_request( const struct get_message_reply_reque fprintf( stderr, " cancel=%d", req->cancel ); } -static void dump_get_message_reply_reply( const struct get_message_reply_request *req ) +static void dump_get_message_reply_reply( const struct get_message_reply_reply *req ) { fprintf( stderr, " result=%08x,", req->result ); fprintf( stderr, " data=" ); - cur_pos += dump_varargs_bytes( req ); + dump_varargs_bytes( cur_size ); } static void dump_set_win_timer_request( const struct set_win_timer_request *req ) @@ -1696,10 +1701,10 @@ static void dump_create_serial_request( const struct create_serial_request *req fprintf( stderr, " attributes=%08x,", req->attributes ); fprintf( stderr, " sharing=%08x,", req->sharing ); fprintf( stderr, " name=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } -static void dump_create_serial_reply( const struct create_serial_request *req ) +static void dump_create_serial_reply( const struct create_serial_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1709,7 +1714,7 @@ static void dump_get_serial_info_request( const struct get_serial_info_request * fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_serial_info_reply( const struct get_serial_info_request *req ) +static void dump_get_serial_info_reply( const struct get_serial_info_reply *req ) { fprintf( stderr, " readinterval=%08x,", req->readinterval ); fprintf( stderr, " readconst=%08x,", req->readconst ); @@ -1740,7 +1745,7 @@ static void dump_create_async_request( const struct create_async_request *req ) fprintf( stderr, " type=%d", req->type ); } -static void dump_create_async_reply( const struct create_async_request *req ) +static void dump_create_async_reply( const struct create_async_reply *req ) { fprintf( stderr, " timeout=%d", req->timeout ); } @@ -1754,10 +1759,10 @@ static void dump_create_named_pipe_request( const struct create_named_pipe_reque fprintf( stderr, " insize=%08x,", req->insize ); fprintf( stderr, " timeout=%08x,", req->timeout ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } -static void dump_create_named_pipe_reply( const struct create_named_pipe_request *req ) +static void dump_create_named_pipe_reply( const struct create_named_pipe_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1766,10 +1771,10 @@ static void dump_open_named_pipe_request( const struct open_named_pipe_request * { fprintf( stderr, " access=%08x,", req->access ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } -static void dump_open_named_pipe_reply( const struct open_named_pipe_request *req ) +static void dump_open_named_pipe_reply( const struct open_named_pipe_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -1787,7 +1792,7 @@ static void dump_wait_named_pipe_request( const struct wait_named_pipe_request * fprintf( stderr, " overlapped=%p,", req->overlapped ); fprintf( stderr, " func=%p,", req->func ); fprintf( stderr, " filename=" ); - cur_pos += dump_varargs_string( req ); + dump_varargs_string( cur_size ); } static void dump_disconnect_named_pipe_request( const struct disconnect_named_pipe_request *req ) @@ -1800,7 +1805,7 @@ static void dump_get_named_pipe_info_request( const struct get_named_pipe_info_r fprintf( stderr, " handle=%d", req->handle ); } -static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_request *req ) +static void dump_get_named_pipe_info_reply( const struct get_named_pipe_info_reply *req ) { fprintf( stderr, " flags=%08x,", req->flags ); fprintf( stderr, " maxinstances=%08x,", req->maxinstances ); @@ -1815,7 +1820,7 @@ static void dump_create_window_request( const struct create_window_request *req fprintf( stderr, " atom=%04x", req->atom ); } -static void dump_create_window_reply( const struct create_window_request *req ) +static void dump_create_window_reply( const struct create_window_reply *req ) { fprintf( stderr, " handle=%08x", req->handle ); } @@ -1827,7 +1832,7 @@ static void dump_link_window_request( const struct link_window_request *req ) fprintf( stderr, " previous=%08x", req->previous ); } -static void dump_link_window_reply( const struct link_window_request *req ) +static void dump_link_window_reply( const struct link_window_reply *req ) { fprintf( stderr, " full_parent=%08x", req->full_parent ); } @@ -1843,7 +1848,7 @@ static void dump_set_window_owner_request( const struct set_window_owner_request fprintf( stderr, " owner=%08x", req->owner ); } -static void dump_set_window_owner_reply( const struct set_window_owner_request *req ) +static void dump_set_window_owner_reply( const struct set_window_owner_reply *req ) { fprintf( stderr, " full_owner=%08x", req->full_owner ); } @@ -1853,7 +1858,7 @@ static void dump_get_window_info_request( const struct get_window_info_request * fprintf( stderr, " handle=%08x", req->handle ); } -static void dump_get_window_info_reply( const struct get_window_info_request *req ) +static void dump_get_window_info_reply( const struct get_window_info_reply *req ) { fprintf( stderr, " full_handle=%08x,", req->full_handle ); fprintf( stderr, " pid=%p,", req->pid ); @@ -1872,7 +1877,7 @@ static void dump_set_window_info_request( const struct set_window_info_request * fprintf( stderr, " user_data=%p", req->user_data ); } -static void dump_set_window_info_reply( const struct set_window_info_request *req ) +static void dump_set_window_info_reply( const struct set_window_info_reply *req ) { fprintf( stderr, " old_style=%08x,", req->old_style ); fprintf( stderr, " old_ex_style=%08x,", req->old_ex_style ); @@ -1886,11 +1891,11 @@ static void dump_get_window_parents_request( const struct get_window_parents_req fprintf( stderr, " handle=%08x", req->handle ); } -static void dump_get_window_parents_reply( const struct get_window_parents_request *req ) +static void dump_get_window_parents_reply( const struct get_window_parents_reply *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " parents=" ); - cur_pos += dump_varargs_user_handles( req ); + dump_varargs_user_handles( cur_size ); } static void dump_get_window_children_request( const struct get_window_children_request *req ) @@ -1900,11 +1905,11 @@ static void dump_get_window_children_request( const struct get_window_children_r fprintf( stderr, " tid=%p", req->tid ); } -static void dump_get_window_children_reply( const struct get_window_children_request *req ) +static void dump_get_window_children_reply( const struct get_window_children_reply *req ) { fprintf( stderr, " count=%d,", req->count ); fprintf( stderr, " children=" ); - cur_pos += dump_varargs_user_handles( req ); + dump_varargs_user_handles( cur_size ); } static void dump_get_window_tree_request( const struct get_window_tree_request *req ) @@ -1912,7 +1917,7 @@ static void dump_get_window_tree_request( const struct get_window_tree_request * fprintf( stderr, " handle=%08x", req->handle ); } -static void dump_get_window_tree_reply( const struct get_window_tree_request *req ) +static void dump_get_window_tree_reply( const struct get_window_tree_reply *req ) { fprintf( stderr, " parent=%08x,", req->parent ); fprintf( stderr, " owner=%08x,", req->owner ); @@ -1928,10 +1933,10 @@ static void dump_set_window_rectangles_request( const struct set_window_rectangl { fprintf( stderr, " handle=%08x,", req->handle ); fprintf( stderr, " window=" ); - dump_rectangle( req, &req->window ); + dump_rectangle( &req->window ); fprintf( stderr, "," ); fprintf( stderr, " client=" ); - dump_rectangle( req, &req->client ); + dump_rectangle( &req->client ); } static void dump_get_window_rectangles_request( const struct get_window_rectangles_request *req ) @@ -1939,13 +1944,13 @@ static void dump_get_window_rectangles_request( const struct get_window_rectangl fprintf( stderr, " handle=%08x", req->handle ); } -static void dump_get_window_rectangles_reply( const struct get_window_rectangles_request *req ) +static void dump_get_window_rectangles_reply( const struct get_window_rectangles_reply *req ) { fprintf( stderr, " window=" ); - dump_rectangle( req, &req->window ); + dump_rectangle( &req->window ); fprintf( stderr, "," ); fprintf( stderr, " client=" ); - dump_rectangle( req, &req->client ); + dump_rectangle( &req->client ); } static void dump_get_window_text_request( const struct get_window_text_request *req ) @@ -1953,17 +1958,17 @@ static void dump_get_window_text_request( const struct get_window_text_request * fprintf( stderr, " handle=%08x", req->handle ); } -static void dump_get_window_text_reply( const struct get_window_text_request *req ) +static void dump_get_window_text_reply( const struct get_window_text_reply *req ) { fprintf( stderr, " text=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_set_window_text_request( const struct set_window_text_request *req ) { fprintf( stderr, " handle=%08x,", req->handle ); fprintf( stderr, " text=" ); - cur_pos += dump_varargs_unicode_str( req ); + dump_varargs_unicode_str( cur_size ); } static void dump_inc_window_paint_count_request( const struct inc_window_paint_count_request *req ) @@ -1978,7 +1983,7 @@ static void dump_get_windows_offset_request( const struct get_windows_offset_req fprintf( stderr, " to=%08x", req->to ); } -static void dump_get_windows_offset_reply( const struct get_windows_offset_request *req ) +static void dump_get_windows_offset_reply( const struct get_windows_offset_reply *req ) { fprintf( stderr, " x=%d,", req->x ); fprintf( stderr, " y=%d", req->y ); @@ -1998,7 +2003,7 @@ static void dump_remove_window_property_request( const struct remove_window_prop fprintf( stderr, " atom=%04x", req->atom ); } -static void dump_remove_window_property_reply( const struct remove_window_property_request *req ) +static void dump_remove_window_property_reply( const struct remove_window_property_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -2009,7 +2014,7 @@ static void dump_get_window_property_request( const struct get_window_property_r fprintf( stderr, " atom=%04x", req->atom ); } -static void dump_get_window_property_reply( const struct get_window_property_request *req ) +static void dump_get_window_property_reply( const struct get_window_property_reply *req ) { fprintf( stderr, " handle=%d", req->handle ); } @@ -2019,10 +2024,11 @@ static void dump_get_window_properties_request( const struct get_window_properti fprintf( stderr, " window=%08x", req->window ); } -static void dump_get_window_properties_reply( const struct get_window_properties_request *req ) +static void dump_get_window_properties_reply( const struct get_window_properties_reply *req ) { + fprintf( stderr, " total=%d,", req->total ); fprintf( stderr, " props=" ); - cur_pos += dump_varargs_properties( req ); + dump_varargs_properties( cur_size ); } static const dump_func req_dumpers[REQ_NB_REQUESTS] = { @@ -2033,7 +2039,6 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_init_process_request, (dump_func)dump_init_process_done_request, (dump_func)dump_init_thread_request, - (dump_func)dump_set_thread_buffer_request, (dump_func)dump_terminate_process_request, (dump_func)dump_terminate_thread_request, (dump_func)dump_get_process_info_request, @@ -2092,6 +2097,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_write_console_input_request, (dump_func)dump_read_console_input_request, (dump_func)dump_write_console_output_request, + (dump_func)dump_fill_console_output_request, (dump_func)dump_read_console_output_request, (dump_func)dump_move_console_output_request, (dump_func)dump_create_change_notification_request, @@ -2184,7 +2190,6 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_init_process_reply, (dump_func)dump_init_process_done_reply, (dump_func)dump_init_thread_reply, - (dump_func)dump_set_thread_buffer_reply, (dump_func)dump_terminate_process_reply, (dump_func)dump_terminate_thread_reply, (dump_func)dump_get_process_info_reply, @@ -2243,6 +2248,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_write_console_input_reply, (dump_func)dump_read_console_input_reply, (dump_func)dump_write_console_output_reply, + (dump_func)dump_fill_console_output_reply, (dump_func)dump_read_console_output_reply, (dump_func)0, (dump_func)dump_create_change_notification_reply, @@ -2335,7 +2341,6 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "init_process", "init_process_done", "init_thread", - "set_thread_buffer", "terminate_process", "terminate_thread", "get_process_info", @@ -2394,6 +2399,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "write_console_input", "read_console_input", "write_console_output", + "fill_console_output", "read_console_output", "move_console_output", "create_change_notification", @@ -2538,36 +2544,41 @@ static const char *get_status_name( unsigned int status ) return buffer; } -void trace_request( struct thread *thread, const union generic_request *request ) +void trace_request(void) { - enum request req = request->header.req; - cur_pos = 0; + enum request req = current->req.request_header.req; if (req < REQ_NB_REQUESTS) { - fprintf( stderr, "%08x: %s(", (unsigned int)thread, req_names[req] ); - cur_pos = 0; - req_dumpers[req]( request ); + fprintf( stderr, "%08x: %s(", (unsigned int)current, req_names[req] ); + if (req_dumpers[req]) + { + cur_pos = 0; + cur_data = get_req_data(); + cur_size = get_req_data_size(); + req_dumpers[req]( ¤t->req ); + } fprintf( stderr, " )\n" ); } - else fprintf( stderr, "%08x: %d(?)\n", (unsigned int)thread, req ); + else fprintf( stderr, "%08x: %d(?)\n", (unsigned int)current, req ); } -void trace_reply( struct thread *thread, const union generic_request *request ) +void trace_reply( enum request req, const union generic_reply *reply ) { - enum request req = request->header.req; if (req < REQ_NB_REQUESTS) { fprintf( stderr, "%08x: %s() = %s", - (unsigned int)thread, req_names[req], get_status_name(thread->error) ); + (unsigned int)current, req_names[req], get_status_name(current->error) ); if (reply_dumpers[req]) { fprintf( stderr, " {" ); cur_pos = 0; - reply_dumpers[req]( request ); + cur_data = current->reply_data; + cur_size = reply->reply_header.reply_size; + reply_dumpers[req]( reply ); fprintf( stderr, " }" ); } fputc( '\n', stderr ); } else fprintf( stderr, "%08x: %d() = %s\n", - (unsigned int)thread, req, get_status_name(thread->error) ); + (unsigned int)current, req, get_status_name(current->error) ); } diff --git a/server/window.c b/server/window.c index 1a3c4f260d7..c1ffe8499ff 100644 --- a/server/window.c +++ b/server/window.c @@ -215,23 +215,6 @@ inline static void destroy_properties( struct window *win ) free( win->properties ); } -/* enum all properties into the data array */ -static int enum_properties( struct window *win, property_data_t *data, int max ) -{ - int i, count; - - for (i = count = 0; i < win->prop_inuse && count < max; i++) - { - if (win->properties[i].type == PROP_TYPE_FREE) continue; - data->atom = win->properties[i].atom; - data->string = (win->properties[i].type == PROP_TYPE_STRING); - data->handle = win->properties[i].handle; - data++; - count++; - } - return count; -} - /* destroy a window */ static void destroy_window( struct window *win ) { @@ -376,7 +359,7 @@ user_handle_t find_window_to_repaint( user_handle_t parent, struct thread *threa /* create a window */ DECL_HANDLER(create_window) { - req->handle = 0; + reply->handle = 0; if (!req->parent) /* return desktop window */ { if (!top_window) @@ -384,7 +367,7 @@ DECL_HANDLER(create_window) if (!(top_window = create_window( NULL, NULL, req->atom ))) return; top_window->thread = NULL; /* no thread owns the desktop */ } - req->handle = top_window->handle; + reply->handle = top_window->handle; } else { @@ -400,7 +383,7 @@ DECL_HANDLER(create_window) return; } if (!(win = create_window( parent, owner, req->atom ))) return; - req->handle = win->handle; + reply->handle = win->handle; } } @@ -418,7 +401,7 @@ DECL_HANDLER(link_window) set_error( STATUS_INVALID_PARAMETER ); return; } - req->full_parent = parent ? parent->handle : 0; + reply->full_parent = parent ? parent->handle : 0; if (parent && req->previous) { if (req->previous == (user_handle_t)1) /* special case: HWND_BOTTOM */ @@ -467,7 +450,7 @@ DECL_HANDLER(set_window_owner) return; } win->owner = owner; - req->full_owner = owner->handle; + reply->full_owner = owner->handle; } @@ -476,16 +459,16 @@ DECL_HANDLER(get_window_info) { struct window *win = get_window( req->handle ); - req->full_handle = 0; - req->tid = req->pid = 0; + reply->full_handle = 0; + reply->tid = reply->pid = 0; if (win) { - req->full_handle = win->handle; + reply->full_handle = win->handle; if (win->thread) { - req->tid = get_thread_id( win->thread ); - req->pid = get_process_id( win->thread->process ); - req->atom = win->atom; + reply->tid = get_thread_id( win->thread ); + reply->pid = get_process_id( win->thread->process ); + reply->atom = win->atom; } } } @@ -496,11 +479,11 @@ DECL_HANDLER(set_window_info) { struct window *win = get_window( req->handle ); if (!win) return; - req->old_style = win->style; - req->old_ex_style = win->ex_style; - req->old_id = win->id; - req->old_instance = win->instance; - req->old_user_data = win->user_data; + reply->old_style = win->style; + reply->old_ex_style = win->ex_style; + reply->old_id = win->id; + reply->old_instance = win->instance; + reply->old_user_data = win->user_data; if (req->flags & SET_WIN_STYLE) win->style = req->style; if (req->flags & SET_WIN_EXSTYLE) win->ex_style = req->ex_style; if (req->flags & SET_WIN_ID) win->id = req->id; @@ -514,16 +497,15 @@ DECL_HANDLER(get_window_parents) { struct window *ptr, *win = get_window( req->handle ); int total = 0; + user_handle_t *data; size_t len; if (win) for (ptr = win->parent; ptr; ptr = ptr->parent) total++; - req->count = total; - len = min( get_req_data_size(req), total * sizeof(user_handle_t) ); - set_req_data_size( req, len ); - if (len) + reply->count = total; + len = min( get_reply_max_size(), total * sizeof(user_handle_t) ); + if (len && ((data = set_reply_data_size( len )))) { - user_handle_t *data = get_req_data(req); for (ptr = win->parent; ptr && len; ptr = ptr->parent, len -= sizeof(*data)) *data++ = ptr->handle; } @@ -535,6 +517,7 @@ DECL_HANDLER(get_window_children) { struct window *ptr, *parent = get_window( req->parent ); int total = 0; + user_handle_t *data; size_t len; if (parent) @@ -545,12 +528,10 @@ DECL_HANDLER(get_window_children) total++; } - req->count = total; - len = min( get_req_data_size(req), total * sizeof(user_handle_t) ); - set_req_data_size( req, len ); - if (len) + reply->count = total; + len = min( get_reply_max_size(), total * sizeof(user_handle_t) ); + if (len && ((data = set_reply_data_size( len )))) { - user_handle_t *data = get_req_data(req); for (ptr = parent->first_child; ptr && len; ptr = ptr->next, len -= sizeof(*data)) { if (req->atom && ptr->atom != req->atom) continue; @@ -571,24 +552,24 @@ DECL_HANDLER(get_window_tree) if (win->parent) { struct window *parent = win->parent; - req->parent = parent->handle; - req->owner = win->owner ? win->owner->handle : 0; - req->next_sibling = win->next ? win->next->handle : 0; - req->prev_sibling = win->prev ? win->prev->handle : 0; - req->first_sibling = parent->first_child ? parent->first_child->handle : 0; - req->last_sibling = parent->last_child ? parent->last_child->handle : 0; + reply->parent = parent->handle; + reply->owner = win->owner ? win->owner->handle : 0; + reply->next_sibling = win->next ? win->next->handle : 0; + reply->prev_sibling = win->prev ? win->prev->handle : 0; + reply->first_sibling = parent->first_child ? parent->first_child->handle : 0; + reply->last_sibling = parent->last_child ? parent->last_child->handle : 0; } else { - req->parent = 0; - req->owner = 0; - req->next_sibling = 0; - req->prev_sibling = 0; - req->first_sibling = 0; - req->last_sibling = 0; + reply->parent = 0; + reply->owner = 0; + reply->next_sibling = 0; + reply->prev_sibling = 0; + reply->first_sibling = 0; + reply->last_sibling = 0; } - req->first_child = win->first_child ? win->first_child->handle : 0; - req->last_child = win->last_child ? win->last_child->handle : 0; + reply->first_child = win->first_child ? win->first_child->handle : 0; + reply->last_child = win->last_child ? win->last_child->handle : 0; } @@ -612,8 +593,8 @@ DECL_HANDLER(get_window_rectangles) if (win) { - req->window = win->window_rect; - req->client = win->client_rect; + reply->window = win->window_rect; + reply->client = win->client_rect; } } @@ -622,15 +603,13 @@ DECL_HANDLER(get_window_rectangles) DECL_HANDLER(get_window_text) { struct window *win = get_window( req->handle ); - size_t len = 0; if (win && win->text) { - len = strlenW( win->text ) * sizeof(WCHAR); - if (len > get_req_data_size(req)) len = get_req_data_size(req); - memcpy( get_req_data(req), win->text, len ); + size_t len = strlenW( win->text ) * sizeof(WCHAR); + if (len > get_reply_max_size()) len = get_reply_max_size(); + set_reply_data( win->text, len ); } - set_req_data_size( req, len ); } @@ -642,11 +621,11 @@ DECL_HANDLER(set_window_text) if (win) { WCHAR *text = NULL; - size_t len = get_req_data_size(req) / sizeof(WCHAR); + size_t len = get_req_data_size() / sizeof(WCHAR); if (len) { if (!(text = mem_alloc( (len+1) * sizeof(WCHAR) ))) return; - memcpy( text, get_req_data(req), len * sizeof(WCHAR) ); + memcpy( text, get_req_data(), len * sizeof(WCHAR) ); text[len] = 0; } if (win->text) free( win->text ); @@ -674,14 +653,14 @@ DECL_HANDLER(get_windows_offset) { struct window *win; - req->x = req->y = 0; + reply->x = reply->y = 0; if (req->from) { if (!(win = get_window( req->from ))) return; while (win) { - req->x += win->client_rect.left; - req->y += win->client_rect.top; + reply->x += win->client_rect.left; + reply->y += win->client_rect.top; win = win->parent; } } @@ -690,8 +669,8 @@ DECL_HANDLER(get_windows_offset) if (!(win = get_window( req->to ))) return; while (win) { - req->x -= win->client_rect.left; - req->y -= win->client_rect.top; + reply->x -= win->client_rect.left; + reply->y -= win->client_rect.top; win = win->parent; } } @@ -712,8 +691,8 @@ DECL_HANDLER(set_window_property) DECL_HANDLER(remove_window_property) { struct window *win = get_window( req->window ); - req->handle = 0; - if (win) req->handle = remove_property( win, req->atom ); + reply->handle = 0; + if (win) reply->handle = remove_property( win, req->atom ); } @@ -721,18 +700,35 @@ DECL_HANDLER(remove_window_property) DECL_HANDLER(get_window_property) { struct window *win = get_window( req->window ); - req->handle = 0; - if (win) req->handle = get_property( win, req->atom ); + reply->handle = 0; + if (win) reply->handle = get_property( win, req->atom ); } /* get the list of properties of a window */ DECL_HANDLER(get_window_properties) { - int count = 0; - property_data_t *data = get_req_data(req); + property_data_t *data; + int i, count, max = get_reply_max_size() / sizeof(*data); struct window *win = get_window( req->window ); - if (win) count = enum_properties( win, data, get_req_data_size(req) / sizeof(*data) ); - set_req_data_size( req, count * sizeof(*data) ); + reply->total = 0; + if (!win) return; + + for (i = count = 0; i < win->prop_inuse; i++) + if (win->properties[i].type != PROP_TYPE_FREE) count++; + reply->total = count; + + if (count > max) count = max; + if (!count || !(data = set_reply_data_size( count * sizeof(*data) ))) return; + + for (i = 0; i < win->prop_inuse && count; i++) + { + if (win->properties[i].type == PROP_TYPE_FREE) continue; + data->atom = win->properties[i].atom; + data->string = (win->properties[i].type == PROP_TYPE_STRING); + data->handle = win->properties[i].handle; + data++; + count--; + } } diff --git a/tools/make_requests b/tools/make_requests index ed3c59ecf26..34cd54d0b53 100755 --- a/tools/make_requests +++ b/tools/make_requests @@ -16,10 +16,12 @@ "unsigned int" => "%08x", "void*" => "%p", "time_t" => "%ld", + "size_t" => "%d", "handle_t" => "%d", "atom_t" => "%04x", "user_handle_t" => "%08x", "rectangle_t" => "&dump_rectangle", + "char_info_t" => "&dump_char_info", ); my @requests = (); @@ -44,16 +46,24 @@ print SERVER_PROT "#define __WINE_WINE_SERVER_PROTOCOL_H\n"; &PARSE_REQUESTS; -### Build the request list +### Build the request list and structures print SERVER_PROT "\n\nenum request\n{\n"; foreach $req (@requests) { print SERVER_PROT " REQ_$req,\n"; } print SERVER_PROT " REQ_NB_REQUESTS\n};\n\n"; + print SERVER_PROT "union generic_request\n{\n"; print SERVER_PROT " struct request_max_size max_size;\n"; -print SERVER_PROT " struct request_header header;\n"; -foreach $req (@requests) { print SERVER_PROT " struct ${req}_request $req;\n"; } +print SERVER_PROT " struct request_header request_header;\n"; +foreach $req (@requests) { print SERVER_PROT " struct ${req}_request ${req}_request;\n"; } +print SERVER_PROT "};\n"; + +print SERVER_PROT "union generic_reply\n{\n"; +print SERVER_PROT " struct request_max_size max_size;\n"; +print SERVER_PROT " struct reply_header reply_header;\n"; +foreach $req (@requests) { print SERVER_PROT " struct ${req}_reply ${req}_reply;\n"; } print SERVER_PROT "};\n\n"; + printf SERVER_PROT "#define SERVER_PROTOCOL_VERSION %d\n\n", $protocol + 1; print SERVER_PROT "#endif /* __WINE_WINE_SERVER_PROTOCOL_H */\n"; close SERVER_PROT; @@ -89,7 +99,7 @@ my @request_lines = (); foreach $req (@requests) { push @request_lines, "DECL_HANDLER($req);\n"; } push @request_lines, "\n#ifdef WANT_REQUEST_HANDLERS\n\n"; -push @request_lines, "typedef void (*req_handler)( void *req );\n"; +push @request_lines, "typedef void (*req_handler)( const void *req, void *reply );\n"; push @request_lines, "static const req_handler req_handlers[REQ_NB_REQUESTS] =\n{\n"; foreach $req (@requests) { @@ -145,6 +155,9 @@ sub PARSE_REQUESTS if (/^\@REPLY/) { die "Misplaced \@REPLY" unless $state == 2; + print SERVER_PROT "};\n"; + print SERVER_PROT "struct ${name}_reply\n{\n"; + print SERVER_PROT " struct reply_header __header;\n"; $state++; next; } @@ -154,6 +167,13 @@ sub PARSE_REQUESTS die "Misplaced \@END" unless ($state == 2 || $state == 3); print SERVER_PROT "};\n"; + if ($state == 2) # build dummy reply struct + { + print SERVER_PROT "struct ${name}_reply\n{\n"; + print SERVER_PROT " struct reply_header __header;\n"; + print SERVER_PROT "};\n"; + } + # got a complete request push @requests, $name; &DO_DUMP_FUNC( $name, "request", @in_struct); @@ -175,17 +195,23 @@ sub PARSE_REQUESTS next; } - if (/^\s*VARARG\((\w+),(\w+)\)/) + if (/^\s*VARARG\((\w+),(\w+),(\w+)\)/) { $var = $1; - $type = "&dump_varargs_" . $2; + $type = "dump_varargs_" . $2 . "( min(cur_size,req->" . $3 . ") )"; s!(VARARG\(.*\)\s*;)!/* $1 */!; } - elsif (/^\s*(\w+\**(\s+\w+\**)*)\s+(\w+)(\[[1]\])?;/) + elsif (/^\s*VARARG\((\w+),(\w+)\)/) { - $type = $1 . ($4 || ""); + $var = $1; + $type = "dump_varargs_" . $2 . "( cur_size )"; + s!(VARARG\(.*\)\s*;)!/* $1 */!; + } + elsif (/^\s*(\w+\**(\s+\w+\**)*)\s+(\w+);/) + { + $type = $1; $var = $3; - die "Unrecognized type $type" unless (defined($formats{$type}) || $4); + die "Unrecognized type $type" unless defined($formats{$type}); } else { @@ -207,7 +233,7 @@ sub DO_DUMP_FUNC { my $name = shift; my $req = shift; - push @trace_lines, "static void dump_${name}_$req( const struct ${name}_request *req )\n{\n"; + push @trace_lines, "static void dump_${name}_$req( const struct ${name}_$req *req )\n{\n"; while ($#_ >= 0) { my $type = shift; @@ -218,8 +244,7 @@ sub DO_DUMP_FUNC { my $func = $1; push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; - if ($type =~ /[1]/) { push @trace_lines, " $func( req, req->$var );\n"; } - else { push @trace_lines, " $func( req, &req->$var );\n"; } + push @trace_lines, " $func( &req->$var );\n"; push @trace_lines, " fprintf( stderr, \",\" );\n" if ($#_ > 0); } else @@ -232,18 +257,10 @@ sub DO_DUMP_FUNC } else # must be some varargs format { - if ($type =~ /^&(.*)/) - { - my $func = $1; - push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; - push @trace_lines, " cur_pos += $func( req );\n"; - push @trace_lines, " fputc( ',', stderr );\n" if ($#_ > 0); - } - else - { - push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; - push @trace_lines, " dump_varargs_${name}_${req}( req );\n"; - } + my $func = $type; + push @trace_lines, " fprintf( stderr, \" $var=\" );\n"; + push @trace_lines, " $func;\n"; + push @trace_lines, " fputc( ',', stderr );\n" if ($#_ > 0); } } push @trace_lines, "}\n\n"; diff --git a/win32/console.c b/win32/console.c index 25e3c82c55d..0ed21e3c2b7 100644 --- a/win32/console.c +++ b/win32/console.c @@ -47,7 +47,7 @@ BOOL WINAPI FreeConsole(VOID) SERVER_START_REQ(free_console) { - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -172,7 +172,7 @@ BOOL WINAPI AllocConsole(void) HANDLE handle_in = INVALID_HANDLE_VALUE; HANDLE handle_out = INVALID_HANDLE_VALUE; HANDLE handle_err = INVALID_HANDLE_VALUE; - STARTUPINFOA si; + STARTUPINFOW si; TRACE("()\n"); @@ -206,7 +206,7 @@ BOOL WINAPI AllocConsole(void) SetStdHandle(STD_OUTPUT_HANDLE, handle_out); SetStdHandle(STD_ERROR_HANDLE, handle_err); - GetStartupInfoA(&si); + GetStartupInfoW(&si); if (si.dwFlags & STARTF_USESIZE) { COORD c; @@ -217,7 +217,7 @@ BOOL WINAPI AllocConsole(void) if (si.dwFlags & STARTF_USEFILLATTRIBUTE) SetConsoleTextAttribute(handle_out, si.dwFillAttribute); if (si.lpTitle) - SetConsoleTitleA(si.lpTitle); + SetConsoleTitleW(si.lpTitle); SetLastError(ERROR_SUCCESS); @@ -245,19 +245,14 @@ static BOOL read_console_input(HANDLE handle, LPINPUT_RECORD buffer, DWORD count unsigned read = 0; DWORD mode; - count = min(count, REQUEST_MAX_VAR_SIZE/sizeof(INPUT_RECORD)); - - SERVER_START_VAR_REQ(read_console_input, count*sizeof(INPUT_RECORD)) + SERVER_START_REQ( read_console_input ) { req->handle = handle; req->flush = flush; - if ((ret = !SERVER_CALL_ERR())) - { - if (count) memcpy(buffer, server_data_ptr(req), server_data_size(req)); - read = req->read; - } + wine_server_set_reply( req, buffer, count * sizeof(INPUT_RECORD) ); + if ((ret = !wine_server_call_err( req ))) read = reply->read; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (count && flush && GetConsoleMode(handle, &mode) && (mode & ENABLE_PROCESSED_INPUT)) { int i; @@ -356,33 +351,6 @@ BOOL WINAPI ReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer, } -/****************************************************************************** - * ReadConsoleInputA [KERNEL32.@] Reads data from a console - * - * PARAMS - * hConsoleInput [I] Handle to console input buffer - * lpBuffer [O] Address of buffer for read data - * nLength [I] Number of records to read - * lpNumberOfEventsRead [O] Address of number of records read - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI ReadConsoleInputA(HANDLE hConsoleInput, LPINPUT_RECORD lpBuffer, - DWORD nLength, LPDWORD lpNumberOfEventsRead) -{ - DWORD nread; - - if (!ReadConsoleInputW(hConsoleInput, lpBuffer, nLength, &nread)) - return FALSE; - - /* FIXME for now, the low part of unicode would do as ASCII */ - if (lpNumberOfEventsRead) *lpNumberOfEventsRead = nread; - return TRUE; -} - - /*********************************************************************** * ReadConsoleInputW (KERNEL32.@) */ @@ -412,53 +380,74 @@ BOOL WINAPI ReadConsoleInputW(HANDLE hConsoleInput, LPINPUT_RECORD lpBuffer, } -/*********************************************************************** - * FlushConsoleInputBuffer (KERNEL32.@) - */ -BOOL WINAPI FlushConsoleInputBuffer(HANDLE handle) -{ - return read_console_input(handle, NULL, 0, NULL, TRUE); -} - - -/*********************************************************************** - * PeekConsoleInputA (KERNEL32.@) +/****************************************************************************** + * WriteConsoleOutputCharacterW [KERNEL32.@] Copies character to consecutive + * cells in the console screen buffer * - * Gets 'count' first events (or less) from input queue. + * PARAMS + * hConsoleOutput [I] Handle to screen buffer + * str [I] Pointer to buffer with chars to write + * length [I] Number of cells to write to + * coord [I] Coords of first cell + * lpNumCharsWritten [O] Pointer to number of cells written * - * Does not need a complex console. + * RETURNS + * Success: TRUE + * Failure: FALSE + * */ -BOOL WINAPI PeekConsoleInputA(HANDLE hConsoleInput, LPINPUT_RECORD pirBuffer, - DWORD cInRecords, LPDWORD lpcRead) +BOOL WINAPI WriteConsoleOutputCharacterW( HANDLE hConsoleOutput, LPCWSTR str, DWORD length, + COORD coord, LPDWORD lpNumCharsWritten ) { - /* FIXME: Hmm. Fix this if we get UNICODE input. */ - return PeekConsoleInputW(hConsoleInput, pirBuffer, cInRecords, lpcRead); -} + BOOL ret; + TRACE("(%d,%s,%ld,%dx%d,%p)\n", hConsoleOutput, + debugstr_wn(str, length), length, coord.X, coord.Y, lpNumCharsWritten); -/*********************************************************************** - * PeekConsoleInputW (KERNEL32.@) - */ -BOOL WINAPI PeekConsoleInputW(HANDLE hConsoleInput, LPINPUT_RECORD pirBuffer, - DWORD cInRecords, LPDWORD lpcRead) -{ - if (!cInRecords) + SERVER_START_REQ( write_console_output ) { - if (lpcRead) *lpcRead = 0; - return TRUE; + req->handle = hConsoleOutput; + req->x = coord.X; + req->y = coord.Y; + req->mode = CHAR_INFO_MODE_TEXT; + req->wrap = TRUE; + wine_server_add_data( req, str, length * sizeof(WCHAR) ); + if ((ret = !wine_server_call_err( req ))) + { + if (lpNumCharsWritten) *lpNumCharsWritten = reply->written; + } } - return read_console_input(hConsoleInput, pirBuffer, cInRecords, lpcRead, FALSE); + SERVER_END_REQ; + return ret; } -/*********************************************************************** - * GetNumberOfConsoleInputEvents (KERNEL32.@) +/****************************************************************************** + * SetConsoleTitleW [KERNEL32.@] Sets title bar string for console + * + * PARAMS + * title [I] Address of new title + * + * RETURNS + * Success: TRUE + * Failure: FALSE */ -BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE hcon, LPDWORD nrofevents) +BOOL WINAPI SetConsoleTitleW(LPCWSTR title) { - return read_console_input(hcon, NULL, 0, nrofevents, FALSE); + BOOL ret; + + SERVER_START_REQ( set_console_input_info ) + { + req->handle = 0; + req->mask = SET_CONSOLE_INPUT_INFO_TITLE; + wine_server_add_data( req, title, strlenW(title) * sizeof(WCHAR) ); + ret = !wine_server_call_err( req ); + } + SERVER_END_REQ; + return ret; } + /*********************************************************************** * GetNumberOfConsoleMouseButtons (KERNEL32.@) */ @@ -469,70 +458,6 @@ BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD nrofbuttons) return TRUE; } -/****************************************************************************** - * WriteConsoleInputA [KERNEL32.@] Write data to a console input buffer - * - */ -BOOL WINAPI WriteConsoleInputA(HANDLE handle, INPUT_RECORD *buffer, - DWORD count, LPDWORD written) -{ - BOOL ret = TRUE; - - if (written) *written = 0; - /* FIXME should zero out the non ASCII part for key events */ - - while (count && ret) - { - DWORD len = min(count, REQUEST_MAX_VAR_SIZE/sizeof(INPUT_RECORD)); - SERVER_START_VAR_REQ(write_console_input, len * sizeof(INPUT_RECORD)) - { - req->handle = handle; - memcpy(server_data_ptr(req), buffer, len * sizeof(INPUT_RECORD)); - if ((ret = !SERVER_CALL_ERR())) - { - if (written) *written += req->written; - count -= len; - buffer += len; - } - } - SERVER_END_VAR_REQ; - } - return ret; -} - -/****************************************************************************** - * WriteConsoleInputW [KERNEL32.@] Write data to a console input buffer - * - */ -BOOL WINAPI WriteConsoleInputW(HANDLE handle, INPUT_RECORD *buffer, - DWORD count, LPDWORD written) -{ - BOOL ret = TRUE; - - TRACE("(%d,%p,%ld,%p)\n", handle, buffer, count, written); - - if (written) *written = 0; - while (count && ret) - { - DWORD len = min(count, REQUEST_MAX_VAR_SIZE/sizeof(INPUT_RECORD)); - SERVER_START_VAR_REQ(write_console_input, len * sizeof(INPUT_RECORD)) - { - req->handle = handle; - memcpy(server_data_ptr(req), buffer, len * sizeof(INPUT_RECORD)); - if ((ret = !SERVER_CALL_ERR())) - { - if (written) *written += req->written; - count -= len; - buffer += len; - } - } - SERVER_END_VAR_REQ; - } - - return ret; -} - - /****************************************************************************** * SetConsoleInputExeNameW [KERNEL32.@] * @@ -661,8 +586,6 @@ static WINE_EXCEPTION_FILTER(CONSOLE_CtrlEventHandler) BOOL WINAPI GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, DWORD dwProcessGroupID) { - BOOL dbgOn = FALSE; - if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT) { ERR("invalid event %ld for PGID %ld\n", dwCtrlEvent, dwProcessGroupID); @@ -681,45 +604,27 @@ BOOL WINAPI GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, if (dwCtrlEvent == CTRL_C_EVENT && console_ignore_ctrl_c) return TRUE; - /* if the program is debugged, then generate an exception to the debugger first */ - SERVER_START_REQ( get_process_info ) - { - req->handle = GetCurrentProcess(); - if (!SERVER_CALL_ERR()) dbgOn = req->debugged; - } - SERVER_END_REQ; - - if (dbgOn && (dwCtrlEvent == CTRL_C_EVENT || dwCtrlEvent == CTRL_BREAK_EVENT)) - { - /* the debugger is running... so try to pass the exception to it - * if it continues, there's nothing more to do - * otherwise, we need to send the ctrl-event to the handlers - */ - BOOL seen; - __TRY - { - seen = TRUE; - RaiseException((dwCtrlEvent == CTRL_C_EVENT) ? DBG_CONTROL_C : DBG_CONTROL_BREAK, 0, 0, NULL); - } - __EXCEPT(CONSOLE_CtrlEventHandler) - { - /* the debugger didn't continue... so, pass to ctrl handlers */ - seen = FALSE; - } - __ENDTRY; - if (seen) return TRUE; - } - - /* proceed with installed handlers */ - for (i = 0; i < sizeof(handlers)/sizeof(handlers[0]); i++) - { - if (handlers[i] && (handlers[i])(dwCtrlEvent)) break; - } - - return TRUE; + /* try to pass the exception to the debugger + * if it continues, there's nothing more to do + * otherwise, we need to send the ctrl-event to the handlers + */ + __TRY + { + RaiseException( (dwCtrlEvent == CTRL_C_EVENT) ? DBG_CONTROL_C : DBG_CONTROL_BREAK, + 0, 0, NULL); + } + __EXCEPT(CONSOLE_CtrlEventHandler) + { + /* the debugger didn't continue... so, pass to ctrl handlers */ + for (i = 0; i < sizeof(handlers)/sizeof(handlers[0]); i++) + { + if (handlers[i] && (handlers[i])(dwCtrlEvent)) break; + } + } + __ENDTRY; + return TRUE; } - FIXME("event %ld to external PGID %ld - not implemented yet\n", - dwCtrlEvent, dwProcessGroupID); + FIXME("event %ld to external PGID %ld - not implemented yet\n", dwCtrlEvent, dwProcessGroupID); return FALSE; } @@ -762,8 +667,7 @@ HANDLE WINAPI CreateConsoleScreenBuffer(DWORD dwDesiredAccess, DWORD dwShareMode req->access = dwDesiredAccess; req->share = dwShareMode; req->inherit = (sa && sa->bInheritHandle); - if (!SERVER_CALL_ERR()) - ret = req->handle_out; + if (!wine_server_call_err( req )) ret = reply->handle_out; } SERVER_END_REQ; @@ -780,21 +684,21 @@ BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, LPCONSOLE_SCREEN_B SERVER_START_REQ(get_console_output_info) { - req->handle = (handle_t)hConsoleOutput; - if ((ret = !SERVER_CALL_ERR())) - { - csbi->dwSize.X = req->width; - csbi->dwSize.Y = req->height; - csbi->dwCursorPosition.X = req->cursor_x; - csbi->dwCursorPosition.Y = req->cursor_y; - csbi->wAttributes = req->attr; - csbi->srWindow.Left = req->win_left; - csbi->srWindow.Right = req->win_right; - csbi->srWindow.Top = req->win_top; - csbi->srWindow.Bottom = req->win_bottom; - csbi->dwMaximumWindowSize.X = req->max_width; - csbi->dwMaximumWindowSize.Y = req->max_height; - } + req->handle = hConsoleOutput; + if ((ret = !wine_server_call_err( req ))) + { + csbi->dwSize.X = reply->width; + csbi->dwSize.Y = reply->height; + csbi->dwCursorPosition.X = reply->cursor_x; + csbi->dwCursorPosition.Y = reply->cursor_y; + csbi->wAttributes = reply->attr; + csbi->srWindow.Left = reply->win_left; + csbi->srWindow.Right = reply->win_right; + csbi->srWindow.Top = reply->win_top; + csbi->srWindow.Bottom = reply->win_bottom; + csbi->dwMaximumWindowSize.X = reply->max_width; + csbi->dwMaximumWindowSize.Y = reply->max_height; + } } SERVER_END_REQ; @@ -811,116 +715,22 @@ BOOL WINAPI GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, LPCONSOLE_SCREEN_B */ BOOL WINAPI SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput) { - BOOL ret; - + BOOL ret; + TRACE("(%x)\n", hConsoleOutput); - - SERVER_START_VAR_REQ(set_console_input_info, 0) + + SERVER_START_REQ( set_console_input_info ) { - req->handle = 0; - req->mask = SET_CONSOLE_INPUT_INFO_ACTIVE_SB; - req->active_sb = hConsoleOutput; - - ret = !SERVER_CALL_ERR(); + req->handle = 0; + req->mask = SET_CONSOLE_INPUT_INFO_ACTIVE_SB; + req->active_sb = hConsoleOutput; + ret = !wine_server_call_err( req ); } - SERVER_END_VAR_REQ; - + SERVER_END_REQ; return ret; } -/*********************************************************************** - * GetLargestConsoleWindowSize (KERNEL32.@) - * - * NOTE - * This should return a COORD, but calling convention for returning - * structures is different between Windows and gcc on i386. - * - * VERSION: [i386] - */ -#ifdef __i386__ -#undef GetLargestConsoleWindowSize -DWORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) -{ - COORD c; - c.X = 80; - c.Y = 24; - return *(DWORD *)&c; -} -#endif /* defined(__i386__) */ - - -/*********************************************************************** - * GetLargestConsoleWindowSize (KERNEL32.@) - * - * NOTE - * This should return a COORD, but calling convention for returning - * structures is different between Windows and gcc on i386. - * - * VERSION: [!i386] - */ -#ifndef __i386__ -COORD WINAPI GetLargestConsoleWindowSize(HANDLE hConsoleOutput) -{ - COORD c; - c.X = 80; - c.Y = 24; - return c; -} -#endif /* defined(__i386__) */ - - -/****************************************************************************** - * GetConsoleCP [KERNEL32.@] Returns the OEM code page for the console - * - * RETURNS - * Code page code - */ -UINT WINAPI GetConsoleCP(VOID) -{ - return GetACP(); -} - - -/****************************************************************************** - * SetConsoleCP [KERNEL32.@] - * - * BUGS - * Unimplemented - */ -BOOL WINAPI SetConsoleCP(UINT cp) -{ - FIXME("(%d): stub\n", cp); - - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - -/*********************************************************************** - * GetConsoleOutputCP (KERNEL32.@) - */ -UINT WINAPI GetConsoleOutputCP(VOID) -{ - return GetConsoleCP(); -} - -/****************************************************************************** - * SetConsoleOutputCP [KERNEL32.@] Set the output codepage used by the console - * - * PARAMS - * cp [I] code page to set - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI SetConsoleOutputCP(UINT cp) -{ - FIXME("stub\n"); - return TRUE; -} - - /*********************************************************************** * GetConsoleMode (KERNEL32.@) */ @@ -931,8 +741,8 @@ BOOL WINAPI GetConsoleMode(HANDLE hcon, LPDWORD mode) SERVER_START_REQ(get_console_mode) { req->handle = hcon; - ret = !SERVER_CALL_ERR(); - if (ret && mode) *mode = req->mode; + ret = !wine_server_call_err( req ); + if (ret && mode) *mode = reply->mode; } SERVER_END_REQ; return ret; @@ -960,7 +770,7 @@ BOOL WINAPI SetConsoleMode(HANDLE hcon, DWORD mode) { req->handle = hcon; req->mode = mode; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; /* FIXME: when resetting a console input to editline mode, I think we should @@ -970,142 +780,30 @@ BOOL WINAPI SetConsoleMode(HANDLE hcon, DWORD mode) } -/*********************************************************************** - * SetConsoleTitleA (KERNEL32.@) - * - * Sets the console title. - * - * We do not necessarily need to create a complex console for that, - * but should remember the title and set it on creation of the latter. - * (not fixed at this time). - */ -BOOL WINAPI SetConsoleTitleA(LPCSTR title) -{ - LPWSTR titleW = NULL; - BOOL ret; - DWORD len; - - len = MultiByteToWideChar(CP_ACP, 0, title, -1, NULL, 0); - titleW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); - if (!titleW) return FALSE; - - MultiByteToWideChar(CP_ACP, 0, title, -1, titleW, len); - ret = SetConsoleTitleW(titleW); - - HeapFree(GetProcessHeap(), 0, titleW); - return ret; -} - - -/****************************************************************************** - * SetConsoleTitleW [KERNEL32.@] Sets title bar string for console - * - * PARAMS - * title [I] Address of new title - * - * NOTES - * This should not be calling the A version - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI SetConsoleTitleW(LPCWSTR title) -{ - size_t len = strlenW(title) * sizeof(WCHAR); - BOOL ret; - - len = min(len, REQUEST_MAX_VAR_SIZE); - SERVER_START_VAR_REQ(set_console_input_info, len) - { - req->handle = 0; - req->mask = SET_CONSOLE_INPUT_INFO_TITLE; - memcpy(server_data_ptr(req), title, len); - ret = !SERVER_CALL_ERR(); - } - SERVER_END_VAR_REQ; - - return ret; -} - -/*********************************************************************** - * GetConsoleTitleA (KERNEL32.@) - */ -DWORD WINAPI GetConsoleTitleA(LPSTR title, DWORD size) -{ - WCHAR* ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * size); - DWORD ret; - - if (!ptr) return 0; - - ret = GetConsoleTitleW(ptr, size); - if (ret) WideCharToMultiByte(CP_ACP, 0, ptr, ret + 1, title, size, NULL, NULL); - - return ret; -} - - -/****************************************************************************** - * GetConsoleTitleW [KERNEL32.@] Retrieves title string for console - * - * PARAMS - * title [O] Address of buffer for title - * size [I] Size of buffer - * - * RETURNS - * Success: Length of string copied - * Failure: 0 - */ -DWORD WINAPI GetConsoleTitleW(LPWSTR title, DWORD size) -{ - DWORD ret = 0; - - SERVER_START_VAR_REQ(get_console_input_info, REQUEST_MAX_VAR_SIZE) - { - req->handle = 0; - if (!SERVER_CALL_ERR()) - { - ret = server_data_size(req) / sizeof(WCHAR); - size = min(size - 1, ret); - memcpy(title, server_data_ptr(req), size * sizeof(WCHAR)); - title[size] = 0; - } - } - SERVER_END_VAR_REQ; - - return ret; -} - /****************************************************************** * write_char * * WriteConsoleOutput helper: hides server call semantics */ -static int write_char(HANDLE hCon, LPCVOID lpBuffer, int nc, COORD* pos) +static int write_char(HANDLE hCon, LPCWSTR lpBuffer, int nc, COORD* pos) { - BOOL ret; - int written = -1; + int written = -1; if (!nc) return 0; - assert(nc * sizeof(WCHAR) <= REQUEST_MAX_VAR_SIZE); - - SERVER_START_VAR_REQ(write_console_output, nc * sizeof(WCHAR)) + SERVER_START_REQ( write_console_output ) { - req->handle = hCon; - req->x = pos->X; - req->y = pos->Y; - req->mode = WRITE_CONSOLE_MODE_TEXTSTDATTR; - memcpy(server_data_ptr(req), lpBuffer, nc * sizeof(WCHAR)); - if ((ret = !SERVER_CALL_ERR())) - { - written = req->written; - } + req->handle = hCon; + req->x = pos->X; + req->y = pos->Y; + req->mode = CHAR_INFO_MODE_TEXTSTDATTR; + req->wrap = FALSE; + wine_server_add_data( req, lpBuffer, nc * sizeof(WCHAR) ); + if (!wine_server_call_err( req )) written = reply->written; } - SERVER_END_VAR_REQ; - - if (written > 0) pos->X += written; + SERVER_END_REQ; + if (written > 0) pos->X += written; return written; } @@ -1292,85 +990,6 @@ BOOL WINAPI WriteConsoleA(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumber return ret; } -/*********************************************************************** - * WriteConsoleOutputA (KERNEL32.@) - */ -BOOL WINAPI WriteConsoleOutputA(HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion) -{ - CHAR_INFO *ciw; - int i; - BOOL ret; - - ciw = HeapAlloc(GetProcessHeap(), 0, sizeof(CHAR_INFO) * dwBufferSize.X * dwBufferSize.Y); - if (!ciw) return FALSE; - - for (i = 0; i < dwBufferSize.X * dwBufferSize.Y; i++) - { - ciw[i].Attributes = lpBuffer[i].Attributes; - MultiByteToWideChar(CP_ACP, 0, &lpBuffer[i].Char.AsciiChar, 1, &ciw[i].Char.UnicodeChar, 1); - } - ret = WriteConsoleOutputW(hConsoleOutput, ciw, dwBufferSize, dwBufferCoord, lpWriteRegion); - HeapFree(GetProcessHeap(), 0, ciw); - - return ret; -} - -/*********************************************************************** - * WriteConsoleOutputW (KERNEL32.@) - */ -BOOL WINAPI WriteConsoleOutputW(HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpWriteRegion) -{ - short int w, h; - unsigned y; - DWORD ret = TRUE; - DWORD actual_width; - - TRACE("(%x,%p,(%d,%d),(%d,%d),(%d,%dx%d,%d)\n", - hConsoleOutput, lpBuffer, dwBufferSize.X, dwBufferSize.Y, dwBufferCoord.X, dwBufferCoord.Y, - lpWriteRegion->Left, lpWriteRegion->Top, lpWriteRegion->Right, lpWriteRegion->Bottom); - - w = min(lpWriteRegion->Right - lpWriteRegion->Left + 1, dwBufferSize.X - dwBufferCoord.X); - h = min(lpWriteRegion->Bottom - lpWriteRegion->Top + 1, dwBufferSize.Y - dwBufferCoord.Y); - - if (w <= 0 || h <= 0) - { - memset(lpWriteRegion, 0, sizeof(SMALL_RECT)); - return FALSE; - } - - /* this isn't supported for now, even if hConsoleOutput's row size fits in a single - * server's request... it would request cropping on client side - */ - if (w * sizeof(CHAR_INFO) > REQUEST_MAX_VAR_SIZE) - { - FIXME("This isn't supported yet, too wide CHAR_INFO array (%d)\n", w); - memset(lpWriteRegion, 0, sizeof(SMALL_RECT)); - return FALSE; - } - - actual_width = w; - for (y = 0; ret && y < h; y++) - { - SERVER_START_VAR_REQ(write_console_output, w * sizeof(CHAR_INFO)) - { - req->handle = hConsoleOutput; - req->mode = WRITE_CONSOLE_MODE_TEXTATTR; - req->x = lpWriteRegion->Left; - req->y = lpWriteRegion->Top + y; - memcpy(server_data_ptr(req), &lpBuffer[(y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X], w * sizeof(CHAR_INFO)); - if ((ret = !SERVER_CALL())) - actual_width = min(actual_width, req->written); - } - SERVER_END_VAR_REQ; - } - lpWriteRegion->Bottom = lpWriteRegion->Top + h; - lpWriteRegion->Right = lpWriteRegion->Left + actual_width; - - return ret; -} - /****************************************************************************** * SetConsoleCursorPosition [KERNEL32.@] * Sets the cursor position in console @@ -1396,7 +1015,7 @@ BOOL WINAPI SetConsoleCursorPosition(HANDLE hcon, COORD pos) req->cursor_x = pos.X; req->cursor_y = pos.Y; req->mask = SET_CONSOLE_OUTPUT_INFO_CURSOR_POS; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -1453,11 +1072,11 @@ BOOL WINAPI GetConsoleCursorInfo(HANDLE hcon, LPCONSOLE_CURSOR_INFO cinfo) SERVER_START_REQ(get_console_output_info) { req->handle = hcon; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); if (ret && cinfo) { - cinfo->dwSize = req->cursor_size; - cinfo->bVisible = req->cursor_visible; + cinfo->dwSize = reply->cursor_size; + cinfo->bVisible = reply->cursor_visible; } } SERVER_END_REQ; @@ -1485,7 +1104,7 @@ BOOL WINAPI SetConsoleCursorInfo(HANDLE hCon, LPCONSOLE_CURSOR_INFO cinfo) req->cursor_size = cinfo->dwSize; req->cursor_visible = cinfo->bVisible; req->mask = SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1526,7 +1145,7 @@ BOOL WINAPI SetConsoleWindowInfo(HANDLE hCon, BOOL bAbsolute, LPSMALL_RECT windo req->win_right = p.Right; req->win_bottom = p.Bottom; req->mask = SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -1550,10 +1169,10 @@ BOOL WINAPI SetConsoleTextAttribute(HANDLE hConsoleOutput, WORD wAttr) SERVER_START_REQ(set_console_output_info) { - req->handle = hConsoleOutput; - req->attr = wAttr; - req->mask = SET_CONSOLE_OUTPUT_INFO_ATTR; - ret = !SERVER_CALL_ERR(); + req->handle = hConsoleOutput; + req->attr = wAttr; + req->mask = SET_CONSOLE_OUTPUT_INFO_ATTR; + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -1575,158 +1194,19 @@ BOOL WINAPI SetConsoleScreenBufferSize(HANDLE hConsoleOutput, COORD dwSize) { BOOL ret; - /* FIXME: most code relies on the fact we can transfer a complete row at a time... - * so check if it's possible... - */ - if (dwSize.X > REQUEST_MAX_VAR_SIZE / 4) - { - FIXME("too wide width not supported\n"); - SetLastError(STATUS_INVALID_PARAMETER); - return FALSE; - } - SERVER_START_REQ(set_console_output_info) { - req->handle = hConsoleOutput; - req->width = dwSize.X; - req->height = dwSize.Y; - req->mask = SET_CONSOLE_OUTPUT_INFO_SIZE; - ret = !SERVER_CALL_ERR(); + req->handle = hConsoleOutput; + req->width = dwSize.X; + req->height = dwSize.Y; + req->mask = SET_CONSOLE_OUTPUT_INFO_SIZE; + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; } -/****************************************************************************** - * FillConsoleOutputCharacterA [KERNEL32.@] - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * cCharacter [I] Character to write - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumCharsWritten [O] Pointer to number of cells written - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI FillConsoleOutputCharacterA(HANDLE hConsoleOutput, BYTE cCharacter, - DWORD nLength, COORD dwCoord, LPDWORD lpNumCharsWritten) -{ - WCHAR wch; - - MultiByteToWideChar(CP_ACP, 0, &cCharacter, 1, &wch, 1); - - return FillConsoleOutputCharacterW(hConsoleOutput, wch, nLength, dwCoord, lpNumCharsWritten); -} - - -/****************************************************************************** - * FillConsoleOutputCharacterW [KERNEL32.@] Writes characters to console - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * cCharacter [I] Character to write - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumCharsWritten [O] Pointer to number of cells written - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI FillConsoleOutputCharacterW(HANDLE hConsoleOutput, WCHAR cCharacter, - DWORD nLength, COORD dwCoord, LPDWORD lpNumCharsWritten) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; - int written; - DWORD initLen = nLength; - - TRACE("(%d,%s,%ld,(%dx%d),%p)\n", - hConsoleOutput, debugstr_wn(&cCharacter, 1), nLength, - dwCoord.X, dwCoord.Y, lpNumCharsWritten); - - if (!GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) - return FALSE; - - while (nLength) - { - SERVER_START_VAR_REQ(write_console_output, - min(csbi.dwSize.X - dwCoord.X, nLength) * sizeof(WCHAR)) - { - req->handle = hConsoleOutput; - req->x = dwCoord.X; - req->y = dwCoord.Y; - req->mode = WRITE_CONSOLE_MODE_TEXTSTDATTR|WRITE_CONSOLE_MODE_UNIFORM; - memcpy(server_data_ptr(req), &cCharacter, sizeof(WCHAR)); - written = SERVER_CALL_ERR() ? 0 : req->written; - } - SERVER_END_VAR_REQ; - - if (!written) break; - nLength -= written; - dwCoord.X = 0; - if (++dwCoord.Y == csbi.dwSize.Y) break; - } - - if (lpNumCharsWritten) *lpNumCharsWritten = initLen - nLength; - return initLen != nLength; -} - - -/****************************************************************************** - * FillConsoleOutputAttribute [KERNEL32.@] Sets attributes for console - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * wAttribute [I] Color attribute to write - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumAttrsWritten [O] Pointer to number of cells written - * - * RETURNS - * Success: TRUE - * Failure: FALSE - */ -BOOL WINAPI FillConsoleOutputAttribute(HANDLE hConsoleOutput, WORD wAttribute, - DWORD nLength, COORD dwCoord, LPDWORD lpNumAttrsWritten) -{ - CONSOLE_SCREEN_BUFFER_INFO csbi; - int written; - DWORD initLen = nLength; - - TRACE("(%d,%d,%ld,(%dx%d),%p)\n", - hConsoleOutput, wAttribute, nLength, dwCoord.X, dwCoord.Y, lpNumAttrsWritten); - - if (!GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) - return FALSE; - - while (nLength) - { - SERVER_START_VAR_REQ(write_console_output, - min(csbi.dwSize.X - dwCoord.X, nLength) * sizeof(WCHAR)) - { - req->handle = hConsoleOutput; - req->x = dwCoord.X; - req->y = dwCoord.Y; - req->mode = WRITE_CONSOLE_MODE_ATTR|WRITE_CONSOLE_MODE_UNIFORM; - memcpy(server_data_ptr(req), &wAttribute, sizeof(WORD)); - written = SERVER_CALL_ERR() ? 0 : req->written; - } - SERVER_END_VAR_REQ; - - if (!written) break; - nLength -= written; - dwCoord.X = 0; - if (++dwCoord.Y == csbi.dwSize.Y) break; - } - - if (lpNumAttrsWritten) *lpNumAttrsWritten = initLen - nLength; - return initLen != nLength; -} - /****************************************************************************** * ScrollConsoleScreenBufferA [KERNEL32.@] * @@ -1752,16 +1232,19 @@ BOOL WINAPI ScrollConsoleScreenBufferA(HANDLE hConsoleOutput, LPSMALL_RECT lpScr */ static void fill_line_uniform(HANDLE hConsoleOutput, int i, int j, int len, LPCHAR_INFO lpFill) { - SERVER_START_VAR_REQ(write_console_output, len * sizeof(CHAR_INFO)) + SERVER_START_REQ( fill_console_output ) { - req->handle = hConsoleOutput; - req->x = i; - req->y = j; - req->mode = WRITE_CONSOLE_MODE_TEXTATTR|WRITE_CONSOLE_MODE_UNIFORM; - memcpy(server_data_ptr(req), lpFill, sizeof(CHAR_INFO)); - SERVER_CALL_ERR(); + req->handle = hConsoleOutput; + req->mode = CHAR_INFO_MODE_TEXTATTR; + req->x = i; + req->y = j; + req->count = len; + req->wrap = FALSE; + req->data.ch = lpFill->Char.UnicodeChar; + req->data.attr = lpFill->Attributes; + wine_server_call_err( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } /****************************************************************************** @@ -1836,7 +1319,7 @@ BOOL WINAPI ScrollConsoleScreenBufferW(HANDLE hConsoleOutput, LPSMALL_RECT lpScr req->y_dst = dst.Top; req->w = dst.Right - dst.Left + 1; req->h = dst.Bottom - dst.Top + 1; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; @@ -1874,350 +1357,6 @@ BOOL WINAPI ScrollConsoleScreenBufferW(HANDLE hConsoleOutput, LPSMALL_RECT lpScr return TRUE; } -/****************************************************************************** - * ReadConsoleOutputCharacterA [KERNEL32.@] - * - */ -BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE hConsoleOutput, LPSTR lpstr, DWORD toRead, - COORD coord, LPDWORD lpdword) -{ - DWORD read; - LPWSTR wptr = HeapAlloc(GetProcessHeap(), 0, toRead * sizeof(WCHAR)); - BOOL ret; - - if (lpdword) *lpdword = 0; - if (!wptr) return FALSE; - - ret = ReadConsoleOutputCharacterW(hConsoleOutput, wptr, toRead, coord, &read); - - read = WideCharToMultiByte(CP_ACP, 0, wptr, read, lpstr, toRead, NULL, NULL); - if (lpdword) *lpdword = read; - - HeapFree(GetProcessHeap(), 0, wptr); - - return ret; -} - -/****************************************************************************** - * ReadConsoleOutputCharacterW [KERNEL32.@] - * - */ -BOOL WINAPI ReadConsoleOutputCharacterW(HANDLE hConsoleOutput, LPWSTR lpstr, DWORD toRead, - COORD coord, LPDWORD lpdword) -{ - DWORD read = 0; - DWORD ret = TRUE; - int i; - DWORD* ptr; - - TRACE("(%d,%p,%ld,%dx%d,%p)\n", hConsoleOutput, lpstr, toRead, coord.X, coord.Y, lpdword); - - while (ret && (read < toRead)) - { - SERVER_START_VAR_REQ(read_console_output, REQUEST_MAX_VAR_SIZE) - { - req->handle = (handle_t)hConsoleOutput; - req->x = coord.X; - req->y = coord.Y; - req->w = REQUEST_MAX_VAR_SIZE / 4; - req->h = 1; - if ((ret = !SERVER_CALL_ERR())) - { - ptr = server_data_ptr(req); - - for (i = 0; i < req->eff_w && read < toRead; i++) - { - lpstr[read++] = LOWORD(ptr[i]); - } - coord.X = 0; coord.Y++; - } - } - SERVER_END_VAR_REQ; - } - if (lpdword) *lpdword = read; - - TRACE("=> %lu %s\n", read, debugstr_wn(lpstr, read)); - - return ret; -} - - -/****************************************************************************** - * ReadConsoleOutputA [KERNEL32.@] - * - */ -BOOL WINAPI ReadConsoleOutputA(HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpReadRegion) -{ - BOOL ret; - int x, y; - int pos; - - ret = ReadConsoleOutputW(hConsoleOutput, lpBuffer, dwBufferSize, dwBufferCoord, lpReadRegion); - if (!ret) return FALSE; - for (y = 0; y <= lpReadRegion->Bottom - lpReadRegion->Top; y++) - { - for (x = 0; x <= lpReadRegion->Right - lpReadRegion->Left; x++) - { - pos = (dwBufferCoord.Y + y) * dwBufferSize.X + dwBufferCoord.X + x; - WideCharToMultiByte(CP_ACP, 0, &lpBuffer[pos].Char.UnicodeChar, 1, - &lpBuffer[pos].Char.AsciiChar, 1, NULL, NULL); - } - } - return TRUE; -} - -/****************************************************************************** - * ReadConsoleOutputW [KERNEL32.@] - * - */ -BOOL WINAPI ReadConsoleOutputW(HANDLE hConsoleOutput, LPCHAR_INFO lpBuffer, COORD dwBufferSize, - COORD dwBufferCoord, LPSMALL_RECT lpReadRegion) -{ - int w, h; - int actual_width; - int y; - BOOL ret = TRUE; - - w = min(lpReadRegion->Right - lpReadRegion->Left + 1, dwBufferSize.X - dwBufferCoord.X); - h = min(lpReadRegion->Bottom - lpReadRegion->Top + 1, dwBufferSize.Y - dwBufferCoord.Y); - - if (w <= 0 || h <= 0) goto got_err; - - /* this isn't supported for now, even if hConsoleOutput's row size fits in a single - * server's request... it would request cropping on client side - */ - if (w * sizeof(CHAR_INFO) > REQUEST_MAX_VAR_SIZE) - { - FIXME("This isn't supported yet, too wide CHAR_INFO array (%d)\n", w); - goto got_err; - } - - actual_width = w; - for (y = 0; ret && y < h; y++) - { - SERVER_START_VAR_REQ(read_console_output, w * sizeof(CHAR_INFO)) - { - req->handle = hConsoleOutput; - req->x = lpReadRegion->Left; - req->y = lpReadRegion->Top; - req->w = w; - req->h = 1; - if ((ret = !SERVER_CALL())) - { - actual_width = min(actual_width, req->eff_w); - memcpy(&lpBuffer[(y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X], - server_data_ptr(req), - req->eff_w * sizeof(CHAR_INFO)); - } - } - SERVER_END_VAR_REQ; - } - if (!ret) goto got_err; - - lpReadRegion->Bottom = lpReadRegion->Top + y; - lpReadRegion->Right = lpReadRegion->Left + actual_width; - - return ret; - got_err: - memset(lpReadRegion, 0, sizeof(SMALL_RECT)); - return FALSE; -} - -/****************************************************************************** - * ReadConsoleOutputAttribute [KERNEL32.@] - * - */ -BOOL WINAPI ReadConsoleOutputAttribute(HANDLE hConsoleOutput, LPWORD lpAttribute, DWORD nLength, - COORD coord, LPDWORD lpNumberOfAttrsRead) -{ - DWORD read = 0; - DWORD ret = TRUE; - int i; - DWORD* ptr; - - TRACE("(%d,%p,%ld,%dx%d,%p)\n", - hConsoleOutput, lpAttribute, nLength, coord.X, coord.Y, lpNumberOfAttrsRead); - - while (ret && (read < nLength)) - { - SERVER_START_VAR_REQ(read_console_output, REQUEST_MAX_VAR_SIZE) - { - req->handle = (handle_t)hConsoleOutput; - req->x = coord.X; - req->y = coord.Y; - req->w = REQUEST_MAX_VAR_SIZE / 4; - req->h = 1; - if (SERVER_CALL_ERR()) - { - ret = FALSE; - } - else - { - ptr = server_data_ptr(req); - - for (i = 0; i < req->eff_w && read < nLength; i++) - { - lpAttribute[read++] = HIWORD(ptr[i]); - } - coord.X = 0; coord.Y++; - } - } - SERVER_END_VAR_REQ; - } - if (lpNumberOfAttrsRead) *lpNumberOfAttrsRead = read; - - return ret; -} - -/****************************************************************************** - * WriteConsoleOutputAttribute [KERNEL32.@] Sets attributes for some cells in - * the console screen buffer - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * lpAttribute [I] Pointer to buffer with write attributes - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumAttrsWritten [O] Pointer to number of cells written - * - * RETURNS - * Success: TRUE - * Failure: FALSE - * - */ -BOOL WINAPI WriteConsoleOutputAttribute(HANDLE hConsoleOutput, CONST WORD *lpAttribute, - DWORD nLength, COORD dwCoord, LPDWORD lpNumAttrsWritten) -{ - int written = 0; - int len; - BOOL ret = TRUE; - DWORD init_len = nLength; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - TRACE("(%d,%p,%ld,%dx%d,%p)\n", hConsoleOutput, - lpAttribute,nLength,dwCoord.X,dwCoord.Y,lpNumAttrsWritten); - - if (!GetConsoleScreenBufferInfo(hConsoleOutput, & csbi)) - return FALSE; - - while (ret && nLength) - { - len = min(nLength * sizeof(WORD), REQUEST_MAX_VAR_SIZE); - SERVER_START_VAR_REQ(write_console_output, len) - { - req->handle = hConsoleOutput; - req->x = dwCoord.X; - req->y = dwCoord.Y; - req->mode = WRITE_CONSOLE_MODE_ATTR; - memcpy(server_data_ptr(req), &lpAttribute[written], len); - written = (SERVER_CALL_ERR()) ? 0 : req->written; - } - SERVER_END_VAR_REQ; - - if (!written) break; - nLength -= written; - dwCoord.X = 0; - if (++dwCoord.Y == csbi.dwSize.Y) break; - } - - if (lpNumAttrsWritten) *lpNumAttrsWritten = init_len - nLength; - return nLength != init_len; -} - -/****************************************************************************** - * WriteConsoleOutputCharacterA [KERNEL32.@] Copies character to consecutive - * cells in the console screen buffer - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * lpCharacter [I] Pointer to buffer with chars to write - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumCharsWritten [O] Pointer to number of cells written - */ -BOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput, LPCSTR lpCharacter, DWORD nLength, - COORD dwCoord, LPDWORD lpNumCharsWritten) -{ - BOOL ret; - LPWSTR xstring; - DWORD n; - - TRACE("(%d,%s,%ld,%dx%d,%p)\n", hConsoleOutput, - debugstr_an(lpCharacter, nLength), nLength, dwCoord.X, dwCoord.Y, lpNumCharsWritten); - - n = MultiByteToWideChar(CP_ACP, 0, lpCharacter, nLength, NULL, 0); - - if (lpNumCharsWritten) *lpNumCharsWritten = 0; - xstring = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR)); - if (!xstring) return FALSE; - - MultiByteToWideChar(CP_ACP, 0, lpCharacter, nLength, xstring, n); - - ret = WriteConsoleOutputCharacterW(hConsoleOutput, xstring, n, dwCoord, lpNumCharsWritten); - - HeapFree(GetProcessHeap(), 0, xstring); - - return ret; -} - -/****************************************************************************** - * WriteConsoleOutputCharacterW [KERNEL32.@] Copies character to consecutive - * cells in the console screen buffer - * - * PARAMS - * hConsoleOutput [I] Handle to screen buffer - * lpCharacter [I] Pointer to buffer with chars to write - * nLength [I] Number of cells to write to - * dwCoord [I] Coords of first cell - * lpNumCharsWritten [O] Pointer to number of cells written - * - * RETURNS - * Success: TRUE - * Failure: FALSE - * - */ -BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput, LPCWSTR lpCharacter, DWORD nLength, - COORD dwCoord, LPDWORD lpNumCharsWritten) -{ - int written = 0; - int len; - DWORD init_len = nLength; - CONSOLE_SCREEN_BUFFER_INFO csbi; - - TRACE("(%d,%s,%ld,%dx%d,%p)\n", hConsoleOutput, - debugstr_wn(lpCharacter, nLength), nLength, dwCoord.X, dwCoord.Y, lpNumCharsWritten); - - if (!GetConsoleScreenBufferInfo(hConsoleOutput, &csbi)) - return FALSE; - - while (nLength) - { - len = min(nLength * sizeof(WCHAR), REQUEST_MAX_VAR_SIZE); - SERVER_START_VAR_REQ(write_console_output, len) - { - req->handle = hConsoleOutput; - req->x = dwCoord.X; - req->y = dwCoord.Y; - req->mode = WRITE_CONSOLE_MODE_TEXT; - memcpy(server_data_ptr(req), &lpCharacter[written], len); - written = (SERVER_CALL_ERR()) ? 0 : req->written; - } - SERVER_END_VAR_REQ; - - if (!written) break; - nLength -= written; - dwCoord.X += written; - if (dwCoord.X >= csbi.dwSize.X) - { - dwCoord.X = 0; - if (++dwCoord.Y == csbi.dwSize.Y) break; - } - } - - if (lpNumCharsWritten) *lpNumCharsWritten = init_len - nLength; - return nLength != init_len; -} /* ==================================================================== * @@ -2232,26 +1371,25 @@ BOOL WINAPI WriteConsoleOutputCharacterW(HANDLE hConsoleOutput, LPCWSTR lpCharac * SetConsoleCommandHistoryMode * SetConsoleNumberOfCommands[AW] */ -int CONSOLE_GetHistory(int idx, WCHAR* buf, int buf_len) +int CONSOLE_GetHistory(int idx, WCHAR* buf, int buf_len) { - int len = 0; + int len = 0; - SERVER_START_VAR_REQ(get_console_input_history, REQUEST_MAX_VAR_SIZE) + SERVER_START_REQ( get_console_input_history ) { - req->handle = 0; - req->index = idx; - if (!SERVER_CALL_ERR()) - { - len = server_data_size(req) / sizeof(WCHAR) + 1; - if (buf) - { - len = min(len, buf_len); - memcpy(buf, server_data_ptr(req), len * sizeof(WCHAR)); - buf[len - 1] = 0; - } - } - } - SERVER_END_VAR_REQ; + req->handle = 0; + req->index = idx; + if (buf && buf_len > sizeof(WCHAR)) + { + wine_server_set_reply( req, buf, buf_len - sizeof(WCHAR) ); + } + if (!wine_server_call_err( req )) + { + if (buf) buf[wine_server_reply_size(reply) / sizeof(WCHAR)] = 0; + len = reply->total / sizeof(WCHAR) + 1; + } + } + SERVER_END_REQ; return len; } @@ -2265,17 +1403,15 @@ BOOL CONSOLE_AppendHistory(const WCHAR* ptr) size_t len = strlenW(ptr); BOOL ret; - while (len && (ptr[len - 1] == '\n' || ptr[len - 1] == '\r')) - len--; + while (len && (ptr[len - 1] == '\n' || ptr[len - 1] == '\r')) len--; - len *= sizeof(WCHAR); - SERVER_START_VAR_REQ(append_console_input_history, len) + SERVER_START_REQ( append_console_input_history ) { - req->handle = 0; - memcpy(server_data_ptr(req), ptr, len); - ret = !SERVER_CALL_ERR(); + req->handle = 0; + wine_server_add_data( req, ptr, len * sizeof(WCHAR) ); + ret = !wine_server_call_err( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; return ret; } @@ -2289,8 +1425,8 @@ unsigned CONSOLE_GetNumHistoryEntries(void) unsigned ret = 0; SERVER_START_REQ(get_console_input_info) { - req->handle = 0; - if (!SERVER_CALL_ERR()) ret = req->history_index; + req->handle = 0; + if (!wine_server_call_err( req )) ret = reply->history_index; } SERVER_END_REQ; return ret; diff --git a/win32/device.c b/win32/device.c index 1e850185e4f..0856d9780a1 100644 --- a/win32/device.c +++ b/win32/device.c @@ -339,12 +339,12 @@ static const struct VxDInfo *DEVICE_GetInfo( HANDLE handle ) SERVER_START_REQ( get_file_info ) { req->handle = handle; - if (!SERVER_CALL() && - (req->type == FILE_TYPE_UNKNOWN) && - (req->attr & 0x10000)) + if (!wine_server_call( req ) && + (reply->type == FILE_TYPE_UNKNOWN) && + (reply->attr & 0x10000)) { for (info = VxDList; info->name; info++) - if (info->id == LOWORD(req->attr)) break; + if (info->id == LOWORD(reply->attr)) break; } } SERVER_END_REQ; diff --git a/win32/except.c b/win32/except.c index 849b5f41612..d10783523d0 100644 --- a/win32/except.c +++ b/win32/except.c @@ -159,29 +159,28 @@ static int send_debug_event( EXCEPTION_RECORD *rec, int first_chance, CONTEXT *c int ret; HANDLE handle = 0; - SERVER_START_VAR_REQ( queue_exception_event, sizeof(*rec) + sizeof(*context) ) + SERVER_START_REQ( queue_exception_event ) { - CONTEXT *context_ptr = server_data_ptr(req); - EXCEPTION_RECORD *rec_ptr = (EXCEPTION_RECORD *)(context_ptr + 1); req->first = first_chance; - *rec_ptr = *rec; - *context_ptr = *context; - if (!SERVER_CALL()) handle = req->handle; + wine_server_add_data( req, context, sizeof(*context) ); + wine_server_add_data( req, rec, sizeof(*rec) ); + if (!wine_server_call(req)) handle = reply->handle; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; if (!handle) return 0; /* no debugger present or other error */ /* No need to wait on the handle since the process gets suspended * once the event is passed to the debugger, so when we get back * here the event has been continued already. */ - SERVER_START_VAR_REQ( get_exception_status, sizeof(*context) ) + SERVER_START_REQ( get_exception_status ) { req->handle = handle; - if (!SERVER_CALL()) *context = *(CONTEXT *)server_data_ptr(req); - ret = req->status; + wine_server_set_reply( req, context, sizeof(*context) ); + wine_server_call( req ); + ret = reply->status; } - SERVER_END_VAR_REQ; + SERVER_END_REQ; NtClose( handle ); return ret; } diff --git a/windows/defwnd.c b/windows/defwnd.c index d56404c8c7d..7fe5e941bea 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -75,18 +75,16 @@ static void DEFWND_SetTextA( HWND hwnd, LPCSTR text ) if (!(wndPtr = WIN_GetPtr( hwnd ))) return; if ((textW = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) { - size_t len = min( REQUEST_MAX_VAR_SIZE, (count-1) * sizeof(WCHAR) ); - if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text); wndPtr->text = textW; MultiByteToWideChar( CP_ACP, 0, text, -1, textW, count ); - SERVER_START_VAR_REQ( set_window_text, len ) + SERVER_START_REQ( set_window_text ) { req->handle = hwnd; - memcpy( server_data_ptr(req), textW, len ); - SERVER_CALL(); + wine_server_add_data( req, textW, (count-1) * sizeof(WCHAR) ); + wine_server_call( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } else ERR("Not enough memory for window text\n"); @@ -113,16 +111,14 @@ static void DEFWND_SetTextW( HWND hwnd, LPCWSTR text ) if (wndPtr->text) HeapFree(GetProcessHeap(), 0, wndPtr->text); if ((wndPtr->text = HeapAlloc(GetProcessHeap(), 0, count * sizeof(WCHAR)))) { - size_t len = min( REQUEST_MAX_VAR_SIZE, (count-1) * sizeof(WCHAR) ); - strcpyW( wndPtr->text, text ); - SERVER_START_VAR_REQ( set_window_text, len ) + SERVER_START_REQ( set_window_text ) { req->handle = hwnd; - memcpy( server_data_ptr(req), wndPtr->text, len ); - SERVER_CALL(); + wine_server_add_data( req, wndPtr->text, (count-1) * sizeof(WCHAR) ); + wine_server_call( req ); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; } else ERR("Not enough memory for window text\n"); diff --git a/windows/input.c b/windows/input.c index 9004c1351e3..7a916a7fd82 100644 --- a/windows/input.c +++ b/windows/input.c @@ -110,7 +110,7 @@ static void queue_raw_hardware_message( UINT message, WPARAM wParam, LPARAM lPar req->time = time; req->info = extraInfo; req->timeout = 0; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } diff --git a/windows/message.c b/windows/message.c index 8743e7bde0b..fdd7981318b 100644 --- a/windows/message.c +++ b/windows/message.c @@ -109,7 +109,7 @@ static void queue_hardware_message( MSG *msg, ULONG_PTR extra_info, enum message req->time = msg->time; req->info = extra_info; req->timeout = 0; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } @@ -707,7 +707,7 @@ DWORD WINAPI MsgWaitForMultipleObjectsEx( DWORD count, CONST HANDLE *pHandles, req->wake_mask = (flags & MWMO_INPUTAVAILABLE) ? mask : 0; req->changed_mask = mask; req->skip_wait = 0; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; @@ -751,7 +751,7 @@ DWORD WINAPI WaitForInputIdle( HANDLE hProcess, DWORD dwTimeOut ) { req->handle = hProcess; req->timeout = dwTimeOut; - if (!(ret = SERVER_CALL_ERR())) idle_event = req->event; + if (!(ret = wine_server_call_err( req ))) idle_event = reply->event; } SERVER_END_REQ; if (ret) return WAIT_FAILED; /* error */ diff --git a/windows/painting.c b/windows/painting.c index fa579eb3eec..2963efe8fe2 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -54,7 +54,7 @@ static void add_paint_count( HWND hwnd, int incr ) { req->handle = hwnd; req->incr = incr; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; } diff --git a/windows/queue.c b/windows/queue.c index 1829d6cf055..00dd6aa22b4 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -348,8 +348,8 @@ static HQUEUE16 QUEUE_CreateMsgQueue( BOOL16 bCreatePerQData ) { SERVER_START_REQ( get_msg_queue ) { - SERVER_CALL_ERR(); - handle = req->handle; + wine_server_call_err( req ); + handle = reply->handle; } SERVER_END_REQ; if (!handle) @@ -483,8 +483,8 @@ DWORD WINAPI GetQueueStatus( UINT flags ) SERVER_START_REQ( get_queue_status ) { req->clear = 1; - SERVER_CALL(); - ret = MAKELONG( req->changed_bits & flags, req->wake_bits & flags ); + wine_server_call( req ); + ret = MAKELONG( reply->changed_bits & flags, reply->wake_bits & flags ); } SERVER_END_REQ; return ret; @@ -501,8 +501,8 @@ BOOL WINAPI GetInputState(void) SERVER_START_REQ( get_queue_status ) { req->clear = 0; - SERVER_CALL(); - ret = req->wake_bits & (QS_KEY | QS_MOUSEBUTTON); + wine_server_call( req ); + ret = reply->wake_bits & (QS_KEY | QS_MOUSEBUTTON); } SERVER_END_REQ; return ret; diff --git a/windows/timer.c b/windows/timer.c index 2168d61e4b0..2dc61fd7d77 100644 --- a/windows/timer.c +++ b/windows/timer.c @@ -154,7 +154,7 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout, req->id = id; req->rate = max( timeout, SYS_TIMER_RATE ); req->lparam = (unsigned int)winproc; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; @@ -191,7 +191,7 @@ static BOOL TIMER_KillTimer( HWND hwnd, UINT id, BOOL sys ) req->win = hwnd; req->msg = sys ? WM_SYSTIMER : WM_TIMER; req->id = id; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; diff --git a/windows/win.c b/windows/win.c index b2bdb11b403..cf39d3f79f7 100644 --- a/windows/win.c +++ b/windows/win.c @@ -94,7 +94,7 @@ static WND *create_window_handle( HWND parent, HWND owner, ATOM atom, INT size ) req->parent = parent; req->owner = owner; req->atom = atom; - if ((res = !SERVER_CALL_ERR())) handle = req->handle; + if ((res = !wine_server_call_err( req ))) handle = reply->handle; } SERVER_END_REQ; @@ -131,7 +131,7 @@ static WND *free_window_handle( HWND hwnd ) SERVER_START_REQ( destroy_window ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) user_handles[index] = NULL; else ptr = NULL; @@ -152,26 +152,34 @@ static WND *free_window_handle( HWND hwnd ) */ static HWND *list_window_children( HWND hwnd, ATOM atom, DWORD tid ) { - HWND *list = NULL; + HWND *list; + int size = 32; - SERVER_START_VAR_REQ( get_window_children, REQUEST_MAX_VAR_SIZE ) + for (;;) { - req->parent = hwnd; - req->atom = atom; - req->tid = (void *)tid; - if (!SERVER_CALL()) + int count = 0; + + if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) break; + + SERVER_START_REQ( get_window_children ) { - user_handle_t *data = server_data_ptr(req); - int i, count = server_data_size(req) / sizeof(*data); - if (count && ((list = HeapAlloc( GetProcessHeap(), 0, (count + 1) * sizeof(HWND) )))) - { - for (i = 0; i < count; i++) list[i] = data[i]; - list[i] = 0; - } + req->parent = hwnd; + req->atom = atom; + req->tid = (void *)tid; + wine_server_set_reply( req, list, (size-1) * sizeof(HWND) ); + if (!wine_server_call( req )) count = reply->count; } + SERVER_END_REQ; + if (count && count < size) + { + list[count] = 0; + return list; + } + HeapFree( GetProcessHeap(), 0, list ); + if (!count) break; + size = count + 1; /* restart with a large enough buffer */ } - SERVER_END_VAR_REQ; - return list; + return NULL; } @@ -194,19 +202,15 @@ static void send_parent_notify( HWND hwnd, UINT msg ) */ static void get_server_window_text( HWND hwnd, LPWSTR text, INT count ) { - size_t len = (count - 1) * sizeof(WCHAR); - len = min( len, REQUEST_MAX_VAR_SIZE ); - SERVER_START_VAR_REQ( get_window_text, len ) + size_t len = 0; + + SERVER_START_REQ( get_window_text ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) - { - len = server_data_size(req); - memcpy( text, server_data_ptr(req), len ); - } - else len = 0; + wine_server_set_reply( req, text, (count - 1) * sizeof(WCHAR) ); + if (!wine_server_call_err( req )) len = wine_server_reply_size(reply); } - SERVER_END_VAR_REQ; + SERVER_END_REQ; text[len / sizeof(WCHAR)] = 0; } @@ -300,7 +304,7 @@ HWND WIN_Handle32( HWND16 hwnd16 ) SERVER_START_REQ( get_window_info ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) hwnd = req->full_handle; + if (!wine_server_call_err( req )) hwnd = reply->full_handle; } SERVER_END_REQ; } @@ -400,12 +404,12 @@ void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) req->handle = hwnd; req->parent = parent; req->previous = hwndInsertAfter; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - if (req->full_parent && req->full_parent != wndPtr->parent) + if (reply->full_parent && reply->full_parent != wndPtr->parent) { wndPtr->owner = 0; /* reset owner when changing parent */ - wndPtr->parent = req->full_parent; + wndPtr->parent = reply->full_parent; } } @@ -434,7 +438,7 @@ void WIN_SetOwner( HWND hwnd, HWND owner ) { req->handle = hwnd; req->owner = owner; - if (!SERVER_CALL()) win->owner = req->full_owner; + if (!wine_server_call( req )) win->owner = reply->full_owner; } SERVER_END_REQ; WIN_ReleasePtr( win ); @@ -469,9 +473,9 @@ LONG WIN_SetStyle( HWND hwnd, LONG style ) req->handle = hwnd; req->flags = SET_WIN_STYLE; req->style = style; - if ((ok = !SERVER_CALL())) + if ((ok = !wine_server_call( req ))) { - ret = req->old_style; + ret = reply->old_style; win->dwStyle = style; } } @@ -509,9 +513,9 @@ LONG WIN_SetExStyle( HWND hwnd, LONG style ) req->handle = hwnd; req->flags = SET_WIN_EXSTYLE; req->ex_style = style; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - ret = req->old_ex_style; + ret = reply->old_ex_style; win->dwExStyle = style; } } @@ -548,7 +552,7 @@ void WIN_SetRectangles( HWND hwnd, const RECT *rectWindow, const RECT *rectClien req->client.top = rectClient->top; req->client.right = rectClient->right; req->client.bottom = rectClient->bottom; - ret = !SERVER_CALL(); + ret = !wine_server_call( req ); } SERVER_END_REQ; if (ret) @@ -1062,7 +1066,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, req->style = wndPtr->dwStyle; req->ex_style = wndPtr->dwExStyle; req->instance = (void *)wndPtr->hInstance; - SERVER_CALL(); + wine_server_call( req ); } SERVER_END_REQ; @@ -1821,15 +1825,15 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) { req->handle = hwnd; req->flags = 0; /* don't set anything, just retrieve */ - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { switch(offset) { - case GWL_STYLE: retvalue = req->style; break; - case GWL_EXSTYLE: retvalue = req->ex_style; break; - case GWL_ID: retvalue = req->id; break; - case GWL_HINSTANCE: retvalue = (ULONG_PTR)req->instance; break; - case GWL_USERDATA: retvalue = (ULONG_PTR)req->user_data; break; + case GWL_STYLE: retvalue = reply->old_style; break; + case GWL_EXSTYLE: retvalue = reply->old_ex_style; break; + case GWL_ID: retvalue = reply->old_id; break; + case GWL_HINSTANCE: retvalue = (ULONG_PTR)reply->old_instance; break; + case GWL_USERDATA: retvalue = (ULONG_PTR)reply->old_user_data; break; default: SetLastError( ERROR_INVALID_INDEX ); break; @@ -1991,29 +1995,29 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval, req->user_data = (void *)newval; break; } - if ((ok = !SERVER_CALL_ERR())) + if ((ok = !wine_server_call_err( req ))) { switch(offset) { case GWL_STYLE: wndPtr->dwStyle = newval; - retval = req->old_style; + retval = reply->old_style; break; case GWL_EXSTYLE: wndPtr->dwExStyle = newval; - retval = req->old_ex_style; + retval = reply->old_ex_style; break; case GWL_ID: wndPtr->wIDmenu = newval; - retval = req->old_id; + retval = reply->old_id; break; case GWL_HINSTANCE: wndPtr->hInstance = newval; - retval = (HINSTANCE)req->old_instance; + retval = (HINSTANCE)reply->old_instance; break; case GWL_USERDATA: wndPtr->userdata = newval; - retval = (ULONG_PTR)req->old_user_data; + retval = (ULONG_PTR)reply->old_user_data; break; } } @@ -2281,7 +2285,7 @@ BOOL WINAPI IsWindow( HWND hwnd ) SERVER_START_REQ( get_window_info ) { req->handle = hwnd; - ret = !SERVER_CALL_ERR(); + ret = !wine_server_call_err( req ); } SERVER_END_REQ; return ret; @@ -2315,10 +2319,10 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process ) SERVER_START_REQ( get_window_info ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { - tid = (DWORD)req->tid; - if (process) *process = (DWORD)req->pid; + tid = (DWORD)reply->tid; + if (process) *process = (DWORD)reply->pid; } } SERVER_END_REQ; @@ -2347,10 +2351,10 @@ HWND WINAPI GetParent( HWND hwnd ) SERVER_START_REQ( get_window_tree ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { - if (style & WS_CHILD) retvalue = req->parent; - else retvalue = req->owner; + if (style & WS_CHILD) retvalue = reply->parent; + else retvalue = reply->owner; } } SERVER_END_REQ; @@ -2372,56 +2376,43 @@ HWND WINAPI GetParent( HWND hwnd ) HWND WINAPI GetAncestor( HWND hwnd, UINT type ) { WND *win; - HWND ret = 0; - size_t size; + HWND *list, ret = 0; - for (;;) + if (type == GA_PARENT) { if (!(win = WIN_GetPtr( hwnd ))) { SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return 0; } - if (win == WND_OTHER_PROCESS) break; /* need to do it the hard way */ - ret = win->parent; - WIN_ReleasePtr( win ); - if (type == GA_PARENT) return ret; - if (!ret || ret == GetDesktopWindow()) + if (win != WND_OTHER_PROCESS) { - ret = hwnd; /* if ret is the desktop, hwnd is the root ancestor */ - goto done; + ret = win->parent; + WIN_ReleasePtr( win ); } - hwnd = ret; /* restart with parent as hwnd */ - } - - size = (type == GA_PARENT) ? sizeof(user_handle_t) : REQUEST_MAX_VAR_SIZE; - - SERVER_START_VAR_REQ( get_window_parents, size ) - { - req->handle = hwnd; - if (!SERVER_CALL()) + else /* need to query the server */ { - user_handle_t *data = server_data_ptr(req); - int count = server_data_size(req) / sizeof(*data); - if (count) + SERVER_START_REQ( get_window_tree ) { - switch(type) - { - case GA_PARENT: - ret = data[0]; - break; - case GA_ROOT: - case GA_ROOTOWNER: - if (count > 1) ret = data[count - 2]; /* get the one before the desktop */ - else ret = WIN_GetFullHandle( hwnd ); - break; - } + req->handle = hwnd; + if (!wine_server_call_err( req )) ret = reply->parent; } + SERVER_END_REQ; } + return ret; } - SERVER_END_VAR_REQ; - done: + if (!(list = WIN_ListParents( hwnd ))) return 0; + + if (!list[0] || !list[1]) ret = WIN_GetFullHandle( hwnd ); /* top-level window */ + else + { + int count = 2; + while (list[count]) count++; + ret = list[count - 2]; /* get the one before the desktop */ + } + HeapFree( GetProcessHeap(), 0, list ); + if (ret && type == GA_ROOTOWNER) { for (;;) @@ -2597,27 +2588,27 @@ HWND WINAPI GetWindow( HWND hwnd, UINT rel ) SERVER_START_REQ( get_window_tree ) { req->handle = hwnd; - if (!SERVER_CALL_ERR()) + if (!wine_server_call_err( req )) { switch(rel) { case GW_HWNDFIRST: - retval = req->first_sibling; + retval = reply->first_sibling; break; case GW_HWNDLAST: - retval = req->last_sibling; + retval = reply->last_sibling; break; case GW_HWNDNEXT: - retval = req->next_sibling; + retval = reply->next_sibling; break; case GW_HWNDPREV: - retval = req->prev_sibling; + retval = reply->prev_sibling; break; case GW_OWNER: - retval = req->owner; + retval = reply->owner; break; case GW_CHILD: - retval = req->first_child; + retval = reply->first_child; break; } } @@ -2795,29 +2786,27 @@ HWND *WIN_ListParents( HWND hwnd ) } /* at least one parent belongs to another process, have to query the server */ - SERVER_START_VAR_REQ( get_window_parents, REQUEST_MAX_VAR_SIZE ) + + for (;;) { - req->handle = hwnd; - if (!SERVER_CALL()) + count = 0; + SERVER_START_REQ( get_window_parents ) { - user_handle_t *data = server_data_ptr(req); - count = server_data_size(req) / sizeof(*data); - if (count) - { - HWND *new_list = HeapReAlloc( GetProcessHeap(), 0, - list, (count + 1) * sizeof(HWND) ); - if (new_list) - { - list = new_list; - for (pos = 0; pos < count; pos++) list[pos] = data[pos]; - list[pos] = 0; - } - else count = 0; - } + req->handle = hwnd; + wine_server_set_reply( req, list, (size-1) * sizeof(HWND) ); + if (!wine_server_call( req )) count = reply->count; } + SERVER_END_REQ; + if (!count) goto empty; + if (size > count) + { + list[count] = 0; + return list; + } + HeapFree( GetProcessHeap(), 0, list ); + size = count + 1; + if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) return NULL; } - SERVER_END_VAR_REQ; - if (count) return list; empty: HeapFree( GetProcessHeap(), 0, list ); diff --git a/windows/winpos.c b/windows/winpos.c index 64f8ddd6844..bb7e48dcfc1 100644 --- a/windows/winpos.c +++ b/windows/winpos.c @@ -189,12 +189,12 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect ) SERVER_START_REQ( get_window_rectangles ) { req->handle = hwnd; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - rect->left = req->window.left; - rect->top = req->window.top; - rect->right = req->window.right; - rect->bottom = req->window.bottom; + rect->left = reply->window.left; + rect->top = reply->window.top; + rect->right = reply->window.right; + rect->bottom = reply->window.bottom; } } SERVER_END_REQ; @@ -309,10 +309,10 @@ BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect ) SERVER_START_REQ( get_window_rectangles ) { req->handle = hwnd; - if ((ret = !SERVER_CALL_ERR())) + if ((ret = !wine_server_call_err( req ))) { - rect->right = req->client.right - req->client.left; - rect->bottom = req->client.bottom - req->client.top; + rect->right = reply->client.right - reply->client.left; + rect->bottom = reply->client.bottom - reply->client.top; } } SERVER_END_REQ; @@ -600,10 +600,10 @@ static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset ) { req->from = hwndFrom; req->to = hwndTo; - if (!SERVER_CALL()) + if (!wine_server_call( req )) { - offset->x = req->x; - offset->y = req->y; + offset->x = reply->x; + offset->y = reply->y; } } SERVER_END_REQ;