user32: Check for invalid menu handle passed to TrackPopupMenu and TrackPopupMenuEx.

This commit is contained in:
Rein Klazes 2009-03-06 09:27:48 +01:00 committed by Alexandre Julliard
parent 29bd889cf8
commit 366334c2fa
2 changed files with 157 additions and 28 deletions

View File

@ -3447,6 +3447,40 @@ track_menu:
MENU_ExitTracking( hwnd );
}
/**********************************************************************
* TrackPopupMenuEx (USER32.@)
*/
BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
HWND hWnd, LPTPMPARAMS lpTpm )
{
BOOL ret = FALSE;
TRACE("hmenu %p flags %04x (%d,%d) hwnd %p lpTpm %p rect %s\n",
hMenu, wFlags, x, y, hWnd, lpTpm,
lpTpm ? wine_dbgstr_rect( &lpTpm->rcExclude) : "-" );
/* Parameter check */
/* FIXME: this check is performed several times, here and in the called
functions. That could be optimized */
if (!MENU_GetMenu( hMenu ))
{
SetLastError( ERROR_INVALID_MENU_HANDLE );
return FALSE;
}
MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd,
lpTpm ? &lpTpm->rcExclude : NULL );
MENU_ExitTracking(hWnd);
return ret;
}
/**********************************************************************
* TrackPopupMenu (USER32.@)
@ -3458,33 +3492,7 @@ track_menu:
BOOL WINAPI TrackPopupMenu( HMENU hMenu, UINT wFlags, INT x, INT y,
INT nReserved, HWND hWnd, const RECT *lpRect )
{
BOOL ret = FALSE;
TRACE("hmenu %p flags %04x (%d,%d) reserved %d hwnd %p rect %s\n",
hMenu, wFlags, x, y, nReserved, hWnd, wine_dbgstr_rect(lpRect));
MENU_InitTracking(hWnd, hMenu, TRUE, wFlags);
/* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( hWnd, WM_INITMENUPOPUP, (WPARAM)hMenu, 0);
if (MENU_ShowPopup( hWnd, hMenu, 0, wFlags, x, y, 0, 0 ))
ret = MENU_TrackMenu( hMenu, wFlags | TPM_POPUPMENU, 0, 0, hWnd, lpRect );
MENU_ExitTracking(hWnd);
return ret;
}
/**********************************************************************
* TrackPopupMenuEx (USER32.@)
*/
BOOL WINAPI TrackPopupMenuEx( HMENU hMenu, UINT wFlags, INT x, INT y,
HWND hWnd, LPTPMPARAMS lpTpm )
{
FIXME("not fully implemented\n" );
return TrackPopupMenu( hMenu, wFlags, x, y, 0, hWnd,
lpTpm ? &lpTpm->rcExclude : NULL );
return TrackPopupMenuEx( hMenu, wFlags, x, y, hWnd, NULL);
}
/***********************************************************************

View File

@ -140,12 +140,25 @@ static int MOD_odheight;
static SIZE MODsizes[MOD_NRMENUS]= { {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE},
{MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}};
static int MOD_GotDrawItemMsg = FALSE;
static int gflag_initmenupopup,
gflag_entermenuloop,
gflag_initmenu;
/* wndproc used by test_menu_ownerdraw() */
static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg,
WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_INITMENUPOPUP:
gflag_initmenupopup++;
break;
case WM_ENTERMENULOOP:
gflag_entermenuloop++;
break;
case WM_INITMENU:
gflag_initmenu++;
break;
case WM_MEASUREITEM:
{
MEASUREITEMSTRUCT* pmis = (MEASUREITEMSTRUCT*)lparam;
@ -2628,6 +2641,113 @@ static void test_menu_setmenuinfo(void)
return;
}
/* little func to easy switch either TrackPopupMenu() or TrackPopupMenuEx() */
static DWORD MyTrackPopupMenu( int ex, HMENU hmenu, UINT flags, INT x, INT y, HWND hwnd, LPTPMPARAMS ptpm)
{
return ex
? TrackPopupMenuEx( hmenu, flags, x, y, hwnd, ptpm)
: TrackPopupMenu( hmenu, flags, x, y, 0, hwnd, NULL);
}
/* some TrackPopupMenu and TrackPopupMenuEx tests */
/* the LastError values differ between NO_ERROR and invalid handle */
/* between all windows versions tested. The first value is that valid on XP */
/* Vista was the only that made returned different error values */
/* between the TrackPopupMenu and TrackPopupMenuEx functions */
static void test_menu_trackpopupmenu(void)
{
BOOL ret;
HMENU hmenu;
DWORD gle;
int Ex;
HWND hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL,
WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
NULL, NULL, NULL, NULL);
ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
if (!hwnd) return;
SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG_PTR)menu_ownerdraw_wnd_proc);
for( Ex = 0; Ex < 2; Ex++)
{
hmenu = CreatePopupMenu();
ok(hmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
if (!hmenu)
{
DestroyWindow(hwnd);
return;
}
/* display the menu */
/* start with an invalid menu handle */
gle = 0xdeadbeef;
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, NULL, 0x100, 100,100, hwnd, NULL);
gle = GetLastError();
ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
ok( gle == ERROR_INVALID_MENU_HANDLE
|| broken (gle == 0xdeadbeef) /* win95 */
|| broken (gle == NO_ERROR) /* win98/ME */
,"TrackPopupMenu%s error got %u expected %u\n",
Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu),
"got unexpected message(s)%s%s%s\n",
gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
gflag_initmenu ? "WM_INITMENU": "");
/* another one but not NULL */
gle = 0xdeadbeef;
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, (HMENU)hwnd, 0x100, 100,100, hwnd, NULL);
gle = GetLastError();
ok( !ret, "TrackPopupMenu%s should have failed\n", Ex ? "Ex" : "");
ok( gle == ERROR_INVALID_MENU_HANDLE
|| broken (gle == 0xdeadbeef) /* win95 */
|| broken (gle == NO_ERROR) /* win98/ME */
,"TrackPopupMenu%s error got %u expected %u\n",
Ex ? "Ex" : "", gle, ERROR_INVALID_MENU_HANDLE);
ok( !(gflag_initmenupopup || gflag_entermenuloop || gflag_initmenu),
"got unexpected message(s)%s%s%s\n",
gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
gflag_entermenuloop ? "WM_INITMENULOOP ": "",
gflag_initmenu ? "WM_INITMENU": "");
/* now a somewhat successfull call */
gle = 0xdeadbeef;
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL);
gle = GetLastError();
ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
ok( gle == NO_ERROR
|| gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k */
|| broken (gle == 0xdeadbeef) /* win95 */
,"TrackPopupMenu%s error got %u expected %u or %u\n",
Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu,
"missed expected message(s)%s%s%s\n",
!gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
!gflag_entermenuloop ? "WM_INITMENULOOP ": "",
!gflag_initmenu ? "WM_INITMENU": "");
/* and another */
ret = AppendMenuA( hmenu, MF_STRING, 1, "winetest");
ok( ret, "AppendMenA has failed!\n");
gle = 0xdeadbeef;
gflag_initmenupopup = gflag_entermenuloop = gflag_initmenu = 0;
ret = MyTrackPopupMenu( Ex, hmenu, 0x100, 100,100, hwnd, NULL);
gle = GetLastError();
ok( ret == 0, "TrackPopupMenu%s returned %d expected zero\n", Ex ? "Ex" : "", ret);
ok( gle == NO_ERROR
|| gle == ERROR_INVALID_MENU_HANDLE /* NT4, win2k and Vista in the TrackPopupMenuEx case */
|| broken (gle == 0xdeadbeef) /* win95 */
,"TrackPopupMenu%s error got %u expected %u or %u\n",
Ex ? "Ex" : "", gle, NO_ERROR, ERROR_INVALID_MENU_HANDLE);
ok( gflag_initmenupopup && gflag_entermenuloop && gflag_initmenu,
"missed expected message(s)%s%s%s\n",
!gflag_initmenupopup ? " WM_INITMENUPOPUP ": " ",
!gflag_entermenuloop ? "WM_INITMENULOOP ": "",
!gflag_initmenu ? "WM_INITMENU": "");
DestroyMenu(hmenu);
}
/* clean up */
DestroyWindow(hwnd);
}
START_TEST(menu)
{
init_function_pointers();
@ -2663,4 +2783,5 @@ START_TEST(menu)
test_menu_flags();
test_menu_hilitemenuitem();
test_menu_trackpopupmenu();
}