// Copyright (c) 2011 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/memory/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; }