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