123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <windows.h>
- #include <dbt.h>
- #include <stddef.h>
- #include <memory>
- #include <string>
- #include <utility>
- #include <vector>
- #include "base/memory/free_deleter.h"
- #include "base/memory/raw_ptr.h"
- #include "base/memory/ref_counted.h"
- #include "base/run_loop.h"
- #include "base/strings/utf_string_conversions.h"
- #include "base/synchronization/waitable_event.h"
- #include "components/storage_monitor/mock_removable_storage_observer.h"
- #include "components/storage_monitor/portable_device_watcher_win.h"
- #include "components/storage_monitor/removable_device_constants.h"
- #include "components/storage_monitor/storage_info.h"
- #include "components/storage_monitor/storage_monitor_win.h"
- #include "components/storage_monitor/test_portable_device_watcher_win.h"
- #include "components/storage_monitor/test_storage_monitor.h"
- #include "components/storage_monitor/test_storage_monitor_win.h"
- #include "components/storage_monitor/test_volume_mount_watcher_win.h"
- #include "components/storage_monitor/volume_mount_watcher_win.h"
- #include "content/public/test/browser_task_environment.h"
- #include "content/public/test/test_utils.h"
- #include "testing/gtest/include/gtest/gtest.h"
- using base::ASCIIToUTF16;
- typedef std::vector<int> DeviceIndices;
- // StorageMonitorWinTest -------------------------------------------------------
- namespace storage_monitor {
- class StorageMonitorWinTest : public testing::Test {
- public:
- StorageMonitorWinTest();
- StorageMonitorWinTest(const StorageMonitorWinTest&) = delete;
- StorageMonitorWinTest& operator=(const StorageMonitorWinTest&) = delete;
- ~StorageMonitorWinTest() override;
- protected:
- // testing::Test:
- void SetUp() override;
- void TearDown() override;
- void PreAttachDevices();
- void DoMassStorageDeviceAttachedTest(const DeviceIndices& device_indices);
- void DoMassStorageDevicesDetachedTest(const DeviceIndices& device_indices);
- // Injects a device attach or detach change (depending on the value of
- // |test_attach|) and tests that the appropriate handler is called.
- void DoMTPDeviceTest(const std::wstring& pnp_device_id, bool test_attach);
- // Gets the MTP details of the storage specified by the |storage_device_id|.
- // On success, returns true and fills in |pnp_device_id| and
- // |storage_object_id|.
- bool GetMTPStorageInfo(const std::string& storage_device_id,
- std::wstring* pnp_device_id,
- std::wstring* storage_object_id);
- std::unique_ptr<TestStorageMonitorWin> monitor_;
- // Weak pointer; owned by the device notifications class.
- raw_ptr<TestVolumeMountWatcherWin> volume_mount_watcher_;
- MockRemovableStorageObserver observer_;
- private:
- content::BrowserTaskEnvironment task_environment_;
- };
- StorageMonitorWinTest::StorageMonitorWinTest() {
- }
- StorageMonitorWinTest::~StorageMonitorWinTest() {
- }
- void StorageMonitorWinTest::SetUp() {
- auto volume_mount_watcher = std::make_unique<TestVolumeMountWatcherWin>();
- volume_mount_watcher_ = volume_mount_watcher.get();
- monitor_ = std::make_unique<TestStorageMonitorWin>(
- std::move(volume_mount_watcher),
- std::make_unique<TestPortableDeviceWatcherWin>());
- monitor_->Init();
- content::RunAllTasksUntilIdle();
- monitor_->AddObserver(&observer_);
- }
- void StorageMonitorWinTest::TearDown() {
- content::RunAllTasksUntilIdle();
- monitor_->RemoveObserver(&observer_);
- // Windows storage monitor must be destroyed on the same thread
- // as construction.
- monitor_.reset();
- }
- void StorageMonitorWinTest::PreAttachDevices() {
- monitor_.reset();
- auto volume_mount_watcher = std::make_unique<TestVolumeMountWatcherWin>();
- volume_mount_watcher_ = volume_mount_watcher.get();
- volume_mount_watcher_->SetAttachedDevicesFake();
- int expect_attach_calls = 0;
- std::vector<base::FilePath> initial_devices =
- volume_mount_watcher_->GetAttachedDevicesCallback().Run();
- for (std::vector<base::FilePath>::const_iterator it = initial_devices.begin();
- it != initial_devices.end(); ++it) {
- bool removable;
- ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable(*it, &removable));
- if (removable)
- expect_attach_calls++;
- }
- monitor_ = std::make_unique<TestStorageMonitorWin>(
- std::move(volume_mount_watcher),
- std::make_unique<TestPortableDeviceWatcherWin>());
- monitor_->AddObserver(&observer_);
- monitor_->Init();
- EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
- content::RunAllTasksUntilIdle();
- std::vector<base::FilePath> checked_devices =
- volume_mount_watcher_->devices_checked();
- sort(checked_devices.begin(), checked_devices.end());
- EXPECT_EQ(initial_devices, checked_devices);
- EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
- EXPECT_EQ(0, observer_.detach_calls());
- }
- void StorageMonitorWinTest::DoMassStorageDeviceAttachedTest(
- const DeviceIndices& device_indices) {
- DEV_BROADCAST_VOLUME volume_broadcast;
- volume_broadcast.dbcv_size = sizeof(volume_broadcast);
- volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
- volume_broadcast.dbcv_unitmask = 0x0;
- volume_broadcast.dbcv_flags = 0x0;
- int expect_attach_calls = observer_.attach_calls();
- for (DeviceIndices::const_iterator it = device_indices.begin();
- it != device_indices.end(); ++it) {
- volume_broadcast.dbcv_unitmask |= 0x1 << *it;
- bool removable;
- ASSERT_TRUE(volume_mount_watcher_->GetDeviceRemovable(
- VolumeMountWatcherWin::DriveNumberToFilePath(*it), &removable));
- if (removable)
- expect_attach_calls++;
- }
- monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
- reinterpret_cast<LPARAM>(&volume_broadcast));
- content::RunAllTasksUntilIdle();
- EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
- EXPECT_EQ(0, observer_.detach_calls());
- }
- void StorageMonitorWinTest::DoMassStorageDevicesDetachedTest(
- const DeviceIndices& device_indices) {
- DEV_BROADCAST_VOLUME volume_broadcast;
- volume_broadcast.dbcv_size = sizeof(volume_broadcast);
- volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
- volume_broadcast.dbcv_unitmask = 0x0;
- volume_broadcast.dbcv_flags = 0x0;
- int pre_attach_calls = observer_.attach_calls();
- int expect_detach_calls = 0;
- for (DeviceIndices::const_iterator it = device_indices.begin();
- it != device_indices.end(); ++it) {
- volume_broadcast.dbcv_unitmask |= 0x1 << *it;
- StorageInfo info;
- ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(
- VolumeMountWatcherWin::DriveNumberToFilePath(*it), &info));
- if (StorageInfo::IsRemovableDevice(info.device_id()))
- ++expect_detach_calls;
- }
- monitor_->InjectDeviceChange(DBT_DEVICEREMOVECOMPLETE,
- reinterpret_cast<LPARAM>(&volume_broadcast));
- content::RunAllTasksUntilIdle();
- EXPECT_EQ(pre_attach_calls, observer_.attach_calls());
- EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
- }
- void StorageMonitorWinTest::DoMTPDeviceTest(const std::wstring& pnp_device_id,
- bool test_attach) {
- GUID guidDevInterface = GUID_NULL;
- HRESULT hr = CLSIDFromString(kWPDDevInterfaceGUID, &guidDevInterface);
- if (FAILED(hr))
- return;
- size_t device_id_size = pnp_device_id.size() * sizeof(wchar_t);
- size_t size = sizeof(DEV_BROADCAST_DEVICEINTERFACE) + device_id_size;
- std::unique_ptr<DEV_BROADCAST_DEVICEINTERFACE, base::FreeDeleter>
- dev_interface_broadcast(
- static_cast<DEV_BROADCAST_DEVICEINTERFACE*>(malloc(size)));
- DCHECK(dev_interface_broadcast);
- ZeroMemory(dev_interface_broadcast.get(), size);
- dev_interface_broadcast->dbcc_size = size;
- dev_interface_broadcast->dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
- dev_interface_broadcast->dbcc_classguid = guidDevInterface;
- memcpy(dev_interface_broadcast->dbcc_name, pnp_device_id.data(),
- device_id_size);
- int expect_attach_calls = observer_.attach_calls();
- int expect_detach_calls = observer_.detach_calls();
- PortableDeviceWatcherWin::StorageObjectIDs storage_object_ids =
- TestPortableDeviceWatcherWin::GetMTPStorageObjectIds(pnp_device_id);
- for (PortableDeviceWatcherWin::StorageObjectIDs::const_iterator it =
- storage_object_ids.begin(); it != storage_object_ids.end(); ++it) {
- std::string unique_id;
- std::wstring name;
- std::wstring location;
- TestPortableDeviceWatcherWin::GetMTPStorageDetails(pnp_device_id, *it,
- &location, &unique_id,
- &name);
- if (test_attach && !name.empty() && !unique_id.empty())
- expect_attach_calls++;
- else if (!name.empty() && !unique_id.empty())
- expect_detach_calls++;
- }
- monitor_->InjectDeviceChange(
- test_attach ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
- reinterpret_cast<LPARAM>(dev_interface_broadcast.get()));
- content::RunAllTasksUntilIdle();
- EXPECT_EQ(expect_attach_calls, observer_.attach_calls());
- EXPECT_EQ(expect_detach_calls, observer_.detach_calls());
- }
- bool StorageMonitorWinTest::GetMTPStorageInfo(
- const std::string& storage_device_id,
- std::wstring* pnp_device_id,
- std::wstring* storage_object_id) {
- return monitor_->GetMTPStorageInfoFromDeviceId(
- storage_device_id, pnp_device_id, storage_object_id);
- }
- TEST_F(StorageMonitorWinTest, RandomMessage) {
- monitor_->InjectDeviceChange(DBT_DEVICEQUERYREMOVE, NULL);
- content::RunAllTasksUntilIdle();
- }
- TEST_F(StorageMonitorWinTest, DevicesAttached) {
- DeviceIndices device_indices;
- device_indices.push_back(1); // B
- device_indices.push_back(5); // F
- device_indices.push_back(7); // H
- device_indices.push_back(13); // N
- DoMassStorageDeviceAttachedTest(device_indices);
- StorageInfo info;
- EXPECT_TRUE(monitor_->volume_mount_watcher()->GetDeviceInfo(
- base::FilePath(FILE_PATH_LITERAL("F:\\")), &info));
- EXPECT_EQ(L"F:\\", info.location());
- EXPECT_EQ("dcim:\\\\?\\Volume{F0000000-0000-0000-0000-000000000000}\\",
- info.device_id());
- EXPECT_EQ(u"F:\\ Drive", info.storage_label());
- EXPECT_FALSE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("G:\\")), &info));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\")), &info));
- StorageInfo info1;
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\subdir")), &info1));
- StorageInfo info2;
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\subdir\\sub")), &info2));
- EXPECT_EQ(u"F:\\ Drive", info.storage_label());
- EXPECT_EQ(u"F:\\ Drive", info1.storage_label());
- EXPECT_EQ(u"F:\\ Drive", info2.storage_label());
- }
- TEST_F(StorageMonitorWinTest, PathMountDevices) {
- PreAttachDevices();
- size_t init_storages = monitor_->GetAllAvailableStorages().size();
- volume_mount_watcher_->AddDeviceForTesting(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1")), "dcim:mount1", u"mount1",
- 100);
- volume_mount_watcher_->AddDeviceForTesting(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir")),
- "dcim:mount1subdir", u"mount1subdir", 100);
- volume_mount_watcher_->AddDeviceForTesting(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount2")), "dcim:mount2", u"mount2",
- 100);
- content::RunAllTasksUntilIdle();
- EXPECT_EQ(init_storages + 3, monitor_->GetAllAvailableStorages().size());
- StorageInfo info;
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\dir")), &info));
- EXPECT_EQ(u"F:\\ Drive", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1")), &info));
- EXPECT_EQ(u"mount1", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\dir")), &info));
- EXPECT_EQ(u"mount1", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount2\\dir")), &info));
- EXPECT_EQ(u"mount2", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir")), &info));
- EXPECT_EQ(u"mount1subdir", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir\\dir")), &info));
- EXPECT_EQ(u"mount1subdir", info.GetDisplayName(false));
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(
- base::FilePath(FILE_PATH_LITERAL("F:\\mount1\\subdir\\dir\\dir")),
- &info));
- EXPECT_EQ(u"mount1subdir", info.GetDisplayName(false));
- }
- TEST_F(StorageMonitorWinTest, DevicesAttachedHighBoundary) {
- DeviceIndices device_indices;
- device_indices.push_back(25);
- DoMassStorageDeviceAttachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesAttachedLowBoundary) {
- DeviceIndices device_indices;
- device_indices.push_back(0);
- DoMassStorageDeviceAttachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesAttachedAdjacentBits) {
- DeviceIndices device_indices;
- device_indices.push_back(0);
- device_indices.push_back(1);
- device_indices.push_back(2);
- device_indices.push_back(3);
- DoMassStorageDeviceAttachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesDetached) {
- PreAttachDevices();
- DeviceIndices device_indices;
- device_indices.push_back(1);
- device_indices.push_back(5);
- device_indices.push_back(7);
- device_indices.push_back(13);
- DoMassStorageDevicesDetachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesDetachedHighBoundary) {
- PreAttachDevices();
- DeviceIndices device_indices;
- device_indices.push_back(25);
- DoMassStorageDevicesDetachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesDetachedLowBoundary) {
- PreAttachDevices();
- DeviceIndices device_indices;
- device_indices.push_back(0);
- DoMassStorageDevicesDetachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DevicesDetachedAdjacentBits) {
- PreAttachDevices();
- DeviceIndices device_indices;
- device_indices.push_back(0);
- device_indices.push_back(1);
- device_indices.push_back(2);
- device_indices.push_back(3);
- DoMassStorageDevicesDetachedTest(device_indices);
- }
- TEST_F(StorageMonitorWinTest, DuplicateAttachCheckSuppressed) {
- // Make sure the original C: mount notification makes it all the
- // way through.
- content::RunAllTasksUntilIdle();
- volume_mount_watcher_->BlockDeviceCheckForTesting();
- base::FilePath kAttachedDevicePath =
- VolumeMountWatcherWin::DriveNumberToFilePath(8); // I:
- DEV_BROADCAST_VOLUME volume_broadcast;
- volume_broadcast.dbcv_size = sizeof(volume_broadcast);
- volume_broadcast.dbcv_devicetype = DBT_DEVTYP_VOLUME;
- volume_broadcast.dbcv_flags = 0x0;
- volume_broadcast.dbcv_unitmask = 0x100; // I: drive
- monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
- reinterpret_cast<LPARAM>(&volume_broadcast));
- EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
- // Re-attach the same volume. We haven't released the mock device check
- // event, so there'll be pending calls in the UI thread to finish the
- // device check notification, blocking the duplicate device injection.
- monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
- reinterpret_cast<LPARAM>(&volume_broadcast));
- EXPECT_EQ(0u, volume_mount_watcher_->devices_checked().size());
- volume_mount_watcher_->ReleaseDeviceCheck();
- content::RunAllTasksUntilIdle();
- volume_mount_watcher_->ReleaseDeviceCheck();
- // Now let all attach notifications finish running. We'll only get one
- // finish-attach call.
- content::RunAllTasksUntilIdle();
- const std::vector<base::FilePath>& checked_devices =
- volume_mount_watcher_->devices_checked();
- ASSERT_EQ(1u, checked_devices.size());
- EXPECT_EQ(kAttachedDevicePath, checked_devices[0]);
- // We'll receive a duplicate check now that the first check has fully cleared.
- monitor_->InjectDeviceChange(DBT_DEVICEARRIVAL,
- reinterpret_cast<LPARAM>(&volume_broadcast));
- content::RunAllTasksUntilIdle();
- volume_mount_watcher_->ReleaseDeviceCheck();
- content::RunAllTasksUntilIdle();
- ASSERT_EQ(2u, checked_devices.size());
- EXPECT_EQ(kAttachedDevicePath, checked_devices[0]);
- EXPECT_EQ(kAttachedDevicePath, checked_devices[1]);
- }
- TEST_F(StorageMonitorWinTest, DeviceInfoForPath) {
- PreAttachDevices();
- StorageInfo device_info;
- // An invalid path.
- EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"COM1:\\"),
- &device_info));
- // An unconnected removable device.
- EXPECT_FALSE(monitor_->GetStorageInfoForPath(base::FilePath(L"E:\\"),
- &device_info));
- // A connected removable device.
- base::FilePath removable_device(L"F:\\");
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(removable_device, &device_info));
- StorageInfo info;
- ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(removable_device, &info));
- EXPECT_TRUE(StorageInfo::IsRemovableDevice(info.device_id()));
- EXPECT_EQ(info.device_id(), device_info.device_id());
- EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false));
- EXPECT_EQ(info.location(), device_info.location());
- EXPECT_EQ(1000000u, info.total_size_in_bytes());
- // A fixed device.
- base::FilePath fixed_device(L"N:\\");
- EXPECT_TRUE(monitor_->GetStorageInfoForPath(fixed_device, &device_info));
- ASSERT_TRUE(volume_mount_watcher_->GetDeviceInfo(
- fixed_device, &info));
- EXPECT_FALSE(StorageInfo::IsRemovableDevice(info.device_id()));
- EXPECT_EQ(info.device_id(), device_info.device_id());
- EXPECT_EQ(info.GetDisplayName(false), device_info.GetDisplayName(false));
- EXPECT_EQ(info.location(), device_info.location());
- }
- // Test to verify basic MTP storage attach and detach notifications.
- TEST_F(StorageMonitorWinTest, MTPDeviceBasicAttachDetach) {
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true);
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false);
- }
- // When a MTP storage device with invalid storage label and id is
- // attached/detached, there should not be any device attach/detach
- // notifications.
- TEST_F(StorageMonitorWinTest, MTPDeviceWithInvalidInfo) {
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo,
- true);
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithInvalidInfo,
- false);
- }
- // Attach a device with two data partitions. Verify that attach/detach
- // notifications are sent out for each removable storage.
- TEST_F(StorageMonitorWinTest, MTPDeviceWithMultipleStorageObjects) {
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages,
- true);
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithMultipleStorages,
- false);
- }
- TEST_F(StorageMonitorWinTest, DriveNumberToFilePath) {
- EXPECT_EQ(L"A:\\", VolumeMountWatcherWin::DriveNumberToFilePath(0).value());
- EXPECT_EQ(L"Y:\\", VolumeMountWatcherWin::DriveNumberToFilePath(24).value());
- EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(-1).value());
- EXPECT_EQ(L"", VolumeMountWatcherWin::DriveNumberToFilePath(199).value());
- }
- // Given a MTP storage persistent id, GetMTPStorageInfo() should fetch the
- // device interface path and local storage object identifier.
- TEST_F(StorageMonitorWinTest, GetMTPStorageInfoFromDeviceId) {
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, true);
- PortableDeviceWatcherWin::StorageObjects storage_objects =
- TestPortableDeviceWatcherWin::GetDeviceStorageObjects(
- TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo);
- for (PortableDeviceWatcherWin::StorageObjects::const_iterator it =
- storage_objects.begin();
- it != storage_objects.end(); ++it) {
- std::wstring pnp_device_id;
- std::wstring storage_object_id;
- ASSERT_TRUE(GetMTPStorageInfo(it->object_persistent_id, &pnp_device_id,
- &storage_object_id));
- std::wstring expected(
- TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo);
- EXPECT_EQ(expected, pnp_device_id);
- EXPECT_EQ(it->object_persistent_id,
- TestPortableDeviceWatcherWin::GetMTPStorageUniqueId(
- pnp_device_id, storage_object_id));
- }
- DoMTPDeviceTest(TestPortableDeviceWatcherWin::kMTPDeviceWithValidInfo, false);
- }
- } // namespace storage_monitor
|