1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #ifdef _MSC_VER 29*cdf0e10cSrcweir #pragma warning(push,1) /* disable warnings within system headers */ 30*cdf0e10cSrcweir #endif 31*cdf0e10cSrcweir #include <windows.h> 32*cdf0e10cSrcweir #ifdef _MSC_VER 33*cdf0e10cSrcweir #pragma warning(pop) 34*cdf0e10cSrcweir #endif 35*cdf0e10cSrcweir #include <tlhelp32.h> 36*cdf0e10cSrcweir #include <systools/win32/uwinapi.h> 37*cdf0e10cSrcweir #include <winsock.h> 38*cdf0e10cSrcweir #include <osl/diagnose.h> 39*cdf0e10cSrcweir #include <sal/types.h> 40*cdf0e10cSrcweir #include <float.h> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <osl/diagnose.h> 43*cdf0e10cSrcweir #include <osl/mutex.h> 44*cdf0e10cSrcweir #include <sal/types.h> 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir //------------------------------------------------------------------------------ 47*cdf0e10cSrcweir // externals 48*cdf0e10cSrcweir //------------------------------------------------------------------------------ 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir extern DWORD g_dwTLSTextEncodingIndex; 51*cdf0e10cSrcweir extern void SAL_CALL _osl_callThreadKeyCallbackOnThreadDetach(void); 52*cdf0e10cSrcweir extern CRITICAL_SECTION g_ThreadKeyListCS; 53*cdf0e10cSrcweir extern oslMutex g_Mutex; 54*cdf0e10cSrcweir extern oslMutex g_CurrentDirectoryMutex; 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir extern void rtl_locale_fini (void); 57*cdf0e10cSrcweir extern void rtl_memory_fini (void); 58*cdf0e10cSrcweir extern void rtl_cache_fini (void); 59*cdf0e10cSrcweir extern void rtl_arena_fini (void); 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir #ifdef __MINGW32__ 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir typedef void (*func_ptr) (void); 64*cdf0e10cSrcweir extern func_ptr __CTOR_LIST__[]; 65*cdf0e10cSrcweir extern func_ptr __DTOR_LIST__[]; 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir static void do_startup(void); 68*cdf0e10cSrcweir static void do_cleanup(void); 69*cdf0e10cSrcweir 70*cdf0e10cSrcweir #else 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir /* 73*cdf0e10cSrcweir This is needed because DllMain is called after static constructors. A DLL's 74*cdf0e10cSrcweir startup and shutdown sequence looks like this: 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir _pRawDllMain() 77*cdf0e10cSrcweir _CRT_INIT() 78*cdf0e10cSrcweir DllMain() 79*cdf0e10cSrcweir .... 80*cdf0e10cSrcweir DllMain() 81*cdf0e10cSrcweir _CRT_INIT() 82*cdf0e10cSrcweir _pRawDllMain() 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir */ 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir static BOOL WINAPI _RawDllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ); 87*cdf0e10cSrcweir extern BOOL (WINAPI *_pRawDllMain)(HANDLE, DWORD, LPVOID) = _RawDllMain; 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir #endif 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir //------------------------------------------------------------------------------ 92*cdf0e10cSrcweir // globales 93*cdf0e10cSrcweir //------------------------------------------------------------------------------ 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir DWORD g_dwPlatformId = VER_PLATFORM_WIN32_WINDOWS; // remember plattform 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir //------------------------------------------------------------------------------ 98*cdf0e10cSrcweir // DllMain 99*cdf0e10cSrcweir //------------------------------------------------------------------------------ 100*cdf0e10cSrcweir #ifdef _M_IX86 101*cdf0e10cSrcweir int osl_isSingleCPU = 0; 102*cdf0e10cSrcweir #endif 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir #ifdef __MINGW32__ 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir void 107*cdf0e10cSrcweir __do_global_dtors (void) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir static func_ptr *p = __DTOR_LIST__ + 1; 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir /* 112*cdf0e10cSrcweir * Call each destructor in the destructor list until a null pointer 113*cdf0e10cSrcweir * is encountered. 114*cdf0e10cSrcweir */ 115*cdf0e10cSrcweir while (*p) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir (*(p)) (); 118*cdf0e10cSrcweir p++; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir } 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir void 123*cdf0e10cSrcweir __do_global_ctors (void) 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; 126*cdf0e10cSrcweir unsigned i; 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir /* 129*cdf0e10cSrcweir * If the first entry in the constructor list is -1 then the list 130*cdf0e10cSrcweir * is terminated with a null entry. Otherwise the first entry was 131*cdf0e10cSrcweir * the number of pointers in the list. 132*cdf0e10cSrcweir */ 133*cdf0e10cSrcweir if (nptrs == -1) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++) 136*cdf0e10cSrcweir ; 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir /* 140*cdf0e10cSrcweir * Go through the list backwards calling constructors. 141*cdf0e10cSrcweir */ 142*cdf0e10cSrcweir for (i = nptrs; i >= 1; i--) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir __CTOR_LIST__[i] (); 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir /* 148*cdf0e10cSrcweir * Register the destructors for processing on exit. 149*cdf0e10cSrcweir */ 150*cdf0e10cSrcweir atexit (__do_global_dtors); 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir static int initialized = 0; 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir void 156*cdf0e10cSrcweir __main (void) 157*cdf0e10cSrcweir { 158*cdf0e10cSrcweir if (!initialized) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir initialized = 1; 161*cdf0e10cSrcweir do_startup(); 162*cdf0e10cSrcweir __do_global_ctors (); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir static void do_startup( void ) 167*cdf0e10cSrcweir { 168*cdf0e10cSrcweir #else 169*cdf0e10cSrcweir static BOOL WINAPI _RawDllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir (void)hinstDLL; /* avoid warnings */ 172*cdf0e10cSrcweir (void)lpvReserved; /* avoid warnings */ 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir switch (fdwReason) 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir case DLL_PROCESS_ATTACH: 177*cdf0e10cSrcweir { 178*cdf0e10cSrcweir #endif 179*cdf0e10cSrcweir OSVERSIONINFO aInfo; 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir #ifdef _M_IX86 182*cdf0e10cSrcweir SYSTEM_INFO SystemInfo; 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir GetSystemInfo(&SystemInfo); 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir /* Determine if we are on a multiprocessor/multicore/HT x86/x64 system 187*cdf0e10cSrcweir * 188*cdf0e10cSrcweir * The lock prefix for atomic operations in osl_[inc|de]crementInterlockedCount() 189*cdf0e10cSrcweir * comes with a cost and is especially expensive on pre HT x86 single processor 190*cdf0e10cSrcweir * systems, where it isn't needed at all. 191*cdf0e10cSrcweir */ 192*cdf0e10cSrcweir if ( SystemInfo.dwNumberOfProcessors == 1 ) { 193*cdf0e10cSrcweir osl_isSingleCPU = 1; 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir #endif 196*cdf0e10cSrcweir /* Suppress file error messages from system like "Floppy A: not inserted" */ 197*cdf0e10cSrcweir SetErrorMode( SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS ); 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir /* initialize global mutex */ 200*cdf0e10cSrcweir g_Mutex = osl_createMutex(); 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir /* initialize "current directory" mutex */ 203*cdf0e10cSrcweir g_CurrentDirectoryMutex = osl_createMutex(); 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir /* initialize Win9x unicode functions */ 207*cdf0e10cSrcweir aInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO ); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir if ( GetVersionEx(&aInfo) ) 210*cdf0e10cSrcweir g_dwPlatformId = aInfo.dwPlatformId; 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir g_dwTLSTextEncodingIndex = TlsAlloc(); 213*cdf0e10cSrcweir InitializeCriticalSection( &g_ThreadKeyListCS ); 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir //We disable floating point exceptions. This is the usual state at program startup 216*cdf0e10cSrcweir //but on Windows 98 and ME this is not always the case. 217*cdf0e10cSrcweir _control87(_MCW_EM, _MCW_EM); 218*cdf0e10cSrcweir #ifdef __MINGW32__ 219*cdf0e10cSrcweir atexit(do_cleanup); 220*cdf0e10cSrcweir } 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir void do_cleanup( void ) 223*cdf0e10cSrcweir { 224*cdf0e10cSrcweir #else 225*cdf0e10cSrcweir break; 226*cdf0e10cSrcweir } 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir case DLL_PROCESS_DETACH: 229*cdf0e10cSrcweir #endif 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir WSACleanup( ); 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir TlsFree( g_dwTLSTextEncodingIndex ); 234*cdf0e10cSrcweir DeleteCriticalSection( &g_ThreadKeyListCS ); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir osl_destroyMutex( g_Mutex ); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir osl_destroyMutex( g_CurrentDirectoryMutex ); 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir #ifndef __MINGW32__ 241*cdf0e10cSrcweir 242*cdf0e10cSrcweir /* 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir On a product build memory management finalization might 245*cdf0e10cSrcweir cause a crash without assertion (assertions off) if heap is 246*cdf0e10cSrcweir corrupted. But a crash report won't help here because at 247*cdf0e10cSrcweir this point all other threads have been terminated and only 248*cdf0e10cSrcweir ntdll is on the stack. No chance to find the reason for the 249*cdf0e10cSrcweir corrupted heap if so. 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir So annoying the user with a crash report is completly useless. 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir */ 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir #ifndef DBG_UTIL 256*cdf0e10cSrcweir __try 257*cdf0e10cSrcweir #endif 258*cdf0e10cSrcweir { 259*cdf0e10cSrcweir /* cleanup locale hashtable */ 260*cdf0e10cSrcweir rtl_locale_fini(); 261*cdf0e10cSrcweir 262*cdf0e10cSrcweir /* finalize memory management */ 263*cdf0e10cSrcweir rtl_memory_fini(); 264*cdf0e10cSrcweir rtl_cache_fini(); 265*cdf0e10cSrcweir rtl_arena_fini(); 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir #ifndef DBG_UTIL 268*cdf0e10cSrcweir __except( EXCEPTION_EXECUTE_HANDLER ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir #endif 272*cdf0e10cSrcweir break; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir return TRUE; 276*cdf0e10cSrcweir #endif 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir static DWORD GetParentProcessId() 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir DWORD dwParentProcessId = 0; 282*cdf0e10cSrcweir HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir if ( IsValidHandle( hSnapshot ) ) 285*cdf0e10cSrcweir { 286*cdf0e10cSrcweir PROCESSENTRY32 pe; 287*cdf0e10cSrcweir BOOL fSuccess; 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir ZeroMemory( &pe, sizeof(pe) ); 290*cdf0e10cSrcweir pe.dwSize = sizeof(pe); 291*cdf0e10cSrcweir fSuccess = Process32First( hSnapshot, &pe ); 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir while( fSuccess ) 294*cdf0e10cSrcweir { 295*cdf0e10cSrcweir if ( GetCurrentProcessId() == pe.th32ProcessID ) 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir dwParentProcessId = pe.th32ParentProcessID; 298*cdf0e10cSrcweir break; 299*cdf0e10cSrcweir } 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir fSuccess = Process32Next( hSnapshot, &pe ); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir CloseHandle( hSnapshot ); 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir return dwParentProcessId; 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir static DWORD WINAPI ParentMonitorThreadProc( LPVOID lpParam ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir DWORD dwParentProcessId = (DWORD)lpParam; 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir HANDLE hParentProcess = OpenProcess( SYNCHRONIZE, FALSE, dwParentProcessId ); 315*cdf0e10cSrcweir if ( IsValidHandle( hParentProcess ) ) 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir if ( WAIT_OBJECT_0 == WaitForSingleObject( hParentProcess, INFINITE ) ) 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir TerminateProcess( GetCurrentProcess(), 0 ); 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir CloseHandle( hParentProcess ); 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir return 0; 324*cdf0e10cSrcweir } 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) 327*cdf0e10cSrcweir { 328*cdf0e10cSrcweir (void)hinstDLL; /* avoid warning */ 329*cdf0e10cSrcweir (void)lpvReserved; /* avoid warning */ 330*cdf0e10cSrcweir switch (fdwReason) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir case DLL_PROCESS_ATTACH: 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir TCHAR szBuffer[64]; 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir // This code will attach the process to it's parent process 337*cdf0e10cSrcweir // if the parent process had set the environment variable. 338*cdf0e10cSrcweir // The corresponding code (setting the environment variable) 339*cdf0e10cSrcweir // is is desktop/win32/source/officeloader.cxx 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir DWORD dwResult = GetEnvironmentVariable( "ATTACHED_PARENT_PROCESSID", szBuffer, sizeof(szBuffer) ); 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir if ( dwResult && dwResult < sizeof(szBuffer) ) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir DWORD dwThreadId = 0; 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir DWORD dwParentProcessId = (DWORD)atol( szBuffer ); 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir if ( dwParentProcessId && GetParentProcessId() == dwParentProcessId ) 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir // No error check, it works or it does not 353*cdf0e10cSrcweir // Thread should only be started for headless mode, see desktop/win32/source/officeloader.cxx 354*cdf0e10cSrcweir CreateThread( NULL, 0, ParentMonitorThreadProc, (LPVOID)dwParentProcessId, 0, &dwThreadId ); // 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir return TRUE; 359*cdf0e10cSrcweir } 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir case DLL_THREAD_ATTACH: 362*cdf0e10cSrcweir break; 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir case DLL_THREAD_DETACH: 365*cdf0e10cSrcweir _osl_callThreadKeyCallbackOnThreadDetach( ); 366*cdf0e10cSrcweir break; 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir 369*cdf0e10cSrcweir return TRUE; 370*cdf0e10cSrcweir } 371