Index: components/storage_monitor/storage_monitor_win.cc |
diff --git a/components/storage_monitor/storage_monitor_win.cc b/components/storage_monitor/storage_monitor_win.cc |
index fb721bb3284826999bde409d67109cff8699cb6b..95a6911552d83a20827bdd9bb29a876131652fc7 100644 |
--- a/components/storage_monitor/storage_monitor_win.cc |
+++ b/components/storage_monitor/storage_monitor_win.cc |
@@ -7,6 +7,7 @@ |
#include <windows.h> |
#include <dbt.h> |
#include <fileapi.h> |
+#include <shlobj.h> |
#include "base/win/wrapped_window_proc.h" |
#include "components/storage_monitor/portable_device_watcher_win.h" |
@@ -14,6 +15,8 @@ |
#include "components/storage_monitor/storage_info.h" |
#include "components/storage_monitor/volume_mount_watcher_win.h" |
+#define WM_USER_MEDIACHANGED (WM_USER + 5) |
+ |
// StorageMonitorWin ------------------------------------------------------- |
namespace storage_monitor { |
@@ -24,6 +27,7 @@ StorageMonitorWin::StorageMonitorWin( |
: window_class_(0), |
instance_(NULL), |
window_(NULL), |
+ shell_change_notify_id_(0), |
volume_mount_watcher_(volume_mount_watcher), |
portable_device_watcher_(portable_device_watcher) { |
DCHECK(volume_mount_watcher_); |
@@ -33,6 +37,8 @@ StorageMonitorWin::StorageMonitorWin( |
} |
StorageMonitorWin::~StorageMonitorWin() { |
+ if (shell_change_notify_id_) |
+ SHChangeNotifyDeregister(shell_change_notify_id_); |
volume_mount_watcher_->SetNotifications(NULL); |
portable_device_watcher_->SetNotifications(NULL); |
@@ -59,6 +65,7 @@ void StorageMonitorWin::Init() { |
SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); |
volume_mount_watcher_->Init(); |
portable_device_watcher_->Init(window_); |
+ MediaChangeNotificationRegister(); |
} |
bool StorageMonitorWin::GetStorageInfoForPath(const base::FilePath& path, |
@@ -138,6 +145,9 @@ LRESULT CALLBACK StorageMonitorWin::WndProc(HWND hwnd, UINT message, |
case WM_DEVICECHANGE: |
OnDeviceChange(static_cast<UINT>(wparam), lparam); |
return TRUE; |
+ case WM_USER_MEDIACHANGED: |
+ OnMediaChange(wparam, lparam); |
+ return TRUE; |
default: |
break; |
} |
@@ -145,6 +155,22 @@ LRESULT CALLBACK StorageMonitorWin::WndProc(HWND hwnd, UINT message, |
return ::DefWindowProc(hwnd, message, wparam, lparam); |
} |
+void StorageMonitorWin::MediaChangeNotificationRegister() { |
+ LPITEMIDLIST id_list; |
+ if (SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &id_list) == NOERROR) { |
+ SHChangeNotifyEntry notify_entry; |
+ notify_entry.pidl = id_list; |
+ notify_entry.fRecursive = TRUE; |
+ shell_change_notify_id_ = SHChangeNotifyRegister( |
+ window_, SHCNRF_ShellLevel, SHCNE_MEDIAINSERTED | SHCNE_MEDIAREMOVED, |
+ WM_USER_MEDIACHANGED, 1, ¬ify_entry); |
+ if (!shell_change_notify_id_) |
+ DVLOG(1) << "SHChangeNotifyRegister FAILED"; |
+ } else { |
+ DVLOG(1) << "SHGetSpecialFolderLocation FAILED"; |
+ } |
+} |
+ |
bool StorageMonitorWin::GetDeviceInfo(const base::FilePath& device_path, |
StorageInfo* info) const { |
DCHECK(info); |
@@ -156,10 +182,15 @@ bool StorageMonitorWin::GetDeviceInfo(const base::FilePath& device_path, |
} |
void StorageMonitorWin::OnDeviceChange(UINT event_type, LPARAM data) { |
+ DVLOG(1) << "OnDeviceChange " << event_type << " " << data; |
volume_mount_watcher_->OnWindowMessage(event_type, data); |
portable_device_watcher_->OnWindowMessage(event_type, data); |
} |
+void StorageMonitorWin::OnMediaChange(WPARAM wparam, LPARAM lparam) { |
+ volume_mount_watcher_->OnMediaChange(wparam, lparam); |
+} |
+ |
StorageMonitor* StorageMonitor::CreateInternal() { |
return new StorageMonitorWin(new VolumeMountWatcherWin(), |
new PortableDeviceWatcherWin()); |