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 |