Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: media/midi/midi_manager_winrt.cc

Issue 2318953002: Replace Setup API with PnP Configuration Manager in MidiManagerWinrt (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« media/midi/BUILD.gn ('K') | « media/midi/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "media/midi/midi_manager_winrt.h" 5 #include "media/midi/midi_manager_winrt.h"
6 6
7 // TODO(shaochuan): Remove this once clang supports uuid syntax in <robuffer.h>. 7 // TODO(shaochuan): Remove this once clang supports uuid syntax in <robuffer.h>.
8 // https://reviews.llvm.org/D23895 8 // https://reviews.llvm.org/D23895
9 namespace Windows { 9 namespace Windows {
10 namespace Storage { 10 namespace Storage {
11 namespace Streams { 11 namespace Streams {
12 #pragma warning(disable : 4467) 12 #pragma warning(disable : 4467)
13 struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da")) 13 struct __declspec(uuid("905a0fef-bc53-11df-8c49-001e4fc686da"))
14 IBufferByteAccess; 14 IBufferByteAccess;
15 } 15 }
16 } 16 }
17 } 17 }
18 18
19 #include <initguid.h> // Required by <devpkey.h>
20
21 #include <cfgmgr32.h>
19 #include <comdef.h> 22 #include <comdef.h>
23 #include <devpkey.h>
20 #include <robuffer.h> 24 #include <robuffer.h>
21 #include <setupapi.h>
22 #include <windows.devices.enumeration.h> 25 #include <windows.devices.enumeration.h>
23 #include <windows.devices.midi.h> 26 #include <windows.devices.midi.h>
24 #include <wrl/event.h> 27 #include <wrl/event.h>
25 28
26 #include <iomanip> 29 #include <iomanip>
27 #include <unordered_map> 30 #include <unordered_map>
28 #include <unordered_set> 31 #include <unordered_set>
29 32
30 #include "base/bind.h" 33 #include "base/bind.h"
31 #include "base/lazy_instance.h" 34 #include "base/lazy_instance.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 bool IsMicrosoftSynthesizer(IDeviceInformation* info) { 259 bool IsMicrosoftSynthesizer(IDeviceInformation* info) {
257 auto midi_synthesizer_statics = 260 auto midi_synthesizer_statics =
258 WrlStaticsFactory<IMidiSynthesizerStatics, 261 WrlStaticsFactory<IMidiSynthesizerStatics,
259 RuntimeClass_Windows_Devices_Midi_MidiSynthesizer>(); 262 RuntimeClass_Windows_Devices_Midi_MidiSynthesizer>();
260 boolean result = FALSE; 263 boolean result = FALSE;
261 HRESULT hr = midi_synthesizer_statics->IsSynthesizer(info, &result); 264 HRESULT hr = midi_synthesizer_statics->IsSynthesizer(info, &result);
262 VLOG_IF(1, FAILED(hr)) << "IsSynthesizer failed: " << PrintHr(hr); 265 VLOG_IF(1, FAILED(hr)) << "IsSynthesizer failed: " << PrintHr(hr);
263 return result != FALSE; 266 return result != FALSE;
264 } 267 }
265 268
266 class ScopedDeviceInfoListTraits { 269 // This is the maximum string length in driver INF files.
Takashi Toyoshima 2016/09/07 09:22:34 If you know an official document about this magic
Shao-Chuan Lee 2016/09/08 06:23:30 Now retrieving buffer size from CM_Get_DevNode_Pro
267 public: 270 const size_t kMaxDevicePropertyLength = 4096;
268 static HDEVINFO InvalidValue() { return INVALID_HANDLE_VALUE; }
269
270 static void Free(HDEVINFO devinfo_set) {
271 SetupDiDestroyDeviceInfoList(devinfo_set);
272 }
273 };
274
275 using ScopedDeviceInfoList =
276 base::ScopedGeneric<HDEVINFO, ScopedDeviceInfoListTraits>;
277 271
278 // Retrieves manufacturer (provider) and version information of underlying 272 // Retrieves manufacturer (provider) and version information of underlying
279 // device driver using Setup API, given device (interface) ID provided by WinRT. 273 // device driver through PnP Configuration Manager, given device (interface) ID
280 // |out_manufacturer| and |out_driver_version| won't be modified if retrieval 274 // provided by WinRT. |out_manufacturer| and |out_driver_version| won't be
281 // fails. Note that SetupDiBuildDriverInfoList() would block for a few hundred 275 // modified if retrieval fails.
282 // milliseconds so consider calling this function in an asynchronous manner.
283 // 276 //
284 // Device instance ID is extracted from device (interface) ID provided by WinRT 277 // Device instance ID is extracted from device (interface) ID provided by WinRT
285 // APIs, for example from the following interface ID: 278 // APIs, for example from the following interface ID:
286 // \\?\SWD#MMDEVAPI#MIDII_60F39FCA.P_0002#{504be32c-ccf6-4d2c-b73f-6f8b3747e22b} 279 // \\?\SWD#MMDEVAPI#MIDII_60F39FCA.P_0002#{504be32c-ccf6-4d2c-b73f-6f8b3747e22b}
287 // we extract the device instance ID: SWD\MMDEVAPI\MIDII_60F39FCA.P_0002 280 // we extract the device instance ID: SWD\MMDEVAPI\MIDII_60F39FCA.P_0002
281 //
282 // However the extracted device instance ID represent a "software device"
283 // provided by Microsoft, which is an interface on top of the hardware for each
284 // input/output port. Therefore we further locate its parent device, which is
285 // the actual hardware device, for driver information.
288 void GetDriverInfoFromDeviceId(const std::string& dev_id, 286 void GetDriverInfoFromDeviceId(const std::string& dev_id,
289 std::string* out_manufacturer, 287 std::string* out_manufacturer,
290 std::string* out_driver_version) { 288 std::string* out_driver_version) {
291 base::string16 dev_instance_id = 289 base::string16 dev_instance_id =
292 base::UTF8ToWide(dev_id.substr(4, dev_id.size() - 43)); 290 base::UTF8ToWide(dev_id.substr(4, dev_id.size() - 43));
293 base::ReplaceChars(dev_instance_id, L"#", L"\\", &dev_instance_id); 291 base::ReplaceChars(dev_instance_id, L"#", L"\\", &dev_instance_id);
294 292
295 ScopedDeviceInfoList devinfo_list( 293 DEVINST dev_instance_handle;
296 SetupDiCreateDeviceInfoList(nullptr, nullptr)); 294 CONFIGRET cr = CM_Locate_DevNode(&dev_instance_handle, &dev_instance_id[0],
297 if (!devinfo_list.is_valid()) { 295 CM_LOCATE_DEVNODE_NORMAL);
298 VLOG(1) << "SetupDiCreateDeviceInfoList failed: " 296 if (cr != CR_SUCCESS) {
299 << PrintHr(HRESULT_FROM_WIN32(GetLastError())); 297 VLOG(1) << "CM_Locate_DevNode failed: CONFIGRET 0x" << std::hex << cr;
Takashi Toyoshima 2016/09/07 09:22:34 Hum.... another kind of error code again :/ CM_Map
Shao-Chuan Lee 2016/09/08 06:23:30 Tried this and found only a few error codes are ma
Takashi Toyoshima 2016/09/09 05:17:41 So could you left what you tried and why you do li
Shao-Chuan Lee 2016/09/09 05:44:47 Done.
300 return; 298 return;
301 } 299 }
302 300
303 SP_DEVINFO_DATA devinfo_data = {0}; 301 DEVINST parent_handle;
304 devinfo_data.cbSize = sizeof(SP_DEVINFO_DATA); 302 cr = CM_Get_Parent(&parent_handle, dev_instance_handle, 0);
305 SP_DRVINFO_DATA drvinfo_data = {0}; 303 if (cr != CR_SUCCESS) {
306 drvinfo_data.cbSize = sizeof(SP_DRVINFO_DATA); 304 VLOG(1) << "CM_Get_Parent failed: CONFIGRET 0x" << std::hex << cr;
307
308 if (!SetupDiOpenDeviceInfo(devinfo_list.get(), dev_instance_id.c_str(),
309 nullptr, 0, &devinfo_data)) {
310 VLOG(1) << "SetupDiOpenDeviceInfo failed: "
311 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
312 return; 305 return;
313 } 306 }
314 307
315 if (!SetupDiBuildDriverInfoList(devinfo_list.get(), &devinfo_data, 308 DEVPROPTYPE devprop_type;
316 SPDIT_COMPATDRIVER)) { 309 base::char16 buffer[kMaxDevicePropertyLength];
317 VLOG(1) << "SetupDiBuildDriverInfoList failed: " 310 unsigned long buffer_size = sizeof(buffer);
318 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
319 return;
320 }
321 311
322 // Assume only one entry in driver info list. 312 cr = CM_Get_DevNode_Property(parent_handle, &DEVPKEY_Device_DriverProvider,
323 if (SetupDiEnumDriverInfo(devinfo_list.get(), &devinfo_data, 313 &devprop_type, reinterpret_cast<BYTE*>(buffer),
324 SPDIT_COMPATDRIVER, 0, &drvinfo_data)) { 314 &buffer_size, 0);
325 *out_manufacturer = base::WideToUTF8(drvinfo_data.ProviderName); 315 if (cr != CR_SUCCESS)
316 VLOG(1) << "CM_Get_DevNode_Property failed: CONFIGRET 0x" << std::hex << cr;
317 else if (devprop_type != DEVPROP_TYPE_STRING)
318 VLOG(1) << "CM_Get_DevNode_Property returns wrong data type, "
319 << "expected DEVPROP_TYPE_STRING.";
320 else
321 *out_manufacturer = base::WideToUTF8(buffer);
326 322
327 std::stringstream ss; 323 buffer_size = sizeof(buffer);
328 ss << (drvinfo_data.DriverVersion >> 48) << "." 324 cr = CM_Get_DevNode_Property(parent_handle, &DEVPKEY_Device_DriverVersion,
329 << (drvinfo_data.DriverVersion >> 32 & 0xffff) << "." 325 &devprop_type, reinterpret_cast<BYTE*>(buffer),
330 << (drvinfo_data.DriverVersion >> 16 & 0xffff) << "." 326 &buffer_size, 0);
331 << (drvinfo_data.DriverVersion & 0xffff); 327 if (cr != CR_SUCCESS)
332 *out_driver_version = ss.str(); 328 VLOG(1) << "CM_Get_DevNode_Property failed: CONFIGRET 0x" << std::hex << cr;
333 } else { 329 else if (devprop_type != DEVPROP_TYPE_STRING)
334 VLOG(1) << "SetupDiEnumDriverInfo failed: " 330 VLOG(1) << "CM_Get_DevNode_Property returns wrong data type, "
335 << PrintHr(HRESULT_FROM_WIN32(GetLastError())); 331 << "expected DEVPROP_TYPE_STRING.";
336 } 332 else
337 333 *out_driver_version = base::WideToUTF8(buffer);
338 if (!SetupDiDestroyDriverInfoList(devinfo_list.get(), &devinfo_data,
339 SPDIT_COMPATDRIVER))
340 VLOG(1) << "SetupDiDestroyDriverInfoList failed: "
341 << PrintHr(HRESULT_FROM_WIN32(GetLastError()));
342 } 334 }
343 335
344 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>). 336 // Tokens with value = 0 are considered invalid (as in <wrl/event.h>).
345 const int64_t kInvalidTokenValue = 0; 337 const int64_t kInvalidTokenValue = 0;
346 338
347 template <typename InterfaceType> 339 template <typename InterfaceType>
348 struct MidiPort { 340 struct MidiPort {
349 MidiPort() = default; 341 MidiPort() = default;
350 342
351 uint32_t index; 343 uint32_t index;
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 void MidiManagerWinrt::OnPortManagerReady() { 1025 void MidiManagerWinrt::OnPortManagerReady() {
1034 DCHECK(com_thread_checker_->CalledOnValidThread()); 1026 DCHECK(com_thread_checker_->CalledOnValidThread());
1035 DCHECK(port_manager_ready_count_ < 2); 1027 DCHECK(port_manager_ready_count_ < 2);
1036 1028
1037 if (++port_manager_ready_count_ == 2) 1029 if (++port_manager_ready_count_ == 2)
1038 CompleteInitialization(Result::OK); 1030 CompleteInitialization(Result::OK);
1039 } 1031 }
1040 1032
1041 } // namespace midi 1033 } // namespace midi
1042 } // namespace media 1034 } // namespace media
OLDNEW
« media/midi/BUILD.gn ('K') | « media/midi/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698