Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: chrome/utility/wifi/wifi_service_win.cc

Issue 27722003: Windows-specific implementation of Networking Private API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Renamed feature platforms to 'win' and 'mac' to match Platforms from model.py Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/utility/wifi/wifi_service_test.cc ('k') | chrome/utility/wifi/wifi_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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/utility/wifi/wifi_service.h"
6
7 #include <iphlpapi.h>
8 #include <objbase.h>
9 #include <wlanapi.h>
10
11 #include "base/base_paths_win.h"
12 #include "base/bind.h"
13 #include "base/files/file_path.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/message_loop/message_loop.h"
16 #include "base/path_service.h"
17 #include "base/strings/string16.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/win/registry.h"
21 #include "components/onc/onc_constants.h"
22
23 namespace {
24 const char kWiFiServiceError[] = "Error.WiFiService";
25 const wchar_t kNwCategoryWizardRegKey[] =
26 L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Network\\"
27 L"NwCategoryWizard";
28 const wchar_t kNwCategoryWizardRegValue[] = L"Show";
29 const wchar_t kNwCategoryWizardSavedRegValue[] = L"ShowSaved";
30 const wchar_t kNwCategoryWizardDeleteRegValue[] = L"ShowDelete";
31 const wchar_t kWlanApiDll[] = L"wlanapi.dll";
32
33 // WlanApi function names
34 const char kWlanConnect[] = "WlanConnect";
35 const char kWlanCloseHandle[] = "WlanCloseHandle";
36 const char kWlanDisconnect[] = "WlanDisconnect";
37 const char kWlanEnumInterfaces[] = "WlanEnumInterfaces";
38 const char kWlanFreeMemory[] = "WlanFreeMemory";
39 const char kWlanGetAvailableNetworkList[] = "WlanGetAvailableNetworkList";
40 const char kWlanGetNetworkBssList[] = "WlanGetNetworkBssList";
41 const char kWlanGetProfile[] = "WlanGetProfile";
42 const char kWlanOpenHandle[] = "WlanOpenHandle";
43 const char kWlanRegisterNotification[] = "WlanRegisterNotification";
44 const char kWlanSaveTemporaryProfile[] = "WlanSaveTemporaryProfile";
45 const char kWlanScan[] = "WlanScan";
46
47 // WlanApi function definitions
48 typedef DWORD (WINAPI* WlanConnectFunction)(
49 HANDLE hClientHandle,
50 CONST GUID *pInterfaceGuid,
51 CONST PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
52 PVOID pReserved);
53
54 typedef DWORD (WINAPI* WlanCloseHandleFunction)(
55 HANDLE hClientHandle,
56 PVOID pReserved);
57
58 typedef DWORD (WINAPI* WlanDisconnectFunction)(
59 HANDLE hClientHandle,
60 CONST GUID *pInterfaceGuid,
61 PVOID pReserved);
62
63 typedef DWORD (WINAPI* WlanEnumInterfacesFunction)(
64 HANDLE hClientHandle,
65 PVOID pReserved,
66 PWLAN_INTERFACE_INFO_LIST *ppInterfaceList);
67
68 typedef VOID (WINAPI* WlanFreeMemoryFunction)(
69 _In_ PVOID pMemory);
70
71 typedef DWORD (WINAPI* WlanGetAvailableNetworkListFunction)(
72 HANDLE hClientHandle,
73 CONST GUID *pInterfaceGuid,
74 DWORD dwFlags,
75 PVOID pReserved,
76 PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList);
77
78 typedef DWORD (WINAPI* WlanGetNetworkBssListFunction)(
79 HANDLE hClientHandle,
80 const GUID* pInterfaceGuid,
81 const PDOT11_SSID pDot11Ssid,
82 DOT11_BSS_TYPE dot11BssType,
83 BOOL bSecurityEnabled,
84 PVOID pReserved,
85 PWLAN_BSS_LIST* ppWlanBssList);
86
87 typedef DWORD (WINAPI* WlanGetProfileFunction)(
88 HANDLE hClientHandle,
89 CONST GUID *pInterfaceGuid,
90 LPCWSTR strProfileName,
91 PVOID pReserved,
92 LPWSTR *pstrProfileXml,
93 DWORD *pdwFlags,
94 DWORD *pdwGrantedAccess);
95
96 typedef DWORD (WINAPI* WlanOpenHandleFunction)(
97 DWORD dwClientVersion,
98 PVOID pReserved,
99 PDWORD pdwNegotiatedVersion,
100 PHANDLE phClientHandle);
101
102 typedef DWORD (WINAPI* WlanRegisterNotificationFunction)(
103 HANDLE hClientHandle,
104 DWORD dwNotifSource,
105 BOOL bIgnoreDuplicate,
106 WLAN_NOTIFICATION_CALLBACK funcCallback,
107 PVOID pCallbackContext,
108 PVOID pReserved,
109 PDWORD pdwPrevNotifSource);
110
111 typedef DWORD (WINAPI* WlanSaveTemporaryProfileFunction)(
112 HANDLE hClientHandle,
113 CONST GUID* pInterfaceGuid,
114 LPCWSTR strProfileName,
115 LPCWSTR strAllUserProfileSecurity,
116 DWORD dwFlags,
117 BOOL bOverWrite,
118 PVOID pReserved);
119
120 typedef DWORD (WINAPI* WlanScanFunction)(
121 HANDLE hClientHandle,
122 CONST GUID *pInterfaceGuid,
123 CONST PDOT11_SSID pDot11Ssid,
124 CONST PWLAN_RAW_DATA pIeData,
125 PVOID pReserved);
126
127 } // namespace
128
129 namespace wifi {
130
131 // Implementation of WiFiService for Windows.
132 class WiFiServiceImpl : public WiFiService, base::NonThreadSafe {
133 public:
134 WiFiServiceImpl();
135 virtual ~WiFiServiceImpl();
136
137 // WiFiService interface implementation.
138
139 virtual bool Initialize() OVERRIDE;
140
141 virtual void UnInitialize() OVERRIDE;
142
143 virtual void GetProperties(const std::string& network_guid,
144 const NetworkPropertiesCallback& callback,
145 const ErrorCallback& error_callback) OVERRIDE;
146
147 virtual void GetState(const std::string& network_guid,
148 const NetworkPropertiesCallback& callback,
149 const ErrorCallback& error_callback) OVERRIDE;
150
151 virtual void GetManagedProperties(
152 const std::string& network_guid,
153 const DictionaryResultCallback& callback,
154 const ErrorCallback& error_callback) OVERRIDE;
155
156 virtual void SetProperties(const std::string& network_guid,
157 const base::DictionaryValue& properties,
158 const StringResultCallback& callback,
159 const ErrorCallback& error_callback) OVERRIDE;
160
161 virtual void GetVisibleNetworks(const NetworkListCallback& callback,
162 const ErrorCallback& error_callback) OVERRIDE;
163
164 virtual void RequestNetworkScan() OVERRIDE;
165
166 virtual void StartConnect(const std::string& network_guid,
167 const StringResultCallback& callback,
168 const ErrorCallback& error_callback) OVERRIDE;
169
170 virtual void StartDisconnect(const std::string& network_guid,
171 const StringResultCallback& callback,
172 const ErrorCallback& error_callback) OVERRIDE;
173
174 virtual void SetNetworksChangedObserver(
175 const NetworkGuidListCallback& observer) OVERRIDE;
176
177 virtual void SetNetworkListChangedObserver(
178 const NetworkGuidListCallback& observer) OVERRIDE;
179
180 private:
181 // Static callback for Windows WLAN_NOTIFICATION. Calls OnWlanNotification
182 // on WiFiServiceImpl passed back as |context|.
183 static void __stdcall OnWlanNotificationCallback(
184 PWLAN_NOTIFICATION_DATA wlan_notification_data,
185 PVOID context);
186
187 // Callback for Windows WLAN_NOTIFICATION. Called on random thread from
188 // OnWlanNotificationCallback. Handles network connectivity and scan complete
189 // notification and posts tasks to main thread.
190 void OnWlanNotification(PWLAN_NOTIFICATION_DATA wlan_notification_data);
191
192 // Handles NetworkScanComplete notification on main thread. Sends
193 // |NetworkListChanged| event with new list of visible networks.
194 void OnNetworkScanCompleteOnMainThread();
195
196 // Wait up to |kMaxAttempts| with |kAttemptDelayMs| delay for connection
197 // to network with |network_guid|. Reset DHCP and Notify that |NetworkChanged|
198 // upon success.
199 void WaitForNetworkConnect(const std::string& network_guid, int attempt);
200
201 // Check |error_code| and if is not |ERROR_SUCCESS|, then run |error_callback|
202 // with |error_name|.
203 bool CheckError(const ErrorCallback& error_callback,
204 const std::string& error_name,
205 DWORD error_code) const;
206
207 // Return |iterator| to network identified by |network_guid| in |networks|
208 // list.
209 NetworkList::iterator FindNetwork(NetworkList& networks,
210 const std::string& network_guid);
211
212 // Save currently connected network profile and return its
213 // |connected_network_guid|, so it can be re-connected later.
214 DWORD SaveCurrentConnectedNetwork(std::string* connected_network_guid);
215
216 // Sort networks, so connected/connecting is up front, then by type:
217 // Ethernet, WiFi, Cellular, VPN
218 static void SortNetworks(NetworkList* networks);
219
220 // Open a WLAN client handle, register for WLAN notifications.
221 DWORD OpenClientHandle();
222
223 // Reset DHCP on wireless network to work around an issue when Windows
224 // takes forever to connect to the network, e.g. after Chromecast
225 // device reset.
226 DWORD ResetDHCP();
227
228 // Find |adapter_index_map| by |interface_guid| for DHCP reset.
229 DWORD FindAdapterIndexMapByGUID(const GUID& interface_guid,
230 IP_ADAPTER_INDEX_MAP* adapter_index_map);
231
232 // Avoid the network location wizard to pop up when network is connected.
233 // Preserve current value in |saved_nw_category_wizard_|.
234 DWORD DisableNwCategoryWizard();
235
236 // Restore network location wizard to value saved by DisableNwCategoryWizard.
237 DWORD RestoreNwCategoryWizard();
238
239 // Ensure that |client_| handle is initialized.
240 DWORD EnsureInitialized();
241
242 // Close |client_| handle if it is open.
243 DWORD CloseClientHandle();
244
245 // Get |profile_name| from unique |network_guid|.
246 base::string16 ProfileNameFromGUID(const std::string& network_guid) const {
247 return base::UTF8ToUTF16(network_guid);
248 }
249
250 // Get |dot11_ssid| from unique |network_guid|.
251 DOT11_SSID SSIDFromGUID(const std::string& network_guid) const;
252
253 // Get unique |network_guid| string based on |dot11_ssid|.
254 std::string GUIDFromSSID(const DOT11_SSID& dot11_ssid) const {
255 return std::string(reinterpret_cast<const char*>(dot11_ssid.ucSSID),
256 dot11_ssid.uSSIDLength);
257 }
258
259 // Get network |ssid| string based on |wlan|.
260 std::string SSIDFromWLAN(const WLAN_AVAILABLE_NETWORK& wlan) const {
261 return GUIDFromSSID(wlan.dot11Ssid);
262 }
263
264 // Get unique |network_guid| string based on |wlan|.
265 std::string GUIDFromWLAN(const WLAN_AVAILABLE_NETWORK& wlan) const {
266 return SSIDFromWLAN(wlan);
267 }
268
269 // Deduce |onc::wifi| security from |alg|.
270 std::string SecurityFromDot11AuthAlg(DOT11_AUTH_ALGORITHM alg) const;
271
272 // Populate |properties| based on |wlan| and its corresponding bss info from
273 // |wlan_bss_list|.
274 void NetworkPropertiesFromAvailableNetwork(const WLAN_AVAILABLE_NETWORK& wlan,
275 const WLAN_BSS_LIST& wlan_bss_list,
276 NetworkProperties* properties);
277
278 // Get the list of visible wireless networks.
279 DWORD GetVisibleNetworkList(NetworkList* network_list);
280
281 // Find currently connected network if any. Populate |connected_network_guid|
282 // on success.
283 DWORD FindConnectedNetwork(std::string* connected_network_guid);
284
285 // Connect to network |network_guid| using previosly stored profile if exists,
286 // or just network sid.
287 DWORD Connect(const std::string& network_guid);
288
289 // Disconnect from currently connected network if any.
290 DWORD Disconnect();
291
292 // Save temporary wireless profile for |network_guid|.
293 DWORD SaveTempProfile(const std::string& network_guid);
294
295 // Get previously stored |profile_xml| for |network_guid|.
296 DWORD GetProfile(const std::string& network_guid, std::string* profile_xml);
297
298 // Return true if there is previously stored profile xml for |network_guid|.
299 bool HaveProfile(const std::string& network_guid);
300
301 // Notify |network_list_changed_observer_| that list of visible networks has
302 // changed to |networks|.
303 void NotifyNetworkListChanged(const NetworkList& networks);
304
305 // Notify |networks_changed_observer_| that network |network_guid| status has
306 // changed.
307 void NotifyNetworkChanged(const std::string& network_guid);
308
309 // Load WlanApi.dll from SystemDirectory and get Api function pointers.
310 DWORD LoadWlanLibrary();
311 // Instance of WlanApi.dll.
312 HINSTANCE wlan_api_library_;
313 // WlanApi function pointers
314 WlanConnectFunction WlanConnect_function_;
315 WlanCloseHandleFunction WlanCloseHandle_function_;
316 WlanDisconnectFunction WlanDisconnect_function_;
317 WlanEnumInterfacesFunction WlanEnumInterfaces_function_;
318 WlanFreeMemoryFunction WlanFreeMemory_function_;
319 WlanGetAvailableNetworkListFunction WlanGetAvailableNetworkList_function_;
320 // WlanGetNetworkBssList function may not be avaiable on Windows XP.
321 WlanGetNetworkBssListFunction WlanGetNetworkBssList_function_;
322 WlanGetProfileFunction WlanGetProfile_function_;
323 WlanOpenHandleFunction WlanOpenHandle_function_;
324 WlanRegisterNotificationFunction WlanRegisterNotification_function_;
325 WlanScanFunction WlanScan_function_;
326 // WlanSaveTemporaryProfile function may not be avaiable on Windows XP.
327 WlanSaveTemporaryProfileFunction WlanSaveTemporaryProfile_function_;
328
329 // WLAN service handle.
330 HANDLE client_;
331 // GUID of the currently connected interface, if any, otherwise the GUID of
332 // one of the WLAN interfaces.
333 GUID interface_guid_;
334 // Preserved WLAN profile xml.
335 std::map<std::string, std::string> saved_profiles_xml_;
336 // Observer to get notified when network(s) have changed (e.g. connect).
337 NetworkGuidListCallback networks_changed_observer_;
338 // Observer to get notified when network list has changed (scan complete).
339 NetworkGuidListCallback network_list_changed_observer_;
340 // Saved value of network location wizard show value.
341 scoped_ptr<DWORD> saved_nw_category_wizard_;
342 // Task runner to post tasks on main thread.
343 scoped_refptr<base::TaskRunner> task_runner_;
344 // If |false|, then |networks_changed_observer_| is not notified.
345 bool enable_notify_network_changed_;
346 // Number of attempts to check that network has connected successfully.
347 static const int kMaxAttempts = 100;
348 // Delay between attempts to check that network has connected successfully.
349 static const int kAttemptDelayMs = 100;
350
351 DISALLOW_COPY_AND_ASSIGN(WiFiServiceImpl);
352 };
353
354 WiFiServiceImpl::WiFiServiceImpl()
355 : wlan_api_library_(NULL),
356 WlanConnect_function_(NULL),
357 WlanCloseHandle_function_(NULL),
358 WlanDisconnect_function_(NULL),
359 WlanEnumInterfaces_function_(NULL),
360 WlanFreeMemory_function_(NULL),
361 WlanGetAvailableNetworkList_function_(NULL),
362 WlanGetNetworkBssList_function_(NULL),
363 WlanGetProfile_function_(NULL),
364 WlanOpenHandle_function_(NULL),
365 WlanRegisterNotification_function_(NULL),
366 WlanSaveTemporaryProfile_function_(NULL),
367 WlanScan_function_(NULL),
368 client_(NULL),
369 enable_notify_network_changed_(true) {}
370
371 WiFiServiceImpl::~WiFiServiceImpl() { UnInitialize(); }
372
373 bool WiFiServiceImpl::Initialize() {
374 DCHECK(!client_);
375 // Restore NwCategoryWizard in case if we crashed during connect.
376 RestoreNwCategoryWizard();
377 DWORD error = OpenClientHandle();
378 return error == ERROR_SUCCESS;
379 }
380
381 void WiFiServiceImpl::UnInitialize() {
382 CloseClientHandle();
383 }
384
385 void WiFiServiceImpl::GetProperties(const std::string& network_guid,
386 const NetworkPropertiesCallback& callback,
387 const ErrorCallback& error_callback) {
388 DWORD error = EnsureInitialized();
389 if (error == ERROR_SUCCESS) {
390 NetworkList network_list;
391 error = GetVisibleNetworkList(&network_list);
392 if (error == ERROR_SUCCESS && !network_list.empty()) {
393 NetworkList::const_iterator it = FindNetwork(network_list, network_guid);
394 if (it != network_list.end()) {
395 DLOG(INFO) << "Get Properties: " << network_guid << ":"
396 << it->connection_state;
397 callback.Run(network_guid, *it);
398 return;
399 } else {
400 error = ERROR_NOT_FOUND;
401 }
402 }
403 }
404
405 CheckError(error_callback, kWiFiServiceError, error);
406 }
407
408 void WiFiServiceImpl::GetState(const std::string& network_guid,
409 const NetworkPropertiesCallback& callback,
410 const ErrorCallback& error_callback) {
411 // This method is not implemented in first version as it is not used by
412 // Google Cast extension.
413 CheckError(error_callback, kWiFiServiceError, ERROR_CALL_NOT_IMPLEMENTED);
414 }
415
416 void WiFiServiceImpl::GetManagedProperties(
417 const std::string& network_guid,
418 const DictionaryResultCallback& callback,
419 const ErrorCallback& error_callback) {
420 // This method is not implemented in first version as it is not used by
421 // Google Cast extension.
422 CheckError(error_callback, kWiFiServiceError, ERROR_CALL_NOT_IMPLEMENTED);
423 }
424
425 void WiFiServiceImpl::SetProperties(const std::string& network_guid,
426 const base::DictionaryValue& properties,
427 const StringResultCallback& callback,
428 const ErrorCallback& error_callback) {
429 // This method is not implemented in first version as it is not used by
430 // Google Cast extension.
431 CheckError(error_callback, kWiFiServiceError, ERROR_CALL_NOT_IMPLEMENTED);
432 }
433
434 void WiFiServiceImpl::GetVisibleNetworks(const NetworkListCallback& callback,
435 const ErrorCallback& error_callback) {
436 DWORD error = EnsureInitialized();
437
438 if (error == ERROR_SUCCESS) {
439 NetworkList network_list;
440 error = GetVisibleNetworkList(&network_list);
441 if (error == ERROR_SUCCESS && !network_list.empty()) {
442 SortNetworks(&network_list);
443 callback.Run(network_list);
444 return;
445 }
446 }
447
448 CheckError(error_callback, kWiFiServiceError, error);
449 }
450
451 void WiFiServiceImpl::RequestNetworkScan() {
452 DWORD error = EnsureInitialized();
453 if (error == ERROR_SUCCESS) {
454 WlanScan_function_(client_, &interface_guid_, NULL, NULL, NULL);
455 }
456 }
457
458 void WiFiServiceImpl::StartConnect(const std::string& network_guid,
459 const StringResultCallback& callback,
460 const ErrorCallback& error_callback) {
461 DLOG(INFO) << "Start Connect: " << network_guid;
462 DWORD error = EnsureInitialized();
463 if (error == ERROR_SUCCESS) {
464 std::string connected_network_guid;
465 error = SaveCurrentConnectedNetwork(&connected_network_guid);
466 if (error == ERROR_SUCCESS) {
467 // Connect only if network |network_guid| is not connected already.
468 if (network_guid != connected_network_guid)
469 error = Connect(network_guid);
470 if (error == ERROR_SUCCESS) {
471 DisableNwCategoryWizard();
472 callback.Run(network_guid);
473 // Notify that previously connected network has changed.
474 NotifyNetworkChanged(connected_network_guid);
475 // Start waiting for network connection state change.
476 if (!networks_changed_observer_.is_null()) {
477 // Disable automatic network change notifications as they get fired
478 // when network is just connected, but not yet accessible (doesn't
479 // have valid IP address).
480 enable_notify_network_changed_ = false;
481 WaitForNetworkConnect(network_guid, 0);
482 return;
483 }
484 }
485 }
486 }
487 CheckError(error_callback, kWiFiServiceError, error);
488 }
489
490 void WiFiServiceImpl::StartDisconnect(const std::string& network_guid,
491 const StringResultCallback& callback,
492 const ErrorCallback& error_callback) {
493 DLOG(INFO) << "Start Disconnect: " << network_guid;
494 DWORD error = EnsureInitialized();
495 if (error == ERROR_SUCCESS) {
496 std::string connected_network_guid;
497 error = SaveCurrentConnectedNetwork(&connected_network_guid);
498 if (error == ERROR_SUCCESS && network_guid == connected_network_guid) {
499 error = Disconnect();
500 if (error == ERROR_SUCCESS) {
501 callback.Run(network_guid);
502 NotifyNetworkChanged(network_guid);
503 return;
504 }
505 }
506 }
507 CheckError(error_callback, kWiFiServiceError, error);
508 }
509
510 void WiFiServiceImpl::SetNetworksChangedObserver(
511 const NetworkGuidListCallback& observer) {
512 networks_changed_observer_ = observer;
513 }
514
515 void WiFiServiceImpl::SetNetworkListChangedObserver(
516 const NetworkGuidListCallback& observer) {
517 network_list_changed_observer_ = observer;
518 }
519
520 void WiFiServiceImpl::OnWlanNotificationCallback(
521 PWLAN_NOTIFICATION_DATA wlan_notification_data,
522 PVOID context) {
523 WiFiServiceImpl* service = reinterpret_cast<WiFiServiceImpl*>(context);
524 service->OnWlanNotification(wlan_notification_data);
525 }
526
527 void WiFiServiceImpl::OnWlanNotification(
528 PWLAN_NOTIFICATION_DATA wlan_notification_data) {
529 if (task_runner_ == NULL)
530 return;
531 switch (wlan_notification_data->NotificationCode) {
532 case wlan_notification_acm_disconnected:
533 case wlan_notification_acm_connection_complete:
534 case wlan_notification_acm_connection_attempt_fail: {
535 PWLAN_CONNECTION_NOTIFICATION_DATA wlan_connection_data =
536 reinterpret_cast<PWLAN_CONNECTION_NOTIFICATION_DATA>(
537 wlan_notification_data->pData);
538 task_runner_->PostTask(
539 FROM_HERE,
540 base::Bind(&WiFiServiceImpl::NotifyNetworkChanged,
541 base::Unretained(this),
542 GUIDFromSSID(wlan_connection_data->dot11Ssid)));
543 break;
544 }
545 case wlan_notification_acm_scan_complete:
546 task_runner_->PostTask(
547 FROM_HERE,
548 base::Bind(&WiFiServiceImpl::OnNetworkScanCompleteOnMainThread,
549 base::Unretained(this)));
550 break;
551 }
552 }
553
554 void WiFiServiceImpl::OnNetworkScanCompleteOnMainThread() {
555 NetworkList networks;
556 // Get current list of visible networks and notify that network list has
557 // changed.
558 DWORD error = GetVisibleNetworkList(&networks);
559 DCHECK(error == ERROR_SUCCESS);
560 if (error == ERROR_SUCCESS)
561 NotifyNetworkListChanged(networks);
562 }
563
564 void WiFiServiceImpl::WaitForNetworkConnect(const std::string& network_guid,
565 int attempt) {
566 // If network didn't get connected in |kMaxAttempts|, then restore automatic
567 // network change notifications and stop waiting.
568 if (attempt > kMaxAttempts) {
569 DLOG(ERROR) << kMaxAttempts << " attempts exceeded waiting for connect to "
570 << network_guid;
571 enable_notify_network_changed_ = true;
572 RestoreNwCategoryWizard();
573 return;
574 }
575 std::string connected_network_guid;
576 DWORD error = FindConnectedNetwork(&connected_network_guid);
577 if (network_guid == connected_network_guid) {
578 DLOG(INFO) << "WiFi Connected, Reset DHCP: " << network_guid;
579 // Even though wireless network is now connected, it may still be unusable,
580 // e.g. after Chromecast device reset. Reset DHCP on wireless network to
581 // work around this issue.
582 error = ResetDHCP();
583 // Restore previously suppressed notifications.
584 enable_notify_network_changed_ = true;
585 RestoreNwCategoryWizard();
586 NotifyNetworkChanged(network_guid);
587 } else {
588 // Continue waiting for network connection state change.
589 base::MessageLoop::current()->PostDelayedTask(
590 FROM_HERE,
591 base::Bind(&WiFiServiceImpl::WaitForNetworkConnect,
592 base::Unretained(this),
593 network_guid,
594 ++attempt),
595 base::TimeDelta::FromMilliseconds(kAttemptDelayMs));
596 }
597 }
598
599 bool WiFiServiceImpl::CheckError(const ErrorCallback& error_callback,
600 const std::string& error_name,
601 DWORD error_code) const {
602 if (error_code != ERROR_SUCCESS) {
603 DLOG(ERROR) << "WiFiService Error " << error_code << ": " << error_name;
604 scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
605 error_data->SetInteger("Win32ErrorCode", error_code);
606 error_callback.Run(error_name, error_data.Pass());
607 return true;
608 }
609 return false;
610 }
611
612 WiFiService::NetworkList::iterator WiFiServiceImpl::FindNetwork(
613 NetworkList& networks,
614 const std::string& network_guid) {
615 for (NetworkList::iterator it = networks.begin(); it != networks.end();
616 ++it) {
617 if (it->guid == network_guid)
618 return it;
619 }
620 return networks.end();
621 }
622
623 DWORD WiFiServiceImpl::SaveCurrentConnectedNetwork(
624 std::string* connected_network_guid) {
625 // Find currently connected network.
626 DWORD error = FindConnectedNetwork(connected_network_guid);
627 if (error == ERROR_SUCCESS && !connected_network_guid->empty()) {
628 if (error == ERROR_SUCCESS) {
629 SaveTempProfile(*connected_network_guid);
630 std::string profile_xml;
631 error = GetProfile(*connected_network_guid, &profile_xml);
632 if (error == ERROR_SUCCESS) {
633 saved_profiles_xml_[*connected_network_guid] = profile_xml;
634 }
635 }
636 }
637 return error;
638 }
639
640 void WiFiServiceImpl::SortNetworks(NetworkList* networks) {
641 networks->sort(NetworkProperties::OrderByType);
642 }
643
644
645 DWORD WiFiServiceImpl::LoadWlanLibrary() {
646 // Use an absolute path to load the DLL to avoid DLL preloading attacks.
647 base::FilePath path;
648 if (!PathService::Get(base::DIR_SYSTEM, &path)) {
649 DLOG(ERROR) << "Unable to get system path.";
650 return ERROR_NOT_FOUND;
651 }
652 wlan_api_library_ = ::LoadLibraryEx(path.Append(kWlanApiDll).value().c_str(),
653 NULL,
654 LOAD_WITH_ALTERED_SEARCH_PATH);
655 if (!wlan_api_library_) {
656 DLOG(ERROR) << "Unable to load WlanApi.dll.";
657 return ERROR_NOT_FOUND;
658 }
659
660 // Initialize WlanApi function pointers
661 WlanConnect_function_ =
662 reinterpret_cast<WlanConnectFunction>(
663 ::GetProcAddress(wlan_api_library_, kWlanConnect));
664 WlanCloseHandle_function_ =
665 reinterpret_cast<WlanCloseHandleFunction>(
666 ::GetProcAddress(wlan_api_library_, kWlanCloseHandle));
667 WlanDisconnect_function_ =
668 reinterpret_cast<WlanDisconnectFunction>(
669 ::GetProcAddress(wlan_api_library_, kWlanDisconnect));
670 WlanEnumInterfaces_function_ =
671 reinterpret_cast<WlanEnumInterfacesFunction>(
672 ::GetProcAddress(wlan_api_library_, kWlanEnumInterfaces));
673 WlanFreeMemory_function_ =
674 reinterpret_cast<WlanFreeMemoryFunction>(
675 ::GetProcAddress(wlan_api_library_, kWlanFreeMemory));
676 WlanGetAvailableNetworkList_function_ =
677 reinterpret_cast<WlanGetAvailableNetworkListFunction>(
678 ::GetProcAddress(wlan_api_library_, kWlanGetAvailableNetworkList));
679 WlanGetNetworkBssList_function_ =
680 reinterpret_cast<WlanGetNetworkBssListFunction>(
681 ::GetProcAddress(wlan_api_library_, kWlanGetNetworkBssList));
682 WlanGetProfile_function_ =
683 reinterpret_cast<WlanGetProfileFunction>(
684 ::GetProcAddress(wlan_api_library_, kWlanGetProfile));
685 WlanOpenHandle_function_ =
686 reinterpret_cast<WlanOpenHandleFunction>(
687 ::GetProcAddress(wlan_api_library_, kWlanOpenHandle));
688 WlanRegisterNotification_function_ =
689 reinterpret_cast<WlanRegisterNotificationFunction>(
690 ::GetProcAddress(wlan_api_library_, kWlanRegisterNotification));
691 WlanSaveTemporaryProfile_function_ =
692 reinterpret_cast<WlanSaveTemporaryProfileFunction>(
693 ::GetProcAddress(wlan_api_library_, kWlanSaveTemporaryProfile));
694 WlanScan_function_ =
695 reinterpret_cast<WlanScanFunction>(
696 ::GetProcAddress(wlan_api_library_, kWlanScan));
697
698 if (!WlanConnect_function_ ||
699 !WlanCloseHandle_function_ ||
700 !WlanDisconnect_function_ ||
701 !WlanEnumInterfaces_function_ ||
702 !WlanFreeMemory_function_ ||
703 !WlanGetAvailableNetworkList_function_ ||
704 !WlanGetProfile_function_ ||
705 !WlanOpenHandle_function_ ||
706 !WlanRegisterNotification_function_ ||
707 !WlanScan_function_) {
708 DLOG(ERROR) << "Unable to find required WlanApi function.";
709 FreeLibrary(wlan_api_library_);
710 wlan_api_library_ = NULL;
711 return ERROR_NOT_FOUND;
712 }
713
714 // Some WlanApi functions may not be available on XP.
715 if (!WlanGetNetworkBssList_function_ ||
716 !WlanSaveTemporaryProfile_function_) {
717 DLOG(INFO) << "WlanApi function is not be available on XP.";
718 }
719
720 return ERROR_SUCCESS;
721 }
722
723 DWORD WiFiServiceImpl::OpenClientHandle() {
724 DWORD error = LoadWlanLibrary();
725 DWORD service_version = 0;
726
727 if (error != ERROR_SUCCESS)
728 return error;
729
730 // Open a handle to the service.
731 error = WlanOpenHandle_function_(1, NULL, &service_version, &client_);
732
733 PWLAN_INTERFACE_INFO_LIST interface_list = NULL;
734 if (error == ERROR_SUCCESS) {
735 // Enumerate wireless interfaces.
736 error = WlanEnumInterfaces_function_(client_, NULL, &interface_list);
737 if (error == ERROR_SUCCESS) {
738 if (interface_list != NULL && interface_list->dwNumberOfItems != 0) {
739 // Remember first interface just in case if none are connected.
740 interface_guid_ = interface_list->InterfaceInfo[0].InterfaceGuid;
741 // Try to find a connected interface.
742 for (DWORD itf = 0; itf < interface_list->dwNumberOfItems; ++itf) {
743 if (interface_list->InterfaceInfo[itf].isState ==
744 wlan_interface_state_connected) {
745 // Found connected interface, remember it!
746 interface_guid_ = interface_list->InterfaceInfo[itf].InterfaceGuid;
747 break;
748 }
749 }
750 WlanRegisterNotification_function_(client_,
751 WLAN_NOTIFICATION_SOURCE_ALL,
752 FALSE,
753 OnWlanNotificationCallback,
754 this,
755 NULL,
756 NULL);
757 } else {
758 error = ERROR_NOINTERFACE;
759 }
760 }
761 // Clean up.
762 if (interface_list != NULL)
763 WlanFreeMemory_function_(interface_list);
764 }
765 return error;
766 }
767
768 DWORD WiFiServiceImpl::ResetDHCP() {
769 IP_ADAPTER_INDEX_MAP adapter_index_map = {0};
770 DWORD error = FindAdapterIndexMapByGUID(interface_guid_, &adapter_index_map);
771 if (error == ERROR_SUCCESS) {
772 error = ::IpReleaseAddress(&adapter_index_map);
773 if (error == ERROR_SUCCESS) {
774 error = ::IpRenewAddress(&adapter_index_map);
775 }
776 }
777 return error;
778 }
779
780 DWORD WiFiServiceImpl::FindAdapterIndexMapByGUID(
781 const GUID& interface_guid,
782 IP_ADAPTER_INDEX_MAP* adapter_index_map) {
783 string16 guid_string;
784 const int kGUIDSize = 39;
785 ::StringFromGUID2(
786 interface_guid, WriteInto(&guid_string, kGUIDSize), kGUIDSize);
787
788 ULONG buffer_length = 0;
789 DWORD error = ::GetInterfaceInfo(NULL, &buffer_length);
790 if (error == ERROR_INSUFFICIENT_BUFFER) {
791 scoped_ptr<unsigned char[]> buffer(new unsigned char[buffer_length]);
792 IP_INTERFACE_INFO* interface_info =
793 reinterpret_cast<IP_INTERFACE_INFO*>(buffer.get());
794 error = GetInterfaceInfo(interface_info, &buffer_length);
795 if (error == ERROR_SUCCESS) {
796 for (int adapter = 0; adapter < interface_info->NumAdapters; ++adapter) {
797 if (EndsWith(
798 interface_info->Adapter[adapter].Name, guid_string, false)) {
799 *adapter_index_map = interface_info->Adapter[adapter];
800 break;
801 }
802 }
803 }
804 }
805 return error;
806 }
807
808 DWORD WiFiServiceImpl::DisableNwCategoryWizard() {
809 base::win::RegKey nw_category_wizard;
810 DWORD error = nw_category_wizard.Open(HKEY_CURRENT_USER,
811 kNwCategoryWizardRegKey,
812 KEY_READ | KEY_SET_VALUE);
813 if (error == ERROR_SUCCESS) {
814 // Save current value if present.
815 if (nw_category_wizard.HasValue(kNwCategoryWizardRegValue)) {
816 DWORD saved = 0u;
817 error = nw_category_wizard.ReadValueDW(kNwCategoryWizardRegValue,
818 &saved);
819 if (error == ERROR_SUCCESS) {
820 error = nw_category_wizard.WriteValue(kNwCategoryWizardSavedRegValue,
821 saved);
822 }
823 } else {
824 // Mark that temporary value has to be deleted.
825 error = nw_category_wizard.WriteValue(kNwCategoryWizardDeleteRegValue,
826 1u);
827 }
828
829 // Disable network location wizard.
830 error = nw_category_wizard.WriteValue(kNwCategoryWizardRegValue,
831 static_cast<DWORD>(0));
832 }
833
834 return error;
835 }
836
837 DWORD WiFiServiceImpl::RestoreNwCategoryWizard() {
838 base::win::RegKey nw_category_wizard;
839 DWORD error = nw_category_wizard.Open(HKEY_CURRENT_USER,
840 kNwCategoryWizardRegKey,
841 KEY_SET_VALUE);
842 if (error == ERROR_SUCCESS) {
843 // Restore saved value if present.
844 if (nw_category_wizard.HasValue(kNwCategoryWizardSavedRegValue)) {
845 DWORD saved = 0u;
846 error = nw_category_wizard.ReadValueDW(kNwCategoryWizardSavedRegValue,
847 &saved);
848 if (error == ERROR_SUCCESS) {
849 error = nw_category_wizard.WriteValue(kNwCategoryWizardRegValue,
850 saved);
851 error = nw_category_wizard.DeleteValue(kNwCategoryWizardSavedRegValue);
852 }
853 } else if (nw_category_wizard.HasValue(kNwCategoryWizardDeleteRegValue)) {
854 error = nw_category_wizard.DeleteValue(kNwCategoryWizardRegValue);
855 error = nw_category_wizard.DeleteValue(kNwCategoryWizardDeleteRegValue);
856 }
857 }
858
859 return error;
860 }
861
862 DWORD WiFiServiceImpl::EnsureInitialized() {
863 DCHECK(CalledOnValidThread());
864 if (task_runner_ == NULL)
865 task_runner_ = base::MessageLoopProxy::current();
866
867 if (client_ != NULL)
868 return ERROR_SUCCESS;
869 return Initialize() ? ERROR_SUCCESS : ERROR_NOINTERFACE;
870 }
871
872 DWORD WiFiServiceImpl::CloseClientHandle() {
873 DWORD error = ERROR_SUCCESS;
874 if (client_ != NULL) {
875 error = WlanCloseHandle_function_(client_, NULL);
876 client_ = NULL;
877 }
878 if (wlan_api_library_ != NULL) {
879 WlanConnect_function_ = NULL;
880 WlanCloseHandle_function_ = NULL;
881 WlanDisconnect_function_ = NULL;
882 WlanEnumInterfaces_function_ = NULL;
883 WlanFreeMemory_function_ = NULL;
884 WlanGetAvailableNetworkList_function_ = NULL;
885 WlanGetNetworkBssList_function_ = NULL;
886 WlanGetProfile_function_ = NULL;
887 WlanOpenHandle_function_ = NULL;
888 WlanRegisterNotification_function_ = NULL;
889 WlanSaveTemporaryProfile_function_ = NULL;
890 WlanScan_function_ = NULL;
891 ::FreeLibrary(wlan_api_library_);
892 wlan_api_library_ = NULL;
893 }
894 return error;
895 }
896
897 DOT11_SSID WiFiServiceImpl::SSIDFromGUID(
898 const std::string& network_guid) const {
899 DOT11_SSID ssid = {0};
900 if (network_guid.length() <= DOT11_SSID_MAX_LENGTH) {
901 ssid.uSSIDLength = network_guid.length();
902 strncpy(reinterpret_cast<char*>(ssid.ucSSID),
903 network_guid.c_str(),
904 ssid.uSSIDLength);
905 } else {
906 NOTREACHED();
907 }
908 return ssid;
909 }
910
911 std::string WiFiServiceImpl::SecurityFromDot11AuthAlg(
912 DOT11_AUTH_ALGORITHM alg) const {
913 switch (alg) {
914 case DOT11_AUTH_ALGO_RSNA:
915 return onc::wifi::kWPA_EAP;
916 case DOT11_AUTH_ALGO_RSNA_PSK:
917 return onc::wifi::kWPA_PSK;
918 case DOT11_AUTH_ALGO_80211_SHARED_KEY:
919 return onc::wifi::kWEP_PSK;
920 case DOT11_AUTH_ALGO_80211_OPEN:
921 return onc::wifi::kNone;
922 default:
923 return onc::wifi::kWPA_EAP;
924 }
925 }
926
927 void WiFiServiceImpl::NetworkPropertiesFromAvailableNetwork(
928 const WLAN_AVAILABLE_NETWORK& wlan,
929 const WLAN_BSS_LIST& wlan_bss_list,
930 NetworkProperties* properties) {
931 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
932 properties->connection_state = onc::connection_state::kConnected;
933 } else {
934 properties->connection_state = onc::connection_state::kNotConnected;
935 }
936
937 properties->ssid = SSIDFromWLAN(wlan);
938 properties->name = properties->ssid;
939 properties->guid = GUIDFromWLAN(wlan);
940 properties->type = onc::network_type::kWiFi;
941
942 for (size_t bss = 0; bss < wlan_bss_list.dwNumberOfItems; ++bss) {
943 const WLAN_BSS_ENTRY& bss_entry(wlan_bss_list.wlanBssEntries[bss]);
944 if (bss_entry.dot11Ssid.uSSIDLength == wlan.dot11Ssid.uSSIDLength &&
945 0 == memcmp(bss_entry.dot11Ssid.ucSSID,
946 wlan.dot11Ssid.ucSSID,
947 bss_entry.dot11Ssid.uSSIDLength)) {
948 if (bss_entry.ulChCenterFrequency < 3000000)
949 properties->frequency = kFrequency2400;
950 else
951 properties->frequency = kFrequency5000;
952 properties->frequency_list.push_back(properties->frequency);
953 properties->bssid = NetworkProperties::MacAddressAsString(
954 bss_entry.dot11Bssid);
955 }
956 }
957 properties->frequency_list.sort();
958 properties->frequency_list.unique();
959 properties->security =
960 SecurityFromDot11AuthAlg(wlan.dot11DefaultAuthAlgorithm);
961 properties->signal_strength = wlan.wlanSignalQuality;
962 }
963
964 // Get the list of visible wireless networks
965 DWORD WiFiServiceImpl::GetVisibleNetworkList(NetworkList* network_list) {
966 if (client_ == NULL) {
967 NOTREACHED();
968 return ERROR_NOINTERFACE;
969 }
970
971 DWORD error = ERROR_SUCCESS;
972 PWLAN_AVAILABLE_NETWORK_LIST available_network_list = NULL;
973 PWLAN_BSS_LIST bss_list = NULL;
974
975 error = WlanGetAvailableNetworkList_function_(
976 client_,
977 &interface_guid_,
978 WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,
979 NULL,
980 &available_network_list);
981
982 std::set<std::string> network_guids;
983
984 if (error == ERROR_SUCCESS &&
985 available_network_list &&
986 WlanGetNetworkBssList_function_) {
987 // TODO(mef): WlanGetNetworkBssList is not available on XP. If XP support is
988 // needed, then different method of getting BSS (e.g. OID query) will have
989 // to be used.
990 error = WlanGetNetworkBssList_function_(client_,
991 &interface_guid_,
992 NULL,
993 dot11_BSS_type_any,
994 FALSE,
995 NULL,
996 &bss_list);
997 if (error == ERROR_SUCCESS && NULL != bss_list) {
998 for (DWORD i = 0; i < available_network_list->dwNumberOfItems; ++i) {
999 NetworkProperties network_properties;
1000 NetworkPropertiesFromAvailableNetwork(
1001 available_network_list->Network[i],
1002 *bss_list,
1003 &network_properties);
1004 // Check for duplicate network guids.
1005 if (network_guids.count(network_properties.guid)) {
1006 // There should be no difference between properties except for
1007 // |connection_state|, so mark it as |kConnected| if either one is.
1008 if (network_properties.connection_state ==
1009 onc::connection_state::kConnected) {
1010 NetworkList::iterator previous_network_properties =
1011 FindNetwork(*network_list, network_properties.guid);
1012 DCHECK(previous_network_properties != network_list->end());
1013 previous_network_properties->connection_state =
1014 network_properties.connection_state;
1015 }
1016 } else {
1017 network_list->push_back(network_properties);
1018 }
1019 network_guids.insert(network_properties.guid);
1020 }
1021 }
1022 }
1023
1024 // clean up
1025 if (available_network_list != NULL) {
1026 WlanFreeMemory_function_(available_network_list);
1027 }
1028 if (bss_list != NULL) {
1029 WlanFreeMemory_function_(bss_list);
1030 }
1031 return error;
1032 }
1033
1034 // Find currently connected network.
1035 DWORD WiFiServiceImpl::FindConnectedNetwork(
1036 std::string* connected_network_guid) {
1037 if (client_ == NULL) {
1038 NOTREACHED();
1039 return ERROR_NOINTERFACE;
1040 }
1041
1042 DWORD error = ERROR_SUCCESS;
1043 PWLAN_AVAILABLE_NETWORK_LIST available_network_list = NULL;
1044 error = WlanGetAvailableNetworkList_function_(
1045 client_, &interface_guid_, 0, NULL, &available_network_list);
1046
1047 if (error == ERROR_SUCCESS && NULL != available_network_list) {
1048 for (DWORD i = 0; i < available_network_list->dwNumberOfItems; ++i) {
1049 const WLAN_AVAILABLE_NETWORK& wlan = available_network_list->Network[i];
1050 if (wlan.dwFlags & WLAN_AVAILABLE_NETWORK_CONNECTED) {
1051 *connected_network_guid = GUIDFromWLAN(wlan);
1052 break;
1053 }
1054 }
1055 }
1056
1057 // clean up
1058 if (available_network_list != NULL) {
1059 WlanFreeMemory_function_(available_network_list);
1060 }
1061
1062 return error;
1063 }
1064
1065 DWORD WiFiServiceImpl::Connect(const std::string& network_guid) {
1066 if (client_ == NULL) {
1067 NOTREACHED();
1068 return ERROR_NOINTERFACE;
1069 }
1070
1071 DWORD error = ERROR_SUCCESS;
1072 base::string16 profile_name = ProfileNameFromGUID(network_guid);
1073
1074 if (HaveProfile(network_guid)) {
1075 WLAN_CONNECTION_PARAMETERS wlan_params = {
1076 wlan_connection_mode_profile,
1077 profile_name.c_str(),
1078 NULL,
1079 NULL,
1080 dot11_BSS_type_any,
1081 0};
1082 error = WlanConnect_function_(
1083 client_, &interface_guid_, &wlan_params, NULL);
1084 } else {
1085 // TODO(mef): wlan_connection_mode_discovery_unsecure is not available on
1086 // XP. If XP support is needed, then temporary profile will have to be
1087 // created.
1088 DOT11_SSID ssid = SSIDFromGUID(network_guid);
1089 WLAN_CONNECTION_PARAMETERS wlan_params = {
1090 wlan_connection_mode_discovery_unsecure,
1091 NULL,
1092 &ssid,
1093 NULL,
1094 dot11_BSS_type_infrastructure,
1095 0};
1096 error = WlanConnect_function_(
1097 client_, &interface_guid_, &wlan_params, NULL);
1098 }
1099
1100 return error;
1101 }
1102
1103 DWORD WiFiServiceImpl::Disconnect() {
1104 if (client_ == NULL) {
1105 NOTREACHED();
1106 return ERROR_NOINTERFACE;
1107 }
1108
1109 DWORD error = ERROR_SUCCESS;
1110 error = WlanDisconnect_function_(client_, &interface_guid_, NULL);
1111 return error;
1112 }
1113
1114 DWORD WiFiServiceImpl::SaveTempProfile(const std::string& network_guid) {
1115 if (client_ == NULL) {
1116 NOTREACHED();
1117 return ERROR_NOINTERFACE;
1118 }
1119
1120 DWORD error = ERROR_SUCCESS;
1121 base::string16 profile_name = ProfileNameFromGUID(network_guid);
1122 // TODO(mef): WlanSaveTemporaryProfile is not available on XP. If XP support
1123 // is needed, then different method of saving network profile will have to be
1124 // used.
1125 if (WlanSaveTemporaryProfile_function_) {
1126 error = WlanSaveTemporaryProfile_function_(client_,
1127 &interface_guid_,
1128 profile_name.c_str(),
1129 NULL,
1130 WLAN_PROFILE_USER,
1131 true,
1132 NULL);
1133 } else {
1134 error = ERROR_NOT_SUPPORTED;
1135 }
1136 return error;
1137 }
1138
1139 DWORD WiFiServiceImpl::GetProfile(const std::string& network_guid,
1140 std::string* profile_xml) {
1141 if (client_ == NULL) {
1142 NOTREACHED();
1143 return ERROR_NOINTERFACE;
1144 }
1145
1146 DWORD error = ERROR_SUCCESS;
1147 base::string16 profile_name = ProfileNameFromGUID(network_guid);
1148 LPWSTR str_profile_xml = NULL;
1149 error = WlanGetProfile_function_(client_,
1150 &interface_guid_,
1151 profile_name.c_str(),
1152 NULL,
1153 &str_profile_xml,
1154 NULL,
1155 NULL);
1156
1157 if (error == ERROR_SUCCESS && str_profile_xml != NULL) {
1158 *profile_xml = base::UTF16ToUTF8(str_profile_xml);
1159 }
1160 // clean up
1161 if (str_profile_xml != NULL) {
1162 WlanFreeMemory_function_(str_profile_xml);
1163 }
1164
1165 return error;
1166 }
1167
1168 bool WiFiServiceImpl::HaveProfile(const std::string& network_guid) {
1169 DWORD error = ERROR_SUCCESS;
1170 std::string profile_xml;
1171 return GetProfile(network_guid, &profile_xml) == ERROR_SUCCESS;
1172 }
1173
1174 void WiFiServiceImpl::NotifyNetworkListChanged(const NetworkList& networks) {
1175 if (network_list_changed_observer_.is_null())
1176 return;
1177
1178 NetworkGuidList current_networks;
1179 for (NetworkList::const_iterator it = networks.begin();
1180 it != networks.end();
1181 ++it) {
1182 current_networks.push_back(it->guid);
1183 }
1184 network_list_changed_observer_.Run(current_networks);
1185 }
1186
1187 void WiFiServiceImpl::NotifyNetworkChanged(const std::string& network_guid) {
1188 if (enable_notify_network_changed_ && !networks_changed_observer_.is_null()) {
1189 DLOG(INFO) << "NotifyNetworkChanged: " << network_guid;
1190 NetworkGuidList changed_networks(1, network_guid);
1191 networks_changed_observer_.Run(changed_networks);
1192 }
1193 }
1194
1195 WiFiService* WiFiService::CreateService() { return new WiFiServiceImpl(); }
1196
1197 } // namespace wifi
OLDNEW
« no previous file with comments | « chrome/utility/wifi/wifi_service_test.cc ('k') | chrome/utility/wifi/wifi_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698