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