[SHELL32_WINETEST] Sync with Wine Staging 3.3. CORE-14434

This commit is contained in:
Amine Khaldi 2018-04-03 13:47:46 +01:00
parent cdd41ac6c4
commit 0be033fe1d
22 changed files with 1865 additions and 1487 deletions

View file

@ -32,7 +32,7 @@ add_executable(shell32_winetest
target_link_libraries(shell32_winetest uuid) target_link_libraries(shell32_winetest uuid)
set_module_type(shell32_winetest win32cui) set_module_type(shell32_winetest win32cui)
add_importlibs(shell32_winetest shell32 ole32 oleaut32 user32 gdi32 advapi32 msvcrt kernel32) add_importlibs(shell32_winetest shell32 shlwapi ole32 oleaut32 user32 gdi32 advapi32 msvcrt kernel32)
if(MSVC) if(MSVC)
add_importlibs(shell32_winetest ntdll) add_importlibs(shell32_winetest ntdll)

View file

@ -17,7 +17,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdarg.h>
#include <windows.h>
#include "shellapi.h"
#include "wine/test.h"
#define MSG_APPBAR WM_APP #define MSG_APPBAR WM_APP

View file

@ -17,9 +17,17 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define COBJMACROS
#include <stdarg.h>
#include "shlwapi.h"
#include "shlguid.h"
#include "shobjidl.h"
#include "wine/heap.h"
#include "wine/test.h"
#include <shobjidl.h>
static void test_IQueryAssociations_QueryInterface(void) static void test_IQueryAssociations_QueryInterface(void)
{ {
@ -114,7 +122,7 @@ static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCW
return; return;
} }
buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); buffer = heap_alloc(len * sizeof(WCHAR));
ok_(__FILE__, line)(buffer != NULL, "out of memory\n"); ok_(__FILE__, line)(buffer != NULL, "out of memory\n");
hr = IQueryAssociations_GetString(assoc, 0, str, NULL, buffer, &len); hr = IQueryAssociations_GetString(assoc, 0, str, NULL, buffer, &len);
ok_(__FILE__, line)(hr == S_OK, "GetString returned 0x%x, expected S_OK\n", hr); ok_(__FILE__, line)(hr == S_OK, "GetString returned 0x%x, expected S_OK\n", hr);
@ -126,7 +134,7 @@ static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCW
} }
IQueryAssociations_Release(assoc); IQueryAssociations_Release(assoc);
HeapFree(GetProcessHeap(), 0, buffer); heap_free(buffer);
} }
static void test_IQueryAssociations_GetString(void) static void test_IQueryAssociations_GetString(void)

View file

@ -18,7 +18,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define COBJMACROS
#include <stdarg.h>
#include "windows.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "initguid.h"
#include "shldisp.h"
#include "wine/heap.h"
#include "wine/test.h"
static HWND hMainWnd, hEdit; static HWND hMainWnd, hEdit;
static HINSTANCE hinst; static HINSTANCE hinst;
@ -216,6 +227,171 @@ static void createMainWnd(void)
CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0); CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0);
} }
struct string_enumerator
{
IEnumString IEnumString_iface;
LONG ref;
WCHAR **data;
int data_len;
int cur;
};
static struct string_enumerator *impl_from_IEnumString(IEnumString *iface)
{
return CONTAINING_RECORD(iface, struct string_enumerator, IEnumString_iface);
}
static HRESULT WINAPI string_enumerator_QueryInterface(IEnumString *iface, REFIID riid, void **ppv)
{
if (IsEqualGUID(riid, &IID_IEnumString) || IsEqualGUID(riid, &IID_IUnknown))
{
IUnknown_AddRef(iface);
*ppv = iface;
return S_OK;
}
*ppv = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI string_enumerator_AddRef(IEnumString *iface)
{
struct string_enumerator *this = impl_from_IEnumString(iface);
ULONG ref = InterlockedIncrement(&this->ref);
return ref;
}
static ULONG WINAPI string_enumerator_Release(IEnumString *iface)
{
struct string_enumerator *this = impl_from_IEnumString(iface);
ULONG ref = InterlockedDecrement(&this->ref);
if (!ref)
heap_free(this);
return ref;
}
static HRESULT WINAPI string_enumerator_Next(IEnumString *iface, ULONG num, LPOLESTR *strings, ULONG *num_returned)
{
struct string_enumerator *this = impl_from_IEnumString(iface);
int i, len;
*num_returned = 0;
for (i = 0; i < num; i++)
{
if (this->cur >= this->data_len)
return S_FALSE;
len = lstrlenW(this->data[this->cur]) + 1;
strings[i] = CoTaskMemAlloc(len * sizeof(WCHAR));
memcpy(strings[i], this->data[this->cur], len * sizeof(WCHAR));
(*num_returned)++;
this->cur++;
}
return S_OK;
}
static HRESULT WINAPI string_enumerator_Reset(IEnumString *iface)
{
struct string_enumerator *this = impl_from_IEnumString(iface);
this->cur = 0;
return S_OK;
}
static HRESULT WINAPI string_enumerator_Skip(IEnumString *iface, ULONG num)
{
struct string_enumerator *this = impl_from_IEnumString(iface);
this->cur += num;
return S_OK;
}
static HRESULT WINAPI string_enumerator_Clone(IEnumString *iface, IEnumString **out)
{
*out = NULL;
return E_NOTIMPL;
}
static IEnumStringVtbl string_enumerator_vtlb =
{
string_enumerator_QueryInterface,
string_enumerator_AddRef,
string_enumerator_Release,
string_enumerator_Next,
string_enumerator_Skip,
string_enumerator_Reset,
string_enumerator_Clone
};
static HRESULT string_enumerator_create(void **ppv, WCHAR **suggestions, int count)
{
struct string_enumerator *object;
object = heap_alloc_zero(sizeof(*object));
object->IEnumString_iface.lpVtbl = &string_enumerator_vtlb;
object->ref = 1;
object->data = suggestions;
object->data_len = count;
object->cur = 0;
*ppv = &object->IEnumString_iface;
return S_OK;
}
static void test_custom_source(void)
{
static WCHAR str_alpha[] = {'t','e','s','t','1',0};
static WCHAR str_alpha2[] = {'t','e','s','t','2',0};
static WCHAR str_beta[] = {'a','u','t','o',' ','c','o','m','p','l','e','t','e',0};
static WCHAR *suggestions[] = { str_alpha, str_alpha2, str_beta };
IUnknown *enumerator;
IAutoComplete2 *autocomplete;
HWND hwnd_edit;
WCHAR buffer[20];
HRESULT hr;
MSG msg;
ShowWindow(hMainWnd, SW_SHOW);
hwnd_edit = CreateWindowA("Edit", "", WS_OVERLAPPED | WS_VISIBLE | WS_CHILD | WS_BORDER, 50, 5, 200, 20, hMainWnd, 0, NULL, 0);
hr = CoCreateInstance(&CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, &IID_IAutoComplete2, (void**)&autocomplete);
ok(hr == S_OK, "CoCreateInstance failed: %x\n", hr);
string_enumerator_create((void**)&enumerator, suggestions, sizeof(suggestions) / sizeof(*suggestions));
hr = IAutoComplete2_SetOptions(autocomplete, ACO_AUTOSUGGEST | ACO_AUTOAPPEND);
ok(hr == S_OK, "IAutoComplete2_SetOptions failed: %x\n", hr);
hr = IAutoComplete2_Init(autocomplete, hwnd_edit, enumerator, NULL, NULL);
ok(hr == S_OK, "IAutoComplete_Init failed: %x\n", hr);
SendMessageW(hwnd_edit, WM_CHAR, 'a', 1);
/* Send a keyup message since wine doesn't handle WM_CHAR yet */
SendMessageW(hwnd_edit, WM_KEYUP, 'u', 1);
Sleep(100);
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
SendMessageW(hwnd_edit, WM_GETTEXT, sizeof(buffer) / sizeof(*buffer), (LPARAM)buffer);
ok(lstrcmpW(str_beta, buffer) == 0, "Expected %s, got %s\n", wine_dbgstr_w(str_beta), wine_dbgstr_w(buffer));
ShowWindow(hMainWnd, SW_HIDE);
DestroyWindow(hwnd_edit);
}
START_TEST(autocomplete) START_TEST(autocomplete)
{ {
HRESULT r; HRESULT r;
@ -237,6 +413,8 @@ START_TEST(autocomplete)
goto cleanup; goto cleanup;
test_killfocus(); test_killfocus();
test_custom_source();
PostQuitMessage(0); PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) { while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg); TranslateMessage(&msg);

View file

@ -19,8 +19,15 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define COBJMACROS
#include <windows.h>
#include <shlobj.h>
#include <shobjidl.h>
#include <string.h>
#include "shellapi.h"
#include "wine/test.h"
#define IDD_MAKENEWFOLDER 0x3746 /* From "../shresdef.h" */ #define IDD_MAKENEWFOLDER 0x3746 /* From "../shresdef.h" */
#define TIMER_WAIT_MS 50 /* Should be long enough for slow systems */ #define TIMER_WAIT_MS 50 /* Should be long enough for slow systems */

View file

@ -18,10 +18,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdio.h>
#include <initguid.h> #define COBJMACROS
#include <mshtml.h> #define CONST_VTABLE
#include "shlobj.h"
#include "shlwapi.h"
#include "wine/heap.h"
#include "wine/test.h"
#include "initguid.h"
#include "mshtml.h"
/********************************************************************** /**********************************************************************
* Some IIDs for test_SetSite. * Some IIDs for test_SetSite.
@ -231,7 +240,7 @@ static ULONG WINAPI IExplorerPaneVisibility_fnRelease(IExplorerPaneVisibility *i
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
if(!ref) if(!ref)
HeapFree(GetProcessHeap(), 0, This); heap_free(This);
return ref; return ref;
} }
@ -277,7 +286,7 @@ static IExplorerPaneVisibilityImpl *create_explorerpanevisibility(void)
{ {
IExplorerPaneVisibilityImpl *epv; IExplorerPaneVisibilityImpl *epv;
epv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IExplorerPaneVisibilityImpl)); epv = heap_alloc_zero(sizeof(*epv));
epv->IExplorerPaneVisibility_iface.lpVtbl = &epvvt; epv->IExplorerPaneVisibility_iface.lpVtbl = &epvvt;
epv->ref = 1; epv->ref = 1;
@ -320,7 +329,7 @@ static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
if(!ref) if(!ref)
HeapFree(GetProcessHeap(), 0, This); heap_free(This);
return ref; return ref;
} }
@ -431,7 +440,7 @@ static ICommDlgBrowser3Impl *create_commdlgbrowser3(void)
{ {
ICommDlgBrowser3Impl *cdb; ICommDlgBrowser3Impl *cdb;
cdb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ICommDlgBrowser3Impl)); cdb = heap_alloc_zero(sizeof(*cdb));
cdb->ICommDlgBrowser3_iface.lpVtbl = &cdbvtbl; cdb->ICommDlgBrowser3_iface.lpVtbl = &cdbvtbl;
cdb->ref = 1; cdb->ref = 1;
@ -489,7 +498,7 @@ static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
LONG ref = InterlockedDecrement(&This->ref); LONG ref = InterlockedDecrement(&This->ref);
if(!ref) if(!ref)
HeapFree(GetProcessHeap(), 0, This); heap_free(This);
return ref; return ref;
} }
@ -540,7 +549,7 @@ static const IServiceProviderVtbl spvtbl =
static IServiceProviderImpl *create_serviceprovider(void) static IServiceProviderImpl *create_serviceprovider(void)
{ {
IServiceProviderImpl *sp = HeapAlloc(GetProcessHeap(), 0, sizeof(IServiceProviderImpl)); IServiceProviderImpl *sp = heap_alloc(sizeof(*sp));
sp->IServiceProvider_iface.lpVtbl = &spvtbl; sp->IServiceProvider_iface.lpVtbl = &spvtbl;
sp->ref = 1; sp->ref = 1;
return sp; return sp;

View file

@ -5,7 +5,24 @@
* Unit tests for data structure packing * Unit tests for data structure packing
*/ */
#include "precomp.h" #ifndef __REACTOS__
#define WINVER 0x0501
#define _WIN32_IE 0x0501
#define _WIN32_WINNT 0x0501
#endif
#define WINE_NOWINSOCK
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "shellapi.h"
#include "winuser.h"
#include "wingdi.h"
#include "shlobj.h"
#include "wine/test.h"
/*********************************************************************** /***********************************************************************
* Compatibility macros * Compatibility macros

View file

@ -20,6 +20,12 @@
#pragma once #pragma once
#include <assert.h>
#include <windows.h>
#include "wine/heap.h"
#include "wine/test.h"
/* undocumented SWP flags - from SDK 3.1 */ /* undocumented SWP flags - from SDK 3.1 */
#define SWP_NOCLIENTSIZE 0x0800 #define SWP_NOCLIENTSIZE 0x0800
#define SWP_NOCLIENTMOVE 0x1000 #define SWP_NOCLIENTMOVE 0x1000
@ -64,16 +70,13 @@ static void add_message(struct msg_sequence **seq, int sequence_index,
if (!msg_seq->sequence) if (!msg_seq->sequence)
{ {
msg_seq->size = 10; msg_seq->size = 10;
msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0, msg_seq->sequence = heap_alloc(msg_seq->size * sizeof (struct message));
msg_seq->size * sizeof (struct message));
} }
if (msg_seq->count == msg_seq->size) if (msg_seq->count == msg_seq->size)
{ {
msg_seq->size *= 2; msg_seq->size *= 2;
msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0, msg_seq->sequence = heap_realloc(msg_seq->sequence, msg_seq->size * sizeof (struct message));
msg_seq->sequence,
msg_seq->size * sizeof (struct message));
} }
assert(msg_seq->sequence); assert(msg_seq->sequence);
@ -90,7 +93,7 @@ static void add_message(struct msg_sequence **seq, int sequence_index,
static void flush_sequence(struct msg_sequence **seg, int sequence_index) static void flush_sequence(struct msg_sequence **seg, int sequence_index)
{ {
struct msg_sequence *msg_seq = seg[sequence_index]; struct msg_sequence *msg_seq = seg[sequence_index];
HeapFree(GetProcessHeap(), 0, msg_seq->sequence); heap_free(msg_seq->sequence);
msg_seq->sequence = NULL; msg_seq->sequence = NULL;
msg_seq->count = msg_seq->size = 0; msg_seq->count = msg_seq->size = 0;
} }
@ -288,5 +291,5 @@ static void init_msg_sequences(struct msg_sequence **seq, int n)
int i; int i;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence)); seq[i] = heap_alloc_zero(sizeof(struct msg_sequence));
} }

View file

@ -1,3 +1,4 @@
#ifndef _SHELL32_WINETEST_PRECOMP_H_ #ifndef _SHELL32_WINETEST_PRECOMP_H_
#define _SHELL32_WINETEST_PRECOMP_H_ #define _SHELL32_WINETEST_PRECOMP_H_
@ -5,23 +6,19 @@
#include <stdio.h> #include <stdio.h>
#define WIN32_NO_STATUS #define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define COBJMACROS #define COBJMACROS
#define CONST_VTABLE #define CONST_VTABLE
#include <windows.h>
#include <wine/heap.h>
#include <wine/test.h> #include <wine/test.h>
#include <winreg.h>
#include <winnls.h>
#include <winuser.h>
#include <wincon.h>
#include <shellapi.h> #include <shellapi.h>
#include <shlwapi.h> #include <shlwapi.h>
#include <shlguid.h> #include <shlguid.h>
#include <shlobj.h> #include <shlobj.h>
#include <ddeml.h>
#include <commoncontrols.h> #include <commoncontrols.h>
#include <reactos/undocshell.h> #include <reactos/undocshell.h>

View file

@ -26,30 +26,15 @@
* Tests for Invalid Characters in Names / Invalid Parameters * Tests for Invalid Characters in Names / Invalid Parameters
*/ */
#include "precomp.h" #include <stdio.h>
#include <wine/test.h>
/* Timeout on DdeClientTransaction Call */ #include <winbase.h>
#define MS_TIMEOUT_VAL 1000 #include "dde.h"
/* # of times to poll for window creation */ #include "ddeml.h"
#define PDDE_POLL_NUM 150 #include "winuser.h"
/* time to sleep between polls */ #include "shlobj.h"
#define PDDE_POLL_TIME 300
/* Call Info */
#define DDE_TEST_MISC 0x00010000
#define DDE_TEST_CREATEGROUP 0x00020000
#define DDE_TEST_DELETEGROUP 0x00030000
#define DDE_TEST_SHOWGROUP 0x00040000
#define DDE_TEST_ADDITEM 0x00050000
#define DDE_TEST_DELETEITEM 0x00060000
#define DDE_TEST_COMPOUND 0x00070000
#define DDE_TEST_CALLMASK 0x00ff0000
#define DDE_TEST_NUMMASK 0x0000ffff
static HRESULT (WINAPI *pSHGetLocalizedName)(LPCWSTR, LPWSTR, UINT, int *); static HRESULT (WINAPI *pSHGetLocalizedName)(LPCWSTR, LPWSTR, UINT, int *);
static BOOL (WINAPI *pSHGetSpecialFolderPathA)(HWND, LPSTR, int, BOOL);
static BOOL (WINAPI *pReadCabinetState)(CABINETSTATE *, int);
static void init_function_pointers(void) static void init_function_pointers(void)
{ {
@ -57,10 +42,6 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("shell32.dll"); hmod = GetModuleHandleA("shell32.dll");
pSHGetLocalizedName = (void*)GetProcAddress(hmod, "SHGetLocalizedName"); pSHGetLocalizedName = (void*)GetProcAddress(hmod, "SHGetLocalizedName");
pSHGetSpecialFolderPathA = (void*)GetProcAddress(hmod, "SHGetSpecialFolderPathA");
pReadCabinetState = (void*)GetProcAddress(hmod, "ReadCabinetState");
if (!pReadCabinetState)
pReadCabinetState = (void*)GetProcAddress(hmod, (LPSTR)651);
} }
static BOOL use_common(void) static BOOL use_common(void)
@ -101,63 +82,20 @@ static BOOL full_title(void)
CABINETSTATE cs; CABINETSTATE cs;
memset(&cs, 0, sizeof(cs)); memset(&cs, 0, sizeof(cs));
if (pReadCabinetState) ReadCabinetState(&cs, sizeof(cs));
{
pReadCabinetState(&cs, sizeof(cs));
}
else
{
HKEY key;
DWORD size;
win_skip("ReadCabinetState is not available, reading registry directly\n");
RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\CabinetState", &key);
size = sizeof(cs);
RegQueryValueExA(key, "Settings", NULL, NULL, (LPBYTE)&cs, &size);
RegCloseKey(key);
}
return (cs.fFullPathTitle == -1); return (cs.fFullPathTitle == -1);
} }
static char ProgramsDir[MAX_PATH]; static char ProgramsDir[MAX_PATH];
static char Group1Title[MAX_PATH] = "Group1";
static char Group2Title[MAX_PATH] = "Group2";
static char Group3Title[MAX_PATH] = "Group3";
static char StartupTitle[MAX_PATH] = "Startup";
static void init_strings(void) static void init_strings(void)
{ {
char startup[MAX_PATH];
char commonprograms[MAX_PATH]; char commonprograms[MAX_PATH];
char programs[MAX_PATH]; char programs[MAX_PATH];
if (pSHGetSpecialFolderPathA) SHGetSpecialFolderPathA(NULL, programs, CSIDL_PROGRAMS, FALSE);
{ SHGetSpecialFolderPathA(NULL, commonprograms, CSIDL_COMMON_PROGRAMS, FALSE);
pSHGetSpecialFolderPathA(NULL, programs, CSIDL_PROGRAMS, FALSE);
pSHGetSpecialFolderPathA(NULL, commonprograms, CSIDL_COMMON_PROGRAMS, FALSE);
pSHGetSpecialFolderPathA(NULL, startup, CSIDL_STARTUP, FALSE);
}
else
{
HKEY key;
DWORD size;
/* Older Win9x and NT4 */
RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key);
size = sizeof(programs);
RegQueryValueExA(key, "Programs", NULL, NULL, (LPBYTE)&programs, &size);
size = sizeof(startup);
RegQueryValueExA(key, "Startup", NULL, NULL, (LPBYTE)&startup, &size);
RegCloseKey(key);
RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", &key);
size = sizeof(commonprograms);
RegQueryValueExA(key, "Common Programs", NULL, NULL, (LPBYTE)&commonprograms, &size);
RegCloseKey(key);
}
/* ProgramsDir on Vista+ is always the users one (CSIDL_PROGRAMS). Before Vista /* ProgramsDir on Vista+ is always the users one (CSIDL_PROGRAMS). Before Vista
* it depends on whether the user is an administrator (CSIDL_COMMON_PROGRAMS) or * it depends on whether the user is an administrator (CSIDL_COMMON_PROGRAMS) or
@ -167,55 +105,6 @@ static void init_strings(void)
lstrcpyA(ProgramsDir, commonprograms); lstrcpyA(ProgramsDir, commonprograms);
else else
lstrcpyA(ProgramsDir, programs); lstrcpyA(ProgramsDir, programs);
if (full_title())
{
lstrcpyA(Group1Title, ProgramsDir);
lstrcatA(Group1Title, "\\Group1");
lstrcpyA(Group2Title, ProgramsDir);
lstrcatA(Group2Title, "\\Group2");
lstrcpyA(Group3Title, ProgramsDir);
lstrcatA(Group3Title, "\\Group3");
lstrcpyA(StartupTitle, startup);
}
else
{
/* Vista has the nice habit of displaying the full path in English
* and the short one localized. CSIDL_STARTUP on Vista gives us the
* English version so we have to 'translate' this one.
*
* MSDN claims it should be used for files not folders but this one
* suits our purposes just fine.
*/
if (pSHGetLocalizedName)
{
WCHAR startupW[MAX_PATH];
WCHAR module[MAX_PATH];
WCHAR module_expanded[MAX_PATH];
WCHAR localized[MAX_PATH];
HRESULT hr;
int id;
MultiByteToWideChar(CP_ACP, 0, startup, -1, startupW, sizeof(startupW)/sizeof(WCHAR));
hr = pSHGetLocalizedName(startupW, module, MAX_PATH, &id);
todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
/* check to be removed when SHGetLocalizedName is implemented */
if (hr == S_OK)
{
ExpandEnvironmentStringsW(module, module_expanded, MAX_PATH);
LoadStringW(GetModuleHandleW(module_expanded), id, localized, MAX_PATH);
WideCharToMultiByte(CP_ACP, 0, localized, -1, StartupTitle, sizeof(StartupTitle), NULL, NULL);
}
else
lstrcpyA(StartupTitle, (strrchr(startup, '\\') + 1));
}
else
{
lstrcpyA(StartupTitle, (strrchr(startup, '\\') + 1));
}
}
} }
static HDDEDATA CALLBACK DdeCallback(UINT type, UINT format, HCONV hConv, HSZ hsz1, HSZ hsz2, static HDDEDATA CALLBACK DdeCallback(UINT type, UINT format, HCONV hConv, HSZ hsz1, HSZ hsz2,
@ -225,472 +114,305 @@ static HDDEDATA CALLBACK DdeCallback(UINT type, UINT format, HCONV hConv, HSZ hs
return NULL; return NULL;
} }
/* static UINT dde_execute(DWORD instance, HCONV hconv, const char *command_str)
* Encoded String for Error Messages so that inner failures can determine
* what test is failing. Format is: [Code:TestNum]
*/
static const char * GetStringFromTestParams(int testParams)
{ {
int testNum; HDDEDATA command, hdata;
static char testParamString[64]; DWORD result;
const char *callId; UINT ret;
testNum = testParams & DDE_TEST_NUMMASK; command = DdeCreateDataHandle(instance, (BYTE *)command_str, strlen(command_str)+1, 0, 0, 0, 0);
switch (testParams & DDE_TEST_CALLMASK) ok(command != NULL, "DdeCreateDataHandle() failed: %u\n", DdeGetLastError(instance));
{
default: hdata = DdeClientTransaction((BYTE *)command, -1, hconv, 0, 0, XTYP_EXECUTE, 2000, &result);
case DDE_TEST_MISC: ret = DdeGetLastError(instance);
callId = "MISC"; /* PROGMAN always returns 1 on success */
break; ok((UINT_PTR)hdata == !ret, "expected %u, got %p\n", !ret, hdata);
case DDE_TEST_CREATEGROUP:
callId = "C_G"; return ret;
break;
case DDE_TEST_DELETEGROUP:
callId = "D_G";
break;
case DDE_TEST_SHOWGROUP:
callId = "S_G";
break;
case DDE_TEST_ADDITEM:
callId = "A_I";
break;
case DDE_TEST_DELETEITEM:
callId = "D_I";
break;
case DDE_TEST_COMPOUND:
callId = "CPD";
break;
} }
sprintf(testParamString, " [%s:%i]", callId, testNum); static char *dde_request(DWORD instance, HCONV hconv, const char *request_str)
return testParamString; {
static char data[2000];
HDDEDATA hdata;
HSZ item;
DWORD result;
item = DdeCreateStringHandleA(instance, request_str, CP_WINANSI);
ok(item != NULL, "DdeCreateStringHandle() failed: %u\n", DdeGetLastError(instance));
hdata = DdeClientTransaction(NULL, -1, hconv, item, CF_TEXT, XTYP_REQUEST, 2000, &result);
if (hdata == NULL) return NULL;
DdeGetData(hdata, (BYTE *)data, 2000, 0);
return data;
} }
/* Transfer DMLERR's into text readable strings for Error Messages */ static BOOL check_window_exists(const char *name)
#define DMLERR_TO_STR(x) case x: return#x;
static const char * GetStringFromError(UINT err)
{
switch (err)
{
DMLERR_TO_STR(DMLERR_NO_ERROR);
DMLERR_TO_STR(DMLERR_ADVACKTIMEOUT);
DMLERR_TO_STR(DMLERR_BUSY);
DMLERR_TO_STR(DMLERR_DATAACKTIMEOUT);
DMLERR_TO_STR(DMLERR_DLL_NOT_INITIALIZED);
DMLERR_TO_STR(DMLERR_DLL_USAGE);
DMLERR_TO_STR(DMLERR_EXECACKTIMEOUT);
DMLERR_TO_STR(DMLERR_INVALIDPARAMETER);
DMLERR_TO_STR(DMLERR_LOW_MEMORY);
DMLERR_TO_STR(DMLERR_MEMORY_ERROR);
DMLERR_TO_STR(DMLERR_NOTPROCESSED);
DMLERR_TO_STR(DMLERR_NO_CONV_ESTABLISHED);
DMLERR_TO_STR(DMLERR_POKEACKTIMEOUT);
DMLERR_TO_STR(DMLERR_POSTMSG_FAILED);
DMLERR_TO_STR(DMLERR_REENTRANCY);
DMLERR_TO_STR(DMLERR_SERVER_DIED);
DMLERR_TO_STR(DMLERR_SYS_ERROR);
DMLERR_TO_STR(DMLERR_UNADVACKTIMEOUT);
DMLERR_TO_STR(DMLERR_UNFOUND_QUEUE_ID);
default:
return "Unknown DML Error";
}
}
/* Helper Function to Transfer DdeGetLastError into a String */
static const char * GetDdeLastErrorStr(DWORD instance)
{
UINT err = DdeGetLastError(instance);
return GetStringFromError(err);
}
/* Execute a Dde Command and return the error & result */
/* Note: Progman DDE always returns a pointer to 0x00000001 on a successful result */
static void DdeExecuteCommand(DWORD instance, HCONV hConv, const char *strCmd, HDDEDATA *hData, UINT *err, int testParams)
{
HDDEDATA command;
command = DdeCreateDataHandle(instance, (LPBYTE) strCmd, strlen(strCmd)+1, 0, 0L, 0, 0);
ok (command != NULL, "DdeCreateDataHandle Error %s.%s\n",
GetDdeLastErrorStr(instance), GetStringFromTestParams(testParams));
*hData = DdeClientTransaction((void *) command,
-1,
hConv,
0,
0,
XTYP_EXECUTE,
MS_TIMEOUT_VAL,
NULL);
/* hData is technically a pointer, but for Program Manager,
* it is NULL (error) or 1 (success)
* TODO: Check other versions of Windows to verify 1 is returned.
* While it is unlikely that anyone is actually testing that the result is 1
* if all versions of windows return 1, Wine should also.
*/
if (*hData == NULL)
{
*err = DdeGetLastError(instance);
}
else
{
*err = DMLERR_NO_ERROR;
todo_wine
{
ok(*hData == (HDDEDATA) 1, "Expected HDDEDATA Handle == 1, actually %p.%s\n",
*hData, GetStringFromTestParams(testParams));
}
}
DdeFreeDataHandle(command);
}
/*
* Check if Window is onscreen with the appropriate name.
*
* Windows are not created synchronously. So we do not know
* when and if the window will be created/shown on screen.
* This function implements a polling mechanism to determine
* creation.
* A more complicated method would be to use SetWindowsHookEx.
* Since polling worked fine in my testing, no reason to implement
* the other. Comments about other methods of determining when
* window creation happened were not encouraging (not including
* SetWindowsHookEx).
*/
static HWND CheckWindowCreated(const char *winName, BOOL closeWindow, int testParams)
{ {
char title[MAX_PATH];
HWND window = NULL; HWND window = NULL;
int i; int i;
/* Poll for Window Creation */ if (full_title())
for (i = 0; window == NULL && i < PDDE_POLL_NUM; i++)
{ {
Sleep(PDDE_POLL_TIME); strcpy(title, ProgramsDir);
/* Specify the window class name to make sure what we find is really an strcat(title, "\\");
* Explorer window. Explorer used two different window classes so try strcat(title, name);
* both.
*/
window = FindWindowA("ExplorerWClass", winName);
if (!window)
window = FindWindowA("CabinetWClass", winName);
} }
ok (window != NULL, "Window \"%s\" was not created in %i seconds - assumed failure.%s\n", else
winName, PDDE_POLL_NUM*PDDE_POLL_TIME/1000, GetStringFromTestParams(testParams)); strcpy(title, name);
/* Close Window as desired. */ for (i = 0; i < 20; i++)
if (window != NULL && closeWindow) {
Sleep(100);
if ((window = FindWindowA("ExplorerWClass", title)) ||
(window = FindWindowA("CabinetWClass", title)))
{ {
SendMessageA(window, WM_SYSCOMMAND, SC_CLOSE, 0); SendMessageA(window, WM_SYSCOMMAND, SC_CLOSE, 0);
window = NULL; break;
} }
return window;
} }
/* Check for Existence (or non-existence) of a file or group return (window != NULL);
* When testing for existence of a group, groupName is not needed }
*/
static void CheckFileExistsInProgramGroups(const char *nameToCheck, BOOL shouldExist, BOOL isGroup, static BOOL check_exists(const char *name)
const char *groupName, int testParams)
{ {
char path[MAX_PATH]; char path[MAX_PATH];
DWORD attributes;
int len;
lstrcpyA(path, ProgramsDir); strcpy(path, ProgramsDir);
len = strlen(path) + strlen(nameToCheck)+1;
if (groupName != NULL)
{
len += strlen(groupName)+1;
}
ok (len <= MAX_PATH, "Path Too Long.%s\n", GetStringFromTestParams(testParams));
if (len <= MAX_PATH)
{
if (groupName != NULL)
{
strcat(path, "\\"); strcat(path, "\\");
strcat(path, groupName); strcat(path, name);
} return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES;
strcat(path, "\\");
strcat(path, nameToCheck);
attributes = GetFileAttributesA(path);
if (!shouldExist)
{
ok (attributes == INVALID_FILE_ATTRIBUTES , "File exists and shouldn't %s.%s\n",
path, GetStringFromTestParams(testParams));
} else {
if (attributes == INVALID_FILE_ATTRIBUTES)
{
ok (FALSE, "Created File %s doesn't exist.%s\n", path, GetStringFromTestParams(testParams));
} else if (isGroup) {
ok (attributes & FILE_ATTRIBUTE_DIRECTORY, "%s is not a folder (attr=%x).%s\n",
path, attributes, GetStringFromTestParams(testParams));
} else {
ok (attributes & FILE_ATTRIBUTE_ARCHIVE, "Created File %s has wrong attributes (%x).%s\n",
path, attributes, GetStringFromTestParams(testParams));
}
}
}
} }
/* Create Group Test. static void test_parser(DWORD instance, HCONV hConv)
* command and expected_result.
* if expected_result is DMLERR_NO_ERROR, test
* 1. group was created
* 2. window is open
*/
static void CreateGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *groupName, const char *windowTitle, int testParams)
{ {
HDDEDATA hData;
UINT error; UINT error;
/* Execute Command & Check Result */ /* Invalid Command */
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[InvalidCommand()]");
todo_wine ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
{
ok (expected_result == error, "CreateGroup %s: Expected Error %s, received %s.%s\n",
groupName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
/* No Error */ /* test parsing */
if (error == DMLERR_NO_ERROR) error = dde_execute(instance, hConv, "");
{ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Check if Group Now Exists */ error = dde_execute(instance, hConv, "CreateGroup");
CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams); ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Check if Window is Open (polling) */
CheckWindowCreated(windowTitle, TRUE, testParams);
}
}
/* Show Group Test. error = dde_execute(instance, hConv, "[CreateGroup");
* DDE command, expected_result, and the group name to check for existence ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
* if expected_result is DMLERR_NO_ERROR, test
* 1. window is open
*/
static HWND ShowGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *groupName, const char *windowTitle, BOOL closeAfterShowing, int testParams)
{
HDDEDATA hData;
UINT error;
HWND hwnd = 0;
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[CreateGroup]");
/* todo_wine... Is expected to fail, wine stubbed functions DO fail */ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* TODO REMOVE THIS CODE!!! */
todo_wine_if (expected_result != DMLERR_NOTPROCESSED)
ok (expected_result == error, "ShowGroup %s: Expected Error %s, received %s.%s\n",
groupName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
if (error == DMLERR_NO_ERROR) error = dde_execute(instance, hConv, "[CreateGroup()]");
{ ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Check if Window is Open (polling) */
hwnd = CheckWindowCreated(windowTitle, closeAfterShowing, testParams);
}
return hwnd;
}
/* Delete Group Test. error = dde_execute(instance, hConv, "[cREATEgROUP(test)]");
* DDE command, expected_result, and the group name to check for existence ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
* if expected_result is DMLERR_NO_ERROR, test ok(check_exists("test"), "directory not created\n");
* 1. group does not exist ok(check_window_exists("test"), "window not created\n");
*/
static void DeleteGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *groupName, int testParams)
{
HDDEDATA hData;
UINT error;
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[AddItem(notepad,foobar)]");
todo_wine ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
{ ok(check_exists("test/foobar.lnk"), "link not created\n");
ok (expected_result == error, "DeleteGroup %s: Expected Error %s, received %s.%s\n",
groupName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
if (error == DMLERR_NO_ERROR) error = dde_execute(instance, hConv, "[AddItem(notepad,foo bar)]");
{ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
/* Check that Group does not exist */ ok(check_exists("test/foo bar.lnk"), "link not created\n");
CheckFileExistsInProgramGroups(groupName, FALSE, TRUE, NULL, testParams);
}
}
/* Add Item Test error = dde_execute(instance, hConv, "[AddItem(notepad,a[b,c]d)]");
* DDE command, expected result, and group and file name where it should exist. ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
* checks to make sure error code matches expected error code
* checks to make sure item exists if successful
*/
static void AddItemTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *fileName, const char *groupName, int testParams)
{
HDDEDATA hData;
UINT error;
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[AddItem(notepad,\"a[b,c]d\")]");
todo_wine ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
{ ok(check_exists("test/a[b,c]d.lnk"), "link not created\n");
ok (expected_result == error, "AddItem %s: Expected Error %s, received %s.%s\n",
fileName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
if (error == DMLERR_NO_ERROR) error = dde_execute(instance, hConv, " [ AddItem ( notepad , test ) ] ");
{ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
/* Check that File exists */ ok(check_exists("test/test.lnk"), "link not created\n");
CheckFileExistsInProgramGroups(fileName, TRUE, FALSE, groupName, testParams);
}
}
/* Delete Item Test. error = dde_execute(instance, hConv, "[AddItem(notepad,one)][AddItem(notepad,two)]");
* DDE command, expected result, and group and file name where it should exist. ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
* checks to make sure error code matches expected error code ok(check_exists("test/one.lnk"), "link not created\n");
* checks to make sure item does not exist if successful ok(check_exists("test/two.lnk"), "link not created\n");
*/
static void DeleteItemTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *fileName, const char *groupName, int testParams)
{
HDDEDATA hData;
UINT error;
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[FakeCommand(test)][DeleteGroup(test)]");
todo_wine ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
{ ok(check_exists("test"), "directory should exist\n");
ok (expected_result == error, "DeleteItem %s: Expected Error %s, received %s.%s\n",
fileName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
if (error == DMLERR_NO_ERROR) error = dde_execute(instance, hConv, "[DeleteGroup(test)]");
{ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
/* Check that File does not exist */ ok(!check_exists("test"), "directory should not exist\n");
CheckFileExistsInProgramGroups(fileName, FALSE, FALSE, groupName, testParams);
}
}
/* Compound Command Test. error = dde_execute(instance, hConv, "[ExitProgman()]");
* not really generic, assumes command of the form: ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
* [CreateGroup ...][AddItem ...][AddItem ...]
* All samples I've seen using Compound were of this form (CreateGroup,
* AddItems) so this covers minimum expected functionality.
*/
static HWND CompoundCommandTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *groupName, const char *windowTitle, const char *fileName1,
const char *fileName2, int testParams)
{
HDDEDATA hData;
UINT error;
HWND hwnd = 0;
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams); error = dde_execute(instance, hConv, "[ExitProgman]");
todo_wine ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
{
ok (expected_result == error, "Compound String %s: Expected Error %s, received %s.%s\n",
command, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
if (error == DMLERR_NO_ERROR)
{
/* Check that File exists */
CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams);
hwnd = CheckWindowCreated(windowTitle, FALSE, testParams);
CheckFileExistsInProgramGroups(fileName1, TRUE, FALSE, groupName, testParams);
CheckFileExistsInProgramGroups(fileName2, TRUE, FALSE, groupName, testParams);
}
return hwnd;
}
static void CreateAddItemText(char *itemtext, const char *cmdline, const char *name)
{
lstrcpyA(itemtext, "[AddItem(");
lstrcatA(itemtext, cmdline);
lstrcatA(itemtext, ",");
lstrcatA(itemtext, name);
lstrcatA(itemtext, ")]");
} }
/* 1st set of tests */ /* 1st set of tests */
static int DdeTestProgman(DWORD instance, HCONV hConv) static void test_progman_dde(DWORD instance, HCONV hConv)
{ {
HDDEDATA hData;
UINT error; UINT error;
int testnum;
char temppath[MAX_PATH];
char f1g1[MAX_PATH], f2g1[MAX_PATH], f3g1[MAX_PATH], f1g3[MAX_PATH], f2g3[MAX_PATH];
char itemtext[MAX_PATH + 20];
char comptext[2 * (MAX_PATH + 20) + 21];
HWND hwnd;
testnum = 1; /* test creating and deleting groups and items */
/* Invalid Command */ error = dde_execute(instance, hConv, "[CreateGroup(Group1)]");
DdeExecuteCommand(instance, hConv, "[InvalidCommand()]", &hData, &error, DDE_TEST_MISC|testnum++); ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok (error == DMLERR_NOTPROCESSED, "InvalidCommand(), expected error %s, received %s.\n", ok(check_exists("Group1"), "directory not created\n");
GetStringFromError(DMLERR_NOTPROCESSED), GetStringFromError(error)); ok(check_window_exists("Group1"), "window not created\n");
/* On Vista+ the files have to exist when adding a link */ error = dde_execute(instance, hConv, "[AddItem]");
GetTempPathA(MAX_PATH, temppath); ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
GetTempFileNameA(temppath, "dde", 0, f1g1);
GetTempFileNameA(temppath, "dde", 0, f2g1);
GetTempFileNameA(temppath, "dde", 0, f3g1);
GetTempFileNameA(temppath, "dde", 0, f1g3);
GetTempFileNameA(temppath, "dde", 0, f2g3);
/* CreateGroup Tests (including AddItem, DeleteItem) */ error = dde_execute(instance, hConv, "[AddItem(test)]");
CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++); ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
CreateAddItemText(itemtext, f1g1, "f1g1Name");
AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f1g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++);
CreateAddItemText(itemtext, f2g1, "f2g1Name");
AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++);
DeleteItemTest(instance, hConv, "[DeleteItem(f2g1Name)]", DMLERR_NO_ERROR, "f2g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++);
CreateAddItemText(itemtext, f3g1, "f3g1Name");
AddItemTest(instance, hConv, itemtext, DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_ADDITEM|testnum++);
CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++);
/* Create Group that already exists - same instance */
CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++);
/* ShowGroup Tests */ error = dde_execute(instance, hConv, "[AddItem(notepad.exe)]");
ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, "Group1", Group1Title, TRUE, DDE_TEST_SHOWGROUP|testnum++); ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++); ok(check_exists("Group1/notepad.lnk"), "link not created\n");
ShowGroupTest(instance, hConv, "[ShowGroup(Startup,0)]", DMLERR_NO_ERROR, "Startup", StartupTitle, TRUE, DDE_TEST_SHOWGROUP|testnum++);
hwnd = ShowGroupTest(instance, hConv, "[ShowGroup(Group1,0)]", DMLERR_NO_ERROR, "Group1", Group1Title, FALSE, DDE_TEST_SHOWGROUP|testnum++);
/* DeleteGroup Test - Note that Window is Open for this test */ error = dde_execute(instance, hConv, "[DeleteItem(notepad.exe)]");
DeleteGroupTest(instance, hConv, "[DeleteGroup(Group1)]", DMLERR_NO_ERROR, "Group1", DDE_TEST_DELETEGROUP|testnum++); ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
/* Compound Execute String Command */ error = dde_execute(instance, hConv, "[DeleteItem(notepad)]");
lstrcpyA(comptext, "[CreateGroup(Group3)]"); ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
CreateAddItemText(itemtext, f1g3, "f1g3Name"); ok(!check_exists("Group1/notepad.lnk"), "link should not exist\n");
lstrcatA(comptext, itemtext);
CreateAddItemText(itemtext, f2g3, "f2g3Name");
lstrcatA(comptext, itemtext);
hwnd = CompoundCommandTest(instance, hConv, comptext, DMLERR_NO_ERROR, "Group3", Group3Title, "f1g3Name.lnk", "f2g3Name.lnk", DDE_TEST_COMPOUND|testnum++);
DeleteGroupTest(instance, hConv, "[DeleteGroup(Group3)]", DMLERR_NO_ERROR, "Group3", DDE_TEST_DELETEGROUP|testnum++); error = dde_execute(instance, hConv, "[DeleteItem(notepad)]");
if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0); ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Full Parameters of Add Item */ error = dde_execute(instance, hConv, "[AddItem(notepad)]");
/* AddItem(CmdLine[,Name[,IconPath[,IconIndex[,xPos,yPos[,DefDir[,HotKey[,fMinimize[fSeparateSpace]]]]]]]) */ ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/notepad.lnk"), "link not created\n");
DeleteFileA(f1g1); error = dde_execute(instance, hConv, "[AddItem(notepad)]");
DeleteFileA(f2g1); ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
DeleteFileA(f3g1);
DeleteFileA(f1g3);
DeleteFileA(f2g3);
return testnum; /* XP allows any valid path even if it does not exist; Vista+ requires that
* the path both exist and be a file (directories are invalid). */
error = dde_execute(instance, hConv, "[AddItem(C:\\windows\\system.ini)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/system.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[AddItem(notepad,test1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/test1.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[DeleteItem(test1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("Group1/test1.lnk"), "link should not exist\n");
error = dde_execute(instance, hConv, "[AddItem(notepad,test1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/test1.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[ReplaceItem(test1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("Group1/test1.lnk"), "link should not exist\n");
error = dde_execute(instance, hConv, "[AddItem(regedit)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/regedit.lnk"), "link not created\n");
/* test ShowGroup() and test which group an item gets added to */
error = dde_execute(instance, hConv, "[ShowGroup(Group1)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
error = dde_execute(instance, hConv, "[ShowGroup(Group1, 0)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_window_exists("Group1"), "window not created\n");
error = dde_execute(instance, hConv, "[CreateGroup(Group2)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group2"), "directory not created\n");
ok(check_window_exists("Group2"), "window not created\n");
error = dde_execute(instance, hConv, "[AddItem(notepad,test2)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group2/test2.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[ShowGroup(Group1, 0)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_window_exists("Group1"), "window not created\n");
error = dde_execute(instance, hConv, "[AddItem(notepad,test3)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/test3.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[DeleteGroup(Group1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("Group1"), "directory should not exist\n");
error = dde_execute(instance, hConv, "[DeleteGroup(Group1)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
error = dde_execute(instance, hConv, "[ShowGroup(Group2, 0)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_window_exists("Group2"), "window not created\n");
error = dde_execute(instance, hConv, "[ExitProgman(1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
error = dde_execute(instance, hConv, "[AddItem(notepad,test4)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group2/test4.lnk"), "link not created\n");
} }
/* 2nd set of tests - 2nd connection */ /* 2nd set of tests - 2nd connection */
static void DdeTestProgman2(DWORD instance, HCONV hConv, int testnum) static void test_progman_dde2(DWORD instance, HCONV hConv)
{ {
/* Create Group that already exists on a separate connection */ UINT error;
CreateGroupTest(instance, hConv, "[CreateGroup(Group2)]", DMLERR_NO_ERROR, "Group2", Group2Title, DDE_TEST_CREATEGROUP|testnum++);
DeleteGroupTest(instance, hConv, "[DeleteGroup(Group2)]", DMLERR_NO_ERROR, "Group2", DDE_TEST_DELETEGROUP|testnum++); /* last open group is retained across connections */
error = dde_execute(instance, hConv, "[AddItem(notepad)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group2/notepad.lnk"), "link not created\n");
error = dde_execute(instance, hConv, "[DeleteGroup(Group2)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("Group2"), "directory should not exist\n");
}
static BOOL check_in_programs_list(const char *list, const char *group)
{
while (1)
{
if (!strncmp(list, group, strlen(group)) && list[strlen(group)] == '\r')
return TRUE;
if (!(list = strchr(list, '\r'))) break;
list += 2;
}
return FALSE;
}
static void test_request_groups(DWORD instance, HCONV hconv)
{
char *list;
char programs[MAX_PATH];
WIN32_FIND_DATAA finddata;
HANDLE hfind;
list = dde_request(instance, hconv, "Groups");
ok(list != NULL, "request failed: %u\n", DdeGetLastError(instance));
strcpy(programs, ProgramsDir);
strcat(programs, "/*");
hfind = FindFirstFileA(programs, &finddata);
do
{
if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && finddata.cFileName[0] != '.')
{
ok(check_in_programs_list(list, finddata.cFileName),
"directory '%s' missing from group list\n", finddata.cFileName);
}
} while (FindNextFileA(hfind, &finddata));
FindClose(hfind);
} }
START_TEST(progman_dde) START_TEST(progman_dde)
@ -699,20 +421,21 @@ START_TEST(progman_dde)
UINT err; UINT err;
HSZ hszProgman; HSZ hszProgman;
HCONV hConv; HCONV hConv;
int testnum; BOOL ret;
init_function_pointers(); init_function_pointers();
init_strings(); init_strings();
/* Initialize DDE Instance */ /* Initialize DDE Instance */
err = DdeInitializeA(&instance, DdeCallback, APPCMD_CLIENTONLY, 0); err = DdeInitializeA(&instance, DdeCallback, APPCMD_CLIENTONLY, 0);
ok (err == DMLERR_NO_ERROR, "DdeInitialize Error %s\n", GetStringFromError(err)); ok(err == DMLERR_NO_ERROR, "DdeInitialize() failed: %u\n", err);
/* Create Connection */ /* Create Connection */
hszProgman = DdeCreateStringHandleA(instance, "PROGMAN", CP_WINANSI); hszProgman = DdeCreateStringHandleA(instance, "PROGMAN", CP_WINANSI);
ok (hszProgman != NULL, "DdeCreateStringHandle Error %s\n", GetDdeLastErrorStr(instance)); ok(hszProgman != NULL, "DdeCreateStringHandle() failed: %u\n", DdeGetLastError(instance));
hConv = DdeConnect(instance, hszProgman, hszProgman, NULL); hConv = DdeConnect(instance, hszProgman, hszProgman, NULL);
ok (DdeFreeStringHandle(instance, hszProgman), "DdeFreeStringHandle failure\n"); ret = DdeFreeStringHandle(instance, hszProgman);
ok(ret, "DdeFreeStringHandle() failed: %u\n", DdeGetLastError(instance));
/* Seeing failures on early versions of Windows Connecting to progman, exit if connection fails */ /* Seeing failures on early versions of Windows Connecting to progman, exit if connection fails */
if (hConv == NULL) if (hConv == NULL)
{ {
@ -720,30 +443,36 @@ START_TEST(progman_dde)
return; return;
} }
/* Run Tests */ test_parser(instance, hConv);
testnum = DdeTestProgman(instance, hConv); test_progman_dde(instance, hConv);
test_request_groups(instance, hConv);
/* Cleanup & Exit */ /* Cleanup & Exit */
ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance)); ret = DdeDisconnect(hConv);
ok (DdeUninitialize(instance), "DdeUninitialize failed\n"); ok(ret, "DdeDisonnect() failed: %u\n", DdeGetLastError(instance));
ret = DdeUninitialize(instance);
ok(ret, "DdeUninitialize() failed: %u\n", DdeGetLastError(instance));
/* 2nd Instance (Followup Tests) */ /* 2nd Instance (Followup Tests) */
/* Initialize DDE Instance */ /* Initialize DDE Instance */
instance = 0; instance = 0;
err = DdeInitializeA(&instance, DdeCallback, APPCMD_CLIENTONLY, 0); err = DdeInitializeA(&instance, DdeCallback, APPCMD_CLIENTONLY, 0);
ok (err == DMLERR_NO_ERROR, "DdeInitialize Error %s\n", GetStringFromError(err)); ok (err == DMLERR_NO_ERROR, "DdeInitialize() failed: %u\n", err);
/* Create Connection */ /* Create Connection */
hszProgman = DdeCreateStringHandleA(instance, "PROGMAN", CP_WINANSI); hszProgman = DdeCreateStringHandleA(instance, "PROGMAN", CP_WINANSI);
ok (hszProgman != NULL, "DdeCreateStringHandle Error %s\n", GetDdeLastErrorStr(instance)); ok(hszProgman != NULL, "DdeCreateStringHandle() failed: %u\n", DdeGetLastError(instance));
hConv = DdeConnect(instance, hszProgman, hszProgman, NULL); hConv = DdeConnect(instance, hszProgman, hszProgman, NULL);
ok (hConv != NULL, "DdeConnect Error %s\n", GetDdeLastErrorStr(instance)); ok(hConv != NULL, "DdeConnect() failed: %u\n", DdeGetLastError(instance));
ok (DdeFreeStringHandle(instance, hszProgman), "DdeFreeStringHandle failure\n"); ret = DdeFreeStringHandle(instance, hszProgman);
ok(ret, "DdeFreeStringHandle() failed: %u\n", DdeGetLastError(instance));
/* Run Tests */ /* Run Tests */
DdeTestProgman2(instance, hConv, testnum); test_progman_dde2(instance, hConv);
/* Cleanup & Exit */ /* Cleanup & Exit */
ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance)); ret = DdeDisconnect(hConv);
ok (DdeUninitialize(instance), "DdeUninitialize failed\n"); ok(ret, "DdeDisonnect() failed: %u\n", DdeGetLastError(instance));
ret = DdeUninitialize(instance);
ok(ret, "DdeUninitialize() failed: %u\n", DdeGetLastError(instance));
} }

View file

@ -18,7 +18,12 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "shellapi.h"
#include <stdio.h>
#include "wine/test.h"
static int (WINAPI *pSHQueryRecycleBinA)(LPCSTR,LPSHQUERYRBINFO); static int (WINAPI *pSHQueryRecycleBinA)(LPCSTR,LPSHQUERYRBINFO);
static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA); static int (WINAPI *pSHFileOperationA)(LPSHFILEOPSTRUCTA);

View file

@ -18,35 +18,63 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <winsvc.h> #include "shldisp.h"
#include <initguid.h> #include "shlobj.h"
#include "shlwapi.h"
#include "winsvc.h"
#include "wine/heap.h"
#include "wine/test.h"
#include "initguid.h"
#define EXPECT_HR(hr,hr_exp) \ #define EXPECT_HR(hr,hr_exp) \
ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp) ok(hr == hr_exp, "got 0x%08x, expected 0x%08x\n", hr, hr_exp)
#define EXPECT_REF(obj,ref) _expect_ref((IUnknown *)obj, ref, __LINE__)
static void _expect_ref(IUnknown *obj, ULONG ref, int line)
{
ULONG rc;
IUnknown_AddRef(obj);
rc = IUnknown_Release(obj);
ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d\n", rc, ref);
}
static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0}; static const WCHAR winetestW[] = {'w','i','n','e','t','e','s','t',0};
static HRESULT (WINAPI *pSHGetFolderPathW)(HWND, int, HANDLE, DWORD, LPWSTR);
static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*); static HRESULT (WINAPI *pSHGetNameFromIDList)(PCIDLIST_ABSOLUTE,SIGDN,PWSTR*);
static HRESULT (WINAPI *pSHGetSpecialFolderLocation)(HWND, int, LPITEMIDLIST *);
static DWORD (WINAPI *pGetLongPathNameW)(LPCWSTR, LPWSTR, DWORD);
/* Updated Windows 7 has a new IShellDispatch6 in its typelib */ /* Updated Windows 7 has a new IShellDispatch6 in its typelib */
DEFINE_GUID(IID_IWin7ShellDispatch6, 0x34936ba1, 0x67ad, 0x4c41, 0x99,0xb8, 0x8c,0x12,0xdf,0xf1,0xe9,0x74); DEFINE_GUID(IID_IWin7ShellDispatch6, 0x34936ba1, 0x67ad, 0x4c41, 0x99,0xb8, 0x8c,0x12,0xdf,0xf1,0xe9,0x74);
static BSTR a2bstr(const char *str)
{
BSTR ret;
int len;
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
ret = SysAllocStringLen(NULL, len);
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
return ret;
}
static void variant_set_string(VARIANT *v, const char *s)
{
V_VT(v) = VT_BSTR;
V_BSTR(v) = a2bstr(s);
}
static void init_function_pointers(void) static void init_function_pointers(void)
{ {
HMODULE hshell32, hkernel32; HMODULE hshell32;
hshell32 = GetModuleHandleA("shell32.dll"); hshell32 = GetModuleHandleA("shell32.dll");
hkernel32 = GetModuleHandleA("kernel32.dll");
pSHGetFolderPathW = (void*)GetProcAddress(hshell32, "SHGetFolderPathW");
pSHGetNameFromIDList = (void*)GetProcAddress(hshell32, "SHGetNameFromIDList"); pSHGetNameFromIDList = (void*)GetProcAddress(hshell32, "SHGetNameFromIDList");
pSHGetSpecialFolderLocation = (void*)GetProcAddress(hshell32,
"SHGetSpecialFolderLocation");
pGetLongPathNameW = (void*)GetProcAddress(hkernel32, "GetLongPathNameW");
} }
static void test_namespace(void) static void test_namespace(void)
@ -108,18 +136,23 @@ static void test_namespace(void)
FolderItem *item; FolderItem *item;
VARIANT var; VARIANT var;
BSTR title, item_path; BSTR title, item_path;
IDispatch *disp;
int len, i; int len, i;
r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void **)&sd);
&IID_IShellDispatch, (LPVOID*)&sd); ok(SUCCEEDED(r), "Failed to create ShellDispatch object: %#x.\n", r);
if (r == REGDB_E_CLASSNOTREG) /* NT4 */
{ disp = NULL;
win_skip("skipping IShellDispatch tests\n"); r = IShellDispatch_get_Application(sd, &disp);
return; ok(r == S_OK, "Failed to get application pointer, hr %#x.\n", r);
} ok(disp == (IDispatch *)sd, "Unexpected application pointer %p.\n", disp);
ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r); IDispatch_Release(disp);
if (FAILED(r))
return; disp = NULL;
r = IShellDispatch_get_Parent(sd, &disp);
ok(r == S_OK, "Failed to get Shell object parent, hr %#x.\n", r);
ok(disp == (IDispatch *)sd, "Unexpected parent pointer %p.\n", disp);
IDispatch_Release(disp);
VariantInit(&var); VariantInit(&var);
folder = (void*)0xdeadbeef; folder = (void*)0xdeadbeef;
@ -135,6 +168,7 @@ static void test_namespace(void)
folder = (void*)0xdeadbeef; folder = (void*)0xdeadbeef;
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
if (special_folders[i] == ssfALTSTARTUP || special_folders[i] == ssfCOMMONALTSTARTUP) if (special_folders[i] == ssfALTSTARTUP || special_folders[i] == ssfCOMMONALTSTARTUP)
todo_wine
ok(r == S_OK || broken(r == S_FALSE) /* winxp */, "Failed to get folder for index %#x, got %08x\n", special_folders[i], r); ok(r == S_OK || broken(r == S_FALSE) /* winxp */, "Failed to get folder for index %#x, got %08x\n", special_folders[i], r);
else else
ok(r == S_OK, "Failed to get folder for index %#x, got %08x\n", special_folders[i], r); ok(r == S_OK, "Failed to get folder for index %#x, got %08x\n", special_folders[i], r);
@ -146,30 +180,21 @@ static void test_namespace(void)
V_I4(&var) = -1; V_I4(&var) = -1;
folder = (void *)0xdeadbeef; folder = (void *)0xdeadbeef;
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
todo_wine { ok(r == S_FALSE, "Unexpected hr %#x.\n", r);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r); ok(folder == NULL, "Unexpected folder instance %p\n", folder);
ok(folder == NULL, "got %p\n", folder);
if (r == S_OK)
Folder_Release(folder);
}
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = ssfPROGRAMFILES; V_I4(&var) = ssfPROGRAMFILES;
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK || ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
broken(r == S_FALSE), /* NT4 */
"IShellDispatch::NameSpace failed: %08x\n", r);
if (r == S_OK) if (r == S_OK)
{ {
static WCHAR path[MAX_PATH]; static WCHAR path[MAX_PATH];
if (pSHGetFolderPathW) r = SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, path);
{ ok(r == S_OK, "Failed to get folder path: %#x.\n", r);
r = pSHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL,
SHGFP_TYPE_CURRENT, path);
ok(r == S_OK, "SHGetFolderPath failed: %08x\n", r);
}
r = Folder_get_Title(folder, &title); r = Folder_get_Title(folder, &title);
todo_wine
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r); ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
if (r == S_OK) if (r == S_OK)
{ {
@ -177,22 +202,20 @@ static void test_namespace(void)
HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir. HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir.
On newer Windows it seems constant and is not changed On newer Windows it seems constant and is not changed
if the program files directory name is changed */ if the program files directory name is changed */
if (pSHGetSpecialFolderLocation && pSHGetNameFromIDList) if (pSHGetNameFromIDList)
{ {
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
PWSTR name; PWSTR name;
r = pSHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidl); r = SHGetSpecialFolderLocation(NULL, CSIDL_PROGRAM_FILES, &pidl);
ok(r == S_OK, "SHGetSpecialFolderLocation failed: %08x\n", r); ok(r == S_OK, "SHGetSpecialFolderLocation failed: %08x\n", r);
r = pSHGetNameFromIDList(pidl, SIGDN_NORMALDISPLAY, &name); r = pSHGetNameFromIDList(pidl, SIGDN_NORMALDISPLAY, &name);
ok(r == S_OK, "SHGetNameFromIDList failed: %08x\n", r); ok(r == S_OK, "SHGetNameFromIDList failed: %08x\n", r);
todo_wine ok(!lstrcmpW(title, name), "expected %s, got %s\n", wine_dbgstr_w(name), wine_dbgstr_w(title));
ok(!lstrcmpW(title, name), "expected %s, got %s\n",
wine_dbgstr_w(name), wine_dbgstr_w(title));
CoTaskMemFree(name); CoTaskMemFree(name);
CoTaskMemFree(pidl); CoTaskMemFree(pidl);
} }
else if (pSHGetFolderPathW) else
{ {
WCHAR *p; WCHAR *p;
@ -202,7 +225,6 @@ static void test_namespace(void)
ok(!lstrcmpiW(title, p), "expected %s, got %s\n", ok(!lstrcmpiW(title, p), "expected %s, got %s\n",
wine_dbgstr_w(p), wine_dbgstr_w(title)); wine_dbgstr_w(p), wine_dbgstr_w(title));
} }
else skip("skipping Folder::get_Title test\n");
SysFreeString(title); SysFreeString(title);
} }
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2); r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
@ -215,9 +237,7 @@ static void test_namespace(void)
{ {
r = FolderItem_get_Path(item, &item_path); r = FolderItem_get_Path(item, &item_path);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r); ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
if (pSHGetFolderPathW) ok(!lstrcmpiW(item_path, path), "expected %s, got %s\n", wine_dbgstr_w(path), wine_dbgstr_w(item_path));
ok(!lstrcmpiW(item_path, path), "expected %s, got %s\n",
wine_dbgstr_w(path), wine_dbgstr_w(item_path));
SysFreeString(item_path); SysFreeString(item_path);
FolderItem_Release(item); FolderItem_Release(item);
} }
@ -229,34 +249,21 @@ static void test_namespace(void)
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = ssfBITBUCKET; V_I4(&var) = ssfBITBUCKET;
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK || ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
broken(r == S_FALSE), /* NT4 */
"IShellDispatch::NameSpace failed: %08x\n", r); r = Folder_QueryInterface(folder, &IID_Folder2, (void **)&folder2);
if (r == S_OK) ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
{
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
ok(r == S_OK ||
broken(r == E_NOINTERFACE), /* NT4 */
"Folder::QueryInterface failed: %08x\n", r);
if (r == S_OK)
{
r = Folder2_get_Self(folder2, &item); r = Folder2_get_Self(folder2, &item);
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r); ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
if (r == S_OK)
{
r = FolderItem_get_Path(item, &item_path); r = FolderItem_get_Path(item, &item_path);
todo_wine
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r); ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
todo_wine /* TODO: we return lowercase GUID here */
ok(!lstrcmpW(item_path, clsidW), "expected %s, got %s\n", ok(!lstrcmpiW(item_path, clsidW), "expected %s, got %s\n", wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
SysFreeString(item_path); SysFreeString(item_path);
FolderItem_Release(item); FolderItem_Release(item);
}
Folder2_Release(folder2); Folder2_Release(folder2);
}
Folder_Release(folder); Folder_Release(folder);
}
GetTempPathW(MAX_PATH, tempW); GetTempPathW(MAX_PATH, tempW);
GetCurrentDirectoryW(MAX_PATH, curW); GetCurrentDirectoryW(MAX_PATH, curW);
@ -269,51 +276,39 @@ static void test_namespace(void)
SysFreeString(V_BSTR(&var)); SysFreeString(V_BSTR(&var));
GetFullPathNameW(winetestW, MAX_PATH, tempW, NULL); GetFullPathNameW(winetestW, MAX_PATH, tempW, NULL);
if (pGetLongPathNameW)
{ len = GetLongPathNameW(tempW, NULL, 0);
len = pGetLongPathNameW(tempW, NULL, 0); long_pathW = heap_alloc(len * sizeof(WCHAR));
long_pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); GetLongPathNameW(tempW, long_pathW, len);
if (long_pathW)
pGetLongPathNameW(tempW, long_pathW, len);
}
V_VT(&var) = VT_BSTR; V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(tempW); V_BSTR(&var) = SysAllocString(tempW);
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r); ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
if (r == S_OK)
{ disp = (void *)0xdeadbeef;
r = Folder_get_Parent(folder, &disp);
ok(r == E_NOTIMPL, "Unexpected hr %#x.\n", r);
ok(disp == NULL, "Unexpected parent pointer %p.\n", disp);
r = Folder_get_Title(folder, &title); r = Folder_get_Title(folder, &title);
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r); ok(r == S_OK, "Failed to get folder title: %#x.\n", r);
if (r == S_OK) ok(!lstrcmpW(title, winetestW), "Unexpected title: %s\n", wine_dbgstr_w(title));
{
ok(!lstrcmpW(title, winetestW), "bad title: %s\n",
wine_dbgstr_w(title));
SysFreeString(title); SysFreeString(title);
}
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2); r = Folder_QueryInterface(folder, &IID_Folder2, (void **)&folder2);
ok(r == S_OK || ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
broken(r == E_NOINTERFACE), /* NT4 */
"Folder::QueryInterface failed: %08x\n", r);
if (r == S_OK)
{
r = Folder2_get_Self(folder2, &item); r = Folder2_get_Self(folder2, &item);
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r); ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
if (r == S_OK)
{
r = FolderItem_get_Path(item, &item_path); r = FolderItem_get_Path(item, &item_path);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r); ok(r == S_OK, "Failed to get item path: %#x.\n", r);
if (long_pathW) ok(!lstrcmpW(item_path, long_pathW), "Unexpected path %s, got %s\n", wine_dbgstr_w(item_path), wine_dbgstr_w(long_pathW));
ok(!lstrcmpW(item_path, long_pathW),
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
wine_dbgstr_w(item_path));
SysFreeString(item_path); SysFreeString(item_path);
FolderItem_Release(item); FolderItem_Release(item);
}
Folder2_Release(folder2); Folder2_Release(folder2);
}
Folder_Release(folder); Folder_Release(folder);
} VariantClear(&var);
SysFreeString(V_BSTR(&var));
len = lstrlenW(tempW); len = lstrlenW(tempW);
if (len < MAX_PATH - 1) if (len < MAX_PATH - 1)
@ -334,9 +329,7 @@ static void test_namespace(void)
SysFreeString(title); SysFreeString(title);
} }
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2); r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
ok(r == S_OK || ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
broken(r == E_NOINTERFACE), /* NT4 */
"Folder::QueryInterface failed: %08x\n", r);
if (r == S_OK) if (r == S_OK)
{ {
r = Folder2_get_Self(folder2, &item); r = Folder2_get_Self(folder2, &item);
@ -345,10 +338,8 @@ static void test_namespace(void)
{ {
r = FolderItem_get_Path(item, &item_path); r = FolderItem_get_Path(item, &item_path);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r); ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
if (long_pathW) ok(!lstrcmpW(item_path, long_pathW), "Unexpected path %s, got %s\n", wine_dbgstr_w(item_path),
ok(!lstrcmpW(item_path, long_pathW), wine_dbgstr_w(long_pathW));
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
wine_dbgstr_w(item_path));
SysFreeString(item_path); SysFreeString(item_path);
FolderItem_Release(item); FolderItem_Release(item);
} }
@ -359,7 +350,7 @@ static void test_namespace(void)
SysFreeString(V_BSTR(&var)); SysFreeString(V_BSTR(&var));
} }
HeapFree(GetProcessHeap(), 0, long_pathW); heap_free(long_pathW);
RemoveDirectoryW(winetestW); RemoveDirectoryW(winetestW);
SetCurrentDirectoryW(curW); SetCurrentDirectoryW(curW);
IShellDispatch_Release(sd); IShellDispatch_Release(sd);
@ -367,55 +358,110 @@ static void test_namespace(void)
static void test_items(void) static void test_items(void)
{ {
WCHAR wstr[MAX_PATH], orig_dir[MAX_PATH]; static const struct
{
char name[32];
enum
{
DIRECTORY,
EMPTY_FILE,
}
type;
}
file_defs[] =
{
{ "00-Myfolder", DIRECTORY },
{ "01-empty.bin", EMPTY_FILE },
};
WCHAR path[MAX_PATH], cur_dir[MAX_PATH], orig_dir[MAX_PATH];
HRESULT r; HRESULT r;
IShellDispatch *sd = NULL; IShellDispatch *sd = NULL;
Folder *folder = NULL; Folder *folder = NULL;
FolderItems *items = NULL; FolderItems *items;
FolderItems2 *items2 = NULL; FolderItems2 *items2 = NULL;
FolderItems3 *items3 = NULL; FolderItems3 *items3 = NULL;
FolderItem *item = (FolderItem*)0xdeadbeef; FolderItem *item = (FolderItem*)0xdeadbeef, *item2;
IDispatch *disp = NULL;
IUnknown *unk = NULL;
FolderItemVerbs *verbs = (FolderItemVerbs*)0xdeadbeef; FolderItemVerbs *verbs = (FolderItemVerbs*)0xdeadbeef;
VARIANT var; VARIANT var, int_index, str_index, str_index2;
LONG lcount = -1; IDispatch *disp, *disp2;
LONG count = -1;
IUnknown *unk;
HANDLE file;
BSTR bstr;
char cstr[64];
BOOL ret;
int i;
r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&sd); r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void**)&sd);
ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r); ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r);
ok(!!sd, "sd is null\n"); ok(!!sd, "sd is null\n");
GetTempPathW(MAX_PATH, wstr); /* create and enter a temporary directory and a folder object for it */
GetTempPathW(MAX_PATH, path);
GetCurrentDirectoryW(MAX_PATH, orig_dir); GetCurrentDirectoryW(MAX_PATH, orig_dir);
SetCurrentDirectoryW(wstr); SetCurrentDirectoryW(path);
CreateDirectoryW(winetestW, NULL); ret = CreateDirectoryW(winetestW, NULL);
GetFullPathNameW(winetestW, MAX_PATH, wstr, NULL); ok(ret, "CreateDirectory failed: %08x\n", GetLastError());
GetFullPathNameW(winetestW, MAX_PATH, path, NULL);
V_VT(&var) = VT_BSTR; V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(wstr); V_BSTR(&var) = SysAllocString(path);
EXPECT_REF(sd, 1);
r = IShellDispatch_NameSpace(sd, var, &folder); r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r); ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
ok(!!folder, "folder is null\n"); ok(!!folder, "folder is null\n");
SysFreeString(V_BSTR(&var)); EXPECT_REF(folder, 1);
IShellDispatch_Release(sd); EXPECT_REF(sd, 1);
SetCurrentDirectoryW(winetestW);
VariantClear(&var);
SetCurrentDirectoryW(winetestW);
GetCurrentDirectoryW(MAX_PATH, path);
GetLongPathNameW(path, cur_dir, MAX_PATH);
/* FolderItems grabs its Folder reference */
items = NULL;
r = Folder_Items(folder, &items); r = Folder_Items(folder, &items);
ok(r == S_OK, "Folder::Items failed: %08x\n", r); ok(r == S_OK, "Folder::Items failed: %08x\n", r);
ok(!!items, "items is null\n"); ok(!!items, "items is null\n");
r = FolderItems_QueryInterface(items, &IID_FolderItems2, (void**)&items2); EXPECT_REF(folder, 2);
ok(r == S_OK || broken(r == E_NOINTERFACE) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r); EXPECT_REF(items, 1);
ok(!!items2 || broken(!items2) /* xp and later */, "items2 is null\n");
r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3); unk = NULL;
ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r); r = Folder_Items(folder, (FolderItems **)&unk);
ok(!!items3, "items3 is null\n"); ok(r == S_OK, "Folder::Items failed: %08x\n", r);
Folder_Release(folder); EXPECT_REF(folder, 3);
IUnknown_Release(unk);
EXPECT_REF(folder, 2);
FolderItems_AddRef(items);
EXPECT_REF(folder, 2);
FolderItems_Release(items);
/* Application property */
disp = NULL;
EXPECT_REF(sd, 1);
r = Folder_get_Application(folder, &disp);
ok(r == S_OK, "Failed to get application %#x.\n", r);
ok(disp != (IDispatch *)sd, "Unexpected application pointer\n");
EXPECT_REF(sd, 1);
disp2 = NULL;
r = Folder_get_Application(folder, &disp2);
ok(r == S_OK, "Failed to get application %#x.\n", r);
ok(disp2 == disp, "Unexpected application pointer\n");
IDispatch_Release(disp2);
r = IDispatch_QueryInterface(disp, &IID_IShellDispatch, (void **)&disp2);
ok(r == S_OK, "Wrong instance, hr %#x.\n", r);
IDispatch_Release(disp2);
IDispatch_Release(disp);
if (0) /* crashes on all versions of Windows */ if (0) /* crashes on all versions of Windows */
r = FolderItems_get_Count(items, NULL); r = FolderItems_get_Count(items, NULL);
r = FolderItems_get_Count(items, &lcount); r = FolderItems_get_Count(items, &count);
ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r); ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
ok(!lcount, "expected 0 files, got %d\n", lcount); ok(!count, "expected 0 files, got %d\n", count);
V_VT(&var) = VT_I4; V_VT(&var) = VT_I4;
V_I4(&var) = 0; V_I4(&var) = 0;
@ -424,7 +470,269 @@ static void test_items(void)
r = FolderItems_Item(items, var, NULL); r = FolderItems_Item(items, var, NULL);
r = FolderItems_Item(items, var, &item); r = FolderItems_Item(items, var, &item);
todo_wine ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(!item, "item is not null\n");
/* create test files */
for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
{
switch (file_defs[i].type)
{
case DIRECTORY:
r = CreateDirectoryA(file_defs[i].name, NULL);
ok(r, "CreateDirectory failed: %08x\n", GetLastError());
PathCombineA(cstr, file_defs[i].name, "foo.txt");
file = CreateFileA(cstr, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
CloseHandle(file);
break;
case EMPTY_FILE:
file = CreateFileA(file_defs[i].name, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %08x\n", GetLastError());
CloseHandle(file);
break;
}
}
/* test that get_Count is not aware of the newly created files */
count = -1;
r = FolderItems_get_Count(items, &count);
ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
ok(!count, "expected 0 files, got %d\n", count);
/* test that the newly created files CAN be retrieved by string index */
variant_set_string(&var, file_defs[0].name);
item = NULL;
r = FolderItems_Item(items, var, &item);
ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
ok(!!item, "item is null\n");
disp = (void *)0xdeadbeef;
r = FolderItems_get_Parent(items, &disp);
ok(r == E_NOTIMPL, "Unexpected hr %#x.\n", r);
ok(disp == NULL, "Unexpected parent pointer %p.\n", disp);
r = FolderItem_get_Parent(item, &disp);
ok(r == S_OK, "Failed to get parent pointer, hr %#x.\n", r);
ok(disp == (IDispatch *)folder, "Unexpected parent pointer %p.\n", disp);
IDispatch_Release(disp);
if (item) FolderItem_Release(item);
VariantClear(&var);
/* recreate the items object */
FolderItems_Release(items);
items = NULL;
r = Folder_Items(folder, &items);
ok(r == S_OK, "Folder::Items failed: %08x\n", r);
ok(!!items, "items is null\n");
r = FolderItems_QueryInterface(items, &IID_FolderItems2, (void**)&items2);
ok(r == S_OK || broken(r == E_NOINTERFACE) /* xp and later */, "FolderItems::QueryInterface failed: %08x\n", r);
if (r == S_OK)
{
ok(!!items2, "items2 is null\n");
FolderItems2_Release(items2);
}
r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3);
ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r);
ok(!!items3, "items3 is null\n");
count = -1;
r = FolderItems_get_Count(items, &count);
ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
ok(count == sizeof(file_defs)/sizeof(file_defs[0]),
"expected %d files, got %d\n", (LONG)(sizeof(file_defs)/sizeof(file_defs[0])), count);
V_VT(&var) = VT_EMPTY;
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, var, &item);
ok(r == E_NOTIMPL, "expected E_NOTIMPL, got %08x\n", r);
ok(!item, "item is not null\n");
V_VT(&var) = VT_I2;
V_I2(&var) = 0;
EXPECT_REF(folder, 2);
EXPECT_REF(items, 2);
item = NULL;
r = FolderItems_Item(items, var, &item);
ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
ok(!!item, "item is null\n");
EXPECT_REF(folder, 3);
EXPECT_REF(items, 2);
r = Folder_get_Application(folder, &disp);
ok(r == S_OK, "Failed to get application pointer %#x.\n", r);
r = FolderItem_get_Application(item, &disp2);
ok(r == S_OK, "Failed to get application pointer %#x.\n", r);
ok(disp == disp2, "Unexpected application pointer.\n");
IDispatch_Release(disp2);
IDispatch_Release(disp);
FolderItem_Release(item);
V_VT(&var) = VT_I4;
V_I4(&var) = 0;
item = NULL;
r = FolderItems_Item(items, var, &item);
ok(r == S_OK, "FolderItems::Item failed: %08x\n", r);
ok(!!item, "item is null\n");
if (item) FolderItem_Release(item);
V_I4(&var) = -1;
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, var, &item);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(!item, "item is not null\n");
V_VT(&var) = VT_ERROR;
V_ERROR(&var) = 0;
item = NULL;
r = FolderItems_Item(items, var, &item);
ok(r == S_OK, "expected S_OK, got %08x\n", r);
ok(!!item, "item is null\n");
if (item)
{
bstr = NULL;
r = FolderItem_get_Path(item, &bstr);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
ok(!lstrcmpW(bstr, cur_dir),
"expected %s, got %s\n", wine_dbgstr_w(cur_dir), wine_dbgstr_w(bstr));
SysFreeString(bstr);
FolderItem_Release(item);
}
V_VT(&int_index) = VT_I4;
/* test the folder item corresponding to each file */
for (i = 0; i < sizeof(file_defs)/sizeof(file_defs[0]); i++)
{
VARIANT_BOOL b;
BSTR name;
V_I4(&int_index) = i;
variant_set_string(&str_index, file_defs[i].name);
item = NULL;
r = FolderItems_Item(items, int_index, &item);
ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
ok(!!item, "file_defs[%d]: item is null\n", i);
item2 = NULL;
r = FolderItems_Item(items, int_index, &item2);
ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
ok(item2 != item, "file_defs[%d]: item and item2 are the same\n", i);
FolderItem_Release(item2);
bstr = NULL;
r = FolderItem_get_Path(item, &bstr);
ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
PathCombineW(path, cur_dir, V_BSTR(&str_index));
ok(!lstrcmpW(bstr, path),
"file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(path), wine_dbgstr_w(bstr));
SysFreeString(bstr);
bstr = a2bstr(file_defs[i].name);
r = FolderItem_get_Name(item, &name);
ok(r == S_OK, "Failed to get item name, hr %#x.\n", r);
/* Returned display name does not have to strictly match file name, e.g. extension could be omitted. */
ok(lstrlenW(name) <= lstrlenW(bstr), "file_defs[%d]: unexpected name length.\n", i);
ok(!memcmp(bstr, name, lstrlenW(name) * sizeof(WCHAR)), "file_defs[%d]: unexpected name %s.\n", i, wine_dbgstr_w(name));
SysFreeString(name);
SysFreeString(bstr);
FolderItem_Release(item);
item = NULL;
r = FolderItems_Item(items, str_index, &item);
ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
ok(!!item, "file_defs[%d]: item is null\n", i);
bstr = NULL;
r = FolderItem_get_Path(item, &bstr);
ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
PathCombineW(path, cur_dir, V_BSTR(&str_index));
ok(!lstrcmpW(bstr, path),
"file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(path), wine_dbgstr_w(bstr));
SysFreeString(bstr);
b = 0xdead;
r = FolderItem_get_IsFolder(item, &b);
ok(r == S_OK, "Failed to get IsFolder property, %#x.\n", r);
ok(file_defs[i].type == DIRECTORY ? b == VARIANT_TRUE : b == VARIANT_FALSE, "Unexpected prop value %#x.\n", b);
FolderItem_Release(item);
if (file_defs[i].type == DIRECTORY)
{
/* test that getting an item object for a file in a subdirectory succeeds */
PathCombineA(cstr, file_defs[i].name, "foo.txt");
variant_set_string(&str_index2, cstr);
item2 = NULL;
r = FolderItems_Item(items, str_index2, &item2);
ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
ok(!!item2, "file_defs[%d]: item is null\n", i);
if (item2) FolderItem_Release(item2);
VariantClear(&str_index2);
/* delete the file in the subdirectory */
ret = DeleteFileA(cstr);
ok(ret, "file_defs[%d]: DeleteFile failed: %08x\n", i, GetLastError());
/* test that getting an item object via a relative path fails */
strcpy(cstr, file_defs[i].name);
strcat(cstr, "\\..\\");
strcat(cstr, file_defs[i].name);
variant_set_string(&str_index2, cstr);
item2 = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, str_index2, &item2);
todo_wine {
ok(r == S_FALSE, "file_defs[%d]: expected S_FALSE, got %08x\n", i, r);
ok(!item2, "file_defs[%d]: item is not null\n", i);
}
if (item2) FolderItem_Release(item2);
VariantClear(&str_index2);
/* remove the directory */
ret = RemoveDirectoryA(file_defs[i].name);
ok(ret, "file_defs[%d]: RemoveDirectory failed: %08x\n", i, GetLastError());
}
else
{
ret = DeleteFileA(file_defs[i].name);
ok(ret, "file_defs[%d]: DeleteFile failed: %08x\n", i, GetLastError());
}
/* test that the folder item is still accessible by integer index */
item = NULL;
r = FolderItems_Item(items, int_index, &item);
ok(r == S_OK, "file_defs[%d]: FolderItems::Item failed: %08x\n", i, r);
ok(!!item, "file_defs[%d]: item is null\n", i);
bstr = NULL;
r = FolderItem_get_Path(item, &bstr);
ok(r == S_OK, "file_defs[%d]: FolderItem::get_Path failed: %08x\n", i, r);
PathCombineW(path, cur_dir, V_BSTR(&str_index));
ok(!lstrcmpW(bstr, path),
"file_defs[%d]: expected %s, got %s\n", i, wine_dbgstr_w(path), wine_dbgstr_w(bstr));
SysFreeString(bstr);
FolderItem_Release(item);
/* test that the folder item is no longer accessible by string index */
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, str_index, &item);
ok(r == S_FALSE, "file_defs[%d]: expected S_FALSE, got %08x\n", i, r);
ok(!item, "file_defs[%d]: item is not null\n", i);
VariantClear(&str_index);
}
/* test that there are only as many folder items as there were files */
V_I4(&int_index) = sizeof(file_defs)/sizeof(file_defs[0]);
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, int_index, &item);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r); ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(!item, "item is not null\n"); ok(!item, "item is not null\n");
@ -435,11 +743,13 @@ todo_wine
} }
r = FolderItems_get_Application(items, &disp); r = FolderItems_get_Application(items, &disp);
todo_wine
ok(r == S_OK, "FolderItems::get_Application failed: %08x\n", r); ok(r == S_OK, "FolderItems::get_Application failed: %08x\n", r);
todo_wine
ok(!!disp, "disp is null\n"); r = Folder_get_Application(folder, &disp2);
if (disp) IDispatch_Release(disp); ok(r == S_OK, "Failed to get application pointer, hr %#x.\n", r);
ok(disp == disp2, "Unexpected application pointer.\n");
IDispatch_Release(disp2);
IDispatch_Release(disp);
if (0) /* crashes on xp */ if (0) /* crashes on xp */
{ {
@ -483,14 +793,37 @@ todo_wine
ok(!verbs, "verbs is not null\n"); ok(!verbs, "verbs is not null\n");
} }
GetTempPathW(MAX_PATH, wstr); /* remove the temporary directory and restore the original working directory */
SetCurrentDirectoryW(wstr); GetTempPathW(MAX_PATH, path);
RemoveDirectoryW(winetestW); SetCurrentDirectoryW(path);
ret = RemoveDirectoryW(winetestW);
ok(ret, "RemoveDirectory failed: %08x\n", GetLastError());
SetCurrentDirectoryW(orig_dir); SetCurrentDirectoryW(orig_dir);
/* test that everything stops working after the directory has been removed */
count = -1;
r = FolderItems_get_Count(items, &count);
ok(r == S_OK, "FolderItems::get_Count failed: %08x\n", r);
ok(!count, "expected 0 files, got %d\n", count);
item = NULL;
V_I4(&int_index) = 0;
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, int_index, &item);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(!item, "item is not null\n");
variant_set_string(&str_index, file_defs[0].name);
item = (FolderItem*)0xdeadbeef;
r = FolderItems_Item(items, str_index, &item);
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(!item, "item is not null\n");
VariantClear(&str_index);
FolderItems_Release(items); FolderItems_Release(items);
if (items2) FolderItems2_Release(items2); Folder_Release(folder);
if (items3) FolderItems3_Release(items3); if (items3) FolderItems3_Release(items3);
IShellDispatch_Release(sd);
} }
static void test_service(void) static void test_service(void)
@ -739,7 +1072,7 @@ todo_wine {
ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr); ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr);
if (hr == S_FALSE) /* winxp and earlier */ { if (hr == S_FALSE) /* winxp and earlier */ {
win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n"); win_skip("SWC_DESKTOP is not supported, some tests will be skipped.\n");
/* older versions allowed to regiser SWC_DESKTOP and access it with FindWindowSW */ /* older versions allowed to register SWC_DESKTOP and access it with FindWindowSW */
ok(disp == NULL, "got %p\n", disp); ok(disp == NULL, "got %p\n", disp);
ok(ret == 0, "got %d\n", ret); ok(ret == 0, "got %d\n", ret);
} }
@ -763,6 +1096,9 @@ todo_wine {
IUnknown *unk; IUnknown *unk;
ok(disp != NULL, "got %p\n", disp); ok(disp != NULL, "got %p\n", disp);
if (disp == NULL) goto skip_disp_tests;
ok(ret != HandleToUlong(hwnd), "got %d\n", ret); ok(ret != HandleToUlong(hwnd), "got %d\n", ret);
/* IDispatch-related tests */ /* IDispatch-related tests */
@ -840,6 +1176,7 @@ if (hr == S_OK) {
IServiceProvider_Release(sp); IServiceProvider_Release(sp);
IDispatch_Release(disp); IDispatch_Release(disp);
} }
skip_disp_tests:
disp = (void*)0xdeadbeef; disp = (void*)0xdeadbeef;
ret = 0xdead; ret = 0xdead;
@ -934,12 +1271,13 @@ static void test_ParseName(void)
static void test_Verbs(void) static void test_Verbs(void)
{ {
FolderItemVerbs *verbs; FolderItemVerbs *verbs, *verbs2;
WCHAR pathW[MAX_PATH]; WCHAR pathW[MAX_PATH];
FolderItemVerb *verb; FolderItemVerb *verb;
IShellDispatch *sd; IShellDispatch *sd;
FolderItem *item; FolderItem *item;
Folder2 *folder2; Folder2 *folder2;
IDispatch *disp;
Folder *folder; Folder *folder;
HRESULT hr; HRESULT hr;
LONG count, i; LONG count, i;
@ -972,6 +1310,21 @@ if (0) { /* crashes on some systems */
hr = FolderItem_Verbs(item, &verbs); hr = FolderItem_Verbs(item, &verbs);
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = FolderItem_Verbs(item, &verbs2);
ok(hr == S_OK, "got 0x%08x\n", hr);
ok(verbs2 != verbs, "Unexpected verbs pointer.\n");
FolderItemVerbs_Release(verbs2);
disp = (void *)0xdeadbeef;
hr = FolderItemVerbs_get_Application(verbs, &disp);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
ok(disp == NULL, "Unexpected application pointer.\n");
disp = (void *)0xdeadbeef;
hr = FolderItemVerbs_get_Parent(verbs, &disp);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
ok(disp == NULL, "Unexpected parent pointer %p.\n", disp);
if (0) { /* crashes on winxp/win2k3 */ if (0) { /* crashes on winxp/win2k3 */
hr = FolderItemVerbs_get_Count(verbs, NULL); hr = FolderItemVerbs_get_Count(verbs, NULL);
ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
@ -998,7 +1351,17 @@ if (0) { /* crashes on winxp/win2k3 */
ok(hr == S_OK, "got 0x%08x\n", hr); ok(hr == S_OK, "got 0x%08x\n", hr);
ok(str != NULL, "%d: name %s\n", i, wine_dbgstr_w(str)); ok(str != NULL, "%d: name %s\n", i, wine_dbgstr_w(str));
if (i == count) if (i == count)
ok(str[0] == 0, "%d: got teminating item %s\n", i, wine_dbgstr_w(str)); ok(str[0] == 0, "%d: got terminating item %s\n", i, wine_dbgstr_w(str));
disp = (void *)0xdeadbeef;
hr = FolderItemVerb_get_Parent(verb, &disp);
ok(hr == E_NOTIMPL, "got %#x.\n", hr);
ok(disp == NULL, "Unexpected parent pointer %p.\n", disp);
disp = (void *)0xdeadbeef;
hr = FolderItemVerb_get_Application(verb, &disp);
ok(hr == E_NOTIMPL, "got %#x.\n", hr);
ok(disp == NULL, "Unexpected parent pointer %p.\n", disp);
SysFreeString(str); SysFreeString(str);
FolderItemVerb_Release(verb); FolderItemVerb_Release(verb);
@ -1054,6 +1417,7 @@ static void test_ShellExecute(void)
ok(hr == S_OK, "ShellExecute failed: %08x\n", hr); ok(hr == S_OK, "ShellExecute failed: %08x\n", hr);
SysFreeString(name); SysFreeString(name);
IShellDispatch2_Release(sd);
} }
START_TEST(shelldispatch) START_TEST(shelldispatch)

View file

@ -19,7 +19,24 @@
* *
*/ */
#include "precomp.h" #define COBJMACROS
#include "initguid.h"
#include "windows.h"
#include "shlguid.h"
#include "shobjidl.h"
#include "shlobj.h"
#include "shellapi.h"
#include "commoncontrols.h"
#include "wine/heap.h"
#include "wine/test.h"
#include "shell32_test.h"
#ifdef __REACTOS__
#include <reactos/undocshell.h>
#endif
#ifndef SLDF_HAS_LOGO3ID #ifndef SLDF_HAS_LOGO3ID
# define SLDF_HAS_LOGO3ID 0x00000800 /* not available in the Vista SDK */ # define SLDF_HAS_LOGO3ID 0x00000800 /* not available in the Vista SDK */
@ -28,6 +45,7 @@
static void (WINAPI *pILFree)(LPITEMIDLIST); static void (WINAPI *pILFree)(LPITEMIDLIST);
static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST); static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
static HRESULT (WINAPI *pSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*); static HRESULT (WINAPI *pSHILCreateFromPath)(LPCWSTR, LPITEMIDLIST *,DWORD*);
static HRESULT (WINAPI *pSHGetFolderLocation)(HWND,INT,HANDLE,DWORD,PIDLIST_ABSOLUTE*);
static HRESULT (WINAPI *pSHDefExtractIconA)(LPCSTR, int, UINT, HICON*, HICON*, UINT); static HRESULT (WINAPI *pSHDefExtractIconA)(LPCSTR, int, UINT, HICON*, HICON*, UINT);
static HRESULT (WINAPI *pSHGetStockIconInfo)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *); static HRESULT (WINAPI *pSHGetStockIconInfo)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *);
static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD); static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD);
@ -71,12 +89,12 @@ static LPITEMIDLIST path_to_pidl(const char* path)
int len; int len;
len=MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0); len=MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
pathW=HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); pathW = heap_alloc(len * sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len); MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, len);
r=pSHILCreateFromPath(pathW, &pidl, NULL); r=pSHILCreateFromPath(pathW, &pidl, NULL);
ok(r == S_OK, "SHILCreateFromPath failed (0x%08x)\n", r); ok(r == S_OK, "SHILCreateFromPath failed (0x%08x)\n", r);
HeapFree(GetProcessHeap(), 0, pathW); heap_free(pathW);
} }
return pidl; return pidl;
} }
@ -93,6 +111,7 @@ static void test_get_set(void)
IShellLinkW *slW = NULL; IShellLinkW *slW = NULL;
char mypath[MAX_PATH]; char mypath[MAX_PATH];
char buffer[INFOTIPSIZE]; char buffer[INFOTIPSIZE];
WIN32_FIND_DATAA finddata;
LPITEMIDLIST pidl, tmp_pidl; LPITEMIDLIST pidl, tmp_pidl;
const char * str; const char * str;
int i; int i;
@ -145,11 +164,20 @@ static void test_get_set(void)
/* Test Getting / Setting the path */ /* Test Getting / Setting the path */
strcpy(buffer,"garbage"); strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH); r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
todo_wine ok(r == S_FALSE || broken(r == S_OK) /* NT4/W2K */, "GetPath failed (0x%08x)\n", r); ok(r == S_FALSE || broken(r == S_OK) /* NT4/W2K */, "GetPath failed (0x%08x)\n", r);
ok(*buffer=='\0', "GetPath returned '%s'\n", buffer); ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, strcpy(buffer,"garbage");
memset(&finddata, 0xaa, sizeof(finddata));
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), &finddata, SLGP_RAWPATH);
ok(r == S_FALSE || broken(r == S_OK) /* NT4/W2K */, "GetPath failed (0x%08x)\n", r);
ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
ok(finddata.dwFileAttributes == 0, "unexpected attributes %x\n", finddata.dwFileAttributes);
ok(finddata.cFileName[0] == 0, "unexpected filename '%s'\n", finddata.cFileName);
r = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellLinkW, (LPVOID*)&slW); &IID_IShellLinkW, (LPVOID*)&slW);
ok(r == S_OK, "CoCreateInstance failed (0x%08x)\n", r);
if (!slW /* Win9x */ || !pGetLongPathNameA /* NT4 */) if (!slW /* Win9x */ || !pGetLongPathNameA /* NT4 */)
skip("SetPath with NULL parameter crashes on Win9x and some NT4\n"); skip("SetPath with NULL parameter crashes on Win9x and some NT4\n");
else else
@ -166,7 +194,7 @@ static void test_get_set(void)
strcpy(buffer,"garbage"); strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH); r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
todo_wine ok(r == S_FALSE, "GetPath failed (0x%08x)\n", r); ok(r == S_FALSE, "GetPath failed (0x%08x)\n", r);
ok(*buffer=='\0', "GetPath returned '%s'\n", buffer); ok(*buffer=='\0', "GetPath returned '%s'\n", buffer);
/* Win98 returns S_FALSE, but WinXP returns S_OK */ /* Win98 returns S_FALSE, but WinXP returns S_OK */
@ -179,6 +207,14 @@ static void test_get_set(void)
ok(r == S_OK, "GetPath failed (0x%08x)\n", r); ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
ok(lstrcmpiA(buffer,str)==0, "GetPath returned '%s'\n", buffer); ok(lstrcmpiA(buffer,str)==0, "GetPath returned '%s'\n", buffer);
strcpy(buffer,"garbage");
memset(&finddata, 0xaa, sizeof(finddata));
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), &finddata, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
ok(lstrcmpiA(buffer,str)==0, "GetPath returned '%s'\n", buffer);
ok(finddata.dwFileAttributes == 0, "unexpected attributes %x\n", finddata.dwFileAttributes);
ok(lstrcmpiA(finddata.cFileName, "file") == 0, "unexpected filename '%s'\n", finddata.cFileName);
/* Get some real path to play with */ /* Get some real path to play with */
GetWindowsDirectoryA( mypath, sizeof(mypath)-12 ); GetWindowsDirectoryA( mypath, sizeof(mypath)-12 );
strcat(mypath, "\\regedit.exe"); strcat(mypath, "\\regedit.exe");
@ -228,8 +264,41 @@ static void test_get_set(void)
strcpy(buffer,"garbage"); strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH); r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r); ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
todo_wine
ok(lstrcmpiA(buffer, mypath)==0, "GetPath returned '%s'\n", buffer); ok(lstrcmpiA(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
strcpy(buffer,"garbage");
memset(&finddata, 0xaa, sizeof(finddata));
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), &finddata, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
ok(lstrcmpiA(buffer, mypath)==0, "GetPath returned '%s'\n", buffer);
ok(finddata.dwFileAttributes != 0, "unexpected attributes %x\n", finddata.dwFileAttributes);
ok(lstrcmpiA(finddata.cFileName, "regedit.exe") == 0, "unexpected filename '%s'\n", finddata.cFileName);
}
if (pSHGetFolderLocation)
{
LPITEMIDLIST pidl_controls;
r = pSHGetFolderLocation(NULL, CSIDL_CONTROLS, NULL, 0, &pidl_controls);
ok(r == S_OK, "SHGetFolderLocation failed (0x%08x)\n", r);
r = IShellLinkA_SetIDList(sl, pidl_controls);
ok(r == S_OK, "SetIDList failed (0x%08x)\n", r);
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r == S_FALSE, "GetPath failed (0x%08x)\n", r);
ok(buffer[0] == 0, "GetPath returned '%s'\n", buffer);
strcpy(buffer,"garbage");
memset(&finddata, 0xaa, sizeof(finddata));
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), &finddata, SLGP_RAWPATH);
ok(r == S_FALSE, "GetPath failed (0x%08x)\n", r);
ok(buffer[0] == 0, "GetPath returned '%s'\n", buffer);
ok(finddata.dwFileAttributes == 0, "unexpected attributes %x\n", finddata.dwFileAttributes);
ok(finddata.cFileName[0] == 0, "unexpected filename '%s'\n", finddata.cFileName);
pILFree(pidl_controls);
} }
/* test path with quotes (IShellLinkA_SetPath returns S_FALSE on W2K and below and S_OK on XP and above */ /* test path with quotes (IShellLinkA_SetPath returns S_FALSE on W2K and below and S_OK on XP and above */
@ -1396,6 +1465,7 @@ START_TEST(shelllink)
pILFree = (void *)GetProcAddress(hmod, (LPSTR)155); pILFree = (void *)GetProcAddress(hmod, (LPSTR)155);
pILIsEqual = (void *)GetProcAddress(hmod, (LPSTR)21); pILIsEqual = (void *)GetProcAddress(hmod, (LPSTR)21);
pSHILCreateFromPath = (void *)GetProcAddress(hmod, (LPSTR)28); pSHILCreateFromPath = (void *)GetProcAddress(hmod, (LPSTR)28);
pSHGetFolderLocation = (void *)GetProcAddress(hmod, "SHGetFolderLocation");
pSHDefExtractIconA = (void *)GetProcAddress(hmod, "SHDefExtractIconA"); pSHDefExtractIconA = (void *)GetProcAddress(hmod, "SHDefExtractIconA");
pSHGetStockIconInfo = (void *)GetProcAddress(hmod, "SHGetStockIconInfo"); pSHGetStockIconInfo = (void *)GetProcAddress(hmod, "SHGetStockIconInfo");
pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA"); pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA");

View file

@ -16,9 +16,19 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #define COBJMACROS
#define CONST_VTABLE
#ifndef __REACTOS__
#define NONAMELESSUNION
#endif
#include <initguid.h> #include <stdio.h>
#include <wine/test.h>
#include "winbase.h"
#include "shlobj.h"
#include "shellapi.h"
#include "initguid.h"
DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12); DEFINE_GUID(FMTID_Test,0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12);
DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13); DEFINE_GUID(FMTID_NotExisting, 0x12345678,0x1234,0x1234,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x13);

View file

@ -21,9 +21,20 @@
* namespace) path for a given folder (CSIDL value). * namespace) path for a given folder (CSIDL value).
*/ */
#include "precomp.h" #define COBJMACROS
#include <initguid.h> #include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "shlguid.h"
#include "shlobj.h"
#include "shlwapi.h"
#include "knownfolders.h"
#include "shellapi.h"
#include "wine/test.h"
#include "initguid.h"
/* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want /* CSIDL_MYDOCUMENTS is now the same as CSIDL_PERSONAL, but what we want
* here is its original value. * here is its original value.
@ -1887,7 +1898,7 @@ static const struct knownFolderDef known_folders[] = {
{ 0 } { 0 }
}; };
#undef KNOWN_FOLDER #undef KNOWN_FOLDER
BOOL known_folder_found[sizeof(known_folders)/sizeof(known_folders[0])-1]; BOOL known_folder_found[ARRAY_SIZE(known_folders)-1];
static BOOL is_in_strarray(const WCHAR *needle, const char *hay) static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
{ {
@ -1903,7 +1914,7 @@ static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
if(strcmp(hay, "(null)") == 0 && !needle) if(strcmp(hay, "(null)") == 0 && !needle)
return TRUE; return TRUE;
ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, sizeof(wstr)/sizeof(wstr[0])); ret = MultiByteToWideChar(CP_ACP, 0, hay, -1, wstr, ARRAY_SIZE(wstr));
if(ret == 0) if(ret == 0)
{ {
ok(0, "Failed to convert string\n"); ok(0, "Failed to convert string\n");
@ -1956,7 +1967,7 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId); ok_(__FILE__, known_folder->line)(hr == S_OK, "cannot get known folder definition for %s\n", known_folder->sFolderId);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{ {
ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1, sName, sizeof(sName)/sizeof(sName[0])); ret = MultiByteToWideChar(CP_ACP, 0, known_folder->sName, -1, sName, ARRAY_SIZE(sName));
ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName); ok_(__FILE__, known_folder->line)(ret != 0, "cannot convert known folder name \"%s\" to wide characters\n", known_folder->sName);
ok_(__FILE__, known_folder->line)(lstrcmpW(kfd.pszName, sName)==0, "invalid known folder name returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(sName), wine_dbgstr_w(kfd.pszName)); ok_(__FILE__, known_folder->line)(lstrcmpW(kfd.pszName, sName)==0, "invalid known folder name returned for %s: %s expected, but %s retrieved\n", known_folder->sFolderId, wine_dbgstr_w(sName), wine_dbgstr_w(kfd.pszName));
@ -2052,10 +2063,10 @@ static void test_knownFolders(void)
GetWindowsDirectoryW( sWinDir, MAX_PATH ); GetWindowsDirectoryW( sWinDir, MAX_PATH );
GetTempPathW(sizeof(sExamplePath)/sizeof(sExamplePath[0]), sExamplePath); GetTempPathW(ARRAY_SIZE(sExamplePath), sExamplePath);
lstrcatW(sExamplePath, sExample); lstrcatW(sExamplePath, sExample);
GetTempPathW(sizeof(sExample2Path)/sizeof(sExample2Path[0]), sExample2Path); GetTempPathW(ARRAY_SIZE(sExample2Path), sExample2Path);
lstrcatW(sExample2Path, sExample2); lstrcatW(sExample2Path, sExample2);
lstrcpyW(sSubFolderPath, sExamplePath); lstrcpyW(sSubFolderPath, sExamplePath);
@ -2110,7 +2121,6 @@ static void test_knownFolders(void)
CoTaskMemFree(folderPath); CoTaskMemFree(folderPath);
hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities); hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities);
todo_wine
ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr); ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr);
todo_wine todo_wine
ok(redirectionCapabilities==0, "invalid redirection capabilities returned: %d\n", redirectionCapabilities); ok(redirectionCapabilities==0, "invalid redirection capabilities returned: %d\n", redirectionCapabilities);
@ -2162,7 +2172,7 @@ static void test_knownFolders(void)
ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr); ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
ok(folder == NULL, "got %p\n", folder); ok(folder == NULL, "got %p\n", folder);
for(i=0; i<sizeof(known_folder_found)/sizeof(known_folder_found[0]); ++i) for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
known_folder_found[i] = FALSE; known_folder_found[i] = FALSE;
hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount); hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount);
@ -2170,7 +2180,7 @@ static void test_knownFolders(void)
for(i=0;i<nCount;++i) for(i=0;i<nCount;++i)
check_known_folder(mgr, &folders[i]); check_known_folder(mgr, &folders[i]);
for(i=0; i<sizeof(known_folder_found)/sizeof(known_folder_found[0]); ++i) for(i=0; i < ARRAY_SIZE(known_folder_found); ++i)
if(!known_folder_found[i]) if(!known_folder_found[i])
trace("Known folder %s not found on current platform\n", known_folders[i].sFolderId); trace("Known folder %s not found on current platform\n", known_folders[i].sFolderId);
@ -2544,7 +2554,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1); memset(bufferA, '#', MAX_PATH - 1);
bufferA[MAX_PATH - 1] = 0; bufferA[MAX_PATH - 1] = 0;
lstrcpyA(bufferA, names[i]); lstrcpyA(bufferA, names[i]);
MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, sizeof(bufferW)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
res2 = ExpandEnvironmentStringsA(names[i], expectedA, MAX_PATH); res2 = ExpandEnvironmentStringsA(names[i], expectedA, MAX_PATH);
res = DoEnvironmentSubstA(bufferA, MAX_PATH); res = DoEnvironmentSubstA(bufferA, MAX_PATH);
@ -2575,7 +2585,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1); memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0; bufferA[len + 2] = 0;
lstrcpyA(bufferA, names[i]); lstrcpyA(bufferA, names[i]);
MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, sizeof(bufferW)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
res2 = ExpandEnvironmentStringsA(bufferA, expectedA, MAX_PATH); res2 = ExpandEnvironmentStringsA(bufferA, expectedA, MAX_PATH);
res = DoEnvironmentSubstA(bufferA, len + 1); res = DoEnvironmentSubstA(bufferA, len + 1);
@ -2596,7 +2606,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1); memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0; bufferA[len + 2] = 0;
lstrcpyA(bufferA, names[i]); lstrcpyA(bufferA, names[i]);
MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, sizeof(bufferW)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
/* ANSI version failed without an extra byte, as documented on msdn */ /* ANSI version failed without an extra byte, as documented on msdn */
res = DoEnvironmentSubstA(bufferA, len); res = DoEnvironmentSubstA(bufferA, len);
@ -2619,7 +2629,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1); memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0; bufferA[len + 2] = 0;
lstrcpyA(bufferA, names[i]); lstrcpyA(bufferA, names[i]);
MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, sizeof(bufferW)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
res = DoEnvironmentSubstA(bufferA, len - 1); res = DoEnvironmentSubstA(bufferA, len - 1);
ok(!HIWORD(res) && (LOWORD(res) == (len - 1)), ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
@ -2640,7 +2650,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1); memset(bufferA, '#', MAX_PATH - 1);
bufferA[MAX_PATH - 1] = 0; bufferA[MAX_PATH - 1] = 0;
lstrcpyA(bufferA, does_not_existA); lstrcpyA(bufferA, does_not_existA);
MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, sizeof(bufferW)/sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, bufferA, MAX_PATH, bufferW, ARRAY_SIZE(bufferW));
res2 = lstrlenA(does_not_existA) + 1; res2 = lstrlenA(does_not_existA) + 1;
res = DoEnvironmentSubstA(bufferA, MAX_PATH); res = DoEnvironmentSubstA(bufferA, MAX_PATH);
@ -2691,7 +2701,7 @@ if (0)
ok(!ret, "got %d\n", ret); ok(!ret, "got %d\n", ret);
} }
GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW); GetTempPathW(ARRAY_SIZE(pathW), pathW);
/* Using short name only first */ /* Using short name only first */
nameW[0] = 0; nameW[0] = 0;

View file

@ -19,7 +19,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#ifndef __REACTOS__
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "shellapi.h"
#include "shlobj.h"
#include "wine/test.h"
static inline BOOL SHELL_OsIsUnicode(void) static inline BOOL SHELL_OsIsUnicode(void)
{ {

View file

@ -30,7 +30,28 @@
* we could check * we could check
*/ */
#include "precomp.h" /* Needed to get SEE_MASK_NOZONECHECKS with the PSDK */
#ifndef __REACTOS__
#define NTDDI_WINXPSP1 0x05010100
#define NTDDI_VERSION NTDDI_WINXPSP1
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <assert.h>
#include "wtypes.h"
#include "winbase.h"
#include "windef.h"
#include "shellapi.h"
#include "shlwapi.h"
#include "ddeml.h"
#include "wine/heap.h"
#include "wine/test.h"
#include "shell32_test.h"
static char argv0[MAX_PATH]; static char argv0[MAX_PATH];
static int myARGC; static int myARGC;
@ -742,7 +763,7 @@ static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR)) if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
{ {
/* Name too big: alloc a buffer for it */ /* Name too big: alloc a buffer for it */
if (!(lpszName = HeapAlloc( GetProcessHeap(), 0, dwMaxLen*sizeof(CHAR)))) if (!(lpszName = heap_alloc(dwMaxLen*sizeof(CHAR))))
{ {
ret = ERROR_NOT_ENOUGH_MEMORY; ret = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup; goto cleanup;
@ -777,7 +798,7 @@ static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
cleanup: cleanup:
/* Free buffer if allocated */ /* Free buffer if allocated */
if (lpszName != szNameBuf) if (lpszName != szNameBuf)
HeapFree( GetProcessHeap(), 0, lpszName); heap_free(lpszName);
if(lpszSubKey) if(lpszSubKey)
RegCloseKey(hSubKey); RegCloseKey(hSubKey);
return ret; return ret;
@ -837,11 +858,11 @@ static void create_test_verb_dde(const char* classname, const char* verb,
} }
else else
{ {
cmd=HeapAlloc(GetProcessHeap(), 0, strlen(argv0)+10+strlen(child_file)+2+strlen(cmdtail)+1); cmd = heap_alloc(strlen(argv0) + 10 + strlen(child_file) + 2 + strlen(cmdtail) + 1);
sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail); sprintf(cmd,"%s shlexec \"%s\" %s", argv0, child_file, cmdtail);
rc=RegSetValueExA(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1); rc=RegSetValueExA(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1);
ok(rc == ERROR_SUCCESS, "setting command failed with %d\n", rc); ok(rc == ERROR_SUCCESS, "setting command failed with %d\n", rc);
HeapFree(GetProcessHeap(), 0, cmd); heap_free(cmd);
} }
if (ddeexec) if (ddeexec)

View file

@ -18,7 +18,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#define WINE_NOWINSOCK
#include <windows.h>
#include "shellapi.h"
#include "shlobj.h"
#include "commoncontrols.h"
#include "wine/test.h"
#ifdef __REACTOS__
#include <reactos/undocshell.h>
#endif
#ifndef FOF_NORECURSION #ifndef FOF_NORECURSION
#define FOF_NORECURSION 0x1000 #define FOF_NORECURSION 0x1000

File diff suppressed because it is too large Load diff

View file

@ -18,10 +18,35 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#define CONST_VTABLE
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "shellapi.h"
#include "shlguid.h"
#include "shlobj.h"
#include "shobjidl.h"
#include "shlwapi.h"
#include "ocidl.h"
#include "oleauto.h"
#include "initguid.h"
#include "wine/heap.h"
#include "wine/test.h"
#include "msg.h" #include "msg.h"
#ifdef __REACTOS__
#include <reactos/undocshell.h>
#endif
#define LISTVIEW_SEQ_INDEX 0 #define LISTVIEW_SEQ_INDEX 0
#define NUM_MSG_SEQUENCES 1 #define NUM_MSG_SEQUENCES 1
@ -129,7 +154,7 @@ static IDataObject* IDataObjectImpl_Construct(void)
{ {
IDataObjectImpl *obj; IDataObjectImpl *obj;
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj)); obj = heap_alloc(sizeof(*obj));
obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl; obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl;
obj->ref = 1; obj->ref = 1;
@ -143,7 +168,7 @@ static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID
if (IsEqualIID(riid, &IID_IUnknown) || if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDataObject)) IsEqualIID(riid, &IID_IDataObject))
{ {
*ppvObj = This; *ppvObj = &This->IDataObject_iface;
} }
if(*ppvObj) if(*ppvObj)
@ -167,10 +192,8 @@ static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
if (!ref) if (!ref)
{ heap_free(This);
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
return ref; return ref;
} }
@ -256,7 +279,7 @@ static IShellBrowser* IShellBrowserImpl_Construct(void)
{ {
IShellBrowserImpl *browser; IShellBrowserImpl *browser;
browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser)); browser = heap_alloc(sizeof(*browser));
browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl; browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
browser->ref = 1; browser->ref = 1;
@ -275,7 +298,7 @@ static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
IsEqualIID(riid, &IID_IOleWindow) || IsEqualIID(riid, &IID_IOleWindow) ||
IsEqualIID(riid, &IID_IShellBrowser)) IsEqualIID(riid, &IID_IShellBrowser))
{ {
*ppvObj = This; *ppvObj = &This->IShellBrowser_iface;
} }
if(*ppvObj) if(*ppvObj)
@ -299,10 +322,8 @@ static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
ULONG ref = InterlockedDecrement(&This->ref); ULONG ref = InterlockedDecrement(&This->ref);
if (!ref) if (!ref)
{ heap_free(This);
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
return ref; return ref;
} }
@ -1456,6 +1477,35 @@ if (0)
IShellFolder_Release(desktop); IShellFolder_Release(desktop);
} }
static void test_newmenu(void)
{
IUnknown *unk, *unk2;
HRESULT hr;
hr = CoCreateInstance(&CLSID_NewMenu, NULL, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
todo_wine
ok(hr == S_OK, "Failed to create NewMenu object, hr %#x.\n", hr);
if (hr != S_OK)
{
skip("NewMenu is not supported.\n");
return;
}
hr = IUnknown_QueryInterface(unk, &IID_IShellExtInit, (void **)&unk2);
ok(hr == S_OK, "Failed to get IShellExtInit, hr %#x.\n", hr);
IUnknown_Release(unk2);
hr = IUnknown_QueryInterface(unk, &IID_IContextMenu3, (void **)&unk2);
ok(hr == S_OK, "Failed to get IContextMenu3, hr %#x.\n", hr);
IUnknown_Release(unk2);
hr = IUnknown_QueryInterface(unk, &IID_IObjectWithSite, (void **)&unk2);
ok(hr == S_OK, "Failed to get IObjectWithSite, hr %#x.\n", hr);
IUnknown_Release(unk2);
IUnknown_Release(unk);
}
START_TEST(shlview) START_TEST(shlview)
{ {
OleInitialize(NULL); OleInitialize(NULL);
@ -1471,6 +1521,7 @@ START_TEST(shlview)
test_IOleCommandTarget(); test_IOleCommandTarget();
test_SHCreateShellFolderView(); test_SHCreateShellFolderView();
test_SHCreateShellFolderViewEx(); test_SHCreateShellFolderViewEx();
test_newmenu();
OleUninitialize(); OleUninitialize();
} }

View file

@ -18,7 +18,18 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #include <stdarg.h>
#include <stdio.h>
#define WINE_NOWINSOCK
#include "windef.h"
#include "winbase.h"
#include "wtypes.h"
#include "shellapi.h"
#include "shtypes.h"
#include "objbase.h"
#include "wine/test.h"
static HMODULE hShell32; static HMODULE hShell32;
static BOOL (WINAPI *pStrRetToStrNAW)(LPVOID,DWORD,LPSTRRET,const ITEMIDLIST *); static BOOL (WINAPI *pStrRetToStrNAW)(LPVOID,DWORD,LPSTRRET,const ITEMIDLIST *);

View file

@ -17,7 +17,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "precomp.h" #ifndef __REACTOS__
#define _WIN32_IE 0x600
#endif
#include <stdarg.h>
#include <windows.h>
#include "shellapi.h"
#include "wine/test.h"
static HWND hMainWnd; static HWND hMainWnd;
static BOOL (WINAPI *pShell_NotifyIconW)(DWORD,PNOTIFYICONDATAW); static BOOL (WINAPI *pShell_NotifyIconW)(DWORD,PNOTIFYICONDATAW);