Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

761 lines
22 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 2000.
  5. //
  6. // File: ixssocf.cxx
  7. //
  8. // Contents: Standard IClassFactory implementation
  9. //
  10. // Classes: CStaticClassFactory
  11. // CIxssoQueryCF
  12. //
  13. // History: 26-Feb-96 SSanu adapted from my Forms stuff
  14. //
  15. //----------------------------------------------------------------------
  16. #include "pch.cxx"
  17. #pragma hdrstop
  18. #include "stdcf.hxx"
  19. #include "regutil.h"
  20. #include "ssodebug.hxx"
  21. #include "ixsso.hxx"
  22. #include "ixsutil.hxx"
  23. #include <adoid.h> // ADO CLSID and IID definitions
  24. #include <initguid.h>
  25. // HACKHACK - this is stolen from the old sdk\inc\adoid.h header:
  26. #define DEFINE_ADOGUID(name, l) \
  27. DEFINE_GUID(name, l, 0, 0x10, 0x80,0,0,0xAA,0,0x6D,0x2E,0xA4)
  28. // ADO V1.0 recordset class ID
  29. DEFINE_ADOGUID(CLSID_CADORecordset_V1_0, 0x00000281);
  30. #ifndef OLYMPUS_COMPONENT
  31. #define QUERY_PROG_ID L"IXSSO.Query"
  32. #define QUERY_PROG_ID2 L"IXSSO.Query.2"
  33. #define QUERY_PROG_ID3 L"IXSSO.Query.3"
  34. #define QUERY_PROG_DESC L"Indexing Service Query SSO V2."
  35. #define QUERY_PROG_DESC3 L"Indexing Service Query SSO V3."
  36. extern WCHAR * g_pwszProgIdQuery = QUERY_PROG_ID;
  37. #define UTIL_PROG_ID L"IXSSO.Util"
  38. #define UTIL_PROG_ID2 L"IXSSO.Util.2"
  39. #define UTIL_PROG_DESC L"Indexing Service Utility SSO V2."
  40. extern WCHAR * g_pwszProgIdUtil = UTIL_PROG_ID;
  41. extern WCHAR * g_pwszErrorMsgFile = L"query.dll";
  42. #define LIBID_ixsso LIBID_Cisso
  43. #define CLSID_ixssoQuery CLSID_CissoQuery
  44. #define CLSID_ixssoQueryEx CLSID_CissoQueryEx
  45. #define CLSID_ixssoUtil CLSID_CissoUtil
  46. #else
  47. #define NLQUERY_PROG_ID L"MSSEARCH.Query"
  48. #define NLQUERY_PROG_ID1 L"MSSEARCH.Query.1"
  49. #define NLQUERY_PROG_DESC L"Microsoft Site Server Search Query SSO V1."
  50. extern WCHAR * g_pwszProgIdQuery = NLQUERY_PROG_ID;
  51. #define NLUTIL_PROG_ID L"MSSEARCH.Util"
  52. #define NLUTIL_PROG_ID1 L"MSSEARCH.Util.1"
  53. #define NLUTIL_PROG_DESC L"Microsoft Site Server Search Utility SSO V1."
  54. extern WCHAR * g_pwszProgIdUtil = NLUTIL_PROG_ID;
  55. extern WCHAR * g_pwszErrorMsgFile = L"oquery.dll";
  56. #define LIBID_ixsso LIBID_Nlsso
  57. #define CLSID_ixssoQuery CLSID_NlssoQuery
  58. #define CLSID_ixssoUtil CLSID_NlssoUtil
  59. #endif // OLYMPUS_COMPONENT
  60. //+------------------------------------------------------------------------
  61. //
  62. // CStaticClassFactory Implementation
  63. //
  64. //-------------------------------------------------------------------------
  65. //+---------------------------------------------------------------
  66. //
  67. // Member: CStaticClassFactory::QueryInterface, public
  68. //
  69. // Synopsis: Method of IUnknown interface
  70. //
  71. //----------------------------------------------------------------
  72. STDMETHODIMP
  73. CStaticClassFactory::QueryInterface(REFIID riid, LPVOID FAR* ppv)
  74. {
  75. if (!ppv)
  76. return E_INVALIDARG;
  77. if (riid == IID_IUnknown ||
  78. riid == IID_IClassFactory)
  79. {
  80. *ppv = (IClassFactory *) this;
  81. }
  82. else
  83. {
  84. *ppv = 0;
  85. return E_NOINTERFACE;
  86. }
  87. ((IUnknown *)*ppv)->AddRef();
  88. return S_OK;
  89. }
  90. //+---------------------------------------------------------------
  91. //
  92. // Member: CStaticClassFactory::AddRef, public
  93. //
  94. // Synopsis: Method of IUnknown interface
  95. //
  96. //----------------------------------------------------------------
  97. STDMETHODIMP_(ULONG)
  98. CStaticClassFactory::AddRef(void)
  99. {
  100. Win4Assert(_ulRefs);
  101. INC_OBJECT_COUNT();
  102. IXIncrement(_ulRefs);
  103. ixssoDebugOut((DEB_REFCOUNTS, "[DLL] CF::AddRef: refcounts: glob %d obj %d\n",
  104. GET_OBJECT_COUNT(), _ulRefs ));
  105. return _ulRefs;
  106. }
  107. //+---------------------------------------------------------------
  108. //
  109. // Member: CStaticClassFactory::Release, public
  110. //
  111. // Synopsis: Method of IUnknown interface
  112. //
  113. //----------------------------------------------------------------
  114. STDMETHODIMP_(ULONG)
  115. CStaticClassFactory::Release(void)
  116. {
  117. Win4Assert(_ulRefs > 1);
  118. IXDecrement(_ulRefs);
  119. DEC_OBJECT_COUNT();
  120. ixssoDebugOut((DEB_REFCOUNTS, "[DLL] CF::Release: refcounts: glob %d obj %d\n",
  121. GET_OBJECT_COUNT(), _ulRefs ));
  122. return _ulRefs;
  123. }
  124. //+---------------------------------------------------------------
  125. //
  126. // Member: CStaticClassFactory::LockServer, public
  127. //
  128. // Synopsis: Method of IClassFactory interface
  129. //
  130. // Notes: Since class factories based on this class are global static
  131. // objects, this method doesn't serve much purpose.
  132. //
  133. //----------------------------------------------------------------
  134. STDMETHODIMP
  135. CStaticClassFactory::LockServer (BOOL fLock)
  136. {
  137. if (fLock)
  138. INC_OBJECT_COUNT();
  139. else
  140. DEC_OBJECT_COUNT();
  141. ixssoDebugOut((DEB_REFCOUNTS, "[DLL] CF::LockServer( %x ) ==> %d\n", fLock, GET_OBJECT_COUNT() ));
  142. return NOERROR;
  143. }
  144. //-----------------------------------------------------------------------------
  145. // CIxssoQueryCF Class Definition
  146. //-----------------------------------------------------------------------------
  147. class CIxssoQueryCF : public CStaticClassFactory
  148. {
  149. public:
  150. STDMETHOD(CreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID FAR* ppv);
  151. void TryInit();
  152. void SetClsid( CLSID ssoClsid ) { _ssoClsid = ssoClsid; }
  153. static ITypeLib * _pITypeLibIxsso;
  154. static IClassFactory * _pIAdoRecordsetCF;
  155. static BOOL _fAdoV15;
  156. static CLSID _ssoClsid;
  157. } IxssoQueryCF; //The global factory
  158. //-----------------------------------------------------------------------------
  159. // CIxssoUtilCF Class Definition
  160. //-----------------------------------------------------------------------------
  161. class CIxssoUtilCF : public CStaticClassFactory
  162. {
  163. public:
  164. STDMETHOD(CreateInstance)(IUnknown *pUnkOuter, REFIID iid, LPVOID FAR* ppv);
  165. } IxssoUtilCF; //The global factory
  166. //-----------------------------------------------------------------------------
  167. // Global variables
  168. //-----------------------------------------------------------------------------
  169. CRITICAL_SECTION g_cs;
  170. HINSTANCE g_hInst;
  171. ULONG g_ulObjCount = 0; // extern to keep track of object instances
  172. LONG g_lQryCount = 0; // BUGBGUG - debugging for obj. ref. count
  173. LONG g_lUtlCount = 0; // BUGBGUG - debugging for obj. ref. count
  174. ITypeLib * CIxssoQueryCF::_pITypeLibIxsso = 0;
  175. IClassFactory * CIxssoQueryCF::_pIAdoRecordsetCF = 0;
  176. BOOL CIxssoQueryCF::_fAdoV15 = FALSE;
  177. CLSID CIxssoQueryCF::_ssoClsid = CLSID_ixssoQueryEx;
  178. CTheGlobalIXSSOVariables * g_pTheGlobalIXSSOVariables = 0;
  179. //-----------------------------------------------------------------------------
  180. //
  181. // Class: CLockCritSec
  182. //
  183. // Synopsis: Like CLock, but takes a bare CRITICAL_SECTION, not a CMutexSem
  184. //
  185. //-----------------------------------------------------------------------------
  186. class CLockCritSec : INHERIT_UNWIND
  187. {
  188. INLINE_UNWIND(CLockCritSec);
  189. public:
  190. CLockCritSec( CRITICAL_SECTION & cs ) :
  191. _cs( cs )
  192. {
  193. EnterCriticalSection( &_cs );
  194. END_CONSTRUCTION( CLockCritSec );
  195. }
  196. ~CLockCritSec( )
  197. {
  198. LeaveCriticalSection( &_cs );
  199. }
  200. private:
  201. CRITICAL_SECTION & _cs;
  202. };
  203. //-----------------------------------------------------------------------------
  204. // CIxssoQueryCF Methods
  205. //-----------------------------------------------------------------------------
  206. STDMETHODIMP
  207. CIxssoQueryCF::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObj)
  208. {
  209. *ppvObj = 0;
  210. // NTRAID#DB-NTBUG9-84743-2000/07/31-dlee IXSSO class factory object does not support COM aggregation
  211. if (pUnkOuter)
  212. return CLASS_E_NOAGGREGATION;
  213. SCODE sc = E_OUTOFMEMORY;
  214. //
  215. // Guard against a race between TryInit and DllCanUnloadNow...
  216. //
  217. INC_OBJECT_COUNT();
  218. CixssoQuery * pObj = 0;
  219. TRANSLATE_EXCEPTIONS;
  220. TRY
  221. {
  222. TryInit();
  223. Win4Assert( 0 != _pITypeLibIxsso && 0 != _pIAdoRecordsetCF );
  224. // create an instance of our CixssoQuery object
  225. pObj = new CixssoQuery( _pITypeLibIxsso,
  226. _pIAdoRecordsetCF,
  227. _fAdoV15,
  228. _ssoClsid );
  229. }
  230. CATCH( CException, e )
  231. {
  232. ixssoDebugOut(( DEB_ERROR,
  233. "Creation of CixssoQuery failed (%x)\n",
  234. e.GetErrorCode() ));
  235. sc = e.GetErrorCode();
  236. }
  237. END_CATCH
  238. UNTRANSLATE_EXCEPTIONS;
  239. Win4Assert( 0 != _pITypeLibIxsso && 0 != _pIAdoRecordsetCF );
  240. DEC_OBJECT_COUNT();
  241. if (0 == pObj)
  242. {
  243. Win4Assert( !SUCCEEDED(sc) );
  244. return sc;
  245. }
  246. #if CIDBG
  247. LONG l = InterlockedIncrement( &g_lQryCount );
  248. Win4Assert( l >= 1 );
  249. #endif //CIDBG
  250. // fetch the interface and return
  251. sc = pObj->QueryInterface(riid, ppvObj);
  252. pObj->Release(); // on failure, this will release our IXSSO object
  253. // otherwise, object will have a ref count of 1
  254. return sc;
  255. }
  256. //+---------------------------------------------------------------
  257. //
  258. // Member: CIxssoQueryCF::TryInit, public
  259. //
  260. // Synopsis: Do static initialization
  261. //
  262. // Notes: Do any required initialization of global objects.
  263. //
  264. //----------------------------------------------------------------
  265. void CIxssoQueryCF::TryInit()
  266. {
  267. Win4Assert (0 != g_ulObjCount);
  268. // Initialize any global variables needed
  269. if ( 0 == _pITypeLibIxsso ||
  270. 0 == _pIAdoRecordsetCF ||
  271. 0 == g_pTheGlobalIXSSOVariables )
  272. {
  273. CLockCritSec Lock(g_cs);
  274. // get the Type lib
  275. if (0 == _pITypeLibIxsso)
  276. {
  277. SCODE sc = LoadRegTypeLib(LIBID_ixsso, 1, 0, 0x409, &_pITypeLibIxsso);
  278. if (FAILED(sc))
  279. sc = LoadTypeLib( OLESTR("ixsso.tlb"), &_pITypeLibIxsso);
  280. if (FAILED(sc))
  281. {
  282. Win4Assert( 0 == _pITypeLibIxsso );
  283. ixssoDebugOut(( DEB_ERROR, "Type library load failed (%x)\n", sc));
  284. THROW(CException(sc));
  285. }
  286. }
  287. // Get the ADO recordset class factory
  288. if ( 0 == _pIAdoRecordsetCF )
  289. {
  290. SCODE sc = CoGetClassObject( CLSID_CADORecordset,
  291. CLSCTX_INPROC_HANDLER |
  292. CLSCTX_INPROC_SERVER,
  293. 0,
  294. IID_IClassFactory,
  295. (void **)&_pIAdoRecordsetCF );
  296. _fAdoV15 = TRUE;
  297. if (REGDB_E_CLASSNOTREG == sc)
  298. {
  299. //
  300. // The class ID for the recordset changed in ADO V1.5. Try
  301. // the ADO V1.0 class ID.
  302. //
  303. sc = CoGetClassObject( CLSID_CADORecordset_V1_0,
  304. CLSCTX_INPROC_HANDLER |
  305. CLSCTX_INPROC_SERVER,
  306. 0,
  307. IID_IClassFactory,
  308. (void **)&_pIAdoRecordsetCF );
  309. if (SUCCEEDED(sc))
  310. _fAdoV15 = FALSE;
  311. }
  312. if (FAILED(sc))
  313. {
  314. Win4Assert( 0 == _pIAdoRecordsetCF );
  315. ixssoDebugOut(( DEB_ERROR, "CoGetClassObject for ADO recordset failed (%x)\n", sc));
  316. THROW(CException(sc));
  317. }
  318. _pIAdoRecordsetCF->LockServer( TRUE );
  319. }
  320. // Initialize global variables needed by the IXSSO objects
  321. if ( 0 == g_pTheGlobalIXSSOVariables )
  322. {
  323. g_pTheGlobalIXSSOVariables = new CTheGlobalIXSSOVariables();
  324. }
  325. }
  326. }
  327. //-----------------------------------------------------------------------------
  328. // CIxssoUtilCF Methods
  329. //-----------------------------------------------------------------------------
  330. STDMETHODIMP
  331. CIxssoUtilCF::CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR* ppvObj)
  332. {
  333. *ppvObj = 0;
  334. // NTRAID#DB-NTBUG9-84743-2000/07/31-dlee IXSSO class factory object does not support COM aggregation
  335. if (pUnkOuter)
  336. return CLASS_E_NOAGGREGATION;
  337. SCODE sc = E_OUTOFMEMORY;
  338. //
  339. // Guard against a race between TryInit and DllCanUnloadNow...
  340. //
  341. INC_OBJECT_COUNT();
  342. CixssoUtil * pObj = 0;
  343. TRANSLATE_EXCEPTIONS;
  344. TRY
  345. {
  346. IxssoQueryCF.TryInit();
  347. Win4Assert( 0 != CIxssoQueryCF::_pITypeLibIxsso );
  348. // create an instance of our CixssoUtil object
  349. pObj = new CixssoUtil( CIxssoQueryCF::_pITypeLibIxsso );
  350. }
  351. CATCH( CException, e )
  352. {
  353. ixssoDebugOut(( DEB_ERROR,
  354. "Creation of CixssoUtil failed (%x)\n",
  355. e.GetErrorCode() ));
  356. sc = e.GetErrorCode();
  357. }
  358. END_CATCH
  359. UNTRANSLATE_EXCEPTIONS;
  360. Win4Assert( 0 != CIxssoQueryCF::_pITypeLibIxsso );
  361. DEC_OBJECT_COUNT();
  362. if (0 == pObj)
  363. {
  364. Win4Assert( !SUCCEEDED(sc) );
  365. return sc;
  366. }
  367. #if CIDBG
  368. LONG l = InterlockedIncrement( &g_lUtlCount );
  369. Win4Assert( l >= 1 );
  370. #endif //CIDBG
  371. // fetch the interface and return
  372. sc = pObj->QueryInterface(riid, ppvObj);
  373. pObj->Release(); // on failure, this will release our IXSSO object
  374. // otherwise, object will have a ref count of 1
  375. return sc;
  376. }
  377. //-----------------------------------------------------------------------------
  378. // Global Scope
  379. //-----------------------------------------------------------------------------
  380. #ifndef OLYMPUS_COMPONENT
  381. const CLSID clsidCommandCreator = CLSID_CISimpleCommandCreator;
  382. #else
  383. //0b63e347-9ccc-11d0-bcdb-00805fccce04
  384. extern "C" CLSID CLSID_NlCommandCreator;
  385. #define clsidCommandCreator CLSID_NlCommandCreator
  386. #endif // OLYMPUS_COMPONENT
  387. CTheGlobalIXSSOVariables::CTheGlobalIXSSOVariables()
  388. {
  389. VariantInit(&_vtAcceptLanguageHeader);
  390. V_VT(&_vtAcceptLanguageHeader) = VT_BSTR;
  391. V_BSTR(&_vtAcceptLanguageHeader) = SysAllocString(OLESTR("HTTP_ACCEPT_LANGUAGE"));
  392. HRESULT hr = CoCreateInstance( clsidCommandCreator,
  393. 0,
  394. CLSCTX_INPROC_SERVER,
  395. IID_ISimpleCommandCreator,
  396. xCmdCreator.GetQIPointer() );
  397. if ( SUCCEEDED( hr ) && xCmdCreator.GetPointer() )
  398. xCmdCreator->QueryInterface(IID_IColumnMapperCreator,
  399. xColumnMapperCreator.GetQIPointer());
  400. }
  401. //-----------------------------------------------------------------------------
  402. // OLE and DLL Methods
  403. //-----------------------------------------------------------------------------
  404. void FreeResources(void)
  405. {
  406. CLockCritSec Lock(g_cs);
  407. if (0 == g_ulObjCount && CIxssoQueryCF::_pIAdoRecordsetCF)
  408. {
  409. CIxssoQueryCF::_pIAdoRecordsetCF->LockServer( FALSE );
  410. CIxssoQueryCF::_pIAdoRecordsetCF->Release();
  411. CIxssoQueryCF::_pIAdoRecordsetCF = 0;
  412. }
  413. if (0 == g_ulObjCount && CIxssoQueryCF::_pITypeLibIxsso)
  414. {
  415. CIxssoQueryCF::_pITypeLibIxsso->Release();
  416. CIxssoQueryCF::_pITypeLibIxsso = 0;
  417. }
  418. if (0 == g_ulObjCount && g_pTheGlobalIXSSOVariables )
  419. {
  420. delete g_pTheGlobalIXSSOVariables;
  421. g_pTheGlobalIXSSOVariables = 0;
  422. }
  423. ixssoDebugOut((DEB_REFCOUNTS, "[DLL] FreeResources -> %s\n",
  424. (0 == g_ulObjCount) ? "S_OK" : "S_FALSE" ));
  425. }
  426. extern "C"
  427. STDAPI DllCanUnloadNow(void)
  428. {
  429. //Our answer is whether there are any object or locks
  430. ixssoDebugOut((DEB_REFCOUNTS,"[DLL] DllCanUnloadNow\n"));
  431. if (0 == g_ulObjCount)
  432. {
  433. FreeResources();
  434. }
  435. return (0 == g_ulObjCount) ? S_OK : S_FALSE;
  436. }
  437. extern "C"
  438. STDAPI DllRegisterServer()
  439. {
  440. ixssoDebugOut((DEB_TRACE,"[DLL] DllRegisterServer\n"));
  441. SCODE sc = S_OK;
  442. #ifndef OLYMPUS_COMPONENT
  443. sc = _DllRegisterServer(g_hInst, QUERY_PROG_ID, CLSID_CissoQueryEx, QUERY_PROG_DESC3, QUERY_PROG_ID3);
  444. if (SUCCEEDED(sc))
  445. sc = _DllRegisterServer(g_hInst, QUERY_PROG_ID3, CLSID_CissoQueryEx, QUERY_PROG_DESC3);
  446. if (SUCCEEDED(sc))
  447. sc = _DllRegisterServer(g_hInst, QUERY_PROG_ID2, CLSID_CissoQuery, QUERY_PROG_DESC);
  448. if (SUCCEEDED(sc))
  449. sc = _DllRegisterServer(g_hInst, UTIL_PROG_ID, CLSID_CissoUtil, UTIL_PROG_DESC, UTIL_PROG_ID2);
  450. if (SUCCEEDED(sc))
  451. sc = _DllRegisterServer(g_hInst, UTIL_PROG_ID2, CLSID_CissoUtil, UTIL_PROG_DESC);
  452. #else
  453. sc = _DllRegisterServer(g_hInst, NLQUERY_PROG_ID, CLSID_NlssoQuery, NLQUERY_PROG_DESC, NLQUERY_PROG_ID1);
  454. if (SUCCEEDED(sc))
  455. sc = _DllRegisterServer(g_hInst, NLQUERY_PROG_ID1, CLSID_NlssoQuery, NLQUERY_PROG_DESC);
  456. if (SUCCEEDED(sc))
  457. sc = _DllRegisterServer(g_hInst, NLUTIL_PROG_ID, CLSID_NlssoUtil, NLUTIL_PROG_DESC, NLUTIL_PROG_ID1);
  458. if (SUCCEEDED(sc))
  459. sc = _DllRegisterServer(g_hInst, NLUTIL_PROG_ID1, CLSID_NlssoUtil, NLUTIL_PROG_DESC);
  460. #endif
  461. if (SUCCEEDED(sc))
  462. {
  463. // Register the type library
  464. WCHAR wcsProgram[MAX_PATH+1];
  465. ULONG cchPath = GetModuleFileName(g_hInst, wcsProgram, MAX_PATH);
  466. XInterface<ITypeLib> xpITypeLibIxsso;
  467. if ( 0 != cchPath )
  468. sc = LoadTypeLib( wcsProgram, xpITypeLibIxsso.GetPPointer());
  469. else
  470. sc = E_FAIL;
  471. if (SUCCEEDED(sc))
  472. sc = RegisterTypeLib(xpITypeLibIxsso.GetPointer(), wcsProgram, 0);
  473. if (FAILED(sc))
  474. {
  475. ixssoDebugOut(( DEB_ERROR, "Type library load or registration failed (%x)\n", sc));
  476. #ifndef OLYMPUS_COMPONENT
  477. _DllUnregisterServer(QUERY_PROG_ID3, CLSID_CissoQueryEx);
  478. _DllUnregisterServer(QUERY_PROG_ID2, CLSID_CissoQuery);
  479. _DllUnregisterServer(QUERY_PROG_ID, CLSID_CissoQueryEx);
  480. _DllUnregisterServer(UTIL_PROG_ID2, CLSID_CissoUtil);
  481. _DllUnregisterServer(UTIL_PROG_ID, CLSID_CissoUtil);
  482. #else //OLYMPUS_COMPONENT
  483. _DllUnregisterServer(NLQUERY_PROG_ID1, CLSID_NlssoQuery);
  484. _DllUnregisterServer(NLQUERY_PROG_ID, CLSID_NlssoQuery);
  485. _DllUnregisterServer(NLUTIL_PROG_ID1, CLSID_NlssoUtil);
  486. _DllUnregisterServer(NLUTIL_PROG_ID, CLSID_NlssoUtil);
  487. #endif //OLYMPUS_COMPONENT
  488. }
  489. }
  490. return sc;
  491. }
  492. extern "C"
  493. STDAPI DllUnregisterServer()
  494. {
  495. ixssoDebugOut((DEB_TRACE,"[DLL] DllUnregisterServer\n"));
  496. SCODE sc;
  497. #ifndef OLYMPUS_COMPONENT
  498. sc = _DllUnregisterServer(QUERY_PROG_ID, CLSID_CissoQueryEx);
  499. if (SUCCEEDED(sc))
  500. sc = _DllUnregisterServer(QUERY_PROG_ID3, CLSID_CissoQueryEx);
  501. if (SUCCEEDED(sc))
  502. sc = _DllUnregisterServer(QUERY_PROG_ID2, CLSID_CissoQuery);
  503. if (SUCCEEDED(sc))
  504. sc = _DllUnregisterServer(UTIL_PROG_ID, CLSID_CissoUtil);
  505. if (SUCCEEDED(sc))
  506. sc = _DllUnregisterServer(UTIL_PROG_ID2, CLSID_CissoUtil);
  507. #else //OLYMPUS_COMPONENT
  508. sc = _DllUnregisterServer(NLQUERY_PROG_ID, CLSID_NlssoQuery);
  509. if (SUCCEEDED(sc))
  510. sc = _DllUnregisterServer(NLQUERY_PROG_ID1, CLSID_NlssoQuery);
  511. if (SUCCEEDED(sc))
  512. sc = _DllUnregisterServer(NLUTIL_PROG_ID, CLSID_NlssoUtil);
  513. if (SUCCEEDED(sc))
  514. sc = _DllUnregisterServer(NLUTIL_PROG_ID1, CLSID_NlssoUtil);
  515. #endif //OLYMPUS_COMPONENT
  516. return sc;
  517. }
  518. extern "C"
  519. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID * ppv)
  520. {
  521. // get the class factory object
  522. if ( CLSID_ixssoQueryEx == rclsid || CLSID_ixssoQuery == rclsid )
  523. {
  524. IxssoQueryCF.SetClsid( rclsid );
  525. return IxssoQueryCF.QueryInterface( riid, ppv );
  526. }
  527. else if ( CLSID_ixssoUtil == rclsid )
  528. {
  529. // NOTE: There is no difference in the behavior of the Util object.
  530. return IxssoUtilCF.QueryInterface( riid, ppv );
  531. }
  532. else
  533. {
  534. return CLASS_E_CLASSNOTAVAILABLE;
  535. }
  536. }
  537. extern "C"
  538. BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lbv)
  539. {
  540. BOOL fRetval = TRUE;
  541. TRANSLATE_EXCEPTIONS;
  542. TRY
  543. {
  544. switch (dwReason)
  545. {
  546. case DLL_PROCESS_ATTACH:
  547. //DbgPrint("IXSSO: [DLL] Process Attached\n");
  548. g_hInst = hInst;
  549. InitializeCriticalSection( &g_cs );
  550. break;
  551. case DLL_THREAD_DETACH:
  552. //
  553. // This is an opportunity to release resources; necessary since
  554. // ASP doesn't call CoFreeUnusedLibraries.
  555. //
  556. ixssoDebugOut((DEB_REFCOUNTS, "[DLL] Thread detached\n"));
  557. if (0 == g_ulObjCount)
  558. {
  559. FreeResources();
  560. }
  561. break;
  562. case DLL_PROCESS_DETACH:
  563. // NOTE: We can get called here without having freed resources
  564. // if the client application is single-threaded, or if
  565. // thread detach calls are disabled. In this case, it's
  566. // too late to free the ADO recordset class factory because
  567. // the ADO DLL may have already been unloaded.
  568. #if CIDBG
  569. if ( 0 != CIxssoQueryCF::_pIAdoRecordsetCF && 0 != g_ulObjCount )
  570. {
  571. ixssoDebugOut((DEB_WARN, "WARNING - %d unreleased objects\n", g_ulObjCount ));
  572. }
  573. #endif //CIDBG
  574. if (CIxssoQueryCF::_pITypeLibIxsso)
  575. {
  576. CIxssoQueryCF::_pITypeLibIxsso->Release();
  577. CIxssoQueryCF::_pITypeLibIxsso = 0;
  578. }
  579. if (g_pTheGlobalIXSSOVariables)
  580. {
  581. delete g_pTheGlobalIXSSOVariables;
  582. g_pTheGlobalIXSSOVariables = 0;
  583. }
  584. DeleteCriticalSection( &g_cs );
  585. // DbgPrint("IXSSO: [DLL] Process Detached\n");
  586. break;
  587. }
  588. }
  589. CATCH( CException, e )
  590. {
  591. // About the only thing this could be is STATUS_NO_MEMORY which
  592. // can be thrown by InitializeCriticalSection.
  593. ixssoDebugOut(( DEB_ERROR,
  594. "IXSSO: Exception %#x in DllMain\n",
  595. e.GetErrorCode()));
  596. #if CIDBG == 1 // for debugging NTRAID 340297
  597. if (e.GetErrorCode() == STATUS_NO_MEMORY)
  598. DbgPrint( "IXSSO: STATUS_NO_MEMORY exception in DllMain\n");
  599. else
  600. DbgPrint( "IXSSO: ??? Exception in DllMain\n");
  601. #endif // CIDBG == 1
  602. fRetval = FALSE;
  603. }
  604. END_CATCH
  605. UNTRANSLATE_EXCEPTIONS;
  606. return fRetval;
  607. }