Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / storage_monitor / storage_monitor_win.cc
index fb721bb..95a6911 100644 (file)
@@ -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, &notify_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());