1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/net/service_providers_win.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <winsock2.h> 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include <Ws2spi.h> 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/logging.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 12bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/values.h" 13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 14bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid GetWinsockNamespaceProviders( 15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WinsockNamespaceProviderList* namespace_list) { 16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Find out how just how much memory is needed. If we get the expected error, 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // the memory needed is written to size. 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DWORD size = 0; 20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (WSAEnumNameSpaceProviders(&size, NULL) != SOCKET_ERROR || 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen GetLastError() != WSAEFAULT) { 22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED(); 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen scoped_array<char> namespace_provider_bytes(new char[size]); 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WSANAMESPACE_INFO* namespace_providers = 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reinterpret_cast<WSANAMESPACE_INFO*>(namespace_provider_bytes.get()); 29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int num_namespace_providers = WSAEnumNameSpaceProviders(&size, 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen namespace_providers); 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (num_namespace_providers == SOCKET_ERROR) { 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED(); 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 37bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen for (int i = 0; i < num_namespace_providers; ++i) { 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WinsockNamespaceProvider provider; 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen provider.name = namespace_providers[i].lpszIdentifier; 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen provider.active = TRUE == namespace_providers[i].fActive; 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen provider.version = namespace_providers[i].dwVersion; 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen provider.type = namespace_providers[i].dwNameSpace; 44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen namespace_list->push_back(provider); 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid GetWinsockLayeredServiceProviders( 50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WinsockLayeredServiceProviderList* service_list) { 51bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Find out how just how much memory is needed. If we get the expected error, 52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // the memory needed is written to size. 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DWORD size = 0; 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int error; 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (SOCKET_ERROR != WSCEnumProtocols(NULL, NULL, &size, &error) || 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen error != WSAENOBUFS) { 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED(); 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen scoped_array<char> service_provider_bytes(new char[size]); 62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WSAPROTOCOL_INFOW* service_providers = 63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen reinterpret_cast<WSAPROTOCOL_INFOW*>(service_provider_bytes.get()); 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int num_service_providers = WSCEnumProtocols(NULL, service_providers, &size, 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &error); 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (num_service_providers == SOCKET_ERROR) { 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NOTREACHED(); 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen for (int i = 0; i < num_service_providers; ++i) { 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen WinsockLayeredServiceProvider service_provider; 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.name = service_providers[i].szProtocol; 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.version = service_providers[i].iVersion; 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.socket_type = service_providers[i].iSocketType; 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.socket_protocol = service_providers[i].iProtocol; 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.chain_length = service_providers[i].ProtocolChain.ChainLen; 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // TODO(mmenke): Add categories under Vista and later. 82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // http://msdn.microsoft.com/en-us/library/ms742239%28v=VS.85%29.aspx 83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen wchar_t path[MAX_PATH]; 85bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen int path_length = arraysize(path); 86bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path, 87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen &path_length, &error)) { 88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_provider.path = path; 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen service_list->push_back(service_provider); 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 97