15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/net/service_providers_win.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <Ws2spi.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetWinsockNamespaceProviders( 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WinsockNamespaceProviderList* namespace_list) { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find out how just how much memory is needed. If we get the expected error, 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the memory needed is written to size. 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD size = 0; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (WSAEnumNameSpaceProviders(&size, NULL) != SOCKET_ERROR || 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetLastError() != WSAEFAULT) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> namespace_provider_bytes(new char[size]); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WSANAMESPACE_INFO* namespace_providers = 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<WSANAMESPACE_INFO*>(namespace_provider_bytes.get()); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_namespace_providers = WSAEnumNameSpaceProviders(&size, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namespace_providers); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_namespace_providers == SOCKET_ERROR) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_namespace_providers; ++i) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WinsockNamespaceProvider provider; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider.name = namespace_providers[i].lpszIdentifier; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider.active = TRUE == namespace_providers[i].fActive; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider.version = namespace_providers[i].dwVersion; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider.type = namespace_providers[i].dwNameSpace; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) namespace_list->push_back(provider); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetWinsockLayeredServiceProviders( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WinsockLayeredServiceProviderList* service_list) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find out how just how much memory is needed. If we get the expected error, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the memory needed is written to size. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD size = 0; 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SOCKET_ERROR != WSCEnumProtocols(NULL, NULL, &size, &error) || 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error != WSAENOBUFS) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> service_provider_bytes(new char[size]); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WSAPROTOCOL_INFOW* service_providers = 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<WSAPROTOCOL_INFOW*>(service_provider_bytes.get()); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_service_providers = WSCEnumProtocols(NULL, service_providers, &size, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &error); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_service_providers == SOCKET_ERROR) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < num_service_providers; ++i) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WinsockLayeredServiceProvider service_provider; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.name = service_providers[i].szProtocol; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.version = service_providers[i].iVersion; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.socket_type = service_providers[i].iSocketType; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.socket_protocol = service_providers[i].iProtocol; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.chain_length = service_providers[i].ProtocolChain.ChainLen; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(mmenke): Add categories under Vista and later. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://msdn.microsoft.com/en-us/library/ms742239%28v=VS.85%29.aspx 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wchar_t path[MAX_PATH]; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int path_length = arraysize(path); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &path_length, &error)) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_provider.path = path; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_list->push_back(service_provider); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97