More shelllink tests
Francois Gouget
fgouget at codeweavers.com
Sun Feb 13 10:35:22 CST 2005
Changelog:
* dlls/shell32/tests/shelllink.c
Francois Gouget <fgouget at codeweavers.com>
Test the interaction between IShellLink::SetIDList() and
IShellLink::SetPath().
Check what default values one gets on a fresh IShellLink object.
Add some more tests verifying nothing is lost in an IShellLink
save/load cycle. Merged the empty shelllink test with these.
--
Francois Gouget
fgouget at codeweavers.com
-------------- next part --------------
Index: dlls/shell32/tests/shelllink.c
===================================================================
RCS file: /var/cvs/wine/dlls/shell32/tests/shelllink.c,v
retrieving revision 1.1
diff -u -p -r1.1 shelllink.c
--- dlls/shell32/tests/shelllink.c 22 Oct 2004 19:52:33 -0000 1.1
+++ dlls/shell32/tests/shelllink.c 13 Feb 2005 15:47:22 -0000
@@ -30,50 +30,506 @@
#include "winbase.h"
#include "shlguid.h"
#include "shobjidl.h"
+#include "shlobj.h"
#include "wine/test.h"
-static void test_empty_shelllink()
+static const WCHAR lnkfile[]= { 'C',':','\\','t','e','s','t','.','l','n','k',0 };
+static const WCHAR notafile[]= { 'C',':','\\','n','o','n','e','x','i','s','t','e','n','t','\\','f','i','l','e',0 };
+
+
+/* For some reason SHILCreateFromPath does not work on Win98 and
+ * SHSimpleIDListFromPathA does not work on NT4. But if we call both we
+ * get what we want on all platforms.
+ */
+static LPITEMIDLIST (WINAPI *pSHSimpleIDListFromPathA)(LPCSTR)=NULL;
+
+static LPITEMIDLIST path_to_pidl(const char* path)
+{
+ LPITEMIDLIST pidl;
+
+ if (!pSHSimpleIDListFromPathA)
+ {
+ HMODULE hdll=LoadLibraryA("shell32.dll");
+ pSHSimpleIDListFromPathA=(void*)GetProcAddress(hdll, (char*)162);
+ if (!pSHSimpleIDListFromPathA)
+ trace("SHSimpleIDListFromPathA not found in shell32.dll");
+ }
+
+ pidl=NULL;
+ if (pSHSimpleIDListFromPathA)
+ pidl=pSHSimpleIDListFromPathA(path);
+
+ if (!pidl)
+ {
+ WCHAR* pathW;
+ HRESULT r;
+ int len;
+
+ len=MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
+ pathW=HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len);
+
+ r=SHILCreateFromPath(pathW, &pidl, NULL);
+ todo_wine {
+ ok(SUCCEEDED(r), "SHILCreateFromPath failed (0x%08lx)\n", r);
+ }
+ HeapFree(GetProcessHeap(), 0, pathW);
+ }
+ return pidl;
+}
+
+
+/*
+ * Test manipulation of an IShellLink's properties.
+ */
+
+static void test_get_set()
+{
+ HRESULT r;
+ IShellLinkA *sl;
+ char mypath[MAX_PATH];
+ char buffer[INFOTIPSIZE];
+ LPITEMIDLIST pidl, tmp_pidl;
+ char * str;
+ int i;
+ WORD w;
+
+ r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkA, (LPVOID*)&sl);
+ ok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
+ if (!SUCCEEDED(r))
+ return;
+
+ /* Test Getting / Setting the description */
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetDescription failed (0x%08lx)\n", r);
+ ok(*buffer=='\0', "GetDescription returned '%s'\n", buffer);
+
+ str="Some description";
+ r = IShellLinkA_SetDescription(sl, str);
+ ok(SUCCEEDED(r), "SetDescription failed (0x%08lx)\n", r);
+
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetDescription failed (0x%08lx)\n", r);
+ ok(lstrcmp(buffer,str)==0, "GetDescription returned '%s'\n", buffer);
+
+ /* Test Getting / Setting the work directory */
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08lx)\n", r);
+ ok(*buffer=='\0', "GetWorkingDirectory returned '%s'\n", buffer);
+
+ str="c:\\nonexistent\\directory";
+ r = IShellLinkA_SetWorkingDirectory(sl, str);
+ ok(SUCCEEDED(r), "SetWorkingDirectory failed (0x%08lx)\n", r);
+
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08lx)\n", r);
+ ok(lstrcmpi(buffer,str)==0, "GetWorkingDirectory returned '%s'\n", buffer);
+
+ /* Test Getting / Setting the work directory */
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
+ ok(SUCCEEDED(r), "GetPath failed (0x%08lx)\n", r);
+ ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
+
+ str="c:\\nonexistent\\file";
+ r = IShellLinkA_SetPath(sl, str);
+ ok(SUCCEEDED(r), "SetPath failed (0x%08lx)\n", r);
+
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
+ ok(SUCCEEDED(r), "GetPath failed (0x%08lx)\n", r);
+ ok(lstrcmpi(buffer,str)==0, "GetPath returned '%s'\n", buffer);
+
+ /* Get some a real path to play with */
+ r=GetModuleFileName(NULL, mypath, sizeof(mypath));
+ ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%ld)\n", r);
+
+ /* Test the interaction of SetPath and SetIDList */
+ tmp_pidl=NULL;
+ r = IShellLinkA_GetIDList(sl, &tmp_pidl);
+ ok(SUCCEEDED(r), "GetIDList failed (0x%08lx)\n", r);
+ if (SUCCEEDED(r))
+ {
+ strcpy(buffer,"garbage");
+ r=SHGetPathFromIDListA(tmp_pidl, buffer);
+ todo_wine {
+ ok(r, "SHGetPathFromIDListA failed\n");
+ }
+ if (r)
+ ok(lstrcmpi(buffer,str)==0, "GetIDList returned '%s'\n", buffer);
+ }
+
+ pidl=path_to_pidl(mypath);
+ todo_wine {
+ ok(pidl!=NULL, "path_to_pidl returned a NULL pidl\n");
+ }
+
+ if (pidl)
+ {
+ r = IShellLinkA_SetIDList(sl, pidl);
+ ok(SUCCEEDED(r), "SetIDList failed (0x%08lx)\n", r);
+
+ tmp_pidl=NULL;
+ r = IShellLinkA_GetIDList(sl, &tmp_pidl);
+ ok(SUCCEEDED(r), "GetIDList failed (0x%08lx)\n", r);
+ ok(tmp_pidl && ILIsEqual(pidl, tmp_pidl),
+ "GetIDList returned an incorrect pidl\n");
+
+ /* tmp_pidl is owned by IShellLink so we don't free it */
+ ILFree(pidl);
+
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
+ ok(SUCCEEDED(r), "GetPath failed (0x%08lx)\n", r);
+ ok(lstrcmpi(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
+ }
+
+ /* Test Getting / Setting the arguments */
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetArguments failed (0x%08lx)\n", r);
+ ok(*buffer=='\0', "GetArguments returned '%s'\n", buffer);
+
+ str="param1 \"spaced param2\"";
+ r = IShellLinkA_SetArguments(sl, str);
+ ok(SUCCEEDED(r), "SetArguments failed (0x%08lx)\n", r);
+
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer));
+ ok(SUCCEEDED(r), "GetArguments failed (0x%08lx)\n", r);
+ ok(lstrcmp(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
+
+ /* Test Getting / Setting showcmd */
+ i=0xdeadbeef;
+ r = IShellLinkA_GetShowCmd(sl, &i);
+ ok(SUCCEEDED(r), "GetShowCmd failed (0x%08lx)\n", r);
+ ok(i==SW_SHOWNORMAL, "GetShowCmd returned %d\n", i);
+
+ r = IShellLinkA_SetShowCmd(sl, SW_SHOWMAXIMIZED);
+ ok(SUCCEEDED(r), "SetShowCmd failed (0x%08lx)\n", r);
+
+ i=0xdeadbeef;
+ r = IShellLinkA_GetShowCmd(sl, &i);
+ ok(SUCCEEDED(r), "GetShowCmd failed (0x%08lx)\n", r);
+ ok(i==SW_SHOWMAXIMIZED, "GetShowCmd returned %d'\n", i);
+
+ /* Test Getting / Setting the icon */
+ i=0xdeadbeef;
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
+ todo_wine {
+ ok(SUCCEEDED(r), "GetIconLocation failed (0x%08lx)\n", r);
+ }
+ ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer);
+ todo_wine {
+ ok(i==0, "GetIconLocation returned %d\n", i);
+ }
+
+ str="c:\\nonexistent\\file";
+ r = IShellLinkA_SetIconLocation(sl, str, 0xbabecafe);
+ ok(SUCCEEDED(r), "SetIconLocation failed (0x%08lx)\n", r);
+
+ i=0xdeadbeef;
+ r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
+ ok(SUCCEEDED(r), "GetIconLocation failed (0x%08lx)\n", r);
+ ok(lstrcmpi(buffer,str)==0, "GetArguments returned '%s'\n", buffer);
+ ok(i==0xbabecafe, "GetIconLocation returned %d'\n", i);
+
+ /* Test Getting / Setting the hot key */
+ w=0xbeef;
+ r = IShellLinkA_GetHotkey(sl, &w);
+ ok(SUCCEEDED(r), "GetHotkey failed (0x%08lx)\n", r);
+ ok(w==0, "GetHotkey returned %d\n", w);
+
+ r = IShellLinkA_SetHotkey(sl, 0x5678);
+ ok(SUCCEEDED(r), "SetHotkey failed (0x%08lx)\n", r);
+
+ w=0xbeef;
+ r = IShellLinkA_GetHotkey(sl, &w);
+ ok(SUCCEEDED(r), "GetHotkey failed (0x%08lx)\n", r);
+ ok(w==0x5678, "GetHotkey returned %d'\n", w);
+
+ IShellLinkA_Release(sl);
+}
+
+
+/*
+ * Test saving and loading .lnk files
+ */
+
+typedef struct
+{
+ char* description;
+ char* workdir;
+ char* path;
+ LPITEMIDLIST pidl;
+ char* arguments;
+ int showcmd;
+ char* icon;
+ int icon_id;
+ WORD hotkey;
+} lnk_desc_t;
+
+#define lok ok_(__FILE__, line)
+#define create_lnk(a,b,c) create_lnk_(__LINE__, (a), (b), (c))
+#define check_lnk(a,b) check_lnk_(__LINE__, (a), (b))
+
+static void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
{
HRESULT r;
- IShellLinkW *sl;
- WCHAR buffer[0x100];
+ IShellLinkA *sl;
IPersistFile *pf;
- CoInitialize(NULL);
+ r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkA, (LPVOID*)&sl);
+ lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
+ if (!SUCCEEDED(r))
+ return;
- /* empty shelllink ? */
- r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
- &IID_IShellLinkW, (LPVOID*)&sl );
- ok (r == S_OK, "no shelllink\n");
- if (r == S_OK)
- {
- static const WCHAR lnk[]= { 'C',':','\\','t','e','s','t','.','l','n','k',0 };
-
- buffer[0]='x';
- buffer[1]=0;
- r = IShellLinkW_GetPath(sl, buffer, 0x100, NULL, SLGP_RAWPATH );
- ok (r == S_OK, "GetPath failed\n");
- ok (buffer[0]==0, "path wrong\n");
-
- r = IShellLinkW_QueryInterface(sl, &IID_IPersistFile, (LPVOID*) &pf );
- ok (r == S_OK, "no IPersistFile\n");
- todo_wine
+ if (desc->description)
+ {
+ r = IShellLinkA_SetDescription(sl, desc->description);
+ lok(SUCCEEDED(r), "SetDescription failed (0x%08lx)\n", r);
+ }
+ if (desc->workdir)
+ {
+ r = IShellLinkA_SetWorkingDirectory(sl, desc->workdir);
+ lok(SUCCEEDED(r), "SetWorkingDirectory failed (0x%08lx)\n", r);
+ }
+ if (desc->path)
+ {
+ r = IShellLinkA_SetPath(sl, desc->path);
+ lok(SUCCEEDED(r), "SetPath failed (0x%08lx)\n", r);
+ }
+ if (desc->pidl)
+ {
+ r = IShellLinkA_SetIDList(sl, desc->pidl);
+ lok(SUCCEEDED(r), "SetIDList failed (0x%08lx)\n", r);
+ }
+ if (desc->arguments)
+ {
+ r = IShellLinkA_SetArguments(sl, desc->arguments);
+ lok(SUCCEEDED(r), "SetArguments failed (0x%08lx)\n", r);
+ }
+ if (desc->showcmd)
+ {
+ r = IShellLinkA_SetShowCmd(sl, desc->showcmd);
+ lok(SUCCEEDED(r), "SetShowCmd failed (0x%08lx)\n", r);
+ }
+ if (desc->icon)
+ {
+ r = IShellLinkA_SetIconLocation(sl, desc->icon, desc->icon_id);
+ lok(SUCCEEDED(r), "SetIconLocation failed (0x%08lx)\n", r);
+ }
+ if (desc->hotkey)
+ {
+ r = IShellLinkA_SetHotkey(sl, desc->hotkey);
+ lok(SUCCEEDED(r), "SetHotkey failed (0x%08lx)\n", r);
+ }
+
+ r = IShellLinkW_QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf);
+ lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08lx)\n", r);
+ if (SUCCEEDED(r))
+ {
+ r = IPersistFile_Save(pf, path, TRUE);
+ if (save_fails)
{
- if (r == S_OK )
+ todo_wine {
+ lok(SUCCEEDED(r), "save failed (0x%08lx)\n", r);
+ }
+ }
+ else
{
- r = IPersistFile_Save(pf, lnk, TRUE);
- ok (r == S_OK, "save failed\n");
- IPersistFile_Release(pf);
+ lok(SUCCEEDED(r), "save failed (0x%08lx)\n", r);
}
+ IPersistFile_Release(pf);
+ }
- IShellLinkW_Release(sl);
+ IShellLinkA_Release(sl);
+}
- ok (DeleteFileW(lnk), "failed to delete link\n");
- }
+static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
+{
+ HRESULT r;
+ IShellLinkA *sl;
+ IPersistFile *pf;
+ char buffer[INFOTIPSIZE];
+
+ r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IShellLinkA, (LPVOID*)&sl);
+ lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
+ if (!SUCCEEDED(r))
+ return;
+
+ r = IShellLinkA_QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf);
+ lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08lx)\n", r);
+ if (!SUCCEEDED(r))
+ {
+ IShellLinkA_Release(sl);
+ return;
+ }
+
+ r = IPersistFile_Load(pf, path, STGM_READ);
+ todo_wine {
+ lok(SUCCEEDED(r), "load failed (0x%08lx)\n", r);
+ }
+ IPersistFile_Release(pf);
+ if (!SUCCEEDED(r))
+ {
+ IShellLinkA_Release(sl);
+ return;
}
+
+ if (desc->description)
+ {
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
+ lok(SUCCEEDED(r), "GetDescription failed (0x%08lx)\n", r);
+ lok(lstrcmp(buffer, desc->description)==0,
+ "GetDescription returned '%s' instead of '%s'\n",
+ buffer, desc->description);
+ }
+ if (desc->workdir)
+ {
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
+ lok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08lx)\n", r);
+ lok(lstrcmpi(buffer, desc->workdir)==0,
+ "GetWorkingDirectory returned '%s' instead of '%s'\n",
+ buffer, desc->workdir);
+ }
+ if (desc->path)
+ {
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
+ lok(SUCCEEDED(r), "GetPath failed (0x%08lx)\n", r);
+ lok(lstrcmpi(buffer, desc->path)==0,
+ "GetPath returned '%s' instead of '%s'\n",
+ buffer, desc->path);
+ }
+ if (desc->pidl)
+ {
+ LPITEMIDLIST pidl=NULL;
+ r = IShellLinkA_GetIDList(sl, &pidl);
+ lok(SUCCEEDED(r), "GetIDList failed (0x%08lx)\n", r);
+ lok(ILIsEqual(pidl, desc->pidl),
+ "GetIDList returned an incorrect pidl\n");
+ }
+ if (desc->showcmd)
+ {
+ int i=0xdeadbeef;
+ r = IShellLinkA_GetShowCmd(sl, &i);
+ lok(SUCCEEDED(r), "GetShowCmd failed (0x%08lx)\n", r);
+ lok(i==desc->showcmd,
+ "GetShowCmd returned 0x%0x instead of 0x%0x\n",
+ i, desc->showcmd);
+ }
+ if (desc->icon)
+ {
+ int i=0xdeadbeef;
+ strcpy(buffer,"garbage");
+ r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
+ lok(SUCCEEDED(r), "GetIconLocation failed (0x%08lx)\n", r);
+ lok(lstrcmpi(buffer, desc->icon)==0,
+ "GetIconLocation returned '%s' instead of '%s'\n",
+ buffer, desc->icon);
+ lok(i==desc->icon_id,
+ "GetIconLocation returned 0x%0x instead of 0x%0x\n",
+ i, desc->icon_id);
+ }
+ if (desc->hotkey)
+ {
+ WORD i=0xbeef;
+ r = IShellLinkA_GetHotkey(sl, &i);
+ lok(SUCCEEDED(r), "GetHotkey failed (0x%08lx)\n", r);
+ lok(i==desc->hotkey,
+ "GetHotkey returned 0x%04x instead of 0x%04x\n",
+ i, desc->hotkey);
+ }
+
+ IShellLinkA_Release(sl);
+}
+
+static void test_load_save()
+{
+ lnk_desc_t desc;
+ char mypath[MAX_PATH];
+ char mydir[MAX_PATH];
+ char* p;
+ DWORD r;
+
+ /* Save an empty .lnk file */
+ memset(&desc, 0, sizeof(desc));
+ create_lnk(lnkfile, &desc, 1);
+
+ /* It should come back as a bunch of empty strings */
+ desc.description="";
+ desc.workdir="";
+ desc.path="";
+ desc.arguments="";
+ desc.icon="";
+ check_lnk(lnkfile, &desc);
+
+
+ /* Point a .lnk file to nonexistent files */
+ desc.description="";
+ desc.workdir="c:\\Nonexitent\\work\\directory";
+ desc.path="c:\\nonexistent\\path";
+ desc.pidl=NULL;
+ desc.arguments="";
+ desc.showcmd=0;
+ desc.icon="c:\\nonexistent\\icon\\file";
+ desc.icon_id=1234;
+ desc.hotkey=0;
+ create_lnk(lnkfile, &desc, 0);
+ check_lnk(lnkfile, &desc);
+
+ r=GetModuleFileName(NULL, mypath, sizeof(mypath));
+ ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%ld)\n", r);
+ strcpy(mydir, mypath);
+ p=strrchr(mydir, '\\');
+ if (p)
+ *p='\0';
+
+
+ /* Overwrite the existing lnk file and point it to existing files */
+ desc.description="test 2";
+ desc.workdir=mydir;
+ desc.path=mypath;
+ desc.pidl=NULL;
+ desc.arguments="/option1 /option2 \"Some string\"";
+ desc.showcmd=SW_SHOWNORMAL;
+ desc.icon=mypath;
+ desc.icon_id=0;
+ desc.hotkey=0x1234;
+ create_lnk(lnkfile, &desc, 0);
+ check_lnk(lnkfile, &desc);
+
+ /* FIXME: Also test saving a .lnk pointing to a pidl that cannot be
+ * represented as a path.
+ */
+
+ /* DeleteFileW is not implemented on Win9x */
+ r=DeleteFileA("c:\\test.lnk");
+ ok(r, "failed to delete link (%ld)\n", GetLastError());
}
START_TEST(shelllink)
{
- test_empty_shelllink();
+ HRESULT r;
+
+ r = CoInitialize(NULL);
+ ok(SUCCEEDED(r), "CoInitialize failed (0x%08lx)\b", r);
+ if (!SUCCEEDED(r))
+ return;
+
+ test_get_set();
+ test_load_save();
+
+ CoUninitialize();
}
More information about the wine-patches
mailing list