[SHELL32_APITEST]: Add some tests for GetIconLocation. Show also that CShellLink...
[reactos.git] / rostests / apitests / shell32 / CShellLink.cpp
index a023204..ae31559 100644 (file)
@@ -221,12 +221,134 @@ TestDescription(void)
     psl->Release();
 }
 
+
+/* Test IShellLink::Get/SetIconLocation and IExtractIcon::GetIconLocation */
+typedef struct
+{
+    PCWSTR FilePath;
+
+    /* Expected results */
+    HRESULT hrDefIcon;  // Return value for GIL_DEFAULTICON
+    HRESULT hrForShrt;  // Return value for GIL_FORSHORTCUT
+    /* Return values for GIL_FORSHELL */
+    HRESULT hrForShell;
+    PCWSTR  IconPath;
+    UINT    Flags;
+} TEST_SHELL_ICON;
+
+static TEST_SHELL_ICON ShIconTests[] =
+{
+    /* Executable with icons */
+    {L"%SystemRoot%\\system32\\cmd.exe", S_FALSE, E_INVALIDARG,
+     S_OK, L"%SystemRoot%\\system32\\cmd.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
+
+    /* Executable without icon */
+    {L"%SystemRoot%\\system32\\autochk.exe", S_FALSE, E_INVALIDARG,
+     S_OK, L"%SystemRoot%\\system32\\autochk.exe", GIL_NOTFILENAME | GIL_PERINSTANCE},
+
+    /* Existing file */
+    {L"%SystemRoot%\\system32\\shell32.dll", S_FALSE, E_INVALIDARG,
+     S_OK, L"%SystemRoot%\\system32\\shell32.dll", GIL_NOTFILENAME | GIL_PERCLASS},
+
+    /* Non-existing file */
+    {L"c:\\non-existent-path\\non-existent-file.sdf", S_FALSE, E_INVALIDARG,
+     S_OK, L"c:\\non-existent-path\\non-existent-file.sdf", GIL_NOTFILENAME | GIL_PERCLASS},
+};
+
+static
+VOID
+test_iconlocation(UINT i, TEST_SHELL_ICON* testDef)
+{
+    HRESULT hr;
+    IShellLinkW *psl;
+    IExtractIconW *pei;
+    INT iIcon;
+    UINT wFlags;
+    WCHAR szPath[MAX_PATH];
+
+    hr = CoCreateInstance(CLSID_ShellLink,
+                          NULL,
+                          CLSCTX_INPROC_SERVER,
+                          IID_PPV_ARG(IShellLinkW, &psl));
+    ok(hr == S_OK, "CoCreateInstance, hr = 0x%lx\n", hr);
+    if (FAILED(hr))
+    {
+        skip("Could not instantiate CShellLink\n");
+        return;
+    }
+
+    /* Set the path to a file */
+    ExpandEnvironmentStringsW(testDef->FilePath, szPath, _countof(szPath));
+    hr = psl->SetPath(szPath);
+    ok(hr == S_OK, "IShellLink::SetPath failed, hr = 0x%lx\n", hr);
+
+    /*
+     * This test shows that this does not imply that the icon is automatically
+     * set and be retrieved naively by a call to IShellLink::GetIconLocation.
+     */
+    iIcon = 0xdeadbeef;
+    wcscpy(szPath, L"garbage");
+    hr = psl->GetIconLocation(szPath, _countof(szPath), &iIcon);
+    ok(hr == S_OK, "IShellLink::GetIconLocation(%d) failed, hr = 0x%lx\n", i, hr);
+    ok(*szPath == L'\0', "IShellLink::GetIconLocation(%d) returned '%S'\n", i, szPath);
+    ok(iIcon == 0, "IShellLink::GetIconLocation(%d) returned %d\n", i, iIcon);
+
+    /* Try to grab the IExtractIconW interface */
+    hr = psl->QueryInterface(IID_PPV_ARG(IExtractIconW, &pei)); 
+    ok(hr == S_OK, "IShellLink::QueryInterface(IExtractIconW)(%d) failed, hr = 0x%lx\n", i, hr);
+    if (!pei)
+    {
+        win_skip("No IExtractIconW interface\n");
+        psl->Release();
+        return;
+    }
+
+    iIcon = wFlags = 0xdeadbeef;
+    wcscpy(szPath, L"garbage");
+    hr = pei->GetIconLocation(GIL_DEFAULTICON, szPath, _countof(szPath), &iIcon, &wFlags);
+    ok(hr == testDef->hrDefIcon, "IShellLink::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrDefIcon);
+    ok(*szPath == L'\0', "IShellLink::GetIconLocation(%d) returned '%S'\n", i, szPath);
+    // ok(iIcon == 0, "IShellLink::GetIconLocation(%d) returned %d\n", i, iIcon);
+
+    iIcon = wFlags = 0xdeadbeef;
+    wcscpy(szPath, L"garbage");
+    hr = pei->GetIconLocation(GIL_FORSHORTCUT, szPath, _countof(szPath), &iIcon, &wFlags);
+    ok(hr == testDef->hrForShrt, "IShellLink::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShrt);
+    // Here, both szPath and iIcon are untouched...
+
+    iIcon = wFlags = 0xdeadbeef;
+    wcscpy(szPath, L"garbage");
+    hr = pei->GetIconLocation(GIL_FORSHELL, szPath, _countof(szPath), &iIcon, &wFlags);
+    ok(hr == testDef->hrForShell, "IShellLink::GetIconLocation(%d) returned hr = 0x%lx, expected 0x%lx\n", i, hr, testDef->hrForShell);
+    ok(wFlags == testDef->Flags, "IShellLink::GetIconLocation(%d) returned wFlags = 0x%lx, expected 0x%lx\n", i, wFlags, testDef->Flags);
+    // ok(*szPath == L'\0', "IShellLink::GetIconLocation returned '%S'\n", szPath);
+    // ok(iIcon == 0, "IShellLink::GetIconLocation returned %d\n", iIcon);
+    // ok(FALSE, "hr = 0x%lx, szPath = '%S', iIcon = %d, wFlags = %d\n", hr, szPath, iIcon, wFlags);
+
+    /* Release the interfaces */
+    pei->Release();
+    psl->Release();
+}
+
+static
+VOID
+TestIconLocation(void)
+{
+    UINT i;
+
+    for (i = 0; i < _countof(ShIconTests); ++i)
+    {
+        test_iconlocation(i, &ShIconTests[i]);
+    }
+}
+
 START_TEST(CShellLink)
 {
     CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 
     TestShellLink();
     TestDescription();
+    TestIconLocation();
 
     CoUninitialize();
 }