[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