fix script node advise/unadvise
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
index 66f1a7d..57c85c5 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireInstaller/Release/IECrossfireInstaller.msi
Binary files differ
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
index 0ce5aee..1b10614 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.cpp
@@ -1368,29 +1368,6 @@
return false;
}
- CComPtr<IDebugApplicationNode> rootNode = NULL;
- hr = debugApplication->GetRootNode(&rootNode);
- if (FAILED(hr)) {
- Logger::error("CrossfireContext.getDebugApplicationThread(): GetRootNode() failed", hr);
- } else {
- CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
- hr = rootNode->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
- if (FAILED(hr)) {
- Logger::error("CrossfireContext.getDebugApplicationThread(): QI(IConnectionPointContainer) failed", hr);
- } else {
- CComPtr<IConnectionPoint> connectionPoint = NULL;
- hr = connectionPointContainer->FindConnectionPoint(IID_IDebugApplicationNodeEvents, &connectionPoint);
- if (FAILED(hr)) {
- Logger::error("CrossfireContext.getDebugApplicationThread(): FindConnectionPoint() failed", hr);
- } else {
- hr = connectionPoint->Advise(m_debugger, &m_cpcApplicationNodeEvents);
- if (FAILED(hr)) {
- Logger::error("CrossfireContext.getDebugApplicationThread(): Advise() failed", hr);
- }
- }
- }
- }
-
CComPtr<IEnumRemoteDebugApplicationThreads> debugApplicationThreads;
hr = debugApplication->EnumThreads(&debugApplicationThreads);
if (FAILED(hr)) {
@@ -1583,11 +1560,12 @@
Logger::error("CrossfireContext.registerScript(): GetName() failed", hr);
return false;
}
- int length = wcslen(SCHEME_JSCRIPT) + wcslen(value.m_str) + 1;
+ int length = wcslen(SCHEME_JSCRIPT) + wcslen(value.m_str) + 2;
wchar_t* string = new wchar_t[length];
ZeroMemory(string, length * sizeof(wchar_t));
wcscat_s(string, length, SCHEME_JSCRIPT);
wcscat_s(string, length, value.m_str);
+ wcscat_s(string, length, L"/");
url.setString(string);
delete[] string;
}
@@ -1609,7 +1587,6 @@
break;
}
key.assign(url.getString());
- key += wchar_t('/');
wchar_t qualifierString[4];
_ltow_s(qualifierIndex++, qualifierString, 4, 10); /* trailing linebreak */
key += qualifierString;
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
index 989ff75..2dda24d 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/CrossfireContext.h
@@ -38,6 +38,7 @@
CrossfireContext(DWORD processId, wchar_t* url, CrossfireServer* server);
~CrossfireContext();
virtual void breakpointHit(IRemoteDebugApplicationThread *pDebugAppThread, BREAKREASON br, IActiveScriptErrorDebug *pScriptErrorDebug);
+ virtual bool getDebugApplication(IRemoteDebugApplication** _value);
virtual IDebugApplicationNode* getLastInitializedScriptNode();
virtual wchar_t* getName();
virtual DWORD getProcessId();
@@ -71,7 +72,6 @@
virtual bool createValueForScript(IDebugApplicationNode* node, bool includeSource, bool failIfEmpty, Value** _value);
virtual bool evaluate(IDebugStackFrame* stackFrame, wchar_t* expression, int flags, IDebugProperty** _result);
virtual bool evaluateAsync(IDebugStackFrame* stackFrame, wchar_t* expression, int flags, IJSEvalHandler* handler, void* data);
- virtual bool getDebugApplication(IRemoteDebugApplication** _value);
virtual bool getDebugApplicationThread(IRemoteDebugApplicationThread** _value);
virtual bool getScriptUrl(IDebugApplicationNode* node, URL** _value);
virtual IDebugApplicationNode* getScriptNode(URL* url);
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
index d112517..dfe3901 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.cpp
@@ -13,9 +13,13 @@
#include "stdafx.h"
#include "IEDebugger.h"
+/* initialize constants */
+const wchar_t* IEDebugger::ABOUT_BLANK = L"about:blank";
+
IEDebugger::IEDebugger() {
+ m_adviseCookies = new std::map<IDebugApplicationNode*, DWORD>;
m_context = NULL;
- m_adviseCookies = new std::multimap<std::wstring, DWORD>;
+ m_rootNode = NULL;
}
IEDebugger::~IEDebugger() {
@@ -77,69 +81,23 @@
return S_OK;
}
- m_context->scriptInitialized(prddpChild);
-
- CComPtr <IConnectionPointContainer> connectionPointContainer = NULL;
- HRESULT hr = prddpChild->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
- if (FAILED(hr)) {
- Logger::error("IEDebugger.onAddChild(): QI(IID_IConnectionPointContainer) failed", hr);
- return S_FALSE;
- }
- CComPtr <IConnectionPoint> nodeConnectionPoint = NULL;
- hr = connectionPointContainer->FindConnectionPoint(IID_IDebugApplicationNodeEvents, &nodeConnectionPoint);
- if (FAILED(hr)) {
- Logger::error("IEDebugger.onAddChild(): FindConnectionPoint() failed", hr);
- return S_FALSE;
- }
-
- DWORD connectionPointCookie = 0;
- hr = nodeConnectionPoint->Advise(static_cast<IIEDebugger*>(this), &connectionPointCookie);
- if (FAILED(hr)) {
- Logger::error("IEDebugger.onAddChild(): Advise() failed", hr);
- return S_FALSE;
- }
-
+ /* don't register about:blank as a script */
CComBSTR bstrUrl = NULL;
- hr = prddpChild->GetName(DOCUMENTNAMETYPE_TITLE, &bstrUrl);
+ HRESULT hr = prddpChild->GetName(DOCUMENTNAMETYPE_TITLE, &bstrUrl);
if (FAILED(hr)) {
Logger::error("IEDebugger.onAddChild(): GetName() failed", hr);
- return S_FALSE;
+ } else {
+ if (wcscmp(bstrUrl, ABOUT_BLANK) != 0) {
+ m_context->scriptInitialized(prddpChild);
+ }
}
- URL url(bstrUrl);
- m_adviseCookies->insert(std::pair<std::wstring,DWORD>(std::wstring(url.getString()), connectionPointCookie));
+
+ advise(prddpChild, false, false);
return S_OK;
}
STDMETHODIMP IEDebugger::onRemoveChild(IDebugApplicationNode *prddpChild) {
- CComBSTR bstrUrl = NULL;
- if (FAILED(prddpChild->GetName(DOCUMENTNAMETYPE_TITLE, &bstrUrl))) {
- return S_OK;
- }
- URL url(bstrUrl);
-
- CComPtr <IConnectionPointContainer> connectionPointContainer = NULL;
- HRESULT hr = prddpChild->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
- if (FAILED(hr)) {
- Logger::error("IEDebugger.onRemoveChild(): QI(IID_IConnectionPointContainer) failed", hr);
- return S_FALSE;
- }
- CComPtr <IConnectionPoint> nodeConnectionPoint = NULL;
- hr = connectionPointContainer->FindConnectionPoint(IID_IDebugApplicationNodeEvents, &nodeConnectionPoint);
- if (FAILED(hr)) {
- Logger::error("IEDebugger.onRemoveChild(): FindConnectionPoint() failed", hr);
- return S_FALSE;
- }
-
- std::pair<std::multimap<std::wstring,DWORD>::iterator,std::multimap<std::wstring,DWORD>::iterator> range;
- range = m_adviseCookies->equal_range(std::wstring(url.getString()));
- std::multimap<std::wstring,DWORD>::iterator it;
- for (it = range.first; it != range.second; ++it) {
- if (SUCCEEDED(nodeConnectionPoint->Unadvise(it->second))) {
- m_adviseCookies->erase(it);
- break;
- }
- }
-
+ unadvise(prddpChild, false, false);
return S_OK;
}
@@ -160,7 +118,131 @@
/* IEDebugger */
-void IEDebugger::setContext(CrossfireContext* value) {
- m_context = value;
+bool IEDebugger::advise(IDebugApplicationNode* node, bool isRoot, bool recurse) {
+ CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
+ HRESULT hr = node->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.advise(): QI(IID_IConnectionPointContainer) failed", hr);
+ return false;
+ }
+ CComPtr<IConnectionPoint> nodeConnectionPoint = NULL;
+ hr = connectionPointContainer->FindConnectionPoint(IID_IDebugApplicationNodeEvents, &nodeConnectionPoint);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.advise(): FindConnectionPoint() failed", hr);
+ return false;
+ }
+
+ DWORD connectionPointCookie = 0;
+ hr = nodeConnectionPoint->Advise(static_cast<IIEDebugger*>(this), &connectionPointCookie);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.advise(): Advise() failed", hr);
+ return false;
+ }
+
+ if (isRoot) {
+ m_rootCookie = connectionPointCookie;
+ m_rootNode = node;
+ } else {
+ m_adviseCookies->insert(std::pair<IDebugApplicationNode*,DWORD>(node, connectionPointCookie));
+ }
+ node->AddRef();
+
+ if (recurse) {
+ CComPtr<IEnumDebugApplicationNodes> nodes = NULL;
+ hr = node->EnumChildren(&nodes);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.advise(): EnumChildren() failed", hr);
+ } else {
+ IDebugApplicationNode* current = NULL;
+ ULONG count = 0;
+ hr = nodes->Next(1, ¤t, &count);
+ while (SUCCEEDED(hr) && count) {
+ advise(current, false, true);
+ current->Release();
+ hr = nodes->Next(1, ¤t, &count);
+ }
+ }
+ }
+ return true;
}
+void IEDebugger::setContext(CrossfireContext* value) {
+ if (m_context == value) {
+ return;
+ }
+ m_context = value;
+
+ if (m_rootNode) {
+ unadvise(m_rootNode, true, true);
+ }
+
+ if (value) {
+ CComPtr<IRemoteDebugApplication> application = NULL;
+ HRESULT hr = m_context->getDebugApplication(&application);
+ if (SUCCEEDED(hr)) {
+ CComPtr<IDebugApplicationNode> rootNode = NULL;
+ hr = application->GetRootNode(&rootNode);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.setContext(): GetRootNode() failed", hr);
+ return;
+ }
+ advise(rootNode, true, true);
+ }
+ }
+}
+
+bool IEDebugger::unadvise(IDebugApplicationNode* node, bool isRoot, bool recurse) {
+ CComPtr<IConnectionPointContainer> connectionPointContainer = NULL;
+ HRESULT hr = node->QueryInterface(IID_IConnectionPointContainer, (void**)&connectionPointContainer);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.unadvise(): QI(IID_IConnectionPointContainer) failed", hr);
+ return false;
+ }
+ CComPtr<IConnectionPoint> nodeConnectionPoint = NULL;
+ hr = connectionPointContainer->FindConnectionPoint(IID_IDebugApplicationNodeEvents, &nodeConnectionPoint);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.unadvise(): FindConnectionPoint() failed", hr);
+ return false;
+ }
+
+ DWORD cookie = 0;
+ if (isRoot) {
+ cookie = m_rootCookie;
+ m_rootNode->Release();
+ m_rootNode = NULL;
+ } else {
+ std::map<IDebugApplicationNode*, DWORD>::iterator iterator = m_adviseCookies->find(node);
+ if (iterator != m_adviseCookies->end()) {
+ cookie = iterator->second;
+ iterator->first->Release();
+ m_adviseCookies->erase(iterator);
+ }
+ }
+
+ if (cookie) {
+ hr = nodeConnectionPoint->Unadvise(cookie);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.unadvise(): Unadvise() failed", hr);
+ }
+ }
+
+ if (recurse) {
+ CComPtr<IEnumDebugApplicationNodes> nodes = NULL;
+ hr = node->EnumChildren(&nodes);
+ if (FAILED(hr)) {
+ Logger::error("IEDebugger.unadvise(): EnumChildren() failed", hr);
+ } else {
+ IDebugApplicationNode* current = NULL;
+ ULONG count = 0;
+ hr = nodes->Next(1, ¤t, &count);
+ while (SUCCEEDED(hr) && count) {
+ unadvise(current, false, true);
+ current->Release();
+ hr = nodes->Next(1, ¤t, &count);
+ }
+ }
+ }
+ return true;
+}
+
+
diff --git a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.h b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.h
index 8aece0d..3985801 100644
--- a/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.h
+++ b/development/org.eclipse.wst.jsdt.debug.ie/IECrossfireServer/IEDebugger.h
@@ -93,8 +93,16 @@
virtual void setContext(CrossfireContext* value);
private:
+ virtual bool advise(IDebugApplicationNode* node, bool isRoot, bool recurse);
+ virtual bool unadvise(IDebugApplicationNode* node, bool isRoot, bool recurse);
+
+ std::map<IDebugApplicationNode*, DWORD>* m_adviseCookies;
CrossfireContext* m_context;
- std::multimap<std::wstring, DWORD>* m_adviseCookies;
+ DWORD m_rootCookie;
+ IDebugApplicationNode* m_rootNode;
+
+ /* constants */
+ static const wchar_t* ABOUT_BLANK;
};
OBJECT_ENTRY_AUTO(__uuidof(IEDebugger), IEDebugger)