xref: /reactos/dll/win32/sti/sti.c (revision 019f21ee)
1 /*
2  * Copyright (C) 2002 Aric Stewart for CodeWeavers
3  * Copyright (C) 2009 Damjan Jovanovic
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include <stdarg.h>
21 #ifdef __REACTOS__
22 #include <wchar.h>
23 #endif
24 
25 #define COBJMACROS
26 
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winreg.h"
30 #include "winerror.h"
31 #include "objbase.h"
32 #include "sti.h"
33 
34 #include "wine/debug.h"
35 
36 WINE_DEFAULT_DEBUG_CHANNEL(sti);
37 
38 static const WCHAR registeredAppsLaunchPath[] = {
39     'S','O','F','T','W','A','R','E','\\',
40     'M','i','c','r','o','s','o','f','t','\\',
41     'W','i','n','d','o','w','s','\\',
42     'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
43     'S','t','i','l','l','I','m','a','g','e','\\',
44     'R','e','g','i','s','t','e','r','e','d',' ','A','p','p','l','i','c','a','t','i','o','n','s',0
45 };
46 
47 typedef struct _stillimage
48 {
49     IUnknown IUnknown_inner;
50     IStillImageW IStillImageW_iface;
51     IUnknown *outer_unk;
52     LONG ref;
53 } stillimage;
54 
55 static inline stillimage *impl_from_IStillImageW(IStillImageW *iface)
56 {
57     return CONTAINING_RECORD(iface, stillimage, IStillImageW_iface);
58 }
59 
60 static HRESULT WINAPI stillimagew_QueryInterface(IStillImageW *iface, REFIID riid, void **ppvObject)
61 {
62     stillimage *This = impl_from_IStillImageW(iface);
63     TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
64     return IUnknown_QueryInterface(This->outer_unk, riid, ppvObject);
65 }
66 
67 static ULONG WINAPI stillimagew_AddRef(IStillImageW *iface)
68 {
69     stillimage *This = impl_from_IStillImageW(iface);
70     return IUnknown_AddRef(This->outer_unk);
71 }
72 
73 static ULONG WINAPI stillimagew_Release(IStillImageW *iface)
74 {
75     stillimage *This = impl_from_IStillImageW(iface);
76     return IUnknown_Release(This->outer_unk);
77 }
78 
79 static HRESULT WINAPI stillimagew_Initialize(IStillImageW *iface, HINSTANCE hinst, DWORD dwVersion)
80 {
81     stillimage *This = impl_from_IStillImageW(iface);
82     TRACE("(%p, %p, 0x%X)\n", This, hinst, dwVersion);
83     return S_OK;
84 }
85 
86 static HRESULT WINAPI stillimagew_GetDeviceList(IStillImageW *iface, DWORD dwType, DWORD dwFlags,
87                                                 DWORD *pdwItemsReturned, LPVOID *ppBuffer)
88 {
89     stillimage *This = impl_from_IStillImageW(iface);
90     FIXME("(%p, %u, 0x%X, %p, %p): stub\n", This, dwType, dwFlags, pdwItemsReturned, ppBuffer);
91     return E_NOTIMPL;
92 }
93 
94 static HRESULT WINAPI stillimagew_GetDeviceInfo(IStillImageW *iface, LPWSTR pwszDeviceName,
95                                                 LPVOID *ppBuffer)
96 {
97     stillimage *This = impl_from_IStillImageW(iface);
98     FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), ppBuffer);
99     return E_NOTIMPL;
100 }
101 
102 static HRESULT WINAPI stillimagew_CreateDevice(IStillImageW *iface, LPWSTR pwszDeviceName, DWORD dwMode,
103                                                PSTIDEVICEW *pDevice, LPUNKNOWN pUnkOuter)
104 {
105     stillimage *This = impl_from_IStillImageW(iface);
106     FIXME("(%p, %s, %u, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), dwMode, pDevice, pUnkOuter);
107     return E_NOTIMPL;
108 }
109 
110 static HRESULT WINAPI stillimagew_GetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
111                                                  LPDWORD pType, LPBYTE pData, LPDWORD cbData)
112 {
113     stillimage *This = impl_from_IStillImageW(iface);
114     FIXME("(%p, %s, %s, %p, %p, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
115         pType, pData, cbData);
116     return E_NOTIMPL;
117 }
118 
119 static HRESULT WINAPI stillimagew_SetDeviceValue(IStillImageW *iface, LPWSTR pwszDeviceName, LPWSTR pValueName,
120                                                  DWORD type, LPBYTE pData, DWORD cbData)
121 {
122     stillimage *This = impl_from_IStillImageW(iface);
123     FIXME("(%p, %s, %s, %u, %p, %u): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pValueName),
124         type, pData, cbData);
125     return E_NOTIMPL;
126 }
127 
128 static HRESULT WINAPI stillimagew_GetSTILaunchInformation(IStillImageW *iface, LPWSTR pwszDeviceName,
129                                                           DWORD *pdwEventCode, LPWSTR pwszEventName)
130 {
131     stillimage *This = impl_from_IStillImageW(iface);
132     FIXME("(%p, %p, %p, %p): stub\n", This, pwszDeviceName,
133         pdwEventCode, pwszEventName);
134     return E_NOTIMPL;
135 }
136 
137 static HRESULT WINAPI stillimagew_RegisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName,
138                                                             LPWSTR pwszCommandLine)
139 {
140     static const WCHAR format[] = {'%','s',' ','%','s',0};
141     static const WCHAR commandLineSuffix[] = {
142         '/','S','t','i','D','e','v','i','c','e',':','%','1',' ',
143         '/','S','t','i','E','v','e','n','t',':','%','2',0};
144     HKEY registeredAppsKey = NULL;
145     DWORD ret;
146     HRESULT hr = S_OK;
147     stillimage *This = impl_from_IStillImageW(iface);
148 
149     TRACE("(%p, %s, %s)\n", This, debugstr_w(pwszAppName), debugstr_w(pwszCommandLine));
150 
151     ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, &registeredAppsKey);
152     if (ret == ERROR_SUCCESS)
153     {
154         size_t len = lstrlenW(pwszCommandLine) + 1 + lstrlenW(commandLineSuffix) + 1;
155         WCHAR *value = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
156         if (value)
157         {
158             swprintf(value, format, pwszCommandLine, commandLineSuffix);
159             ret = RegSetValueExW(registeredAppsKey, pwszAppName, 0,
160                 REG_SZ, (BYTE*)value, (lstrlenW(value)+1)*sizeof(WCHAR));
161             if (ret != ERROR_SUCCESS)
162                 hr = HRESULT_FROM_WIN32(ret);
163             HeapFree(GetProcessHeap(), 0, value);
164         }
165         else
166             hr = E_OUTOFMEMORY;
167         RegCloseKey(registeredAppsKey);
168     }
169     else
170         hr = HRESULT_FROM_WIN32(ret);
171     return hr;
172 }
173 
174 static HRESULT WINAPI stillimagew_UnregisterLaunchApplication(IStillImageW *iface, LPWSTR pwszAppName)
175 {
176     stillimage *This = impl_from_IStillImageW(iface);
177     HKEY registeredAppsKey = NULL;
178     DWORD ret;
179     HRESULT hr = S_OK;
180 
181     TRACE("(%p, %s)\n", This, debugstr_w(pwszAppName));
182 
183     ret = RegCreateKeyW(HKEY_LOCAL_MACHINE, registeredAppsLaunchPath, &registeredAppsKey);
184     if (ret == ERROR_SUCCESS)
185     {
186         ret = RegDeleteValueW(registeredAppsKey, pwszAppName);
187         if (ret != ERROR_SUCCESS)
188             hr = HRESULT_FROM_WIN32(ret);
189         RegCloseKey(registeredAppsKey);
190     }
191     else
192         hr = HRESULT_FROM_WIN32(ret);
193     return hr;
194 }
195 
196 static HRESULT WINAPI stillimagew_EnableHwNotifications(IStillImageW *iface, LPCWSTR pwszDeviceName,
197                                                         BOOL bNewState)
198 {
199     stillimage *This = impl_from_IStillImageW(iface);
200     FIXME("(%p, %s, %u): stub\n", This, debugstr_w(pwszDeviceName), bNewState);
201     return E_NOTIMPL;
202 }
203 
204 static HRESULT WINAPI stillimagew_GetHwNotificationState(IStillImageW *iface, LPCWSTR pwszDeviceName,
205                                                          BOOL *pbCurrentState)
206 {
207     stillimage *This = impl_from_IStillImageW(iface);
208     FIXME("(%p, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), pbCurrentState);
209     return E_NOTIMPL;
210 }
211 
212 static HRESULT WINAPI stillimagew_RefreshDeviceBus(IStillImageW *iface, LPCWSTR pwszDeviceName)
213 {
214     stillimage *This = impl_from_IStillImageW(iface);
215     FIXME("(%p, %s): stub\n", This, debugstr_w(pwszDeviceName));
216     return E_NOTIMPL;
217 }
218 
219 static HRESULT WINAPI stillimagew_LaunchApplicationForDevice(IStillImageW *iface, LPWSTR pwszDeviceName,
220                                                              LPWSTR pwszAppName, LPSTINOTIFY pStiNotify)
221 {
222     stillimage *This = impl_from_IStillImageW(iface);
223     FIXME("(%p, %s, %s, %p): stub\n", This, debugstr_w(pwszDeviceName), debugstr_w(pwszAppName),
224         pStiNotify);
225     return E_NOTIMPL;
226 }
227 
228 static HRESULT WINAPI stillimagew_SetupDeviceParameters(IStillImageW *iface, PSTI_DEVICE_INFORMATIONW pDevInfo)
229 {
230     stillimage *This = impl_from_IStillImageW(iface);
231     FIXME("(%p, %p): stub\n", This, pDevInfo);
232     return E_NOTIMPL;
233 }
234 
235 static HRESULT WINAPI stillimagew_WriteToErrorLog(IStillImageW *iface, DWORD dwMessageType, LPCWSTR pszMessage)
236 {
237     stillimage *This = impl_from_IStillImageW(iface);
238     FIXME("(%p, %u, %s): stub\n", This, dwMessageType, debugstr_w(pszMessage));
239     return E_NOTIMPL;
240 }
241 
242 static const struct IStillImageWVtbl stillimagew_vtbl =
243 {
244     stillimagew_QueryInterface,
245     stillimagew_AddRef,
246     stillimagew_Release,
247     stillimagew_Initialize,
248     stillimagew_GetDeviceList,
249     stillimagew_GetDeviceInfo,
250     stillimagew_CreateDevice,
251     stillimagew_GetDeviceValue,
252     stillimagew_SetDeviceValue,
253     stillimagew_GetSTILaunchInformation,
254     stillimagew_RegisterLaunchApplication,
255     stillimagew_UnregisterLaunchApplication,
256     stillimagew_EnableHwNotifications,
257     stillimagew_GetHwNotificationState,
258     stillimagew_RefreshDeviceBus,
259     stillimagew_LaunchApplicationForDevice,
260     stillimagew_SetupDeviceParameters,
261     stillimagew_WriteToErrorLog
262 };
263 
264 static inline stillimage *impl_from_IUnknown(IUnknown *iface)
265 {
266     return CONTAINING_RECORD(iface, stillimage, IUnknown_inner);
267 }
268 
269 static HRESULT WINAPI Internal_QueryInterface(IUnknown *iface, REFIID riid, void **ppvObject)
270 {
271     stillimage *This = impl_from_IUnknown(iface);
272 
273     TRACE("(%p %s %p)\n", This, debugstr_guid(riid), ppvObject);
274 
275     if (IsEqualGUID(riid, &IID_IUnknown))
276         *ppvObject = iface;
277     else if (IsEqualGUID(riid, &IID_IStillImageW))
278         *ppvObject = &This->IStillImageW_iface;
279     else
280     {
281         if (IsEqualGUID(riid, &IID_IStillImageA))
282             FIXME("interface IStillImageA is unsupported on Windows Vista too, please report if it's needed\n");
283         else
284             FIXME("interface %s not implemented\n", debugstr_guid(riid));
285         *ppvObject = NULL;
286         return E_NOINTERFACE;
287     }
288 
289     IUnknown_AddRef((IUnknown*) *ppvObject);
290     return S_OK;
291 }
292 
293 static ULONG WINAPI Internal_AddRef(IUnknown *iface)
294 {
295     stillimage *This = impl_from_IUnknown(iface);
296     return InterlockedIncrement(&This->ref);
297 }
298 
299 static ULONG WINAPI Internal_Release(IUnknown *iface)
300 {
301     ULONG ref;
302     stillimage *This = impl_from_IUnknown(iface);
303 
304     ref = InterlockedDecrement(&This->ref);
305     if (ref == 0)
306         HeapFree(GetProcessHeap(), 0, This);
307     return ref;
308 }
309 
310 static const struct IUnknownVtbl internal_unk_vtbl =
311 {
312     Internal_QueryInterface,
313     Internal_AddRef,
314     Internal_Release
315 };
316 
317 /******************************************************************************
318  *           StiCreateInstanceA   (STI.@)
319  */
320 HRESULT WINAPI StiCreateInstanceA(HINSTANCE hinst, DWORD dwVer, PSTIA *ppSti, LPUNKNOWN pUnkOuter)
321 {
322     FIXME("(%p, %u, %p, %p): stub, unimplemented on Windows Vista too, please report if it's needed\n", hinst, dwVer, ppSti, pUnkOuter);
323     return STG_E_UNIMPLEMENTEDFUNCTION;
324 }
325 
326 /******************************************************************************
327  *           StiCreateInstanceW   (STI.@)
328  */
329 HRESULT WINAPI StiCreateInstanceW(HINSTANCE hinst, DWORD dwVer, PSTIW *ppSti, LPUNKNOWN pUnkOuter)
330 {
331     stillimage *This;
332     HRESULT hr;
333 
334     TRACE("(%p, %u, %p, %p)\n", hinst, dwVer, ppSti, pUnkOuter);
335 
336     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(stillimage));
337     if (This)
338     {
339         This->IStillImageW_iface.lpVtbl = &stillimagew_vtbl;
340         This->IUnknown_inner.lpVtbl = &internal_unk_vtbl;
341         if (pUnkOuter)
342             This->outer_unk = pUnkOuter;
343         else
344             This->outer_unk = &This->IUnknown_inner;
345         This->ref = 1;
346 
347         hr = IStillImage_Initialize(&This->IStillImageW_iface, hinst, dwVer);
348         if (SUCCEEDED(hr))
349         {
350             if (pUnkOuter)
351                 *ppSti = (IStillImageW*) &This->IUnknown_inner;
352             else
353                 *ppSti = &This->IStillImageW_iface;
354         }
355     }
356     else
357         hr = E_OUTOFMEMORY;
358 
359     return hr;
360 }
361