Update shell32 tests

svn path=/trunk/; revision=28593
This commit is contained in:
Hervé Poussineau 2007-08-27 07:03:32 +00:00
parent 11b12696f1
commit 7b6bb2a6fd
10 changed files with 3105 additions and 462 deletions

View file

@ -201,14 +201,16 @@ static void test_pack_COAUTHINFO(void)
TEST_FIELD(COAUTHINFO, DWORD, dwCapabilities, 24, 4, 4);
}
static void test_pack_COSERVERINFO(void)
static void test_pack_DATE(void)
{
/* COSERVERINFO (pack 4) */
TEST_TYPE(COSERVERINFO, 16, 4);
TEST_FIELD(COSERVERINFO, DWORD, dwReserved1, 0, 4, 4);
TEST_FIELD(COSERVERINFO, LPWSTR, pwszName, 4, 4, 4);
TEST_FIELD(COSERVERINFO, COAUTHINFO *, pAuthInfo, 8, 4, 4);
TEST_FIELD(COSERVERINFO, DWORD, dwReserved2, 12, 4, 4);
/* DATE */
TEST_TYPE(DATE, 8, 8);
}
static void test_pack_DOUBLE(void)
{
/* DOUBLE */
TEST_TYPE(DOUBLE, 8, 8);
}
static void test_pack_DWORD_SIZEDARR(void)
@ -255,7 +257,6 @@ static void test_pack_LPBLOB(void)
{
/* LPBLOB */
TEST_TYPE(LPBLOB, 4, 4);
TEST_TYPE_POINTER(LPBLOB, 8, 4);
}
static void test_pack_LPBSTR(void)
@ -269,7 +270,6 @@ static void test_pack_LPBSTRBLOB(void)
{
/* LPBSTRBLOB */
TEST_TYPE(LPBSTRBLOB, 4, 4);
TEST_TYPE_POINTER(LPBSTRBLOB, 8, 4);
}
static void test_pack_LPCOLESTR(void)
@ -835,7 +835,6 @@ static void test_pack_LPITEMIDLIST(void)
{
/* LPITEMIDLIST */
TEST_TYPE(LPITEMIDLIST, 4, 4);
TEST_TYPE_POINTER(LPITEMIDLIST, 3, 1);
}
static void test_pack_LPSHELLDETAILS(void)
@ -848,7 +847,6 @@ static void test_pack_LPSHITEMID(void)
{
/* LPSHITEMID */
TEST_TYPE(LPSHITEMID, 4, 4);
TEST_TYPE_POINTER(LPSHITEMID, 3, 1);
}
static void test_pack_LPSTRRET(void)
@ -1011,26 +1009,6 @@ static void test_pack_FILEGROUPDESCRIPTORW(void)
TEST_FIELD(FILEGROUPDESCRIPTORW, FILEDESCRIPTORW[1], fgd, 4, 592, 1);
}
static void test_pack_IFileSystemBindData(void)
{
/* IFileSystemBindData */
}
static void test_pack_IFileSystemBindDataVtbl(void)
{
/* IFileSystemBindDataVtbl */
}
static void test_pack_IShellChangeNotify(void)
{
/* IShellChangeNotify */
}
static void test_pack_IShellIcon(void)
{
/* IShellIcon */
}
static void test_pack_LPBROWSEINFOA(void)
{
/* LPBROWSEINFOA */
@ -1282,8 +1260,9 @@ static void test_pack(void)
test_pack_CLSID();
test_pack_COAUTHIDENTITY();
test_pack_COAUTHINFO();
test_pack_COSERVERINFO();
test_pack_CSFV();
test_pack_DATE();
test_pack_DOUBLE();
test_pack_DRAGINFOA();
test_pack_DRAGINFOW();
test_pack_DROPFILES();
@ -1299,11 +1278,7 @@ static void test_pack(void)
test_pack_GUID();
test_pack_HMETAFILEPICT();
test_pack_HYPER_SIZEDARR();
test_pack_IFileSystemBindData();
test_pack_IFileSystemBindDataVtbl();
test_pack_IID();
test_pack_IShellChangeNotify();
test_pack_IShellIcon();
test_pack_ITEMIDLIST();
test_pack_LPBLOB();
test_pack_LPBROWSEINFOA();

View file

@ -1,17 +1,27 @@
<module name="shell32_winetest" type="win32cui" installbase="bin" installname="shell32_winetest.exe" allowwarnings="true">
<include base="shell32_winetest">.</include>
<define name="__USE_W32API" />
<library>ntdll</library>
<library>shell32</library>
<library>kernel32</library>
<library>advapi32</library>
<library>shlwapi</library>
<library>ole32</library>
<file>shelllink.c</file>
<file>shellpath.c</file>
<file>shlexec.c</file>
<file>shlfileop.c</file>
<file>shlfolder.c</file>
<file>string.c</file>
<file>testlist.c</file>
<include base="shell32_winetest">.</include>
<define name="__USE_W32API" />
<define name="_WIN32_IE">0x600</define>
<define name="_WIN32_WINNT">0x501</define>
<define name="WINVER">0x501</define>
<library>wine</library>
<library>shell32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>shlwapi</library>
<library>user32</library>
<library>gdi32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>uuid</library>
<library>ntdll</library>
<file>generated.c</file>
<file>shelllink.c</file>
<file>shellpath.c</file>
<file>shlexec.c</file>
<file>shlfileop.c</file>
<file>shlfolder.c</file>
<file>string.c</file>
<file>systray.c</file>
<file>testlist.c</file>
</module>

View file

@ -15,7 +15,7 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

View file

@ -15,61 +15,65 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* This is a test program for the SHGet{Special}Folder{Path|Location} functions
* of shell32, that get either a filesytem path or a LPITEMIDLIST (shell
* namespace) path for a given folder (CSIDL value).
*
*/
#define _WIN32_IE 0x0400
#define COBJMACROS
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "basetyps.h"
#include <windows.h>
#include "shlguid.h"
//#include "wine/shobjidl.h"
#include "shobjidl.h"
#include "shlobj.h"
#include "wine/test.h"
#include "shell32_test.h"
extern BOOL WINAPI ILIsEqual(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
extern HRESULT WINAPI SHILCreateFromPath(LPCWSTR path, LPITEMIDLIST * ppidl, DWORD * attributes);
extern void WINAPI ILFree(LPITEMIDLIST pidl);
typedef void (WINAPI *fnILFree)(LPITEMIDLIST);
typedef BOOL (WINAPI *fnILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
typedef HRESULT (WINAPI *fnSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*);
static fnILFree pILFree;
static fnILIsEqual pILIsEqual;
static fnSHILCreateFromPath pSHILCreateFromPath;
static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD);
static const GUID _IID_IShellLinkDataList = {
0x45e2b4ae, 0xb1c3, 0x11d0,
{ 0xb9, 0x2f, 0x00, 0xa0, 0xc9, 0x03, 0x12, 0xe1 }
};
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 };
#if 0 // FIXME: needed to build. Please update shell32 winetest.
const GUID IID_IPersistFile = { 0x0000010b, 0x0000, 0x0000, { 0xc0,0x00, 0x00,0x00,0x00,0x00,0x00,0x46 } };
#endif
/* 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 (WINAPI *pSHSimpleIDListFromPathAW)(LPCVOID);
static LPITEMIDLIST path_to_pidl(const char* path)
{
LPITEMIDLIST pidl;
if (!pSHSimpleIDListFromPathA)
if (!pSHSimpleIDListFromPathAW)
{
HMODULE hdll=LoadLibraryA("shell32.dll");
pSHSimpleIDListFromPathA=(void*)GetProcAddress(hdll, (char*)162);
if (!pSHSimpleIDListFromPathA)
trace("SHSimpleIDListFromPathA not found in shell32.dll\n");
HMODULE hdll=GetModuleHandleA("shell32.dll");
pSHSimpleIDListFromPathAW=(void*)GetProcAddress(hdll, (char*)162);
if (!pSHSimpleIDListFromPathAW)
trace("SHSimpleIDListFromPathAW not found in shell32.dll\n");
}
pidl=NULL;
if (pSHSimpleIDListFromPathA)
pidl=pSHSimpleIDListFromPathA(path);
/* pSHSimpleIDListFromPathAW maps to A on non NT platforms */
if (pSHSimpleIDListFromPathAW && (GetVersion() & 0x80000000))
pidl=pSHSimpleIDListFromPathAW(path);
if (!pidl)
{
@ -81,9 +85,9 @@ static LPITEMIDLIST path_to_pidl(const char* path)
pathW=HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len);
r=SHILCreateFromPath(pathW, &pidl, NULL);
r=pSHILCreateFromPath(pathW, &pidl, NULL);
todo_wine {
ok(SUCCEEDED(r), "SHILCreateFromPath failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "SHILCreateFromPath failed (0x%08x)\n", r);
}
HeapFree(GetProcessHeap(), 0, pathW);
}
@ -108,71 +112,72 @@ static void test_get_set(void)
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkA, (LPVOID*)&sl);
ok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
ok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\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(SUCCEEDED(r), "GetDescription failed (0x%08x)\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);
ok(SUCCEEDED(r), "SetDescription failed (0x%08x)\n", r);
strcpy(buffer,"garbage");
r = IShellLinkA_GetDescription(sl, buffer, sizeof(buffer));
ok(SUCCEEDED(r), "GetDescription failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetDescription failed (0x%08x)\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(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08x)\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);
ok(SUCCEEDED(r), "SetWorkingDirectory failed (0x%08x)\n", r);
strcpy(buffer,"garbage");
r = IShellLinkA_GetWorkingDirectory(sl, buffer, sizeof(buffer));
ok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08x)\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(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
r = IShellLinkA_SetPath(sl, "");
ok(r==S_OK, "SetPath failed (0x%08lx)\n", r);
ok(r==S_OK, "SetPath failed (0x%08x)\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(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
/* Win98 returns S_FALSE, but WinXP returns S_OK */
str="c:\\nonexistent\\file";
r = IShellLinkA_SetPath(sl, str);
ok(r==S_FALSE, "SetPath failed (0x%08lx)\n", r);
ok(r==S_FALSE || r==S_OK, "SetPath failed (0x%08x)\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(SUCCEEDED(r), "GetPath failed (0x%08x)\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);
ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%d)\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);
ok(SUCCEEDED(r), "GetIDList failed (0x%08x)\n", r);
if (SUCCEEDED(r))
{
strcpy(buffer,"garbage");
@ -192,50 +197,73 @@ static void test_get_set(void)
if (pidl)
{
r = IShellLinkA_SetIDList(sl, pidl);
ok(SUCCEEDED(r), "SetIDList failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "SetIDList failed (0x%08x)\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),
ok(SUCCEEDED(r), "GetIDList failed (0x%08x)\n", r);
ok(tmp_pidl && pILIsEqual(pidl, tmp_pidl),
"GetIDList returned an incorrect pidl\n");
/* tmp_pidl is owned by IShellLink so we don't free it */
ILFree(pidl);
pILFree(pidl);
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(SUCCEEDED(r), "GetPath failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
ok(lstrcmpi(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
}
/* test path with quotes (Win98 IShellLinkA_SetPath returns S_FALSE, WinXP returns S_OK) */
r = IShellLinkA_SetPath(sl, "\"c:\\nonexistent\\file\"");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
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"), "case doesn't match\n");
r = IShellLinkA_SetPath(sl, "\"c:\\foo");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
r = IShellLinkA_SetPath(sl, "c:\\foo\"");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\"");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
r = IShellLinkA_SetPath(sl, "\"\"c:\\foo\"\"");
ok(r==S_FALSE || r == S_OK, "SetPath failed (0x%08x)\n", r);
/* 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(SUCCEEDED(r), "GetArguments failed (0x%08x)\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);
ok(SUCCEEDED(r), "SetArguments failed (0x%08x)\n", r);
strcpy(buffer,"garbage");
r = IShellLinkA_GetArguments(sl, buffer, sizeof(buffer));
ok(SUCCEEDED(r), "GetArguments failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetArguments failed (0x%08x)\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(SUCCEEDED(r), "GetShowCmd failed (0x%08x)\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);
ok(SUCCEEDED(r), "SetShowCmd failed (0x%08x)\n", r);
i=0xdeadbeef;
r = IShellLinkA_GetShowCmd(sl, &i);
ok(SUCCEEDED(r), "GetShowCmd failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetShowCmd failed (0x%08x)\n", r);
ok(i==SW_SHOWMAXIMIZED, "GetShowCmd returned %d'\n", i);
/* Test Getting / Setting the icon */
@ -243,33 +271,33 @@ static void test_get_set(void)
strcpy(buffer,"garbage");
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
todo_wine {
ok(SUCCEEDED(r), "GetIconLocation failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetIconLocation failed (0x%08x)\n", r);
}
ok(*buffer=='\0', "GetIconLocation returned '%s'\n", buffer);
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);
ok(SUCCEEDED(r), "SetIconLocation failed (0x%08x)\n", r);
i=0xdeadbeef;
r = IShellLinkA_GetIconLocation(sl, buffer, sizeof(buffer), &i);
ok(SUCCEEDED(r), "GetIconLocation failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetIconLocation failed (0x%08x)\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(SUCCEEDED(r), "GetHotkey failed (0x%08x)\n", r);
ok(w==0, "GetHotkey returned %d\n", w);
r = IShellLinkA_SetHotkey(sl, 0x5678);
ok(SUCCEEDED(r), "SetHotkey failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "SetHotkey failed (0x%08x)\n", r);
w=0xbeef;
r = IShellLinkA_GetHotkey(sl, &w);
ok(SUCCEEDED(r), "GetHotkey failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "GetHotkey failed (0x%08x)\n", r);
ok(w==0x5678, "GetHotkey returned %d'\n", w);
IShellLinkA_Release(sl);
@ -281,7 +309,13 @@ static void test_get_set(void)
*/
#define lok ok_(__FILE__, line)
#define check_lnk(a,b) check_lnk_(__LINE__, (a), (b))
#define lok_todo_4(todo_flag,a,b,c,d) \
if ((todo & todo_flag) == 0) lok((a), (b), (c), (d)); \
else todo_wine lok((a), (b), (c), (d));
#define lok_todo_2(todo_flag,a,b) \
if ((todo & todo_flag) == 0) lok((a), (b)); \
else todo_wine lok((a), (b));
#define check_lnk(a,b,c) check_lnk_(__LINE__, (a), (b), (c))
void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
{
@ -291,65 +325,65 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkA, (LPVOID*)&sl);
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\n", r);
if (!SUCCEEDED(r))
return;
if (desc->description)
{
r = IShellLinkA_SetDescription(sl, desc->description);
lok(SUCCEEDED(r), "SetDescription failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetDescription failed (0x%08x)\n", r);
}
if (desc->workdir)
{
r = IShellLinkA_SetWorkingDirectory(sl, desc->workdir);
lok(SUCCEEDED(r), "SetWorkingDirectory failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetWorkingDirectory failed (0x%08x)\n", r);
}
if (desc->path)
{
r = IShellLinkA_SetPath(sl, desc->path);
lok(SUCCEEDED(r), "SetPath failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetPath failed (0x%08x)\n", r);
}
if (desc->pidl)
{
r = IShellLinkA_SetIDList(sl, desc->pidl);
lok(SUCCEEDED(r), "SetIDList failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetIDList failed (0x%08x)\n", r);
}
if (desc->arguments)
{
r = IShellLinkA_SetArguments(sl, desc->arguments);
lok(SUCCEEDED(r), "SetArguments failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetArguments failed (0x%08x)\n", r);
}
if (desc->showcmd)
{
r = IShellLinkA_SetShowCmd(sl, desc->showcmd);
lok(SUCCEEDED(r), "SetShowCmd failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetShowCmd failed (0x%08x)\n", r);
}
if (desc->icon)
{
r = IShellLinkA_SetIconLocation(sl, desc->icon, desc->icon_id);
lok(SUCCEEDED(r), "SetIconLocation failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetIconLocation failed (0x%08x)\n", r);
}
if (desc->hotkey)
{
r = IShellLinkA_SetHotkey(sl, desc->hotkey);
lok(SUCCEEDED(r), "SetHotkey failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "SetHotkey failed (0x%08x)\n", r);
}
r = IShellLinkW_QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf);
lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08lx)\n", r);
lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08x)\n", r);
if (SUCCEEDED(r))
{
r = IPersistFile_Save(pf, path, TRUE);
if (save_fails)
{
todo_wine {
lok(SUCCEEDED(r), "save failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "save failed (0x%08x)\n", r);
}
}
else
{
lok(SUCCEEDED(r), "save failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "save failed (0x%08x)\n", r);
}
IPersistFile_Release(pf);
}
@ -357,7 +391,7 @@ void create_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int save_fails)
IShellLinkA_Release(sl);
}
static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc, int todo)
{
HRESULT r;
IShellLinkA *sl;
@ -366,12 +400,12 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkA, (LPVOID*)&sl);
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08lx)\n", r);
lok(SUCCEEDED(r), "no IID_IShellLinkA (0x%08x)\n", r);
if (!SUCCEEDED(r))
return;
r = IShellLinkA_QueryInterface(sl, &IID_IPersistFile, (LPVOID*)&pf);
lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08lx)\n", r);
lok(SUCCEEDED(r), "no IID_IPersistFile (0x%08x)\n", r);
if (!SUCCEEDED(r))
{
IShellLinkA_Release(sl);
@ -379,7 +413,7 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
}
r = IPersistFile_Load(pf, path, STGM_READ);
lok(SUCCEEDED(r), "load failed (0x%08lx)\n", r);
lok(SUCCEEDED(r), "load failed (0x%08x)\n", r);
IPersistFile_Release(pf);
if (!SUCCEEDED(r))
{
@ -391,8 +425,8 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
{
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,
lok(SUCCEEDED(r), "GetDescription failed (0x%08x)\n", r);
lok_todo_4(0x1, lstrcmp(buffer, desc->description)==0,
"GetDescription returned '%s' instead of '%s'\n",
buffer, desc->description);
}
@ -400,8 +434,8 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
{
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,
lok(SUCCEEDED(r), "GetWorkingDirectory failed (0x%08x)\n", r);
lok_todo_4(0x2, lstrcmpi(buffer, desc->workdir)==0,
"GetWorkingDirectory returned '%s' instead of '%s'\n",
buffer, desc->workdir);
}
@ -409,8 +443,8 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
{
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,
lok(SUCCEEDED(r), "GetPath failed (0x%08x)\n", r);
lok_todo_4(0x4, lstrcmpi(buffer, desc->path)==0,
"GetPath returned '%s' instead of '%s'\n",
buffer, desc->path);
}
@ -418,16 +452,16 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
{
LPITEMIDLIST pidl=NULL;
r = IShellLinkA_GetIDList(sl, &pidl);
lok(SUCCEEDED(r), "GetIDList failed (0x%08lx)\n", r);
lok(ILIsEqual(pidl, desc->pidl),
lok(SUCCEEDED(r), "GetIDList failed (0x%08x)\n", r);
lok_todo_2(0x8, pILIsEqual(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,
lok(SUCCEEDED(r), "GetShowCmd failed (0x%08x)\n", r);
lok_todo_4(0x10, i==desc->showcmd,
"GetShowCmd returned 0x%0x instead of 0x%0x\n",
i, desc->showcmd);
}
@ -436,11 +470,11 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
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,
lok(SUCCEEDED(r), "GetIconLocation failed (0x%08x)\n", r);
lok_todo_4(0x20, lstrcmpi(buffer, desc->icon)==0,
"GetIconLocation returned '%s' instead of '%s'\n",
buffer, desc->icon);
lok(i==desc->icon_id,
lok_todo_4(0x20, i==desc->icon_id,
"GetIconLocation returned 0x%0x instead of 0x%0x\n",
i, desc->icon_id);
}
@ -448,8 +482,8 @@ static void check_lnk_(int line, const WCHAR* path, lnk_desc_t* desc)
{
WORD i=0xbeef;
r = IShellLinkA_GetHotkey(sl, &i);
lok(SUCCEEDED(r), "GetHotkey failed (0x%08lx)\n", r);
lok(i==desc->hotkey,
lok(SUCCEEDED(r), "GetHotkey failed (0x%08x)\n", r);
lok_todo_4(0x40, i==desc->hotkey,
"GetHotkey returned 0x%04x instead of 0x%04x\n",
i, desc->hotkey);
}
@ -462,7 +496,9 @@ static void test_load_save(void)
lnk_desc_t desc;
char mypath[MAX_PATH];
char mydir[MAX_PATH];
char realpath[MAX_PATH];
char* p;
HANDLE hf;
DWORD r;
/* Save an empty .lnk file */
@ -475,8 +511,7 @@ static void test_load_save(void)
desc.path="";
desc.arguments="";
desc.icon="";
check_lnk(lnkfile, &desc);
check_lnk(lnkfile, &desc, 0x0);
/* Point a .lnk file to nonexistent files */
desc.description="";
@ -489,16 +524,15 @@ static void test_load_save(void)
desc.icon_id=1234;
desc.hotkey=0;
create_lnk(lnkfile, &desc, 0);
check_lnk(lnkfile, &desc);
check_lnk(lnkfile, &desc, 0x0);
r=GetModuleFileName(NULL, mypath, sizeof(mypath));
ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%ld)\n", r);
ok(r>=0 && r<sizeof(mypath), "GetModuleFileName failed (%d)\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;
@ -510,7 +544,54 @@ static void test_load_save(void)
desc.icon_id=0;
desc.hotkey=0x1234;
create_lnk(lnkfile, &desc, 0);
check_lnk(lnkfile, &desc);
check_lnk(lnkfile, &desc, 0x0);
/* Overwrite the existing lnk file and test link to a command on the path */
desc.description="command on path";
desc.workdir=mypath;
desc.path="rundll32.exe";
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 that link is created to proper location */
SearchPathA( NULL, desc.path, NULL, MAX_PATH, realpath, NULL);
desc.path=realpath;
check_lnk(lnkfile, &desc, 0x0);
/* Create a temporary non-executable file */
r=GetTempPath(sizeof(mypath), mypath);
ok(r>=0 && r<sizeof(mypath), "GetTempPath failed (%d), err %d\n", r, GetLastError());
r=pGetLongPathNameA(mypath, mydir, sizeof(mydir));
ok(r>=0 && r<sizeof(mydir), "GetLongPathName failed (%d), err %d\n", r, GetLastError());
p=strrchr(mydir, '\\');
if (p)
*p='\0';
strcpy(mypath, mydir);
strcat(mypath, "\\test.txt");
hf = CreateFile(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 */
desc.description="non-executable file";
desc.workdir=mydir;
desc.path=mypath;
desc.pidl=NULL;
desc.arguments="";
desc.showcmd=SW_SHOWNORMAL;
desc.icon=mypath;
desc.icon_id=0;
desc.hotkey=0x1234;
create_lnk(lnkfile, &desc, 0);
check_lnk(lnkfile, &desc, 0x0);
r = DeleteFileA(mypath);
ok(r, "failed to delete file %s (%d)\n", mypath, GetLastError());
/* FIXME: Also test saving a .lnk pointing to a pidl that cannot be
* represented as a path.
@ -518,20 +599,107 @@ static void test_load_save(void)
/* DeleteFileW is not implemented on Win9x */
r=DeleteFileA("c:\\test.lnk");
ok(r, "failed to delete link (%ld)\n", GetLastError());
ok(r, "failed to delete link (%d)\n", GetLastError());
}
static void test_datalink(void)
{
static const WCHAR lnk[] = {
':',':','{','9','d','b','1','1','8','6','f','-','4','0','d','f','-','1',
'1','d','1','-','a','a','8','c','-','0','0','c','0','4','f','b','6','7',
'8','6','3','}',':','{','0','0','0','1','0','4','0','9','-','7','8','E',
'1','-','1','1','D','2','-','B','6','0','F','-','0','0','6','0','9','7',
'C','9','9','8','E','7','}',':',':','{','9','d','b','1','1','8','6','e',
'-','4','0','d','f','-','1','1','d','1','-','a','a','8','c','-','0','0',
'c','0','4','f','b','6','7','8','6','3','}',':','2','6',',','!','!','g',
'x','s','f','(','N','g',']','q','F','`','H','{','L','s','A','C','C','E',
'S','S','F','i','l','e','s','>','p','l','T',']','j','I','{','j','f','(',
'=','1','&','L','[','-','8','1','-',']',':',':',0 };
static const WCHAR comp[] = {
'2','6',',','!','!','g','x','s','f','(','N','g',']','q','F','`','H','{',
'L','s','A','C','C','E','S','S','F','i','l','e','s','>','p','l','T',']',
'j','I','{','j','f','(','=','1','&','L','[','-','8','1','-',']',0 };
IShellLinkDataList *dl = NULL;
IShellLinkW *sl = NULL;
HRESULT r;
DWORD flags = 0;
EXP_DARWIN_LINK *dar;
r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkW, (LPVOID*)&sl );
ok( r == S_OK || r == E_NOINTERFACE, "CoCreateInstance failed (0x%08x)\n", r);
if (!sl)
{
skip("no shelllink\n");
return;
}
r = IShellLinkW_QueryInterface( sl, &_IID_IShellLinkDataList, (LPVOID*) &dl );
ok(r == S_OK, "IShellLinkW_QueryInterface failed (0x%08x)\n", r);
if (!dl)
{
skip("no datalink interface\n");
return;
}
flags = 0;
r = dl->lpVtbl->GetFlags( dl, &flags );
ok( r == S_OK, "GetFlags failed\n");
ok( flags == 0, "GetFlags returned wrong flags\n");
dar = (void*)-1;
r = dl->lpVtbl->CopyDataBlock( dl, EXP_DARWIN_ID_SIG, (LPVOID*) &dar );
ok( r == E_FAIL, "CopyDataBlock failed\n");
ok( dar == NULL, "should be null\n");
r = IShellLinkW_SetPath(sl, lnk);
ok(r == S_OK, "set path failed\n");
/*
* The following crashes:
* r = dl->lpVtbl->GetFlags( dl, NULL );
*/
flags = 0;
r = dl->lpVtbl->GetFlags( dl, &flags );
ok( r == S_OK, "GetFlags failed\n");
ok( flags == (SLDF_HAS_DARWINID|SLDF_HAS_LOGO3ID),
"GetFlags returned wrong flags\n");
dar = NULL;
r = dl->lpVtbl->CopyDataBlock( dl, EXP_DARWIN_ID_SIG, (LPVOID*) &dar );
ok( r == S_OK, "CopyDataBlock failed\n");
ok( dar && ((DATABLOCK_HEADER*)dar)->dwSignature == EXP_DARWIN_ID_SIG, "signature wrong\n");
ok( dar && 0==lstrcmpW(dar->szwDarwinID, comp ), "signature wrong\n");
LocalFree( dar );
IUnknown_Release( dl );
IShellLinkW_Release( sl );
}
START_TEST(shelllink)
{
HRESULT r;
HMODULE hmod = GetModuleHandleA("shell32.dll");
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
pILFree = (fnILFree) GetProcAddress(hmod, (LPSTR)155);
pILIsEqual = (fnILIsEqual) GetProcAddress(hmod, (LPSTR)21);
pSHILCreateFromPath = (fnSHILCreateFromPath) GetProcAddress(hmod, (LPSTR)28);
pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA");
r = CoInitialize(NULL);
ok(SUCCEEDED(r), "CoInitialize failed (0x%08lx)\n", r);
ok(SUCCEEDED(r), "CoInitialize failed (0x%08x)\n", r);
if (!SUCCEEDED(r))
return;
test_get_set();
test_load_save();
test_datalink();
CoUninitialize();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -15,14 +15,12 @@
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define WINE_NOWINSOCK
#include "windef.h"
#include "winbase.h"
@ -67,21 +65,21 @@ static void test_StrRetToStringNW(void)
trace("StrRetToStringNAW is Unicode\n");
strret.uType = STRRET_WSTR;
strret.u.pOleStr = CoDupStrW("Test");
U(strret).pOleStr = CoDupStrW("Test");
memset(buff, 0xff, sizeof(buff));
ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
ok(ret == TRUE && !strcmpW(buff, szTestW),
"STRRET_WSTR: dup failed, ret=%d\n", ret);
strret.uType = STRRET_CSTR;
lstrcpyA(strret.u.cStr, "Test");
lstrcpyA(U(strret).cStr, "Test");
memset(buff, 0xff, sizeof(buff));
ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
ok(ret == TRUE && !strcmpW(buff, szTestW),
"STRRET_CSTR: dup failed, ret=%d\n", ret);
strret.uType = STRRET_OFFSET;
strret.u.uOffset = 1;
U(strret).uOffset = 1;
strcpy((char*)&iidl, " Test");
memset(buff, 0xff, sizeof(buff));
ret = pStrRetToStrNAW(buff, sizeof(buff)/sizeof(WCHAR), &strret, iidl);
@ -92,7 +90,7 @@ static void test_StrRetToStringNW(void)
#if 0
/* Invalid dest - should return FALSE, except NT4 does not, so we don't check. */
strret.uType = STRRET_WSTR;
strret.u.pOleStr = CoDupStrW("Test");
U(strret).pOleStr = CoDupStrW("Test");
pStrRetToStrNAW(NULL, sizeof(buff)/sizeof(WCHAR), &strret, NULL);
trace("NULL dest: ret=%d\n", ret);
#endif
@ -102,9 +100,7 @@ START_TEST(string)
{
CoInitialize(0);
hShell32 = LoadLibraryA("shell32.dll");
if (!hShell32)
return;
hShell32 = GetModuleHandleA("shell32.dll");
pStrRetToStrNAW = (void*)GetProcAddress(hShell32, (LPSTR)96);
if (pStrRetToStrNAW)

View file

@ -0,0 +1,106 @@
/* Unit tests for systray
*
* Copyright 2007 Mikolaj Zalewski
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define _WIN32_IE 0x600
#include <assert.h>
#include <stdarg.h>
#include <windows.h>
#include "wine/test.h"
static HWND hMainWnd;
void test_cbsize()
{
NOTIFYICONDATAW nidW;
NOTIFYICONDATAA nidA;
ZeroMemory(&nidW, sizeof(nidW));
nidW.cbSize = NOTIFYICONDATAW_V1_SIZE;
nidW.hWnd = hMainWnd;
nidW.uID = 1;
nidW.uFlags = NIF_ICON|NIF_MESSAGE;
nidW.hIcon = LoadIcon(NULL, IDI_APPLICATION);
nidW.uCallbackMessage = WM_USER+17;
ok(Shell_NotifyIconW(NIM_ADD, &nidW), "NIM_ADD failed!\n");
/* using an invalid cbSize does work */
nidW.cbSize = 3;
nidW.hWnd = hMainWnd;
nidW.uID = 1;
ok(Shell_NotifyIconW(NIM_DELETE, &nidW), "NIM_DELETE failed!\n");
/* as icon doesn't exist anymore - now there will be an error */
nidW.cbSize = sizeof(nidW);
/* wine currently doesn't return error code put prints an ERR(...) */
todo_wine ok(!Shell_NotifyIconW(NIM_DELETE, &nidW), "The icon was not deleted\n");
/* same for Shell_NotifyIconA */
ZeroMemory(&nidA, sizeof(nidA));
nidA.cbSize = NOTIFYICONDATAA_V1_SIZE;
nidA.hWnd = hMainWnd;
nidA.uID = 1;
nidA.uFlags = NIF_ICON|NIF_MESSAGE;
nidA.hIcon = LoadIcon(NULL, IDI_APPLICATION);
nidA.uCallbackMessage = WM_USER+17;
ok(Shell_NotifyIconA(NIM_ADD, &nidA), "NIM_ADD failed!\n");
/* using an invalid cbSize does work */
nidA.cbSize = 3;
nidA.hWnd = hMainWnd;
nidA.uID = 1;
ok(Shell_NotifyIconA(NIM_DELETE, &nidA), "NIM_DELETE failed!\n");
/* as icon doesn't exist anymore - now there will be an error */
nidA.cbSize = sizeof(nidA);
/* wine currently doesn't return error code put prints an ERR(...) */
todo_wine ok(!Shell_NotifyIconA(NIM_DELETE, &nidA), "The icon was not deleted\n");
}
START_TEST(systray)
{
WNDCLASSA wc;
MSG msg;
RECT rc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandleA(NULL);
wc.hIcon = NULL;
wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_IBEAM));
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = "MyTestWnd";
wc.lpfnWndProc = DefWindowProc;
RegisterClassA(&wc);
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
GetClientRect(hMainWnd, &rc);
ShowWindow(hMainWnd, SW_SHOW);
test_cbsize();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
DestroyWindow(hMainWnd);
}

View file

@ -13,15 +13,17 @@ extern void func_shlexec(void);
extern void func_shlfileop(void);
extern void func_shlfolder(void);
extern void func_string(void);
extern void func_systray(void);
const struct test winetest_testlist[] =
{
// { "generated", func_generated },
{ "generated", func_generated },
{ "shelllink", func_shelllink },
{ "shellpath", func_shellpath },
{ "shlexec", func_shlexec },
{ "shlfileop", func_shlfileop },
{ "shlfolder", func_shlfolder },
{ "string", func_string },
{ "systray", func_systray },
{ 0, 0 }
};