mirror of
https://github.com/reactos/reactos.git
synced 2025-04-20 12:29:56 +00:00
sync mshtml and shdocvw winetests with wine 1.1.14
svn path=/trunk/; revision=39390
This commit is contained in:
parent
cc12355d0e
commit
43eb75a9e4
12 changed files with 5053 additions and 142 deletions
|
@ -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
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
224
rostests/winetests/shdocvw/intshcut.c
Normal file
224
rostests/winetests/shdocvw/intshcut.c
Normal 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();
|
||||
}
|
360
rostests/winetests/shdocvw/shdocvw.c
Normal file
360
rostests/winetests/shdocvw/shdocvw.c
Normal 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();
|
||||
}
|
23
rostests/winetests/shdocvw/shdocvw.rbuild
Normal file
23
rostests/winetests/shdocvw/shdocvw.rbuild
Normal 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>
|
231
rostests/winetests/shdocvw/shortcut.c
Normal file
231
rostests/winetests/shdocvw/shortcut.c
Normal 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();
|
||||
}
|
22
rostests/winetests/shdocvw/testlist.c
Normal file
22
rostests/winetests/shdocvw/testlist.c
Normal 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 }
|
||||
};
|
2137
rostests/winetests/shdocvw/webbrowser.c
Normal file
2137
rostests/winetests/shdocvw/webbrowser.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue