Don't bother to return partial region data in get_window_region and
get_visible_region, return STATUS_BUFFER_OVERFLOW instead.
This commit is contained in:
parent
e1db054315
commit
807fe07417
|
@ -33,6 +33,7 @@
|
|||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "winerror.h"
|
||||
#include "ntstatus.h"
|
||||
#include "wownt32.h"
|
||||
#include "wine/wingdi16.h"
|
||||
|
||||
|
@ -138,9 +139,9 @@ static int clip_children( HWND parent, HWND last, HRGN hrgn, int whole_window )
|
|||
static HRGN get_server_visible_region( HWND hwnd, HWND top, UINT flags )
|
||||
{
|
||||
RGNDATA *data;
|
||||
NTSTATUS status;
|
||||
HRGN ret = 0;
|
||||
size_t size = 256;
|
||||
BOOL retry = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -151,28 +152,22 @@ static HRGN get_server_visible_region( HWND hwnd, HWND top, UINT flags )
|
|||
req->top_win = top;
|
||||
req->flags = flags;
|
||||
wine_server_set_reply( req, data->Buffer, size );
|
||||
if (!wine_server_call_err( req ))
|
||||
if (!(status = wine_server_call( req )))
|
||||
{
|
||||
if (reply->total_size <= size)
|
||||
{
|
||||
size_t reply_size = wine_server_reply_size( reply );
|
||||
data->rdh.dwSize = sizeof(data->rdh);
|
||||
data->rdh.iType = RDH_RECTANGLES;
|
||||
data->rdh.nCount = reply_size / sizeof(RECT);
|
||||
data->rdh.nRgnSize = reply_size;
|
||||
ret = ExtCreateRegion( NULL, size, data );
|
||||
retry = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = reply->total_size;
|
||||
retry = TRUE;
|
||||
}
|
||||
size_t reply_size = wine_server_reply_size( reply );
|
||||
data->rdh.dwSize = sizeof(data->rdh);
|
||||
data->rdh.iType = RDH_RECTANGLES;
|
||||
data->rdh.nCount = reply_size / sizeof(RECT);
|
||||
data->rdh.nRgnSize = reply_size;
|
||||
ret = ExtCreateRegion( NULL, size, data );
|
||||
}
|
||||
else size = reply->total_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
} while (retry);
|
||||
} while (status == STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -618,19 +618,23 @@ void set_region_rect( struct region *region, const rectangle_t *rect )
|
|||
}
|
||||
|
||||
/* retrieve the region data for sending to the client */
|
||||
rectangle_t *get_region_data( const struct region *region, size_t *total_size )
|
||||
rectangle_t *get_region_data( const struct region *region, size_t max_size, size_t *total_size )
|
||||
{
|
||||
const rectangle_t *data = region->rects;
|
||||
|
||||
if (!(*total_size = region->num_rects * sizeof(rectangle_t)))
|
||||
{
|
||||
/* return a single empty rect for empty regions */
|
||||
*total_size = sizeof(empty_rect);
|
||||
return memdup( &empty_rect, sizeof(empty_rect) );
|
||||
data = &empty_rect;
|
||||
}
|
||||
return memdup( region->rects, *total_size );
|
||||
if (max_size >= *total_size) return memdup( data, *total_size );
|
||||
set_error( STATUS_BUFFER_OVERFLOW );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* retrieve the region data for sending to the client and free the region at the same time */
|
||||
rectangle_t *get_region_data_and_free( struct region *region, size_t *total_size )
|
||||
rectangle_t *get_region_data_and_free( struct region *region, size_t max_size, size_t *total_size )
|
||||
{
|
||||
rectangle_t *ret = region->rects;
|
||||
|
||||
|
@ -638,7 +642,18 @@ rectangle_t *get_region_data_and_free( struct region *region, size_t *total_size
|
|||
{
|
||||
/* return a single empty rect for empty regions */
|
||||
*total_size = sizeof(empty_rect);
|
||||
ret = memdup( &empty_rect, sizeof(empty_rect) );
|
||||
if (max_size >= sizeof(empty_rect))
|
||||
{
|
||||
ret = memdup( &empty_rect, sizeof(empty_rect) );
|
||||
free( region->rects );
|
||||
}
|
||||
}
|
||||
|
||||
if (max_size < *total_size)
|
||||
{
|
||||
free( region->rects );
|
||||
set_error( STATUS_BUFFER_OVERFLOW );
|
||||
ret = NULL;
|
||||
}
|
||||
free( region );
|
||||
return ret;
|
||||
|
|
|
@ -71,8 +71,10 @@ extern struct region *create_region( const rectangle_t *rects, unsigned int nb_r
|
|||
extern struct region *create_region_from_req_data( const void *data, size_t size );
|
||||
extern void free_region( struct region *region );
|
||||
extern void set_region_rect( struct region *region, const rectangle_t *rect );
|
||||
extern rectangle_t *get_region_data( const struct region *region, size_t *total_size );
|
||||
extern rectangle_t *get_region_data_and_free( struct region *region, size_t *total_size );
|
||||
extern rectangle_t *get_region_data( const struct region *region, size_t max_size,
|
||||
size_t *total_size );
|
||||
extern rectangle_t *get_region_data_and_free( struct region *region, size_t max_size,
|
||||
size_t *total_size );
|
||||
extern int is_region_empty( const struct region *region );
|
||||
extern void get_region_extents( const struct region *region, rectangle_t *rect );
|
||||
extern void offset_region( struct region *region, int x, int y );
|
||||
|
|
|
@ -1084,8 +1084,8 @@ DECL_HANDLER(get_visible_region)
|
|||
|
||||
if ((region = get_visible_region( win, top, req->flags )))
|
||||
{
|
||||
rectangle_t *data = get_region_data_and_free( region, &reply->total_size );
|
||||
set_reply_data_ptr( data, min(reply->total_size,get_reply_max_size()) );
|
||||
rectangle_t *data = get_region_data_and_free( region, get_reply_max_size(), &reply->total_size );
|
||||
if (data) set_reply_data_ptr( data, reply->total_size );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1097,11 +1097,10 @@ DECL_HANDLER(get_window_region)
|
|||
|
||||
if (!win) return;
|
||||
|
||||
reply->total_size = 0;
|
||||
if (win->win_region)
|
||||
{
|
||||
rectangle_t *data = get_region_data( win->win_region, &reply->total_size );
|
||||
set_reply_data_ptr( data, min( reply->total_size, get_reply_max_size() ) );
|
||||
rectangle_t *data = get_region_data( win->win_region, get_reply_max_size(), &reply->total_size );
|
||||
if (data) set_reply_data_ptr( data, reply->total_size );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winerror.h"
|
||||
#include "ntstatus.h"
|
||||
#include "wine/winuser16.h"
|
||||
#include "wine/server.h"
|
||||
#include "controls.h"
|
||||
|
@ -172,10 +173,10 @@ BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
|
|||
int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
|
||||
{
|
||||
int nRet = ERROR;
|
||||
NTSTATUS status;
|
||||
HRGN win_rgn = 0;
|
||||
RGNDATA *data;
|
||||
size_t size = 256;
|
||||
BOOL retry = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -188,31 +189,26 @@ int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
|
|||
{
|
||||
req->window = hwnd;
|
||||
wine_server_set_reply( req, data->Buffer, size );
|
||||
if (!wine_server_call_err( req ))
|
||||
if (!(status = wine_server_call( req )))
|
||||
{
|
||||
if (!reply->total_size) retry = FALSE; /* no region at all */
|
||||
else if (reply->total_size <= size)
|
||||
size_t reply_size = wine_server_reply_size( reply );
|
||||
if (reply_size)
|
||||
{
|
||||
size_t reply_size = wine_server_reply_size( reply );
|
||||
data->rdh.dwSize = sizeof(data->rdh);
|
||||
data->rdh.iType = RDH_RECTANGLES;
|
||||
data->rdh.nCount = reply_size / sizeof(RECT);
|
||||
data->rdh.nRgnSize = reply_size;
|
||||
win_rgn = ExtCreateRegion( NULL, size, data );
|
||||
retry = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = reply->total_size;
|
||||
retry = TRUE;
|
||||
}
|
||||
}
|
||||
else size = reply->total_size;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
HeapFree( GetProcessHeap(), 0, data );
|
||||
} while (retry);
|
||||
} while (status == STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
if (win_rgn)
|
||||
if (status) SetLastError( RtlNtStatusToDosError(status) );
|
||||
else if (win_rgn)
|
||||
{
|
||||
nRet = CombineRgn( hrgn, win_rgn, 0, RGN_COPY );
|
||||
DeleteObject( win_rgn );
|
||||
|
|
Loading…
Reference in New Issue