Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media_gallery/media_device_notifications_window_win.h" | 5 #include "chrome/browser/media_gallery/media_device_notifications_window_win.h" |
| 6 | 6 |
| 7 #include <windows.h> | 7 #include <windows.h> |
| 8 #include <dbt.h> | 8 #include <dbt.h> |
| 9 | 9 #include <ObjBase.h> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 13 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" |
| 14 #include "base/system_monitor/system_monitor.h" | 14 #include "base/system_monitor/system_monitor.h" |
| 15 #include "base/win/wrapped_window_proc.h" | 15 #include "base/win/wrapped_window_proc.h" |
| 16 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" | 16 #include "chrome/browser/media_gallery/media_device_notifications_utils.h" |
| 17 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 18 | 18 |
| 19 using content::BrowserThread; | 19 using content::BrowserThread; |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 const wchar_t WindowClassName[] = L"Chrome_MediaDeviceNotificationWindow"; | 23 const wchar_t WindowClassName[] = L"Chrome_MediaDeviceNotificationWindow"; |
| 24 | 24 |
| 25 // The WPD device interface GUID | |
| 26 const wchar_t WPDDevInterfaceGUID[] = L"{6ac27878-a6fa-4155-ba85-f98f491d4f33}"; | |
| 27 | |
| 25 LRESULT GetVolumeName(LPCWSTR drive, | 28 LRESULT GetVolumeName(LPCWSTR drive, |
| 26 LPWSTR volume_name, | 29 LPWSTR volume_name, |
| 27 unsigned int volume_name_len) { | 30 unsigned int volume_name_len) { |
| 28 return GetVolumeInformation(drive, volume_name, volume_name_len, NULL, NULL, | 31 return GetVolumeInformation(drive, volume_name, volume_name_len, NULL, NULL, |
| 29 NULL, NULL, 0); | 32 NULL, NULL, 0); |
| 30 } | 33 } |
| 31 | 34 |
| 32 // Returns 0 if the devicetype is not volume. | 35 // Returns 0 if the devicetype is not volume. |
| 33 DWORD GetVolumeBitMaskFromBroadcastHeader(DWORD data) { | 36 DWORD GetVolumeBitMaskFromBroadcastHeader(DWORD data) { |
| 34 PDEV_BROADCAST_HDR dev_broadcast_hdr = | 37 PDEV_BROADCAST_HDR dev_broadcast_hdr = |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 | 88 |
| 86 if (atom_) | 89 if (atom_) |
| 87 UnregisterClass(MAKEINTATOM(atom_), instance_); | 90 UnregisterClass(MAKEINTATOM(atom_), instance_); |
| 88 } | 91 } |
| 89 | 92 |
| 90 LRESULT MediaDeviceNotificationsWindowWin::OnDeviceChange(UINT event_type, | 93 LRESULT MediaDeviceNotificationsWindowWin::OnDeviceChange(UINT event_type, |
| 91 DWORD data) { | 94 DWORD data) { |
| 92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 93 switch (event_type) { | 96 switch (event_type) { |
| 94 case DBT_DEVICEARRIVAL: { | 97 case DBT_DEVICEARRIVAL: { |
| 95 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); | 98 PDEV_BROADCAST_HDR dev_broadcast_hdr = |
| 96 for (int i = 0; unitmask; ++i, unitmask >>= 1) { | 99 reinterpret_cast<PDEV_BROADCAST_HDR>(data); |
| 97 if (unitmask & 0x01) { | 100 if (dev_broadcast_hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) { |
| 98 FilePath::StringType drive(L"_:\\"); | 101 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
| 99 drive[0] = L'A' + i; | 102 for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
| 100 WCHAR volume_name[MAX_PATH + 1]; | 103 if (unitmask & 0x01) { |
| 101 if ((*volume_name_func_)(drive.c_str(), volume_name, MAX_PATH + 1)) { | 104 FilePath::StringType drive(L"_:\\"); |
| 102 BrowserThread::PostTask( | 105 drive[0] = L'A' + i; |
| 103 BrowserThread::FILE, FROM_HERE, | 106 WCHAR volume_name[MAX_PATH + 1]; |
| 104 base::Bind(&MediaDeviceNotificationsWindowWin:: | 107 if ((*volume_name_func_)(drive.c_str(), volume_name, MAX_PATH + 1)) { |
| 105 CheckDeviceTypeOnFileThread, this, i, | 108 BrowserThread::PostTask( |
| 106 FilePath::StringType(volume_name), FilePath(drive))); | 109 BrowserThread::FILE, FROM_HERE, |
| 110 base::Bind(&MediaDeviceNotificationsWindowWin:: | |
| 111 CheckDeviceTypeOnFileThread, this, i, | |
| 112 FilePath::StringType(volume_name), FilePath(drive))); | |
| 113 } | |
| 107 } | 114 } |
| 108 } | 115 } |
| 116 } | |
| 117 #if defined(DBT_DEVTYP_DEVICEINTERFACE) | |
| 118 else if (dev_broadcast_hdr != NULL && | |
| 119 dev_broadcast_hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFAC E) { | |
| 120 GUID guidDevInterface = GUID_NULL; | |
| 121 CLSIDFromString(WPDDevInterfaceGUID, &guidDevInterface); | |
| 122 DEV_BROADCAST_DEVICEINTERFACE* pdbi = | |
| 123 reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(data); | |
| 124 if (!IsEqualGUID(pdbi->dbcc_classguid, guidDevInterface)) | |
| 125 return 0; | |
| 126 ProcessMediaDeviceAttachedOnUIThread(1, FilePath::StringType(pdbi->dbcc_ name), FilePath(pdbi->dbcc_name)); | |
| 109 } | 127 } |
| 128 #endif | |
| 110 break; | 129 break; |
| 111 } | 130 } |
| 112 case DBT_DEVICEREMOVECOMPLETE: { | 131 case DBT_DEVICEREMOVECOMPLETE: { |
| 113 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); | 132 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); |
| 114 for (int i = 0; unitmask; ++i, unitmask >>= 1) { | 133 for (int i = 0; unitmask; ++i, unitmask >>= 1) { |
| 115 if (unitmask & 0x01) { | 134 if (unitmask & 0x01) { |
| 116 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | 135 base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
| 117 monitor->ProcessMediaDeviceDetached(i); | 136 monitor->ProcessMediaDeviceDetached(i); |
| 118 } | 137 } |
| 119 } | 138 } |
| 139 // FIX for MTP Device. | |
| 120 break; | 140 break; |
| 121 } | 141 } |
| 122 } | 142 } |
| 123 return TRUE; | 143 return TRUE; |
| 124 } | 144 } |
| 125 | 145 |
| 126 void MediaDeviceNotificationsWindowWin::CheckDeviceTypeOnFileThread( | 146 void MediaDeviceNotificationsWindowWin::CheckDeviceTypeOnFileThread( |
| 127 unsigned int id, | 147 unsigned int id, |
| 128 const FilePath::StringType& device_name, | 148 const FilePath::StringType& device_name, |
| 129 const FilePath& path) { | 149 const FilePath& path) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 | 182 |
| 163 return ::DefWindowProc(hwnd, message, wparam, lparam); | 183 return ::DefWindowProc(hwnd, message, wparam, lparam); |
| 164 } | 184 } |
| 165 | 185 |
| 166 // static | 186 // static |
| 167 LRESULT CALLBACK MediaDeviceNotificationsWindowWin::WndProcThunk( | 187 LRESULT CALLBACK MediaDeviceNotificationsWindowWin::WndProcThunk( |
| 168 HWND hwnd, | 188 HWND hwnd, |
| 169 UINT message, | 189 UINT message, |
| 170 WPARAM wparam, | 190 WPARAM wparam, |
| 171 LPARAM lparam) { | 191 LPARAM lparam) { |
| 192 #if defined(DBT_DEVTYP_DEVICEINTERFACE) && defined(DEVICE_NOTIFY_WINDOW_HANDLE) | |
| 193 if (message == WM_CREATE) { | |
| 194 GUID guidDevInterface = GUID_NULL; | |
| 195 HRESULT hr = CLSIDFromString(WPDDevInterfaceGUID, &guidDevInterface); | |
| 196 if (SUCCEEDED(hr)) { | |
| 197 static HDEVNOTIFY hDeviceNotify; | |
| 198 DEV_BROADCAST_DEVICEINTERFACE db = {0}; | |
| 199 db.dbcc_size = sizeof(db); | |
| 200 db.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; | |
| 201 db.dbcc_classguid = guidDevInterface; | |
| 202 hDeviceNotify = RegisterDeviceNotification(hwnd, &db, DEVICE_NOTIFY_WINDOW _HANDLE); | |
|
kinuko
2012/07/18 10:33:24
nit: over 80 cols (here and elsewhere; maybe you c
| |
| 203 } | |
| 204 } | |
| 205 #endif | |
| 206 | |
| 172 MediaDeviceNotificationsWindowWin* msg_wnd = | 207 MediaDeviceNotificationsWindowWin* msg_wnd = |
| 173 reinterpret_cast<MediaDeviceNotificationsWindowWin*>( | 208 reinterpret_cast<MediaDeviceNotificationsWindowWin*>( |
| 174 GetWindowLongPtr(hwnd, GWLP_USERDATA)); | 209 GetWindowLongPtr(hwnd, GWLP_USERDATA)); |
| 175 if (msg_wnd) | 210 if (msg_wnd) |
| 176 return msg_wnd->WndProc(hwnd, message, wparam, lparam); | 211 return msg_wnd->WndProc(hwnd, message, wparam, lparam); |
| 177 return ::DefWindowProc(hwnd, message, wparam, lparam); | 212 return ::DefWindowProc(hwnd, message, wparam, lparam); |
| 178 } | 213 } |
| 179 | 214 |
| 180 } // namespace chrome | 215 } // namespace chrome |
| OLD | NEW |