include: Specify calling convention explicitly in idl files where needed.
[wine/hramrach.git] / dlls / sti / tests / sti.c
blob7b9aadef5a4b688f790cbb32a2e8c71107d24cf8
1 /*
2 * General still image implementation
4 * Copyright 2009 Damjan Jovanovic
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
21 #include <stdarg.h>
22 #include <assert.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #define COBJMACROS
26 #include <initguid.h>
27 #include <sti.h>
28 #include <guiddef.h>
29 #include <devguid.h>
30 #include <stdio.h>
32 #include "wine/test.h"
34 static HMODULE sti_dll;
35 static HRESULT (WINAPI *pStiCreateInstance)(HINSTANCE,DWORD,PSTIW*,LPUNKNOWN);
36 static HRESULT (WINAPI *pStiCreateInstanceA)(HINSTANCE,DWORD,PSTIA*,LPUNKNOWN);
37 static HRESULT (WINAPI *pStiCreateInstanceW)(HINSTANCE,DWORD,PSTIW*,LPUNKNOWN);
39 static BOOL aggregator_addref_called;
41 static HRESULT WINAPI aggregator_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
43 return E_NOTIMPL;
46 static ULONG WINAPI aggregator_AddRef(IUnknown *iface)
48 aggregator_addref_called = TRUE;
49 return 2;
52 static ULONG WINAPI aggregator_Release(IUnknown *iface)
54 return 1;
57 static struct IUnknownVtbl aggregator_vtbl =
59 aggregator_QueryInterface,
60 aggregator_AddRef,
61 aggregator_Release
64 static BOOL init_function_pointers(void)
66 sti_dll = LoadLibrary("sti.dll");
67 if (sti_dll)
69 pStiCreateInstance = (void*)
70 GetProcAddress(sti_dll, "StiCreateInstance");
71 pStiCreateInstanceA = (void*)
72 GetProcAddress(sti_dll, "StiCreateInstanceA");
73 pStiCreateInstanceW = (void*)
74 GetProcAddress(sti_dll, "StiCreateInstanceW");
75 return TRUE;
77 return FALSE;
80 static void test_version_flag_versus_aw(void)
82 HRESULT hr;
84 /* Who wins, the STI_VERSION_FLAG_UNICODE or the A/W function? And what about the neutral StiCreateInstance function? */
86 if (pStiCreateInstance)
88 PSTIW pStiW;
89 hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, NULL);
90 if (SUCCEEDED(hr))
92 IUnknown *pUnknown;
93 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
94 if (SUCCEEDED(hr))
96 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
97 IUnknown_Release(pUnknown);
99 IUnknown_Release((IUnknown*)pStiW);
101 else
102 ok(0, "could not create StillImageA, hr = 0x%X\n", hr);
103 hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL);
104 if (SUCCEEDED(hr))
106 IUnknown *pUnknown;
107 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
108 if (SUCCEEDED(hr))
110 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
111 IUnknown_Release(pUnknown);
113 IUnknown_Release((IUnknown*)pStiW);
115 else
116 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
118 else
119 skip("No StiCreateInstance function\n");
121 if (pStiCreateInstanceA)
123 PSTIA pStiA;
124 hr = pStiCreateInstanceA(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiA, NULL);
125 if (SUCCEEDED(hr))
127 IUnknown *pUnknown;
128 hr = IUnknown_QueryInterface((IUnknown*)pStiA, &IID_IStillImageA, (void**)&pUnknown);
129 if (SUCCEEDED(hr))
131 ok(pUnknown == (IUnknown*)pStiA, "created interface was not IID_IStillImageA\n");
132 IUnknown_Release(pUnknown);
134 IUnknown_Release((IUnknown*)pStiA);
136 else
137 todo_wine ok(0, "could not create StillImageA, hr = 0x%X\n", hr);
139 else
140 skip("No StiCreateInstanceA function\n");
142 if (pStiCreateInstanceW)
144 PSTIW pStiW;
145 hr = pStiCreateInstanceW(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, NULL);
146 if (SUCCEEDED(hr))
148 IUnknown *pUnknown;
149 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
150 if (SUCCEEDED(hr))
152 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
153 IUnknown_Release((IUnknown*)pUnknown);
155 IUnknown_Release((IUnknown*)pStiW);
157 else
158 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
160 else
161 skip("No StiCreateInstanceW function\n");
164 static void test_stillimage_aggregation(void)
166 if (pStiCreateInstanceW)
168 IUnknown aggregator = { &aggregator_vtbl };
169 IStillImageW *pStiW;
170 IUnknown *pUnknown;
171 HRESULT hr;
173 /* When aggregating, the outer object must get the non-delegating IUnknown to be
174 able to control the inner object's reference count and query its interfaces.
175 But StiCreateInstance* only take PSTI. So how does the non-delegating IUnknown
176 come back to the outer object calling this function? */
178 hr = pStiCreateInstanceW(GetModuleHandle(NULL), STI_VERSION_REAL, &pStiW, &aggregator);
179 if (SUCCEEDED(hr))
181 IStillImageW *pStiW2 = NULL;
183 /* Does this interface delegate? */
184 aggregator_addref_called = FALSE;
185 IStillImage_AddRef(pStiW);
186 ok(!aggregator_addref_called, "the aggregated IStillImageW shouldn't delegate\n");
187 IStillImage_Release(pStiW);
189 /* Tests show calling IStillImageW_WriteToErrorLog on the interface segfaults on Windows, so I guess it's an IUnknown.
190 But querying for an IUnknown returns a different interface, which also delegates.
191 So much for COM being reflexive...
192 Anyway I doubt apps depend on any of this. */
194 /* And what about the IStillImageW interface? */
195 hr = IStillImage_QueryInterface(pStiW, &IID_IStillImageW, (void**)&pStiW2);
196 if (SUCCEEDED(hr))
198 ok(pStiW != pStiW2, "the aggregated IStillImageW and its queried IStillImageW unexpectedly match\n");
199 /* Does it delegate? */
200 aggregator_addref_called = FALSE;
201 IStillImage_AddRef(pStiW2);
202 ok(aggregator_addref_called, "the created IStillImageW's IStillImageW should delegate\n");
203 IStillImage_Release(pStiW2);
204 IStillImage_Release(pStiW2);
206 else
207 ok(0, "could not query for IID_IStillImageW, hr = 0x%x\n", hr);
209 IStillImage_Release(pStiW);
211 else
212 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
214 /* Now do the above tests prove that STI.DLL isn't picky about querying for IUnknown
215 in CoCreateInterface when aggregating? */
216 hr = CoCreateInstance(&CLSID_Sti, &aggregator, CLSCTX_ALL, &IID_IStillImageW, (void**)&pStiW);
217 ok(FAILED(hr), "CoCreateInstance unexpectedly succeeded when querying for IStillImageW during aggregation\n");
218 if (SUCCEEDED(hr))
219 IStillImage_Release(pStiW);
220 hr = CoCreateInstance(&CLSID_Sti, &aggregator, CLSCTX_ALL, &IID_IUnknown, (void**)&pUnknown);
221 ok(SUCCEEDED(hr) ||
222 broken(hr == CLASS_E_NOAGGREGATION), /* Win 2000 */
223 "CoCreateInstance unexpectedly failed when querying for IUnknown during aggregation, hr = 0x%x\n", hr);
224 if (SUCCEEDED(hr))
225 IUnknown_Release(pUnknown);
227 else
228 skip("No StiCreateInstanceW function\n");
231 static void test_launch_app_registry(void)
233 static WCHAR appName[] = {'w','i','n','e','s','t','i','t','e','s','t','a','p','p',0};
234 IStillImageW *pStiW = NULL;
235 HRESULT hr;
237 if (pStiCreateInstanceW == NULL)
239 win_skip("No StiCreateInstanceW function\n");
240 return;
243 hr = pStiCreateInstance(GetModuleHandle(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL);
244 if (SUCCEEDED(hr))
246 hr = IStillImage_RegisterLaunchApplication(pStiW, appName, appName);
247 ok(SUCCEEDED(hr), "could not register launch application, error 0x%X\n", hr);
248 if (SUCCEEDED(hr))
250 hr = IStillImage_UnregisterLaunchApplication(pStiW, appName);
251 ok(SUCCEEDED(hr), "could not unregister launch application, error 0x%X\n", hr);
253 IStillImage_Release(pStiW);
255 else
256 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
259 START_TEST(sti)
261 if (SUCCEEDED(CoInitialize(NULL)))
263 if (init_function_pointers())
265 test_version_flag_versus_aw();
266 test_stillimage_aggregation();
267 test_launch_app_registry();
268 FreeLibrary(sti_dll);
270 else
271 skip("could not load sti.dll\n");
272 CoUninitialize();
274 else
275 skip("CoInitialize failed\n");