summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-14 13:40:54 +0000
committermmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-14 13:40:54 +0000
commit5490bb983f7e4e111493e853a6091a4a516dd4d7 (patch)
tree5f345034b39d4e25868223b683484c5b7fd762ac /chrome
parenta154ba9bc83408f1f27b27c4dce6af71486b9166 (diff)
downloadchromium_src-5490bb983f7e4e111493e853a6091a4a516dd4d7.zip
chromium_src-5490bb983f7e4e111493e853a6091a4a516dd4d7.tar.gz
chromium_src-5490bb983f7e4e111493e853a6091a4a516dd4d7.tar.bz2
Enumerate layered service providers and namespace providers under Windows and display them on a new net-internals tab. On other OSes, the new tab is always hidden.
BUG=53474 TEST=manual Review URL: http://codereview.chromium.org/3329016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59364 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/dom_ui/net_internals_ui.cc60
-rw-r--r--chrome/browser/net/service_providers_win.cc96
-rw-r--r--chrome/browser/net/service_providers_win.h41
-rw-r--r--chrome/browser/resources/net_internals/index.html34
-rw-r--r--chrome/browser/resources/net_internals/main.css1
-rw-r--r--chrome/browser/resources/net_internals/main.js36
-rw-r--r--chrome/browser/resources/net_internals/serviceprovidersview.js101
-rw-r--r--chrome/chrome_browser.gypi2
8 files changed, 369 insertions, 2 deletions
diff --git a/chrome/browser/dom_ui/net_internals_ui.cc b/chrome/browser/dom_ui/net_internals_ui.cc
index 304097c..9b50165 100644
--- a/chrome/browser/dom_ui/net_internals_ui.cc
+++ b/chrome/browser/dom_ui/net_internals_ui.cc
@@ -51,6 +51,9 @@
#include "net/socket/ssl_client_socket_pool.h"
#include "net/socket/tcp_client_socket_pool.h"
#include "net/url_request/url_request_context.h"
+#ifdef OS_WIN
+#include "chrome/browser/net/service_providers_win.h"
+#endif
namespace {
@@ -210,6 +213,9 @@ class NetInternalsMessageHandler::IOThreadImpl
void OnStartConnectionTests(const ListValue* list);
void OnGetHttpCacheInfo(const ListValue* list);
void OnGetSocketPoolInfo(const ListValue* list);
+#ifdef OS_WIN
+ void OnGetServiceProviders(const ListValue* list);
+#endif
// ChromeNetLog::Observer implementation:
virtual void OnAddEntry(net::NetLog::EventType type,
@@ -393,6 +399,11 @@ void NetInternalsMessageHandler::RegisterMessages() {
dom_ui_->RegisterMessageCallback(
"getSocketPoolInfo",
proxy_->CreateCallback(&IOThreadImpl::OnGetSocketPoolInfo));
+#ifdef OS_WIN
+ dom_ui_->RegisterMessageCallback(
+ "getServiceProviders",
+ proxy_->CreateCallback(&IOThreadImpl::OnGetServiceProviders));
+#endif
}
void NetInternalsMessageHandler::CallJavascriptFunction(
@@ -580,6 +591,9 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady(
OnGetHostResolverCache(NULL);
OnGetHttpCacheInfo(NULL);
OnGetSocketPoolInfo(NULL);
+#ifdef OS_WIN
+ OnGetServiceProviders(NULL);
+#endif
}
void NetInternalsMessageHandler::IOThreadImpl::OnGetProxySettings(
@@ -769,16 +783,58 @@ void NetInternalsMessageHandler::IOThreadImpl::OnGetHttpCacheInfo(
void NetInternalsMessageHandler::IOThreadImpl::OnGetSocketPoolInfo(
const ListValue* list) {
- net::HttpNetworkSession *http_network_session =
+ net::HttpNetworkSession* http_network_session =
GetHttpNetworkSession(context_getter_->GetURLRequestContext());
- Value *socket_pool_info = NULL;
+ Value* socket_pool_info = NULL;
if (http_network_session)
socket_pool_info = http_network_session->SocketPoolInfoToValue();
CallJavascriptFunction(L"g_browser.receivedSocketPoolInfo", socket_pool_info);
}
+#ifdef OS_WIN
+void NetInternalsMessageHandler::IOThreadImpl::OnGetServiceProviders(
+ const ListValue* list) {
+
+ DictionaryValue* service_providers = new DictionaryValue();
+
+ WinsockLayeredServiceProviderList layered_providers;
+ GetWinsockLayeredServiceProviders(&layered_providers);
+ ListValue* layered_provider_list = new ListValue();
+ for (size_t i = 0; i < layered_providers.size(); ++i) {
+ DictionaryValue* service_dict = new DictionaryValue();
+ service_dict->SetString("name", layered_providers[i].name);
+ service_dict->SetInteger("version", layered_providers[i].version);
+ service_dict->SetInteger("chain_length", layered_providers[i].chain_length);
+ service_dict->SetInteger("socket_type", layered_providers[i].socket_type);
+ service_dict->SetInteger("socket_protocol",
+ layered_providers[i].socket_protocol);
+ service_dict->SetString("path", layered_providers[i].path);
+
+ layered_provider_list->Append(service_dict);
+ }
+ service_providers->Set("service_providers", layered_provider_list);
+
+ WinsockNamespaceProviderList namespace_providers;
+ GetWinsockNamespaceProviders(&namespace_providers);
+ ListValue* namespace_list = new ListValue;
+ for (size_t i = 0; i < namespace_providers.size(); ++i) {
+ DictionaryValue* namespace_dict = new DictionaryValue();
+ namespace_dict->SetString("name", namespace_providers[i].name);
+ namespace_dict->SetBoolean("active", namespace_providers[i].active);
+ namespace_dict->SetInteger("version", namespace_providers[i].version);
+ namespace_dict->SetInteger("type", namespace_providers[i].type);
+
+ namespace_list->Append(namespace_dict);
+ }
+ service_providers->Set("namespace_providers", namespace_list);
+
+ CallJavascriptFunction(L"g_browser.receivedServiceProviders",
+ service_providers);
+}
+#endif
+
void NetInternalsMessageHandler::IOThreadImpl::OnAddEntry(
net::NetLog::EventType type,
const base::TimeTicks& time,
diff --git a/chrome/browser/net/service_providers_win.cc b/chrome/browser/net/service_providers_win.cc
new file mode 100644
index 0000000..bc40e1b
--- /dev/null
+++ b/chrome/browser/net/service_providers_win.cc
@@ -0,0 +1,96 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/net/service_providers_win.h"
+
+#include <winsock2.h>
+#include <Ws2spi.h>
+
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/values.h"
+
+void GetWinsockNamespaceProviders(
+ WinsockNamespaceProviderList* namespace_list) {
+
+ // Find out how just how much memory is needed. If we get the expected error,
+ // the memory needed is written to size.
+ DWORD size = 0;
+ if (WSAEnumNameSpaceProviders(&size, NULL) != SOCKET_ERROR ||
+ GetLastError() != WSAEFAULT) {
+ NOTREACHED();
+ return;
+ }
+
+ scoped_array<char> namespace_provider_bytes(new char[size]);
+ WSANAMESPACE_INFO* namespace_providers =
+ reinterpret_cast<WSANAMESPACE_INFO*>(namespace_provider_bytes.get());
+
+ int num_namespace_providers = WSAEnumNameSpaceProviders(&size,
+ namespace_providers);
+ if (num_namespace_providers == SOCKET_ERROR) {
+ NOTREACHED();
+ return;
+ }
+
+ for (int i = 0; i < num_namespace_providers; ++i) {
+ WinsockNamespaceProvider provider;
+
+ provider.name = namespace_providers[i].lpszIdentifier;
+ provider.active = TRUE == namespace_providers[i].fActive;
+ provider.version = namespace_providers[i].dwVersion;
+ provider.type = namespace_providers[i].dwNameSpace;
+
+ namespace_list->push_back(provider);
+ }
+}
+
+void GetWinsockLayeredServiceProviders(
+ WinsockLayeredServiceProviderList* service_list) {
+ // Find out how just how much memory is needed. If we get the expected error,
+ // the memory needed is written to size.
+ DWORD size = 0;
+ int error;
+ if (SOCKET_ERROR != WSCEnumProtocols(NULL, NULL, &size, &error) ||
+ error != WSAENOBUFS) {
+ NOTREACHED();
+ return;
+ }
+
+ scoped_array<char> service_provider_bytes(new char[size]);
+ WSAPROTOCOL_INFOW* service_providers =
+ reinterpret_cast<WSAPROTOCOL_INFOW*>(service_provider_bytes.get());
+
+ int num_service_providers = WSCEnumProtocols(NULL, service_providers, &size,
+ &error);
+ if (num_service_providers == SOCKET_ERROR) {
+ NOTREACHED();
+ return;
+ }
+
+ for (int i = 0; i < num_service_providers; ++i) {
+ WinsockLayeredServiceProvider service_provider;
+
+ service_provider.name = service_providers[i].szProtocol;
+ service_provider.version = service_providers[i].iVersion;
+ service_provider.socket_type = service_providers[i].iSocketType;
+ service_provider.socket_protocol = service_providers[i].iProtocol;
+ service_provider.chain_length = service_providers[i].ProtocolChain.ChainLen;
+
+ // TODO(mmenke): Add categories under Vista and later.
+ // http://msdn.microsoft.com/en-us/library/ms742239%28v=VS.85%29.aspx
+
+ wchar_t path[MAX_PATH];
+ int path_length = arraysize(path);
+ if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path,
+ &path_length, &error)) {
+ service_provider.path = path;
+ }
+
+ service_list->push_back(service_provider);
+ }
+
+ return;
+}
+
diff --git a/chrome/browser/net/service_providers_win.h b/chrome/browser/net/service_providers_win.h
new file mode 100644
index 0000000..39687cd
--- /dev/null
+++ b/chrome/browser/net/service_providers_win.h
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_NET_SERVICE_PROVIDERS_WIN_H_
+#define CHROME_BROWSER_NET_SERVICE_PROVIDERS_WIN_H_
+#pragma once
+
+#include <vector>
+
+class Value;
+
+struct WinsockNamespaceProvider {
+ std::wstring name;
+ int version;
+ bool active;
+ int type;
+};
+typedef std::vector<WinsockNamespaceProvider> WinsockNamespaceProviderList;
+
+struct WinsockLayeredServiceProvider {
+ std::wstring name;
+ std::wstring path;
+ int version;
+ int chain_length;
+ int socket_type;
+ int socket_protocol;
+};
+typedef std::vector<WinsockLayeredServiceProvider>
+ WinsockLayeredServiceProviderList;
+
+// Returns all the Winsock namespace providers.
+void GetWinsockNamespaceProviders(
+ WinsockNamespaceProviderList* namespace_list);
+
+// Returns all the Winsock layered service providers and their paths.
+void GetWinsockLayeredServiceProviders(
+ WinsockLayeredServiceProviderList* service_list);
+
+#endif // CHROME_BROWSER_NET_SERVICE_PROVIDERS_WIN_H_
+
diff --git a/chrome/browser/resources/net_internals/index.html b/chrome/browser/resources/net_internals/index.html
index 84e4186..093b428 100644
--- a/chrome/browser/resources/net_internals/index.html
+++ b/chrome/browser/resources/net_internals/index.html
@@ -24,6 +24,7 @@ found in the LICENSE file.
<script src="loggrouper.js"></script>
<script src="proxyview.js"></script>
<script src="socketsview.js"></script>
+ <script src="serviceprovidersview.js"></script>
</head>
<body onload="onLoaded()">
<!-- Tab switcher for main categories. -->
@@ -35,6 +36,8 @@ found in the LICENSE file.
<li><a href="#dns" id=dnsTab>DNS</a></li>
<li><a href="#sockets" id=socketsTab>Sockets</a></li>
<li><a href="#httpCache" id=httpCacheTab>HTTP Cache</a></li>
+ <!-- Tab is only shown on Windows -->
+ <li><a href="#serviceProviders" id=serviceProvidersTab style="display: none;">SPIs</a></li>
<li><a href="#tests" id=testTab>Tests</a></li>
</ul>
<div style="clear: both;"></div>
@@ -131,6 +134,37 @@ found in the LICENSE file.
<h4>Statistics</h4>
<div id=httpCacheStats>Nothing loaded yet.</div>
</div>
+ <!-- Only shown on Windows -->
+ <div id=serviceProvidersTabContent style="display: none;">
+ <h4>Layered Service Providers</h4>
+ <table class="styledTable">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Type</th>
+ <th>Socket Type</th>
+ <th>Protocol</th>
+ <th>Path</th>
+ </tr>
+ </thead>
+ <tbody id=serviceProvidersTbody>
+ </tbody>
+ </table>
+ <h4>Namespace Providers</h4>
+ <table class="styledTable">
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Version</th>
+ <th>Namespace</th>
+ <th>Active</th>
+ </tr>
+ </thead>
+ <tbody id=namespaceProvidersTbody>
+ </tbody>
+ </table>
+ </div>
<!-- Import/Export data -->
<div id=dataTabContent>
diff --git a/chrome/browser/resources/net_internals/main.css b/chrome/browser/resources/net_internals/main.css
index 7e2e3539..111dcbf 100644
--- a/chrome/browser/resources/net_internals/main.css
+++ b/chrome/browser/resources/net_internals/main.css
@@ -202,6 +202,7 @@ body {
#dataTabContent,
#dnsTabContent,
#socketsTabContent,
+#serviceProvidersTabContent,
#testTabContent {
overflow: auto;
padding: 10px;
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 6cce7ea..756e878 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -83,6 +83,15 @@ function onLoaded() {
"socketTabTbody",
"socketPoolGroupsDiv");
+
+ var serviceView;
+ if (g_browser.isPlatformWindows()) {
+ serviceView = new ServiceProvidersView("serviceProvidersTab",
+ "serviceProvidersTabContent",
+ "serviceProvidersTbody",
+ "namespaceProvidersTbody");
+ }
+
// Create a view which lets you tab between the different sub-views.
var categoryTabSwitcher =
new TabSwitcherView(new DivView('categoryTabHandles'));
@@ -94,6 +103,8 @@ function onLoaded() {
categoryTabSwitcher.addTab('socketsTab', socketsView, false);
categoryTabSwitcher.addTab('httpCacheTab', httpCacheView, false);
categoryTabSwitcher.addTab('dataTab', dataView, false);
+ if (g_browser.isPlatformWindows())
+ categoryTabSwitcher.addTab('serviceProvidersTab', serviceView, false);
categoryTabSwitcher.addTab('testTab', testView, false);
// Build a map from the anchor name of each tab handle to its "tab ID".
@@ -142,6 +153,7 @@ function BrowserBridge() {
this.hostResolverCache_ =
new PollableDataHelper('onHostResolverCacheChanged');
this.socketPoolInfo_ = new PollableDataHelper('onSocketPoolInfoChanged');
+ this.serviceProviders_ = new PollableDataHelper('onServiceProvidersChanged');
// Cache of the data received.
// TODO(eroman): the controls to clear data in the "Requests" tab should be
@@ -169,6 +181,10 @@ BrowserBridge.prototype.sendReady = function() {
this.doPolling_.bind(this), BrowserBridge.POLL_INTERVAL_MS);
};
+BrowserBridge.prototype.isPlatformWindows = function() {
+ return /Win/.test(navigator.platform);
+};
+
BrowserBridge.prototype.sendGetProxySettings = function() {
// The browser will call receivedProxySettings on completion.
chrome.send('getProxySettings');
@@ -208,6 +224,10 @@ BrowserBridge.prototype.sendGetSocketPoolInfo = function() {
chrome.send('getSocketPoolInfo');
};
+BrowserBridge.prototype.sendGetServiceProviders = function() {
+ chrome.send('getServiceProviders');
+};
+
//------------------------------------------------------------------------------
// Messages received from the browser
//------------------------------------------------------------------------------
@@ -270,6 +290,10 @@ BrowserBridge.prototype.receivedSocketPoolInfo = function(socketPoolInfo) {
this.socketPoolInfo_.update(socketPoolInfo);
};
+BrowserBridge.prototype.receivedServiceProviders = function(serviceProviders) {
+ this.serviceProviders_.update(serviceProviders);
+};
+
BrowserBridge.prototype.receivedPassiveLogEntries = function(entries) {
this.passivelyCapturedEvents_ =
this.passivelyCapturedEvents_.concat(entries);
@@ -388,6 +412,16 @@ BrowserBridge.prototype.addSocketPoolInfoObserver = function(observer) {
};
/**
+ * Adds a listener of the service providers info. |observer| will be called
+ * back when data is received, through:
+ *
+ * observer.onServiceProvidersChanged(serviceProviders)
+ */
+BrowserBridge.prototype.addServiceProvidersObserver = function(observer) {
+ this.serviceProviders_.addObserver(observer);
+};
+
+/**
* Adds a listener for the progress of the connection tests.
* The observer will be called back with:
*
@@ -451,6 +485,8 @@ BrowserBridge.prototype.doPolling_ = function() {
this.sendGetHostResolverCache();
this.sendGetHttpCacheInfo();
this.sendGetSocketPoolInfo();
+ if (this.isPlatformWindows())
+ this.sendGetServiceProviders();
};
/**
diff --git a/chrome/browser/resources/net_internals/serviceprovidersview.js b/chrome/browser/resources/net_internals/serviceprovidersview.js
new file mode 100644
index 0000000..5921ceb
--- /dev/null
+++ b/chrome/browser/resources/net_internals/serviceprovidersview.js
@@ -0,0 +1,101 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * This view displays information on Winsock layered service providers and
+ * namespace providers.
+ *
+ * For each layered service provider, shows the name, dll, and type
+ * information. For each namespace provider, shows the name and
+ * whether or not it's active.
+ *
+ * @constructor
+ */
+function ServiceProvidersView(tabId,
+ mainBoxId,
+ serviceProvidersTbodyId,
+ namespaceProvidersTbodyId) {
+ DivView.call(this, mainBoxId);
+
+ var tab = document.getElementById(tabId);
+ setNodeDisplay(tab, true);
+
+ this.serviceProvidersTbody_ =
+ document.getElementById(serviceProvidersTbodyId);
+ this.namespaceProvidersTbody_ =
+ document.getElementById(namespaceProvidersTbodyId);
+
+ g_browser.addServiceProvidersObserver(this);
+}
+
+inherits(ServiceProvidersView, DivView);
+
+ServiceProvidersView.prototype.onServiceProvidersChanged =
+ function(serviceProviders) {
+ this.updateServiceProviders_(serviceProviders["service_providers"]);
+ this.updateNamespaceProviders_(serviceProviders["namespace_providers"]);
+};
+
+/**
+ * Updates the table of layered service providers.
+ */
+ServiceProvidersView.prototype.updateServiceProviders_ =
+ function(serviceProviders) {
+ this.serviceProvidersTbody_.innerHTML = '';
+
+ // Add a table row for each service provider.
+ for (var i = 0; i < serviceProviders.length; ++i) {
+ var tr = addNode(this.serviceProvidersTbody_, 'tr');
+ var entry = serviceProviders[i];
+
+ addNodeWithText(tr, 'td', entry.name);
+ addNodeWithText(tr, 'td', entry.version);
+
+ if (entry.chain_length == 0)
+ addNodeWithText(tr, 'td', 'Layer');
+ else if (entry.chain_length == 1)
+ addNodeWithText(tr, 'td', 'Base');
+ else
+ addNodeWithText(tr, 'td', 'Chain');
+
+ addNodeWithText(tr, 'td', entry.socket_type);
+ addNodeWithText(tr, 'td', entry.socket_protocol);
+ addNodeWithText(tr, 'td', entry.path);
+ }
+};
+
+ServiceProvidersView.namespaceProviderType_ = {
+ '12': 'NS_DNS',
+ '15': 'NS_NLA',
+ '16': 'NS_BTH',
+ '32': 'NS_NTDS',
+ '37': 'NS_EMAIL',
+ '38': 'NS_PNRPNAME',
+ '39': 'NS_PNRPCLOUD'
+};
+
+/**
+ * Updates the lable of namespace providers.
+ */
+ServiceProvidersView.prototype.updateNamespaceProviders_ =
+ function(namespaceProviders) {
+ this.namespaceProvidersTbody_.innerHTML = '';
+
+ // Add a table row for each namespace provider.
+ for (var i = 0; i < namespaceProviders.length; ++i) {
+ var tr = addNode(this.namespaceProvidersTbody_, 'tr');
+ var entry = namespaceProviders[i];
+ addNodeWithText(tr, 'td', entry.name);
+ addNodeWithText(tr, 'td', entry.version);
+
+ var typeString = ServiceProvidersView.namespaceProviderType_[entry.type];
+ if (typeString)
+ addNodeWithText(tr, 'td', typeString);
+ else
+ addNodeWithText(tr, 'td', entry.type);
+
+ addNodeWithText(tr, 'td', entry.active);
+ }
+};
+
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 59c3060..76ddc3a 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2102,6 +2102,8 @@
'browser/net/resolve_proxy_msg_helper.h',
'browser/net/sdch_dictionary_fetcher.cc',
'browser/net/sdch_dictionary_fetcher.h',
+ 'browser/net/service_providers_win.cc',
+ 'browser/net/service_providers_win.h',
'browser/net/sqlite_persistent_cookie_store.cc',
'browser/net/sqlite_persistent_cookie_store.h',
'browser/net/ssl_config_service_manager.h',