bump product version to 5.0.4.1
[LibreOffice.git] / extensions / source / activex / so_activex.cxx
blob45c9174610c4963a4eccecce73305dabe3d10b0d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 // so_activex.cpp : Implementation of DLL Exports.
22 // Note: Proxy/Stub Information
23 // To build a separate proxy/stub DLL,
24 // run nmake -f so_activexps.mk in the project directory.
26 #include "stdio.h"
27 #include "stdafx2.h"
28 #include "resource.h"
29 #include <initguid.h>
30 #include "so_activex.h"
32 #include "so_activex_i.c"
33 #include "SOActiveX.h"
35 #include <comphelper\documentconstants.hxx>
37 CComModule _Module;
39 BEGIN_OBJECT_MAP(ObjectMap)
40 OBJECT_ENTRY(CLSID_SOActiveX, CSOActiveX)
41 END_OBJECT_MAP()
44 #define X64_LIB_NAME "so_activex_x64.dll"
45 #define X32_LIB_NAME "so_activex.dll"
47 // to provide windows xp as build systems for mingw we need to define KEY_WOW64_64KEY
48 // in mingw 3.13 KEY_WOW64_64KEY isn't available < Win2003 systems.
49 // Also defined in setup_native\source\win32\customactions\reg64\reg64.cxx,source\win32\customactions\shellextensions\shellextensions.cxx and
50 // extensions\source\activex\main\so_activex.cpp
51 #ifndef KEY_WOW64_64KEY
52 #define KEY_WOW64_64KEY (0x0100)
53 #endif
54 #ifndef KEY_WOW64_32KEY
55 #define KEY_WOW64_32KEY (0x0200)
56 #endif
58 const REGSAM n64KeyAccess = KEY_ALL_ACCESS | KEY_WOW64_64KEY;
59 const REGSAM n32KeyAccess = KEY_ALL_ACCESS;
61 #ifdef _AMD64_
62 const BOOL bX64 = TRUE;
63 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyExA( key, aPath, nKeyAccess, 0 )
64 #else
65 const BOOL bX64 = FALSE;
66 #define REG_DELETE_KEY_A( key, aPath, nKeyAccess ) RegDeleteKeyA( key, aPath )
67 #endif
69 // MinGW doesn't know anything about RegDeleteKeyExA if WINVER < 0x0502.
70 extern "C" {
71 WINADVAPI LONG WINAPI RegDeleteKeyExA(HKEY,LPCSTR,REGSAM,DWORD);
75 // DLL Entry Point
77 extern "C"
78 BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
80 if (dwReason == DLL_PROCESS_ATTACH)
82 _Module.Init(ObjectMap, hInstance, &LIBID_SO_ACTIVEXLib);
83 DisableThreadLibraryCalls(hInstance);
85 else if (dwReason == DLL_PROCESS_DETACH)
86 _Module.Term();
87 return TRUE; // ok
91 // Used to determine whether the DLL can be unloaded by OLE
93 STDAPI DllCanUnloadNow()
95 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
99 // Returns a class factory to create an object of the requested type
101 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
103 return _Module.GetClassObject(rclsid, riid, ppv);
107 // DllRegisterServer - Adds entries to the system registry
109 // for now database component and chart are always installed
110 #define SUPPORTED_EXT_NUM 30
111 const char* aFileExt[] = { ".vor",
112 ".sds", ".sda", ".sdd", ".sdp", ".sdc", ".sdw", ".smf",
113 ".stw", ".stc", ".sti", ".std",
114 ".sxw", ".sxc", ".sxi", ".sxd", ".sxg", ".sxm",
115 ".ott", ".otg", ".otp", ".ots", ".otf",
116 ".odt", ".oth", ".odm", ".odg", ".odp", ".ods", ".odf"};
117 const char* aMimeType[] = {
118 "application/vnd.stardivision.writer",
120 "application/vnd.stardivision.chart",
121 "application/vnd.stardivision.draw",
122 "application/vnd.stardivision.impress",
123 "application/vnd.stardivision.impress-packed",
124 "application/vnd.stardivision.calc",
125 "application/vnd.stardivision.writer",
126 "application/vnd.stardivision.math",
128 MIMETYPE_VND_SUN_XML_WRITER_TEMPLATE_ASCII,
129 MIMETYPE_VND_SUN_XML_CALC_TEMPLATE_ASCII,
130 MIMETYPE_VND_SUN_XML_IMPRESS_TEMPLATE_ASCII,
131 MIMETYPE_VND_SUN_XML_DRAW_TEMPLATE_ASCII,
133 MIMETYPE_VND_SUN_XML_WRITER_ASCII,
134 MIMETYPE_VND_SUN_XML_CALC_ASCII,
135 MIMETYPE_VND_SUN_XML_IMPRESS_ASCII,
136 MIMETYPE_VND_SUN_XML_DRAW_ASCII,
137 MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII,
138 MIMETYPE_VND_SUN_XML_MATH_ASCII,
140 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII,
141 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_TEMPLATE_ASCII,
142 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII,
143 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII,
144 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII,
145 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII,
147 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII,
148 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII,
149 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII,
150 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII,
151 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII,
152 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII,
153 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII };
155 const int nForModes[] = { 16,
156 1, 2, 4, 4, 8, 16, 32,
157 16, 8, 4, 2,
158 16, 8, 4, 2, 16, 32,
159 16, 2, 4, 8, 32,
160 16, 16, 16, 2, 4, 8, 32 };
162 const char* aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
163 const char* aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
165 // ISOComWindowPeer interface information
166 const char* aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
167 const char* aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
169 // ISODispatchInterceptor interface information
170 const char* aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
171 const char* aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
173 // ISOActionsApproval interface information
174 const char* aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
175 const char* aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
177 // The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
178 const char* aLocalPrefix = "Software\\Classes\\";
180 BOOL createKey( HKEY hkey,
181 const char* aKeyToCreate,
182 REGSAM nKeyAccess,
183 const char* aValue = NULL,
184 const char* aChildName = NULL,
185 const char* aChildValue = NULL )
187 HKEY hkey1;
189 return ( ERROR_SUCCESS == RegCreateKeyExA( hkey, aKeyToCreate, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
190 && ( !aValue || ERROR_SUCCESS == RegSetValueExA( hkey1,
193 REG_SZ,
194 reinterpret_cast<const BYTE*>(aValue),
195 sal::static_int_cast<DWORD>(strlen(aValue))))
196 && ( !aChildName || ERROR_SUCCESS == RegSetValueExA( hkey1,
197 aChildName,
199 REG_SZ,
200 reinterpret_cast<const BYTE*>(aChildValue),
201 sal::static_int_cast<DWORD>(strlen(aChildValue))))
202 && ERROR_SUCCESS == RegCloseKey( hkey1 ) );
206 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
207 STDAPI DllRegisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess, const char* pProgramPath, const char* pLibName )
209 BOOL aResult = FALSE;
211 HKEY hkey = NULL;
212 HKEY hkey1 = NULL;
213 HKEY hkey2 = NULL;
214 HKEY hkey3 = NULL;
215 HKEY hkey4 = NULL;
216 char aSubKey[513];
217 int ind;
218 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
220 char pActiveXPath[1124];
221 char pActiveXPath101[1124];
224 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
225 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
226 // Unfortunately it can be done only for the user who installs the office.
227 if ( bForAllUsers )
228 DllUnregisterServerNative( nMode, sal_False, sal_False );
230 if ( pProgramPath && strlen( pProgramPath ) < 1024 )
232 sprintf( pActiveXPath, "%s\\%s", pProgramPath, pLibName );
233 sprintf( pActiveXPath101, "%s\\%s, 101", pProgramPath, pLibName );
236 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
237 aResult =
238 ( ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
239 && ERROR_SUCCESS == RegSetValueExA( hkey, "", 0, REG_SZ, (const BYTE*)"SOActiveX Class", 17 )
240 && createKey( hkey, "Control", nKeyAccess )
241 && createKey( hkey, "EnableFullPage", nKeyAccess )
242 && createKey( hkey, "InprocServer32", nKeyAccess, pActiveXPath, "ThreadingModel", "Apartment" )
243 && createKey( hkey, "MiscStatus", nKeyAccess, "0" )
244 && createKey( hkey, "MiscStatus\\1", nKeyAccess, "131473" )
245 && createKey( hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1" )
246 && createKey( hkey, "Programmable", nKeyAccess )
247 && createKey( hkey, "ToolboxBitmap32", nKeyAccess, pActiveXPath101 )
248 && createKey( hkey, "TypeLib", nKeyAccess, aTypeLib )
249 && createKey( hkey, "Version", nKeyAccess, "1.0" )
250 && createKey( hkey, "VersionIndependentProgID", nKeyAccess, "so_activex.SOActiveX" )
251 && ERROR_SUCCESS == RegCloseKey( hkey )
252 && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aPrefix, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
253 && createKey( hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class" )
254 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
255 && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
256 && createKey( hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1" )
257 && ERROR_SUCCESS == RegCloseKey( hkey1 )
258 && createKey( hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class" )
259 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX.1", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
260 && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
261 && ERROR_SUCCESS == RegCloseKey( hkey1 )
262 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "TypeLib", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
263 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aTypeLib, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
264 && createKey( hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library" )
265 && ERROR_SUCCESS == RegCreateKeyExA( hkey2, "1.0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey3 , NULL )
266 && ERROR_SUCCESS == RegCreateKeyExA( hkey3, "0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey4 , NULL )
267 && createKey( hkey4, "win32", nKeyAccess, pActiveXPath )
268 && ERROR_SUCCESS == RegCloseKey( hkey4 )
269 && createKey( hkey3, "FLAGS", nKeyAccess, "0" )
270 && createKey( hkey3, "HELPDIR", nKeyAccess, pProgramPath )
271 && ERROR_SUCCESS == RegCloseKey( hkey3 )
272 && ERROR_SUCCESS == RegCloseKey( hkey2 )
273 && ERROR_SUCCESS == RegCloseKey( hkey1 )
274 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "Interface", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
275 && createKey( hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer" )
276 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDWinPeer, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
277 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer )
278 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer )
279 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
280 && ERROR_SUCCESS == RegCloseKey( hkey2 )
281 && createKey( hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval" )
282 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDActApprove, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
283 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove )
284 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove )
285 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
286 && ERROR_SUCCESS == RegCloseKey( hkey2 )
287 && createKey( hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor" )
288 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDDispInt, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
289 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt )
290 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt )
291 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
292 && ERROR_SUCCESS == RegCloseKey( hkey2 )
293 && ERROR_SUCCESS == RegCloseKey( hkey1 )
294 && ERROR_SUCCESS == RegCloseKey( hkey ) );
296 hkey = hkey1 = hkey2 = hkey3 = hkey4 = NULL;
300 for( ind = 0; ind < SUPPORTED_EXT_NUM && aResult; ind++ )
302 if( nForModes[ind] & nMode )
304 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
305 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
306 || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
307 reinterpret_cast<const BYTE *>(aClassID),
308 sal::static_int_cast<DWORD>(strlen(aClassID))) )
310 aResult = FALSE;
313 if( hkey )
314 RegCloseKey(hkey),hkey= NULL;
318 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
319 if ( aResult && ERROR_SUCCESS == RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, nKeyAccess, &hkey) )
321 for( ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
323 wsprintfA( aSubKey, "EnableFullPage\\%s", aFileExt[ind] );
324 if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
325 aResult = FALSE;
327 if ( hkey1 )
328 RegCloseKey(hkey1),hkey1= NULL;
331 else
332 aResult = FALSE;
334 if ( hkey )
335 RegCloseKey(hkey),hkey= NULL;
337 return aResult;
340 STDAPI DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const char* pProgramPath )
342 HRESULT hr = S_OK;
343 if ( bFor64Bit )
344 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
346 if ( SUCCEEDED( hr ) )
347 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
349 return hr;
354 // DllUnregisterServer - Removes entries from the system registry
355 HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
357 HKEY hkey1 = NULL;
359 char pSubKeyName[256];
360 // first delete the subkeys
361 while( ERROR_SUCCESS == RegOpenKeyExA( hkey, pPath, 0, nKeyAccess, &hkey1)
362 && ERROR_SUCCESS == RegEnumKeyA( hkey1, 0, pSubKeyName, 256 )
363 && ERROR_SUCCESS == DeleteKeyTree( hkey1, pSubKeyName, nKeyAccess ) )
365 RegCloseKey( hkey1 ),hkey1= NULL;
368 if ( hkey1 )
369 RegCloseKey( hkey1 ),hkey1= NULL;
371 // delete the key itself
372 return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
375 STDAPI DllUnregisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
377 HKEY hkey = NULL;
378 BOOL fErr = FALSE;
379 char aSubKey[513];
380 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
382 for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
384 if( nForModes[ind] & nMode )
386 DWORD nSubKeys = 0, nValues = 0;
387 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
388 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
389 fErr = TRUE;
390 else
392 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
393 fErr = TRUE;
395 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
396 &nSubKeys, NULL, NULL,
397 &nValues, NULL, NULL, NULL, NULL ) )
399 RegCloseKey( hkey ), hkey = NULL;
400 fErr = TRUE;
402 else
404 RegCloseKey( hkey ), hkey = NULL;
405 if ( !nSubKeys && !nValues )
406 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
410 wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
411 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
412 fErr = TRUE;
413 else
415 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
416 &nSubKeys, NULL, NULL,
417 &nValues, NULL, NULL, NULL, NULL ) )
419 RegCloseKey( hkey ), hkey = NULL;
420 fErr = TRUE;
422 else
424 RegCloseKey( hkey ), hkey = NULL;
425 if ( !nSubKeys && !nValues )
426 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
432 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
433 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
434 fErr = TRUE;
436 wsprintfA( aSubKey, "%sso_activex.SOActiveX", aPrefix );
437 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
438 fErr = TRUE;
440 wsprintfA( aSubKey, "%sso_activex.SOActiveX.1", aPrefix );
441 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
442 fErr = TRUE;
444 wsprintfA( aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib );
445 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
446 fErr = TRUE;
448 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer );
449 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
450 fErr = TRUE;
452 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt );
453 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
454 fErr = TRUE;
456 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove );
457 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
458 fErr = TRUE;
460 return !fErr;
463 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
465 HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
466 if ( SUCCEEDED( hr ) && bFor64Bit )
467 hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
469 return hr;
474 // DllRegisterServerDoc - Adds entries to the system registry
476 #define SUPPORTED_MSEXT_NUM 7
477 const char* aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
478 const char* aMSMimeType[] = { "application/msword",
479 "application/msword",
480 "application/msexcell",
481 "application/msexcell",
482 "application/mspowerpoint",
483 "application/mspowerpoint",
484 "application/mspowerpoint" };
485 const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
487 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
488 STDAPI DllRegisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
490 BOOL aResult = TRUE;
492 HKEY hkey = NULL;
493 HKEY hkey1 = NULL;
494 char aSubKey[513];
495 int ind;
496 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
498 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
499 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
500 // Unfortunately it can be done only for the user who installs the office.
501 if ( bForAllUsers )
502 DllUnregisterServerDoc( nMode, sal_False, sal_False );
504 for( ind = 0; ind < SUPPORTED_MSEXT_NUM && aResult; ind++ )
506 if( nForMSModes[ind] & nMode )
508 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
509 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
510 || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
511 reinterpret_cast<const BYTE *>(aMSFileExt[ind]),
512 sal::static_int_cast<DWORD>(strlen(aMSFileExt[ind])))
513 || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
514 reinterpret_cast<const BYTE *>(aClassID),
515 sal::static_int_cast<DWORD>(strlen(aClassID))))
517 aResult = FALSE;
520 if( hkey )
521 RegCloseKey(hkey),hkey= NULL;
523 wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
524 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
525 || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
526 reinterpret_cast<const BYTE *>(aMSMimeType[ind]),
527 sal::static_int_cast<DWORD>(strlen(aMSMimeType[ind]))))
529 aResult = FALSE;
532 if( hkey )
533 RegCloseKey(hkey),hkey= NULL;
537 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
538 if ( aResult && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
539 && createKey( hkey, "EnableFullPage", nKeyAccess ) )
541 for( ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
543 if( nForMSModes[ind] & nMode )
545 wsprintfA( aSubKey, "EnableFullPage\\%s", aMSFileExt[ind] );
546 if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
547 aResult = FALSE;
549 if ( hkey1 )
550 RegCloseKey(hkey1),hkey1= NULL;
554 else
555 aResult = FALSE;
557 if ( hkey )
558 RegCloseKey(hkey),hkey= NULL;
560 return aResult;
563 STDAPI DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
565 HRESULT hr = S_OK;
566 if ( bFor64Bit )
567 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
569 if ( SUCCEEDED( hr ) )
570 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
572 return hr;
577 // DllUnregisterServerDoc - Removes entries from the system registry
579 STDAPI DllUnregisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
581 HKEY hkey = NULL;
582 BOOL fErr = FALSE;
583 char aSubKey[513];
584 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
586 for( int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
588 if( nForMSModes[ind] & nMode )
590 DWORD nSubKeys = 0, nValues = 0;
592 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
593 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
594 fErr = TRUE;
595 else
597 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Extension" ) )
598 fErr = TRUE;
600 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
601 fErr = TRUE;
603 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
604 &nSubKeys, NULL, NULL,
605 &nValues, NULL, NULL, NULL, NULL ) )
607 RegCloseKey( hkey ), hkey = NULL;
608 fErr = TRUE;
610 else
612 RegCloseKey( hkey ), hkey = NULL;
613 if ( !nSubKeys && !nValues )
614 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
618 wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
619 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
620 fErr = TRUE;
621 else
623 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Content Type" ) )
624 fErr = TRUE;
626 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
627 &nSubKeys, NULL, NULL,
628 &nValues, NULL, NULL, NULL, NULL ) )
630 RegCloseKey( hkey ), hkey = NULL;
631 fErr = TRUE;
633 else
635 RegCloseKey( hkey ), hkey = NULL;
636 if ( !nSubKeys && !nValues )
637 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
643 return !fErr;
646 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
648 HRESULT hr = S_OK;
649 if ( bFor64Bit )
650 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
652 if ( SUCCEEDED( hr ) )
653 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
655 return hr;
659 // DllRegisterServer - regsvr32 entry point
661 STDAPI DllRegisterServer()
663 char pProgramPath[1024];
664 HRESULT aResult = E_FAIL;
666 HMODULE aCurModule = GetModuleHandleA( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
667 DWORD nLibNameLen = sal::static_int_cast<DWORD>(
668 strlen((bX64) ? X64_LIB_NAME : X32_LIB_NAME));
670 if( aCurModule )
672 DWORD nLen = GetModuleFileNameA( aCurModule, pProgramPath, 1024 );
673 if ( nLen && nLen > nLibNameLen + 1 )
675 pProgramPath[ nLen - nLibNameLen - 1 ] = 0;
676 aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
677 if( SUCCEEDED( aResult ) )
678 aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
679 else
681 aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
682 if( SUCCEEDED( aResult ) )
683 aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
688 return aResult;
692 // DllUnregisterServer - regsvr32 entry point
694 STDAPI DllUnregisterServer()
696 DllUnregisterServerDoc( 63, FALSE, bX64 );
697 DllUnregisterServerNative( 63, FALSE, bX64 );
698 DllUnregisterServerDoc( 63, TRUE, bX64 );
699 return DllUnregisterServerNative( 63, TRUE, bX64 );
702 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */