ReactOS 0.4.16-dev-1946-g52006dd
CShellLink.cpp File Reference
#include "shelltest.h"
#include <debug.h>
#include <stdio.h>
#include <shellutils.h>
Include dependency graph for CShellLink.cpp:

Go to the source code of this file.

Classes

struct  TEST_SHELL_LINK_DEF
 
struct  TEST_SHELL_ICON
 

Macros

#define NDEBUG
 

Functions

static VOID test_checklinkpath (UINT i, TEST_SHELL_LINK_DEF *testDef)
 
static VOID TestShellLink (void)
 
static VOID TestDescription (void)
 
static VOID test_iconlocation (UINT i, TEST_SHELL_ICON *testDef)
 
static VOID TestIconLocation (void)
 
 START_TEST (CShellLink)
 

Variables

static TEST_SHELL_LINK_DEF linkTestList_WS03 []
 
static TEST_SHELL_LINK_DEF linkTestList_Vista []
 
static TEST_SHELL_ICON ShIconTests []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 10 of file CShellLink.cpp.

Function Documentation

◆ START_TEST()

START_TEST ( CShellLink  )

Definition at line 474 of file CShellLink.cpp.

475{
477
481
483}
#define NULL
Definition: types.h:112
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:2002
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
@ COINIT_APARTMENTTHREADED
Definition: objbase.h:278

◆ test_checklinkpath()

static VOID test_checklinkpath ( UINT  i,
TEST_SHELL_LINK_DEF testDef 
)
static

Definition at line 154 of file CShellLink.cpp.

155{
156static WCHAR evVar[MAX_PATH];
157
158 HRESULT hr, expectedHr;
159 WCHAR wPathOut[MAX_PATH];
160 BOOL expandPathOut;
161 PCWSTR expectedPathOut;
162 CComPtr<IShellLinkW> psl;
163 UINT i1;
164 DWORD flags;
165
166 hr = CoCreateInstance(CLSID_ShellLink,
167 NULL,
168 CLSCTX_INPROC_SERVER,
169 IID_PPV_ARG(IShellLinkW, &psl));
170 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
171 if (FAILED(hr))
172 {
173 skip("Could not instantiate CShellLink\n");
174 return;
175 }
176
177 hr = psl->SetPath(testDef->pathIn);
178 ok(hr == testDef->hrSetPath, "IShellLink::SetPath(%d), got hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrSetPath);
179
180 expectedPathOut = NULL;
181 for (i1 = 0; i1 <= 1; i1++)
182 {
183 if (i1 == 0) /* Usually SLGP_SHORTPATH */
184 {
185 flags = testDef->flags1;
186 expandPathOut = testDef->expandPathOut1;
187 expectedPathOut = testDef->pathOut1;
188 expectedHr = testDef->hrGetPath1;
189 }
190 else // if (i1 == 1) /* Usually SLGP_RAWPATH */
191 {
192 flags = testDef->flags2;
193 expandPathOut = testDef->expandPathOut2;
194 expectedPathOut = testDef->pathOut2;
195 expectedHr = testDef->hrGetPath2;
196 }
197
198 /* Patch some variables */
199 if (expandPathOut)
200 {
201 ExpandEnvironmentStringsW(expectedPathOut, evVar, _countof(evVar));
202 DPRINT("** %S **\n",evVar);
203 expectedPathOut = evVar;
204 }
205
206 hr = psl->GetPath(wPathOut, _countof(wPathOut), NULL, flags);
207 ok(hr == expectedHr,
208 "IShellLink::GetPath(%d), flags 0x%lx, got hr = 0x%lx, expected 0x%lx\n",
209 i, flags, hr, expectedHr);
210 ok(_wcsicmp(wPathOut, expectedPathOut) == 0,
211 "IShellLink::GetPath(%d), flags 0x%lx, in %S, got %S, expected %S\n",
212 i, flags, testDef->pathIn, wPathOut, expectedPathOut);
213 }
214}
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define MAX_PATH
Definition: compat.h:34
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
unsigned int UINT
Definition: ndis.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
HRESULT hr
Definition: shlfolder.c:183
#define DPRINT
Definition: sndvol32.h:73
#define _countof(array)
Definition: sndvol32.h:70
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by TestShellLink().

◆ test_iconlocation()

static VOID test_iconlocation ( UINT  i,
TEST_SHELL_ICON testDef 
)
static

Definition at line 331 of file CShellLink.cpp.

332{
333 HRESULT hr;
334 CComPtr<IShellLinkW> psl;
335 CComPtr<IExtractIconW> pei;
336 INT iIcon;
337 UINT wFlags;
338 PCWSTR pszExplorer = L"%SystemRoot%\\explorer.exe";
340 WCHAR szPath2[MAX_PATH];
341
342 hr = CoCreateInstance(CLSID_ShellLink,
343 NULL,
344 CLSCTX_INPROC_SERVER,
345 IID_PPV_ARG(IShellLinkW, &psl));
346 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
347 if (FAILED(hr))
348 {
349 skip("Could not instantiate CShellLink\n");
350 return;
351 }
352
353 /* Set the path to a file */
355 hr = psl->SetPath(szPath);
356 ok(hr == S_OK, "IShellLink::SetPath failed, hr = 0x%lx\n", hr);
357
358 /*
359 * This test shows that this does not imply that the icon is automatically
360 * set and be retrieved naively by a call to IShellLink::GetIconLocation.
361 */
362 iIcon = 0xdeadbeef;
363 wcscpy(szPath, L"garbage");
364 hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
365 ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
366 ok(*szPath == L'\0', "IShellLink::GetIconLocation(%d) returned '%S'\n", i, szPath);
367 ok(iIcon == 0, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 0);
368
369 /* Try to grab the IExtractIconW interface */
371 ok(hr == S_OK, "IShellLink::QueryInterface(IExtractIconW)(%d) failed, hr = 0x%lx\n", i, hr);
372 if (!pei)
373 {
374 win_skip("No IExtractIconW interface\n");
375 return;
376 }
377
378 iIcon = wFlags = 0xdeadbeef;
379 wcscpy(szPath, L"garbage");
380 hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
381 ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
382 ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
383 // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
384
385 iIcon = wFlags = 0xdeadbeef;
386 wcscpy(szPath, L"garbage");
387 hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
388 ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
389 // Here, both szPath and iIcon are untouched...
390
391 iIcon = wFlags = 0xdeadbeef;
392 wcscpy(szPath, L"garbage");
393 hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
394 ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
395 ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
396 /*
397 * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
398 * for executables only (at least...), otherwise we can get an asterix '*'.
399 */
400 ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
401 ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
402
403 // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
404 // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
405 // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
406
407
408 /*
409 * Now we test what happens when we explicitly set an icon to the shortcut.
410 * Note that actually, SetIconLocation() does not verify whether the file
411 * really exists.
412 */
413 hr = psl->SetIconLocation(pszExplorer, 1);
414 ok(hr == S_OK, "IShellLink::SetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
415
416 /*
417 * First, we call IShellLink::GetIconLocation. We retrieve
418 * exactly what we specified with SetIconLocation.
419 */
420 iIcon = 0xdeadbeef;
421 wcscpy(szPath, L"garbage");
422 hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
423 ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
424 ok(wcscmp(szPath, pszExplorer) == 0, "IShellLink::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, pszExplorer);
425 ok(iIcon == 1, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 1);
426
427 /*
428 * Now we test what happens with IExtractIcon::GetIconLocation.
429 * We see that it retrieves the icon of the shortcut's underlying file.
430 */
431 iIcon = wFlags = 0xdeadbeef;
432 wcscpy(szPath, L"garbage");
433 hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
434 ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
435 ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
436 // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
437
438 iIcon = wFlags = 0xdeadbeef;
439 wcscpy(szPath, L"garbage");
440 hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
441 ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
442 // Here, both szPath and iIcon are untouched...
443
444 iIcon = wFlags = 0xdeadbeef;
445 wcscpy(szPath, L"garbage");
446 hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
447 ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
448 ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
449 /*
450 * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
451 * for executables only (at least...), otherwise we can get an asterix '*'.
452 */
453 ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
454 ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
455
456 // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
457 // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
458 // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
459}
wcscpy
#define L(x)
Definition: resources.c:13
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define win_skip
Definition: minitest.h:67
LPCWSTR szPath
Definition: env.c:37
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
HRESULT hrForShell
Definition: CShellLink.cpp:303
int32_t INT
Definition: typedefs.h:58
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337

Referenced by TestIconLocation().

◆ TestDescription()

static VOID TestDescription ( void  )
static

Definition at line 248 of file CShellLink.cpp.

249{
250 HRESULT hr;
251 CComPtr<IShellLinkW> psl;
252 WCHAR buffer[64];
253 PCWSTR testDescription = L"This is a test description";
254
255 /* Test SetDescription */
256 hr = CoCreateInstance(CLSID_ShellLink,
257 NULL,
258 CLSCTX_INPROC_SERVER,
259 IID_PPV_ARG(IShellLinkW, &psl));
260 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
261 if (FAILED(hr))
262 {
263 skip("Could not instantiate CShellLink\n");
264 return;
265 }
266
267 memset(buffer, 0x55, sizeof(buffer));
268 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
269 ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
270 ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
271 ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
272
273 hr = psl->SetDescription(testDescription);
274 ok(hr == S_OK, "IShellLink::SetDescription returned hr = 0x%lx\n", hr);
275
276 memset(buffer, 0x55, sizeof(buffer));
277 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
278 ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
279 ok(buffer[wcslen(testDescription)] == 0, "buffer[n] = %x\n", buffer[wcslen(testDescription)]);
280 ok(buffer[wcslen(testDescription) + 1] == 0x5555, "buffer[n+1] = %x\n", buffer[wcslen(testDescription) + 1]);
281 ok(!wcscmp(buffer, testDescription), "buffer = '%ls'\n", buffer);
282
283 hr = psl->SetDescription(NULL);
284 ok(hr == S_OK, "IShellLink::SetDescription returned hr = 0x%lx\n", hr);
285
286 memset(buffer, 0x55, sizeof(buffer));
287 hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
288 ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
289 ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
290 ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
291}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
GLuint buffer
Definition: glext.h:5915
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define memset(x, y, z)
Definition: compat.h:39

Referenced by START_TEST().

◆ TestIconLocation()

static VOID TestIconLocation ( void  )
static

Definition at line 463 of file CShellLink.cpp.

464{
465 UINT i;
466
467 for (i = 0; i < _countof(ShIconTests); ++i)
468 {
470 }
471}

Referenced by START_TEST().

◆ TestShellLink()

static VOID TestShellLink ( void  )
static

Definition at line 218 of file CShellLink.cpp.

219{
220 UINT i, TestListCnt;
222
223 /* Needed for test */
224 SetEnvironmentVariableW(L"shell", L"cmd.exe");
225
227 {
229 TestListCnt = _countof(linkTestList_WS03);
230 }
231 else
232 {
234 TestListCnt = _countof(linkTestList_Vista);
235 }
236
237 for (i = 0; i < TestListCnt; ++i)
238 {
239 DPRINT("IShellLink-Test(%d): %S\n", i, Test[i].pathIn);
241 }
242
244}
#define GetNTVersion()
Definition: apitest.h:17
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
#define _WIN32_WINNT_WS03
Definition: sdkddkver.h:23

Referenced by START_TEST().

Variable Documentation

◆ linkTestList_Vista

TEST_SHELL_LINK_DEF linkTestList_Vista[]
static

Definition at line 93 of file CShellLink.cpp.

Referenced by TestShellLink().

◆ linkTestList_WS03

TEST_SHELL_LINK_DEF linkTestList_WS03[]
static

Definition at line 34 of file CShellLink.cpp.

Referenced by TestShellLink().

◆ ShIconTests

TEST_SHELL_ICON ShIconTests[]
static
Initial value:
=
{
{L"%SystemRoot%\\system32\\cmd.exe", S_FALSE, E_INVALIDARG,
S_OK, L"%SystemRoot%\\system32\\cmd.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
{L"%SystemRoot%\\system32\\autochk.exe", S_FALSE, E_INVALIDARG,
S_OK, L"%SystemRoot%\\system32\\autochk.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
{L"%SystemRoot%\\system32\\shell32.dll", S_FALSE, E_INVALIDARG,
S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
{L"%SystemRoot%\\non-existent-file.sdf", S_FALSE, E_INVALIDARG,
S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
{L"c:\\non-existent-path\\non-existent-file.sdf", S_FALSE, E_INVALIDARG,
S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
}
#define E_INVALIDARG
Definition: ddrawi.h:101
#define S_FALSE
Definition: winerror.h:3451

Definition at line 308 of file CShellLink.cpp.

Referenced by TestIconLocation().