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 "content/browser/system_message_window_win.h" | 5 #include "content/browser/system_message_window_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <dbt.h> | 8 #include <dbt.h> |
9 #include <string> | |
10 | 9 |
11 #include "base/file_path.h" | 10 #include "base/logging.h" |
12 #include "base/sys_string_conversions.h" | |
13 #include "base/system_monitor/system_monitor.h" | 11 #include "base/system_monitor/system_monitor.h" |
14 #include "base/win/wrapped_window_proc.h" | 12 #include "base/win/wrapped_window_proc.h" |
15 | 13 |
16 static const wchar_t* const WindowClassName = L"Chrome_SystemMessageWindow"; | 14 static const wchar_t* const WindowClassName = L"Chrome_SystemMessageWindow"; |
17 | 15 |
18 namespace { | |
19 | 16 |
20 LRESULT GetVolumeName(LPCWSTR drive, | 17 SystemMessageWindowWin::SystemMessageWindowWin() { |
21 LPWSTR volume_name, | |
22 unsigned int volume_name_len) { | |
23 return GetVolumeInformation(drive, volume_name, volume_name_len, NULL, NULL, | |
24 NULL, NULL, 0); | |
25 } | |
26 | |
27 // Returns 0 if the devicetype is not volume. | |
28 DWORD GetVolumeBitMaskFromBroadcastHeader(DWORD data) { | |
29 PDEV_BROADCAST_HDR dev_broadcast_hdr = | |
30 reinterpret_cast<PDEV_BROADCAST_HDR>(data); | |
31 if (dev_broadcast_hdr->dbch_devicetype == DBT_DEVTYP_VOLUME) { | |
32 PDEV_BROADCAST_VOLUME dev_broadcast_volume = | |
33 reinterpret_cast<PDEV_BROADCAST_VOLUME>(dev_broadcast_hdr); | |
34 return dev_broadcast_volume->dbcv_unitmask; | |
35 } | |
36 return 0; | |
37 } | |
38 | |
39 } // namespace | |
40 | |
41 | |
42 SystemMessageWindowWin::SystemMessageWindowWin() | |
43 : volume_name_func_(&GetVolumeName) { | |
44 Init(); | |
45 } | |
46 | |
47 SystemMessageWindowWin::SystemMessageWindowWin(VolumeNameFunc volume_name_func) | |
48 : volume_name_func_(volume_name_func) { | |
49 Init(); | |
50 } | |
51 | |
52 void SystemMessageWindowWin::Init() { | |
53 HINSTANCE hinst = GetModuleHandle(NULL); | 18 HINSTANCE hinst = GetModuleHandle(NULL); |
54 | 19 |
55 WNDCLASSEX wc = {0}; | 20 WNDCLASSEX wc = {0}; |
56 wc.cbSize = sizeof(wc); | 21 wc.cbSize = sizeof(wc); |
57 wc.lpfnWndProc = | 22 wc.lpfnWndProc = |
58 base::win::WrappedWindowProc<&SystemMessageWindowWin::WndProcThunk>; | 23 base::win::WrappedWindowProc<&SystemMessageWindowWin::WndProcThunk>; |
59 wc.hInstance = hinst; | 24 wc.hInstance = hinst; |
60 wc.lpszClassName = WindowClassName; | 25 wc.lpszClassName = WindowClassName; |
61 ATOM clazz = RegisterClassEx(&wc); | 26 ATOM clazz = RegisterClassEx(&wc); |
62 DCHECK(clazz); | 27 DCHECK(clazz); |
63 | 28 |
64 window_ = CreateWindow(WindowClassName, | 29 window_ = CreateWindow(WindowClassName, |
65 0, 0, 0, 0, 0, 0, 0, 0, hinst, 0); | 30 0, 0, 0, 0, 0, 0, 0, 0, hinst, 0); |
66 SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); | 31 SetWindowLongPtr(window_, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this)); |
67 } | 32 } |
68 | 33 |
69 SystemMessageWindowWin::~SystemMessageWindowWin() { | 34 SystemMessageWindowWin::~SystemMessageWindowWin() { |
70 if (window_) { | 35 if (window_) { |
71 DestroyWindow(window_); | 36 DestroyWindow(window_); |
72 UnregisterClass(WindowClassName, GetModuleHandle(NULL)); | 37 UnregisterClass(WindowClassName, GetModuleHandle(NULL)); |
73 } | 38 } |
74 } | 39 } |
75 | 40 |
76 LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, DWORD data) { | 41 LRESULT SystemMessageWindowWin::OnDeviceChange(UINT event_type, DWORD data) { |
77 base::SystemMonitor* monitor = base::SystemMonitor::Get(); | 42 base::SystemMonitor* monitor = base::SystemMonitor::Get(); |
78 switch (event_type) { | 43 switch (event_type) { |
79 case DBT_DEVNODES_CHANGED: | 44 case DBT_DEVNODES_CHANGED: |
80 monitor->ProcessDevicesChanged(); | 45 monitor->ProcessDevicesChanged(); |
81 break; | 46 break; |
82 case DBT_DEVICEARRIVAL: { | |
83 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); | |
84 for (int i = 0; unitmask; ++i, unitmask >>= 1) { | |
85 if (unitmask & 0x01) { | |
86 FilePath::StringType drive(L"_:\\"); | |
87 drive[0] = L'A' + i; | |
88 WCHAR volume_name[MAX_PATH + 1]; | |
89 if ((*volume_name_func_)(drive.c_str(), volume_name, MAX_PATH + 1)) { | |
90 monitor->ProcessMediaDeviceAttached( | |
91 i, base::SysWideToUTF8(volume_name), FilePath(drive)); | |
92 } | |
93 } | |
94 } | |
95 break; | |
96 } | |
97 case DBT_DEVICEREMOVECOMPLETE: { | |
98 DWORD unitmask = GetVolumeBitMaskFromBroadcastHeader(data); | |
99 for (int i = 0; unitmask; ++i, unitmask >>= 1) { | |
100 if (unitmask & 0x01) { | |
101 monitor->ProcessMediaDeviceDetached(i); | |
102 } | |
103 } | |
104 break; | |
105 } | |
106 } | 47 } |
107 return TRUE; | 48 return TRUE; |
108 } | 49 } |
109 | 50 |
110 LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, | 51 LRESULT CALLBACK SystemMessageWindowWin::WndProc(HWND hwnd, UINT message, |
111 WPARAM wparam, LPARAM lparam) { | 52 WPARAM wparam, LPARAM lparam) { |
112 switch (message) { | 53 switch (message) { |
113 case WM_DEVICECHANGE: | 54 case WM_DEVICECHANGE: |
114 return OnDeviceChange(static_cast<UINT>(wparam), | 55 return OnDeviceChange(static_cast<UINT>(wparam), |
115 static_cast<DWORD>(lparam)); | 56 static_cast<DWORD>(lparam)); |
116 default: | 57 default: |
117 break; | 58 break; |
118 } | 59 } |
119 | 60 |
120 return ::DefWindowProc(hwnd, message, wparam, lparam); | 61 return ::DefWindowProc(hwnd, message, wparam, lparam); |
121 } | 62 } |
OLD | NEW |