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