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, ®isteredAppsKey); 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, ®isteredAppsKey); 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