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