[SHELL32_APITEST] Add some tests for ShellExecuteEx showing extension completion...
[reactos.git] / rostests / apitests / shell32 / CShellLink.cpp
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for CShellLink
5 * PROGRAMMER: Andreas Maier
6 */
7
8 #include "shelltest.h"
9 #include <atlbase.h>
10 #include <atlcom.h>
11 #include <strsafe.h>
12 #include <ndk/rtlfuncs.h>
13
14 #define NDEBUG
15 #include <debug.h>
16 #include <shellutils.h>
17
18 typedef
19 struct _TestShellLinkDef
20 {
21 const WCHAR* pathIn;
22 HRESULT hrSetPath;
23 /* Test 1 - hrGetPathX = IShellLink::GetPath(pathOutX, ... , flagsX); */
24 const WCHAR* pathOut1;
25 DWORD flags1;
26 HRESULT hrGetPath1;
27 bool expandPathOut1;
28 /* Test 2 */
29 const WCHAR* pathOut2;
30 DWORD flags2;
31 HRESULT hrGetPath2;
32 bool expandPathOut2;
33 } TestShellLinkDef;
34
35 /* Test IShellLink::SetPath with environment-variables, existing, non-existing, ...*/
36 static struct _TestShellLinkDef linkTestList[] =
37 {
38 {
39 L"%comspec%", S_OK,
40 L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
41 L"%comspec%", SLGP_RAWPATH, S_OK, FALSE
42 },
43 {
44 L"%anyvar%", E_INVALIDARG,
45 L"", SLGP_SHORTPATH, ERROR_INVALID_FUNCTION, FALSE,
46 L"", SLGP_RAWPATH, ERROR_INVALID_FUNCTION, FALSE
47 },
48 {
49 L"%anyvar%%comspec%", S_OK,
50 L"c:\\%anyvar%%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
51 L"%anyvar%%comspec%", SLGP_RAWPATH, S_OK, FALSE
52 },
53 {
54 L"%temp%", S_OK,
55 L"%temp%", SLGP_SHORTPATH, S_OK, TRUE,
56 L"%temp%", SLGP_RAWPATH, S_OK, FALSE
57 },
58 {
59 L"%shell%", S_OK,
60 L"%systemroot%\\system32\\%shell%", SLGP_SHORTPATH, S_OK, TRUE,
61 L"%shell%", SLGP_RAWPATH, S_OK, FALSE
62 },
63 {
64 L"u:\\anypath\\%anyvar%", S_OK,
65 L"u:\\anypath\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE,
66 L"u:\\anypath\\%anyvar%", SLGP_RAWPATH, S_OK, FALSE
67 },
68 {
69 L"c:\\temp", S_OK,
70 L"c:\\temp", SLGP_SHORTPATH, S_OK, FALSE,
71 L"c:\\temp", SLGP_RAWPATH, S_OK, FALSE
72 },
73 {
74 L"cmd.exe", S_OK,
75 L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
76 L"%comspec%", SLGP_RAWPATH, S_OK, TRUE
77 },
78 {
79 L"c:\\non-existent-path\\non-existent-file", S_OK,
80 L"c:\\non-existent-path\\non-existent-file", SLGP_SHORTPATH, S_OK, FALSE,
81 L"c:\\non-existent-path\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
82 },
83 {
84 L"non-existent-file", E_INVALIDARG,
85 L"", SLGP_SHORTPATH, ERROR_INVALID_FUNCTION, FALSE,
86 L"", SLGP_RAWPATH, ERROR_INVALID_FUNCTION, FALSE
87 },
88 { NULL, 0, NULL, 0, 0, NULL, 0, 0 }
89 };
90
91 static const UINT evVarChLen = 255;
92 static WCHAR evVar[evVarChLen];
93
94 static
95 VOID
96 test_checklinkpath(TestShellLinkDef* testDef)
97 {
98 HRESULT hr, expectedHr;
99 WCHAR wPathOut[255];
100 bool expandPathOut;
101 const WCHAR* expectedPathOut;
102 IShellLinkW *psl;
103 UINT i1;
104 DWORD flags;
105
106 hr = CoCreateInstance(CLSID_ShellLink,
107 NULL,
108 CLSCTX_INPROC_SERVER,
109 IID_PPV_ARG(IShellLinkW, &psl));
110 ok(hr == S_OK, "CoCreateInstance, hr = %lx\n", hr);
111 if (FAILED(hr))
112 {
113 skip("Could not instantiate CShellLink\n");
114 return;
115 }
116
117 hr = psl->SetPath(testDef->pathIn);
118 ok(hr == testDef->hrSetPath, "IShellLink::SetPath, got hr = %lx, expected %lx\n", hr, testDef->hrSetPath);
119
120 expectedPathOut = NULL;
121 for (i1 = 0; i1 <= 1; i1++ )
122 {
123 if (i1 == 1)
124 {
125 flags = testDef->flags1;
126 expandPathOut = testDef->expandPathOut1;
127 expectedPathOut = testDef->pathOut1;
128 expectedHr = testDef->hrGetPath1;
129 }
130 else
131 {
132 flags = testDef->flags2;
133 expandPathOut = testDef->expandPathOut2;
134 expectedPathOut = testDef->pathOut2;
135 expectedHr = testDef->hrGetPath2;
136 }
137
138 /* Patch some variables */
139 if (expandPathOut == TRUE)
140 {
141 ExpandEnvironmentStringsW(expectedPathOut,evVar,evVarChLen);
142 DPRINT("** %S **\n",evVar);
143 expectedPathOut = evVar;
144 }
145
146 hr = psl->GetPath(wPathOut,sizeof(wPathOut),NULL,flags);
147 ok(hr == expectedHr,
148 "IShellLink::GetPath, flags %lx, got hr = %lx, expected %lx\n",
149 flags, hr, expectedHr);
150 ok(wcsicmp(wPathOut,expectedPathOut) == 0,
151 "IShellLink::GetPath, flags %lx, in %S, got %S, expected %S\n",
152 flags,testDef->pathIn,wPathOut,expectedPathOut);
153 }
154
155 psl->Release();
156 }
157
158 static
159 VOID
160 TestDescription(void)
161 {
162 HRESULT hr;
163 IShellLinkW *psl;
164 WCHAR buffer[64];
165 PCWSTR testDescription = L"This is a test description";
166
167 /* Test SetDescription */
168 hr = CoCreateInstance(CLSID_ShellLink,
169 NULL,
170 CLSCTX_INPROC_SERVER,
171 IID_PPV_ARG(IShellLinkW, &psl));
172 ok(hr == S_OK, "CoCreateInstance, hr = %lx\n", hr);
173 if (FAILED(hr))
174 {
175 skip("Could not instantiate CShellLink\n");
176 return;
177 }
178
179 memset(buffer, 0x55, sizeof(buffer));
180 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
181 ok(hr == S_OK, "IShellLink::GetDescription returned hr = %lx\n", hr);
182 ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
183 ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
184
185 hr = psl->SetDescription(testDescription);
186 ok(hr == S_OK, "IShellLink::SetDescription returned hr = %lx\n", hr);
187
188 memset(buffer, 0x55, sizeof(buffer));
189 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
190 ok(hr == S_OK, "IShellLink::GetDescription returned hr = %lx\n", hr);
191 ok(buffer[wcslen(testDescription)] == 0, "buffer[n] = %x\n", buffer[wcslen(testDescription)]);
192 ok(buffer[wcslen(testDescription) + 1] == 0x5555, "buffer[n+1] = %x\n", buffer[wcslen(testDescription) + 1]);
193 ok(!wcscmp(buffer, testDescription), "buffer = '%ls'\n", buffer);
194
195 hr = psl->SetDescription(NULL);
196 ok(hr == S_OK, "IShellLink::SetDescription returned hr = %lx\n", hr);
197
198 memset(buffer, 0x55, sizeof(buffer));
199 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
200 ok(hr == S_OK, "IShellLink::GetDescription returned hr = %lx\n", hr);
201 ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
202 ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
203 }
204
205 static
206 VOID
207 TestShellLink(void)
208 {
209 TestShellLinkDef *testDef;
210 UINT i1 = 0;
211
212 /* needed for test */
213 SetEnvironmentVariableW(L"shell",L"cmd.exe");
214
215 testDef = &linkTestList[i1];
216 while (testDef->pathIn != NULL)
217 {
218
219 DPRINT("IShellLink-Test: %S\n", testDef->pathIn);
220 test_checklinkpath(testDef);
221 i1++;
222 testDef = &linkTestList[i1];
223 }
224
225 SetEnvironmentVariableW(L"shell",NULL);
226
227 TestDescription();
228 }
229
230 START_TEST(CShellLink)
231 {
232 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
233
234 TestShellLink();
235 }