sync mshtml and shdocvw winetests with wine 1.1.14

svn path=/trunk/; revision=39390
This commit is contained in:
Christoph von Wittich 2009-02-04 14:36:08 +00:00
parent cc12355d0e
commit 43eb75a9e4
12 changed files with 5053 additions and 142 deletions

View file

@ -118,6 +118,9 @@
<directory name="setupapi">
<xi:include href="setupapi/setupapi.rbuild" />
</directory>
<directory name="shdocvw">
<xi:include href="shdocvw/shdocvw.rbuild" />
</directory>
<directory name="shell32">
<xi:include href="shell32/shell32.rbuild" />
</directory>

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,7 @@
#include "windef.h"
#include "winbase.h"
#include "initguid.h"
#include "ole2.h"
#include "mshtml.h"
#include "docobj.h"
@ -36,7 +37,8 @@
#include "idispids.h"
#include "shlguid.h"
#include "initguid.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
DEFINE_GUID(IID_IProxyManager,0x00000008,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
DEFINE_OLEGUID(CGID_DocHostCmdPriv, 0x000214D4L, 0, 0);
#define DEFINE_EXPECT(func) \
@ -136,6 +138,10 @@ DEFINE_EXPECT(RequestUIActivate);
DEFINE_EXPECT(InPlaceFrame_SetBorderSpace);
DEFINE_EXPECT(InPlaceUIWindow_SetActiveObject);
DEFINE_EXPECT(GetExternal);
DEFINE_EXPECT(EnableModeless_TRUE);
DEFINE_EXPECT(EnableModeless_FALSE);
DEFINE_EXPECT(Frame_EnableModeless_TRUE);
DEFINE_EXPECT(Frame_EnableModeless_FALSE);
static IUnknown *doc_unk;
static BOOL expect_LockContainer_fLock;
@ -143,7 +149,7 @@ static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE;
static BOOL ipsex;
static BOOL set_clientsite = FALSE, container_locked = FALSE;
static BOOL readystate_set_loading = FALSE, load_from_stream;
static BOOL editmode = FALSE;
static BOOL editmode = FALSE, show_failed;
static int stream_read, protocol_read;
static enum load_state_t {
LD_DOLOAD,
@ -649,11 +655,13 @@ static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, D
readystate_set_loading = FALSE;
load_state = LD_LOADING;
}
test_readyState(NULL);
if(!editmode || load_state != LD_LOADING || !called_Exec_Explorer_69)
test_readyState(NULL);
return S_OK;
case 1005:
CHECK_EXPECT(OnChanged_1005);
test_readyState(NULL);
if(!editmode)
test_readyState(NULL);
load_state = LD_INTERACTIVE;
return S_OK;
}
@ -1007,8 +1015,10 @@ static HRESULT WINAPI Moniker_BindToStorage(IMoniker *iface, IBindCtx *pbc, IMon
BINDSTATUS_ENDDOWNLOADDATA, NULL);
ok(hres == S_OK, "OnProgress(BINDSTATUS_ENDDOWNLOADDATA) failed: %08x\n", hres);
SET_EXPECT(GetBindResult);
hres = IBindStatusCallback_OnStopBinding(callback, S_OK, NULL);
ok(hres == S_OK, "OnStopBinding failed: %08x\n", hres);
SET_CALLED(GetBindResult); /* IE7 */
IBindStatusCallback_Release(callback);
@ -1304,7 +1314,10 @@ static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLE
static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
{
ok(0, "unexpected call\n");
if(fEnable)
CHECK_EXPECT(Frame_EnableModeless_TRUE);
else
CHECK_EXPECT(Frame_EnableModeless_FALSE);
return E_NOTIMPL;
}
@ -1664,11 +1677,6 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum
expect_status_text = NULL;
hres = IOleDocumentView_UIActivate(view, TRUE);
if(FAILED(hres)) {
skip("UIActivate failed: %08x\n", hres);
return hres;
}
ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
CHECK_CALLED(CanInPlaceActivate);
@ -1724,6 +1732,14 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum
expect_status_text = (load_state == LD_COMPLETE ? (LPCOLESTR)0xdeadbeef : NULL);
hres = IOleDocumentView_Show(view, TRUE);
if(FAILED(hres)) {
win_skip("Show failed\n");
if(activeobj)
IOleInPlaceActiveObject_Release(activeobj);
IOleDocument_Release(document);
show_failed = TRUE;
return S_OK;
}
ok(hres == S_OK, "Show failed: %08x\n", hres);
CHECK_CALLED(CanInPlaceActivate);
@ -1918,7 +1934,10 @@ static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
{
ok(0, "unexpected call\n");
if(fEnable)
CHECK_EXPECT(EnableModeless_TRUE);
else
CHECK_EXPECT(EnableModeless_FALSE);
return E_NOTIMPL;
}
@ -2635,6 +2654,7 @@ static void test_Load(IPersistMoniker *persist)
}
SET_EXPECT(OnChanged_READYSTATE);
SET_EXPECT(Exec_ShellDocView_84);
SET_EXPECT(IsSystemMoniker);
SET_EXPECT(BindToStorage);
SET_EXPECT(SetActiveObject);
if(set_clientsite) {
@ -2672,6 +2692,7 @@ static void test_Load(IPersistMoniker *persist)
container_locked = TRUE;
}
CHECK_CALLED(OnChanged_READYSTATE);
SET_CALLED(IsSystemMoniker); /* IE7 */
SET_CALLED(Exec_ShellDocView_84);
CHECK_CALLED(BindToStorage);
SET_CALLED(SetActiveObject); /* FIXME */
@ -2719,6 +2740,10 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl)
SET_EXPECT(UnlockRequest);
}
SET_EXPECT(Exec_Explorer_69);
SET_EXPECT(EnableModeless_TRUE); /* IE7 */
SET_EXPECT(Frame_EnableModeless_TRUE); /* IE7 */
SET_EXPECT(EnableModeless_FALSE); /* IE7 */
SET_EXPECT(Frame_EnableModeless_FALSE); /* IE7 */
SET_EXPECT(OnChanged_1005);
SET_EXPECT(OnChanged_READYSTATE);
SET_EXPECT(Exec_SETPROGRESSPOS);
@ -2726,6 +2751,7 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl)
SET_EXPECT(Exec_ShellDocView_103);
SET_EXPECT(Exec_MSHTML_PARSECOMPLETE);
SET_EXPECT(Exec_HTTPEQUIV_DONE);
SET_EXPECT(SetStatusText);
expect_status_text = (LPWSTR)0xdeadbeef; /* TODO */
while(!called_Exec_HTTPEQUIV_DONE && GetMessage(&msg, NULL, 0, 0)) {
@ -2766,6 +2792,10 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl)
}
}
SET_CALLED(Exec_Explorer_69);
SET_CALLED(EnableModeless_TRUE); /* IE7 */
SET_CALLED(Frame_EnableModeless_TRUE); /* IE7 */
SET_CALLED(EnableModeless_FALSE); /* IE7 */
SET_CALLED(Frame_EnableModeless_FALSE); /* IE7 */
CHECK_CALLED(OnChanged_1005);
CHECK_CALLED(OnChanged_READYSTATE);
CHECK_CALLED(Exec_SETPROGRESSPOS);
@ -2773,6 +2803,7 @@ static void test_download(BOOL verb_done, BOOL css_dwl, BOOL css_try_dwl)
SET_CALLED(Exec_ShellDocView_103);
CHECK_CALLED(Exec_MSHTML_PARSECOMPLETE);
CHECK_CALLED(Exec_HTTPEQUIV_DONE);
SET_CALLED(SetStatusText);
load_state = LD_COMPLETE;
@ -3044,6 +3075,7 @@ static void test_exec_editmode(IUnknown *unk, BOOL loaded)
SET_EXPECT(Invoke_AMBIENT_SILENT);
SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
SET_EXPECT(OnChanged_READYSTATE);
SET_EXPECT(IsSystemMoniker);
SET_EXPECT(Exec_ShellDocView_84);
if(loaded)
SET_EXPECT(BindToStorage);
@ -3069,6 +3101,7 @@ static void test_exec_editmode(IUnknown *unk, BOOL loaded)
CHECK_CALLED(Invoke_AMBIENT_SILENT);
CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
CHECK_CALLED(OnChanged_READYSTATE);
SET_CALLED(IsSystemMoniker); /* IE7 */
SET_CALLED(Exec_ShellDocView_84);
if(loaded)
CHECK_CALLED(BindToStorage);
@ -3199,7 +3232,7 @@ static HWND create_container_window(void)
515, 530, NULL, NULL, NULL, NULL);
}
static HRESULT test_DoVerb(IOleObject *oleobj)
static void test_DoVerb(IOleObject *oleobj)
{
RECT rect = {0,0,500,500};
HRESULT hres;
@ -3212,8 +3245,6 @@ static HRESULT test_DoVerb(IOleObject *oleobj)
expect_LockContainer_fLock = TRUE;
hres = IOleObject_DoVerb(oleobj, OLEIVERB_SHOW, NULL, &ClientSite, -1, container_hwnd, &rect);
if(FAILED(hres))
return hres;
ok(hres == S_OK, "DoVerb failed: %08x\n", hres);
if(!container_locked) {
@ -3222,8 +3253,6 @@ static HRESULT test_DoVerb(IOleObject *oleobj)
container_locked = TRUE;
}
CHECK_CALLED(ActivateMe);
return hres;
}
#define CLIENTSITE_EXPECTPATH 0x00000001
@ -3465,7 +3494,7 @@ static void test_InPlaceDeactivate(IUnknown *unk, BOOL expect_call)
IOleInPlaceObjectWindowless_Release(windowlessobj);
}
static HRESULT test_Activate(IUnknown *unk, DWORD flags)
static void test_Activate(IUnknown *unk, DWORD flags)
{
IOleObject *oleobj = NULL;
IOleDocumentView *docview;
@ -3480,8 +3509,6 @@ static HRESULT test_Activate(IUnknown *unk, DWORD flags)
hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
if(FAILED(hres))
return hres;
hres = IOleObject_GetUserClassID(oleobj, NULL);
ok(hres == E_INVALIDARG, "GetUserClassID returned: %08x, expected E_INVALIDARG\n", hres);
@ -3494,8 +3521,7 @@ static HRESULT test_Activate(IUnknown *unk, DWORD flags)
test_ClientSite(oleobj, flags);
test_InPlaceDeactivate(unk, FALSE);
hres = test_DoVerb(oleobj);
test_DoVerb(oleobj);
if(call_UIActivate == CallUIActivate_AfterShow) {
hres = IOleObject_QueryInterface(oleobj, &IID_IOleDocumentView, (void **)&docview);
@ -3523,8 +3549,6 @@ static HRESULT test_Activate(IUnknown *unk, DWORD flags)
IOleObject_Release(oleobj);
test_OnFrameWindowActivate(unk);
return hres;
}
static void test_Window(IUnknown *unk, BOOL expect_success)
@ -3612,9 +3636,23 @@ static void test_Hide(void)
static HRESULT create_document(IUnknown **unk)
{
HRESULT hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
IHTMLDocument5 *doc5;
HRESULT hres;
hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
&IID_IUnknown, (void**)unk);
ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
if(FAILED(hres))
return hres;
hres = IUnknown_QueryInterface(*unk, &IID_IHTMLDocument5, (void**)&doc5);
if(SUCCEEDED(hres)) {
IHTMLDocument5_Release(doc5);
}else {
win_skip("Could not get IHTMLDocument5, probably too old IE\n");
IUnknown_Release(*unk);
}
return hres;
}
@ -3707,27 +3745,32 @@ static void test_QueryInterface(IUnknown *unk)
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qirunnable=%p, ezpected NULL\n", qi);
ok(qi == NULL, "qirunnable=%p, expected NULL\n", qi);
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qi=%p, ezpected NULL\n", qi);
ok(qi == NULL, "qi=%p, expected NULL\n", qi);
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMNode2, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qi=%p, ezpected NULL\n", qi);
ok(qi == NULL, "qi=%p, expected NULL\n", qi);
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_IPersistPropertyBag, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qi=%p, ezpected NULL\n", qi);
ok(qi == NULL, "qi=%p, expected NULL\n", qi);
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_UndocumentedScriptIface, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qi=%p, ezpected NULL\n", qi);
ok(qi == NULL, "qi=%p, expected NULL\n", qi);
qi = (void*)0xdeadbeef;
hres = IUnknown_QueryInterface(unk, &IID_IMarshal, (void**)&qi);
ok(hres == E_NOINTERFACE, "QueryInterface returned %08x, expected E_NOINTERFACE\n", hres);
ok(qi == NULL, "qi=%p, expected NULL\n", qi);
}
static void init_test(enum load_state_t ls) {
@ -3768,11 +3811,7 @@ static void test_HTMLDocument(BOOL do_load)
if(!do_load)
test_OnAmbientPropertyChange2(unk);
hres = test_Activate(unk, CLIENTSITE_EXPECTPATH);
if(FAILED(hres)) {
IUnknown_Release(unk);
return;
}
test_Activate(unk, CLIENTSITE_EXPECTPATH);
if(do_load) {
test_download(FALSE, TRUE, TRUE);
@ -3865,6 +3904,10 @@ static void test_HTMLDocument_hlink(void)
test_GetCurMoniker(unk, NULL, NULL);
test_Persist(unk);
test_Navigate(unk);
if(show_failed) {
IUnknown_Release(unk);
return;
}
test_download(FALSE, TRUE, TRUE);
@ -3999,7 +4042,11 @@ static void test_editing_mode(BOOL do_load)
test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
test_download(TRUE, do_load, do_load);
SET_EXPECT(SetStatusText); /* ignore race in native mshtml */
test_timer(EXPECT_UPDATEUI);
SET_CALLED(SetStatusText);
test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED|OLECMDF_ENABLED);
if(!do_load) {
@ -4088,6 +4135,31 @@ static void gecko_installer_workaround(BOOL disable)
RegCloseKey(hkey);
}
static void test_HTMLDoc_ISupportErrorInfo(void)
{
HRESULT hres;
IUnknown *unk;
ISupportErrorInfo *sinfo;
LONG ref;
hres = create_document(&unk);
if(FAILED(hres))
return;
hres = IUnknown_QueryInterface(unk, &IID_ISupportErrorInfo, (void**)&sinfo);
ok(hres == S_OK, "got %x\n", hres);
ok(sinfo != NULL, "got %p\n", sinfo);
if(sinfo)
{
hres = ISupportErrorInfo_InterfaceSupportsErrorInfo(sinfo, &IID_IErrorInfo);
ok(hres == S_FALSE, "Expected S_OK, got %x\n", hres);
IUnknown_Release(sinfo);
}
ref = IUnknown_Release(unk);
ok(ref == 0, "ref=%d, expected 0\n", ref);
}
START_TEST(htmldoc)
{
gecko_installer_workaround(TRUE);
@ -4096,12 +4168,15 @@ START_TEST(htmldoc)
container_hwnd = create_container_window();
register_protocol();
test_HTMLDocument(FALSE);
test_HTMLDocument(TRUE);
test_HTMLDocument_hlink();
test_HTMLDocument_StreamLoad();
test_editing_mode(FALSE);
test_editing_mode(TRUE);
if(!show_failed) {
test_HTMLDocument(FALSE);
test_HTMLDocument(TRUE);
test_HTMLDocument_StreamLoad();
test_editing_mode(FALSE);
test_editing_mode(TRUE);
}
test_HTMLDoc_ISupportErrorInfo();
DestroyWindow(container_hwnd);
CoUninitialize();

View file

@ -24,9 +24,8 @@
#include "windef.h"
#include "winbase.h"
#include "ole2.h"
#include "optary.h"
#include "initguid.h"
#include "optary.h"
static void test_HTMLLoadOptions(void)
{

View file

@ -266,9 +266,13 @@ static void res_sec_url_cmp(LPCWSTR url, DWORD size, LPCWSTR file)
return;
}
SetLastError(0xdeadbeef);
len = SearchPathW(NULL, file, NULL, sizeof(buf)/sizeof(WCHAR), buf, NULL);
if(!len) {
ok(0, "SearchPath failed: %u\n", GetLastError());
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
win_skip("SearchPathW is not implemented\n");
else
ok(0, "SearchPath failed: %u\n", GetLastError());
return;
}
@ -301,7 +305,7 @@ static void test_res_protocol(void)
hres = CoGetClassObject(&CLSID_ResProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
if(!SUCCEEDED(hres))
if(FAILED(hres))
return;
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
@ -364,7 +368,7 @@ static void test_res_protocol(void)
sizeof(buf)/sizeof(buf[0]), &size, 0);
ok(hres == E_FAIL, "ParseUrl failed: %08x\n", hres);
ok(buf[0] == '?', "buf changed\n");
ok(size == 1, "size=%u, ezpected 1\n", size);
ok(size == 1, "size=%u, expected 1\n", size);
buf[0] = '?';
hres = IInternetProtocolInfo_ParseUrl(protocol_info, blank_url, PARSE_DOMAIN, 0, buf,
@ -610,7 +614,7 @@ static void test_about_protocol(void)
hres = CoGetClassObject(&CLSID_AboutProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
if(!SUCCEEDED(hres))
if(FAILED(hres))
return;
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
@ -660,7 +664,7 @@ static void test_about_protocol(void)
sizeof(buf)/sizeof(buf[0]), &size, 0);
ok(hres == E_FAIL, "ParseUrl failed: %08x\n", hres);
ok(buf[0] == '?', "buf changed\n");
ok(size == 1, "size=%u, ezpected 1\n", size);
ok(size == 1, "size=%u, expected 1\n", size);
buf[0] = '?';
hres = IInternetProtocolInfo_ParseUrl(protocol_info, about_blank_url, PARSE_DOMAIN, 0, buf,

View file

@ -28,11 +28,14 @@
#include "ole2.h"
#include "dispex.h"
#include "mshtml.h"
#include "initguid.h"
#include "activscp.h"
#include "activdbg.h"
#include "objsafe.h"
#include "mshtmdid.h"
DEFINE_GUID(CLSID_IdentityUnmarshal,0x0000001b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
#define DEFINE_EXPECT(func) \
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@ -81,6 +84,7 @@ DEFINE_EXPECT(SetScriptState_DISCONNECTED);
DEFINE_EXPECT(AddNamedItem);
DEFINE_EXPECT(ParseScriptText);
DEFINE_EXPECT(GetScriptDispatch);
DEFINE_EXPECT(funcDisp);
#define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
@ -167,6 +171,145 @@ static IPropertyNotifySinkVtbl PropertyNotifySinkVtbl = {
static IPropertyNotifySink PropertyNotifySink = { &PropertyNotifySinkVtbl };
static HRESULT WINAPI DispatchEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
{
*ppv = NULL;
if(IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDispatch)
|| IsEqualGUID(riid, &IID_IDispatchEx))
*ppv = iface;
else
return E_NOINTERFACE;
return S_OK;
}
static ULONG WINAPI DispatchEx_AddRef(IDispatchEx *iface)
{
return 2;
}
static ULONG WINAPI DispatchEx_Release(IDispatchEx *iface)
{
return 1;
}
static HRESULT WINAPI DispatchEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
LCID lcid, ITypeInfo **ppTInfo)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
LPOLESTR *rgszNames, UINT cNames,
LCID lcid, DISPID *rgDispId)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
{
ok(0, "unexpected call %s %x\n", debugstr_w(bstrName), grfdex);
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
{
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
{
CHECK_EXPECT(funcDisp);
ok(id == DISPID_VALUE, "id = %d\n", id);
ok(lcid == 0, "lcid = %x\n", lcid);
ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
ok(pdp != NULL, "pdp == NULL\n");
ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
ok(pvarRes != NULL, "pvarRes == NULL\n");
ok(pei != NULL, "pei == NULL\n");
ok(!pspCaller, "pspCaller != NULL\n");
V_VT(pvarRes) = VT_I4;
V_I4(pvarRes) = 100;
return S_OK;
}
static IDispatchExVtbl testObjVtbl = {
DispatchEx_QueryInterface,
DispatchEx_AddRef,
DispatchEx_Release,
DispatchEx_GetTypeInfoCount,
DispatchEx_GetTypeInfo,
DispatchEx_GetIDsOfNames,
DispatchEx_Invoke,
DispatchEx_GetDispID,
funcDisp_InvokeEx,
DispatchEx_DeleteMemberByName,
DispatchEx_DeleteMemberByDispID,
DispatchEx_GetMemberProperties,
DispatchEx_GetMemberName,
DispatchEx_GetNextDispID,
DispatchEx_GetNameSpaceParent
};
static IDispatchEx funcDisp = { &testObjVtbl };
static IHTMLDocument2 *create_document(void)
{
IHTMLDocument2 *doc;
@ -234,6 +377,10 @@ static IHTMLDocument2 *create_and_load_doc(const char *str)
ULONG ref;
MSG msg;
HRESULT hres;
static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
DISPID dispID = -1;
OLECHAR *name;
doc = create_doc_with_string(str);
do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
@ -253,6 +400,12 @@ static IHTMLDocument2 *create_and_load_doc(const char *str)
return NULL;
}
/* Check we can query for function on the IHTMLElementBody interface */
name = (WCHAR*)ucPtr;
hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
ok(hres == S_OK, "GetIDsOfNames(background) failed %08x\n", hres);
ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
IHTMLElement_Release(body);
return doc;
}
@ -440,7 +593,7 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
{
IDispatchEx *document;
IUnknown *unk;
VARIANT var;
VARIANT var, arg;
DISPPARAMS dp;
EXCEPINFO ei;
DISPID id, named_arg = DISPID_PROPERTYPUT;
@ -449,6 +602,7 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
static const WCHAR documentW[] = {'d','o','c','u','m','e','n','t',0};
static const WCHAR testW[] = {'t','e','s','t',0};
static const WCHAR funcW[] = {'f','u','n','c',0};
CHECK_EXPECT(ParseScriptText);
@ -512,13 +666,46 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
IDispatchEx_Release(document);
unk = (void*)0xdeadbeef;
hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
ok(hres == S_OK, "GetNameSpaceParent failed: %08x\n", hres);
ok(!unk, "unk=%p, expected NULL\n", unk);
id = 0;
tmp = SysAllocString(funcW);
hres = IDispatchEx_GetDispID(document, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
SysFreeString(tmp);
ok(hres == S_OK, "GetDispID(func) failed: %08x\n", hres);
ok(id, "id == 0\n");
dp.cArgs = 1;
dp.rgvarg = &var;
dp.cNamedArgs = 0;
dp.rgdispidNamedArgs = NULL;
V_VT(&var) = VT_DISPATCH;
V_DISPATCH(&var) = (IDispatch*)&funcDisp;
hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
VariantInit(&var);
memset(&dp, 0, sizeof(dp));
memset(&ei, 0, sizeof(ei));
V_VT(&arg) = VT_BOOL;
V_BOOL(&arg) = VARIANT_TRUE;
dp.cArgs = 1;
dp.rgvarg = &arg;
SET_EXPECT(funcDisp);
hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_FUNC, &dp, &var, &ei, NULL);
CHECK_CALLED(funcDisp);
ok(hres == S_OK, "InvokeEx(INVOKE_FUNC) failed: %08x\n", hres);
ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
IDispatchEx_Release(document);
return S_OK;
}
@ -580,6 +767,8 @@ static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveSc
{
IActiveScriptSiteInterruptPoll *poll;
IActiveScriptSiteDebug *debug;
IServiceProvider *service;
ICanHandleException *canexpection;
LCID lcid;
HRESULT hres;
@ -603,6 +792,14 @@ static HRESULT WINAPI ActiveScript_SetScriptSite(IActiveScript *iface, IActiveSc
if(SUCCEEDED(hres))
IActiveScriptSiteDebug32_Release(debug);
hres = IActiveScriptSite_QueryInterface(pass, &IID_ICanHandleException, (void**)&canexpection);
ok(hres == E_NOINTERFACE, "Could not get IID_ICanHandleException interface: %08x\n", hres);
hres = IActiveScriptSite_QueryInterface(pass, &IID_IServiceProvider, (void**)&service);
todo_wine ok(hres == S_OK, "Could not get IServiceProvider interface: %08x\n", hres);
if(SUCCEEDED(hres))
IServiceProvider_Release(service);
site = pass;
IActiveScriptSite_AddRef(site);
return S_OK;
@ -940,16 +1137,41 @@ static void gecko_installer_workaround(BOOL disable)
RegCloseKey(hkey);
}
/* Check if Internet Explorer is configured to run in "Enhanced Security Configuration" (aka hardened mode) */
/* Note: this code is duplicated in dlls/mshtml/tests/dom.c, dlls/mshtml/tests/script.c and dlls/urlmon/tests/misc.c */
static BOOL is_ie_hardened(void)
{
HKEY zone_map;
DWORD ie_harden, type, size;
ie_harden = 0;
if(RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap",
0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
size = sizeof(DWORD);
if (RegQueryValueEx(zone_map, "IEHarden", NULL, &type, (LPBYTE) &ie_harden, &size) != ERROR_SUCCESS ||
type != REG_DWORD) {
ie_harden = 0;
}
RegCloseKey(zone_map);
}
return ie_harden != 0;
}
START_TEST(script)
{
gecko_installer_workaround(TRUE);
CoInitialize(NULL);
if(register_script_engine()) {
test_simple_script();
init_registry(FALSE);
if(winetest_interactive || ! is_ie_hardened()) {
if(register_script_engine()) {
test_simple_script();
init_registry(FALSE);
}else {
skip("Could not register TestScript engine\n");
}
}else {
skip("Could not register TestScript engine\n");
skip("IE running in Enhanced Security Configuration\n");
}
CoUninitialize();

View file

@ -0,0 +1,224 @@
/*
* Unit tests to document InternetShortcut's behaviour
*
* Copyright 2008 Damjan Jovanovic
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include <stdio.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winerror.h"
#include "shlobj.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "ole2.h"
#include "initguid.h"
#include "isguids.h"
#include "intshcut.h"
#include "wine/test.h"
static HRESULT WINAPI Unknown_QueryInterface(IUnknown *pUnknown, REFIID riid, void **ppvObject)
{
if (IsEqualGUID(&IID_IUnknown, riid))
{
*ppvObject = pUnknown;
return S_OK;
}
return E_NOINTERFACE;
}
static ULONG WINAPI Unknown_AddRef(IUnknown *pUnknown)
{
return 2;
}
static ULONG WINAPI Unknown_Release(IUnknown *pUnknown)
{
return 1;
}
static IUnknownVtbl unknownVtbl = {
Unknown_QueryInterface,
Unknown_AddRef,
Unknown_Release
};
static IUnknown unknown = {
&unknownVtbl
};
static const char *printGUID(const GUID *guid)
{
static char guidSTR[39];
if (!guid) return NULL;
sprintf(guidSTR, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
return guidSTR;
}
static void test_Aggregability(void)
{
HRESULT hr;
IUnknown *pUnknown = NULL;
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUnknown, (void**)&pUnknown);
ok(SUCCEEDED(hr), "could not create instance of CLSID_InternetShortcut with IID_IUnknown, hr = 0x%x\n", hr);
if (pUnknown)
IUnknown_Release(pUnknown);
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&pUnknown);
ok(SUCCEEDED(hr), "could not create instance of CLSID_InternetShortcut with IID_IUniformResourceLocatorA, hr = 0x%x\n", hr);
if (pUnknown)
IUnknown_Release(pUnknown);
hr = CoCreateInstance(&CLSID_InternetShortcut, &unknown, CLSCTX_ALL, &IID_IUnknown, (void**)&pUnknown);
ok(FAILED(hr), "aggregation didn't fail like it should, hr = 0x%x\n", hr);
if (pUnknown)
IUnknown_Release(pUnknown);
}
static void can_query_interface(IUnknown *pUnknown, REFIID riid)
{
HRESULT hr;
IUnknown *newInterface;
hr = IUnknown_QueryInterface(pUnknown, riid, (void**)&newInterface);
ok(SUCCEEDED(hr), "interface %s could not be queried\n", printGUID(riid));
if (SUCCEEDED(hr))
IUnknown_Release(newInterface);
}
static void test_QueryInterface(void)
{
HRESULT hr;
IUnknown *pUnknown;
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUnknown, (void**)&pUnknown);
if (SUCCEEDED(hr))
{
can_query_interface(pUnknown, &IID_IUniformResourceLocatorA);
can_query_interface(pUnknown, &IID_IUniformResourceLocatorW);
can_query_interface(pUnknown, &IID_IPersistFile);
IUnknown_Release(pUnknown);
}
else
skip("could not create a CLSID_InternetShortcut for QueryInterface tests, hr=0x%x\n", hr);
}
static CHAR *set_and_get_url(IUniformResourceLocatorA *urlA, LPCSTR input, DWORD flags)
{
HRESULT hr;
hr = urlA->lpVtbl->SetURL(urlA, input, flags);
if (SUCCEEDED(hr))
{
CHAR *output;
hr = urlA->lpVtbl->GetURL(urlA, &output);
if (SUCCEEDED(hr))
return output;
else
skip("GetUrl failed, hr=0x%x\n", hr);
}
else
skip("SetUrl (%s, 0x%x) failed, hr=0x%x\n", input, flags, hr);
return NULL;
}
static void check_string_transform(IUniformResourceLocatorA *urlA, LPCSTR input, DWORD flags, LPCSTR expectedOutput)
{
CHAR *output = set_and_get_url(urlA, input, flags);
if (output != NULL)
{
ok(lstrcmpA(output, expectedOutput) == 0, "unexpected URL change %s -> %s (expected %s)\n",
input, output, expectedOutput);
CoTaskMemFree(output);
}
}
static void test_NullURLs(void)
{
HRESULT hr;
IUniformResourceLocatorA *urlA;
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&urlA);
if (SUCCEEDED(hr))
{
LPSTR url = NULL;
hr = urlA->lpVtbl->GetURL(urlA, &url);
ok(SUCCEEDED(hr), "getting uninitialized URL unexpectedly failed, hr=0x%x\n", hr);
ok(url == NULL, "uninitialized URL is not NULL but %s\n", url);
hr = urlA->lpVtbl->SetURL(urlA, NULL, 0);
ok(SUCCEEDED(hr), "setting NULL URL unexpectedly failed, hr=0x%x\n", hr);
hr = urlA->lpVtbl->GetURL(urlA, &url);
ok(SUCCEEDED(hr), "getting NULL URL unexpectedly failed, hr=0x%x\n", hr);
ok(url == NULL, "URL unexpectedly not NULL but %s\n", url);
urlA->lpVtbl->Release(urlA);
}
else
skip("could not create a CLSID_InternetShortcut for NullURL tests, hr=0x%x\n", hr);
}
static void test_SetURLFlags(void)
{
HRESULT hr;
IUniformResourceLocatorA *urlA;
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&urlA);
if (SUCCEEDED(hr))
{
check_string_transform(urlA, "somerandomstring", 0, "somerandomstring");
check_string_transform(urlA, "www.winehq.org", 0, "www.winehq.org");
todo_wine
{
check_string_transform(urlA, "www.winehq.org", IURL_SETURL_FL_GUESS_PROTOCOL, "http://www.winehq.org/");
check_string_transform(urlA, "ftp.winehq.org", IURL_SETURL_FL_GUESS_PROTOCOL, "ftp://ftp.winehq.org/");
}
urlA->lpVtbl->Release(urlA);
}
else
skip("could not create a CLSID_InternetShortcut for SetUrl tests, hr=0x%x\n", hr);
}
static void test_InternetShortcut(void)
{
test_Aggregability();
test_QueryInterface();
test_NullURLs();
test_SetURLFlags();
}
START_TEST(intshcut)
{
OleInitialize(NULL);
test_InternetShortcut();
OleUninitialize();
}

View file

@ -0,0 +1,360 @@
/*
* Unit tests for misc shdocvw functions
*
* Copyright 2008 Detlef Riekenberg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "wininet.h"
#include "winnls.h"
#include "wine/test.h"
/* ################ */
static HMODULE hshdocvw;
static HRESULT (WINAPI *pURLSubRegQueryA)(LPCSTR, LPCSTR, DWORD, LPVOID, DWORD, DWORD);
static DWORD (WINAPI *pParseURLFromOutsideSourceA)(LPCSTR, LPSTR, LPDWORD, LPDWORD);
static DWORD (WINAPI *pParseURLFromOutsideSourceW)(LPCWSTR, LPWSTR, LPDWORD, LPDWORD);
static CHAR appdata[] = "AppData";
static CHAR common_appdata[] = "Common AppData";
static CHAR default_page_url[] = "Default_Page_URL";
static CHAR does_not_exist[] = "does_not_exist";
static CHAR regpath_iemain[] = "Software\\Microsoft\\Internet Explorer\\Main";
static CHAR regpath_shellfolders[] = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
static CHAR start_page[] = "Start Page";
/* ################ */
static const struct {
const char *url;
const char *newurl;
DWORD len;
} ParseURL_table[] = {
{"http://www.winehq.org", "http://www.winehq.org/", 22},
{"www.winehq.org", "http://www.winehq.org/", 22},
{"winehq.org", "http://winehq.org/", 18},
{"ftp.winehq.org", "ftp://ftp.winehq.org/", 21},
{"http://winehq.org", "http://winehq.org/", 18},
{"https://winehq.org", "https://winehq.org/", 19},
{"https://www.winehq.org", "https://www.winehq.org/", 23},
{"ftp://winehq.org", "ftp://winehq.org/", 17},
{"ftp://ftp.winehq.org", "ftp://ftp.winehq.org/", 21},
{"about:blank", "about:blank", 11},
{"about:home", "about:home", 10},
{"about:mozilla", "about:mozilla", 13},
/* a space at the start is not allowed */
{" http://www.winehq.org", "http://%20http://www.winehq.org", 31}
};
/* ################ */
static void init_functions(void)
{
hshdocvw = LoadLibraryA("shdocvw.dll");
pURLSubRegQueryA = (void *) GetProcAddress(hshdocvw, (LPSTR) 151);
pParseURLFromOutsideSourceA = (void *) GetProcAddress(hshdocvw, (LPSTR) 169);
pParseURLFromOutsideSourceW = (void *) GetProcAddress(hshdocvw, (LPSTR) 170);
}
/* ################ */
static void test_URLSubRegQueryA(void)
{
CHAR buffer[INTERNET_MAX_URL_LENGTH];
HRESULT hr;
DWORD used;
DWORD len;
if (!pURLSubRegQueryA) {
skip("URLSubRegQueryA not found\n");
return;
}
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
/* called by inetcpl.cpl */
hr = pURLSubRegQueryA(regpath_iemain, default_page_url, REG_SZ, buffer, INTERNET_MAX_URL_LENGTH, -1);
ok(hr == E_FAIL || hr == S_OK, "got 0x%x (expected E_FAIL or S_OK)\n", hr);
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
/* called by inetcpl.cpl */
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, INTERNET_MAX_URL_LENGTH, -1);
len = lstrlenA(buffer);
/* respect privacy: do not dump the url */
ok(hr == S_OK, "got 0x%x and %d (expected S_OK)\n", hr, len);
/* test buffer length: just large enough */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, len+1, -1);
used = lstrlenA(buffer);
/* respect privacy: do not dump the url */
ok((hr == S_OK) && (used == len),
"got 0x%x and %d (expected S_OK and %d)\n", hr, used, len);
/* no space for terminating 0: result is truncated */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, len, -1);
used = lstrlenA(buffer);
ok((hr == S_OK) && (used == len - 1),
"got 0x%x and %d (expected S_OK and %d)\n", hr, used, len - 1);
/* no space for the complete result: truncate another char */
if (len > 1) {
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, len-1, -1);
used = lstrlenA(buffer);
ok((hr == S_OK) && (used == (len - 2)),
"got 0x%x and %d (expected S_OK and %d)\n", hr, used, len - 2);
}
/* only space for the terminating 0: function still succeded */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, 1, -1);
used = lstrlenA(buffer);
ok((hr == S_OK) && !used,
"got 0x%x and %d (expected S_OK and 0)\n", hr, used);
/* size of buffer is 0, but the function still succeed.
buffer[0] is cleared in IE 5.01 and IE 5.5 (Buffer Overflow) */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, buffer, 0, -1);
used = lstrlenA(buffer);
ok( (hr == S_OK) &&
((used == INTERNET_MAX_URL_LENGTH - 1) || broken(used == 0)) ,
"got 0x%x and %d (expected S_OK and INTERNET_MAX_URL_LENGTH - 1)\n",
hr, used);
/* still succeed without a buffer for the result */
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, NULL, 0, -1);
ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
/* still succeed, when a length is given without a buffer */
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_SZ, NULL, INTERNET_MAX_URL_LENGTH, -1);
ok(hr == S_OK, "got 0x%x (expected S_OK)\n", hr);
/* this value does not exist */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, does_not_exist, REG_SZ, buffer, INTERNET_MAX_URL_LENGTH, -1);
/* random bytes are copied to the buffer */
ok((hr == E_FAIL), "got 0x%x (expected E_FAIL)\n", hr);
/* the third parameter is ignored. Is it really a type? (data is REG_SZ) */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_iemain, start_page, REG_DWORD, buffer, INTERNET_MAX_URL_LENGTH, -1);
used = lstrlenA(buffer);
ok((hr == S_OK) && (used == len),
"got 0x%x and %d (expected S_OK and %d)\n", hr, used, len);
/* the function works for HKCU and HKLM */
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_shellfolders, appdata, REG_SZ, buffer, INTERNET_MAX_URL_LENGTH, -1);
used = lstrlenA(buffer);
ok(hr == S_OK, "got 0x%x and %d (expected S_OK)\n", hr, used);
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
hr = pURLSubRegQueryA(regpath_shellfolders, common_appdata, REG_SZ, buffer, INTERNET_MAX_URL_LENGTH, -1);
used = lstrlenA(buffer);
ok(hr == S_OK, "got 0x%x and %d (expected S_OK)\n", hr, used);
/* todo: what does the last parameter mean? */
}
/* ################ */
static void test_ParseURLFromOutsideSourceA(void)
{
CHAR buffer[INTERNET_MAX_URL_LENGTH];
DWORD dummy;
DWORD maxlen;
DWORD len;
DWORD res;
int i;
if (!pParseURLFromOutsideSourceA) {
skip("ParseURLFromOutsideSourceA not found\n");
return;
}
for(i = 0; i < sizeof(ParseURL_table)/sizeof(ParseURL_table[0]); i++) {
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = sizeof(buffer);
dummy = 0;
/* on success, len+1 is returned. No idea, if someone depend on this */
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, &dummy);
/* len does not include the terminating 0, when buffer is large enough */
ok( res != 0 && len == ParseURL_table[i].len &&
!lstrcmpA(buffer, ParseURL_table[i].newurl),
"#%d: got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
i, res, len, buffer, ParseURL_table[i].len, ParseURL_table[i].newurl);
/* use the size test only for the first examples */
if (i > 4) continue;
maxlen = len;
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = maxlen + 1;
dummy = 0;
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, &dummy);
ok( res != 0 && len == ParseURL_table[i].len &&
!lstrcmpA(buffer, ParseURL_table[i].newurl),
"#%d (+1): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
i, res, len, buffer, ParseURL_table[i].len, ParseURL_table[i].newurl);
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = maxlen;
dummy = 0;
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, &dummy);
/* len includes the terminating 0, when the buffer is too small */
ok( res == 0 && len == ParseURL_table[i].len + 1,
"#%d (==): got %d and %d (expected '0' and %d)\n",
i, res, len, ParseURL_table[i].len + 1);
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = maxlen-1;
dummy = 0;
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, &dummy);
/* len includes the terminating 0 on XP SP1 and before, when the buffer is too small */
ok( res == 0 && (len == ParseURL_table[i].len || len == ParseURL_table[i].len + 1),
"#%d (-1): got %d and %d (expected '0' and %d or %d)\n",
i, res, len, ParseURL_table[i].len, ParseURL_table[i].len + 1);
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = maxlen+1;
dummy = 0;
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, NULL, &len, &dummy);
/* len does not include the terminating 0, when buffer is NULL */
ok( res == 0 && len == ParseURL_table[i].len,
"#%d (buffer): got %d and %d (expected '0' and %d)\n",
i, res, len, ParseURL_table[i].len);
if (0) {
/* that test crash on native shdocvw */
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, NULL, &dummy);
}
memset(buffer, '#', sizeof(buffer)-1);
buffer[sizeof(buffer)-1] = '\0';
len = maxlen+1;
dummy = 0;
res = pParseURLFromOutsideSourceA(ParseURL_table[i].url, buffer, &len, NULL);
ok( res != 0 && len == ParseURL_table[i].len &&
!lstrcmpA(buffer, ParseURL_table[i].newurl),
"#%d (unknown): got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
i, res, len, buffer, ParseURL_table[i].len, ParseURL_table[i].newurl);
}
}
/* ################ */
static void test_ParseURLFromOutsideSourceW(void)
{
WCHAR urlW[INTERNET_MAX_URL_LENGTH];
WCHAR bufferW[INTERNET_MAX_URL_LENGTH];
CHAR bufferA[INTERNET_MAX_URL_LENGTH];
DWORD maxlen;
DWORD dummy;
DWORD len;
DWORD res;
if (!pParseURLFromOutsideSourceW) {
skip("ParseURLFromOutsideSourceW not found\n");
return;
}
MultiByteToWideChar(CP_ACP, 0, ParseURL_table[0].url, -1, urlW, INTERNET_MAX_URL_LENGTH);
memset(bufferA, '#', sizeof(bufferA)-1);
bufferA[sizeof(bufferA) - 1] = '\0';
MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, INTERNET_MAX_URL_LENGTH);
/* len is in characters */
len = sizeof(bufferW)/sizeof(bufferW[0]);
dummy = 0;
res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL);
ok( res != 0 && len == ParseURL_table[0].len &&
!lstrcmpA(bufferA, ParseURL_table[0].newurl),
"got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
res, len, bufferA, ParseURL_table[0].len, ParseURL_table[0].newurl);
maxlen = len;
memset(bufferA, '#', sizeof(bufferA)-1);
bufferA[sizeof(bufferA) - 1] = '\0';
MultiByteToWideChar(CP_ACP, 0, bufferA, -1, bufferW, INTERNET_MAX_URL_LENGTH);
len = maxlen+1;
dummy = 0;
res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL);
/* len does not include the terminating 0, when buffer is large enough */
ok( res != 0 && len == ParseURL_table[0].len &&
!lstrcmpA(bufferA, ParseURL_table[0].newurl),
"+1: got %d and %d with '%s' (expected '!=0' and %d with '%s')\n",
res, len, bufferA, ParseURL_table[0].len, ParseURL_table[0].newurl);
len = maxlen;
dummy = 0;
res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
/* len includes the terminating 0, when the buffer is too small */
ok( res == 0 && len == ParseURL_table[0].len + 1,
"==: got %d and %d (expected '0' and %d)\n",
res, len, ParseURL_table[0].len + 1);
len = maxlen - 1;
dummy = 0;
res = pParseURLFromOutsideSourceW(urlW, bufferW, &len, &dummy);
/* len includes the terminating 0 on XP SP1 and before, when the buffer is too small */
ok( res == 0 && (len == ParseURL_table[0].len || len == ParseURL_table[0].len + 1),
"-1: got %d and %d (expected '0' and %d or %d)\n",
res, len, ParseURL_table[0].len, ParseURL_table[0].len + 1);
}
/* ################ */
START_TEST(shdocvw)
{
init_functions();
test_URLSubRegQueryA();
test_ParseURLFromOutsideSourceA();
test_ParseURLFromOutsideSourceW();
}

View file

@ -0,0 +1,23 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<group>
<module name="shdocvw_winetest" type="win32cui" installbase="bin" installname="shdocvw_winetest.exe" allowwarnings="true">
<compilerflag compiler="cc">-Wno-format</compilerflag>
<include base="shdocvw_winetest">.</include>
<define name="__ROS_LONG64__" />
<file>intshcut.c</file>
<file>shdocvw.c</file>
<file>shortcut.c</file>
<file>webbrowser.c</file>
<file>testlist.c</file>
<library>wine</library>
<library>gdi32</library>
<library>shell32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>user32</library>
<library>advapi32</library>
<library>kernel32</library>
<library>ntdll</library>
</module>
</group>

View file

@ -0,0 +1,231 @@
/*
* Unit tests to document shdocvw's 'Shell Instance Objects' features
*
* Copyright 2005 Michael Jung
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* At least since Windows 2000 it's possible to add FolderShortcut objects
* by creating some registry entries. Those objects, which refer to some
* point in the filesystem, can be registered in the shell namespace like other
* shell namespace extensions. Icons, names and filesystem location can be
* configured. This is documented at http://www.virtualplastic.net/html/ui_shell.html
* You can also google for a tool called "ShellObjectEditor" by "Tropical
* Technologies". This mechanism would be cool for wine, since we could
* map Gnome's virtual devices to FolderShortcuts and have them appear in the
* file dialogs. These unit tests are meant to document how this mechanism
* works on windows.
*
* Search MSDN for "Creating Shell Extensions with Shell Instance Objects" for
* more documentation.*/
#include <stdarg.h>
#define COBJMACROS
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "shlobj.h"
#include "shobjidl.h"
#include "shlguid.h"
#include "ole2.h"
#include "wine/test.h"
/* The following definitions and helper functions are meant to make the de-/registration
* of the various necessary registry keys easier. */
struct registry_value {
const char *szName;
const DWORD dwType;
const char *szValue;
const DWORD dwValue;
};
#define REG_VALUE_ADDR(x) ((x->dwType==REG_SZ)?(const BYTE *)x->szValue:(const BYTE *)&x->dwValue)
#define REG_VALUE_SIZE(x) ((x->dwType==REG_SZ)?strlen(x->szValue)+1:sizeof(DWORD))
struct registry_key {
const char *szName;
const struct registry_value *pValues;
const unsigned int cValues;
const struct registry_key *pSubKeys;
const unsigned int cSubKeys;
};
static const struct registry_value ShellFolder_values[] = {
{ "WantsFORPARSING", REG_SZ, "", 0 },
{ "Attributes", REG_DWORD, NULL, 0xF8000100 }
};
static const struct registry_value Instance_values[] = {
{ "CLSID", REG_SZ, "{0AFACED1-E828-11D1-9187-B532F1E9575D}", 0 }
};
static const struct registry_value InitPropertyBag_values[] = {
{ "Attributes", REG_DWORD, NULL, 0x00000015 },
{ "Target", REG_SZ, "C:\\", 0 }
};
static const struct registry_key Instance_keys[] = {
{ "InitPropertyBag", InitPropertyBag_values, 2, NULL, 0 }
};
static const struct registry_value InProcServer32_values[] = {
{ NULL, REG_SZ, "shdocvw.dll", 0 },
{ "ThreadingModel", REG_SZ, "Apartment", 0 }
};
static const struct registry_value DefaultIcon_values[] = {
{ NULL, REG_SZ,"shell32.dll,8", 0 }
};
static const struct registry_key ShortcutCLSID_keys[] = {
{ "DefaultIcon", DefaultIcon_values, 1, NULL, 0 },
{ "InProcServer32", InProcServer32_values, 2, NULL, 0 },
{ "Instance", Instance_values, 1, Instance_keys, 1 },
{ "ShellFolder", ShellFolder_values, 2, NULL, 0 }
};
static const struct registry_value ShortcutCLSID_values[] = {
{ NULL, REG_SZ, "WineTest", 0 }
};
static const struct registry_key HKEY_CLASSES_ROOT_keys[] = {
{ "CLSID\\{9B352EBF-2765-45C1-B4C6-85CC7F7ABC64}", ShortcutCLSID_values, 1, ShortcutCLSID_keys, 4}
};
/* register_keys - helper function, which recursively creates the registry keys and values in
* parameter 'keys' in the registry under hRootKey. */
static BOOL register_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
HKEY hKey;
unsigned int iKey, iValue;
for (iKey = 0; iKey < numKeys; iKey++) {
if (ERROR_SUCCESS == RegCreateKeyExA(hRootKey, keys[iKey].szName, 0, NULL, 0,
KEY_WRITE, NULL, &hKey, NULL))
{
for (iValue = 0; iValue < keys[iKey].cValues; iValue++) {
const struct registry_value * value = &keys[iKey].pValues[iValue];
if (ERROR_SUCCESS != RegSetValueExA(hKey, value->szName, 0, value->dwType,
REG_VALUE_ADDR(value), REG_VALUE_SIZE(value)))
{
RegCloseKey(hKey);
return FALSE;
}
}
if (!register_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys)) {
RegCloseKey(hKey);
return FALSE;
}
RegCloseKey(hKey);
}
}
return TRUE;
}
/* unregister_keys - clean up after register_keys */
static void unregister_keys(HKEY hRootKey, const struct registry_key *keys, unsigned int numKeys) {
HKEY hKey;
unsigned int iKey;
for (iKey = 0; iKey < numKeys; iKey++) {
if (ERROR_SUCCESS == RegOpenKeyExA(hRootKey, keys[iKey].szName, 0, DELETE, &hKey)) {
unregister_keys(hKey, keys[iKey].pSubKeys, keys[iKey].cSubKeys);
RegCloseKey(hKey);
}
RegDeleteKeyA(hRootKey, keys[iKey].szName);
}
}
static void test_ShortcutFolder(void) {
LPSHELLFOLDER pDesktopFolder, pWineTestFolder;
IPersistFolder3 *pWineTestPersistFolder;
LPITEMIDLIST pidlWineTestFolder, pidlCurFolder;
HRESULT hr;
CLSID clsid;
const CLSID CLSID_WineTest =
{ 0x9b352ebf, 0x2765, 0x45c1, { 0xb4, 0xc6, 0x85, 0xcc, 0x7f, 0x7a, 0xbc, 0x64 } };
WCHAR wszWineTestFolder[] = {
':',':','{','9','B','3','5','2','E','B','F','-','2','7','6','5','-','4','5','C','1','-',
'B','4','C','6','-','8','5','C','C','7','F','7','A','B','C','6','4','}',0 };
/* First, we register all the necessary registry keys/values for our 'WineTest'
* shell object. */
register_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
hr = SHGetDesktopFolder(&pDesktopFolder);
ok (SUCCEEDED(hr), "SHGetDesktopFolder failed! hr = %08x\n", hr);
if (FAILED(hr)) goto cleanup;
/* Convert the wszWineTestFolder string to an ITEMIDLIST. */
hr = IShellFolder_ParseDisplayName(pDesktopFolder, NULL, NULL, wszWineTestFolder, NULL,
&pidlWineTestFolder, NULL);
todo_wine
{
ok (hr == HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER),
"Expected %08x, got %08x\n", HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER), hr);
}
if (FAILED(hr)) {
IShellFolder_Release(pDesktopFolder);
goto cleanup;
}
/* FIXME: these tests are never run */
/* Bind to a WineTest folder object. There has to be some support for this in shdocvw.dll.
* This isn't implemented in wine yet.*/
hr = IShellFolder_BindToObject(pDesktopFolder, pidlWineTestFolder, NULL, &IID_IShellFolder,
(LPVOID*)&pWineTestFolder);
IShellFolder_Release(pDesktopFolder);
ILFree(pidlWineTestFolder);
ok (SUCCEEDED(hr), "IShellFolder::BindToObject(WineTestFolder) failed! hr = %08x\n", hr);
if (FAILED(hr)) goto cleanup;
hr = IShellFolder_QueryInterface(pWineTestFolder, &IID_IPersistFolder3, (LPVOID*)&pWineTestPersistFolder);
ok (SUCCEEDED(hr), "IShellFolder::QueryInterface(IPersistFolder3) failed! hr = %08x\n", hr);
IShellFolder_Release(pWineTestFolder);
if (FAILED(hr)) goto cleanup;
/* The resulting folder object has the FolderShortcut CLSID, instead of it's own. */
hr = IPersistFolder3_GetClassID(pWineTestPersistFolder, &clsid);
ok (SUCCEEDED(hr), "IPersist::GetClassID failed! hr = %08x\n", hr);
ok (IsEqualCLSID(&CLSID_FolderShortcut, &clsid), "GetClassId returned wrong CLSID!\n");
pidlCurFolder = (LPITEMIDLIST)0xdeadbeef;
hr = IPersistFolder3_GetCurFolder(pWineTestPersistFolder, &pidlCurFolder);
ok (SUCCEEDED(hr), "IPersistFolder3::GetCurFolder failed! hr = %08x\n", hr);
ok (pidlCurFolder->mkid.cb == 20 && ((LPSHITEMID)((BYTE*)pidlCurFolder+20))->cb == 0 &&
IsEqualCLSID(&CLSID_WineTest, (REFCLSID)((LPBYTE)pidlCurFolder+4)),
"GetCurFolder returned unexpected pidl!\n");
IPersistFolder3_Release(pWineTestPersistFolder);
cleanup:
unregister_keys(HKEY_CLASSES_ROOT, HKEY_CLASSES_ROOT_keys, 1);
}
START_TEST(shortcut)
{
OleInitialize(NULL);
test_ShortcutFolder();
OleUninitialize();
}

View file

@ -0,0 +1,22 @@
/* Automatically generated file; DO NOT EDIT!! */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define STANDALONE
#include "wine/test.h"
extern void func_intshcut(void);
extern void func_shdocvw(void);
extern void func_shortcut(void);
extern void func_protocol(void);
extern void func_webbrowser(void);
const struct test winetest_testlist[] =
{
{ "intshcut", func_intshcut },
{ "shdocvw", func_shdocvw },
{ "shortcut", func_shortcut },
{ "webbrowser", func_webbrowser },
{ 0, 0 }
};

File diff suppressed because it is too large Load diff