ReactOS 0.4.16-dev-1311-g81a4d83
IsQSForward.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * PURPOSE: Tests for IsQSForward
5 * COPYRIGHT: Copyright 2025 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#include <apitest.h>
9#include <docobj.h>
10#include <shlobj.h>
11#include <shlwapi.h>
12#include <shlwapi_undoc.h>
13#include <pseh/pseh2.h>
14#include <versionhelpers.h>
15
17
18static HRESULT
19IsQSForwardMockup(_In_opt_ const GUID *pguidCmdGroup, _In_ ULONG cCmds, _In_ OLECMD *prgCmds)
20{
21 DWORD cmdFlags = 0;
22 OLECMDID cmdID;
23 ULONG iCmd;
24 enum {
25 CMD_FLAG_SUPPORTED_BASIC = 0x1,
26 CMD_FLAG_SUPPORTED_ADVANCED = 0x2,
27 CMD_FLAG_NOT_SUPPORTED = 0x4,
28 };
29
30 //TRACE("(%s, %lu, %p)\n", wine_dbgstr_guid(pguidCmdGroup), cCmds, prgCmds);
31
32 if ((LONG)cCmds <= 0)
33 return OLECMDERR_E_NOTSUPPORTED;
34
35 if (!pguidCmdGroup)
36 {
37 for (iCmd = 0; iCmd < cCmds; ++iCmd)
38 {
39 cmdID = (OLECMDID)prgCmds[iCmd].cmdID;
40 if (cmdID <= OLECMDID_PROPERTIES)
41 {
42 cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported
43 continue;
44 }
45
46 if (cmdID <= OLECMDID_PASTE || cmdID == OLECMDID_SELECTALL)
47 {
48 cmdFlags |= CMD_FLAG_SUPPORTED_BASIC;
49 continue;
50 }
51
52 if (cmdID <= OLECMDID_UPDATECOMMANDS ||
53 (OLECMDID_HIDETOOLBARS <= cmdID && cmdID != OLECMDID_ENABLE_INTERACTION))
54 {
55 cmdFlags |= CMD_FLAG_NOT_SUPPORTED; // Not supported
56 continue;
57 }
58
59 cmdFlags |= CMD_FLAG_SUPPORTED_ADVANCED;
60 }
61 }
62 else
63 {
64 if (!IsEqualGUID(CGID_Explorer, *pguidCmdGroup))
65 {
66 if (g_bVista)
67 return OLECMDERR_E_UNKNOWNGROUP;
68 else
69 return OLECMDERR_E_NOTSUPPORTED;
70 }
71
72 for (iCmd = 0; iCmd < cCmds; ++iCmd)
73 {
74 cmdID = (OLECMDID)prgCmds[iCmd].cmdID;
75 if (cmdID == OLECMDID_SELECTALL ||
76 (OLECMDID_SHOWFIND <= cmdID && cmdID <= OLECMDID_SHOWPRINT))
77 {
78 cmdFlags |= CMD_FLAG_SUPPORTED_BASIC;
79 break;
80 }
81 }
82 }
83
84 if (!cmdFlags || (cmdFlags & CMD_FLAG_NOT_SUPPORTED))
85 return OLECMDERR_E_NOTSUPPORTED; // Not supported
86
88}
89
90static HRESULT
92 _In_ IUnknown *lpUnknown,
93 _In_ INT nUnknown,
94 _In_opt_ const GUID *riidCmdGrp,
95 _In_ ULONG cCmds,
96 _Inout_ OLECMD *prgCmds,
97 _Inout_ OLECMDTEXT *pCmdText)
98{
99 //TRACE("(%p, %d, %s, %d, %p, %p)\n",
100 // lpUnknown, nUnknown, wine_dbgstr_guid(riidCmdGrp), cCmds, prgCmds, pCmdText);
101
102 HRESULT hr = IsQSForwardMockup(riidCmdGrp, cCmds, prgCmds);
103 if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0)
104 return OLECMDERR_E_NOTSUPPORTED;
105
106 return IUnknown_QueryStatus(lpUnknown, *riidCmdGrp, cCmds, prgCmds, pCmdText);
107}
108
109static HRESULT
111 _In_ IUnknown *lpUnknown,
112 _In_ INT nUnknown,
113 _In_opt_ const GUID *pguidCmdGroup,
114 _In_ DWORD nCmdID,
115 _In_ DWORD nCmdexecopt,
116 _In_ VARIANT *pvaIn,
117 _Inout_ VARIANT *pvaOut)
118{
119 //TRACE("(%p, %d, %s, %d, %d, %p, %p)\n", lpUnknown, nUnknown,
120 // wine_dbgstr_guid(pguidCmdGroup), nCmdID, nCmdexecopt, pvaIn, pvaOut);
121
122 OLECMD cmd = { nCmdID };
123 HRESULT hr = IsQSForwardMockup(pguidCmdGroup, 1, &cmd);
124 if (FAILED(hr) || !HRESULT_CODE(hr) || nUnknown <= 0)
125 return OLECMDERR_E_NOTSUPPORTED;
126
127 return IUnknown_Exec(lpUnknown, *pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut);
128}
129
132
133class CDummyClass : public IOleCommandTarget
134{
135public:
137 virtual ~CDummyClass() { }
138
139 // ** IUnknown methods **
141 {
142 if (!ppvObj)
143 return E_POINTER;
144 *ppvObj = NULL;
145 if (riid == IID_IUnknown || riid == IID_IOleCommandTarget)
146 *ppvObj = this;
147 if (*ppvObj)
148 {
149 AddRef();
150 return S_OK;
151 }
152 return E_NOINTERFACE;
153 }
155 {
156 return 2;
157 }
159 {
160 return 2;
161 }
162
163 // ** IOleCommandTarget methods **
164 STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds [], OLECMDTEXT *pCmdText) override
165 {
167 return 0xBEEFCAFE;
168 }
169 STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override
170 {
171 g_bExec = TRUE;
172 return 0x2BAD2BAD;
173 }
174
175 static void *operator new(size_t size)
176 {
177 return LocalAlloc(LPTR, size);
178 }
179 static void operator delete(void *ptr)
180 {
181 LocalFree(ptr);
182 }
183 static void operator delete(void *ptr, size_t size)
184 {
185 LocalFree(ptr);
186 }
187};
188
190{
191 OLECMD cmds[2];
192 LONG cmdID, cmdID2;
193 HRESULT ret1, ret2;
194 ULONG cCmds;
195 BOOL bExcept1, bExcept2;
196 const GUID *pGUID;
197 enum { LOW_VALUE = -1, HIGH_VALUE = OLECMDID_CLOSE };
198
199 cmds[0].cmdf = 0;
200
201 cCmds = 0;
202 pGUID = NULL;
203 for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID)
204 {
205 cmds[0].cmdID = cmdID;
206
207 ret1 = IsQSForward(*pGUID, cCmds, cmds);
208 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
209 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
210
211 ret1 = IsQSForward(*pGUID, cCmds, NULL);
212 ret2 = IsQSForwardMockup(pGUID, cCmds, NULL);
213 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
214 }
215
216 cCmds = 1;
217 for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID)
218 {
219 cmds[0].cmdID = cmdID;
220
221 pGUID = NULL;
222 ret1 = IsQSForward(*pGUID, cCmds, cmds);
223 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
224 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
225
226 ret1 = ret2 = 0xDEADFACE;
227 bExcept1 = bExcept2 = FALSE;
228
230 {
231 ret1 = IsQSForward(*pGUID, cCmds, NULL);
232 }
234 {
235 bExcept1 = TRUE;
236 }
237 _SEH2_END;
238
240 {
241 ret2 = IsQSForwardMockup(pGUID, cCmds, NULL);
242 }
244 {
245 bExcept2 = TRUE;
246 }
247 _SEH2_END;
248
249 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
250 ok((bExcept1 && bExcept2), "cmdID: %ld (%d vs %d)\n", cmdID, bExcept1, bExcept2);
251
252 pGUID = &CGID_Explorer;
253 ret1 = IsQSForward(*pGUID, cCmds, cmds);
254 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
255 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
256
257 pGUID = &IID_IUnknown;
258 ret1 = IsQSForward(*pGUID, cCmds, cmds);
259 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
260 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
261 }
262
263 cCmds = 2;
264 for (cmdID = LOW_VALUE; cmdID <= HIGH_VALUE; ++cmdID)
265 {
266 cmds[0].cmdID = cmdID;
267
268 pGUID = NULL;
269 for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2)
270 {
271 cmds[1].cmdID = cmdID2;
272 ret1 = IsQSForward(*pGUID, cCmds, cmds);
273 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
274 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
275 }
276
277 pGUID = &CGID_Explorer;
278 for (cmdID2 = LOW_VALUE; cmdID2 <= HIGH_VALUE; ++cmdID2)
279 {
280 cmds[1].cmdID = cmdID2;
281 ret1 = IsQSForward(*pGUID, cCmds, cmds);
282 ret2 = IsQSForwardMockup(pGUID, cCmds, cmds);
283 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
284 }
285 }
286}
287
289{
291 LONG cmdID;
292 OLECMD cmds[1];
293 OLECMDTEXT cmdText;
294 HRESULT ret1, ret2;
295
296 // Testing OLECMDID_PROPERTIES support
297 cmds[0].cmdID = cmdID = OLECMDID_PROPERTIES;
298
300 ret1 = MayQSForward(&dummy, 1, CGID_Explorer, _countof(cmds), cmds, &cmdText);
303
305 ret2 = MayQSForwardMockup(&dummy, 1, &CGID_Explorer, _countof(cmds), cmds, &cmdText);
308
309 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
310
311 // Testing OLECMDID_SHOWFIND support
312 cmds[0].cmdID = cmdID = OLECMDID_SHOWFIND;
313
315 ret1 = MayQSForward(&dummy, 1, CGID_Explorer, _countof(cmds), cmds, &cmdText);
318
320 ret2 = MayQSForwardMockup(&dummy, 1, &CGID_Explorer, _countof(cmds), cmds, &cmdText);
323
324 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
325}
326
328{
330 LONG cmdID;
331 HRESULT ret1, ret2;
332
333 // Testing OLECMDID_PROPERTIES support
334 cmdID = OLECMDID_PROPERTIES;
335
337 ret1 = MayExecForward(&dummy, 1, CGID_Explorer, cmdID, 0, NULL, NULL);
340
342 ret2 = MayExecForwardMockup(&dummy, 1, &CGID_Explorer, cmdID, 0, NULL, NULL);
345
346 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
347
348 // Testing OLECMDID_SHOWFIND support
349 cmdID = OLECMDID_SHOWFIND;
350
352 ret1 = MayExecForward(&dummy, 1, CGID_Explorer, cmdID, 0, NULL, NULL);
355
357 ret2 = MayExecForwardMockup(&dummy, 1, &CGID_Explorer, cmdID, 0, NULL, NULL);
360
361 ok(ret1 == ret2, "cmdID: %ld (%ld vs %ld)\n", cmdID, ret1, ret2);
362}
363
365{
367
371}
static BOOL g_bVista
Definition: IsQSForward.cpp:16
static VOID TEST_MayExecForwardMockup(VOID)
static HRESULT IsQSForwardMockup(_In_opt_ const GUID *pguidCmdGroup, _In_ ULONG cCmds, _In_ OLECMD *prgCmds)
Definition: IsQSForward.cpp:19
static HRESULT MayQSForwardMockup(_In_ IUnknown *lpUnknown, _In_ INT nUnknown, _In_opt_ const GUID *riidCmdGrp, _In_ ULONG cCmds, _Inout_ OLECMD *prgCmds, _Inout_ OLECMDTEXT *pCmdText)
Definition: IsQSForward.cpp:91
static BOOL g_bQueryStatus
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)
static VOID TEST_MayQSForwardMockup(VOID)
static BOOL g_bExec
static VOID TEST_IsQSForward(VOID)
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_int(expression, result)
Definition: atltest.h:134
COMMAND cmds[]
Definition: main.c:21
#define STDMETHODIMP
Definition: basetyps.h:43
const GUID IID_IUnknown
STDMETHODIMP_(ULONG) AddRef() override
STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) override
STDMETHODIMP_(ULONG) Release() override
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvObj) override
STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) override
virtual ~CDummyClass()
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI IsQSForward(REFGUID pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds)
Definition: ordinal.c:2353
HRESULT WINAPI IUnknown_QueryStatus(IUnknown *lpUnknown, REFGUID pguidCmdGroup, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
Definition: ordinal.c:1048
HRESULT WINAPI IUnknown_Exec(IUnknown *lpUnknown, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: ordinal.c:1087
HRESULT WINAPI MayQSForward(IUnknown *lpUnknown, PVOID lpReserved, REFGUID riidCmdGrp, ULONG cCmds, OLECMD *prgCmds, OLECMDTEXT *pCmdText)
Definition: ordinal.c:2227
HRESULT WINAPI MayExecForward(IUnknown *lpUnknown, INT nUnknown, REFGUID pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: ordinal.c:2265
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizeiptr size
Definition: glext.h:5919
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
REFIID riid
Definition: atlbase.h:39
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
ULONG AddRef()
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
static PVOID ptr
Definition: dispmode.c:27
#define _Inout_
Definition: no_sal2.h:162
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
HRESULT hr
Definition: shlfolder.c:183
#define _countof(array)
Definition: sndvol32.h:70
Definition: ftp_var.h:139
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
VERSIONHELPERAPI IsWindowsVistaOrGreater()
#define LPTR
Definition: winbase.h:414
#define FACILITY_NULL
Definition: winerror.h:22
#define E_NOINTERFACE
Definition: winerror.h:2364
#define SEVERITY_SUCCESS
Definition: winerror.h:64
#define E_POINTER
Definition: winerror.h:2365
#define HRESULT_CODE(hr)
Definition: winerror.h:76