#include "shlguid.h"
#include "shobjidl.h"
#include "shlobj.h"
+#include "shellapi.h"
#include "wine/test.h"
#include "shell32_test.h"
static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
static HRESULT (WINAPI *pSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*);
static HRESULT (WINAPI *pSHDefExtractIconA)(LPCSTR, int, UINT, HICON*, HICON*, UINT);
-
+static HRESULT (WINAPI *pSHGetStockIconInfo)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *);
static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD);
static DWORD (WINAPI *pGetShortPathNameA)(LPCSTR, LPSTR, DWORD);
+static UINT (WINAPI *pSHExtractIconsW)(LPCWSTR, int, int, int, HICON *, UINT *, UINT, UINT);
static const GUID _IID_IShellLinkDataList = {
0x45e2b4ae, 0xb1c3, 0x11d0,
strcpy(buffer,"garbage");
r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
ok(r == S_OK, "GetDescription failed (0x%08x)\n", r);
- ok(lstrcmp(buffer,str)==0, "GetDescription returned '%s'\n", buffer);
+ ok(strcmp(buffer,str)==0, "GetDescription returned '%s'\n", buffer);
r = IShellLinkA_SetDescription(sl, NULL);
ok(r == S_OK, "SetDescription failed (0x%08x)\n", r);
strcpy(buffer,"garbage");
r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
ok(r == S_OK, "GetDescription failed (0x%08x)\n", r);
- ok(*buffer=='\0' || broken(lstrcmp(buffer,str)==0), "GetDescription returned '%s'\n", buffer); /* NT4 */
-
+ ok(*buffer=='\0' || broken(strcmp(buffer,str)==0), "GetDescription returned '%s'\n", buffer); /* NT4 */
/* Test Getting / Setting the work directory */
strcpy(buffer,"garbage");
strcpy(buffer,"garbage");
r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
ok(r == S_OK, "GetWorkingDirectory failed (0x%08x)\n", r);
- ok(lstrcmpi(buffer,str)==0, "GetWorkingDirectory returned '%s'\n", buffer);
+ ok(lstrcmpiA(buffer,str)==0, "GetWorkingDirectory returned '%s'\n", buffer);
/* Test Getting / Setting the path */
strcpy(buffer,"garbage");
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
- ok(lstrcmpi(buffer,str)==0, "GetPath returned '%s'\n", buffer);
+ ok(lstrcmpiA(buffer,str)==0, "GetPath returned '%s'\n", buffer);
/* Get some real path to play with */
GetWindowsDirectoryA( mypath, sizeof(mypath)-12 );
ret = SHGetPathFromIDListA(tmp_pidl, buffer);
ok(ret, "SHGetPathFromIDListA failed\n");
if (ret)
- ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
+ ok(lstrcmpiA(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
pILFree(tmp_pidl);
}
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
todo_wine
- ok(lstrcmpi(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
-
+ ok(lstrcmpiA(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
}
/* test path with quotes (IShellLinkA_SetPath returns S_FALSE on W2K and below and S_OK on XP and above */
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r==S_OK, "GetPath failed (0x%08x)\n", r);
- ok(!lstrcmp(buffer, "C:\\nonexistent\\file") ||
- broken(!lstrcmp(buffer, "C:\\\"c:\\nonexistent\\file\"")), /* NT4 */
+ ok(!strcmp(buffer, "C:\\nonexistent\\file") ||
+ broken(!strcmp(buffer, "C:\\\"c:\\nonexistent\\file\"")), /* NT4 */
"case doesn't match\n");
r = IShellLinkA_SetPath(sl, "\"c:\\foo");
strcpy(buffer,"garbage");
r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer));
ok(r == S_OK, "GetArguments failed (0x%08x)\n", r);
- ok(lstrcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
+ ok(strcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
strcpy(buffer,"garbage");
r = IShellLinkA_SetArguments(sl, NULL);
ok(r == S_OK, "SetArguments failed (0x%08x)\n", r);
r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer));
ok(r == S_OK, "GetArguments failed (0x%08x)\n", r);
- ok(!buffer[0] || lstrcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
+ ok(!buffer[0] || strcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
strcpy(buffer,"garbage");
r = IShellLinkA_SetArguments(sl, "");
i=0xdeadbeef;
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
- ok(lstrcmpi(buffer,str)==0, "GetIconLocation returned '%s'\n", buffer);
+ ok(lstrcmpiA(buffer,str)==0, "GetIconLocation returned '%s'\n", buffer);
ok(i==0xbabecafe, "GetIconLocation returned %d'\n", i);
/* Test Getting / Setting the hot key */
strcpy(buffer,"garbage");
r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
lok(r == S_OK, "GetDescription failed (0x%08x)\n", r);
- lok_todo_4(0x1, lstrcmp(buffer, desc->description)==0,
+ lok_todo_4(0x1, strcmp(buffer, desc->description)==0,
"GetDescription returned '%s' instead of '%s'\n",
buffer, desc->description);
}
strcpy(buffer,"garbage");
r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
lok(r == S_OK, "GetWorkingDirectory failed (0x%08x)\n", r);
- lok_todo_4(0x2, lstrcmpi(buffer, desc->workdir)==0,
+ lok_todo_4(0x2, lstrcmpiA(buffer, desc->workdir)==0,
"GetWorkingDirectory returned '%s' instead of '%s'\n",
buffer, desc->workdir);
}
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
lok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
- lok_todo_4(0x4, lstrcmpi(buffer, desc->path)==0,
+ lok_todo_4(0x4, lstrcmpiA(buffer, desc->path)==0,
"GetPath returned '%s' instead of '%s'\n",
buffer, desc->path);
}
strcpy(buffer,"garbage");
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
lok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
- lok_todo_4(0x20, lstrcmpi(buffer, desc->icon)==0,
+ lok_todo_4(0x20, lstrcmpiA(buffer, desc->icon)==0,
"GetIconLocation returned '%s' instead of '%s'\n",
buffer, desc->icon);
lok_todo_4(0x20, i==desc->icon_id,
create_lnk(lnkfile, &desc, 0);
check_lnk(lnkfile, &desc, 0x0);
- r=GetModuleFileName(NULL, mypath, sizeof(mypath));
+ r=GetModuleFileNameA(NULL, mypath, sizeof(mypath));
ok(r<sizeof(mypath), "GetModuleFileName failed (%d)\n", r);
strcpy(mydir, mypath);
p=strrchr(mydir, '\\');
check_lnk(lnkfile, &desc, 0x4);
/* Create a temporary non-executable file */
- r=GetTempPath(sizeof(mypath), mypath);
+ r=GetTempPathA(sizeof(mypath), mypath);
ok(r<sizeof(mypath), "GetTempPath failed (%d), err %d\n", r, GetLastError());
r=pGetLongPathNameA(mypath, mydir, sizeof(mydir));
ok(r<sizeof(mydir), "GetLongPathName failed (%d), err %d\n", r, GetLastError());
strcpy(mypath, mydir);
strcat(mypath, "\\test.txt");
- hf = CreateFile(mypath, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ hf = CreateFileA(mypath, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hf);
/* Overwrite the existing lnk file and test link to an existing non-executable file */
/* Create a temporary .bat file */
strcpy(mypath, mydir);
strcat(mypath, "\\test.bat");
- hf = CreateFile(mypath, GENERIC_WRITE, 0, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ hf = CreateFileA(mypath, GENERIC_WRITE, 0, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hf);
strcpy(realpath, mypath);
i = 0xdeadbeef;
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
ok(r == S_OK, "GetIconLocation failed (0x%08x)\n", r);
- ok(lstrcmpi(buffer,str) == 0, "GetIconLocation returned '%s'\n", buffer);
+ ok(lstrcmpiA(buffer,str) == 0, "GetIconLocation returned '%s'\n", buffer);
ok(i == 0xbabecafe, "GetIconLocation returned %d'\n", i);
IShellLinkA_Release(sl);
}
+static void test_SHGetStockIconInfo(void)
+{
+ BYTE buffer[sizeof(SHSTOCKICONINFO) + 16];
+ SHSTOCKICONINFO *sii = (SHSTOCKICONINFO *) buffer;
+ BOOL atleast_win7;
+ HRESULT hr;
+ INT i;
+
+ /* not present before vista */
+ if (!pSHGetStockIconInfo)
+ {
+ win_skip("SHGetStockIconInfo not available\n");
+ return;
+ }
+
+ /* negative values are handled */
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(-1, SHGSI_ICONLOCATION, sii);
+ ok(hr == E_INVALIDARG, "-1: got 0x%x (expected E_INVALIDARG)\n", hr);
+
+ /* max. id for vista is 140 (no definition exists for this value) */
+ for (i = 0; i <= 140; i++)
+ {
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(i, SHGSI_ICONLOCATION, sii);
+
+ ok(hr == S_OK,
+ "%3d: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x (expected S_OK)\n",
+ i, hr, sii->iSysImageIndex, sii->iIcon);
+
+ if ((hr == S_OK) && (winetest_debug > 1))
+ trace("%3d: got iSysImageIndex %3d, iIcon %3d and %s\n", i, sii->iSysImageIndex,
+ sii->iIcon, wine_dbgstr_w(sii->szPath));
+ }
+
+ /* there are more icons since win7 */
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(i, SHGSI_ICONLOCATION, sii);
+ atleast_win7 = (!hr);
+
+ for (; i < (SIID_MAX_ICONS + 25) ; i++)
+ {
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(i, SHGSI_ICONLOCATION, sii);
+
+ if (atleast_win7 && (i == (SIID_MAX_ICONS - 1)) && broken(hr == E_INVALIDARG))
+ {
+ /* Off by one windows bug: there are SIID_MAX_ICONS icons from 0
+ * up to SIID_MAX_ICONS-1 on Windows 8, but the last one is missing
+ * on Windows 7.
+ */
+ trace("%3d: got E_INVALIDARG (windows bug: off by one)\n", i);
+ }
+ else if (atleast_win7 && (i < (SIID_MAX_ICONS)))
+ {
+ ok(hr == S_OK,
+ "%3d: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x (expected S_OK)\n",
+ i, hr, sii->iSysImageIndex, sii->iIcon);
+
+ if ((hr == S_OK) && (winetest_debug > 1))
+ trace("%3d: got iSysImageIndex %3d, iIcon %3d and %s\n", i, sii->iSysImageIndex,
+ sii->iIcon, wine_dbgstr_w(sii->szPath));
+ }
+ else
+ ok(hr == E_INVALIDARG, "%3d: got 0x%x (expected E_INVALIDARG)\n", i, hr);
+ }
+
+ /* test more returned SHSTOCKICONINFO elements without extra flags */
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO);
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, sii);
+ ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
+ ok(!sii->hIcon, "got %p (expected NULL)\n", sii->hIcon);
+ ok(sii->iSysImageIndex == -1, "got %d (expected -1)\n", sii->iSysImageIndex);
+
+ /* the exact size is required of the struct */
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO) + 2;
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, sii);
+ ok(hr == E_INVALIDARG, "+2: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x\n", hr, sii->iSysImageIndex, sii->iIcon);
+
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO) + 1;
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, sii);
+ ok(hr == E_INVALIDARG, "+1: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x\n", hr, sii->iSysImageIndex, sii->iIcon);
+
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO) - 1;
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, sii);
+ ok(hr == E_INVALIDARG, "-1: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x\n", hr, sii->iSysImageIndex, sii->iIcon);
+
+ memset(buffer, '#', sizeof(buffer));
+ sii->cbSize = sizeof(SHSTOCKICONINFO) - 2;
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, sii);
+ ok(hr == E_INVALIDARG, "-2: got 0x%x, iSysImageIndex: 0x%x, iIcon: 0x%x\n", hr, sii->iSysImageIndex, sii->iIcon);
+
+ /* there is a NULL check for the struct */
+ hr = pSHGetStockIconInfo(SIID_FOLDER, SHGSI_ICONLOCATION, NULL);
+ ok(hr == E_INVALIDARG, "NULL: got 0x%x\n", hr);
+}
+
+static void test_SHExtractIcons(void)
+{
+ static const WCHAR notepadW[] = {'n','o','t','e','p','a','d','.','e','x','e',0};
+ static const WCHAR shell32W[] = {'s','h','e','l','l','3','2','.','d','l','l',0};
+ static const WCHAR emptyW[] = {0};
+ UINT ret, ret2;
+ HICON icons[256];
+ UINT ids[256], i;
+
+ if (!pSHExtractIconsW)
+ {
+ win_skip("SHExtractIconsW not available\n");
+ return;
+ }
+
+ ret = pSHExtractIconsW(emptyW, 0, 16, 16, icons, ids, 1, 0);
+ ok(ret == ~0u, "got %u\n", ret);
+
+ ret = pSHExtractIconsW(notepadW, 0, 16, 16, NULL, NULL, 1, 0);
+ ok(ret == 1 || broken(ret == 2) /* win2k */, "got %u\n", ret);
+
+ icons[0] = (HICON)0xdeadbeef;
+ ret = pSHExtractIconsW(notepadW, 0, 16, 16, icons, NULL, 1, 0);
+ ok(ret == 1, "got %u\n", ret);
+ ok(icons[0] != (HICON)0xdeadbeef, "icon not set\n");
+ DestroyIcon(icons[0]);
+
+ icons[0] = (HICON)0xdeadbeef;
+ ids[0] = 0xdeadbeef;
+ ret = pSHExtractIconsW(notepadW, 0, 16, 16, icons, ids, 1, 0);
+ ok(ret == 1, "got %u\n", ret);
+ ok(icons[0] != (HICON)0xdeadbeef, "icon not set\n");
+ ok(ids[0] != 0xdeadbeef, "id not set\n");
+ DestroyIcon(icons[0]);
+
+ ret = pSHExtractIconsW(shell32W, 0, 16, 16, NULL, NULL, 0, 0);
+ ret2 = pSHExtractIconsW(shell32W, 4, MAKELONG(32,16), MAKELONG(32,16), NULL, NULL, 256, 0);
+ ok(ret && ret == ret2,
+ "icon count should be independent of requested icon sizes and base icon index\n");
+
+ ret = pSHExtractIconsW(shell32W, 0, 16, 16, icons, ids, 0, 0);
+ ok(ret == ~0u || !ret /* < vista */, "got %u\n", ret);
+
+ ret = pSHExtractIconsW(shell32W, 0, 16, 16, icons, ids, 3, 0);
+ ok(ret == 3, "got %u\n", ret);
+ for (i = 0; i < ret; i++) DestroyIcon(icons[i]);
+
+ /* count must be a multiple of two when getting two sizes */
+ ret = pSHExtractIconsW(shell32W, 0, MAKELONG(16,32), MAKELONG(16,32), icons, ids, 3, 0);
+ ok(!ret /* vista */ || ret == 4, "got %u\n", ret);
+ for (i = 0; i < ret; i++) DestroyIcon(icons[i]);
+
+ ret = pSHExtractIconsW(shell32W, 0, MAKELONG(16,32), MAKELONG(16,32), icons, ids, 4, 0);
+ ok(ret == 4, "got %u\n", ret);
+ for (i = 0; i < ret; i++) DestroyIcon(icons[i]);
+}
+
START_TEST(shelllink)
{
HRESULT r;
pILIsEqual = (void *)GetProcAddress(hmod, (LPSTR)21);
pSHILCreateFromPath = (void *)GetProcAddress(hmod, (LPSTR)28);
pSHDefExtractIconA = (void *)GetProcAddress(hmod, "SHDefExtractIconA");
-
+ pSHGetStockIconInfo = (void *)GetProcAddress(hmod, "SHGetStockIconInfo");
pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA");
pGetShortPathNameA = (void *)GetProcAddress(hkernel32, "GetShortPathNameA");
+ pSHExtractIconsW = (void *)GetProcAddress(hmod, "SHExtractIconsW");
r = CoInitialize(NULL);
ok(r == S_OK, "CoInitialize failed (0x%08x)\n", r);
test_datalink();
test_shdefextracticon();
test_GetIconLocation();
+ test_SHGetStockIconInfo();
+ test_SHExtractIcons();
CoUninitialize();
}