// 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 <memory>

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/values.h"

WinsockLayeredServiceProvider::WinsockLayeredServiceProvider() {
}

WinsockLayeredServiceProvider::WinsockLayeredServiceProvider(
    const WinsockLayeredServiceProvider& other) = default;

WinsockLayeredServiceProvider::~WinsockLayeredServiceProvider() {
}

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;
  }

  std::unique_ptr<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;
  }

  std::unique_ptr<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 = base::size(path);
    if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path,
                                &path_length, &error)) {
      service_provider.path = path;
    }

    service_list->push_back(service_provider);
  }

  return;
}

