aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llappviewerwin32.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llappviewerwin32.cpp')
-rw-r--r--linden/indra/newview/llappviewerwin32.cpp131
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
80const std::string LLAppViewerWin32::sWindowClass = "Second Life";
81
80LONG WINAPI viewer_windows_exception_handler(struct _EXCEPTION_POINTERS *exception_infop) 82LONG 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.
135bool 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
367bool 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
327void LLAppViewerWin32::initConsole() 378void 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
499bool LLAppViewerWin32::restoreErrorTrap()
500{
501 return LLWinDebug::checkExceptionHandler();
502}
503
448void LLAppViewerWin32::handleSyncCrashTrace() 504void LLAppViewerWin32::handleSyncCrashTrace()
449{ 505{
450 // do nothing 506 // do nothing
451} 507}
452 508
453void LLAppViewerWin32::handleCrashReporting() 509void 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
536bool 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
481std::string LLAppViewerWin32::generateSerialNumber() 562std::string LLAppViewerWin32::generateSerialNumber()
482{ 563{
483 char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore 564 char serial_md5[MD5HEX_STR_SIZE]; // Flawfinder: ignore