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