ReactOS 0.4.15-dev-8219-ge8b88cf
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 []
 
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 403 of file CShellLink.cpp.

404{
406
410
412}
#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 95 of file CShellLink.cpp.

96{
97static WCHAR evVar[MAX_PATH];
98
99 HRESULT hr, expectedHr;
100 WCHAR wPathOut[MAX_PATH];
101 BOOL expandPathOut;
102 PCWSTR expectedPathOut;
103 CComPtr<IShellLinkW> psl;
104 UINT i1;
105 DWORD flags;
106
107 hr = CoCreateInstance(CLSID_ShellLink,
108 NULL,
109 CLSCTX_INPROC_SERVER,
110 IID_PPV_ARG(IShellLinkW, &psl));
111 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
112 if (FAILED(hr))
113 {
114 skip("Could not instantiate CShellLink\n");
115 return;
116 }
117
118 hr = psl->SetPath(testDef->pathIn);
119 ok(hr == testDef->hrSetPath, "IShellLink::SetPath(%d), got hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrSetPath);
120
121 expectedPathOut = NULL;
122 for (i1 = 0; i1 <= 1; i1++)
123 {
124 if (i1 == 0) /* Usually SLGP_SHORTPATH */
125 {
126 flags = testDef->flags1;
127 expandPathOut = testDef->expandPathOut1;
128 expectedPathOut = testDef->pathOut1;
129 expectedHr = testDef->hrGetPath1;
130 }
131 else // if (i1 == 1) /* Usually SLGP_RAWPATH */
132 {
133 flags = testDef->flags2;
134 expandPathOut = testDef->expandPathOut2;
135 expectedPathOut = testDef->pathOut2;
136 expectedHr = testDef->hrGetPath2;
137 }
138
139 /* Patch some variables */
140 if (expandPathOut)
141 {
142 ExpandEnvironmentStringsW(expectedPathOut, evVar, _countof(evVar));
143 DPRINT("** %S **\n",evVar);
144 expectedPathOut = evVar;
145 }
146
147 hr = psl->GetPath(wPathOut, _countof(wPathOut), NULL, flags);
148 ok(hr == expectedHr,
149 "IShellLink::GetPath(%d), flags 0x%lx, got hr = 0x%lx, expected 0x%lx\n",
150 i, flags, hr, expectedHr);
151 ok(wcsicmp(wPathOut, expectedPathOut) == 0,
152 "IShellLink::GetPath(%d), flags 0x%lx, in %S, got %S, expected %S\n",
153 i, flags, testDef->pathIn, wPathOut, expectedPathOut);
154 }
155}
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define MAX_PATH
Definition: compat.h:34
#define wcsicmp
Definition: compat.h:15
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
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 260 of file CShellLink.cpp.

261{
262 HRESULT hr;
263 CComPtr<IShellLinkW> psl;
264 CComPtr<IExtractIconW> pei;
265 INT iIcon;
266 UINT wFlags;
267 PCWSTR pszExplorer = L"%SystemRoot%\\explorer.exe";
269 WCHAR szPath2[MAX_PATH];
270
271 hr = CoCreateInstance(CLSID_ShellLink,
272 NULL,
273 CLSCTX_INPROC_SERVER,
274 IID_PPV_ARG(IShellLinkW, &psl));
275 ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
276 if (FAILED(hr))
277 {
278 skip("Could not instantiate CShellLink\n");
279 return;
280 }
281
282 /* Set the path to a file */
284 hr = psl->SetPath(szPath);
285 ok(hr == S_OK, "IShellLink::SetPath failed, hr = 0x%lx\n", hr);
286
287 /*
288 * This test shows that this does not imply that the icon is automatically
289 * set and be retrieved naively by a call to IShellLink::GetIconLocation.
290 */
291 iIcon = 0xdeadbeef;
292 wcscpy(szPath, L"garbage");
293 hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
294 ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
295 ok(*szPath == L'\0', "IShellLink::GetIconLocation(%d) returned '%S'\n", i, szPath);
296 ok(iIcon == 0, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 0);
297
298 /* Try to grab the IExtractIconW interface */
300 ok(hr == S_OK, "IShellLink::QueryInterface(IExtractIconW)(%d) failed, hr = 0x%lx\n", i, hr);
301 if (!pei)
302 {
303 win_skip("No IExtractIconW interface\n");
304 return;
305 }
306
307 iIcon = wFlags = 0xdeadbeef;
308 wcscpy(szPath, L"garbage");
309 hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
310 ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
311 ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
312 // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
313
314 iIcon = wFlags = 0xdeadbeef;
315 wcscpy(szPath, L"garbage");
316 hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
317 ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
318 // Here, both szPath and iIcon are untouched...
319
320 iIcon = wFlags = 0xdeadbeef;
321 wcscpy(szPath, L"garbage");
322 hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
323 ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
324 ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
325 /*
326 * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
327 * for executables only (at least...), otherwise we can get an asterix '*'.
328 */
329 ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
330 ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
331
332 // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
333 // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
334 // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
335
336
337 /*
338 * Now we test what happens when we explicitly set an icon to the shortcut.
339 * Note that actually, SetIconLocation() does not verify whether the file
340 * really exists.
341 */
342 hr = psl->SetIconLocation(pszExplorer, 1);
343 ok(hr == S_OK, "IShellLink::SetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
344
345 /*
346 * First, we call IShellLink::GetIconLocation. We retrieve
347 * exactly what we specified with SetIconLocation.
348 */
349 iIcon = 0xdeadbeef;
350 wcscpy(szPath, L"garbage");
351 hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
352 ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
353 ok(wcscmp(szPath, pszExplorer) == 0, "IShellLink::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, pszExplorer);
354 ok(iIcon == 1, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 1);
355
356 /*
357 * Now we test what happens with IExtractIcon::GetIconLocation.
358 * We see that it retrieves the icon of the shortcut's underlying file.
359 */
360 iIcon = wFlags = 0xdeadbeef;
361 wcscpy(szPath, L"garbage");
362 hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
363 ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
364 ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
365 // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
366
367 iIcon = wFlags = 0xdeadbeef;
368 wcscpy(szPath, L"garbage");
369 hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
370 ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
371 // Here, both szPath and iIcon are untouched...
372
373 iIcon = wFlags = 0xdeadbeef;
374 wcscpy(szPath, L"garbage");
375 hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
376 ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
377 ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
378 /*
379 * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
380 * for executables only (at least...), otherwise we can get an asterix '*'.
381 */
382 ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
383 ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
384
385 // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
386 // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
387 // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
388}
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
LPCWSTR szPath
Definition: env.c:37
#define L(x)
Definition: ntvdm.h:50
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define win_skip
Definition: test.h:163
HRESULT hrForShell
Definition: CShellLink.cpp:232
int32_t INT
Definition: typedefs.h:58
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531

Referenced by TestIconLocation().

◆ TestDescription()

static VOID TestDescription ( void  )
static

Definition at line 177 of file CShellLink.cpp.

178{
179 HRESULT hr;
180 CComPtr<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}
#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 392 of file CShellLink.cpp.

393{
394 UINT i;
395
396 for (i = 0; i < _countof(ShIconTests); ++i)
397 {
399 }
400}

Referenced by START_TEST().

◆ TestShellLink()

static VOID TestShellLink ( void  )
static

Definition at line 159 of file CShellLink.cpp.

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);
170 }
171
173}
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259

Referenced by START_TEST().

Variable Documentation

◆ linkTestList

TEST_SHELL_LINK_DEF linkTestList[]
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:2357

Definition at line 237 of file CShellLink.cpp.

Referenced by TestIconLocation().