ReactOS 0.4.17-dev-444-g71ee754
CShellDispatch.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS API tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for CShellDispatch
5 * COPYRIGHT: Copyright 2026 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#include "shelltest.h"
9#include <oleauto.h>
10#include <shellutils.h>
11
13{
15 HANDLE hFind = FindFirstFileW(Path, &wfd);
16 if (hFind == INVALID_HANDLE_VALUE)
17 return -1;
18 FindClose(hFind);
19 return wfd.nFileSizeLow;
20}
21
23{
24 if (!pV)
25 return;
26 VariantClear(pV);
27 V_BSTR(pV) = (BSTR)(SIZE_T)0xBAADF00Dul;
28}
29
30template<class T> static void SafeRelease(T &p)
31{
32 if (!p)
33 return;
34 p->Release();
35 p = NULL;
36}
37
38template<class T> static HRESULT CreateFolderFromNameSpace(T Dir, Folder **ppsdf)
39{
40 *ppsdf = NULL;
41 CComPtr<IShellDispatch> pSD;
42 HRESULT hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellDispatch, &pSD));
43 if (FAILED(hr))
44 return -1; // Special return value so we know to skip
45
46 VARIANT vDir = { VT_I4 };
47 V_I4(&vDir) = (UINT)(SIZE_T)Dir;
48 if (!IS_INTRESOURCE((SIZE_T)Dir))
49 {
51 if (!bs)
52 return E_OUTOFMEMORY;
53 V_VT(&vDir) = VT_BSTR;
54 V_BSTR(&vDir) = bs;
55 }
56 hr = pSD->NameSpace(vDir, ppsdf);
57 VariantClear(&vDir);
58 return hr;
59}
60
61#define ok_NameSpaceFolderParseIsPath(ns, parse, path, mustexist, hrparse) do \
62{ \
63 if ((mustexist) && GetFileAttributesW((path)) == INVALID_FILE_ATTRIBUTES) \
64 { \
65 skip("Can't ParseName because \"%ls\" does not exist\n", (path)); \
66 break; \
67 } \
68 hr = CreateFolderFromNameSpace((ns), &psdf); \
69 ok_long(hr, S_OK); \
70 if (SUCCEEDED(hr) && psdf) \
71 { \
72 FolderItem *pfi = NULL; \
73 hr = psdf->ParseName((BSTR)(parse), &pfi); \
74 ok_long(hr, (hrparse)); \
75 if (SUCCEEDED(hr) && pfi) \
76 { \
77 BSTR bs = NULL; \
78 hr = pfi->get_Path(&bs); \
79 ok_long(hr, S_OK); \
80 ok(SUCCEEDED(hr) && !lstrcmpiW(bs, (path)), "ParseName path \"%ls\" is not \"%ls\"\n", bs, (path)); \
81 SysFreeString(SUCCEEDED(hr) ? bs : NULL); \
82 SafeRelease(pfi); \
83 } \
84 } \
85 SafeRelease(psdf); \
86} while (0)
87
89{
90 HRESULT hr;
91 Folder *psdf = NULL;
92 FolderItem *psdfi = NULL;
93 WCHAR buf1[MAX_PATH], buf2[MAX_PATH];
94
95 hr = CreateFolderFromNameSpace(CSIDL_DESKTOP, &psdf); // Root folder
96 ok_long(hr, S_OK);
97 if (hr == -1)
98 {
99 skip("Unable to initialize test\n");
100 return;
101 }
102 SafeRelease(psdf);
103
104 hr = CreateFolderFromNameSpace(CSIDL_CONTROLS, &psdf); // Virtual folder
105 ok_long(hr, S_OK);
106 SafeRelease(psdf);
107
109 ok_long(hr, S_OK);
110 if (SUCCEEDED(hr))
111 {
112 hr = psdf->ParseName((BSTR)L"X:\\DoesNotExist.xyz", (psdfi = NULL, &psdfi));
113 ok(hr != S_OK, "Must fail parsing\n");
114 SafeRelease(psdfi);
115 }
116 SafeRelease(psdf);
117
119 ok_long(hr, S_OK);
120 if (SUCCEEDED(hr))
121 {
122 hr = psdf->ParseName((BSTR)L"", (psdfi = NULL, &psdfi));
123 ok_long(hr, S_OK);
124 SafeRelease(psdfi);
125 }
126 SafeRelease(psdf);
127
128 hr = CreateFolderFromNameSpace(L"", &psdf);
129 ok(hr == S_OK || hr == S_FALSE, "Empty NS"); // S_FALSE on XP
130 SafeRelease(psdf);
131
132 ok_NameSpaceFolderParseIsPath(CSIDL_DESKTOP, L"", L"::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", false, S_OK); // My Computer
133
136
137 GetShortPathNameW(buf1, buf2, _countof(buf2)); // c:\progra~1
138 ok_NameSpaceFolderParseIsPath(CSIDL_DESKTOP, buf2, buf1, true, S_OK); // ParseName+get_Path returns the long path
139}
140
141static void TestFolderItem()
142{
144 VARIANT v = {};
145 Folder *psdf = NULL;
146 FolderItem *psdfi = NULL;
147 FolderItem2 *psdfi2;
149 if (hr == -1)
150 {
151 skip("Unable to initialize test\n");
152 return;
153 }
155 hr = psdf->ParseName(buf, &psdfi);
156 if ((ok(SUCCEEDED(hr), "ParseName %ls failed\n", buf), SUCCEEDED(hr)))
157 {
158 hr = psdfi->get_IsFileSystem(&V_BOOL(&v));
159 ok(hr == S_OK && V_BOOL(&v), "IsFileSystem");
160
161 hr = psdfi->get_IsFolder(&V_BOOL(&v));
162 ok(hr == S_OK && !V_BOOL(&v), "!IsFolder");
163
164 hr = psdfi->get_Size(&V_I4(&v));
165 ok(hr == S_OK && V_I4(&v) == GetFileSize(buf), "Size");
166
167 hr = psdfi->QueryInterface(IID_PPV_ARG(FolderItem2, &psdfi2));
168 if ((ok(SUCCEEDED(hr), "QI FolderItem2\n", buf), SUCCEEDED(hr)))
169 {
170 hr = psdfi2->ExtendedProperty((BSTR)L"Size", &v);
171 if ((ok(SUCCEEDED(hr), "ExtendedProperty failed\n"), SUCCEEDED(hr)))
172 {
173 VariantChangeType(&v, &v, 0, VT_I4);
174 ok(V_I4(&v) == GetFileSize(buf), "Wrong size from property\n");
176 }
177 SafeRelease(psdfi2);
178 }
179 SafeRelease(psdfi);
180 }
181 SafeRelease(psdf);
182}
183
185{
186 CCoInit ComInit;
187
190
191 HRESULT hr;
192 CComPtr<IShellDispatch2> pSD2;
193 if (FAILED(hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellDispatch2, &pSD2))))
194 {
195 skip("Unable to initialize test\n");
196 return;
197 }
198
199 IDispatch *pDisp = NULL;
200 hr = pSD2->get_Application(&pDisp);
201 ok_long(hr, S_OK);
202 ok(!!pDisp, "get_Application\n");
203 SafeRelease(pDisp);
204 hr = pSD2->get_Application(NULL);
205 ok(FAILED(hr), "get_Application NULL\n");
206
207 LONG lVal;
208 hr = pSD2->IsRestricted((BSTR)L"DoesNotExist", (BSTR)L"DoesNotExist", (lVal = 42, &lVal));
209 ok_long(hr, S_OK);
210 ok(lVal == 0, "IsRestricted\n");
211
212 VARIANT v = {};
214 hr = pSD2->GetSystemInformation((BSTR)L"ProcessorArchitecture", &v);
215 ok_long(hr, S_OK);
216 ok(V_I4(&v) != PROCESSOR_ARCHITECTURE_UNKNOWN, "GetSystemInformation ProcessorArchitecture\n");
218
219 hr = pSD2->IsServiceRunning((BSTR)L"DoesNotExist", &v);
220 ok_long(hr, S_OK);
221 ok_long(V_VT(&v), VT_BOOL);
222 ok_long(V_BOOL(&v), VARIANT_FALSE);
224
225 CComPtr<IShellDispatch4> pSD4;
226 if (FAILED(hr = CoCreateInstance(CLSID_Shell, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellDispatch4, &pSD4))))
227 {
228 skip("Unable to initialize test\n");
229 return;
230 }
231 hr = pSD4->GetSetting(SSF_NOCONFIRMRECYCLE, &V_BOOL(&v));
232 ok_long(hr, S_OK);
233 ok(V_BOOL(&v) == VARIANT_FALSE || V_BOOL(&v) == VARIANT_TRUE, "VARIANT_BOOL\n");
234}
PRTL_UNICODE_STRING_BUFFER Path
#define ok_long(expression, result)
Definition: atltest.h:133
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
OLECHAR * BSTR
Definition: compat.h:2293
#define MAX_PATH
Definition: compat.h:34
@ VT_BSTR
Definition: compat.h:2303
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1752
#define IS_INTRESOURCE(x)
Definition: loader.c:613
HRESULT WINAPI SHGetFolderPathW(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
Definition: shellpath.c:2716
#define L(x)
Definition: resources.c:13
const GLdouble * v
Definition: gl.h:2040
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLfloat GLfloat p
Definition: glext.h:8902
unsigned int UINT
Definition: sysinfo.c:13
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
nsrefcnt Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539
#define ok_NameSpaceFolderParseIsPath(ns, parse, path, mustexist, hrparse)
static HRESULT CreateFolderFromNameSpace(T Dir, Folder **ppsdf)
static void VariantClearAndInvalidate(VARIANT *pV)
static void SafeRelease(T &p)
static int GetFileSize(PCWSTR Path)
static void TestNameSpaceFolder()
static void TestFolderItem()
#define PROCESSOR_ARCHITECTURE_UNKNOWN
Definition: ketypes.h:115
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define T(num)
Definition: thunks.c:311
#define CSIDL_PROGRAM_FILES
Definition: shlobj.h:2227
@ SHGFP_TYPE_CURRENT
Definition: shlobj.h:2166
#define SSF_NOCONFIRMRECYCLE
Definition: shlobj.h:1634
#define CSIDL_DESKTOP
Definition: shlobj.h:2190
#define CSIDL_CONTROLS
Definition: shlobj.h:2193
#define _countof(array)
Definition: sndvol32.h:70
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
#define GetModuleFileName
Definition: winbase.h:3552
#define S_FALSE
Definition: winerror.h:3451
#define IID_PPV_ARG(Itype, ppType)