shell32: Pack the appbar data structure to allow crossing 32/64 boundaries.

This commit is contained in:
Alexandre Julliard 2010-03-30 20:48:40 +02:00
parent 01578f51ba
commit 3cd9f97149
2 changed files with 68 additions and 37 deletions

View file

@ -36,17 +36,26 @@
WINE_DEFAULT_DEBUG_CHANNEL(appbar); WINE_DEFAULT_DEBUG_CHANNEL(appbar);
struct appbar_data_msg /* platform-independent data */
{
ULONG hWnd;
UINT uCallbackMessage;
UINT uEdge;
RECT rc;
ULONGLONG lParam;
};
struct appbar_cmd struct appbar_cmd
{ {
HANDLE return_map; ULONG return_map;
DWORD return_process; DWORD return_process;
APPBARDATA abd; struct appbar_data_msg abd;
}; };
struct appbar_response struct appbar_response
{ {
UINT_PTR result; ULONGLONG result;
APPBARDATA abd; struct appbar_data_msg abd;
}; };
/************************************************************************* /*************************************************************************
@ -75,7 +84,11 @@ UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
return FALSE; return FALSE;
} }
command.abd = *data; command.abd.hWnd = HandleToLong( data->hWnd );
command.abd.uCallbackMessage = data->uCallbackMessage;
command.abd.uEdge = data->uEdge;
command.abd.rc = data->rc;
command.abd.lParam = data->lParam;
return_map = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(struct appbar_response), NULL); return_map = CreateFileMappingW(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, sizeof(struct appbar_response), NULL);
if (return_map == NULL) if (return_map == NULL)
@ -83,7 +96,7 @@ UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
ERR("couldn't create file mapping\n"); ERR("couldn't create file mapping\n");
return 0; return 0;
} }
command.return_map = return_map; command.return_map = HandleToUlong( return_map );
command.return_process = GetCurrentProcessId(); command.return_process = GetCurrentProcessId();
@ -112,8 +125,14 @@ UINT_PTR WINAPI SHAppBarMessage(DWORD msg, PAPPBARDATA data)
response = return_view; response = return_view;
ret = response->result; ret = response->result;
*data = response->abd; if (ret)
{
data->hWnd = UlongToHandle( response->abd.hWnd );
data->uCallbackMessage = response->abd.uCallbackMessage;
data->uEdge = response->abd.uEdge;
data->rc = response->abd.rc;
data->lParam = response->abd.lParam;
}
UnmapViewOfFile(return_view); UnmapViewOfFile(return_view);
CloseHandle(return_map); CloseHandle(return_map);

View file

@ -37,17 +37,26 @@
WINE_DEFAULT_DEBUG_CHANNEL(appbar); WINE_DEFAULT_DEBUG_CHANNEL(appbar);
struct appbar_data_msg /* platform-independent data */
{
LONG hWnd;
UINT uCallbackMessage;
UINT uEdge;
RECT rc;
ULONGLONG lParam;
};
struct appbar_cmd struct appbar_cmd
{ {
HANDLE return_map; ULONG return_map;
DWORD return_process; DWORD return_process;
APPBARDATA abd; struct appbar_data_msg abd;
}; };
struct appbar_response struct appbar_response
{ {
UINT_PTR result; ULONGLONG result;
APPBARDATA abd; struct appbar_data_msg abd;
}; };
static HWND appbarmsg_window = NULL; static HWND appbarmsg_window = NULL;
@ -92,12 +101,12 @@ static void send_poschanged(HWND hwnd)
} }
/* appbar_cliprect: cut out parts of the rectangle that interfere with existing appbars */ /* appbar_cliprect: cut out parts of the rectangle that interfere with existing appbars */
static void appbar_cliprect(PAPPBARDATA abd) static void appbar_cliprect( HWND hwnd, RECT *rect )
{ {
struct appbar_data* data; struct appbar_data* data;
LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry) LIST_FOR_EACH_ENTRY(data, &appbars, struct appbar_data, entry)
{ {
if (data->hwnd == abd->hWnd) if (data->hwnd == hwnd)
{ {
/* we only care about appbars that were added before this one */ /* we only care about appbars that were added before this one */
return; return;
@ -108,30 +117,31 @@ static void appbar_cliprect(PAPPBARDATA abd)
switch (data->edge) switch (data->edge)
{ {
case ABE_BOTTOM: case ABE_BOTTOM:
abd->rc.bottom = min(abd->rc.bottom, data->rc.top); rect->bottom = min(rect->bottom, data->rc.top);
break; break;
case ABE_LEFT: case ABE_LEFT:
abd->rc.left = max(abd->rc.left, data->rc.right); rect->left = max(rect->left, data->rc.right);
break; break;
case ABE_RIGHT: case ABE_RIGHT:
abd->rc.right = min(abd->rc.right, data->rc.left); rect->right = min(rect->right, data->rc.left);
break; break;
case ABE_TOP: case ABE_TOP:
abd->rc.top = max(abd->rc.top, data->rc.bottom); rect->top = max(rect->top, data->rc.bottom);
break; break;
} }
} }
} }
} }
static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd) static UINT_PTR handle_appbarmessage(DWORD msg, struct appbar_data_msg *abd)
{ {
struct appbar_data* data; struct appbar_data* data;
HWND hwnd = LongToHandle( abd->hWnd );
switch (msg) switch (msg)
{ {
case ABM_NEW: case ABM_NEW:
if (get_appbar(abd->hWnd)) if (get_appbar(hwnd))
{ {
/* fail when adding an hwnd the second time */ /* fail when adding an hwnd the second time */
return FALSE; return FALSE;
@ -143,42 +153,42 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd)
WINE_ERR("out of memory\n"); WINE_ERR("out of memory\n");
return FALSE; return FALSE;
} }
data->hwnd = abd->hWnd; data->hwnd = hwnd;
data->callback_msg = abd->uCallbackMessage; data->callback_msg = abd->uCallbackMessage;
list_add_tail(&appbars, &data->entry); list_add_tail(&appbars, &data->entry);
return TRUE; return TRUE;
case ABM_REMOVE: case ABM_REMOVE:
if ((data = get_appbar(abd->hWnd))) if ((data = get_appbar(hwnd)))
{ {
list_remove(&data->entry); list_remove(&data->entry);
send_poschanged(abd->hWnd); send_poschanged(hwnd);
HeapFree(GetProcessHeap(), 0, data); HeapFree(GetProcessHeap(), 0, data);
} }
else else
WINE_WARN("removing hwnd %p not on the list\n", abd->hWnd); WINE_WARN("removing hwnd %p not on the list\n", hwnd);
return TRUE; return TRUE;
case ABM_QUERYPOS: case ABM_QUERYPOS:
if (abd->uEdge > ABE_BOTTOM) if (abd->uEdge > ABE_BOTTOM)
WINE_WARN("invalid edge %i for %p\n", abd->uEdge, abd->hWnd); WINE_WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
appbar_cliprect(abd); appbar_cliprect( hwnd, &abd->rc );
return TRUE; return TRUE;
case ABM_SETPOS: case ABM_SETPOS:
if (abd->uEdge > ABE_BOTTOM) if (abd->uEdge > ABE_BOTTOM)
{ {
WINE_WARN("invalid edge %i for %p\n", abd->uEdge, abd->hWnd); WINE_WARN("invalid edge %i for %p\n", abd->uEdge, hwnd);
return TRUE; return TRUE;
} }
if ((data = get_appbar(abd->hWnd))) if ((data = get_appbar(hwnd)))
{ {
/* calculate acceptable space */ /* calculate acceptable space */
appbar_cliprect(abd); appbar_cliprect( hwnd, &abd->rc );
if (!EqualRect(&abd->rc, &data->rc)) if (!EqualRect(&abd->rc, &data->rc))
send_poschanged(abd->hWnd); send_poschanged(hwnd);
/* reserve that space for this appbar */ /* reserve that space for this appbar */
data->edge = abd->uEdge; data->edge = abd->uEdge;
@ -187,14 +197,14 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd)
} }
else else
{ {
WINE_WARN("app sent ABM_SETPOS message for %p without ABM_ADD\n", abd->hWnd); WINE_WARN("app sent ABM_SETPOS message for %p without ABM_ADD\n", hwnd);
} }
return TRUE; return TRUE;
case ABM_GETSTATE: case ABM_GETSTATE:
WINE_FIXME("SHAppBarMessage(ABM_GETSTATE): stub\n"); WINE_FIXME("SHAppBarMessage(ABM_GETSTATE): stub\n");
return ABS_ALWAYSONTOP | ABS_AUTOHIDE; return ABS_ALWAYSONTOP | ABS_AUTOHIDE;
case ABM_GETTASKBARPOS: case ABM_GETTASKBARPOS:
WINE_FIXME("SHAppBarMessage(ABM_GETTASKBARPOS, hwnd=%p): stub\n", abd->hWnd); WINE_FIXME("SHAppBarMessage(ABM_GETTASKBARPOS, hwnd=%p): stub\n", hwnd);
/* Report the taskbar is at the bottom of the screen. */ /* Report the taskbar is at the bottom of the screen. */
abd->rc.left = 0; abd->rc.left = 0;
abd->rc.right = GetSystemMetrics(SM_CXSCREEN); abd->rc.right = GetSystemMetrics(SM_CXSCREEN);
@ -205,10 +215,11 @@ static UINT_PTR handle_appbarmessage(DWORD msg, PAPPBARDATA abd)
case ABM_ACTIVATE: case ABM_ACTIVATE:
return TRUE; return TRUE;
case ABM_GETAUTOHIDEBAR: case ABM_GETAUTOHIDEBAR:
WINE_FIXME("SHAppBarMessage(ABM_GETAUTOHIDEBAR, hwnd=%p, edge=%x): stub\n", abd->hWnd, abd->uEdge); WINE_FIXME("SHAppBarMessage(ABM_GETAUTOHIDEBAR, hwnd=%p, edge=%x): stub\n", hwnd, abd->uEdge);
return 0; return 0;
case ABM_SETAUTOHIDEBAR: case ABM_SETAUTOHIDEBAR:
WINE_FIXME("SHAppBarMessage(ABM_SETAUTOHIDEBAR, hwnd=%p, edge=%x, lparam=%lx): stub\n", abd->hWnd, abd->uEdge, abd->lParam); WINE_FIXME("SHAppBarMessage(ABM_SETAUTOHIDEBAR, hwnd=%p, edge=%x, lparam=%s): stub\n",
hwnd, abd->uEdge, wine_dbgstr_longlong(abd->lParam));
return TRUE; return TRUE;
case ABM_WINDOWPOSCHANGED: case ABM_WINDOWPOSCHANGED:
return TRUE; return TRUE;
@ -246,7 +257,8 @@ static LRESULT CALLBACK appbar_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
return TRUE; return TRUE;
} }
if (!DuplicateHandle(return_hproc, cmd.return_map, GetCurrentProcess(), &return_map, 0, FALSE, DUPLICATE_SAME_ACCESS)) if (!DuplicateHandle(return_hproc, UlongToHandle(cmd.return_map),
GetCurrentProcess(), &return_map, 0, FALSE, DUPLICATE_SAME_ACCESS))
{ {
WINE_ERR("couldn't duplicate handle\n"); WINE_ERR("couldn't duplicate handle\n");
CloseHandle(return_hproc); CloseHandle(return_hproc);