blob: 66fb715f991b8484098b054a55d475bfc26969f6 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]5490bb982010-09-14 13:40:542// 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
dcheng4e7c0422016-04-14 00:59:0510#include <memory>
11
[email protected]5490bb982010-09-14 13:40:5412#include "base/logging.h"
avi6846aef2015-12-26 01:09:3813#include "base/macros.h"
[email protected]5490bb982010-09-14 13:40:5414#include "base/values.h"
15
thakis43ae9a22015-05-02 04:58:3916WinsockLayeredServiceProvider::WinsockLayeredServiceProvider() {
17}
18
vmpstrbcdec0d2016-04-14 01:24:5219WinsockLayeredServiceProvider::WinsockLayeredServiceProvider(
20 const WinsockLayeredServiceProvider& other) = default;
21
thakis43ae9a22015-05-02 04:58:3922WinsockLayeredServiceProvider::~WinsockLayeredServiceProvider() {
23}
24
[email protected]5490bb982010-09-14 13:40:5425void GetWinsockNamespaceProviders(
26 WinsockNamespaceProviderList* namespace_list) {
27
28 // Find out how just how much memory is needed. If we get the expected error,
29 // the memory needed is written to size.
30 DWORD size = 0;
31 if (WSAEnumNameSpaceProviders(&size, NULL) != SOCKET_ERROR ||
32 GetLastError() != WSAEFAULT) {
33 NOTREACHED();
34 return;
35 }
36
dcheng4e7c0422016-04-14 00:59:0537 std::unique_ptr<char[]> namespace_provider_bytes(new char[size]);
[email protected]5490bb982010-09-14 13:40:5438 WSANAMESPACE_INFO* namespace_providers =
39 reinterpret_cast<WSANAMESPACE_INFO*>(namespace_provider_bytes.get());
40
41 int num_namespace_providers = WSAEnumNameSpaceProviders(&size,
42 namespace_providers);
43 if (num_namespace_providers == SOCKET_ERROR) {
44 NOTREACHED();
45 return;
46 }
47
48 for (int i = 0; i < num_namespace_providers; ++i) {
49 WinsockNamespaceProvider provider;
50
51 provider.name = namespace_providers[i].lpszIdentifier;
52 provider.active = TRUE == namespace_providers[i].fActive;
53 provider.version = namespace_providers[i].dwVersion;
54 provider.type = namespace_providers[i].dwNameSpace;
55
56 namespace_list->push_back(provider);
57 }
58}
59
60void GetWinsockLayeredServiceProviders(
61 WinsockLayeredServiceProviderList* service_list) {
62 // Find out how just how much memory is needed. If we get the expected error,
63 // the memory needed is written to size.
64 DWORD size = 0;
65 int error;
66 if (SOCKET_ERROR != WSCEnumProtocols(NULL, NULL, &size, &error) ||
67 error != WSAENOBUFS) {
68 NOTREACHED();
69 return;
70 }
71
dcheng4e7c0422016-04-14 00:59:0572 std::unique_ptr<char[]> service_provider_bytes(new char[size]);
[email protected]5490bb982010-09-14 13:40:5473 WSAPROTOCOL_INFOW* service_providers =
74 reinterpret_cast<WSAPROTOCOL_INFOW*>(service_provider_bytes.get());
75
76 int num_service_providers = WSCEnumProtocols(NULL, service_providers, &size,
77 &error);
78 if (num_service_providers == SOCKET_ERROR) {
79 NOTREACHED();
80 return;
81 }
82
83 for (int i = 0; i < num_service_providers; ++i) {
84 WinsockLayeredServiceProvider service_provider;
85
86 service_provider.name = service_providers[i].szProtocol;
87 service_provider.version = service_providers[i].iVersion;
88 service_provider.socket_type = service_providers[i].iSocketType;
89 service_provider.socket_protocol = service_providers[i].iProtocol;
90 service_provider.chain_length = service_providers[i].ProtocolChain.ChainLen;
91
92 // TODO(mmenke): Add categories under Vista and later.
93 // http://msdn.microsoft.com/en-us/library/ms742239%28v=VS.85%29.aspx
94
95 wchar_t path[MAX_PATH];
96 int path_length = arraysize(path);
97 if (0 == WSCGetProviderPath(&service_providers[i].ProviderId, path,
98 &path_length, &error)) {
99 service_provider.path = path;
100 }
101
102 service_list->push_back(service_provider);
103 }
104
105 return;
106}
107