From 1ece13917839eed60c60d1780366a37e922df1a8 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 16 Jun 2025 07:31:47 +0900 Subject: [PATCH] [SHLWAPI][SHLWAPI_APITEST][SDK] Support MayExecForward + MayQSForward (#8125) Follow-up of #8124. Implementing missing features... JIRA issue: CORE-19278 - Implement MayExecForward and MayQSForward functions. - Modify these prototypes in . - Add tests to shlwapi_apitest IsQSForward. --- dll/win32/shlwapi/ordinal.c | 48 ++- .../rostests/apitests/shlwapi/CMakeLists.txt | 2 +- .../rostests/apitests/shlwapi/IsQSForward.c | 194 --------- .../rostests/apitests/shlwapi/IsQSForward.cpp | 371 ++++++++++++++++++ sdk/include/reactos/shlwapi_undoc.h | 22 +- 5 files changed, 438 insertions(+), 199 deletions(-) delete mode 100644 modules/rostests/apitests/shlwapi/IsQSForward.c create mode 100644 modules/rostests/apitests/shlwapi/IsQSForward.cpp diff --git a/dll/win32/shlwapi/ordinal.c b/dll/win32/shlwapi/ordinal.c index 9106c2696e5..5b6e842a4e8 100644 --- a/dll/win32/shlwapi/ordinal.c +++ b/dll/win32/shlwapi/ordinal.c @@ -2204,6 +2204,26 @@ VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown) * @ [SHLWAPI.200] * */ +#ifdef __REACTOS__ +HRESULT WINAPI +MayQSForward( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ REFGUID riidCmdGrp, + _In_ ULONG cCmds, + _Inout_ OLECMD *prgCmds, + _Inout_ OLECMDTEXT *pCmdText) +{ + TRACE("(%p, %d, %s, %d, %p, %p)\n", + lpUnknown, nUnknown, wine_dbgstr_guid(riidCmdGrp), cCmds, prgCmds, pCmdText); + + HRESULT hr = IsQSForward(riidCmdGrp, cCmds, prgCmds); + if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0) + return OLECMDERR_E_NOTSUPPORTED; + + return IUnknown_QueryStatus(lpUnknown, riidCmdGrp, cCmds, prgCmds, pCmdText); +} +#else HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved, REFGUID riidCmdGrp, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT* pCmdText) @@ -2214,19 +2234,43 @@ HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved, /* FIXME: Calls IsQSForward & IUnknown_QueryStatus */ return DRAGDROP_E_NOTREGISTERED; } +#endif /************************************************************************* * @ [SHLWAPI.201] * */ -HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup, +#ifdef __REACTOS__ +HRESULT WINAPI +MayExecForward( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ REFGUID pguidCmdGroup, + _In_ DWORD nCmdID, + _In_ DWORD nCmdexecopt, + _In_ VARIANT *pvaIn, + _Inout_ VARIANT *pvaOut) +{ + TRACE("(%p, %d, %s, %d, %d, %p, %p)\n", lpUnknown, nUnknown, + wine_dbgstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut); + + OLECMD cmd = { nCmdID }; + HRESULT hr = IsQSForward(pguidCmdGroup, 1, &cmd); + if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0) + return OLECMDERR_E_NOTSUPPORTED; + + return IUnknown_Exec(lpUnknown, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); +} +#else +HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT nUnknown, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT* pvaIn, VARIANT* pvaOut) { - FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, iUnk, pguidCmdGroup, + FIXME("(%p,%d,%p,%d,%d,%p,%p) - stub!\n", lpUnknown, nUnknown, pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); return DRAGDROP_E_NOTREGISTERED; } +#endif /************************************************************************* * @ [SHLWAPI.202] diff --git a/modules/rostests/apitests/shlwapi/CMakeLists.txt b/modules/rostests/apitests/shlwapi/CMakeLists.txt index 3138093a85e..bd7556a66bb 100644 --- a/modules/rostests/apitests/shlwapi/CMakeLists.txt +++ b/modules/rostests/apitests/shlwapi/CMakeLists.txt @@ -7,7 +7,7 @@ include_directories($) list(APPEND SOURCE AssocQueryString.c IShellFolderHelpers.cpp - IsQSForward.c + IsQSForward.cpp PathFileExistsDefExtAndAttributesW.c PathFindOnPath.c PathIsUNC.c diff --git a/modules/rostests/apitests/shlwapi/IsQSForward.c b/modules/rostests/apitests/shlwapi/IsQSForward.c deleted file mode 100644 index c4e1fa15993..00000000000 --- a/modules/rostests/apitests/shlwapi/IsQSForward.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * PROJECT: ReactOS api tests - * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) - * PURPOSE: Tests for IsQSForward - * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ - */ - -#include -#include -#include -#include -#include -#include -#include - -static BOOL g_bVista = FALSE; - -static HRESULT -IsQSForwardMockup(_In_opt_ REFGUID pguidCmdGroup, _In_ ULONG cCmds, _In_ OLECMD *prgCmds) -{ - DWORD cmdFlags = 0; - OLECMDID cmdID; - ULONG iCmd; - enum { - CMD_FLAG_SUPPORTED_BASIC = 0x1, - CMD_FLAG_SUPPORTED_ADVANCED = 0x2, - CMD_FLAG_NOT_SUPPORTED = 0x4, - }; - - //TRACE("(%s, %lu, %p)\n", wine_dbgstr_guid(pguidCmdGroup), cCmds, prgCmds); - - if ((LONG)cCmds <= 0) - return OLECMDERR_E_NOTSUPPORTED; - - if (!pguidCmdGroup) - { - for (iCmd = 0; iCmd < cCmds; ++iCmd) - { - cmdID = prgCmds[iCmd].cmdID; - if (cmdID <= OLECMDID_PROPERTIES) - { - cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported - continue; - } - - if (cmdID <= OLECMDID_PASTE || cmdID == OLECMDID_SELECTALL) - { - cmdFlags |= CMD_FLAG_SUPPORTED_BASIC; - continue; - } - - if (cmdID <= OLECMDID_UPDATECOMMANDS || - (OLECMDID_HIDETOOLBARS <= cmdID && cmdID != OLECMDID_ENABLE_INTERACTION)) - { - cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported - continue; - } - - cmdFlags |= CMD_FLAG_SUPPORTED_ADVANCED; - } - } - else - { - if (!IsEqualGUID(&CGID_Explorer, pguidCmdGroup)) - { - if (g_bVista) - return OLECMDERR_E_UNKNOWNGROUP; - else - return OLECMDERR_E_NOTSUPPORTED; - } - - for (iCmd = 0; iCmd < cCmds; ++iCmd) - { - cmdID = prgCmds[iCmd].cmdID; - if (cmdID == OLECMDID_SELECTALL || - (OLECMDID_SHOWFIND <= cmdID && cmdID <= OLECMDID_SHOWPRINT)) - { - cmdFlags |= CMD_FLAG_SUPPORTED_BASIC; - break; - } - } - } - - if (!cmdFlags || (cmdFlags & CMD_FLAG_NOT_SUPPORTED)) - return OLECMDERR_E_NOTSUPPORTED; // Not supported - - return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, cmdFlags); -} - -static VOID TEST_IsQSForward(VOID) -{ - OLECMD cmds[2]; - LONG cmdID, cmdID2; - HRESULT ret1, ret2; - ULONG cCmds; - BOOL bExcept1, bExcept2; - const GUID *pGUID; - enum { LOW_VALUE = -1, HIGH_VALUE = OLECMDID_CLOSE }; - - cmds[0].cmdf = 0; - - cCmds = 0; - pGUID = NULL; - for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) - { - cmds[0].cmdID = cmdID; - - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - - ret1 = IsQSForward(pGUID, cCmds, NULL); - ret2 = IsQSForwardMockup(pGUID, cCmds, NULL); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - } - - cCmds = 1; - for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) - { - cmds[0].cmdID = cmdID; - - pGUID = NULL; - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - - ret1 = ret2 = 0xDEADFACE; - bExcept1 = bExcept2 = FALSE; - - _SEH2_TRY - { - ret1 = IsQSForward(pGUID, cCmds, NULL); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - bExcept1 = TRUE; - } - _SEH2_END; - - _SEH2_TRY - { - ret2 = IsQSForwardMockup(pGUID, cCmds, NULL); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - bExcept2 = TRUE; - } - _SEH2_END; - - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - ok((bExcept1 && bExcept2), "cmdID: %ld (%d vs %d)\n", cmdID, bExcept1, bExcept2); - - pGUID = &CGID_Explorer; - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - - pGUID = &IID_IUnknown; - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - } - - cCmds = 2; - for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) - { - cmds[0].cmdID = cmdID; - - pGUID = NULL; - for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2) - { - cmds[1].cmdID = cmdID2; - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - } - - pGUID = &CGID_Explorer; - for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2) - { - cmds[1].cmdID = cmdID2; - ret1 = IsQSForward(pGUID, cCmds, cmds); - ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); - ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); - } - } -} - -START_TEST(IsQSForward) -{ - g_bVista = IsWindowsVistaOrGreater(); - - TEST_IsQSForward(); -} diff --git a/modules/rostests/apitests/shlwapi/IsQSForward.cpp b/modules/rostests/apitests/shlwapi/IsQSForward.cpp new file mode 100644 index 00000000000..696c3147c0d --- /dev/null +++ b/modules/rostests/apitests/shlwapi/IsQSForward.cpp @@ -0,0 +1,371 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) + * PURPOSE: Tests for IsQSForward + * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ + */ + +#include +#include +#include +#include +#include +#include +#include + +static BOOL g_bVista = FALSE; + +static HRESULT +IsQSForwardMockup(_In_opt_ const GUID *pguidCmdGroup, _In_ ULONG cCmds, _In_ OLECMD *prgCmds) +{ + DWORD cmdFlags = 0; + OLECMDID cmdID; + ULONG iCmd; + enum { + CMD_FLAG_SUPPORTED_BASIC = 0x1, + CMD_FLAG_SUPPORTED_ADVANCED = 0x2, + CMD_FLAG_NOT_SUPPORTED = 0x4, + }; + + //TRACE("(%s, %lu, %p)\n", wine_dbgstr_guid(pguidCmdGroup), cCmds, prgCmds); + + if ((LONG)cCmds <= 0) + return OLECMDERR_E_NOTSUPPORTED; + + if (!pguidCmdGroup) + { + for (iCmd = 0; iCmd < cCmds; ++iCmd) + { + cmdID = (OLECMDID)prgCmds[iCmd].cmdID; + if (cmdID <= OLECMDID_PROPERTIES) + { + cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported + continue; + } + + if (cmdID <= OLECMDID_PASTE || cmdID == OLECMDID_SELECTALL) + { + cmdFlags |= CMD_FLAG_SUPPORTED_BASIC; + continue; + } + + if (cmdID <= OLECMDID_UPDATECOMMANDS || + (OLECMDID_HIDETOOLBARS <= cmdID && cmdID != OLECMDID_ENABLE_INTERACTION)) + { + cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported + continue; + } + + cmdFlags |= CMD_FLAG_SUPPORTED_ADVANCED; + } + } + else + { + if (!IsEqualGUID(CGID_Explorer, *pguidCmdGroup)) + { + if (g_bVista) + return OLECMDERR_E_UNKNOWNGROUP; + else + return OLECMDERR_E_NOTSUPPORTED; + } + + for (iCmd = 0; iCmd < cCmds; ++iCmd) + { + cmdID = (OLECMDID)prgCmds[iCmd].cmdID; + if (cmdID == OLECMDID_SELECTALL || + (OLECMDID_SHOWFIND <= cmdID && cmdID <= OLECMDID_SHOWPRINT)) + { + cmdFlags |= CMD_FLAG_SUPPORTED_BASIC; + break; + } + } + } + + if (!cmdFlags || (cmdFlags & CMD_FLAG_NOT_SUPPORTED)) + return OLECMDERR_E_NOTSUPPORTED; // Not supported + + return MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, cmdFlags); +} + +static HRESULT +MayQSForwardMockup( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ const GUID *riidCmdGrp, + _In_ ULONG cCmds, + _Inout_ OLECMD *prgCmds, + _Inout_ OLECMDTEXT *pCmdText) +{ + //TRACE("(%p, %d, %s, %d, %p, %p)\n", + // lpUnknown, nUnknown, wine_dbgstr_guid(riidCmdGrp), cCmds, prgCmds, pCmdText); + + HRESULT hr = IsQSForwardMockup(riidCmdGrp, cCmds, prgCmds); + if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0) + return OLECMDERR_E_NOTSUPPORTED; + + return IUnknown_QueryStatus(lpUnknown, *riidCmdGrp, cCmds, prgCmds, pCmdText); +} + +static HRESULT +MayExecForwardMockup( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ const GUID *pguidCmdGroup, + _In_ DWORD nCmdID, + _In_ DWORD nCmdexecopt, + _In_ VARIANT *pvaIn, + _Inout_ VARIANT *pvaOut) +{ + //TRACE("(%p, %d, %s, %d, %d, %p, %p)\n", lpUnknown, nUnknown, + // wine_dbgstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut); + + OLECMD cmd = { nCmdID }; + HRESULT hr = IsQSForwardMockup(pguidCmdGroup, 1, &cmd); + if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0) + return OLECMDERR_E_NOTSUPPORTED; + + return IUnknown_Exec(lpUnknown, *pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut); +} + +static BOOL g_bQueryStatus = FALSE; +static BOOL g_bExec = FALSE; + +class CDummyClass : public IOleCommandTarget +{ +public: + CDummyClass() { } + virtual ~CDummyClass() { } + + // ** IUnknown methods ** + STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppvObj) override + { + if (!ppvObj) + return E_POINTER; + *ppvObj = NULL; + if (riid == IID_IUnknown || riid == IID_IOleCommandTarget) + *ppvObj = this; + if (*ppvObj) + { + AddRef(); + return S_OK; + } + return E_NOINTERFACE; + } + STDMETHODIMP_(ULONG) AddRef() override + { + return 2; + } + STDMETHODIMP_(ULONG) Release() override + { + return 2; + } + + // ** IOleCommandTarget methods ** + STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) override + { + g_bQueryStatus = TRUE; + return 0xBEEFCAFE; + } + STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override + { + g_bExec = TRUE; + return 0x2BAD2BAD; + } + + static void *operator new(size_t size) + { + return LocalAlloc(LPTR, size); + } + static void operator delete(void *ptr) + { + LocalFree(ptr); + } + static void operator delete(void *ptr, size_t size) + { + LocalFree(ptr); + } +}; + +static VOID TEST_IsQSForward(VOID) +{ + OLECMD cmds[2]; + LONG cmdID, cmdID2; + HRESULT ret1, ret2; + ULONG cCmds; + BOOL bExcept1, bExcept2; + const GUID *pGUID; + enum { LOW_VALUE = -1, HIGH_VALUE = OLECMDID_CLOSE }; + + cmds[0].cmdf = 0; + + cCmds = 0; + pGUID = NULL; + for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) + { + cmds[0].cmdID = cmdID; + + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + + ret1 = IsQSForward(*pGUID, cCmds, NULL); + ret2 = IsQSForwardMockup(pGUID, cCmds, NULL); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + } + + cCmds = 1; + for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) + { + cmds[0].cmdID = cmdID; + + pGUID = NULL; + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + + ret1 = ret2 = 0xDEADFACE; + bExcept1 = bExcept2 = FALSE; + + _SEH2_TRY + { + ret1 = IsQSForward(*pGUID, cCmds, NULL); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + bExcept1 = TRUE; + } + _SEH2_END; + + _SEH2_TRY + { + ret2 = IsQSForwardMockup(pGUID, cCmds, NULL); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + bExcept2 = TRUE; + } + _SEH2_END; + + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + ok((bExcept1 && bExcept2), "cmdID: %ld (%d vs %d)\n", cmdID, bExcept1, bExcept2); + + pGUID = &CGID_Explorer; + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + + pGUID = &IID_IUnknown; + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + } + + cCmds = 2; + for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID) + { + cmds[0].cmdID = cmdID; + + pGUID = NULL; + for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2) + { + cmds[1].cmdID = cmdID2; + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + } + + pGUID = &CGID_Explorer; + for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2) + { + cmds[1].cmdID = cmdID2; + ret1 = IsQSForward(*pGUID, cCmds, cmds); + ret2 = IsQSForwardMockup(pGUID, cCmds, cmds); + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + } + } +} + +static VOID TEST_MayQSForwardMockup(VOID) +{ + CDummyClass dummy; + LONG cmdID; + OLECMD cmds[1]; + OLECMDTEXT cmdText; + HRESULT ret1, ret2; + + // Testing OLECMDID_PROPERTIES support + cmds[0].cmdID = cmdID = OLECMDID_PROPERTIES; + + g_bQueryStatus = g_bExec = FALSE; + ret1 = MayQSForward(&dummy, 1, CGID_Explorer, _countof(cmds), cmds, &cmdText); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, FALSE); + + g_bQueryStatus = g_bExec = FALSE; + ret2 = MayQSForwardMockup(&dummy, 1, &CGID_Explorer, _countof(cmds), cmds, &cmdText); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, FALSE); + + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + + // Testing OLECMDID_SHOWFIND support + cmds[0].cmdID = cmdID = OLECMDID_SHOWFIND; + + g_bQueryStatus = g_bExec = FALSE; + ret1 = MayQSForward(&dummy, 1, CGID_Explorer, _countof(cmds), cmds, &cmdText); + ok_int(g_bQueryStatus, TRUE); + ok_int(g_bExec, FALSE); + + g_bQueryStatus = g_bExec = FALSE; + ret2 = MayQSForwardMockup(&dummy, 1, &CGID_Explorer, _countof(cmds), cmds, &cmdText); + ok_int(g_bQueryStatus, TRUE); + ok_int(g_bExec, FALSE); + + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); +} + +static VOID TEST_MayExecForwardMockup(VOID) +{ + CDummyClass dummy; + LONG cmdID; + HRESULT ret1, ret2; + + // Testing OLECMDID_PROPERTIES support + cmdID = OLECMDID_PROPERTIES; + + g_bQueryStatus = g_bExec = FALSE; + ret1 = MayExecForward(&dummy, 1, CGID_Explorer, cmdID, 0, NULL, NULL); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, FALSE); + + g_bQueryStatus = g_bExec = FALSE; + ret2 = MayExecForwardMockup(&dummy, 1, &CGID_Explorer, cmdID, 0, NULL, NULL); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, FALSE); + + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); + + // Testing OLECMDID_SHOWFIND support + cmdID = OLECMDID_SHOWFIND; + + g_bQueryStatus = g_bExec = FALSE; + ret1 = MayExecForward(&dummy, 1, CGID_Explorer, cmdID, 0, NULL, NULL); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, TRUE); + + g_bQueryStatus = g_bExec = FALSE; + ret2 = MayExecForwardMockup(&dummy, 1, &CGID_Explorer, cmdID, 0, NULL, NULL); + ok_int(g_bQueryStatus, FALSE); + ok_int(g_bExec, TRUE); + + ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2); +} + +START_TEST(IsQSForward) +{ + g_bVista = IsWindowsVistaOrGreater(); + + TEST_IsQSForward(); + TEST_MayQSForwardMockup(); + TEST_MayExecForwardMockup(); +} diff --git a/sdk/include/reactos/shlwapi_undoc.h b/sdk/include/reactos/shlwapi_undoc.h index 61896d93a29..547e5e52680 100644 --- a/sdk/include/reactos/shlwapi_undoc.h +++ b/sdk/include/reactos/shlwapi_undoc.h @@ -109,8 +109,26 @@ HRESULT WINAPI SHIsExpandableFolder(LPSHELLFOLDER lpFolder, LPCITEMIDLIST pidl); DWORD WINAPI SHFillRectClr(HDC hDC, LPCRECT pRect, COLORREF cRef); int WINAPI SHSearchMapInt(const int *lpKeys, const int *lpValues, int iLen, int iKey); VOID WINAPI IUnknown_Set(IUnknown **lppDest, IUnknown *lpUnknown); -HRESULT WINAPI MayQSForward(IUnknown* lpUnknown, PVOID lpReserved, REFGUID riidCmdGrp, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText); -HRESULT WINAPI MayExecForward(IUnknown* lpUnknown, INT iUnk, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut); + +HRESULT WINAPI +MayQSForward( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ REFGUID riidCmdGrp, + _In_ ULONG cCmds, + _Inout_ OLECMD *prgCmds, + _Inout_ OLECMDTEXT *pCmdText); + +HRESULT WINAPI +MayExecForward( + _In_ IUnknown *lpUnknown, + _In_ INT nUnknown, + _In_opt_ REFGUID pguidCmdGroup, + _In_ DWORD nCmdID, + _In_ DWORD nCmdexecopt, + _In_ VARIANT *pvaIn, + _Inout_ VARIANT *pvaOut); + HRESULT WINAPI IsQSForward(_In_opt_ REFGUID pguidCmdGroup, _In_ ULONG cCmds, _In_ OLECMD *prgCmds); BOOL WINAPI SHIsChildOrSelf(HWND hParent, HWND hChild); HRESULT WINAPI SHForwardContextMenuMsg(IUnknown* pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* pResult, BOOL useIContextMenu2);