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