ReactOS 0.4.15-dev-7788-g1ad9096
sti.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include <initguid.h>
#include <sti.h>
#include <guiddef.h>
#include <devguid.h>
#include <stdio.h>
#include "wine/test.h"
Include dependency graph for sti.c:

Go to the source code of this file.

Macros

#define COBJMACROS
 

Functions

static HRESULT (WINAPI *pStiCreateInstance)(HINSTANCE
 
static HRESULT WINAPI aggregator_QueryInterface (IUnknown *iface, REFIID riid, void **ppvObject)
 
static ULONG WINAPI aggregator_AddRef (IUnknown *iface)
 
static ULONG WINAPI aggregator_Release (IUnknown *iface)
 
static BOOL init_function_pointers (void)
 
static void test_version_flag_versus_aw (void)
 
static void test_stillimage_aggregation (void)
 
static void test_launch_app_registry (void)
 
 START_TEST (sti)
 

Variables

static HMODULE sti_dll
 
static DWORD
 
static PSTIW LPUNKNOWN
 
static BOOL aggregator_addref_called
 
static struct IUnknownVtbl aggregator_vtbl
 

Macro Definition Documentation

◆ COBJMACROS

#define COBJMACROS

Definition at line 25 of file sti.c.

Function Documentation

◆ aggregator_AddRef()

static ULONG WINAPI aggregator_AddRef ( IUnknown iface)
static

Definition at line 46 of file sti.c.

47{
49 return 2;
50}
#define TRUE
Definition: types.h:120
static BOOL aggregator_addref_called
Definition: sti.c:39

◆ aggregator_QueryInterface()

static HRESULT WINAPI aggregator_QueryInterface ( IUnknown iface,
REFIID  riid,
void **  ppvObject 
)
static

Definition at line 41 of file sti.c.

42{
43 return E_NOTIMPL;
44}
#define E_NOTIMPL
Definition: ddrawi.h:99

◆ aggregator_Release()

static ULONG WINAPI aggregator_Release ( IUnknown iface)
static

Definition at line 52 of file sti.c.

53{
54 return 1;
55}

◆ HRESULT()

static HRESULT ( WINAPI pStiCreateInstance)
static

◆ init_function_pointers()

static BOOL init_function_pointers ( void  )
static

Definition at line 64 of file sti.c.

65{
66 sti_dll = LoadLibraryA("sti.dll");
67 if (sti_dll)
68 {
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;
76 }
77 return FALSE;
78}
#define FALSE
Definition: types.h:117
#define GetProcAddress(x, y)
Definition: compat.h:753
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
static HMODULE sti_dll
Definition: sti.c:34

Referenced by START_TEST().

◆ START_TEST()

START_TEST ( sti  )

Definition at line 262 of file sti.c.

263{
265 {
267 {
272 }
273 else
274 skip("could not load sti.dll\n");
276 }
277 else
278 skip("CoInitialize failed\n");
279}
#define skip(...)
Definition: atltest.h:64
#define NULL
Definition: types.h:112
#define FreeLibrary(x)
Definition: compat.h:748
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
#define SUCCEEDED(hr)
Definition: intsafe.h:50
static void test_stillimage_aggregation(void)
Definition: sti.c:164
static BOOL init_function_pointers(void)
Definition: sti.c:64
static void test_launch_app_registry(void)
Definition: sti.c:231
static void test_version_flag_versus_aw(void)
Definition: sti.c:80

◆ test_launch_app_registry()

static void test_launch_app_registry ( void  )
static

Definition at line 231 of file sti.c.

232{
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;
236
237 if (pStiCreateInstanceW == NULL)
238 {
239 win_skip("No StiCreateInstanceW function\n");
240 return;
241 }
242
243 hr = pStiCreateInstance(GetModuleHandleA(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL);
244 if (SUCCEEDED(hr))
245 {
247 if (hr == E_ACCESSDENIED)
248 skip("Not authorized to register a launch application\n");
249 else if (SUCCEEDED(hr))
250 {
252 ok(SUCCEEDED(hr), "could not unregister launch application, error 0x%X\n", hr);
253 }
254 else
255 ok(0, "could not register launch application, error 0x%X\n", hr);
256 IStillImage_Release(pStiW);
257 }
258 else
259 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
260}
#define ok(value,...)
Definition: atltest.h:57
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
const char * appName(const char *argv0)
Definition: loadlib.c:89
#define win_skip
Definition: test.h:160
HRESULT hr
Definition: shlfolder.c:183
#define STI_VERSION_FLAG_UNICODE
Definition: sti.h:39
#define IStillImage_Release(p)
Definition: sti.h:135
#define IStillImage_UnregisterLaunchApplication(p, a)
Definition: sti.h:145
#define IStillImage_RegisterLaunchApplication(p, a, b)
Definition: sti.h:144
#define STI_VERSION_REAL
Definition: sti.h:38
#define E_ACCESSDENIED
Definition: winerror.h:2849
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by START_TEST().

◆ test_stillimage_aggregation()

static void test_stillimage_aggregation ( void  )
static

Definition at line 164 of file sti.c.

165{
166 if (pStiCreateInstanceW)
167 {
168 IUnknown aggregator = { &aggregator_vtbl };
169 IStillImageW *pStiW;
171 HRESULT hr;
172
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? */
177
178 hr = pStiCreateInstanceW(GetModuleHandleA(NULL), STI_VERSION_REAL, &pStiW, &aggregator);
179 if (SUCCEEDED(hr))
180 {
181 IStillImageW *pStiW2 = NULL;
182
183 /* Does this interface delegate? */
185 IStillImage_AddRef(pStiW);
186 ok(!aggregator_addref_called, "the aggregated IStillImageW shouldn't delegate\n");
187 IStillImage_Release(pStiW);
188
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. */
193
194 /* And what about the IStillImageW interface? */
195 hr = IStillImage_QueryInterface(pStiW, &IID_IStillImageW, (void**)&pStiW2);
196 if (SUCCEEDED(hr))
197 {
198 ok(pStiW != pStiW2, "the aggregated IStillImageW and its queried IStillImageW unexpectedly match\n");
199 /* Does it delegate? */
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);
205 }
206 else
207 ok(0, "could not query for IID_IStillImageW, hr = 0x%x\n", hr);
208
209 IStillImage_Release(pStiW);
210 }
211 else
212 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
213
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);
226 }
227 else
228 skip("No StiCreateInstanceW function\n");
229}
#define broken(x)
Definition: _sntprintf.h:21
const GUID IID_IUnknown
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
#define FAILED(hr)
Definition: intsafe.h:51
static struct IUnknownVtbl aggregator_vtbl
Definition: sti.c:57
#define IStillImage_AddRef(p)
Definition: sti.h:134
#define IStillImage_QueryInterface(p, a, b)
Definition: sti.h:133
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662

Referenced by START_TEST().

◆ test_version_flag_versus_aw()

static void test_version_flag_versus_aw ( void  )
static

Definition at line 80 of file sti.c.

81{
82 HRESULT hr;
83
84 /* Who wins, the STI_VERSION_FLAG_UNICODE or the A/W function? And what about the neutral StiCreateInstance function? */
85
86 if (pStiCreateInstance)
87 {
88 PSTIW pStiW;
89 hr = pStiCreateInstance(GetModuleHandleA(NULL), STI_VERSION_REAL, &pStiW, NULL);
90 if (SUCCEEDED(hr))
91 {
93 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
94 if (SUCCEEDED(hr))
95 {
96 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
97 IUnknown_Release(pUnknown);
98 }
99 IUnknown_Release((IUnknown*)pStiW);
100 }
101 else
102 ok(0, "could not create StillImageA, hr = 0x%X\n", hr);
103 hr = pStiCreateInstance(GetModuleHandleA(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiW, NULL);
104 if (SUCCEEDED(hr))
105 {
107 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
108 if (SUCCEEDED(hr))
109 {
110 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
111 IUnknown_Release(pUnknown);
112 }
113 IUnknown_Release((IUnknown*)pStiW);
114 }
115 else
116 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
117 }
118 else
119 skip("No StiCreateInstance function\n");
120
121 if (pStiCreateInstanceA)
122 {
123 PSTIA pStiA;
124 hr = pStiCreateInstanceA(GetModuleHandleA(NULL), STI_VERSION_REAL | STI_VERSION_FLAG_UNICODE, &pStiA, NULL);
125 if (SUCCEEDED(hr))
126 {
128 hr = IUnknown_QueryInterface((IUnknown*)pStiA, &IID_IStillImageA, (void**)&pUnknown);
129 if (SUCCEEDED(hr))
130 {
131 ok(pUnknown == (IUnknown*)pStiA, "created interface was not IID_IStillImageA\n");
132 IUnknown_Release(pUnknown);
133 }
134 IUnknown_Release((IUnknown*)pStiA);
135 }
136 else
137 todo_wine ok(0, "could not create StillImageA, hr = 0x%X\n", hr);
138 }
139 else
140 skip("No StiCreateInstanceA function\n");
141
142 if (pStiCreateInstanceW)
143 {
144 PSTIW pStiW;
145 hr = pStiCreateInstanceW(GetModuleHandleA(NULL), STI_VERSION_REAL, &pStiW, NULL);
146 if (SUCCEEDED(hr))
147 {
149 hr = IUnknown_QueryInterface((IUnknown*)pStiW, &IID_IStillImageW, (void**)&pUnknown);
150 if (SUCCEEDED(hr))
151 {
152 ok(pUnknown == (IUnknown*)pStiW, "created interface was not IID_IStillImageW\n");
153 IUnknown_Release(pUnknown);
154 }
155 IUnknown_Release((IUnknown*)pStiW);
156 }
157 else
158 ok(0, "could not create StillImageW, hr = 0x%X\n", hr);
159 }
160 else
161 skip("No StiCreateInstanceW function\n");
162}
#define todo_wine
Definition: custom.c:79
struct IStillImageW * PSTIW
Definition: sti.h:50
struct IStillImageA * PSTIA
Definition: sti.h:49

Referenced by START_TEST().

Variable Documentation

◆ aggregator_addref_called

BOOL aggregator_addref_called
static

Definition at line 39 of file sti.c.

Referenced by aggregator_AddRef(), and test_stillimage_aggregation().

◆ aggregator_vtbl

struct IUnknownVtbl aggregator_vtbl
static
Initial value:
=
{
}
static ULONG WINAPI aggregator_Release(IUnknown *iface)
Definition: sti.c:52
static ULONG WINAPI aggregator_AddRef(IUnknown *iface)
Definition: sti.c:46
static HRESULT WINAPI aggregator_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
Definition: sti.c:41

Definition at line 57 of file sti.c.

Referenced by test_stillimage_aggregation().

◆ DWORD

Definition at line 35 of file sti.c.

◆ LPUNKNOWN

PSTIW LPUNKNOWN

Definition at line 35 of file sti.c.

◆ sti_dll

HMODULE sti_dll
static

Definition at line 34 of file sti.c.

Referenced by init_function_pointers(), and START_TEST().