bump product version to 4.1.6.2
[LibreOffice.git] / extensions / source / activex / so_activex.cxx
blob4fbf3580bceb9385c3297c6c41db85bfefe572c6
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);
74 /////////////////////////////////////////////////////////////////////////////
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
90 /////////////////////////////////////////////////////////////////////////////
91 // Used to determine whether the DLL can be unloaded by OLE
93 STDAPI DllCanUnloadNow(void)
95 return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
98 /////////////////////////////////////////////////////////////////////////////
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);
106 /////////////////////////////////////////////////////////////////////////////
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_DRAWING_TEMPLATE_ASCII,
142 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII,
143 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII,
144 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII,
146 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII,
147 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII,
148 MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII,
149 MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII,
150 MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII,
151 MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII,
152 MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII };
154 const int nForModes[] = { 16,
155 1, 2, 4, 4, 8, 16, 32,
156 16, 8, 4, 2,
157 16, 8, 4, 2, 16, 32,
158 16, 2, 4, 8, 32,
159 16, 16, 16, 2, 4, 8, 32 };
161 const char* aClassID = "{67F2A879-82D5-4A6D-8CC5-FFB3C114B69D}";
162 const char* aTypeLib = "{61FA3F13-8061-4796-B055-3697ED28CB38}";
164 // ISOComWindowPeer interface information
165 const char* aInterIDWinPeer = "{BF5D10F3-8A10-4A0B-B150-2B6AA2D7E118}";
166 const char* aProxyStubWinPeer = "{00020424-0000-0000-C000-000000000046}";
168 // ISODispatchInterceptor interface information
169 const char* aInterIDDispInt = "{9337694C-B27D-4384-95A4-9D8E0EABC9E5}";
170 const char* aProxyStubDispInt = "{00020424-0000-0000-C000-000000000046}";
172 // ISOActionsApproval interface information
173 const char* aInterIDActApprove = "{029E9F1E-2B3F-4297-9160-8197DE7ED54F}";
174 const char* aProxyStubActApprove = "{00020424-0000-0000-C000-000000000046}";
176 // The following prefix is required for HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER ( not for HKEY_CLASSES_ROOT )
177 const char* aLocalPrefix = "Software\\Classes\\";
179 BOOL createKey( HKEY hkey,
180 const char* aKeyToCreate,
181 REGSAM nKeyAccess,
182 const char* aValue = NULL,
183 const char* aChildName = NULL,
184 const char* aChildValue = NULL )
186 HKEY hkey1;
188 return ( ERROR_SUCCESS == RegCreateKeyExA( hkey, aKeyToCreate, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
189 && ( !aValue || ERROR_SUCCESS == RegSetValueExA( hkey1,
192 REG_SZ,
193 reinterpret_cast<const BYTE*>(aValue),
194 sal::static_int_cast<DWORD>(strlen(aValue))))
195 && ( !aChildName || ERROR_SUCCESS == RegSetValueExA( hkey1,
196 aChildName,
198 REG_SZ,
199 reinterpret_cast<const BYTE*>(aChildValue),
200 sal::static_int_cast<DWORD>(strlen(aChildValue))))
201 && ERROR_SUCCESS == RegCloseKey( hkey1 ) );
205 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
206 STDAPI DllRegisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess, const char* pProgramPath, const char* pLibName )
208 BOOL aResult = FALSE;
210 HKEY hkey = NULL;
211 HKEY hkey1 = NULL;
212 HKEY hkey2 = NULL;
213 HKEY hkey3 = NULL;
214 HKEY hkey4 = NULL;
215 char aSubKey[513];
216 int ind;
217 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
219 char pActiveXPath[1124];
220 char pActiveXPath101[1124];
223 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
224 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
225 // Unfortunately it can be done only for the user who installs the office.
226 if ( bForAllUsers )
227 DllUnregisterServerNative( nMode, sal_False, sal_False );
229 if ( pProgramPath && strlen( pProgramPath ) < 1024 )
231 sprintf( pActiveXPath, "%s\\%s", pProgramPath, pLibName );
232 sprintf( pActiveXPath101, "%s\\%s, 101", pProgramPath, pLibName );
235 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
236 aResult =
237 ( ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
238 && ERROR_SUCCESS == RegSetValueExA( hkey, "", 0, REG_SZ, (const BYTE*)"SOActiveX Class", 17 )
239 && createKey( hkey, "Control", nKeyAccess )
240 && createKey( hkey, "EnableFullPage", nKeyAccess )
241 && createKey( hkey, "InprocServer32", nKeyAccess, pActiveXPath, "ThreadingModel", "Apartment" )
242 && createKey( hkey, "MiscStatus", nKeyAccess, "0" )
243 && createKey( hkey, "MiscStatus\\1", nKeyAccess, "131473" )
244 && createKey( hkey, "ProgID", nKeyAccess, "so_activex.SOActiveX.1" )
245 && createKey( hkey, "Programmable", nKeyAccess )
246 && createKey( hkey, "ToolboxBitmap32", nKeyAccess, pActiveXPath101 )
247 && createKey( hkey, "TypeLib", nKeyAccess, aTypeLib )
248 && createKey( hkey, "Version", nKeyAccess, "1.0" )
249 && createKey( hkey, "VersionIndependentProgID", nKeyAccess, "so_activex.SOActiveX" )
250 && ERROR_SUCCESS == RegCloseKey( hkey )
251 && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aPrefix, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
252 && createKey( hkey, "so_activex.SOActiveX", nKeyAccess, "SOActiveX Class" )
253 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
254 && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
255 && createKey( hkey1, "CurVer", nKeyAccess, "so_activex.SOActiveX.1" )
256 && ERROR_SUCCESS == RegCloseKey( hkey1 )
257 && createKey( hkey, "so_activex.SOActiveX.1", nKeyAccess, "SOActiveX Class" )
258 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "so_activex.SOActiveX.1", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
259 && createKey( hkey1, "CLSID", nKeyAccess, aClassID )
260 && ERROR_SUCCESS == RegCloseKey( hkey1 )
261 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "TypeLib", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
262 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aTypeLib, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
263 && createKey( hkey2, "1.0", nKeyAccess, "wrap_activex 1.0 Type Library" )
264 && ERROR_SUCCESS == RegCreateKeyExA( hkey2, "1.0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey3 , NULL )
265 && ERROR_SUCCESS == RegCreateKeyExA( hkey3, "0", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey4 , NULL )
266 && createKey( hkey4, "win32", nKeyAccess, pActiveXPath )
267 && ERROR_SUCCESS == RegCloseKey( hkey4 )
268 && createKey( hkey3, "FLAGS", nKeyAccess, "0" )
269 && createKey( hkey3, "HELPDIR", nKeyAccess, pProgramPath )
270 && ERROR_SUCCESS == RegCloseKey( hkey3 )
271 && ERROR_SUCCESS == RegCloseKey( hkey2 )
272 && ERROR_SUCCESS == RegCloseKey( hkey1 )
273 && ERROR_SUCCESS == RegCreateKeyExA( hkey, "Interface", 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL )
274 && createKey( hkey1, aInterIDWinPeer, nKeyAccess, "ISOComWindowPeer" )
275 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDWinPeer, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
276 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubWinPeer )
277 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubWinPeer )
278 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
279 && ERROR_SUCCESS == RegCloseKey( hkey2 )
280 && createKey( hkey1, aInterIDActApprove, nKeyAccess, "ISOActionsApproval" )
281 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDActApprove, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
282 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubActApprove )
283 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubActApprove )
284 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
285 && ERROR_SUCCESS == RegCloseKey( hkey2 )
286 && createKey( hkey1, aInterIDDispInt, nKeyAccess, "ISODispatchInterceptor" )
287 && ERROR_SUCCESS == RegCreateKeyExA( hkey1, aInterIDDispInt, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey2 , NULL )
288 && createKey( hkey2, "ProxyStubClsid", nKeyAccess, aProxyStubDispInt )
289 && createKey( hkey2, "ProxyStubClsid32", nKeyAccess, aProxyStubDispInt )
290 && createKey( hkey2, "TypeLib", nKeyAccess, aTypeLib, "Version", "1.0" )
291 && ERROR_SUCCESS == RegCloseKey( hkey2 )
292 && ERROR_SUCCESS == RegCloseKey( hkey1 )
293 && ERROR_SUCCESS == RegCloseKey( hkey ) );
295 hkey = hkey1 = hkey2 = hkey3 = hkey4 = NULL;
299 for( ind = 0; ind < SUPPORTED_EXT_NUM && aResult; ind++ )
301 if( nForModes[ind] & nMode )
303 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
304 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
305 || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
306 reinterpret_cast<const BYTE *>(aClassID),
307 sal::static_int_cast<DWORD>(strlen(aClassID))) )
309 aResult = FALSE;
312 if( hkey )
313 RegCloseKey(hkey),hkey= NULL;
317 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
318 if ( aResult && ERROR_SUCCESS == RegOpenKeyExA(bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, nKeyAccess, &hkey) )
320 for( ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
322 wsprintfA( aSubKey, "EnableFullPage\\%s", aFileExt[ind] );
323 if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
324 aResult = FALSE;
326 if ( hkey1 )
327 RegCloseKey(hkey1),hkey1= NULL;
330 else
331 aResult = FALSE;
333 if ( hkey )
334 RegCloseKey(hkey),hkey= NULL;
336 return aResult;
339 STDAPI DllRegisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit, const char* pProgramPath )
341 HRESULT hr = S_OK;
342 if ( bFor64Bit )
343 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess, pProgramPath, X64_LIB_NAME );
345 if ( SUCCEEDED( hr ) )
346 hr = DllRegisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess, pProgramPath, X32_LIB_NAME );
348 return hr;
352 /////////////////////////////////////////////////////////////////////////////
353 // DllUnregisterServer - Removes entries from the system registry
354 HRESULT DeleteKeyTree( HKEY hkey, const char* pPath, REGSAM nKeyAccess )
356 HKEY hkey1 = NULL;
358 char pSubKeyName[256];
359 // first delete the subkeys
360 while( ERROR_SUCCESS == RegOpenKeyExA( hkey, pPath, 0, nKeyAccess, &hkey1)
361 && ERROR_SUCCESS == RegEnumKeyA( hkey1, 0, pSubKeyName, 256 )
362 && ERROR_SUCCESS == DeleteKeyTree( hkey1, pSubKeyName, nKeyAccess ) )
364 RegCloseKey( hkey1 ),hkey1= NULL;
367 if ( hkey1 )
368 RegCloseKey( hkey1 ),hkey1= NULL;
370 // delete the key itself
371 return REG_DELETE_KEY_A( hkey, pPath, nKeyAccess & ( KEY_WOW64_64KEY | KEY_WOW64_32KEY ) );
374 STDAPI DllUnregisterServerNative_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
376 HKEY hkey = NULL;
377 BOOL fErr = FALSE;
378 char aSubKey[513];
379 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
381 for( int ind = 0; ind < SUPPORTED_EXT_NUM; ind++ )
383 if( nForModes[ind] & nMode )
385 DWORD nSubKeys = 0, nValues = 0;
386 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMimeType[ind] );
387 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
388 fErr = TRUE;
389 else
391 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
392 fErr = TRUE;
394 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
395 &nSubKeys, NULL, NULL,
396 &nValues, NULL, NULL, NULL, NULL ) )
398 RegCloseKey( hkey ), hkey = NULL;
399 fErr = TRUE;
401 else
403 RegCloseKey( hkey ), hkey = NULL;
404 if ( !nSubKeys && !nValues )
405 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
409 wsprintfA( aSubKey, "%s%s", aPrefix, aFileExt[ind] );
410 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
411 fErr = TRUE;
412 else
414 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
415 &nSubKeys, NULL, NULL,
416 &nValues, NULL, NULL, NULL, NULL ) )
418 RegCloseKey( hkey ), hkey = NULL;
419 fErr = TRUE;
421 else
423 RegCloseKey( hkey ), hkey = NULL;
424 if ( !nSubKeys && !nValues )
425 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
431 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
432 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
433 fErr = TRUE;
435 wsprintfA( aSubKey, "%sso_activex.SOActiveX", aPrefix );
436 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
437 fErr = TRUE;
439 wsprintfA( aSubKey, "%sso_activex.SOActiveX.1", aPrefix );
440 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
441 fErr = TRUE;
443 wsprintfA( aSubKey, "%s\\TypeLib\\%s", aPrefix, aTypeLib );
444 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
445 fErr = TRUE;
447 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDWinPeer );
448 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
449 fErr = TRUE;
451 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDDispInt );
452 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
453 fErr = TRUE;
455 wsprintfA( aSubKey, "%s\\Interface\\%s", aPrefix, aInterIDActApprove );
456 if( ERROR_SUCCESS != DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess ) )
457 fErr = TRUE;
459 return !fErr;
462 STDAPI DllUnregisterServerNative( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
464 HRESULT hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n32KeyAccess );
465 if ( SUCCEEDED( hr ) && bFor64Bit )
466 hr = DllUnregisterServerNative_Impl( nMode, bForAllUsers, n64KeyAccess );
468 return hr;
472 /////////////////////////////////////////////////////////////////////////////
473 // DllRegisterServerDoc - Adds entries to the system registry
475 #define SUPPORTED_MSEXT_NUM 7
476 const char* aMSFileExt[] = { ".dot", ".doc", ".xlt", ".xls", ".pot", ".ppt", ".pps" };
477 const char* aMSMimeType[] = { "application/msword",
478 "application/msword",
479 "application/msexcell",
480 "application/msexcell",
481 "application/mspowerpoint",
482 "application/mspowerpoint",
483 "application/mspowerpoint" };
484 const int nForMSModes[] = { 1, 1, 2, 2, 4, 4, 4 };
486 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit );
487 STDAPI DllRegisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
489 BOOL aResult = TRUE;
491 HKEY hkey = NULL;
492 HKEY hkey1 = NULL;
493 char aSubKey[513];
494 int ind;
495 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
497 // In case SO7 is installed for this user he can have local registry entries that will prevent him from
498 // using SO8 ActiveX control. The fix is just to clean up the local entries related to ActiveX control.
499 // Unfortunately it can be done only for the user who installs the office.
500 if ( bForAllUsers )
501 DllUnregisterServerDoc( nMode, sal_False, sal_False );
503 for( ind = 0; ind < SUPPORTED_MSEXT_NUM && aResult; ind++ )
505 if( nForMSModes[ind] & nMode )
507 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
508 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
509 || ERROR_SUCCESS != RegSetValueExA(hkey, "Extension", 0, REG_SZ,
510 reinterpret_cast<const BYTE *>(aMSFileExt[ind]),
511 sal::static_int_cast<DWORD>(strlen(aMSFileExt[ind])))
512 || ERROR_SUCCESS != RegSetValueExA(hkey, "CLSID", 0, REG_SZ,
513 reinterpret_cast<const BYTE *>(aClassID),
514 sal::static_int_cast<DWORD>(strlen(aClassID))))
516 aResult = FALSE;
519 if( hkey )
520 RegCloseKey(hkey),hkey= NULL;
522 wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
523 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL )
524 || ERROR_SUCCESS != RegSetValueExA(hkey, "Content Type", 0, REG_SZ,
525 reinterpret_cast<const BYTE *>(aMSMimeType[ind]),
526 sal::static_int_cast<DWORD>(strlen(aMSMimeType[ind]))))
528 aResult = FALSE;
531 if( hkey )
532 RegCloseKey(hkey),hkey= NULL;
536 wsprintfA( aSubKey, "%sCLSID\\%s", aPrefix, aClassID );
537 if ( aResult && ERROR_SUCCESS == RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey , NULL )
538 && createKey( hkey, "EnableFullPage", nKeyAccess ) )
540 for( ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
542 if( nForMSModes[ind] & nMode )
544 wsprintfA( aSubKey, "EnableFullPage\\%s", aMSFileExt[ind] );
545 if ( ERROR_SUCCESS != RegCreateKeyExA( hkey, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey1 , NULL ) )
546 aResult = FALSE;
548 if ( hkey1 )
549 RegCloseKey(hkey1),hkey1= NULL;
553 else
554 aResult = FALSE;
556 if ( hkey )
557 RegCloseKey(hkey),hkey= NULL;
559 return aResult;
562 STDAPI DllRegisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
564 HRESULT hr = S_OK;
565 if ( bFor64Bit )
566 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
568 if ( SUCCEEDED( hr ) )
569 hr = DllRegisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
571 return hr;
575 /////////////////////////////////////////////////////////////////////////////
576 // DllUnregisterServerDoc - Removes entries from the system registry
578 STDAPI DllUnregisterServerDoc_Impl( int nMode, BOOL bForAllUsers, REGSAM nKeyAccess )
580 HKEY hkey = NULL;
581 BOOL fErr = FALSE;
582 char aSubKey[513];
583 const char* aPrefix = aLocalPrefix; // bForAllUsers ? "" : aLocalPrefix;
585 for( int ind = 0; ind < SUPPORTED_MSEXT_NUM; ind++ )
587 if( nForMSModes[ind] & nMode )
589 DWORD nSubKeys = 0, nValues = 0;
591 wsprintfA( aSubKey, "%sMIME\\DataBase\\Content Type\\%s", aPrefix, aMSMimeType[ind] );
592 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
593 fErr = TRUE;
594 else
596 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Extension" ) )
597 fErr = TRUE;
599 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "CLSID" ) )
600 fErr = TRUE;
602 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
603 &nSubKeys, NULL, NULL,
604 &nValues, NULL, NULL, NULL, NULL ) )
606 RegCloseKey( hkey ), hkey = NULL;
607 fErr = TRUE;
609 else
611 RegCloseKey( hkey ), hkey = NULL;
612 if ( !nSubKeys && !nValues )
613 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
617 wsprintfA( aSubKey, "%s%s", aPrefix, aMSFileExt[ind] );
618 if ( ERROR_SUCCESS != RegCreateKeyExA( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, nKeyAccess, NULL, &hkey, NULL ) )
619 fErr = TRUE;
620 else
622 if ( ERROR_SUCCESS != RegDeleteValue( hkey, "Content Type" ) )
623 fErr = TRUE;
625 if ( ERROR_SUCCESS != RegQueryInfoKey( hkey, NULL, NULL, NULL,
626 &nSubKeys, NULL, NULL,
627 &nValues, NULL, NULL, NULL, NULL ) )
629 RegCloseKey( hkey ), hkey = NULL;
630 fErr = TRUE;
632 else
634 RegCloseKey( hkey ), hkey = NULL;
635 if ( !nSubKeys && !nValues )
636 DeleteKeyTree( bForAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, aSubKey, nKeyAccess );
642 return !fErr;
645 STDAPI DllUnregisterServerDoc( int nMode, BOOL bForAllUsers, BOOL bFor64Bit )
647 HRESULT hr = S_OK;
648 if ( bFor64Bit )
649 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n64KeyAccess );
651 if ( SUCCEEDED( hr ) )
652 hr = DllUnregisterServerDoc_Impl( nMode, bForAllUsers, n32KeyAccess );
654 return hr;
657 /////////////////////////////////////////////////////////////////////////////
658 // DllRegisterServer - regsvr32 entry point
660 STDAPI DllRegisterServer( void )
662 char pProgramPath[1024];
663 HRESULT aResult = E_FAIL;
665 HMODULE aCurModule = GetModuleHandleA( bX64 ? X64_LIB_NAME : X32_LIB_NAME );
666 DWORD nLibNameLen = sal::static_int_cast<DWORD>(
667 strlen((bX64) ? X64_LIB_NAME : X32_LIB_NAME));
669 if( aCurModule )
671 DWORD nLen = GetModuleFileNameA( aCurModule, pProgramPath, 1024 );
672 if ( nLen && nLen > nLibNameLen + 1 )
674 pProgramPath[ nLen - nLibNameLen - 1 ] = 0;
675 aResult = DllRegisterServerNative( 31, TRUE, bX64, pProgramPath );
676 if( SUCCEEDED( aResult ) )
677 aResult = DllRegisterServerDoc( 31, TRUE, bX64 );
678 else
680 aResult = DllRegisterServerNative( 31, FALSE, bX64, pProgramPath );
681 if( SUCCEEDED( aResult ) )
682 aResult = DllRegisterServerDoc( 31, FALSE, bX64 );
687 return aResult;
690 /////////////////////////////////////////////////////////////////////////////
691 // DllUnregisterServer - regsvr32 entry point
693 STDAPI DllUnregisterServer( void )
695 DllUnregisterServerDoc( 63, FALSE, bX64 );
696 DllUnregisterServerNative( 63, FALSE, bX64 );
697 DllUnregisterServerDoc( 63, TRUE, bX64 );
698 return DllUnregisterServerNative( 63, TRUE, bX64 );
701 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */