Redesign of the server communication protocol to allow arbitrary sized

data to be exchanged.
Split request and reply structures to make backwards compatibility
easier.
Moved many console functions to dlls/kernel, added code page support,
changed a few requests to behave properly with the new protocol.
This commit is contained in:
Alexandre Julliard 2001-11-30 18:46:42 +00:00
parent 8c2e573f9d
commit 9caa71eef4
87 changed files with 4878 additions and 4520 deletions

View File

@ -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;

View File

@ -9,6 +9,7 @@ IMPORTS = ntdll
C_SRCS = \
comm.c \
console.c \
debugger.c \
format_msg.c \
kernel_main.c \

View File

@ -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;

806
dlls/kernel/console.c Normal file
View File

@ -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 <stdio.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#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__) */

View File

@ -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;

View File

@ -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;

View File

@ -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 */
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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) */

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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)

View File

@ -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);

View File

@ -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 );

File diff suppressed because it is too large Load Diff

View File

@ -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();

View File

@ -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;
}

View File

@ -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)

View File

@ -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;

View File

@ -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 );
}
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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 );

View File

@ -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;

View File

@ -5,7 +5,8 @@
*/
#include <stdio.h>
#include <wine/server.h>
#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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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 );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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 */

View File

@ -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 );

View File

@ -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 );

View File

@ -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 */

View File

@ -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 );
}
}

View File

@ -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 */

View File

@ -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 );
}
}

View File

@ -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 );

View File

@ -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 );
}
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 );
}
}

View File

@ -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

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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( &current->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]( &current->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" );

View File

@ -7,6 +7,8 @@
#ifndef __WINE_SERVER_REQUEST_H
#define __WINE_SERVER_REQUEST_H
#include <assert.h>
#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,

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}
}

View File

@ -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)
{

View File

@ -14,9 +14,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <sys/types.h>
#include <unistd.h>
#include <stdarg.h>
@ -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 );
}
}

View File

@ -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

View File

@ -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 */

File diff suppressed because it is too large Load Diff

View File

@ -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--;
}
}

View File

@ -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";

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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;
}

View File

@ -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");

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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 );

View File

@ -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;