1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // so_activex.cpp : Implementation of DLL Exports.
23 
24 
25 // Note: Proxy/Stub Information
26 //      To build a separate proxy/stub DLL,
27 //      run nmake -f so_activexps.mk in the project directory.
28 
29 #include "stdio.h"
30 #include "stdafx2.h"
31 #include "resource.h"
32 #include <initguid.h>
33 #include "so_activex.h"
34 
35 #include "so_activex_i.c"
36 #include "SOActiveX.h"
37 
38 #include <comphelper\documentconstants.hxx>
39 
40 // #define MY_DEBUG 1
41 
42 CComModule _Module;
43 
44 BEGIN_OBJECT_MAP(ObjectMap)
45 OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
46 END_OBJECT_MAP()
47 
48 
49 #define X64_LIB_NAME "so_activex_x64.dll"
50 #define X32_LIB_NAME "so_activex.dll"
51 
52 // 06.11.2009 tkr: to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
53 // in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
54 // Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
55 // extensions\source\activex\main\so_activex.cpp
56 #ifndef KEY_WOW64_64KEY
57 	#define KEY_WOW64_64KEY	(0x0100)
58 #endif
59 #ifndef KEY_WOW64_32KEY
60 	#define KEY_WOW64_32KEY	(0x0200)
61 #endif
62 
63 const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
64 const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
65 
66 #ifdef _AMD64_
67 const BOOL bX64 = TRUE;
68 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
69 #else
70 const BOOL bX64 = FALSE;
71 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
72 #endif
73 
74 // 10.11.2009 tkr: MinGW doesn't know anything about RegDeleteKeyExA if WINVER < 0x0502.
75 extern "C" {
76 WINADVAPI LONG WINAPI RegDeleteKeyExA(HKEY,LPCSTR,REGSAM,DWORD);
77 }
78 
79 /////////////////////////////////////////////////////////////////////////////
80 // DLL Entry Point
81 
82 extern "C"
DllMain(HINSTANCE hInstance,DWORD dwReason,LPVOID)83 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
84 {
85     if (dwReason == DLL_PROCESS_ATTACH)
86     {
87         _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
88         DisableThreadLibraryCalls(hInstance);
89     }
90     else if (dwReason == DLL_PROCESS_DETACH)
91         _Module.Term();
92     return TRUE;    // ok
93 }
94 
95 /////////////////////////////////////////////////////////////////////////////
96 // Used to determine whether the DLL can be unloaded by OLE
97 
DllCanUnloadNow(void)98 STDAPI DllCanUnloadNow(void)
99 {
100     return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
101 }
102 
103 /////////////////////////////////////////////////////////////////////////////
104 // Returns a class factory to create an object of the requested type
105 
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)106 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
107 {
108     return _Module.GetClassObject(rclsid, riid, ppv);
109 }
110 
111 /////////////////////////////////////////////////////////////////////////////
112 // DllRegisterServer - Adds entries to the system registry
113 
114 // for now database component and chart are always installed
115 #define SUPPORTED_EXT_NUM 30
116 const char* aFileExt[] = { ".vor",
117                            ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
118                            ".stw", ".stc", ".sti", ".std",
119                            ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
120                            ".ott", ".otg", ".otp", ".ots", ".otf",
121                            ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
122 const char* aMimeType[] = {
123                           "application/vnd.stardivision.writer",
124 
125                           "application/vnd.stardivision.chart",
126                           "application/vnd.stardivision.draw",
127                           "application/vnd.stardivision.impress",
128                           "application/vnd.stardivision.impress-packed",
129                           "application/vnd.stardivision.calc",
130                           "application/vnd.stardivision.writer",
131                           "application/vnd.stardivision.math",
132 
133                           MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII,
134                           MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII,
135                           MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII,
136                           MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII,
137 
138                           MIMETYPE_VND_SUN_XML_WRITER_ASCII,
139                           MIMETYPE_VND_SUN_XML_CALC_ASCII,
140                           MIMETYPE_VND_SUN_XML_IMPRESS_ASCII,
141                           MIMETYPE_VND_SUN_XML_DRAW_ASCII,
142                           MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII,
143                           MIMETYPE_VND_SUN_XML_MATH_ASCII,
144 
145                           MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII,
146                           MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII,
147                           MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII,
148                           MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII,
149                           MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII,
150 
151                           MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII,
152                           MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII,
153                           MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII,
154                           MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII,
155                           MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII,
156                           MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII,
157                           MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII };
158 
159 const int nForModes[] = { 16,
160                            1,  2,  4,  4,  8, 16, 32,
161                           16,  8,  4,  2,
162                           16,  8,  4,  2, 16, 32,
163                           16,  2,  4,  8, 32,
164                           16, 16, 16,  2,  4,  8, 32 };
165 
166 const char* aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
167 const char* aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
168 
169 // ISOComWindowPeer interface information
170 const char* aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
171 const char* aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
172 
173 // ISODispatchInterceptor interface information
174 const char* aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
175 const char* aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
176 
177 // ISOActionsApproval interface information
178 const char* aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
179 const char* aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
180 
181 // The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
182 const char* aLocalPrefix = "Software\\Classes\\";
183 
createKey(HKEY hkey,const char * aKeyToCreate,REGSAM nKeyAccess,const char * aValue=NULL,const char * aChildName=NULL,const char * aChildValue=NULL)184 BOOL createKey( HKEY hkey,
185                 const char* aKeyToCreate,
186 		REGSAM nKeyAccess,
187                 const char* aValue = NULL,
188                 const char* aChildName = NULL,
189                 const char* aChildValue = NULL )
190 {
191     HKEY hkey1;
192 
193     return ( ERROR_SUCCESS == RegCreateKeyExA( hkey, aKeyToCreate, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
194            && ( !aValue || ERROR_SUCCESS == RegSetValueExA( hkey1,
195                                                            "",
196                                                            0,
197                                                            REG_SZ,
198                                                            (const BYTE*)aValue,
199                                                            strlen( aValue ) ) )
200            && ( !aChildName || ERROR_SUCCESS == RegSetValueExA( hkey1,
201                                                                aChildName,
202                                                                0,
203                                                                REG_SZ,
204                                                                (const BYTE*)aChildValue,
205                                                                strlen( aChildValue ) ) )
206            && ERROR_SUCCESS == RegCloseKey( hkey1 ) );
207 
208 }
209 
210 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
DllRegisterServerNative_Impl(int nMode,BOOL bForAllUsers,REGSAM nKeyAccess,const char * pProgramPath,const char * pLibName)211 STDAPI DllRegisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess, const char* pProgramPath, const char* pLibName )
212 {
213     BOOL aResult = FALSE;
214 
215     HKEY        hkey = NULL;
216     HKEY        hkey1 = NULL;
217     HKEY        hkey2 = NULL;
218     HKEY        hkey3 = NULL;
219     HKEY        hkey4 = NULL;
220     char aSubKey[513];
221     int         ind;
222     const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
223 
224     char pActiveXPath[1124];
225     char pActiveXPath101[1124];
226 
227 
228     // In case SO7 is installed for this user he can have local registry entries that will prevent him from
229     // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
230     // Unfortunately it can be done only for the user who installs the office.
231     if ( bForAllUsers )
232         DllUnregisterServerNative( nMode, sal_False, sal_False );
233 
234 #ifdef MY_DEBUG
235     MessageBoxA(NULL, pProgramPath, "Library Path, ( from library )", MB_OK | MB_ICONINFORMATION);
236 #endif
237 
238     if ( pProgramPath && strlen( pProgramPath ) < 1024 )
239     {
240         sprintf( pActiveXPath, "%s\\%s", pProgramPath, pLibName );
241         sprintf( pActiveXPath101, "%s\\%s, 101", pProgramPath, pLibName );
242 
243         {
244             wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
245             aResult =
246                 ( ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
247                     && ERROR_SUCCESS == RegSetValueExA( hkey, "", 0, REG_SZ, (const BYTE*)"SOActiveX Class", 17 )
248                     && createKey( hkey, "Control", nKeyAccess )
249                     && createKey( hkey, "EnableFullPage", nKeyAccess )
250                     && createKey( hkey, "InprocServer32", nKeyAccess, pActiveXPath, "ThreadingModel", "Apartment" )
251                     && createKey( hkey, "MiscStatus", nKeyAccess, "0" )
252                     && createKey( hkey, "MiscStatus\\1", nKeyAccess, "131473" )
253                     && createKey( hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1" )
254                     && createKey( hkey, "Programmable", nKeyAccess )
255                     && createKey( hkey, "ToolboxBitmap32", nKeyAccess, pActiveXPath101 )
256                     && createKey( hkey, "TypeLib", nKeyAccess, aTypeLib )
257                     && createKey( hkey, "Version", nKeyAccess, "1.0" )
258                     && createKey( hkey, "VersionIndependentProgID", nKeyAccess, "so_activex.SOActiveX" )
259                 && ERROR_SUCCESS == RegCloseKey( hkey )
260                 && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aPrefix, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
261                     && createKey( hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class" )
262                     && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
263                         && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
264                         && createKey( hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1" )
265                     && ERROR_SUCCESS == RegCloseKey( hkey1 )
266                     && createKey( hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class" )
267                     && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX.1", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
268                         && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
269                     && ERROR_SUCCESS == RegCloseKey( hkey1 )
270                     && ERROR_SUCCESS == RegCreateKeyExA( hkey, "TypeLib", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
271                         && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aTypeLib, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
272                             && createKey( hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library" )
273                             && ERROR_SUCCESS == RegCreateKeyExA( hkey2, "1.0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey3 , NULL )
274                                 && ERROR_SUCCESS == RegCreateKeyExA( hkey3, "0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey4 , NULL )
275                                     && createKey( hkey4, "win32", nKeyAccess, pActiveXPath )
276                                 && ERROR_SUCCESS == RegCloseKey( hkey4 )
277                                 && createKey( hkey3, "FLAGS", nKeyAccess, "0" )
278                                 && createKey( hkey3, "HELPDIR", nKeyAccess, pProgramPath )
279                             && ERROR_SUCCESS == RegCloseKey( hkey3 )
280                         && ERROR_SUCCESS == RegCloseKey( hkey2 )
281                     && ERROR_SUCCESS == RegCloseKey( hkey1 )
282                     && ERROR_SUCCESS == RegCreateKeyExA( hkey, "Interface", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
283                         && createKey( hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer" )
284                         && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDWinPeer, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
285                             && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer )
286                             && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer )
287                             && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
288                         && ERROR_SUCCESS == RegCloseKey( hkey2 )
289                         && createKey( hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval" )
290                         && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDActApprove, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
291                             && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove )
292                             && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove )
293                             && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
294                         && ERROR_SUCCESS == RegCloseKey( hkey2 )
295                         && createKey( hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor" )
296                         && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDDispInt, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
297                             && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt )
298                             && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt )
299                             && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
300                         && ERROR_SUCCESS == RegCloseKey( hkey2 )
301                     && ERROR_SUCCESS == RegCloseKey( hkey1 )
302                 && ERROR_SUCCESS == RegCloseKey( hkey ) );
303 
304             hkey = hkey1 = hkey2 = hkey3 = hkey4 = NULL;
305         }
306     }
307 
308     for( ind = 0; ind < SUPPORTED_EXT_NUM && aResult; ind++ )
309     {
310         if( nForModes[ind] & nMode )
311         {
312             wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
313             if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
314 //              || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
315 //                 (const BYTE *)aFileExt[ind], strlen( aFileExt[ind] ) )
316               || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
317                  (const BYTE *)aClassID, strlen(aClassID)) )
318                     aResult = FALSE;
319 
320             if( hkey )
321                 RegCloseKey(hkey),hkey= NULL;
322 
323 /*
324             wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
325             if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
326               || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
327                  (const BYTE *)aMimeType[ind], strlen( aMimeType[ind] ) ) )
328                     aResult = FALSE;
329             if( hkey )
330                 RegCloseKey(hkey),hkey= NULL;
331 */
332         }
333     }
334 
335     wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
336     if ( aResult && ERROR_SUCCESS == RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, nKeyAccess, &hkey) )
337     {
338            for( ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
339            {
340                wsprintfA( aSubKey, "EnableFullPage\\%s", aFileExt[ind] );
341                if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
342                    aResult = FALSE;
343 
344             if ( hkey1 )
345                    RegCloseKey(hkey1),hkey1= NULL;
346          }
347     }
348     else
349         aResult = FALSE;
350 
351     if ( hkey )
352            RegCloseKey(hkey),hkey= NULL;
353 
354     return aResult;
355 }
356 
DllRegisterServerNative(int nMode,BOOL bForAllUsers,BOOL bFor64Bit,const char * pProgramPath)357 STDAPI DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const char* pProgramPath )
358 {
359     HRESULT hr = S_OK;
360     if ( bFor64Bit )
361         hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
362 
363     if ( SUCCEEDED( hr ) )
364     	hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
365 
366     return hr;
367 }
368 
369 
370 /////////////////////////////////////////////////////////////////////////////
371 // DllUnregisterServer - Removes entries from the system registry
DeleteKeyTree(HKEY hkey,const char * pPath,REGSAM nKeyAccess)372 HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
373 {
374     HKEY hkey1 = NULL;
375 
376     char pSubKeyName[256];
377     // first delete the subkeys
378     while( ERROR_SUCCESS == RegOpenKeyExA( hkey, pPath, 0, nKeyAccess, &hkey1)
379         && ERROR_SUCCESS == RegEnumKeyA( hkey1, 0, pSubKeyName, 256 )
380         && ERROR_SUCCESS == DeleteKeyTree( hkey1, pSubKeyName, nKeyAccess ) )
381     {
382         RegCloseKey( hkey1 ),hkey1= NULL;
383     }
384 
385     if ( hkey1 )
386         RegCloseKey( hkey1 ),hkey1= NULL;
387 
388     // delete the key itself
389     return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
390 }
391 
DllUnregisterServerNative_Impl(int nMode,BOOL bForAllUsers,REGSAM nKeyAccess)392 STDAPI DllUnregisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
393 {
394     HKEY        hkey = NULL;
395     BOOL        fErr = FALSE;
396     char aSubKey[513];
397     const char*    aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
398 
399     for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
400     {
401         if( nForModes[ind] & nMode )
402         {
403             DWORD nSubKeys = 0, nValues = 0;
404             wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
405             if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
406                 fErr = TRUE;
407             else
408             {
409                 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
410                     fErr = TRUE;
411 
412                 if ( ERROR_SUCCESS != RegQueryInfoKey(  hkey, NULL, NULL, NULL,
413                                                     &nSubKeys, NULL, NULL,
414                                                     &nValues, NULL, NULL, NULL, NULL ) )
415                 {
416                     RegCloseKey( hkey ), hkey = NULL;
417                     fErr = TRUE;
418                 }
419                 else
420                 {
421                     RegCloseKey( hkey ), hkey = NULL;
422                     if ( !nSubKeys && !nValues )
423                         DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
424                 }
425             }
426 
427                wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
428                if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
429                 fErr = TRUE;
430             else
431             {
432                    if ( ERROR_SUCCESS != RegQueryInfoKey(  hkey, NULL, NULL, NULL,
433                                                     &nSubKeys, NULL, NULL,
434                                                     &nValues, NULL, NULL, NULL, NULL ) )
435                 {
436                     RegCloseKey( hkey ), hkey = NULL;
437                     fErr = TRUE;
438                 }
439                 else
440                 {
441                     RegCloseKey( hkey ), hkey = NULL;
442                     if ( !nSubKeys && !nValues )
443                         DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
444                 }
445             }
446         }
447     }
448 
449     wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
450     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
451            fErr = TRUE;
452 
453     wsprintfA( aSubKey, "%sso_activex.SOActiveX", aPrefix );
454     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
455            fErr = TRUE;
456 
457     wsprintfA( aSubKey, "%sso_activex.SOActiveX.1", aPrefix );
458     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
459            fErr = TRUE;
460 
461     wsprintfA( aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib );
462     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
463            fErr = TRUE;
464 
465     wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer );
466     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
467            fErr = TRUE;
468 
469     wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt );
470     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
471            fErr = TRUE;
472 
473     wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove );
474     if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
475            fErr = TRUE;
476 
477     return !fErr;
478 }
479 
DllUnregisterServerNative(int nMode,BOOL bForAllUsers,BOOL bFor64Bit)480 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
481 {
482     HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
483     if ( SUCCEEDED( hr ) && bFor64Bit )
484         hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
485 
486     return hr;
487 }
488 
489 
490 /////////////////////////////////////////////////////////////////////////////
491 // DllRegisterServerDoc - Adds entries to the system registry
492 
493 #define SUPPORTED_MSEXT_NUM 7
494 const char* aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
495 const char* aMSMimeType[] = { "application/msword",
496                           "application/msword",
497                           "application/msexcell",
498                           "application/msexcell",
499                           "application/mspowerpoint",
500                           "application/mspowerpoint",
501                           "application/mspowerpoint" };
502 const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
503 
504 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
DllRegisterServerDoc_Impl(int nMode,BOOL bForAllUsers,REGSAM nKeyAccess)505 STDAPI DllRegisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
506 {
507     BOOL aResult = TRUE;
508 
509     HKEY        hkey = NULL;
510     HKEY        hkey1 = NULL;
511     char aSubKey[513];
512     int         ind;
513     const char*    aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
514 
515     // In case SO7 is installed for this user he can have local registry entries that will prevent him from
516     // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
517     // Unfortunately it can be done only for the user who installs the office.
518     if ( bForAllUsers )
519         DllUnregisterServerDoc( nMode, sal_False, sal_False );
520 
521     for( ind = 0; ind < SUPPORTED_MSEXT_NUM && aResult; ind++ )
522     {
523         if( nForMSModes[ind] & nMode )
524         {
525                wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
526                if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
527                || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
528                    (const BYTE *)aMSFileExt[ind], strlen( aMSFileExt[ind] ) )
529                || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
530                    (const BYTE *)aClassID, strlen(aClassID)) )
531                        aResult = FALSE;
532 
533                if( hkey )
534                    RegCloseKey(hkey),hkey= NULL;
535 
536                wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
537                if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
538                || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
539                    (const BYTE *)aMSMimeType[ind], strlen( aMSMimeType[ind] ) ) )
540                        aResult = FALSE;
541 
542                if( hkey )
543                    RegCloseKey(hkey),hkey= NULL;
544         }
545     }
546 
547     wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
548     if ( aResult && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
549       && createKey( hkey, "EnableFullPage", nKeyAccess ) )
550     {
551            for( ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
552            {
553             if( nForMSModes[ind] & nMode )
554             {
555                    wsprintfA( aSubKey, "EnableFullPage\\%s", aMSFileExt[ind] );
556                    if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
557                        aResult = FALSE;
558 
559                    if ( hkey1 )
560                        RegCloseKey(hkey1),hkey1= NULL;
561             }
562            }
563     }
564     else
565         aResult = FALSE;
566 
567     if ( hkey )
568         RegCloseKey(hkey),hkey= NULL;
569 
570     return aResult;
571 }
572 
DllRegisterServerDoc(int nMode,BOOL bForAllUsers,BOOL bFor64Bit)573 STDAPI DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
574 {
575     HRESULT hr = S_OK;
576     if ( bFor64Bit )
577         hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
578 
579     if ( SUCCEEDED( hr ) )
580     	hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
581 
582     return hr;
583 }
584 
585 
586 /////////////////////////////////////////////////////////////////////////////
587 // DllUnregisterServerDoc - Removes entries from the system registry
588 
DllUnregisterServerDoc_Impl(int nMode,BOOL bForAllUsers,REGSAM nKeyAccess)589 STDAPI DllUnregisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
590 {
591     HKEY        hkey = NULL;
592     BOOL        fErr = FALSE;
593     char aSubKey[513];
594     const char*    aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
595 
596       for( int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
597        {
598         if( nForMSModes[ind] & nMode )
599         {
600             DWORD nSubKeys = 0, nValues = 0;
601 
602                wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
603                if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
604                 fErr = TRUE;
605             else
606             {
607                    if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Extension" ) )
608                     fErr = TRUE;
609 
610                    if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
611                     fErr = TRUE;
612 
613                 if ( ERROR_SUCCESS != RegQueryInfoKey(  hkey, NULL, NULL, NULL,
614                                                         &nSubKeys, NULL, NULL,
615                                                         &nValues, NULL, NULL, NULL, NULL ) )
616                 {
617                     RegCloseKey( hkey ), hkey = NULL;
618                     fErr = TRUE;
619                 }
620                 else
621                 {
622                     RegCloseKey( hkey ), hkey = NULL;
623                     if ( !nSubKeys && !nValues )
624                         DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
625                 }
626             }
627 
628                wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
629                if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
630                 fErr = TRUE;
631             else
632             {
633                    if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Content Type" ) )
634                     fErr = TRUE;
635 
636                 if ( ERROR_SUCCESS != RegQueryInfoKey(  hkey, NULL, NULL, NULL,
637                                                         &nSubKeys, NULL, NULL,
638                                                         &nValues, NULL, NULL, NULL, NULL ) )
639                 {
640                     RegCloseKey( hkey ), hkey = NULL;
641                     fErr = TRUE;
642                 }
643                 else
644                 {
645                     RegCloseKey( hkey ), hkey = NULL;
646                     if ( !nSubKeys && !nValues )
647                         DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
648                 }
649             }
650         }
651        }
652 
653     return !fErr;
654 }
655 
DllUnregisterServerDoc(int nMode,BOOL bForAllUsers,BOOL bFor64Bit)656 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
657 {
658     HRESULT hr = S_OK;
659     if ( bFor64Bit )
660         hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
661 
662     if ( SUCCEEDED( hr ) )
663     	hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
664 
665     return hr;
666 }
667 
668 /////////////////////////////////////////////////////////////////////////////
669 // DllRegisterServer - regsvr32 entry point
670 
DllRegisterServer(void)671 STDAPI DllRegisterServer( void )
672 {
673     char pProgramPath[1024];
674     HRESULT aResult = E_FAIL;
675 
676     HMODULE aCurModule = GetModuleHandleA( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
677     DWORD nLen = 0;
678     DWORD nLibNameLen = strlen( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
679 
680     if( aCurModule )
681     {
682         nLen = GetModuleFileNameA( aCurModule, pProgramPath, 1024 );
683         if ( nLen && nLen > nLibNameLen + 1 )
684         {
685             pProgramPath[ nLen - nLibNameLen - 1 ] = 0;
686             aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
687             if( SUCCEEDED( aResult ) )
688                 aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
689             else
690             {
691                 aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
692                 if( SUCCEEDED( aResult ) )
693                     aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
694             }
695         }
696     }
697 
698     return aResult;
699 }
700 
701 /////////////////////////////////////////////////////////////////////////////
702 // DllUnregisterServer - regsvr32 entry point
703 
DllUnregisterServer(void)704 STDAPI DllUnregisterServer( void )
705 {
706     DllUnregisterServerDoc( 63, FALSE, bX64 );
707     DllUnregisterServerNative( 63, FALSE, bX64 );
708     DllUnregisterServerDoc( 63, TRUE, bX64 );
709     return DllUnregisterServerNative( 63, TRUE, bX64 );
710 }
711 
712