1 /* 2 * ITSS Class Factory 3 * 4 * Copyright 2002 Lionel Ulmer 5 * Copyright 2004 Mike McCormack 6 * 7 * see http://bonedaddy.net/pabs3/hhm/#chmspec 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 22 */ 23 24 #include "config.h" 25 26 #include <stdarg.h> 27 #include <stdio.h> 28 29 #define COBJMACROS 30 31 #include "windef.h" 32 #include "winbase.h" 33 #include "winuser.h" 34 #include "winreg.h" 35 #include "ole2.h" 36 #include "rpcproxy.h" 37 #include "advpub.h" 38 39 #include "wine/unicode.h" 40 #include "wine/debug.h" 41 42 #include "itsstor.h" 43 44 #include "initguid.h" 45 #include "wine/itss.h" 46 47 WINE_DEFAULT_DEBUG_CHANNEL(itss); 48 49 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj); 50 51 LONG dll_count = 0; 52 static HINSTANCE hInst; 53 54 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) 55 { 56 switch(fdwReason) { 57 case DLL_PROCESS_ATTACH: 58 DisableThreadLibraryCalls(hInstDLL); 59 hInst = hInstDLL; 60 break; 61 } 62 return TRUE; 63 } 64 65 /****************************************************************************** 66 * ITSS ClassFactory 67 */ 68 typedef struct { 69 IClassFactory IClassFactory_iface; 70 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 71 } IClassFactoryImpl; 72 73 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 74 { 75 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 76 } 77 78 static HRESULT WINAPI 79 ITSSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) 80 { 81 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 82 83 if (IsEqualGUID(riid, &IID_IUnknown) || 84 IsEqualGUID(riid, &IID_IClassFactory)) 85 { 86 IClassFactory_AddRef(iface); 87 *ppobj = &This->IClassFactory_iface; 88 return S_OK; 89 } 90 91 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj); 92 return E_NOINTERFACE; 93 } 94 95 static ULONG WINAPI ITSSCF_AddRef(LPCLASSFACTORY iface) 96 { 97 ITSS_LockModule(); 98 return 2; 99 } 100 101 static ULONG WINAPI ITSSCF_Release(LPCLASSFACTORY iface) 102 { 103 ITSS_UnlockModule(); 104 return 1; 105 } 106 107 108 static HRESULT WINAPI ITSSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, 109 REFIID riid, LPVOID *ppobj) 110 { 111 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 112 HRESULT hres; 113 LPUNKNOWN punk; 114 115 TRACE("(%p)->(%p,%s,%p)\n", This, pOuter, debugstr_guid(riid), ppobj); 116 117 *ppobj = NULL; 118 hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); 119 if (SUCCEEDED(hres)) { 120 hres = IUnknown_QueryInterface(punk, riid, ppobj); 121 IUnknown_Release(punk); 122 } 123 return hres; 124 } 125 126 static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) 127 { 128 TRACE("(%p)->(%d)\n", iface, dolock); 129 130 if (dolock) 131 ITSS_LockModule(); 132 else 133 ITSS_UnlockModule(); 134 135 return S_OK; 136 } 137 138 static const IClassFactoryVtbl ITSSCF_Vtbl = 139 { 140 ITSSCF_QueryInterface, 141 ITSSCF_AddRef, 142 ITSSCF_Release, 143 ITSSCF_CreateInstance, 144 ITSSCF_LockServer 145 }; 146 147 static const IClassFactoryImpl ITStorage_factory = { { &ITSSCF_Vtbl }, ITSS_create }; 148 static const IClassFactoryImpl MSITStore_factory = { { &ITSSCF_Vtbl }, ITS_IParseDisplayName_create }; 149 static const IClassFactoryImpl ITSProtocol_factory = { { &ITSSCF_Vtbl }, ITSProtocol_create }; 150 151 /*********************************************************************** 152 * DllGetClassObject (ITSS.@) 153 */ 154 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) 155 { 156 const IClassFactoryImpl *factory; 157 158 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); 159 160 if (IsEqualGUID(&CLSID_ITStorage, rclsid)) 161 factory = &ITStorage_factory; 162 else if (IsEqualGUID(&CLSID_MSITStore, rclsid)) 163 factory = &MSITStore_factory; 164 else if (IsEqualGUID(&CLSID_ITSProtocol, rclsid)) 165 factory = &ITSProtocol_factory; 166 else 167 { 168 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 169 return CLASS_E_CLASSNOTAVAILABLE; 170 } 171 172 return IUnknown_QueryInterface( (IUnknown*) factory, iid, ppv ); 173 } 174 175 /*****************************************************************************/ 176 177 typedef struct { 178 IITStorage IITStorage_iface; 179 LONG ref; 180 } ITStorageImpl; 181 182 static inline ITStorageImpl *impl_from_IITStorage(IITStorage *iface) 183 { 184 return CONTAINING_RECORD(iface, ITStorageImpl, IITStorage_iface); 185 } 186 187 188 static HRESULT WINAPI ITStorageImpl_QueryInterface( 189 IITStorage* iface, 190 REFIID riid, 191 void** ppvObject) 192 { 193 ITStorageImpl *This = impl_from_IITStorage(iface); 194 if (IsEqualGUID(riid, &IID_IUnknown) 195 || IsEqualGUID(riid, &IID_IITStorage)) 196 { 197 IITStorage_AddRef(iface); 198 *ppvObject = iface; 199 return S_OK; 200 } 201 202 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); 203 return E_NOINTERFACE; 204 } 205 206 static ULONG WINAPI ITStorageImpl_AddRef( 207 IITStorage* iface) 208 { 209 ITStorageImpl *This = impl_from_IITStorage(iface); 210 TRACE("%p\n", This); 211 return InterlockedIncrement(&This->ref); 212 } 213 214 static ULONG WINAPI ITStorageImpl_Release( 215 IITStorage* iface) 216 { 217 ITStorageImpl *This = impl_from_IITStorage(iface); 218 ULONG ref = InterlockedDecrement(&This->ref); 219 220 if (ref == 0) { 221 HeapFree(GetProcessHeap(), 0, This); 222 ITSS_UnlockModule(); 223 } 224 225 return ref; 226 } 227 228 static HRESULT WINAPI ITStorageImpl_StgCreateDocfile( 229 IITStorage* iface, 230 const WCHAR* pwcsName, 231 DWORD grfMode, 232 DWORD reserved, 233 IStorage** ppstgOpen) 234 { 235 ITStorageImpl *This = impl_from_IITStorage(iface); 236 237 TRACE("%p %s %u %u %p\n", This, 238 debugstr_w(pwcsName), grfMode, reserved, ppstgOpen ); 239 240 return ITSS_StgOpenStorage( pwcsName, NULL, grfMode, 241 0, reserved, ppstgOpen); 242 } 243 244 static HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes( 245 IITStorage* iface, 246 ILockBytes* plkbyt, 247 DWORD grfMode, 248 DWORD reserved, 249 IStorage** ppstgOpen) 250 { 251 ITStorageImpl *This = impl_from_IITStorage(iface); 252 FIXME("%p\n", This); 253 return E_NOTIMPL; 254 } 255 256 static HRESULT WINAPI ITStorageImpl_StgIsStorageFile( 257 IITStorage* iface, 258 const WCHAR* pwcsName) 259 { 260 ITStorageImpl *This = impl_from_IITStorage(iface); 261 FIXME("%p\n", This); 262 return E_NOTIMPL; 263 } 264 265 static HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes( 266 IITStorage* iface, 267 ILockBytes* plkbyt) 268 { 269 ITStorageImpl *This = impl_from_IITStorage(iface); 270 FIXME("%p\n", This); 271 return E_NOTIMPL; 272 } 273 274 static HRESULT WINAPI ITStorageImpl_StgOpenStorage( 275 IITStorage* iface, 276 const WCHAR* pwcsName, 277 IStorage* pstgPriority, 278 DWORD grfMode, 279 SNB snbExclude, 280 DWORD reserved, 281 IStorage** ppstgOpen) 282 { 283 ITStorageImpl *This = impl_from_IITStorage(iface); 284 285 TRACE("%p %s %p %d %p\n", This, debugstr_w( pwcsName ), 286 pstgPriority, grfMode, snbExclude ); 287 288 return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode, 289 snbExclude, reserved, ppstgOpen); 290 } 291 292 static HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes( 293 IITStorage* iface, 294 ILockBytes* plkbyt, 295 IStorage* pStgPriority, 296 DWORD grfMode, 297 SNB snbExclude, 298 DWORD reserved, 299 IStorage** ppstgOpen) 300 { 301 ITStorageImpl *This = impl_from_IITStorage(iface); 302 FIXME("%p\n", This); 303 return E_NOTIMPL; 304 } 305 306 static HRESULT WINAPI ITStorageImpl_StgSetTimes( 307 IITStorage* iface, 308 const WCHAR* lpszName, 309 const FILETIME* pctime, 310 const FILETIME* patime, 311 const FILETIME* pmtime) 312 { 313 ITStorageImpl *This = impl_from_IITStorage(iface); 314 FIXME("%p\n", This); 315 return E_NOTIMPL; 316 } 317 318 static HRESULT WINAPI ITStorageImpl_SetControlData( 319 IITStorage* iface, 320 PITS_Control_Data pControlData) 321 { 322 ITStorageImpl *This = impl_from_IITStorage(iface); 323 FIXME("%p\n", This); 324 return E_NOTIMPL; 325 } 326 327 static HRESULT WINAPI ITStorageImpl_DefaultControlData( 328 IITStorage* iface, 329 PITS_Control_Data* ppControlData) 330 { 331 ITStorageImpl *This = impl_from_IITStorage(iface); 332 FIXME("%p\n", This); 333 return E_NOTIMPL; 334 } 335 336 static HRESULT WINAPI ITStorageImpl_Compact( 337 IITStorage* iface, 338 const WCHAR* pwcsName, 339 ECompactionLev iLev) 340 { 341 ITStorageImpl *This = impl_from_IITStorage(iface); 342 FIXME("%p\n", This); 343 return E_NOTIMPL; 344 } 345 346 static const IITStorageVtbl ITStorageImpl_Vtbl = 347 { 348 ITStorageImpl_QueryInterface, 349 ITStorageImpl_AddRef, 350 ITStorageImpl_Release, 351 ITStorageImpl_StgCreateDocfile, 352 ITStorageImpl_StgCreateDocfileOnILockBytes, 353 ITStorageImpl_StgIsStorageFile, 354 ITStorageImpl_StgIsStorageILockBytes, 355 ITStorageImpl_StgOpenStorage, 356 ITStorageImpl_StgOpenStorageOnILockBytes, 357 ITStorageImpl_StgSetTimes, 358 ITStorageImpl_SetControlData, 359 ITStorageImpl_DefaultControlData, 360 ITStorageImpl_Compact, 361 }; 362 363 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj) 364 { 365 ITStorageImpl *its; 366 367 if( pUnkOuter ) 368 return CLASS_E_NOAGGREGATION; 369 370 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) ); 371 its->IITStorage_iface.lpVtbl = &ITStorageImpl_Vtbl; 372 its->ref = 1; 373 374 TRACE("-> %p\n", its); 375 *ppObj = its; 376 377 ITSS_LockModule(); 378 return S_OK; 379 } 380 381 /*****************************************************************************/ 382 383 HRESULT WINAPI DllCanUnloadNow(void) 384 { 385 TRACE("dll_count = %u\n", dll_count); 386 return dll_count ? S_FALSE : S_OK; 387 } 388 389 /*********************************************************************** 390 * DllRegisterServer (ITSS.@) 391 */ 392 HRESULT WINAPI DllRegisterServer(void) 393 { 394 return __wine_register_resources( hInst ); 395 } 396 397 /*********************************************************************** 398 * DllUnregisterServer (ITSS.@) 399 */ 400 HRESULT WINAPI DllUnregisterServer(void) 401 { 402 return __wine_unregister_resources( hInst ); 403 } 404