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(IClassFactory *iface, IUnknown *outer, 109 REFIID riid, void **ppv) 110 { 111 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 112 IUnknown *unk; 113 HRESULT hres; 114 115 TRACE("(%p)->(%p %s %p)\n", This, outer, debugstr_guid(riid), ppv); 116 117 if(outer && !IsEqualGUID(riid, &IID_IUnknown)) { 118 *ppv = NULL; 119 return CLASS_E_NOAGGREGATION; 120 } 121 122 hres = This->pfnCreateInstance(outer, (void**)&unk); 123 if(FAILED(hres)) { 124 *ppv = NULL; 125 return hres; 126 } 127 128 if(!IsEqualGUID(riid, &IID_IUnknown)) { 129 hres = IUnknown_QueryInterface(unk, riid, ppv); 130 IUnknown_Release(unk); 131 }else { 132 *ppv = unk; 133 } 134 return hres; 135 } 136 137 static HRESULT WINAPI ITSSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock) 138 { 139 TRACE("(%p)->(%d)\n", iface, dolock); 140 141 if (dolock) 142 ITSS_LockModule(); 143 else 144 ITSS_UnlockModule(); 145 146 return S_OK; 147 } 148 149 static const IClassFactoryVtbl ITSSCF_Vtbl = 150 { 151 ITSSCF_QueryInterface, 152 ITSSCF_AddRef, 153 ITSSCF_Release, 154 ITSSCF_CreateInstance, 155 ITSSCF_LockServer 156 }; 157 158 static const IClassFactoryImpl ITStorage_factory = { { &ITSSCF_Vtbl }, ITSS_create }; 159 static const IClassFactoryImpl MSITStore_factory = { { &ITSSCF_Vtbl }, ITS_IParseDisplayName_create }; 160 static const IClassFactoryImpl ITSProtocol_factory = { { &ITSSCF_Vtbl }, ITSProtocol_create }; 161 162 /*********************************************************************** 163 * DllGetClassObject (ITSS.@) 164 */ 165 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) 166 { 167 const IClassFactoryImpl *factory; 168 169 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); 170 171 if (IsEqualGUID(&CLSID_ITStorage, rclsid)) 172 factory = &ITStorage_factory; 173 else if (IsEqualGUID(&CLSID_MSITStore, rclsid)) 174 factory = &MSITStore_factory; 175 else if (IsEqualGUID(&CLSID_ITSProtocol, rclsid)) 176 factory = &ITSProtocol_factory; 177 else 178 { 179 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 180 return CLASS_E_CLASSNOTAVAILABLE; 181 } 182 183 return IUnknown_QueryInterface( (IUnknown*) factory, iid, ppv ); 184 } 185 186 /*****************************************************************************/ 187 188 typedef struct { 189 IITStorage IITStorage_iface; 190 LONG ref; 191 } ITStorageImpl; 192 193 static inline ITStorageImpl *impl_from_IITStorage(IITStorage *iface) 194 { 195 return CONTAINING_RECORD(iface, ITStorageImpl, IITStorage_iface); 196 } 197 198 199 static HRESULT WINAPI ITStorageImpl_QueryInterface( 200 IITStorage* iface, 201 REFIID riid, 202 void** ppvObject) 203 { 204 ITStorageImpl *This = impl_from_IITStorage(iface); 205 if (IsEqualGUID(riid, &IID_IUnknown) 206 || IsEqualGUID(riid, &IID_IITStorage)) 207 { 208 IITStorage_AddRef(iface); 209 *ppvObject = iface; 210 return S_OK; 211 } 212 213 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject); 214 return E_NOINTERFACE; 215 } 216 217 static ULONG WINAPI ITStorageImpl_AddRef( 218 IITStorage* iface) 219 { 220 ITStorageImpl *This = impl_from_IITStorage(iface); 221 TRACE("%p\n", This); 222 return InterlockedIncrement(&This->ref); 223 } 224 225 static ULONG WINAPI ITStorageImpl_Release( 226 IITStorage* iface) 227 { 228 ITStorageImpl *This = impl_from_IITStorage(iface); 229 ULONG ref = InterlockedDecrement(&This->ref); 230 231 if (ref == 0) { 232 HeapFree(GetProcessHeap(), 0, This); 233 ITSS_UnlockModule(); 234 } 235 236 return ref; 237 } 238 239 static HRESULT WINAPI ITStorageImpl_StgCreateDocfile( 240 IITStorage* iface, 241 const WCHAR* pwcsName, 242 DWORD grfMode, 243 DWORD reserved, 244 IStorage** ppstgOpen) 245 { 246 ITStorageImpl *This = impl_from_IITStorage(iface); 247 248 TRACE("%p %s %u %u %p\n", This, 249 debugstr_w(pwcsName), grfMode, reserved, ppstgOpen ); 250 251 return ITSS_StgOpenStorage( pwcsName, NULL, grfMode, 252 0, reserved, ppstgOpen); 253 } 254 255 static HRESULT WINAPI ITStorageImpl_StgCreateDocfileOnILockBytes( 256 IITStorage* iface, 257 ILockBytes* plkbyt, 258 DWORD grfMode, 259 DWORD reserved, 260 IStorage** ppstgOpen) 261 { 262 ITStorageImpl *This = impl_from_IITStorage(iface); 263 FIXME("%p\n", This); 264 return E_NOTIMPL; 265 } 266 267 static HRESULT WINAPI ITStorageImpl_StgIsStorageFile( 268 IITStorage* iface, 269 const WCHAR* pwcsName) 270 { 271 ITStorageImpl *This = impl_from_IITStorage(iface); 272 FIXME("%p\n", This); 273 return E_NOTIMPL; 274 } 275 276 static HRESULT WINAPI ITStorageImpl_StgIsStorageILockBytes( 277 IITStorage* iface, 278 ILockBytes* plkbyt) 279 { 280 ITStorageImpl *This = impl_from_IITStorage(iface); 281 FIXME("%p\n", This); 282 return E_NOTIMPL; 283 } 284 285 static HRESULT WINAPI ITStorageImpl_StgOpenStorage( 286 IITStorage* iface, 287 const WCHAR* pwcsName, 288 IStorage* pstgPriority, 289 DWORD grfMode, 290 SNB snbExclude, 291 DWORD reserved, 292 IStorage** ppstgOpen) 293 { 294 ITStorageImpl *This = impl_from_IITStorage(iface); 295 296 TRACE("%p %s %p %d %p\n", This, debugstr_w( pwcsName ), 297 pstgPriority, grfMode, snbExclude ); 298 299 return ITSS_StgOpenStorage( pwcsName, pstgPriority, grfMode, 300 snbExclude, reserved, ppstgOpen); 301 } 302 303 static HRESULT WINAPI ITStorageImpl_StgOpenStorageOnILockBytes( 304 IITStorage* iface, 305 ILockBytes* plkbyt, 306 IStorage* pStgPriority, 307 DWORD grfMode, 308 SNB snbExclude, 309 DWORD reserved, 310 IStorage** ppstgOpen) 311 { 312 ITStorageImpl *This = impl_from_IITStorage(iface); 313 FIXME("%p\n", This); 314 return E_NOTIMPL; 315 } 316 317 static HRESULT WINAPI ITStorageImpl_StgSetTimes( 318 IITStorage* iface, 319 const WCHAR* lpszName, 320 const FILETIME* pctime, 321 const FILETIME* patime, 322 const FILETIME* pmtime) 323 { 324 ITStorageImpl *This = impl_from_IITStorage(iface); 325 FIXME("%p\n", This); 326 return E_NOTIMPL; 327 } 328 329 static HRESULT WINAPI ITStorageImpl_SetControlData( 330 IITStorage* iface, 331 PITS_Control_Data pControlData) 332 { 333 ITStorageImpl *This = impl_from_IITStorage(iface); 334 FIXME("%p\n", This); 335 return E_NOTIMPL; 336 } 337 338 static HRESULT WINAPI ITStorageImpl_DefaultControlData( 339 IITStorage* iface, 340 PITS_Control_Data* ppControlData) 341 { 342 ITStorageImpl *This = impl_from_IITStorage(iface); 343 FIXME("%p\n", This); 344 return E_NOTIMPL; 345 } 346 347 static HRESULT WINAPI ITStorageImpl_Compact( 348 IITStorage* iface, 349 const WCHAR* pwcsName, 350 ECompactionLev iLev) 351 { 352 ITStorageImpl *This = impl_from_IITStorage(iface); 353 FIXME("%p\n", This); 354 return E_NOTIMPL; 355 } 356 357 static const IITStorageVtbl ITStorageImpl_Vtbl = 358 { 359 ITStorageImpl_QueryInterface, 360 ITStorageImpl_AddRef, 361 ITStorageImpl_Release, 362 ITStorageImpl_StgCreateDocfile, 363 ITStorageImpl_StgCreateDocfileOnILockBytes, 364 ITStorageImpl_StgIsStorageFile, 365 ITStorageImpl_StgIsStorageILockBytes, 366 ITStorageImpl_StgOpenStorage, 367 ITStorageImpl_StgOpenStorageOnILockBytes, 368 ITStorageImpl_StgSetTimes, 369 ITStorageImpl_SetControlData, 370 ITStorageImpl_DefaultControlData, 371 ITStorageImpl_Compact, 372 }; 373 374 static HRESULT ITSS_create(IUnknown *pUnkOuter, LPVOID *ppObj) 375 { 376 ITStorageImpl *its; 377 378 if( pUnkOuter ) 379 return CLASS_E_NOAGGREGATION; 380 381 its = HeapAlloc( GetProcessHeap(), 0, sizeof(ITStorageImpl) ); 382 its->IITStorage_iface.lpVtbl = &ITStorageImpl_Vtbl; 383 its->ref = 1; 384 385 TRACE("-> %p\n", its); 386 *ppObj = its; 387 388 ITSS_LockModule(); 389 return S_OK; 390 } 391 392 /*****************************************************************************/ 393 394 HRESULT WINAPI DllCanUnloadNow(void) 395 { 396 TRACE("dll_count = %u\n", dll_count); 397 return dll_count ? S_FALSE : S_OK; 398 } 399 400 /*********************************************************************** 401 * DllRegisterServer (ITSS.@) 402 */ 403 HRESULT WINAPI DllRegisterServer(void) 404 { 405 return __wine_register_resources( hInst ); 406 } 407 408 /*********************************************************************** 409 * DllUnregisterServer (ITSS.@) 410 */ 411 HRESULT WINAPI DllUnregisterServer(void) 412 { 413 return __wine_unregister_resources( hInst ); 414 } 415