diff options
Diffstat (limited to 'linden/indra/newview/llappviewerwin32.cpp')
-rw-r--r-- | linden/indra/newview/llappviewerwin32.cpp | 131 |
1 files changed, 106 insertions, 25 deletions
diff --git a/linden/indra/newview/llappviewerwin32.cpp b/linden/indra/newview/llappviewerwin32.cpp index 9f37534..b68cad6 100644 --- a/linden/indra/newview/llappviewerwin32.cpp +++ b/linden/indra/newview/llappviewerwin32.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | 7 | * Copyright (c) 2007-2009, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -64,7 +64,7 @@ | |||
64 | 64 | ||
65 | #include "llcommandlineparser.h" | 65 | #include "llcommandlineparser.h" |
66 | 66 | ||
67 | //*FIX:Mani - This hack is to fix a linker issue with libndofdev.lib | 67 | // *FIX:Mani - This hack is to fix a linker issue with libndofdev.lib |
68 | // The lib was compiled under VS2005 - in VS2003 we need to remap assert | 68 | // The lib was compiled under VS2005 - in VS2003 we need to remap assert |
69 | #ifdef LL_DEBUG | 69 | #ifdef LL_DEBUG |
70 | #ifdef LL_MSVC7 | 70 | #ifdef LL_MSVC7 |
@@ -77,12 +77,15 @@ extern "C" { | |||
77 | #endif | 77 | #endif |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | const std::string LLAppViewerWin32::sWindowClass = "Second Life"; | ||
81 | |||
80 | LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) | 82 | LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) |
81 | { | 83 | { |
82 | // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. | 84 | // *NOTE:Mani - this code is stolen from LLApp, where its never actually used. |
83 | 85 | //OSMessageBox("Attach Debugger Now", "Error", OSMB_OK); | |
84 | // Translate the signals/exceptions into cross-platform stuff | 86 | // Translate the signals/exceptions into cross-platform stuff |
85 | // Windows implementation | 87 | // Windows implementation |
88 | _tprintf( _T("Entering Windows Exception Handler...\n") ); | ||
86 | llinfos << "Entering Windows Exception Handler..." << llendl; | 89 | llinfos << "Entering Windows Exception Handler..." << llendl; |
87 | 90 | ||
88 | // Make sure the user sees something to indicate that the app crashed. | 91 | // Make sure the user sees something to indicate that the app crashed. |
@@ -90,7 +93,9 @@ LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *excepti | |||
90 | 93 | ||
91 | if (LLApp::isError()) | 94 | if (LLApp::isError()) |
92 | { | 95 | { |
96 | _tprintf( _T("Got another fatal signal while in the error handler, die now!\n") ); | ||
93 | llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; | 97 | llwarns << "Got another fatal signal while in the error handler, die now!" << llendl; |
98 | |||
94 | retval = EXCEPTION_EXECUTE_HANDLER; | 99 | retval = EXCEPTION_EXECUTE_HANDLER; |
95 | return retval; | 100 | return retval; |
96 | } | 101 | } |
@@ -119,7 +124,28 @@ LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *excepti | |||
119 | return retval; | 124 | return retval; |
120 | } | 125 | } |
121 | 126 | ||
127 | // Create app mutex creates a unique global windows object. | ||
128 | // If the object can be created it returns true, otherwise | ||
129 | // it returns false. The false result can be used to determine | ||
130 | // if another instance of a second life app (this vers. or later) | ||
131 | // is running. | ||
132 | // *NOTE: Do not use this method to run a single instance of the app. | ||
133 | // This is intended to help debug problems with the cross-platform | ||
134 | // locked file method used for that purpose. | ||
135 | bool create_app_mutex() | ||
136 | { | ||
137 | bool result = true; | ||
138 | LPCWSTR unique_mutex_name = L"SecondLifeAppMutex"; | ||
139 | HANDLE hMutex; | ||
140 | hMutex = CreateMutex(NULL, TRUE, unique_mutex_name); | ||
141 | if(GetLastError() == ERROR_ALREADY_EXISTS) | ||
142 | { | ||
143 | result = false; | ||
144 | } | ||
145 | return result; | ||
146 | } | ||
122 | 147 | ||
148 | //#define DEBUGGING_SEH_FILTER 1 | ||
123 | #if DEBUGGING_SEH_FILTER | 149 | #if DEBUGGING_SEH_FILTER |
124 | # define WINMAIN DebuggingWinMain | 150 | # define WINMAIN DebuggingWinMain |
125 | #else | 151 | #else |
@@ -146,6 +172,10 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, | |||
146 | 172 | ||
147 | viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); | 173 | viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash); |
148 | 174 | ||
175 | // Set a debug info flag to indicate if multiple instances are running. | ||
176 | bool found_other_instance = !create_app_mutex(); | ||
177 | gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance); | ||
178 | |||
149 | bool ok = viewer_app_ptr->init(); | 179 | bool ok = viewer_app_ptr->init(); |
150 | if(!ok) | 180 | if(!ok) |
151 | { | 181 | { |
@@ -195,6 +225,16 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, | |||
195 | } | 225 | } |
196 | delete viewer_app_ptr; | 226 | delete viewer_app_ptr; |
197 | viewer_app_ptr = NULL; | 227 | viewer_app_ptr = NULL; |
228 | |||
229 | //start updater | ||
230 | if(LLAppViewer::sUpdaterInfo) | ||
231 | { | ||
232 | _spawnl(_P_NOWAIT, LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mUpdateExePath.c_str(), LLAppViewer::sUpdaterInfo->mParams.str().c_str(), NULL); | ||
233 | |||
234 | delete LLAppViewer::sUpdaterInfo ; | ||
235 | LLAppViewer::sUpdaterInfo = NULL ; | ||
236 | } | ||
237 | |||
198 | return 0; | 238 | return 0; |
199 | } | 239 | } |
200 | 240 | ||
@@ -324,6 +364,17 @@ bool LLAppViewerWin32::cleanup() | |||
324 | return result; | 364 | return result; |
325 | } | 365 | } |
326 | 366 | ||
367 | bool LLAppViewerWin32::initLogging() | ||
368 | { | ||
369 | // Remove the crash stack log from previous executions. | ||
370 | // Since we've started logging a new instance of the app, we can assume | ||
371 | // *NOTE: This should happen before the we send a 'previous instance froze' | ||
372 | // crash report, but it must happen after we initialize the DirUtil. | ||
373 | LLWinDebug::clearCrashStacks(); | ||
374 | |||
375 | return LLAppViewer::initLogging(); | ||
376 | } | ||
377 | |||
327 | void LLAppViewerWin32::initConsole() | 378 | void LLAppViewerWin32::initConsole() |
328 | { | 379 | { |
329 | // pop up debug console | 380 | // pop up debug console |
@@ -405,7 +456,7 @@ bool LLAppViewerWin32::initHardwareTest() | |||
405 | LLSplashScreen::update(splash_msg.str()); | 456 | LLSplashScreen::update(splash_msg.str()); |
406 | } | 457 | } |
407 | 458 | ||
408 | if (!LLWinDebug::checkExceptionHandler()) | 459 | if (!restoreErrorTrap()) |
409 | { | 460 | { |
410 | LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL; | 461 | LL_WARNS("AppInit") << " Someone took over my exception handler (post hardware probe)!" << LL_ENDL; |
411 | } | 462 | } |
@@ -445,39 +496,69 @@ bool LLAppViewerWin32::initParseCommandLine(LLCommandLineParser& clp) | |||
445 | return true; | 496 | return true; |
446 | } | 497 | } |
447 | 498 | ||
499 | bool LLAppViewerWin32::restoreErrorTrap() | ||
500 | { | ||
501 | return LLWinDebug::checkExceptionHandler(); | ||
502 | } | ||
503 | |||
448 | void LLAppViewerWin32::handleSyncCrashTrace() | 504 | void LLAppViewerWin32::handleSyncCrashTrace() |
449 | { | 505 | { |
450 | // do nothing | 506 | // do nothing |
451 | } | 507 | } |
452 | 508 | ||
453 | void LLAppViewerWin32::handleCrashReporting() | 509 | void LLAppViewerWin32::handleCrashReporting(bool reportFreeze) |
454 | { | 510 | { |
455 | // Windows only behaivor. Spawn win crash reporter. | 511 | const char* logger_name = "win_crash_logger.exe"; |
456 | std::string exe_path = gDirUtilp->getAppRODataDir(); | 512 | std::string exe_path = gDirUtilp->getExecutableDir(); |
457 | exe_path += gDirUtilp->getDirDelimiter(); | 513 | exe_path += gDirUtilp->getDirDelimiter(); |
458 | exe_path += "win_crash_logger.exe"; | 514 | exe_path += logger_name; |
459 | 515 | ||
460 | std::string arg_string = "-user "; | 516 | const char* arg_str = logger_name; |
461 | arg_string += LLViewerLogin::getInstance()->getGridLabel(); | 517 | |
462 | 518 | // *NOTE:Mani - win_crash_logger.exe no longer parses command line options. | |
463 | S32 cb = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); | 519 | if(reportFreeze) |
464 | switch(cb) | ||
465 | { | 520 | { |
466 | case CRASH_BEHAVIOR_ASK: | 521 | // Spawn crash logger. |
467 | default: | 522 | // NEEDS to wait until completion, otherwise log files will get smashed. |
468 | arg_string += " -dialog "; | 523 | _spawnl(_P_WAIT, exe_path.c_str(), arg_str, NULL); |
469 | _spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); | ||
470 | break; | ||
471 | |||
472 | case CRASH_BEHAVIOR_ALWAYS_SEND: | ||
473 | _spawnl(_P_NOWAIT, exe_path.c_str(), exe_path.c_str(), arg_string.c_str(), NULL); | ||
474 | break; | ||
475 | |||
476 | case CRASH_BEHAVIOR_NEVER_SEND: | ||
477 | break; | ||
478 | } | 524 | } |
525 | else | ||
526 | { | ||
527 | S32 cb = gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING); | ||
528 | if(cb != CRASH_BEHAVIOR_NEVER_SEND) | ||
529 | { | ||
530 | _spawnl(_P_NOWAIT, exe_path.c_str(), arg_str, NULL); | ||
531 | } | ||
532 | } | ||
533 | } | ||
534 | |||
535 | //virtual | ||
536 | bool LLAppViewerWin32::sendURLToOtherInstance(const std::string& url) | ||
537 | { | ||
538 | wchar_t window_class[256]; /* Flawfinder: ignore */ // Assume max length < 255 chars. | ||
539 | mbstowcs(window_class, sWindowClass.c_str(), 255); | ||
540 | window_class[255] = 0; | ||
541 | // Use the class instead of the window name. | ||
542 | HWND other_window = FindWindow(window_class, NULL); | ||
543 | |||
544 | if (other_window != NULL) | ||
545 | { | ||
546 | lldebugs << "Found other window with the name '" << getWindowTitle() << "'" << llendl; | ||
547 | COPYDATASTRUCT cds; | ||
548 | const S32 SLURL_MESSAGE_TYPE = 0; | ||
549 | cds.dwData = SLURL_MESSAGE_TYPE; | ||
550 | cds.cbData = url.length() + 1; | ||
551 | cds.lpData = (void*)url.c_str(); | ||
552 | |||
553 | LRESULT msg_result = SendMessage(other_window, WM_COPYDATA, NULL, (LPARAM)&cds); | ||
554 | lldebugs << "SendMessage(WM_COPYDATA) to other window '" | ||
555 | << getWindowTitle() << "' returned " << msg_result << llendl; | ||
556 | return true; | ||
557 | } | ||
558 | return false; | ||
479 | } | 559 | } |
480 | 560 | ||
561 | |||
481 | std::string LLAppViewerWin32::generateSerialNumber() | 562 | std::string LLAppViewerWin32::generateSerialNumber() |
482 | { | 563 | { |
483 | char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore | 564 | char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore |