15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <windows.h> 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <dbt.h> 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/run_loop.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/mock_removable_storage_observer.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/portable_device_watcher_win.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/removable_device_constants.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/storage_info.h" 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/storage_monitor_win.h" 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/test_portable_device_watcher_win.h" 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/test_storage_monitor.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/test_storage_monitor_win.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/test_volume_mount_watcher_win.h" 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "components/storage_monitor/volume_mount_watcher_win.h" 261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/test/test_browser_thread_bundle.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::ASCIIToUTF16; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using content::BrowserThread; 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)typedef std::vector<int> DeviceIndices; 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// StorageMonitorWinTest ------------------------------------------------------- 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace storage_monitor { 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class StorageMonitorWinTest : public testing::Test { 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageMonitorWinTest(); 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~StorageMonitorWinTest(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // testing::Test: 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void SetUp() OVERRIDE; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void TearDown() OVERRIDE; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void PreAttachDevices(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Runs all the pending tasks on UI thread, FILE thread and blocking thread. 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RunUntilIdle(); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DoMassStorageDeviceAttachedTest(const DeviceIndices& device_indices); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void DoMassStorageDevicesDetachedTest(const DeviceIndices& device_indices); 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Injects a device attach or detach change (depending on the value of 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |test_attach|) and tests that the appropriate handler is called. 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DoMTPDeviceTest(const base::string16& pnp_device_id, bool test_attach); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Gets the MTP details of the storage specified by the |storage_device_id|. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On success, returns true and fills in |pnp_device_id| and 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |storage_object_id|. 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool GetMTPStorageInfo(const std::string& storage_device_id, 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16* pnp_device_id, 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16* storage_object_id); 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<TestStorageMonitorWin> monitor_; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Weak pointer; owned by the device notifications class. 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestVolumeMountWatcherWin* volume_mount_watcher_; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MockRemovableStorageObserver observer_; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) content::TestBrowserThreadBundle thread_bundle_; 771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(StorageMonitorWinTest); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)StorageMonitorWinTest::StorageMonitorWinTest() { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)StorageMonitorWinTest::~StorageMonitorWinTest() { 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::SetUp() { 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_ = new TestVolumeMountWatcherWin; 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_, 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new TestPortableDeviceWatcherWin)); 91ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->Init(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->AddObserver(&observer_); 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::TearDown() { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->RemoveObserver(&observer_); 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->ShutdownWorkerPool(); 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 102ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Windows storage monitor must be destroyed on the same thread 103ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // as construction. 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor_.reset(); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::PreAttachDevices() { 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor_.reset(); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_ = new TestVolumeMountWatcherWin; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->SetAttachedDevicesFake(); 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expect_attach_calls = 0; 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> initial_devices = 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->GetAttachedDevicesCallback().Run(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::vector<base::FilePath>::const_iterator it = initial_devices.begin(); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != initial_devices.end(); ++it) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool removable; 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable(*it, &removable)); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (removable) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expect_attach_calls++; 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) monitor_.reset(new TestStorageMonitorWin(volume_mount_watcher_, 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new TestPortableDeviceWatcherWin)); 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->AddObserver(&observer_); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->Init(); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size()); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This dance is because attachment bounces through a couple of 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // closures, which need to be executed to finish the process. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::FilePath> checked_devices = 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->devices_checked(); 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sort(checked_devices.begin(), checked_devices.end()); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(initial_devices, checked_devices); 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expect_attach_calls, observer_.attach_calls()); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, observer_.detach_calls()); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::RunUntilIdle() { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::RunLoop().RunUntilIdle(); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::DoMassStorageDeviceAttachedTest( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DeviceIndices& device_indices) { 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEV_BROADCAST_VOLUME volume_broadcast; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_size = sizeof(volume_broadcast); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_unitmask = 0x0; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_flags = 0x0; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int expect_attach_calls = observer_.attach_calls(); 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DeviceIndices::const_iterator it = device_indices.begin(); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != device_indices.end(); ++it) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_unitmask |= 0x1 << *it; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool removable; 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable( 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VolumeMountWatcherWin::DriveNumberToFilePath(*it), &removable)); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (removable) 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expect_attach_calls++; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL, 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(&volume_broadcast)); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expect_attach_calls, observer_.attach_calls()); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, observer_.detach_calls()); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void StorageMonitorWinTest::DoMassStorageDevicesDetachedTest( 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const DeviceIndices& device_indices) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEV_BROADCAST_VOLUME volume_broadcast; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_size = sizeof(volume_broadcast); 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_unitmask = 0x0; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_flags = 0x0; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int pre_attach_calls = observer_.attach_calls(); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expect_detach_calls = 0; 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (DeviceIndices::const_iterator it = device_indices.begin(); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != device_indices.end(); ++it) { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_unitmask |= 0x1 << *it; 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageInfo info; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo( 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VolumeMountWatcherWin::DriveNumberToFilePath(*it), &info)); 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StorageInfo::IsRemovableDevice(info.device_id())) 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++expect_detach_calls; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(&volume_broadcast)); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(pre_attach_calls, observer_.attach_calls()); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expect_detach_calls, observer_.detach_calls()); 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void StorageMonitorWinTest::DoMTPDeviceTest(const base::string16& pnp_device_id, 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool test_attach) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GUID guidDevInterface = GUID_NULL; 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HRESULT hr = CLSIDFromString(kWPDDevInterfaceGUID, &guidDevInterface); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FAILED(hr)) 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size_t device_id_size = pnp_device_id.size() * sizeof(base::char16); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t size = sizeof(DEV_BROADCAST_DEVICEINTERFACE) + device_id_size; 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_ptr<DEV_BROADCAST_DEVICEINTERFACE, base::FreeDeleter> 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) dev_interface_broadcast( 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<DEV_BROADCAST_DEVICEINTERFACE*>(malloc(size))); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dev_interface_broadcast.get()); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ZeroMemory(dev_interface_broadcast.get(), size); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_interface_broadcast->dbcc_size = size; 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_interface_broadcast->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dev_interface_broadcast->dbcc_classguid = guidDevInterface; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) memcpy(dev_interface_broadcast->dbcc_name, pnp_device_id.data(), 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_id_size); 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expect_attach_calls = observer_.attach_calls(); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int expect_detach_calls = observer_.detach_calls(); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids = 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPortableDeviceWatcherWin::GetMTPStorageObjectIds(pnp_device_id); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it = 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_object_ids.begin(); it != storage_object_ids.end(); ++it) { 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string unique_id; 232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 name; 233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 location; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPortableDeviceWatcherWin::GetMTPStorageDetails(pnp_device_id, *it, 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &location, &unique_id, 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &name); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (test_attach && !name.empty() && !unique_id.empty()) 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expect_attach_calls++; 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (!name.empty() && !unique_id.empty()) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expect_detach_calls++; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange( 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) test_attach ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE, 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(dev_interface_broadcast.get())); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expect_attach_calls, observer_.attach_calls()); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(expect_detach_calls, observer_.detach_calls()); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool StorageMonitorWinTest::GetMTPStorageInfo( 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& storage_device_id, 254868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16* pnp_device_id, 255868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16* storage_object_id) { 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return monitor_->GetMTPStorageInfoFromDeviceId(storage_device_id, 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pnp_device_id, 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_object_id); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, RandomMessage) { 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesAttached) { 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(1); // B 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(5); // F 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(7); // H 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(13); // N 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDeviceAttachedTest(device_indices); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageInfo info; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->volume_mount_watcher()->GetDeviceInfo( 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\")), &info)); 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("F:\\"), info.location()); 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ("dcim:\\\\?\\Volume{F0000000-0000-0000-0000-000000000000}\\", 27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) info.device_id()); 28090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info.storage_label()); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(monitor_->GetStorageInfoForPath( 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(ASCIIToUTF16("G:\\")), &info)); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\")), &info)); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageInfo info1; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\subdir")), &info1)); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StorageInfo info2; 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\subdir\\sub")), &info2)); 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info.storage_label()); 29390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info1.storage_label()); 29490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(ASCIIToUTF16("F:\\ Drive"), info2.storage_label()); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, PathMountDevices) { 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PreAttachDevices(); 2997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int init_storages = monitor_->GetAllAvailableStorages().size(); 300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) volume_mount_watcher_->AddDeviceForTesting( 302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("F:\\mount1")), 303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "dcim:mount1", L"mount1", 100); 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) volume_mount_watcher_->AddDeviceForTesting( 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir")), 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "dcim:mount1subdir", L"mount1subdir", 100); 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) volume_mount_watcher_->AddDeviceForTesting( 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(FILE_PATH_LITERAL("F:\\mount2")), 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "dcim:mount2", L"mount2", 100); 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RunUntilIdle(); 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EXPECT_EQ(init_storages + 3, monitor_->GetAllAvailableStorages().size()); 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageInfo info; 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\dir")), &info)); 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"F:\\ Drive", info.GetDisplayName(false)); 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount1")), &info)); 319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount1", info.GetDisplayName(false)); 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount1\\dir")), &info)); 322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount1", info.GetDisplayName(false)); 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount2\\dir")), &info)); 325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount2", info.GetDisplayName(false)); 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir")), &info)); 328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false)); 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir\\dir")), &info)); 331a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false)); 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath( 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath(ASCIIToUTF16("F:\\mount1\\subdir\\dir\\dir")), &info)); 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(L"mount1subdir", info.GetDisplayName(false)); 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesAttachedHighBoundary) { 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(25); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDeviceAttachedTest(device_indices); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesAttachedLowBoundary) { 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(0); 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDeviceAttachedTest(device_indices); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesAttachedAdjacentBits) { 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(0); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(1); 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(2); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(3); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDeviceAttachedTest(device_indices); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesDetached) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreAttachDevices(); 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(1); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(5); 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(7); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(13); 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDevicesDetachedTest(device_indices); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesDetachedHighBoundary) { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreAttachDevices(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(25); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDevicesDetachedTest(device_indices); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesDetachedLowBoundary) { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreAttachDevices(); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(0); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDevicesDetachedTest(device_indices); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DevicesDetachedAdjacentBits) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreAttachDevices(); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DeviceIndices device_indices; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(0); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(1); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(2); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) device_indices.push_back(3); 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMassStorageDevicesDetachedTest(device_indices); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) { 404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make sure the original C: mount notification makes it all the 405c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // way through. 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RunUntilIdle(); 407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RunUntilIdle(); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->BlockDeviceCheckForTesting(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath kAttachedDevicePath = 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VolumeMountWatcherWin::DriveNumberToFilePath(8); // I: 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DEV_BROADCAST_VOLUME volume_broadcast; 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_size = sizeof(volume_broadcast); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME; 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_flags = 0x0; 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_broadcast.dbcv_unitmask = 0x100; // I: drive 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL, 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(&volume_broadcast)); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size()); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Re-attach the same volume. We haven't released the mock device check 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // event, so there'll be pending calls in the UI thread to finish the 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // device check notification, blocking the duplicate device injection. 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL, 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(&volume_broadcast)); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size()); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->ReleaseDeviceCheck(); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->ReleaseDeviceCheck(); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Now let all attach notifications finish running. We'll only get one 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // finish-attach call. 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 440868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<base::FilePath>& checked_devices = 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->devices_checked(); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(1u, checked_devices.size()); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kAttachedDevicePath, checked_devices[0]); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We'll receive a duplicate check now that the first check has fully cleared. 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL, 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reinterpret_cast<DWORD>(&volume_broadcast)); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->FlushWorkerPoolForTesting(); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) volume_mount_watcher_->ReleaseDeviceCheck(); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunUntilIdle(); 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_EQ(2u, checked_devices.size()); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kAttachedDevicePath, checked_devices[0]); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(kAttachedDevicePath, checked_devices[1]); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DeviceInfoForPath) { 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PreAttachDevices(); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) StorageInfo device_info; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // An invalid path. 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"COM1:\\"), 46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &device_info)); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // An unconnected removable device. 46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"E:\\"), 46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &device_info)); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A connected removable device. 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath removable_device(L"F:\\"); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath(removable_device, &device_info)); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StorageInfo info; 474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(removable_device, &info)); 47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_TRUE(StorageInfo::IsRemovableDevice(info.device_id())); 47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(info.device_id(), device_info.device_id()); 477a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false)); 47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(info.location(), device_info.location()); 47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(1000000, info.total_size_in_bytes()); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // A fixed device. 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath fixed_device(L"N:\\"); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(monitor_->GetStorageInfoForPath(fixed_device, &device_info)); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo( 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fixed_device, &info)); 48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_FALSE(StorageInfo::IsRemovableDevice(info.device_id())); 48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(info.device_id(), device_info.device_id()); 489a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false)); 49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) EXPECT_EQ(info.location(), device_info.location()); 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test to verify basic MTP storage attach and detach notifications. 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, MTPDeviceBasicAttachDetach) { 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true); 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false); 4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// When a MTP storage device with invalid storage label and id is 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// attached/detached, there should not be any device attach/detach 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// notifications. 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, MTPDeviceWithInvalidInfo) { 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo, 5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true); 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo, 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Attach a device with two data partitions. Verify that attach/detach 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// notifications are sent out for each removable storage. 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, MTPDeviceWithMultipleStorageObjects) { 5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages, 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true); 5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages, 5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) false); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, DriveNumberToFilePath) { 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(L"A:\\", VolumeMountWatcherWin::DriveNumberToFilePath(0).value()); 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(L"Y:\\", VolumeMountWatcherWin::DriveNumberToFilePath(24).value()); 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(-1).value()); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(199).value()); 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Given a MTP storage persistent id, GetMTPStorageInfo() should fetch the 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// device interface path and local storage object identifier. 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(StorageMonitorWinTest, GetMTPStorageInfoFromDeviceId) { 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true); 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PortableDeviceWatcherWin::StorageObjects storage_objects = 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPortableDeviceWatcherWin::GetDeviceStorageObjects( 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo); 5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (PortableDeviceWatcherWin::StorageObjects::const_iterator it = 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) storage_objects.begin(); 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != storage_objects.end(); ++it) { 535868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 pnp_device_id; 536868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 storage_object_id; 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(GetMTPStorageInfo(it->object_persistent_id, &pnp_device_id, 5382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &storage_object_id)); 539868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::string16 expected( 540868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo); 541868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_EQ(expected, pnp_device_id); 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(it->object_persistent_id, 5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPortableDeviceWatcherWin::GetMTPStorageUniqueId( 5442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pnp_device_id, storage_object_id)); 5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false); 5472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 548a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 549a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace storage_monitor 550