2 * Default Handler Tests
4 * Copyright 2008 Huw Davies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/test.h"
33 #define DEFINE_EXPECT(func) \
34 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
36 #define SET_EXPECT(func) \
37 expect_ ## func = TRUE
39 #define CHECK_EXPECT2(func) \
41 ok(expect_ ##func, "unexpected call " #func "\n"); \
42 called_ ## func = TRUE; \
45 #define CHECK_EXPECT(func) \
47 CHECK_EXPECT2(func); \
48 expect_ ## func = FALSE; \
51 #define CHECK_CALLED(func) \
53 ok(called_ ## func, "expected " #func "\n"); \
54 expect_ ## func = called_ ## func = FALSE; \
57 #define CHECK_NOT_CALLED(func) \
59 ok(!called_ ## func, "unexpected " #func "\n"); \
60 expect_ ## func = called_ ## func = FALSE; \
63 DEFINE_EXPECT(CF_QueryInterface_ClassFactory
);
64 DEFINE_EXPECT(CF_CreateInstance
);
65 DEFINE_EXPECT(CF_QueryInterface_IMarshal
);
67 static HRESULT
create_storage(IStorage
**stg
)
70 ILockBytes
*lock_bytes
;
72 hr
= CreateILockBytesOnHGlobal(NULL
, TRUE
, &lock_bytes
);
75 hr
= StgCreateDocfileOnILockBytes(lock_bytes
,
76 STGM_CREATE
| STGM_SHARE_EXCLUSIVE
| STGM_READWRITE
, 0, stg
);
77 ILockBytes_Release(lock_bytes
);
86 DWORD link_update_opt
;
89 } ole_stream_header_t
;
91 static void test_olestream(void)
94 const CLSID non_existent_class
= {0xa5f1772f, 0x3772, 0x490f, {0x9e, 0xc6, 0x77, 0x13, 0xe8, 0xb3, 0x4b, 0x5d}};
96 IPersistStorage
*persist
;
99 static const WCHAR olestream
[] = {1,'O','l','e',0};
101 ole_stream_header_t header
;
103 hr
= create_storage(&stg
);
104 ok(hr
== S_OK
, "got %08x\n", hr
);
106 hr
= IStorage_OpenStream(stg
, olestream
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, &stm
);
107 ok(hr
== STG_E_FILENOTFOUND
, "got %08x\n", hr
);
109 hr
= OleCreateDefaultHandler(&non_existent_class
, 0, &IID_IOleObject
, (void**)&ole_obj
);
110 ok(hr
== S_OK
, "got %08x\n", hr
);
112 hr
= IOleObject_QueryInterface(ole_obj
, &IID_IPersistStorage
, (void**)&persist
);
113 ok(hr
== S_OK
, "got %08x\n", hr
);
115 hr
= IPersistStorage_InitNew(persist
, stg
);
116 ok(hr
== S_OK
, "got %08x\n", hr
);
118 hr
= IStorage_OpenStream(stg
, olestream
, NULL
, STGM_SHARE_EXCLUSIVE
| STGM_READ
, 0, &stm
);
119 ok(hr
== S_OK
, "got %08x\n", hr
);
120 hr
= IStream_Read(stm
, &header
, sizeof(header
), &read
);
121 ok(hr
== S_OK
, "got %08x\n", hr
);
122 ok(read
== sizeof(header
), "read %d\n", read
);
123 ok(header
.version
== 0x02000001, "got version %08x\n", header
.version
);
124 ok(header
.flags
== 0x0, "got flags %08x\n", header
.flags
);
125 ok(header
.link_update_opt
== 0x0, "got link update option %08x\n", header
.link_update_opt
);
126 ok(header
.res
== 0x0, "got reserved %08x\n", header
.res
);
127 ok(header
.moniker_size
== 0x0, "got moniker size %08x\n", header
.moniker_size
);
129 IStream_Release(stm
);
131 IPersistStorage_Release(persist
);
132 IOleObject_Release(ole_obj
);
134 IStorage_Release(stg
);
137 static HRESULT WINAPI
test_class_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
139 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
142 }else if(IsEqualGUID(riid
, &IID_IOleObject
)) {
143 ok(0, "unexpected query for IOleObject interface\n");
145 return E_NOINTERFACE
;
149 return E_NOINTERFACE
;
152 static ULONG WINAPI
test_class_AddRef(IUnknown
*iface
)
157 static ULONG WINAPI
test_class_Release(IUnknown
*iface
)
162 static const IUnknownVtbl test_class_vtbl
= {
163 test_class_QueryInterface
,
168 static IUnknown test_class
= { &test_class_vtbl
};
170 static HRESULT WINAPI
ClassFactory_QueryInterface(IClassFactory
*iface
, REFIID riid
, void **ppv
)
172 if(IsEqualGUID(riid
, &IID_IUnknown
)) {
175 }else if(IsEqualGUID(riid
, &IID_IMarshal
)) {
176 CHECK_EXPECT(CF_QueryInterface_IMarshal
);
178 return E_NOINTERFACE
;
179 }else if(IsEqualGUID(riid
, &IID_IClassFactory
)) {
180 CHECK_EXPECT(CF_QueryInterface_ClassFactory
);
185 ok(0, "unexpected interface: %s\n", wine_dbgstr_guid(riid
));
187 return E_NOINTERFACE
;
190 static ULONG WINAPI
ClassFactory_AddRef(IClassFactory
*iface
)
195 static ULONG WINAPI
ClassFactory_Release(IClassFactory
*iface
)
200 static HRESULT WINAPI
ClassFactory_CreateInstance(IClassFactory
*iface
,
201 IUnknown
*pUnkOuter
, REFIID riid
, void **ppv
)
203 CHECK_EXPECT(CF_CreateInstance
);
205 ok(pUnkOuter
== NULL
, "pUnkOuter != NULL\n");
206 todo_wine
ok(IsEqualGUID(riid
, &IID_IUnknown
), "riid = %s\n", wine_dbgstr_guid(riid
));
207 if(IsEqualGUID(riid
, &IID_IOleObject
)) {
209 return E_NOINTERFACE
;
216 static HRESULT WINAPI
ClassFactory_LockServer(IClassFactory
*iface
, BOOL fLock
)
218 ok(0, "unexpected call\n");
222 static const IClassFactoryVtbl ClassFactoryVtbl
= {
223 ClassFactory_QueryInterface
,
225 ClassFactory_Release
,
226 ClassFactory_CreateInstance
,
227 ClassFactory_LockServer
230 static IClassFactory ClassFactory
= { &ClassFactoryVtbl
};
232 static void test_default_handler_run(void)
234 const CLSID test_server_clsid
= {0x0f77e570,0x80c3,0x11e2,{0x9e,0x96,0x08,0x00,0x20,0x0c,0x9a,0x66}};
239 IPersistStorage
*persist
;
243 if(!GetProcAddress(GetModuleHandleA("ole32"), "CoRegisterSurrogateEx")) {
244 win_skip("skipping OleCreateDefaultHandler tests\n");
248 hres
= CoRegisterClassObject(&test_server_clsid
, (IUnknown
*)&ClassFactory
,
249 CLSCTX_INPROC_SERVER
, 0, &class_reg
);
250 ok(hres
== S_OK
, "CoRegisterClassObject failed: %x\n", hres
);
252 hres
= OleCreateDefaultHandler(&test_server_clsid
, NULL
, &IID_IUnknown
, (void**)&unk
);
253 ok(hres
== S_OK
, "OleCreateDefaultHandler failed: %x\n", hres
);
255 hres
= IUnknown_QueryInterface(unk
, &IID_IRunnableObject
, (void**)&ro
);
256 ok(hres
== S_OK
, "QueryInterface(IRunnableObject) failed: %x\n", hres
);
257 IUnknown_Release(unk
);
259 hres
= IRunnableObject_Run(ro
, NULL
);
260 ok(hres
== REGDB_E_CLASSNOTREG
, "Run returned: %x, expected REGDB_E_CLASSNOTREG\n", hres
);
261 IRunnableObject_Release(ro
);
263 SET_EXPECT(CF_QueryInterface_IMarshal
);
264 CoRevokeClassObject(class_reg
);
265 todo_wine
CHECK_CALLED(CF_QueryInterface_IMarshal
);
267 hres
= CoRegisterClassObject(&test_server_clsid
, (IUnknown
*)&ClassFactory
,
268 CLSCTX_LOCAL_SERVER
, 0, &class_reg
);
269 ok(hres
== S_OK
, "CoRegisterClassObject failed: %x\n", hres
);
271 hres
= OleCreateDefaultHandler(&test_server_clsid
, NULL
, &IID_IUnknown
, (void**)&unk
);
272 ok(hres
== S_OK
, "OleCreateDefaultHandler failed: %x\n", hres
);
274 hres
= IUnknown_QueryInterface(unk
, &IID_IOleObject
, (void**)&oleobj
);
275 ok(hres
== S_OK
, "QueryInterface(IID_IOleObject) failed: %x\n", hres
);
277 hres
= IOleObject_QueryInterface(oleobj
, &IID_IPersistStorage
, (void**)&persist
);
278 ok(hres
== S_OK
, "QueryInterface(IID_IPersistStorage) failed: %x\n", hres
);
279 IPersistStorage_Release(persist
);
280 IOleObject_Release(oleobj
);
282 hres
= IUnknown_QueryInterface(unk
, &IID_IRunnableObject
, (void**)&ro
);
283 ok(hres
== S_OK
, "QueryInterface(IRunnableObject) failed: %x\n", hres
);
284 IUnknown_Release(unk
);
286 SET_EXPECT(CF_QueryInterface_ClassFactory
);
287 SET_EXPECT(CF_CreateInstance
);
288 hres
= IRunnableObject_Run(ro
, NULL
);
290 ok(hres
== S_OK
, "Run failed: %x\n", hres
);
291 CHECK_CALLED(CF_QueryInterface_ClassFactory
);
292 CHECK_CALLED(CF_CreateInstance
);
293 IRunnableObject_Release(ro
);
295 SET_EXPECT(CF_QueryInterface_ClassFactory
);
296 SET_EXPECT(CF_CreateInstance
);
297 hres
= CoCreateInstance(&test_server_clsid
, NULL
, CLSCTX_LOCAL_SERVER
,
298 &IID_IOleObject
, (void**)&oleobj
);
300 ok(hres
== REGDB_E_CLASSNOTREG
, "expected REGDB_E_CLASSNOTREG, got %x\n", hres
);
302 CHECK_NOT_CALLED(CF_QueryInterface_ClassFactory
);
304 CHECK_NOT_CALLED(CF_CreateInstance
);
306 SET_EXPECT(CF_QueryInterface_IMarshal
);
307 CoRevokeClassObject(class_reg
);
308 todo_wine
CHECK_CALLED(CF_QueryInterface_IMarshal
);
311 START_TEST(defaulthandler
)
316 test_default_handler_run();