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