1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include <stdio.h>
29*cdf0e10cSrcweir #include <inprocembobj.h>
30*cdf0e10cSrcweir #ifdef __MINGW32__
31*cdf0e10cSrcweir #define INITGUID
32*cdf0e10cSrcweir #endif
33*cdf0e10cSrcweir #include <embservconst.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir static const GUID* guidList[ SUPPORTED_FACTORIES_NUM ] = {
36*cdf0e10cSrcweir 	&OID_WriterTextServer,
37*cdf0e10cSrcweir 	&OID_WriterOASISTextServer,
38*cdf0e10cSrcweir 	&OID_CalcServer,
39*cdf0e10cSrcweir 	&OID_CalcOASISServer,
40*cdf0e10cSrcweir 	&OID_DrawingServer,
41*cdf0e10cSrcweir 	&OID_DrawingOASISServer,
42*cdf0e10cSrcweir 	&OID_PresentationServer,
43*cdf0e10cSrcweir 	&OID_PresentationOASISServer,
44*cdf0e10cSrcweir 	&OID_MathServer,
45*cdf0e10cSrcweir 	&OID_MathOASISServer
46*cdf0e10cSrcweir };
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir static HINSTANCE g_hInstance = NULL;
49*cdf0e10cSrcweir static ULONG g_nObj = 0;
50*cdf0e10cSrcweir static ULONG g_nLock = 0;
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir namespace {
54*cdf0e10cSrcweir     void FillCharFromInt( int nValue, char* pBuf, int nLen )
55*cdf0e10cSrcweir     {
56*cdf0e10cSrcweir         int nInd = 0;
57*cdf0e10cSrcweir         while( nInd < nLen )
58*cdf0e10cSrcweir         {
59*cdf0e10cSrcweir             char nSign = ( nValue / ( 1 << ( ( nLen - nInd ) * 4 ) ) ) % 16;
60*cdf0e10cSrcweir             if ( nSign >= 0 && nSign <= 9 )
61*cdf0e10cSrcweir                 pBuf[nInd] = nSign + '0';
62*cdf0e10cSrcweir             else if ( nSign >= 10 && nSign <= 15 )
63*cdf0e10cSrcweir                 pBuf[nInd] = nSign - 10 + 'a';
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir             nInd++;
66*cdf0e10cSrcweir         }
67*cdf0e10cSrcweir     }
68*cdf0e10cSrcweir 
69*cdf0e10cSrcweir     int GetStringFromClassID( const GUID& guid, char* pBuf, int nLen )
70*cdf0e10cSrcweir     {
71*cdf0e10cSrcweir         // is not allowed to insert
72*cdf0e10cSrcweir         if ( nLen < 38 )
73*cdf0e10cSrcweir             return 0;
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir         pBuf[0] = '{';
76*cdf0e10cSrcweir         FillCharFromInt( guid.Data1, &pBuf[1], 8 );
77*cdf0e10cSrcweir         pBuf[9] = '-';
78*cdf0e10cSrcweir         FillCharFromInt( guid.Data2, &pBuf[10], 4 );
79*cdf0e10cSrcweir         pBuf[14] = '-';
80*cdf0e10cSrcweir         FillCharFromInt( guid.Data3, &pBuf[15], 4 );
81*cdf0e10cSrcweir         pBuf[19] = '-';
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir         int nInd = 0;
84*cdf0e10cSrcweir         for ( nInd = 0; nInd < 2 ; nInd++ )
85*cdf0e10cSrcweir             FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 2*nInd], 2 );
86*cdf0e10cSrcweir         pBuf[24] = '-';
87*cdf0e10cSrcweir         for ( nInd = 2; nInd < 8 ; nInd++ )
88*cdf0e10cSrcweir             FillCharFromInt( guid.Data4[nInd], &pBuf[20 + 1 + 2*nInd], 2 );
89*cdf0e10cSrcweir         pBuf[37] = '}';
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir         return 38;
92*cdf0e10cSrcweir 	}
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir     HRESULT WriteLibraryToRegistry( char* pLibrary, DWORD nLen )
95*cdf0e10cSrcweir     {
96*cdf0e10cSrcweir         HRESULT hRes = E_FAIL;
97*cdf0e10cSrcweir         if ( pLibrary && nLen )
98*cdf0e10cSrcweir         {
99*cdf0e10cSrcweir             HKEY hKey = NULL;
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir             hRes = S_OK;
102*cdf0e10cSrcweir             for ( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
103*cdf0e10cSrcweir             {
104*cdf0e10cSrcweir                 char* pSubKey = "Software\\Classes\\CLSID\\.....................................\\InprocHandler32";
105*cdf0e10cSrcweir 
106*cdf0e10cSrcweir                 int nGuidLen = GetStringFromClassID( *guidList[nInd], &pSubKey[23], 38 );
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir                 BOOL bLocalSuccess = FALSE;
109*cdf0e10cSrcweir                 if ( nGuidLen && nGuidLen == 38 )
110*cdf0e10cSrcweir                 {
111*cdf0e10cSrcweir                     if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, pSubKey, &hKey ) )
112*cdf0e10cSrcweir                     {
113*cdf0e10cSrcweir                         if ( ERROR_SUCCESS == RegSetValueEx( hKey, "", 0, REG_SZ, (const BYTE*)pLibrary, nLen ) )
114*cdf0e10cSrcweir                             bLocalSuccess = TRUE;
115*cdf0e10cSrcweir                     }
116*cdf0e10cSrcweir 
117*cdf0e10cSrcweir                     if ( hKey )
118*cdf0e10cSrcweir                     {
119*cdf0e10cSrcweir                         RegCloseKey( hKey );
120*cdf0e10cSrcweir                         hKey = NULL;
121*cdf0e10cSrcweir                     }
122*cdf0e10cSrcweir                 }
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir                 if ( !bLocalSuccess )
125*cdf0e10cSrcweir                     hRes = E_FAIL;
126*cdf0e10cSrcweir             }
127*cdf0e10cSrcweir         }
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir         return hRes;
130*cdf0e10cSrcweir     }
131*cdf0e10cSrcweir };
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir // ===========================
134*cdf0e10cSrcweir // InprocEmbedProvider_Impl declaration
135*cdf0e10cSrcweir // ===========================
136*cdf0e10cSrcweir 
137*cdf0e10cSrcweir namespace inprocserv
138*cdf0e10cSrcweir {
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir class InprocEmbedProvider_Impl : public IClassFactory, public InprocCountedObject_Impl
141*cdf0e10cSrcweir {
142*cdf0e10cSrcweir public:
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 	InprocEmbedProvider_Impl( const GUID& guid );
145*cdf0e10cSrcweir 	virtual ~InprocEmbedProvider_Impl();
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir 	/* IUnknown methods */
148*cdf0e10cSrcweir 	STDMETHOD(QueryInterface)(REFIID riid, LPVOID FAR * ppvObj);
149*cdf0e10cSrcweir 	STDMETHOD_(ULONG, AddRef)();
150*cdf0e10cSrcweir 	STDMETHOD_(ULONG, Release)();
151*cdf0e10cSrcweir 
152*cdf0e10cSrcweir 	/* IClassFactory methods */
153*cdf0e10cSrcweir 	STDMETHOD(CreateInstance)(IUnknown FAR* punkOuter, REFIID riid, void FAR* FAR* ppv);
154*cdf0e10cSrcweir 	STDMETHOD(LockServer)(int fLock);
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir protected:
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir 	ULONG               m_refCount;
159*cdf0e10cSrcweir 	GUID				m_guid;
160*cdf0e10cSrcweir };
161*cdf0e10cSrcweir }; // namespace inprocserv
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir // ===========================
165*cdf0e10cSrcweir // Entry points
166*cdf0e10cSrcweir // ===========================
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir // -------------------------------------------------------------------------------
169*cdf0e10cSrcweir extern "C" BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/ )
170*cdf0e10cSrcweir {
171*cdf0e10cSrcweir     if (dwReason == DLL_PROCESS_ATTACH)
172*cdf0e10cSrcweir     {
173*cdf0e10cSrcweir         g_hInstance = hInstance;
174*cdf0e10cSrcweir     }
175*cdf0e10cSrcweir     else if (dwReason == DLL_PROCESS_DETACH)
176*cdf0e10cSrcweir     {
177*cdf0e10cSrcweir     }
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir     return TRUE;    // ok
180*cdf0e10cSrcweir }
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir // -------------------------------------------------------------------------------
183*cdf0e10cSrcweir extern "C" STDAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, LPVOID* ppv )
184*cdf0e10cSrcweir {
185*cdf0e10cSrcweir 	for( int nInd = 0; nInd < SUPPORTED_FACTORIES_NUM; nInd++ )
186*cdf0e10cSrcweir 		 if ( *guidList[nInd] == rclsid )
187*cdf0e10cSrcweir          {
188*cdf0e10cSrcweir             if ( !IsEqualIID( riid, IID_IUnknown ) && !IsEqualIID( riid, IID_IClassFactory ) )
189*cdf0e10cSrcweir                 return E_NOINTERFACE;
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir             *ppv = new inprocserv::InprocEmbedProvider_Impl( rclsid );
192*cdf0e10cSrcweir             if ( *ppv == NULL )
193*cdf0e10cSrcweir                 return E_OUTOFMEMORY;
194*cdf0e10cSrcweir 
195*cdf0e10cSrcweir             ((LPUNKNOWN)*ppv)->AddRef();
196*cdf0e10cSrcweir             return S_OK;
197*cdf0e10cSrcweir          }
198*cdf0e10cSrcweir 
199*cdf0e10cSrcweir     return E_FAIL;
200*cdf0e10cSrcweir }
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir // -------------------------------------------------------------------------------
203*cdf0e10cSrcweir extern "C" STDAPI DllCanUnloadNow()
204*cdf0e10cSrcweir {
205*cdf0e10cSrcweir     if ( !g_nObj && !g_nLock )
206*cdf0e10cSrcweir         return S_OK;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir     return S_FALSE;
209*cdf0e10cSrcweir }
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir // -------------------------------------------------------------------------------
212*cdf0e10cSrcweir STDAPI DllRegisterServer( void )
213*cdf0e10cSrcweir {
214*cdf0e10cSrcweir 	char aLibPath[1024];
215*cdf0e10cSrcweir 	HMODULE aCurModule = GetModuleHandleA( "inprocserv.dll" );
216*cdf0e10cSrcweir 	if( aCurModule )
217*cdf0e10cSrcweir     {
218*cdf0e10cSrcweir         DWORD nLen = GetModuleFileNameA( aCurModule, aLibPath, 1019 );
219*cdf0e10cSrcweir         if ( nLen && nLen < 1019 )
220*cdf0e10cSrcweir         {
221*cdf0e10cSrcweir             aLibPath[nLen++] = 0;
222*cdf0e10cSrcweir             return WriteLibraryToRegistry( aLibPath, nLen );
223*cdf0e10cSrcweir         }
224*cdf0e10cSrcweir     }
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir     return E_FAIL;
227*cdf0e10cSrcweir }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir // -------------------------------------------------------------------------------
230*cdf0e10cSrcweir STDAPI DllUnregisterServer( void )
231*cdf0e10cSrcweir {
232*cdf0e10cSrcweir     return WriteLibraryToRegistry( "ole32.dll", 10 );
233*cdf0e10cSrcweir }
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir // ===========================
236*cdf0e10cSrcweir // End of entry points
237*cdf0e10cSrcweir // ===========================
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir namespace inprocserv
240*cdf0e10cSrcweir {
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir // ===========================
243*cdf0e10cSrcweir // InprocCountedObject_Impl implementation
244*cdf0e10cSrcweir // ===========================
245*cdf0e10cSrcweir 
246*cdf0e10cSrcweir // -------------------------------------------------------------------------------
247*cdf0e10cSrcweir InprocCountedObject_Impl::InprocCountedObject_Impl()
248*cdf0e10cSrcweir {
249*cdf0e10cSrcweir     g_nObj++;
250*cdf0e10cSrcweir }
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir // -------------------------------------------------------------------------------
253*cdf0e10cSrcweir InprocCountedObject_Impl::~InprocCountedObject_Impl()
254*cdf0e10cSrcweir {
255*cdf0e10cSrcweir     g_nObj--;
256*cdf0e10cSrcweir }
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir // ===========================
259*cdf0e10cSrcweir // InprocEmbedProvider_Impl implementation
260*cdf0e10cSrcweir // ===========================
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir // -------------------------------------------------------------------------------
263*cdf0e10cSrcweir InprocEmbedProvider_Impl::InprocEmbedProvider_Impl( const GUID& guid )
264*cdf0e10cSrcweir : m_refCount( 0 )
265*cdf0e10cSrcweir , m_guid( guid )
266*cdf0e10cSrcweir {
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir // -------------------------------------------------------------------------------
270*cdf0e10cSrcweir InprocEmbedProvider_Impl::~InprocEmbedProvider_Impl()
271*cdf0e10cSrcweir {
272*cdf0e10cSrcweir }
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir // IUnknown
275*cdf0e10cSrcweir // -------------------------------------------------------------------------------
276*cdf0e10cSrcweir STDMETHODIMP InprocEmbedProvider_Impl::QueryInterface( REFIID riid, void FAR* FAR* ppv )
277*cdf0e10cSrcweir {
278*cdf0e10cSrcweir     if(IsEqualIID(riid, IID_IUnknown))
279*cdf0e10cSrcweir 	{
280*cdf0e10cSrcweir 		AddRef();
281*cdf0e10cSrcweir 		*ppv = (IUnknown*) this;
282*cdf0e10cSrcweir 		return S_OK;
283*cdf0e10cSrcweir     }
284*cdf0e10cSrcweir     else if (IsEqualIID(riid, IID_IClassFactory))
285*cdf0e10cSrcweir 	{
286*cdf0e10cSrcweir 		AddRef();
287*cdf0e10cSrcweir 		*ppv = (IClassFactory*) this;
288*cdf0e10cSrcweir 		return S_OK;
289*cdf0e10cSrcweir 	}
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir     *ppv = NULL;
292*cdf0e10cSrcweir     return E_NOINTERFACE;
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir // -------------------------------------------------------------------------------
296*cdf0e10cSrcweir STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::AddRef()
297*cdf0e10cSrcweir {
298*cdf0e10cSrcweir 	return ++m_refCount;
299*cdf0e10cSrcweir }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir // -------------------------------------------------------------------------------
302*cdf0e10cSrcweir STDMETHODIMP_(ULONG) InprocEmbedProvider_Impl::Release()
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir 	sal_Int32 nCount = --m_refCount;
305*cdf0e10cSrcweir 	if ( nCount == 0 )
306*cdf0e10cSrcweir 		delete this;
307*cdf0e10cSrcweir     return nCount;
308*cdf0e10cSrcweir }
309*cdf0e10cSrcweir 
310*cdf0e10cSrcweir // -------------------------------------------------------------------------------
311*cdf0e10cSrcweir STDMETHODIMP InprocEmbedProvider_Impl::CreateInstance(IUnknown FAR* punkOuter,
312*cdf0e10cSrcweir                                                        REFIID riid,
313*cdf0e10cSrcweir                                                        void FAR* FAR* ppv)
314*cdf0e10cSrcweir {
315*cdf0e10cSrcweir     // TODO/LATER: should the aggregation be supported?
316*cdf0e10cSrcweir     // if ( punkOuter != NULL && riid != IID_IUnknown )
317*cdf0e10cSrcweir     //     return E_NOINTERFACE;
318*cdf0e10cSrcweir     if ( punkOuter != NULL )
319*cdf0e10cSrcweir         return CLASS_E_NOAGGREGATION;
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir     InprocEmbedDocument_Impl* pEmbedDocument = new InprocEmbedDocument_Impl( m_guid );
322*cdf0e10cSrcweir     if ( !pEmbedDocument )
323*cdf0e10cSrcweir         return E_OUTOFMEMORY;
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir     pEmbedDocument->AddRef();
326*cdf0e10cSrcweir     HRESULT hr = pEmbedDocument->Init();
327*cdf0e10cSrcweir     if ( SUCCEEDED( hr ) )
328*cdf0e10cSrcweir         hr = pEmbedDocument->QueryInterface( riid, ppv );
329*cdf0e10cSrcweir 	pEmbedDocument->Release();
330*cdf0e10cSrcweir 
331*cdf0e10cSrcweir 	if ( !SUCCEEDED( hr ) )
332*cdf0e10cSrcweir         *ppv = NULL;
333*cdf0e10cSrcweir 
334*cdf0e10cSrcweir     return hr;
335*cdf0e10cSrcweir }
336*cdf0e10cSrcweir 
337*cdf0e10cSrcweir // -------------------------------------------------------------------------------
338*cdf0e10cSrcweir STDMETHODIMP InprocEmbedProvider_Impl::LockServer( int fLock )
339*cdf0e10cSrcweir {
340*cdf0e10cSrcweir     if ( fLock )
341*cdf0e10cSrcweir         g_nLock++;
342*cdf0e10cSrcweir     else
343*cdf0e10cSrcweir         g_nLock--;
344*cdf0e10cSrcweir 
345*cdf0e10cSrcweir     return S_OK;
346*cdf0e10cSrcweir }
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir }; // namespace inprocserv
349*cdf0e10cSrcweir 
350