[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)
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)
add_importlibs(shell32_winetest ntdll)

View file

@ -17,7 +17,12 @@
* 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

View file

@ -17,9 +17,17 @@
* 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)
{
@ -114,7 +122,7 @@ static void getstring_test(LPCWSTR assocName, HKEY progIdKey, ASSOCSTR str, LPCW
return;
}
buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
buffer = heap_alloc(len * sizeof(WCHAR));
ok_(__FILE__, line)(buffer != NULL, "out of memory\n");
hr = IQueryAssociations_GetString(assoc, 0, str, NULL, buffer, &len);
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);
HeapFree(GetProcessHeap(), 0, buffer);
heap_free(buffer);
}
static void test_IQueryAssociations_GetString(void)

View file

@ -18,7 +18,18 @@
* 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 HINSTANCE hinst;
@ -216,6 +227,171 @@ static void createMainWnd(void)
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)
{
HRESULT r;
@ -237,6 +413,8 @@ START_TEST(autocomplete)
goto cleanup;
test_killfocus();
test_custom_source();
PostQuitMessage(0);
while(GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);

View file

@ -19,8 +19,15 @@
* 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 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
*/
#include "precomp.h"
#include <stdio.h>
#include <initguid.h>
#include <mshtml.h>
#define COBJMACROS
#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.
@ -231,7 +240,7 @@ static ULONG WINAPI IExplorerPaneVisibility_fnRelease(IExplorerPaneVisibility *i
ULONG ref = InterlockedDecrement(&This->ref);
if(!ref)
HeapFree(GetProcessHeap(), 0, This);
heap_free(This);
return ref;
}
@ -277,7 +286,7 @@ static IExplorerPaneVisibilityImpl *create_explorerpanevisibility(void)
{
IExplorerPaneVisibilityImpl *epv;
epv = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IExplorerPaneVisibilityImpl));
epv = heap_alloc_zero(sizeof(*epv));
epv->IExplorerPaneVisibility_iface.lpVtbl = &epvvt;
epv->ref = 1;
@ -320,7 +329,7 @@ static ULONG WINAPI ICommDlgBrowser3_fnRelease(ICommDlgBrowser3 *iface)
ULONG ref = InterlockedDecrement(&This->ref);
if(!ref)
HeapFree(GetProcessHeap(), 0, This);
heap_free(This);
return ref;
}
@ -431,7 +440,7 @@ static ICommDlgBrowser3Impl *create_commdlgbrowser3(void)
{
ICommDlgBrowser3Impl *cdb;
cdb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ICommDlgBrowser3Impl));
cdb = heap_alloc_zero(sizeof(*cdb));
cdb->ICommDlgBrowser3_iface.lpVtbl = &cdbvtbl;
cdb->ref = 1;
@ -489,7 +498,7 @@ static ULONG WINAPI IServiceProvider_fnRelease(IServiceProvider *iface)
LONG ref = InterlockedDecrement(&This->ref);
if(!ref)
HeapFree(GetProcessHeap(), 0, This);
heap_free(This);
return ref;
}
@ -540,7 +549,7 @@ static const IServiceProviderVtbl spvtbl =
static IServiceProviderImpl *create_serviceprovider(void)
{
IServiceProviderImpl *sp = HeapAlloc(GetProcessHeap(), 0, sizeof(IServiceProviderImpl));
IServiceProviderImpl *sp = heap_alloc(sizeof(*sp));
sp->IServiceProvider_iface.lpVtbl = &spvtbl;
sp->ref = 1;
return sp;

View file

@ -5,7 +5,24 @@
* 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

View file

@ -20,6 +20,12 @@
#pragma once
#include <assert.h>
#include <windows.h>
#include "wine/heap.h"
#include "wine/test.h"
/* undocumented SWP flags - from SDK 3.1 */
#define SWP_NOCLIENTSIZE 0x0800
#define SWP_NOCLIENTMOVE 0x1000
@ -64,16 +70,13 @@ static void add_message(struct msg_sequence **seq, int sequence_index,
if (!msg_seq->sequence)
{
msg_seq->size = 10;
msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0,
msg_seq->size * sizeof (struct message));
msg_seq->sequence = heap_alloc(msg_seq->size * sizeof (struct message));
}
if (msg_seq->count == msg_seq->size)
{
msg_seq->size *= 2;
msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0,
msg_seq->sequence,
msg_seq->size * sizeof (struct message));
msg_seq->sequence = heap_realloc(msg_seq->sequence, msg_seq->size * sizeof (struct message));
}
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)
{
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->count = msg_seq->size = 0;
}
@ -288,5 +291,5 @@ static void init_msg_sequences(struct msg_sequence **seq, int n)
int 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_
#define _SHELL32_WINETEST_PRECOMP_H_
@ -5,23 +6,19 @@
#include <stdio.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
#define COM_NO_WINDOWS_H
#define COBJMACROS
#define CONST_VTABLE
#include <windows.h>
#include <wine/heap.h>
#include <wine/test.h>
#include <winreg.h>
#include <winnls.h>
#include <winuser.h>
#include <wincon.h>
#include <shellapi.h>
#include <shlwapi.h>
#include <shlguid.h>
#include <shlobj.h>
#include <ddeml.h>
#include <commoncontrols.h>
#include <reactos/undocshell.h>

View file

@ -26,30 +26,15 @@
* Tests for Invalid Characters in Names / Invalid Parameters
*/
#include "precomp.h"
/* Timeout on DdeClientTransaction Call */
#define MS_TIMEOUT_VAL 1000
/* # of times to poll for window creation */
#define PDDE_POLL_NUM 150
/* time to sleep between polls */
#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
#include <stdio.h>
#include <wine/test.h>
#include <winbase.h>
#include "dde.h"
#include "ddeml.h"
#include "winuser.h"
#include "shlobj.h"
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)
{
@ -57,10 +42,6 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("shell32.dll");
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)
@ -101,63 +82,20 @@ static BOOL full_title(void)
CABINETSTATE cs;
memset(&cs, 0, sizeof(cs));
if (pReadCabinetState)
{
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);
}
ReadCabinetState(&cs, sizeof(cs));
return (cs.fFullPathTitle == -1);
}
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)
{
char startup[MAX_PATH];
char commonprograms[MAX_PATH];
char programs[MAX_PATH];
if (pSHGetSpecialFolderPathA)
{
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);
}
SHGetSpecialFolderPathA(NULL, programs, CSIDL_PROGRAMS, FALSE);
SHGetSpecialFolderPathA(NULL, commonprograms, CSIDL_COMMON_PROGRAMS, FALSE);
/* 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
@ -167,55 +105,6 @@ static void init_strings(void)
lstrcpyA(ProgramsDir, commonprograms);
else
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,
@ -225,472 +114,305 @@ static HDDEDATA CALLBACK DdeCallback(UINT type, UINT format, HCONV hConv, HSZ hs
return NULL;
}
/*
* 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)
static UINT dde_execute(DWORD instance, HCONV hconv, const char *command_str)
{
int testNum;
static char testParamString[64];
const char *callId;
HDDEDATA command, hdata;
DWORD result;
UINT ret;
testNum = testParams & DDE_TEST_NUMMASK;
switch (testParams & DDE_TEST_CALLMASK)
{
default:
case DDE_TEST_MISC:
callId = "MISC";
break;
case DDE_TEST_CREATEGROUP:
callId = "C_G";
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;
}
command = DdeCreateDataHandle(instance, (BYTE *)command_str, strlen(command_str)+1, 0, 0, 0, 0);
ok(command != NULL, "DdeCreateDataHandle() failed: %u\n", DdeGetLastError(instance));
sprintf(testParamString, " [%s:%i]", callId, testNum);
return testParamString;
hdata = DdeClientTransaction((BYTE *)command, -1, hconv, 0, 0, XTYP_EXECUTE, 2000, &result);
ret = DdeGetLastError(instance);
/* PROGMAN always returns 1 on success */
ok((UINT_PTR)hdata == !ret, "expected %u, got %p\n", !ret, hdata);
return ret;
}
/* Transfer DMLERR's into text readable strings for Error Messages */
#define DMLERR_TO_STR(x) case x: return#x;
static const char * GetStringFromError(UINT err)
static char *dde_request(DWORD instance, HCONV hconv, const char *request_str)
{
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";
}
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;
}
/* 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)
static BOOL check_window_exists(const char *name)
{
char title[MAX_PATH];
HWND window = NULL;
int i;
/* Poll for Window Creation */
for (i = 0; window == NULL && i < PDDE_POLL_NUM; i++)
if (full_title())
{
Sleep(PDDE_POLL_TIME);
/* Specify the window class name to make sure what we find is really an
* Explorer window. Explorer used two different window classes so try
* both.
*/
window = FindWindowA("ExplorerWClass", winName);
if (!window)
window = FindWindowA("CabinetWClass", winName);
strcpy(title, ProgramsDir);
strcat(title, "\\");
strcat(title, name);
}
ok (window != NULL, "Window \"%s\" was not created in %i seconds - assumed failure.%s\n",
winName, PDDE_POLL_NUM*PDDE_POLL_TIME/1000, GetStringFromTestParams(testParams));
else
strcpy(title, name);
/* Close Window as desired. */
if (window != NULL && closeWindow)
for (i = 0; i < 20; i++)
{
Sleep(100);
if ((window = FindWindowA("ExplorerWClass", title)) ||
(window = FindWindowA("CabinetWClass", title)))
{
SendMessageA(window, WM_SYSCOMMAND, SC_CLOSE, 0);
window = NULL;
break;
}
return window;
}
return (window != NULL);
}
/* Check for Existence (or non-existence) of a file or group
* When testing for existence of a group, groupName is not needed
*/
static void CheckFileExistsInProgramGroups(const char *nameToCheck, BOOL shouldExist, BOOL isGroup,
const char *groupName, int testParams)
static BOOL check_exists(const char *name)
{
char path[MAX_PATH];
DWORD attributes;
int len;
lstrcpyA(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)
{
strcpy(path, ProgramsDir);
strcat(path, "\\");
strcat(path, groupName);
}
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));
}
}
}
strcat(path, name);
return GetFileAttributesA(path) != INVALID_FILE_ATTRIBUTES;
}
/* Create Group Test.
* 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)
static void test_parser(DWORD instance, HCONV hConv)
{
HDDEDATA hData;
UINT error;
/* Execute Command & Check Result */
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
todo_wine
{
ok (expected_result == error, "CreateGroup %s: Expected Error %s, received %s.%s\n",
groupName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
/* Invalid Command */
error = dde_execute(instance, hConv, "[InvalidCommand()]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* No Error */
if (error == DMLERR_NO_ERROR)
{
/* test parsing */
error = dde_execute(instance, hConv, "");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Check if Group Now Exists */
CheckFileExistsInProgramGroups(groupName, TRUE, TRUE, NULL, testParams);
/* Check if Window is Open (polling) */
CheckWindowCreated(windowTitle, TRUE, testParams);
}
}
error = dde_execute(instance, hConv, "CreateGroup");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Show Group Test.
* DDE command, expected_result, and the group name to check for existence
* 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;
error = dde_execute(instance, hConv, "[CreateGroup");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
/* todo_wine... Is expected to fail, wine stubbed functions DO fail */
/* 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));
error = dde_execute(instance, hConv, "[CreateGroup]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
if (error == DMLERR_NO_ERROR)
{
/* Check if Window is Open (polling) */
hwnd = CheckWindowCreated(windowTitle, closeAfterShowing, testParams);
}
return hwnd;
}
error = dde_execute(instance, hConv, "[CreateGroup()]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Delete Group Test.
* DDE command, expected_result, and the group name to check for existence
* if expected_result is DMLERR_NO_ERROR, test
* 1. group does not exist
*/
static void DeleteGroupTest(DWORD instance, HCONV hConv, const char *command, UINT expected_result,
const char *groupName, int testParams)
{
HDDEDATA hData;
UINT error;
error = dde_execute(instance, hConv, "[cREATEgROUP(test)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("test"), "directory not created\n");
ok(check_window_exists("test"), "window not created\n");
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
todo_wine
{
ok (expected_result == error, "DeleteGroup %s: Expected Error %s, received %s.%s\n",
groupName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
error = dde_execute(instance, hConv, "[AddItem(notepad,foobar)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("test/foobar.lnk"), "link not created\n");
if (error == DMLERR_NO_ERROR)
{
/* Check that Group does not exist */
CheckFileExistsInProgramGroups(groupName, FALSE, TRUE, NULL, testParams);
}
}
error = dde_execute(instance, hConv, "[AddItem(notepad,foo bar)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("test/foo bar.lnk"), "link not created\n");
/* Add Item Test
* DDE command, expected result, and group and file name where it should exist.
* 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;
error = dde_execute(instance, hConv, "[AddItem(notepad,a[b,c]d)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
todo_wine
{
ok (expected_result == error, "AddItem %s: Expected Error %s, received %s.%s\n",
fileName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
error = dde_execute(instance, hConv, "[AddItem(notepad,\"a[b,c]d\")]");
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");
if (error == DMLERR_NO_ERROR)
{
/* Check that File exists */
CheckFileExistsInProgramGroups(fileName, TRUE, FALSE, groupName, testParams);
}
}
error = dde_execute(instance, hConv, " [ AddItem ( notepad , test ) ] ");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("test/test.lnk"), "link not created\n");
/* Delete Item Test.
* DDE command, expected result, and group and file name where it should exist.
* checks to make sure error code matches expected error code
* checks to make sure item does not exist if successful
*/
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;
error = dde_execute(instance, hConv, "[AddItem(notepad,one)][AddItem(notepad,two)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("test/one.lnk"), "link not created\n");
ok(check_exists("test/two.lnk"), "link not created\n");
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
todo_wine
{
ok (expected_result == error, "DeleteItem %s: Expected Error %s, received %s.%s\n",
fileName, GetStringFromError(expected_result), GetStringFromError(error),
GetStringFromTestParams(testParams));
}
error = dde_execute(instance, hConv, "[FakeCommand(test)][DeleteGroup(test)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
ok(check_exists("test"), "directory should exist\n");
if (error == DMLERR_NO_ERROR)
{
/* Check that File does not exist */
CheckFileExistsInProgramGroups(fileName, FALSE, FALSE, groupName, testParams);
}
}
error = dde_execute(instance, hConv, "[DeleteGroup(test)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("test"), "directory should not exist\n");
/* Compound Command Test.
* not really generic, assumes command of the form:
* [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;
error = dde_execute(instance, hConv, "[ExitProgman()]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
DdeExecuteCommand(instance, hConv, command, &hData, &error, testParams);
todo_wine
{
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, ")]");
error = dde_execute(instance, hConv, "[ExitProgman]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
}
/* 1st set of tests */
static int DdeTestProgman(DWORD instance, HCONV hConv)
static void test_progman_dde(DWORD instance, HCONV hConv)
{
HDDEDATA hData;
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;
/* Invalid Command */
DdeExecuteCommand(instance, hConv, "[InvalidCommand()]", &hData, &error, DDE_TEST_MISC|testnum++);
ok (error == DMLERR_NOTPROCESSED, "InvalidCommand(), expected error %s, received %s.\n",
GetStringFromError(DMLERR_NOTPROCESSED), GetStringFromError(error));
/* test creating and deleting groups and items */
error = dde_execute(instance, hConv, "[CreateGroup(Group1)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1"), "directory not created\n");
ok(check_window_exists("Group1"), "window not created\n");
/* On Vista+ the files have to exist when adding a link */
GetTempPathA(MAX_PATH, temppath);
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);
error = dde_execute(instance, hConv, "[AddItem]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* CreateGroup Tests (including AddItem, DeleteItem) */
CreateGroupTest(instance, hConv, "[CreateGroup(Group1)]", DMLERR_NO_ERROR, "Group1", Group1Title, DDE_TEST_CREATEGROUP|testnum++);
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++);
error = dde_execute(instance, hConv, "[AddItem(test)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* ShowGroup Tests */
ShowGroupTest(instance, hConv, "[ShowGroup(Group1)]", DMLERR_NOTPROCESSED, "Group1", Group1Title, TRUE, DDE_TEST_SHOWGROUP|testnum++);
DeleteItemTest(instance, hConv, "[DeleteItem(f3g1Name)]", DMLERR_NO_ERROR, "f3g1Name.lnk", "Group1", DDE_TEST_DELETEITEM|testnum++);
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++);
error = dde_execute(instance, hConv, "[AddItem(notepad.exe)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(check_exists("Group1/notepad.lnk"), "link not created\n");
/* DeleteGroup Test - Note that Window is Open for this test */
DeleteGroupTest(instance, hConv, "[DeleteGroup(Group1)]", DMLERR_NO_ERROR, "Group1", DDE_TEST_DELETEGROUP|testnum++);
if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
error = dde_execute(instance, hConv, "[DeleteItem(notepad.exe)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Compound Execute String Command */
lstrcpyA(comptext, "[CreateGroup(Group3)]");
CreateAddItemText(itemtext, f1g3, "f1g3Name");
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++);
error = dde_execute(instance, hConv, "[DeleteItem(notepad)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
ok(!check_exists("Group1/notepad.lnk"), "link should not exist\n");
DeleteGroupTest(instance, hConv, "[DeleteGroup(Group3)]", DMLERR_NO_ERROR, "Group3", DDE_TEST_DELETEGROUP|testnum++);
if (hwnd) SendMessageA(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0);
error = dde_execute(instance, hConv, "[DeleteItem(notepad)]");
ok(error == DMLERR_NOTPROCESSED, "expected DMLERR_NOTPROCESSED, got %u\n", error);
/* Full Parameters of Add Item */
/* AddItem(CmdLine[,Name[,IconPath[,IconIndex[,xPos,yPos[,DefDir[,HotKey[,fMinimize[fSeparateSpace]]]]]]]) */
error = dde_execute(instance, hConv, "[AddItem(notepad)]");
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);
DeleteFileA(f2g1);
DeleteFileA(f3g1);
DeleteFileA(f1g3);
DeleteFileA(f2g3);
error = dde_execute(instance, hConv, "[AddItem(notepad)]");
ok(error == DMLERR_NO_ERROR, "expected DMLERR_NO_ERROR, got %u\n", error);
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 */
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 */
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++);
UINT error;
/* 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)
@ -699,20 +421,21 @@ START_TEST(progman_dde)
UINT err;
HSZ hszProgman;
HCONV hConv;
int testnum;
BOOL ret;
init_function_pointers();
init_strings();
/* Initialize DDE Instance */
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 */
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);
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 */
if (hConv == NULL)
{
@ -720,30 +443,36 @@ START_TEST(progman_dde)
return;
}
/* Run Tests */
testnum = DdeTestProgman(instance, hConv);
test_parser(instance, hConv);
test_progman_dde(instance, hConv);
test_request_groups(instance, hConv);
/* Cleanup & Exit */
ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance));
ok (DdeUninitialize(instance), "DdeUninitialize failed\n");
ret = DdeDisconnect(hConv);
ok(ret, "DdeDisonnect() failed: %u\n", DdeGetLastError(instance));
ret = DdeUninitialize(instance);
ok(ret, "DdeUninitialize() failed: %u\n", DdeGetLastError(instance));
/* 2nd Instance (Followup Tests) */
/* Initialize DDE Instance */
instance = 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 */
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);
ok (hConv != NULL, "DdeConnect Error %s\n", GetDdeLastErrorStr(instance));
ok (DdeFreeStringHandle(instance, hszProgman), "DdeFreeStringHandle failure\n");
ok(hConv != NULL, "DdeConnect() failed: %u\n", DdeGetLastError(instance));
ret = DdeFreeStringHandle(instance, hszProgman);
ok(ret, "DdeFreeStringHandle() failed: %u\n", DdeGetLastError(instance));
/* Run Tests */
DdeTestProgman2(instance, hConv, testnum);
test_progman_dde2(instance, hConv);
/* Cleanup & Exit */
ok (DdeDisconnect(hConv), "DdeDisonnect Error %s\n", GetDdeLastErrorStr(instance));
ok (DdeUninitialize(instance), "DdeUninitialize failed\n");
ret = DdeDisconnect(hConv);
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
*/
#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 *pSHFileOperationA)(LPSHFILEOPSTRUCTA);

View file

@ -18,35 +18,63 @@
* 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 <initguid.h>
#include "shldisp.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) \
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 HRESULT (WINAPI *pSHGetFolderPathW)(HWND, int, HANDLE, DWORD, LPWSTR);
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 */
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)
{
HMODULE hshell32, hkernel32;
HMODULE hshell32;
hshell32 = GetModuleHandleA("shell32.dll");
hkernel32 = GetModuleHandleA("kernel32.dll");
pSHGetFolderPathW = (void*)GetProcAddress(hshell32, "SHGetFolderPathW");
pSHGetNameFromIDList = (void*)GetProcAddress(hshell32, "SHGetNameFromIDList");
pSHGetSpecialFolderLocation = (void*)GetProcAddress(hshell32,
"SHGetSpecialFolderLocation");
pGetLongPathNameW = (void*)GetProcAddress(hkernel32, "GetLongPathNameW");
}
static void test_namespace(void)
@ -108,18 +136,23 @@ static void test_namespace(void)
FolderItem *item;
VARIANT var;
BSTR title, item_path;
IDispatch *disp;
int len, i;
r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER,
&IID_IShellDispatch, (LPVOID*)&sd);
if (r == REGDB_E_CLASSNOTREG) /* NT4 */
{
win_skip("skipping IShellDispatch tests\n");
return;
}
ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r);
if (FAILED(r))
return;
r = CoCreateInstance(&CLSID_Shell, NULL, CLSCTX_INPROC_SERVER, &IID_IShellDispatch, (void **)&sd);
ok(SUCCEEDED(r), "Failed to create ShellDispatch object: %#x.\n", r);
disp = NULL;
r = IShellDispatch_get_Application(sd, &disp);
ok(r == S_OK, "Failed to get application pointer, hr %#x.\n", r);
ok(disp == (IDispatch *)sd, "Unexpected application pointer %p.\n", disp);
IDispatch_Release(disp);
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);
folder = (void*)0xdeadbeef;
@ -135,6 +168,7 @@ static void test_namespace(void)
folder = (void*)0xdeadbeef;
r = IShellDispatch_NameSpace(sd, var, &folder);
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);
else
ok(r == S_OK, "Failed to get folder for index %#x, got %08x\n", special_folders[i], r);
@ -144,32 +178,23 @@ static void test_namespace(void)
V_VT(&var) = VT_I4;
V_I4(&var) = -1;
folder = (void*)0xdeadbeef;
folder = (void *)0xdeadbeef;
r = IShellDispatch_NameSpace(sd, var, &folder);
todo_wine {
ok(r == S_FALSE, "expected S_FALSE, got %08x\n", r);
ok(folder == NULL, "got %p\n", folder);
if (r == S_OK)
Folder_Release(folder);
}
ok(r == S_FALSE, "Unexpected hr %#x.\n", r);
ok(folder == NULL, "Unexpected folder instance %p\n", folder);
V_VT(&var) = VT_I4;
V_I4(&var) = ssfPROGRAMFILES;
r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK ||
broken(r == S_FALSE), /* NT4 */
"IShellDispatch::NameSpace failed: %08x\n", r);
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
if (r == S_OK)
{
static WCHAR path[MAX_PATH];
if (pSHGetFolderPathW)
{
r = pSHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL,
SHGFP_TYPE_CURRENT, path);
ok(r == S_OK, "SHGetFolderPath failed: %08x\n", r);
}
r = SHGetFolderPathW(NULL, CSIDL_PROGRAM_FILES, NULL, SHGFP_TYPE_CURRENT, path);
ok(r == S_OK, "Failed to get folder path: %#x.\n", r);
r = Folder_get_Title(folder, &title);
todo_wine
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
if (r == S_OK)
{
@ -177,22 +202,20 @@ static void test_namespace(void)
HKLM\Software\Microsoft\Windows\CurrentVersion\ProgramFilesDir.
On newer Windows it seems constant and is not changed
if the program files directory name is changed */
if (pSHGetSpecialFolderLocation && pSHGetNameFromIDList)
if (pSHGetNameFromIDList)
{
LPITEMIDLIST pidl;
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);
r = pSHGetNameFromIDList(pidl, SIGDN_NORMALDISPLAY, &name);
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(pidl);
}
else if (pSHGetFolderPathW)
else
{
WCHAR *p;
@ -202,7 +225,6 @@ static void test_namespace(void)
ok(!lstrcmpiW(title, p), "expected %s, got %s\n",
wine_dbgstr_w(p), wine_dbgstr_w(title));
}
else skip("skipping Folder::get_Title test\n");
SysFreeString(title);
}
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
@ -215,9 +237,7 @@ static void test_namespace(void)
{
r = FolderItem_get_Path(item, &item_path);
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);
FolderItem_Release(item);
}
@ -229,34 +249,21 @@ static void test_namespace(void)
V_VT(&var) = VT_I4;
V_I4(&var) = ssfBITBUCKET;
r = IShellDispatch_NameSpace(sd, var, &folder);
ok(r == S_OK ||
broken(r == S_FALSE), /* NT4 */
"IShellDispatch::NameSpace failed: %08x\n", r);
if (r == S_OK)
{
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)
{
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
r = Folder_QueryInterface(folder, &IID_Folder2, (void **)&folder2);
ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
r = Folder2_get_Self(folder2, &item);
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
if (r == S_OK)
{
r = FolderItem_get_Path(item, &item_path);
todo_wine
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
todo_wine
ok(!lstrcmpW(item_path, clsidW), "expected %s, got %s\n",
wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
/* TODO: we return lowercase GUID here */
ok(!lstrcmpiW(item_path, clsidW), "expected %s, got %s\n", wine_dbgstr_w(clsidW), wine_dbgstr_w(item_path));
SysFreeString(item_path);
FolderItem_Release(item);
}
Folder2_Release(folder2);
}
Folder_Release(folder);
}
GetTempPathW(MAX_PATH, tempW);
GetCurrentDirectoryW(MAX_PATH, curW);
@ -269,51 +276,39 @@ static void test_namespace(void)
SysFreeString(V_BSTR(&var));
GetFullPathNameW(winetestW, MAX_PATH, tempW, NULL);
if (pGetLongPathNameW)
{
len = pGetLongPathNameW(tempW, NULL, 0);
long_pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (long_pathW)
pGetLongPathNameW(tempW, long_pathW, len);
}
len = GetLongPathNameW(tempW, NULL, 0);
long_pathW = heap_alloc(len * sizeof(WCHAR));
GetLongPathNameW(tempW, long_pathW, len);
V_VT(&var) = VT_BSTR;
V_BSTR(&var) = SysAllocString(tempW);
r = IShellDispatch_NameSpace(sd, var, &folder);
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);
ok(r == S_OK, "Folder::get_Title failed: %08x\n", r);
if (r == S_OK)
{
ok(!lstrcmpW(title, winetestW), "bad title: %s\n",
wine_dbgstr_w(title));
ok(r == S_OK, "Failed to get folder title: %#x.\n", r);
ok(!lstrcmpW(title, winetestW), "Unexpected title: %s\n", wine_dbgstr_w(title));
SysFreeString(title);
}
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 = Folder_QueryInterface(folder, &IID_Folder2, (void **)&folder2);
ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
r = Folder2_get_Self(folder2, &item);
ok(r == S_OK, "Folder::get_Self failed: %08x\n", r);
if (r == S_OK)
{
r = FolderItem_get_Path(item, &item_path);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
if (long_pathW)
ok(!lstrcmpW(item_path, long_pathW),
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
wine_dbgstr_w(item_path));
ok(r == S_OK, "Failed to get item path: %#x.\n", r);
ok(!lstrcmpW(item_path, long_pathW), "Unexpected path %s, got %s\n", wine_dbgstr_w(item_path), wine_dbgstr_w(long_pathW));
SysFreeString(item_path);
FolderItem_Release(item);
}
Folder2_Release(folder2);
}
Folder_Release(folder);
}
SysFreeString(V_BSTR(&var));
VariantClear(&var);
len = lstrlenW(tempW);
if (len < MAX_PATH - 1)
@ -334,9 +329,7 @@ static void test_namespace(void)
SysFreeString(title);
}
r = Folder_QueryInterface(folder, &IID_Folder2, (LPVOID*)&folder2);
ok(r == S_OK ||
broken(r == E_NOINTERFACE), /* NT4 */
"Folder::QueryInterface failed: %08x\n", r);
ok(r == S_OK, "Failed to get Folder2 interface: %#x.\n", r);
if (r == S_OK)
{
r = Folder2_get_Self(folder2, &item);
@ -345,10 +338,8 @@ static void test_namespace(void)
{
r = FolderItem_get_Path(item, &item_path);
ok(r == S_OK, "FolderItem::get_Path failed: %08x\n", r);
if (long_pathW)
ok(!lstrcmpW(item_path, long_pathW),
"expected %s, got %s\n", wine_dbgstr_w(long_pathW),
wine_dbgstr_w(item_path));
ok(!lstrcmpW(item_path, long_pathW), "Unexpected path %s, got %s\n", wine_dbgstr_w(item_path),
wine_dbgstr_w(long_pathW));
SysFreeString(item_path);
FolderItem_Release(item);
}
@ -359,7 +350,7 @@ static void test_namespace(void)
SysFreeString(V_BSTR(&var));
}
HeapFree(GetProcessHeap(), 0, long_pathW);
heap_free(long_pathW);
RemoveDirectoryW(winetestW);
SetCurrentDirectoryW(curW);
IShellDispatch_Release(sd);
@ -367,55 +358,110 @@ static void test_namespace(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;
IShellDispatch *sd = NULL;
Folder *folder = NULL;
FolderItems *items = NULL;
FolderItems *items;
FolderItems2 *items2 = NULL;
FolderItems3 *items3 = NULL;
FolderItem *item = (FolderItem*)0xdeadbeef;
IDispatch *disp = NULL;
IUnknown *unk = NULL;
FolderItem *item = (FolderItem*)0xdeadbeef, *item2;
FolderItemVerbs *verbs = (FolderItemVerbs*)0xdeadbeef;
VARIANT var;
LONG lcount = -1;
VARIANT var, int_index, str_index, str_index2;
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);
ok(SUCCEEDED(r), "CoCreateInstance failed: %08x\n", r);
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);
SetCurrentDirectoryW(wstr);
CreateDirectoryW(winetestW, NULL);
GetFullPathNameW(winetestW, MAX_PATH, wstr, NULL);
SetCurrentDirectoryW(path);
ret = CreateDirectoryW(winetestW, NULL);
ok(ret, "CreateDirectory failed: %08x\n", GetLastError());
GetFullPathNameW(winetestW, MAX_PATH, path, NULL);
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);
ok(r == S_OK, "IShellDispatch::NameSpace failed: %08x\n", r);
ok(!!folder, "folder is null\n");
SysFreeString(V_BSTR(&var));
IShellDispatch_Release(sd);
SetCurrentDirectoryW(winetestW);
EXPECT_REF(folder, 1);
EXPECT_REF(sd, 1);
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);
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);
ok(!!items2 || broken(!items2) /* xp and later */, "items2 is null\n");
r = FolderItems_QueryInterface(items, &IID_FolderItems3, (void**)&items3);
ok(r == S_OK, "FolderItems::QueryInterface failed: %08x\n", r);
ok(!!items3, "items3 is null\n");
Folder_Release(folder);
EXPECT_REF(folder, 2);
EXPECT_REF(items, 1);
unk = NULL;
r = Folder_Items(folder, (FolderItems **)&unk);
ok(r == S_OK, "Folder::Items failed: %08x\n", r);
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 */
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(!lcount, "expected 0 files, got %d\n", lcount);
ok(!count, "expected 0 files, got %d\n", count);
V_VT(&var) = VT_I4;
V_I4(&var) = 0;
@ -424,7 +470,269 @@ static void test_items(void)
r = FolderItems_Item(items, var, NULL);
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(!item, "item is not null\n");
@ -435,11 +743,13 @@ todo_wine
}
r = FolderItems_get_Application(items, &disp);
todo_wine
ok(r == S_OK, "FolderItems::get_Application failed: %08x\n", r);
todo_wine
ok(!!disp, "disp is null\n");
if (disp) IDispatch_Release(disp);
r = Folder_get_Application(folder, &disp2);
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 */
{
@ -483,14 +793,37 @@ todo_wine
ok(!verbs, "verbs is not null\n");
}
GetTempPathW(MAX_PATH, wstr);
SetCurrentDirectoryW(wstr);
RemoveDirectoryW(winetestW);
/* remove the temporary directory and restore the original working directory */
GetTempPathW(MAX_PATH, path);
SetCurrentDirectoryW(path);
ret = RemoveDirectoryW(winetestW);
ok(ret, "RemoveDirectory failed: %08x\n", GetLastError());
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);
if (items2) FolderItems2_Release(items2);
Folder_Release(folder);
if (items3) FolderItems3_Release(items3);
IShellDispatch_Release(sd);
}
static void test_service(void)
@ -739,7 +1072,7 @@ todo_wine {
ok(hr == S_OK || broken(hr == S_FALSE), "got 0x%08x\n", hr);
if (hr == S_FALSE) /* winxp and earlier */ {
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(ret == 0, "got %d\n", ret);
}
@ -763,6 +1096,9 @@ todo_wine {
IUnknown *unk;
ok(disp != NULL, "got %p\n", disp);
if (disp == NULL) goto skip_disp_tests;
ok(ret != HandleToUlong(hwnd), "got %d\n", ret);
/* IDispatch-related tests */
@ -840,6 +1176,7 @@ if (hr == S_OK) {
IServiceProvider_Release(sp);
IDispatch_Release(disp);
}
skip_disp_tests:
disp = (void*)0xdeadbeef;
ret = 0xdead;
@ -934,12 +1271,13 @@ static void test_ParseName(void)
static void test_Verbs(void)
{
FolderItemVerbs *verbs;
FolderItemVerbs *verbs, *verbs2;
WCHAR pathW[MAX_PATH];
FolderItemVerb *verb;
IShellDispatch *sd;
FolderItem *item;
Folder2 *folder2;
IDispatch *disp;
Folder *folder;
HRESULT hr;
LONG count, i;
@ -972,6 +1310,21 @@ if (0) { /* crashes on some systems */
hr = FolderItem_Verbs(item, &verbs);
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 */
hr = FolderItemVerbs_get_Count(verbs, NULL);
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(str != NULL, "%d: name %s\n", i, wine_dbgstr_w(str));
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);
FolderItemVerb_Release(verb);
@ -1054,6 +1417,7 @@ static void test_ShellExecute(void)
ok(hr == S_OK, "ShellExecute failed: %08x\n", hr);
SysFreeString(name);
IShellDispatch2_Release(sd);
}
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
# define SLDF_HAS_LOGO3ID 0x00000800 /* not available in the Vista SDK */
@ -28,6 +45,7 @@
static void (WINAPI *pILFree)(LPITEMIDLIST);
static BOOL (WINAPI *pILIsEqual)(LPCITEMIDLIST, LPCITEMIDLIST);
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 *pSHGetStockIconInfo)(SHSTOCKICONID, UINT, SHSTOCKICONINFO *);
static DWORD (WINAPI *pGetLongPathNameA)(LPCSTR, LPSTR, DWORD);
@ -71,12 +89,12 @@ static LPITEMIDLIST path_to_pidl(const char* path)
int len;
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);
r=pSHILCreateFromPath(pathW, &pidl, NULL);
ok(r == S_OK, "SHILCreateFromPath failed (0x%08x)\n", r);
HeapFree(GetProcessHeap(), 0, pathW);
heap_free(pathW);
}
return pidl;
}
@ -93,6 +111,7 @@ static void test_get_set(void)
IShellLinkW *slW = NULL;
char mypath[MAX_PATH];
char buffer[INFOTIPSIZE];
WIN32_FIND_DATAA finddata;
LPITEMIDLIST pidl, tmp_pidl;
const char * str;
int i;
@ -145,11 +164,20 @@ static void test_get_set(void)
/* Test Getting / Setting the path */
strcpy(buffer,"garbage");
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);
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);
ok(r == S_OK, "CoCreateInstance failed (0x%08x)\n", r);
if (!slW /* Win9x */ || !pGetLongPathNameA /* NT4 */)
skip("SetPath with NULL parameter crashes on Win9x and some NT4\n");
else
@ -166,7 +194,7 @@ static void test_get_set(void)
strcpy(buffer,"garbage");
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);
/* 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(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 */
GetWindowsDirectoryA( mypath, sizeof(mypath)-12 );
strcat(mypath, "\\regedit.exe");
@ -228,8 +264,41 @@ static void test_get_set(void)
strcpy(buffer,"garbage");
r = IShellLinkA_GetPath(sl, buffer, sizeof(buffer), NULL, SLGP_RAWPATH);
ok(r == S_OK, "GetPath failed (0x%08x)\n", r);
todo_wine
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 */
@ -1396,6 +1465,7 @@ START_TEST(shelllink)
pILFree = (void *)GetProcAddress(hmod, (LPSTR)155);
pILIsEqual = (void *)GetProcAddress(hmod, (LPSTR)21);
pSHILCreateFromPath = (void *)GetProcAddress(hmod, (LPSTR)28);
pSHGetFolderLocation = (void *)GetProcAddress(hmod, "SHGetFolderLocation");
pSHDefExtractIconA = (void *)GetProcAddress(hmod, "SHDefExtractIconA");
pSHGetStockIconInfo = (void *)GetProcAddress(hmod, "SHGetStockIconInfo");
pGetLongPathNameA = (void *)GetProcAddress(hkernel32, "GetLongPathNameA");

View file

@ -16,9 +16,19 @@
* 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_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).
*/
#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
* here is its original value.
@ -1887,7 +1898,7 @@ static const struct knownFolderDef known_folders[] = {
{ 0 }
};
#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)
{
@ -1903,7 +1914,7 @@ static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
if(strcmp(hay, "(null)") == 0 && !needle)
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)
{
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);
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)(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 );
GetTempPathW(sizeof(sExamplePath)/sizeof(sExamplePath[0]), sExamplePath);
GetTempPathW(ARRAY_SIZE(sExamplePath), sExamplePath);
lstrcatW(sExamplePath, sExample);
GetTempPathW(sizeof(sExample2Path)/sizeof(sExample2Path[0]), sExample2Path);
GetTempPathW(ARRAY_SIZE(sExample2Path), sExample2Path);
lstrcatW(sExample2Path, sExample2);
lstrcpyW(sSubFolderPath, sExamplePath);
@ -2110,7 +2121,6 @@ static void test_knownFolders(void)
CoTaskMemFree(folderPath);
hr = IKnownFolder_GetRedirectionCapabilities(folder, &redirectionCapabilities);
todo_wine
ok(hr == S_OK, "failed to get redirection capabilities: 0x%08x\n", hr);
todo_wine
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(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;
hr = IKnownFolderManager_GetFolderIds(mgr, &folders, &nCount);
@ -2170,7 +2180,7 @@ static void test_knownFolders(void)
for(i=0;i<nCount;++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])
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);
bufferA[MAX_PATH - 1] = 0;
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);
res = DoEnvironmentSubstA(bufferA, MAX_PATH);
@ -2575,7 +2585,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0;
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);
res = DoEnvironmentSubstA(bufferA, len + 1);
@ -2596,7 +2606,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0;
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 */
res = DoEnvironmentSubstA(bufferA, len);
@ -2619,7 +2629,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1);
bufferA[len + 2] = 0;
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);
ok(!HIWORD(res) && (LOWORD(res) == (len - 1)),
@ -2640,7 +2650,7 @@ static void test_DoEnvironmentSubst(void)
memset(bufferA, '#', MAX_PATH - 1);
bufferA[MAX_PATH - 1] = 0;
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;
res = DoEnvironmentSubstA(bufferA, MAX_PATH);
@ -2691,7 +2701,7 @@ if (0)
ok(!ret, "got %d\n", ret);
}
GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
GetTempPathW(ARRAY_SIZE(pathW), pathW);
/* Using short name only first */
nameW[0] = 0;

View file

@ -19,7 +19,21 @@
* 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)
{

View file

@ -30,7 +30,28 @@
* 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 int myARGC;
@ -742,7 +763,7 @@ static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
if (dwMaxLen > sizeof(szNameBuf)/sizeof(CHAR))
{
/* 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;
goto cleanup;
@ -777,7 +798,7 @@ static LSTATUS myRegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
cleanup:
/* Free buffer if allocated */
if (lpszName != szNameBuf)
HeapFree( GetProcessHeap(), 0, lpszName);
heap_free(lpszName);
if(lpszSubKey)
RegCloseKey(hSubKey);
return ret;
@ -837,11 +858,11 @@ static void create_test_verb_dde(const char* classname, const char* verb,
}
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);
rc=RegSetValueExA(hkey_cmd, NULL, 0, REG_SZ, (LPBYTE)cmd, strlen(cmd)+1);
ok(rc == ERROR_SUCCESS, "setting command failed with %d\n", rc);
HeapFree(GetProcessHeap(), 0, cmd);
heap_free(cmd);
}
if (ddeexec)

View file

@ -18,7 +18,21 @@
* 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
#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
*/
#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"
#ifdef __REACTOS__
#include <reactos/undocshell.h>
#endif
#define LISTVIEW_SEQ_INDEX 0
#define NUM_MSG_SEQUENCES 1
@ -129,7 +154,7 @@ static IDataObject* IDataObjectImpl_Construct(void)
{
IDataObjectImpl *obj;
obj = HeapAlloc(GetProcessHeap(), 0, sizeof(*obj));
obj = heap_alloc(sizeof(*obj));
obj->IDataObject_iface.lpVtbl = &IDataObjectImpl_Vtbl;
obj->ref = 1;
@ -143,7 +168,7 @@ static HRESULT WINAPI IDataObjectImpl_QueryInterface(IDataObject *iface, REFIID
if (IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IDataObject))
{
*ppvObj = This;
*ppvObj = &This->IDataObject_iface;
}
if(*ppvObj)
@ -167,10 +192,8 @@ static ULONG WINAPI IDataObjectImpl_Release(IDataObject * iface)
ULONG ref = InterlockedDecrement(&This->ref);
if (!ref)
{
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
heap_free(This);
return ref;
}
@ -256,7 +279,7 @@ static IShellBrowser* IShellBrowserImpl_Construct(void)
{
IShellBrowserImpl *browser;
browser = HeapAlloc(GetProcessHeap(), 0, sizeof(*browser));
browser = heap_alloc(sizeof(*browser));
browser->IShellBrowser_iface.lpVtbl = &IShellBrowserImpl_Vtbl;
browser->ref = 1;
@ -275,7 +298,7 @@ static HRESULT WINAPI IShellBrowserImpl_QueryInterface(IShellBrowser *iface,
IsEqualIID(riid, &IID_IOleWindow) ||
IsEqualIID(riid, &IID_IShellBrowser))
{
*ppvObj = This;
*ppvObj = &This->IShellBrowser_iface;
}
if(*ppvObj)
@ -299,10 +322,8 @@ static ULONG WINAPI IShellBrowserImpl_Release(IShellBrowser * iface)
ULONG ref = InterlockedDecrement(&This->ref);
if (!ref)
{
HeapFree(GetProcessHeap(), 0, This);
return 0;
}
heap_free(This);
return ref;
}
@ -1456,6 +1477,35 @@ if (0)
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)
{
OleInitialize(NULL);
@ -1471,6 +1521,7 @@ START_TEST(shlview)
test_IOleCommandTarget();
test_SHCreateShellFolderView();
test_SHCreateShellFolderViewEx();
test_newmenu();
OleUninitialize();
}

View file

@ -18,7 +18,18 @@
* 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 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
*/
#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 BOOL (WINAPI *pShell_NotifyIconW)(DWORD,PNOTIFYICONDATAW);