Home | History | Annotate | Download | only in net
      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_array<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_array<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