ReactOS  0.4.13-dev-259-g5ca9c9c
CShellLink.cpp
Go to the documentation of this file.
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 
10 #define NDEBUG
11 #include <debug.h>
12 #include <shellutils.h>
13 
14 /* Test IShellLink::SetPath with environment-variables, existing, non-existing, ...*/
15 typedef struct
16 {
19 
20  /* Test 1 - hrGetPathX = IShellLink::GetPath(pathOutX, ... , flagsX); */
25 
26  /* Test 2 */
32 
34 {
35  {
36  L"%comspec%", S_OK,
37  L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
38  L"%comspec%", SLGP_RAWPATH, S_OK, FALSE
39  },
40  {
41  L"%anyvar%", E_INVALIDARG,
42  L"", SLGP_SHORTPATH, S_FALSE, FALSE,
43  L"", SLGP_RAWPATH, S_FALSE, FALSE
44  },
45  {
46  L"%anyvar%%comspec%", S_OK,
47  L"c:\\%anyvar%%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
48  L"%anyvar%%comspec%", SLGP_RAWPATH, S_OK, FALSE
49  },
50  {
51  L"%temp%", S_OK,
52  L"%temp%", SLGP_SHORTPATH, S_OK, TRUE,
53  L"%temp%", SLGP_RAWPATH, S_OK, FALSE
54  },
55  {
56  L"%shell%", S_OK,
57  L"%systemroot%\\system32\\%shell%", SLGP_SHORTPATH, S_OK, TRUE,
58  L"%shell%", SLGP_RAWPATH, S_OK, FALSE
59  },
60  {
61  L"u:\\anypath\\%anyvar%", S_OK,
62  L"u:\\anypath\\%anyvar%", SLGP_SHORTPATH, S_OK, TRUE,
63  L"u:\\anypath\\%anyvar%", SLGP_RAWPATH, S_OK, FALSE
64  },
65  {
66  L"c:\\temp", S_OK,
67  L"c:\\temp", SLGP_SHORTPATH, S_OK, FALSE,
68  L"c:\\temp", SLGP_RAWPATH, S_OK, FALSE
69  },
70  {
71  L"cmd.exe", S_OK,
72  L"%comspec%", SLGP_SHORTPATH, S_OK, TRUE,
73  L"%comspec%", SLGP_RAWPATH, S_OK, TRUE
74  },
75  {
76  L"%systemroot%\\non-existent-file", S_OK,
77  L"%systemroot%\\non-existent-file", SLGP_SHORTPATH, S_OK, TRUE,
78  L"%systemroot%\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
79  },
80  {
81  L"c:\\non-existent-path\\non-existent-file", S_OK,
82  L"c:\\non-existent-path\\non-existent-file", SLGP_SHORTPATH, S_OK, FALSE,
83  L"c:\\non-existent-path\\non-existent-file", SLGP_RAWPATH, S_OK, FALSE
84  },
85  {
86  L"non-existent-file", E_INVALIDARG,
87  L"", SLGP_SHORTPATH, S_FALSE, FALSE,
88  L"", SLGP_RAWPATH, S_FALSE, FALSE
89  },
90 };
91 
92 static
93 VOID
95 {
96 static WCHAR evVar[MAX_PATH];
97 
98  HRESULT hr, expectedHr;
99  WCHAR wPathOut[MAX_PATH];
100  BOOL expandPathOut;
101  PCWSTR expectedPathOut;
102  CComPtr<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 = 0x%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(%d), got hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrSetPath);
119 
120  expectedPathOut = NULL;
121  for (i1 = 0; i1 <= 1; i1++)
122  {
123  if (i1 == 0) /* Usually SLGP_SHORTPATH */
124  {
125  flags = testDef->flags1;
126  expandPathOut = testDef->expandPathOut1;
127  expectedPathOut = testDef->pathOut1;
128  expectedHr = testDef->hrGetPath1;
129  }
130  else // if (i1 == 1) /* Usually SLGP_RAWPATH */
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)
140  {
141  ExpandEnvironmentStringsW(expectedPathOut, evVar, _countof(evVar));
142  DPRINT("** %S **\n",evVar);
143  expectedPathOut = evVar;
144  }
145 
146  hr = psl->GetPath(wPathOut, _countof(wPathOut), NULL, flags);
147  ok(hr == expectedHr,
148  "IShellLink::GetPath(%d), flags 0x%lx, got hr = 0x%lx, expected 0x%lx\n",
149  i, flags, hr, expectedHr);
150  ok(wcsicmp(wPathOut, expectedPathOut) == 0,
151  "IShellLink::GetPath(%d), flags 0x%lx, in %S, got %S, expected %S\n",
152  i, flags, testDef->pathIn, wPathOut, expectedPathOut);
153  }
154 }
155 
156 static
157 VOID
159 {
160  UINT i;
161 
162  /* Needed for test */
163  SetEnvironmentVariableW(L"shell", L"cmd.exe");
164 
165  for (i = 0; i < _countof(linkTestList); ++i)
166  {
167  DPRINT("IShellLink-Test(%d): %S\n", i, linkTestList[i].pathIn);
169  }
170 
172 }
173 
174 static
175 VOID
177 {
178  HRESULT hr;
179  CComPtr<IShellLinkW> psl;
180  WCHAR buffer[64];
181  PCWSTR testDescription = L"This is a test description";
182 
183  /* Test SetDescription */
184  hr = CoCreateInstance(CLSID_ShellLink,
185  NULL,
186  CLSCTX_INPROC_SERVER,
187  IID_PPV_ARG(IShellLinkW, &psl));
188  ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
189  if (FAILED(hr))
190  {
191  skip("Could not instantiate CShellLink\n");
192  return;
193  }
194 
195  memset(buffer, 0x55, sizeof(buffer));
196  hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
197  ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
198  ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
199  ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
200 
201  hr = psl->SetDescription(testDescription);
202  ok(hr == S_OK, "IShellLink::SetDescription returned hr = 0x%lx\n", hr);
203 
204  memset(buffer, 0x55, sizeof(buffer));
205  hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
206  ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
207  ok(buffer[wcslen(testDescription)] == 0, "buffer[n] = %x\n", buffer[wcslen(testDescription)]);
208  ok(buffer[wcslen(testDescription) + 1] == 0x5555, "buffer[n+1] = %x\n", buffer[wcslen(testDescription) + 1]);
209  ok(!wcscmp(buffer, testDescription), "buffer = '%ls'\n", buffer);
210 
211  hr = psl->SetDescription(NULL);
212  ok(hr == S_OK, "IShellLink::SetDescription returned hr = 0x%lx\n", hr);
213 
214  memset(buffer, 0x55, sizeof(buffer));
215  hr = psl->GetDescription(buffer, RTL_NUMBER_OF(buffer));
216  ok(hr == S_OK, "IShellLink::GetDescription returned hr = 0x%lx\n", hr);
217  ok(buffer[0] == 0, "buffer[0] = %x\n", buffer[0]);
218  ok(buffer[1] == 0x5555, "buffer[1] = %x\n", buffer[1]);
219 }
220 
221 
222 /* Test IShellLink::Get/SetIconLocation and IExtractIcon::GetIconLocation */
223 typedef struct
224 {
226 
227  /* Expected results */
228  HRESULT hrDefIcon; // Return value for GIL_DEFAULTICON
229  HRESULT hrForShrt; // Return value for GIL_FORSHORTCUT
230  /* Return values for GIL_FORSHELL */
235 
237 {
238  /* Executable with icons */
239  {L"%SystemRoot%\\system32\\cmd.exe", S_FALSE, E_INVALIDARG,
240  S_OK, L"%SystemRoot%\\system32\\cmd.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
241 
242  /* Executable without icon */
243  {L"%SystemRoot%\\system32\\autochk.exe", S_FALSE, E_INVALIDARG,
244  S_OK, L"%SystemRoot%\\system32\\autochk.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
245 
246  /* Existing file */
247  {L"%SystemRoot%\\system32\\shell32.dll", S_FALSE, E_INVALIDARG,
248  S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
249 
250  /* Non-existing files */
251  {L"%SystemRoot%\\non-existent-file.sdf", S_FALSE, E_INVALIDARG,
252  S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
253  {L"c:\\non-existent-path\\non-existent-file.sdf", S_FALSE, E_INVALIDARG,
254  S_OK, L"*", GIL_NOTFILENAME | GIL_PERCLASS},
255 };
256 
257 static
258 VOID
260 {
261  HRESULT hr;
262  CComPtr<IShellLinkW> psl;
263  CComPtr<IExtractIconW> pei;
264  INT iIcon;
265  UINT wFlags;
266  PCWSTR pszExplorer = L"%SystemRoot%\\explorer.exe";
268  WCHAR szPath2[MAX_PATH];
269 
270  hr = CoCreateInstance(CLSID_ShellLink,
271  NULL,
272  CLSCTX_INPROC_SERVER,
273  IID_PPV_ARG(IShellLinkW, &psl));
274  ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
275  if (FAILED(hr))
276  {
277  skip("Could not instantiate CShellLink\n");
278  return;
279  }
280 
281  /* Set the path to a file */
283  hr = psl->SetPath(szPath);
284  ok(hr == S_OK, "IShellLink::SetPath failed, hr = 0x%lx\n", hr);
285 
286  /*
287  * This test shows that this does not imply that the icon is automatically
288  * set and be retrieved naively by a call to IShellLink::GetIconLocation.
289  */
290  iIcon = 0xdeadbeef;
291  wcscpy(szPath, L"garbage");
292  hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
293  ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
294  ok(*szPath == L'\0', "IShellLink::GetIconLocation(%d) returned '%S'\n", i, szPath);
295  ok(iIcon == 0, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 0);
296 
297  /* Try to grab the IExtractIconW interface */
298  hr = psl->QueryInterface(IID_PPV_ARG(IExtractIconW, &pei));
299  ok(hr == S_OK, "IShellLink::QueryInterface(IExtractIconW)(%d) failed, hr = 0x%lx\n", i, hr);
300  if (!pei)
301  {
302  win_skip("No IExtractIconW interface\n");
303  return;
304  }
305 
306  iIcon = wFlags = 0xdeadbeef;
307  wcscpy(szPath, L"garbage");
308  hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
309  ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
310  ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
311  // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
312 
313  iIcon = wFlags = 0xdeadbeef;
314  wcscpy(szPath, L"garbage");
315  hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
316  ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
317  // Here, both szPath and iIcon are untouched...
318 
319  iIcon = wFlags = 0xdeadbeef;
320  wcscpy(szPath, L"garbage");
321  hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
322  ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
323  ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
324  /*
325  * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
326  * for executables only (at least...), otherwise we can get an asterix '*'.
327  */
328  ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
329  ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
330 
331  // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
332  // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
333  // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
334 
335 
336  /*
337  * Now we test what happens when we explicitly set an icon to the shortcut.
338  * Note that actually, SetIconLocation() does not verify whether the file
339  * really exists.
340  */
341  hr = psl->SetIconLocation(pszExplorer, 1);
342  ok(hr == S_OK, "IShellLink::SetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
343 
344  /*
345  * First, we call IShellLink::GetIconLocation. We retrieve
346  * exactly what we specified with SetIconLocation.
347  */
348  iIcon = 0xdeadbeef;
349  wcscpy(szPath, L"garbage");
350  hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
351  ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
352  ok(wcscmp(szPath, pszExplorer) == 0, "IShellLink::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, pszExplorer);
353  ok(iIcon == 1, "IShellLink::GetIconLocation(%d) returned %d, expected %d\n", i, iIcon, 1);
354 
355  /*
356  * Now we test what happens with IExtractIcon::GetIconLocation.
357  * We see that it retrieves the icon of the shortcut's underlying file.
358  */
359  iIcon = wFlags = 0xdeadbeef;
360  wcscpy(szPath, L"garbage");
361  hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
362  ok(hr == testDef->hrDefIcon, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
363  ok(*szPath == L'\0', "IExtractIcon::GetIconLocation(%d) returned '%S'\n", i, szPath);
364  // ok(iIcon == 0, "IExtractIcon::GetIconLocation(%d) returned %d\n", i, iIcon);
365 
366  iIcon = wFlags = 0xdeadbeef;
367  wcscpy(szPath, L"garbage");
368  hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
369  ok(hr == testDef->hrForShrt, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
370  // Here, both szPath and iIcon are untouched...
371 
372  iIcon = wFlags = 0xdeadbeef;
373  wcscpy(szPath, L"garbage");
374  hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
375  ok(hr == testDef->hrForShell, "IExtractIcon::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
376  ok(wFlags == testDef->Flags, "IExtractIcon::GetIconLocation(%d) returned wFlags = 0x%x, expected 0x%x\n", i, wFlags, testDef->Flags);
377  /*
378  * Actually, even if wFlags specifies GIL_NOTFILENAME, a correct file name is returned
379  * for executables only (at least...), otherwise we can get an asterix '*'.
380  */
381  ExpandEnvironmentStringsW(testDef->IconPath, szPath2, _countof(szPath2));
382  ok(_wcsicmp(szPath2, szPath) == 0, "IExtractIcon::GetIconLocation(%d) returned '%S', expected '%S'\n", i, szPath, szPath2);
383 
384  // ok(*szPath == L'\0', "IExtractIcon::GetIconLocation returned '%S'\n", szPath);
385  // ok(iIcon == 0, "IExtractIcon::GetIconLocation returned %d\n", iIcon);
386  // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
387 }
388 
389 static
390 VOID
392 {
393  UINT i;
394 
395  for (i = 0; i < _countof(ShIconTests); ++i)
396  {
398  }
399 }
400 
401 
403 {
405 
406  TestShellLink();
407  TestDescription();
409 
410  CoUninitialize();
411 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
HRESULT hr
Definition: shlfolder.c:183
#define _countof(array)
Definition: fontsub.cpp:30
HRESULT hrForShell
Definition: CShellLink.cpp:231
GLuint buffer
Definition: glext.h:5915
#define IID_PPV_ARG(Itype, ppType)
int32_t INT
Definition: typedefs.h:56
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
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ok(value,...)
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW(IN LPCWSTR lpName, IN LPCWSTR lpValue)
Definition: environ.c:259
GLbitfield flags
Definition: glext.h:7161
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
#define wcsicmp
Definition: string.h:1152
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3234
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define S_OK
Definition: intsafe.h:59
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
LPCWSTR szPath
Definition: env.c:35
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:1991
HRESULT WINAPI DECLSPEC_HOTPATCH CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
Definition: compobj.c:1935
unsigned int UINT
Definition: ndis.h:50
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:519
#define skip(...)
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:141
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)