[commit] r1770 - in trunk/GME: Console Gme

GMESRC Repository Notifications gme-commit at list.isis.vanderbilt.edu
Wed Jan 4 14:36:02 CST 2012


Author: ksmyth
Date: Wed Jan  4 14:36:01 2012
New Revision: 1770

Log:
Fix race condition with out-of-proc GMEOleApp use on x64: CoCreateInstance(ScriptHost, LOCAL_SERVER) pumps messages, which due to COleObjectFactory::RegisterAll being called too early could include RPC calls, which will crash since the console is not initialized yet

Modified:
   trunk/GME/Console/ConsoleCtl.cpp
   trunk/GME/Console/ScriptEdit.cpp
   trunk/GME/Console/ScriptHost.cpp
   trunk/GME/Gme/GMEApp.cpp

Modified: trunk/GME/Console/ConsoleCtl.cpp
==============================================================================
--- trunk/GME/Console/ConsoleCtl.cpp	Wed Jan  4 14:35:43 2012	(r1769)
+++ trunk/GME/Console/ConsoleCtl.cpp	Wed Jan  4 14:36:01 2012	(r1770)
@@ -438,10 +438,33 @@
 		// FIXME: warn user that GME requires IE (e.g. Windows Server Core 2008R2)
 		return -1;
 	m_browser.LoadFromResource(_T("BLANK.HTML"));
+	
+	// KMS: need to pump messages here, since m_browser loads in a different thread and 
+	// posts messages to initialize. If RPC wins the race, it can call SetContents et al and
+	// get_body will return NULL
+	// (out-of-proc CoCreateInstance("GMEOleApp") will block until after this method returns)
+	CComPtr<IHTMLDocument2> pHtmlDoc;
+	CComPtr<IDispatch> pDispatch = m_browser.GetHtmlDocument();
+	COMTHROW(pDispatch.QueryInterface(&pHtmlDoc));
+	ASSERT(pHtmlDoc != NULL);
+	MSG msg;
+	while (GetMessage(&msg, NULL, 0, 0)) 
+	{
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+		CComPtr<IHTMLElement> pElement;
+		COMTHROW(pHtmlDoc->get_body( &pElement ));
+		if (pElement != NULL)
+			break;
+	}
 
 	m_edit.Create((ES_AUTOHSCROLL | WS_VISIBLE | WS_CHILD), rect, this, IDD_EDIT);
 	m_edit.LimitText(300);
 	bool ret = m_edit.Init(this);
+	if (!ret) {
+		ASSERT(false);
+		return -1;
+	}
 
 	m_hIco1 = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_LOADSCR),	IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);
 	m_hIco2 = (HICON)::LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_EXECSCR),	IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR);

Modified: trunk/GME/Console/ScriptEdit.cpp
==============================================================================
--- trunk/GME/Console/ScriptEdit.cpp	Wed Jan  4 14:35:43 2012	(r1769)
+++ trunk/GME/Console/ScriptEdit.cpp	Wed Jan  4 14:36:01 2012	(r1770)
@@ -237,10 +237,11 @@
 		CComPtr<IMgaRegistrar> registrar;
 		COMTHROW(registrar.CoCreateInstance(L"Mga.MgaRegistrar"));
 		ASSERT( registrar != NULL );
-		BSTR eng = NULL;
-		COMTHROW( registrar->get_ScriptEngine(REGACCESS_USER, &eng) );
+		_bstr_t eng;
+		COMTHROW(registrar->get_ScriptEngine(REGACCESS_USER, eng.GetAddress()));
 		_bstr_t engine(L"JScript");
-		if (eng != NULL  &&  ((_bstr_t)eng).length() != 0)
+		int len = eng.length();
+		if (eng.length() != 0)
 			engine = eng;
 
 		_bstr_t input = p_str;
@@ -252,6 +253,12 @@
 		_stprintf_s(s, _T("Scripting Error: 0x%x"), e.hr);
 		m_console->Message(s, MSG_ERROR);
 	}
+	catch(_com_error& e) {
+		TCHAR s[1000];
+		COMTHROW(e.Error());
+		_stprintf_s(s, _T("Execute Script Error: 0x%x"), e.Error());
+		m_console->Message(s, MSG_ERROR);
+	}
 	catch(...) {
 		m_console->Message( _T("Exception handled."), MSG_ERROR);
 	}

Modified: trunk/GME/Console/ScriptHost.cpp
==============================================================================
--- trunk/GME/Console/ScriptHost.cpp	Wed Jan  4 14:35:43 2012	(r1769)
+++ trunk/GME/Console/ScriptHost.cpp	Wed Jan  4 14:36:01 2012	(r1770)
@@ -171,6 +171,10 @@
 	{ 
 		return e.hr;
 	}
+	catch(_com_error &e) 
+	{ 
+		return e.Error();
+	}
 
 	return S_OK;
 }
@@ -225,6 +229,10 @@
 	{ 
 		return e.hr;
 	}
+	catch(_com_error &e) 
+	{ 
+		return e.Error();
+	}
 	return S_OK;
 }
 

Modified: trunk/GME/Gme/GMEApp.cpp
==============================================================================
--- trunk/GME/Gme/GMEApp.cpp	Wed Jan  4 14:35:43 2012	(r1769)
+++ trunk/GME/Gme/GMEApp.cpp	Wed Jan  4 14:36:01 2012	(r1770)
@@ -358,15 +358,6 @@
 	pDocTemplate->SetContainerInfo(IDR_GMETYPE_CNTR_IP);
 	AddDocTemplate(pDocTemplate);
 
-	// Register all OLE server factories as running.  This enables the
-	//  OLE libraries to create objects from other applications.
-	COleObjectFactory::RegisterAll();
-		// Note: MDI applications register all server objects without regard
-		//  to the /Embedding or /Automation on the command line.
-	// Note: we switched the default REGCLS_MULTIPLEUSE behavior to REGCLS_SINGLEUSE,
-	// see GMEOLEApp.cpp's MY_IMPLEMENT_OLECREATE macro, and
-	// "How to use single or multiple instances of an OLE object in MFC by using Visual C++" KB article:
-	// http://support.microsoft.com/kb/141154
 
 
 	// create main MDI Frame window
@@ -404,6 +395,16 @@
 	CGMEOLEApp *t_pGmeOleApp = new CGMEOLEApp();
 	((CMainFrame*)m_pMainWnd)->setGmeOleApp( t_pGmeOleApp );
 
+	// Register all OLE server factories as running.  This enables the
+	//  OLE libraries to create objects from other applications.
+	COleObjectFactory::RegisterAll();
+		// Note: MDI applications register all server objects without regard
+		//  to the /Embedding or /Automation on the command line.
+	// Note: we switched the default REGCLS_MULTIPLEUSE behavior to REGCLS_SINGLEUSE,
+	// see GMEOLEApp.cpp's MY_IMPLEMENT_OLECREATE macro, and
+	// "How to use single or multiple instances of an OLE object in MFC by using Visual C++" KB article:
+	// http://support.microsoft.com/kb/141154
+
 	// Check to see if launched as OLE server
 	if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
 	{


More information about the gme-commit mailing list