/*
 * Unit tests for BroadcastSystemMessage
 *
 * Copyright 2008 Maarten Lankhorst
 *
 * 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_WINNT 0x0501

#include <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"

#include "wine/test.h"

typedef LONG (WINAPI *PBROADCAST)( DWORD,LPDWORD,UINT,WPARAM,LPARAM );
typedef LONG (WINAPI *PBROADCASTEX)( DWORD,LPDWORD,UINT,WPARAM,LPARAM,PBSMINFO );
static PBROADCAST pBroadcastA;
static PBROADCAST pBroadcastW;
static PBROADCASTEX pBroadcastExA;
static PBROADCASTEX pBroadcastExW;
static HANDLE hevent;

static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if (msg == WM_NULL)
    {
        trace("main_window_procA: Sleeping for %lu ms\n", wparam);
        if (wparam)
        {
            if (WaitForSingleObject(hevent, wparam) == WAIT_TIMEOUT)
                SetEvent(hevent);
        }
        trace("main_window_procA: Returning WM_NULL with parameter %08lx\n", lparam);
        return lparam;
    }

    return DefWindowProcA(hwnd, msg, wparam, lparam);
}

static BOOL init_procs(void)
{
    WNDCLASSA cls;
    HANDLE user32 = GetModuleHandle("user32");
    pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageA");
    if (!pBroadcastA)
        pBroadcastA = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessage");
    ok(pBroadcastA != NULL, "No BroadcastSystemMessage found\n");
    if (!pBroadcastA)
    {
        win_skip("BroadcastA is not available\n");
        return FALSE;
    }

    pBroadcastW = (PBROADCAST)GetProcAddress(user32, "BroadcastSystemMessageW");
    pBroadcastExA = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExA");
    pBroadcastExW = (PBROADCASTEX)GetProcAddress(user32, "BroadcastSystemMessageExW");

    hevent = CreateEventA(NULL, TRUE, FALSE, "Asynchronous checking event");

    cls.style = CS_DBLCLKS;
    cls.lpfnWndProc = main_window_procA;
    cls.cbClsExtra = 0;
    cls.cbWndExtra = 0;
    cls.hInstance = GetModuleHandleA(0);
    cls.hIcon = 0;
    cls.hCursor = LoadCursorA(0, IDC_ARROW);
    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
    cls.lpszMenuName = NULL;
    cls.lpszClassName = "MainWindowClass";

    if (!RegisterClassA(&cls))
        return FALSE;

    if (!CreateWindowExA(0, "MainWindowClass", "Main window", WS_CAPTION | WS_SYSMENU |
                               WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP, 100, 100, 200,
                               200, 0, 0, GetModuleHandle(0), NULL))
        return FALSE;
    return TRUE;
}

static void test_parameters(PBROADCAST broadcast, const char *functionname)
{
    LONG ret;
    DWORD recips;

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
    if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
    {
        win_skip("%s is not implemented\n", functionname);
        return;
    }
    ok(!ret || broken(ret), "Returned: %d\n", ret);
    if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
    ok(!ret || broken(ret), "Returned: %d\n", ret);
    if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());

#if 0 /* TODO: Check the hang flags */
    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0 );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0 );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);
#endif

    recips = BSM_APPLICATIONS;
    ResetEvent(hevent);
    ret = broadcast( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0 );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);

    SetLastError( 0xdeadbeef );
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
    if (ret)
    {
        ok(ret==1, "Returned: %d\n", ret);
        ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
        PulseEvent(hevent);

        recips = BSM_APPLICATIONS;
        ret = broadcast( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
        ok(ret==1, "Returned: %d\n", ret);
        ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
        PulseEvent(hevent);

        recips = BSM_APPLICATIONS;
        ret = broadcast( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY );
        ok(!ret, "Returned: %d\n", ret);
        ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
        PulseEvent(hevent);
    }
    else  /* BSF_SENDNOTIFYMESSAGE not supported on NT4 */
        ok( GetLastError() == ERROR_INVALID_PARAMETER, "failed with err %u\n", GetLastError() );

    recips = BSM_APPLICATIONS;
    ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);
}

/* BSF_SENDNOTIFYMESSAGE and BSF_QUERY are both synchronous within the same process
 * However you should be able to distinguish them by sending the BROADCAST_QUERY_DENY flag
 */

static void test_parametersEx(PBROADCASTEX broadcastex)
{
    LONG ret;
    DWORD recips;

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
    ok(!ret, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcastex( 0x80000000, &recips, WM_NULL, 0, 0, NULL );
    ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
    ok(!ret, "Returned: %d\n", ret);

#if 0 /* TODO: Check the hang flags */
    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOHANG|BSF_NOTIMEOUTIFNOTHUNG), &recips, WM_NULL, 30000, 0, NULL );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_QUERY|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);

    SetLastError(0xcafebabe);
    recips = BSM_APPLICATIONS;
    ret = broadcast( BSF_POSTMESSAGE|(BSF_NOTIMEOUTIFNOTHUNG|BSF_FORCEIFHUNG), &recips, WM_NULL, 30000, 0, NULL );
    ok(0, "Last error: %08x\n", GetLastError());
    ok(0, "Returned: %d\n", ret);
#endif

    recips = BSM_APPLICATIONS;
    ResetEvent(hevent);
    ret = broadcastex( BSF_POSTMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);

    recips = BSM_APPLICATIONS;
    ret = broadcastex( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
    PulseEvent(hevent);

    recips = BSM_APPLICATIONS;
    ret = broadcastex( BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);

    recips = BSM_APPLICATIONS;
    ret = broadcastex( BSF_SENDNOTIFYMESSAGE|BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
    ok(!ret, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);

    recips = BSM_APPLICATIONS;
    ret = broadcastex( 0, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    PulseEvent(hevent);
}

static BOOL (WINAPI *pOpenProcessToken)(HANDLE, DWORD, HANDLE*);
static BOOL (WINAPI *pAdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);

static void test_noprivileges(void)
{
    HANDLE advapi32 = GetModuleHandleA("advapi32");
    HANDLE token;
    DWORD recips;
    BOOL ret;

    static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
                                        BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;

    pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
    pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
    if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
    {
        skip("Can't open security token for process\n");
        return;
    }
    if (!pAdjustTokenPrivileges(token, TRUE, NULL, 0, NULL, NULL))
    {
        skip("Can't adjust security token for process\n");
        return;
    }

    trace("Trying privileged edition!\n");
    SetLastError(0xcafebabe);
    recips = BSM_ALLDESKTOPS;
    ResetEvent(hevent);
    ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    ok(recips == BSM_ALLDESKTOPS ||
       recips == BSM_ALL_RECIPS, /* win2k3 */
       "Received by: %08x\n", recips);
    PulseEvent(hevent);

    SetLastError(0xcafebabe);
    recips = BSM_ALLCOMPONENTS;
    ResetEvent(hevent);
    ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    ok(recips == BSM_ALLCOMPONENTS ||
       recips == BSM_ALL_RECIPS, /* win2k3 */
       "Received by: %08x\n", recips);
    PulseEvent(hevent);

    SetLastError(0xcafebabe);
    recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
    ResetEvent(hevent);
    ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
    ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
       recips == BSM_APPLICATIONS, /* win2k3 */
       "Received by: %08x\n", recips);
    PulseEvent(hevent);

    SetLastError(0xcafebabe);
    recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
    ResetEvent(hevent);
    ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
    ok(!ret, "Returned: %d\n", ret);
    ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
    ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
       recips == BSM_APPLICATIONS, /* win2k3 */
       "Received by: %08x\n", recips);
    PulseEvent(hevent);
}

START_TEST(broadcast)
{
    if (!init_procs())
        return;

    trace("Running BroadcastSystemMessageA tests\n");
    test_parameters(pBroadcastA, "BroadcastSystemMessageA");
    if (pBroadcastW)
    {
        trace("Running BroadcastSystemMessageW tests\n");
        test_parameters(pBroadcastW, "BroadcastSystemMessageW");
    }
    else
        win_skip("No BroadcastSystemMessageW, skipping\n");
    if (pBroadcastExA)
    {
        trace("Running BroadcastSystemMessageExA tests\n");
        test_parametersEx(pBroadcastExA);
    }
    else
        win_skip("No BroadcastSystemMessageExA, skipping\n");
    if (pBroadcastExW)
    {
        trace("Running BroadcastSystemMessageExW tests\n");
        test_parametersEx(pBroadcastExW);
        trace("Attempting privileges checking tests\n");
        test_noprivileges();
    }
    else
        win_skip("No BroadcastSystemMessageExW, skipping\n");
}
