diff options
author | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-14 13:40:54 +0000 |
---|---|---|
committer | mmenke@chromium.org <mmenke@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-14 13:40:54 +0000 |
commit | 5490bb983f7e4e111493e853a6091a4a516dd4d7 (patch) | |
tree | 5f345034b39d4e25868223b683484c5b7fd762ac /chrome | |
parent | a154ba9bc83408f1f27b27c4dce6af71486b9166 (diff) | |
download | chromium_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.cc | 60 | ||||
-rw-r--r-- | chrome/browser/net/service_providers_win.cc | 96 | ||||
-rw-r--r-- | chrome/browser/net/service_providers_win.h | 41 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/index.html | 34 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/main.css | 1 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/main.js | 36 | ||||
-rw-r--r-- | chrome/browser/resources/net_internals/serviceprovidersview.js | 101 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 |
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', |