shell32: Handle invalid cbSize in Shell_NotifyIcon[AW].

oldstable
Mikołaj Zalewski 2007-05-09 23:47:36 +02:00 committed by Alexandre Julliard
parent c904290336
commit 44e3200a8d
4 changed files with 143 additions and 7 deletions

View File

@ -45,6 +45,20 @@ static const WCHAR classname[] = /* Shell_TrayWnd */ {'S','h','e','l','l','_','T
BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
{
NOTIFYICONDATAW nidW;
INT cbSize;
/* Validate the cbSize as Windows XP does */
if (pnid->cbSize != NOTIFYICONDATAA_V1_SIZE &&
pnid->cbSize != NOTIFYICONDATAA_V2_SIZE &&
pnid->cbSize != NOTIFYICONDATAA_V3_SIZE &&
pnid->cbSize != sizeof(NOTIFYICONDATAA))
{
WARN("Invalid cbSize (%d) - using only Win95 fields (size=%d)\n",
pnid->cbSize, NOTIFYICONDATAA_V1_SIZE);
cbSize = NOTIFYICONDATAA_V1_SIZE;
}
else
cbSize = pnid->cbSize;
ZeroMemory(&nidW, sizeof(nidW));
nidW.cbSize = sizeof(nidW);
@ -58,7 +72,7 @@ BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
if (pnid->uFlags & NIF_TIP)
MultiByteToWideChar(CP_ACP, 0, pnid->szTip, -1, nidW.szTip, sizeof(nidW.szTip)/sizeof(WCHAR));
if (pnid->cbSize >= NOTIFYICONDATAA_V2_SIZE)
if (cbSize >= NOTIFYICONDATAA_V2_SIZE)
{
nidW.dwState = pnid->dwState;
nidW.dwStateMask = pnid->dwStateMask;
@ -74,10 +88,10 @@ BOOL WINAPI Shell_NotifyIconA(DWORD dwMessage, PNOTIFYICONDATAA pnid)
nidW.dwInfoFlags = pnid->dwInfoFlags;
}
if (pnid->cbSize >= NOTIFYICONDATAA_V3_SIZE)
if (cbSize >= NOTIFYICONDATAA_V3_SIZE)
nidW.guidItem = pnid->guidItem;
if (pnid->cbSize >= sizeof(NOTIFYICONDATAA))
if (cbSize >= sizeof(NOTIFYICONDATAA))
nidW.hBalloonIcon = pnid->hBalloonIcon;
return Shell_NotifyIconW(dwMessage, &nidW);
}
@ -93,6 +107,21 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
TRACE("dwMessage = %d, nid->cbSize=%d\n", dwMessage, nid->cbSize);
/* Validate the cbSize so that WM_COPYDATA doesn't crash the application */
if (nid->cbSize != NOTIFYICONDATAW_V1_SIZE &&
nid->cbSize != NOTIFYICONDATAW_V2_SIZE &&
nid->cbSize != NOTIFYICONDATAW_V3_SIZE &&
nid->cbSize != sizeof(NOTIFYICONDATAW))
{
NOTIFYICONDATAW newNid;
WARN("Invalid cbSize (%d) - using only Win95 fields (size=%d)\n",
nid->cbSize, NOTIFYICONDATAW_V1_SIZE);
CopyMemory(&newNid, nid, NOTIFYICONDATAW_V1_SIZE);
newNid.cbSize = NOTIFYICONDATAW_V1_SIZE;
return Shell_NotifyIconW(dwMessage, &newNid);
}
tray = FindWindowExW(0, NULL, classname, NULL);
if (!tray) return FALSE;
@ -131,7 +160,7 @@ BOOL WINAPI Shell_NotifyIconW(DWORD dwMessage, PNOTIFYICONDATAW nid)
}
cds.lpData = buffer;
memcpy(buffer, nid, sizeof(*nid));
memcpy(buffer, nid, nid->cbSize);
buffer += nid->cbSize;
memcpy(buffer, &bmMask, sizeof(bmMask));
buffer += sizeof(bmMask);

View File

@ -3,7 +3,7 @@ TOPOBJDIR = ../../..
SRCDIR = @srcdir@
VPATH = @srcdir@
TESTDLL = shell32.dll
IMPORTS = shell32 ole32 oleaut32 shlwapi advapi32 kernel32
IMPORTS = shell32 ole32 oleaut32 shlwapi user32 gdi32 advapi32 kernel32
EXTRALIBS = -luuid
CTESTS = \
@ -13,7 +13,8 @@ CTESTS = \
shlexec.c \
shlfileop.c \
shlfolder.c \
string.c
string.c \
systray.c
@MAKE_TEST_RULES@

View File

@ -0,0 +1,106 @@
/* Unit tests for systray
*
* Copyright 2007 Mikolaj Zalewski
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define _WIN32_IE 0x600
#include <assert.h>
#include <stdarg.h>
#include <windows.h>
#include "wine/test.h"
static HWND hMainWnd;
void test_cbsize()
{
NOTIFYICONDATAW nidW;
NOTIFYICONDATAA nidA;
ZeroMemory(&nidW, sizeof(nidW));
nidW.cbSize = NOTIFYICONDATAW_V1_SIZE;
nidW.hWnd = hMainWnd;
nidW.uID = 1;
nidW.uFlags = NIF_ICON|NIF_MESSAGE;
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
nidW.uCallbackMessage = WM_USER+17;
ok(Shell_NotifyIconW(NIM_ADD, &nidW), "NIM_ADD failed!\n");
/* using an invalid cbSize does work */
nidW.cbSize = 3;
nidW.hWnd = hMainWnd;
nidW.uID = 1;
ok(Shell_NotifyIconW(NIM_DELETE, &nidW), "NIM_DELETE failed!\n");
/* as icon doesn't exist anymore - now there will be an error */
nidW.cbSize = sizeof(nidW);
/* wine currently doesn't return error code put prints an ERR(...) */
todo_wine ok(!Shell_NotifyIconW(NIM_DELETE, &nidW), "The icon was not deleted\n");
/* same for Shell_NotifyIconA */
ZeroMemory(&nidA, sizeof(nidA));
nidA.cbSize = NOTIFYICONDATAA_V1_SIZE;
nidA.hWnd = hMainWnd;
nidA.uID = 1;
nidA.uFlags = NIF_ICON|NIF_MESSAGE;
nidA.hIcon = LoadIcon(NULL, IDI_APPLICATION);
nidA.uCallbackMessage = WM_USER+17;
ok(Shell_NotifyIconA(NIM_ADD, &nidA), "NIM_ADD failed!\n");
/* using an invalid cbSize does work */
nidA.cbSize = 3;
nidA.hWnd = hMainWnd;
nidA.uID = 1;
ok(Shell_NotifyIconA(NIM_DELETE, &nidA), "NIM_DELETE failed!\n");
/* as icon doesn't exist anymore - now there will be an error */
nidA.cbSize = sizeof(nidA);
/* wine currently doesn't return error code put prints an ERR(...) */
todo_wine ok(!Shell_NotifyIconA(NIM_DELETE, &nidA), "The icon was not deleted\n");
}
START_TEST(systray)
{
WNDCLASSA wc;
MSG msg;
RECT rc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandleA(NULL);
wc.hIcon = NULL;
wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_IBEAM));
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyTestWnd";
wc.lpfnWndProc = DefWindowProc;
RegisterClassA(&wc);
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
GetClientRect(hMainWnd, &rc);
ShowWindow(hMainWnd, SW_SHOW);
test_cbsize();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
DestroyWindow(hMainWnd);
}

View File

@ -290,7 +290,7 @@ static void delete_icon(const NOTIFYICONDATAW *nid)
if (!icon)
{
WINE_ERR("invalid tray icon ID specified: %ud\n", nid->uID);
WINE_ERR("invalid tray icon ID specified: %u\n", nid->uID);
return;
}