OSDN Git Service

リセット
[momiji/momiji_main.git] / Core / Momiji.Core.MMDeviceAPI.cpp
1 /*
2 [momiji music component library]
3 ---------------------------------------------------------------------
4 Momiji.Core.Midi.Out.cpp
5         midi output component.
6 ---------------------------------------------------------------------
7 Copyright (C) 2011 tyiki badwell {miria@users.sourceforge.jp}.
8
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program.  If not, see <http://www.gnu.org/licenses/gpl-3.0.html>.
21 ---------------------------------------------------------------------
22 */
23 #include "StdAfx.h"
24
25 #include "Momiji.Interop.MMDeviceAPI.h"
26 #include "Momiji.Core.MMDeviceAPI.h"
27
28 namespace Momiji {
29 namespace Core {
30 namespace MMDeviceAPI {
31
32         Devices::Devices(
33                 Interop::MMDeviceAPI::EDataFlow dataFlow
34         )
35         {
36                 #ifdef _DEBUG
37                         System::Console::WriteLine("[{0}][dataFlow:{1}]",__FUNCTION__, dataFlow);
38                 #endif
39
40                 #ifdef _DEBUG
41                         System::Console::WriteLine("[{0}][dataFlow:{1}]",__FUNCTION__, Interop::MMDeviceAPI::FunctionDiscoveryKeys_devpkey::PKEY_Device);
42                 #endif
43                 
44
45
46                 Interop::MMDeviceAPI::IMMDeviceEnumerator^ a = gcnew Interop::MMDeviceAPI::MMDeviceEnumeratorClass();
47                 Interop::MMDeviceAPI::IMMDeviceCollection^ b;
48
49                 a->EnumAudioEndpoints(dataFlow, 1, b);
50
51                 System::UInt32 c;
52                 b->GetCount(c);
53
54                 #ifdef _DEBUG
55                         System::Console::WriteLine("[{0}][IMMDeviceCollection.GetCount:{1}]",__FUNCTION__, c);
56                 #endif
57
58                 for (auto i = 0; i < c; i++) {
59                         Interop::MMDeviceAPI::IMMDevice^ d;
60
61                         b->Item(i, d);
62
63                         System::String^ e;
64                         d->GetId(e);
65
66                 #ifdef _DEBUG
67                         System::Console::WriteLine("[{0}][IMMDevice.GetId:{1}]",__FUNCTION__, e);
68                 #endif
69
70                         Interop::MMDeviceAPI::DEVICE_STATE f;
71                         d->GetState(f);
72
73                 #ifdef _DEBUG
74                         System::Console::WriteLine("[{0}][IMMDevice.GetState:{1:F}]",__FUNCTION__, f);
75                 #endif
76
77                         Interop::PropIdl::IPropertyStore^ g;
78                         d->OpenPropertyStore(Interop::MMDeviceAPI::STGM::READ, g);
79
80                         System::UInt32 h;
81                         g->GetCount(h);
82
83                 #ifdef _DEBUG
84                         System::Console::WriteLine("[{0}][IPropertyStore.GetCount:{1}]",__FUNCTION__, h);
85                 #endif
86
87                         for (auto j = 0; j < h; j++) {
88                                 auto x = gcnew Interop::PropIdl::PROPERTYKEY();
89                                 g->GetAt(j, x);
90
91                 #ifdef _DEBUG
92                         System::Console::WriteLine("[{0}][IPropertyStore.GetAt:{1}]",__FUNCTION__, x);
93                 #endif
94                                 auto y = gcnew Interop::PropIdl::PROPVARIANT();
95                                 auto marshaler = Interop::PropIdl::PROPVARIANTMarshaler::GetInstance("");
96                                 auto z = marshaler->MarshalManagedToNative(y);
97                                 try
98                                 {
99                                         g->GetValue(x, z);
100                                         y = safe_cast<Interop::PropIdl::PROPVARIANT^>(marshaler->MarshalNativeToManaged(z));
101                                 }
102                                 finally
103                                 {
104                                         marshaler->CleanUpNativeData(z);
105                                 }
106
107                 #ifdef _DEBUG
108                         System::Console::WriteLine("[{0}][IPropertyStore.GetValue:{1}]",__FUNCTION__, y);
109                 #endif
110                         }
111
112                         delete g;
113                         delete d;
114                 }
115
116                 delete b;
117                 delete a;
118
119         }
120
121         Devices::~Devices()
122         {
123                 #ifdef _DEBUG
124                         System::Console::WriteLine("[{0}]",__FUNCTION__);
125                 #endif
126                 this->!Devices();
127         }
128
129         Devices::!Devices()
130         {
131                 #ifdef _DEBUG
132                         System::Console::WriteLine("[{0}]",__FUNCTION__);
133                 #endif
134         //      this->_handle->Close();
135         }
136
137         Devices::Detail::Detail(
138                 Devices^ devices,
139                 System::UInt32 index
140         )//:
141         //      _devices(devices)
142         {
143                 #ifdef _DEBUG
144                         System::Console::WriteLine("[{0}]",__FUNCTION__);
145                 #endif
146
147 //              this->GetDetail(index);
148         }
149
150         Devices::Detail::~Detail()
151         {
152                 #ifdef _DEBUG
153                         System::Console::WriteLine("[{0}]",__FUNCTION__);
154                 #endif
155                 this->!Detail();
156         }
157
158         Devices::Detail::!Detail()
159         {
160                 #ifdef _DEBUG
161                         System::Console::WriteLine("[{0}]",__FUNCTION__);
162                 #endif
163         }
164 /*
165         void Devices::Detail::GetDetail(
166                 System::UInt32 index
167         )
168         {
169                 #ifdef _DEBUG
170                         System::Console::WriteLine("[{0}][index: {1}]",__FUNCTION__, index);
171                 #endif
172
173                 auto data = Interop::Setupapi::SpDeviceInterfaceData();
174                 data.cbSize = safe_cast<System::UInt32>(InteropServices::Marshal::SizeOf(data));
175                 #ifdef _DEBUG
176                         System::Console::WriteLine("[{0}] data->cbSize {1}",__FUNCTION__, data.cbSize);
177                 #endif
178                 if (
179                         !Interop::Setupapi::Function::SetupDiEnumDeviceInterfaces(
180                                 this->_devices->_handle,
181                                 nullptr,
182                                 this->_devices->_category,
183                                 index,
184                                 data
185                         )
186                 )
187                 {
188                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
189                         #ifdef _DEBUG
190                                 System::Console::WriteLine("[{0}] error [{1}]",__FUNCTION__, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
191                         #endif
192                         if (error == 0x80070103) //ERROR_NO_MORE_ITEMS
193                         {
194                                 this->_noMoreItems = true;
195                                 return;
196                         }
197                         else
198                         {
199                                 InteropServices::Marshal::ThrowExceptionForHR(error);
200                         }
201                 }
202                         
203                 #ifdef _DEBUG
204                         System::Console::WriteLine("[{0}] data [{1}]", __FUNCTION__, data);
205                 #endif
206
207                 this->_data = data;
208
209                 //\83f\81[\83^\83T\83C\83Y\8am\94F
210                 System::UInt32 reqired = 0;
211                 
212                 if (
213                         !Interop::Setupapi::Function::SetupDiGetDeviceInterfaceDetail(
214                                 this->_devices->_handle,
215                                 this->_data,
216                                 System::IntPtr::Zero,
217                                 0,
218                                 reqired,
219                                 System::IntPtr::Zero
220                         )
221                 )
222                 {
223                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
224                         #ifdef _DEBUG
225                                 System::Console::WriteLine("[{0}] error [{1}]",__FUNCTION__, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
226                         #endif
227                         if (error != 0x8007007A)//ERROR_INSUFFICIENT_BUFFER
228                         {
229                                 InteropServices::Marshal::ThrowExceptionForHR(error);
230                         }
231                 }
232
233                 #ifdef _DEBUG
234                         System::Console::WriteLine("[{0}] reqired {1}",__FUNCTION__, reqired);
235                 #endif
236                 
237                 //\81E\81E\81E\82Í\82µ\82Ä\82é\82à\82Ì\82Ì\81A\8c\8b\8bÇ\8d¡\82Í\81A1024byte\8cÅ\92è\82Å\93Ç\82Ý\8d\9e\82ñ\82Å\82¢\82é
238                 auto detail = Interop::Setupapi::SpDeviceInterfaceDetailData();
239                 detail.cbSize = safe_cast<System::UInt32>(InteropServices::Marshal::SizeOf(detail.cbSize) + InteropServices::Marshal::SystemDefaultCharSize);
240
241                 auto info = Interop::Setupapi::SpDevinfoData();
242                 info.cbSize = safe_cast<System::UInt32>(InteropServices::Marshal::SizeOf(info));
243                 
244                 #ifdef _DEBUG
245                         System::Console::WriteLine("[{0}] detail->cbSize {1}",__FUNCTION__, detail.cbSize);
246                 #endif
247
248                 #ifdef _DEBUG
249                         System::Console::WriteLine("[{0}] info->cbSize {1}",__FUNCTION__, info.cbSize);
250                 #endif
251
252                 if (
253                         !Interop::Setupapi::Function::SetupDiGetDeviceInterfaceDetail(
254                                 this->_devices->_handle,
255                                 this->_data,
256                                 detail,
257                                 reqired,
258                                 reqired,
259                                 info
260                         )
261                 )
262                 {
263                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
264                         InteropServices::Marshal::ThrowExceptionForHR(error);
265                 }
266
267                 #ifdef _DEBUG
268                         System::Console::WriteLine("[{0}] detail [{1}]",__FUNCTION__, detail);
269                         System::Console::WriteLine("[{0}] info [{1}]", __FUNCTION__, info);
270                 #endif
271
272                 this->_devicePath = detail.DevicePath;
273                 this->_info = info;
274         }
275
276         Interop::Setupapi::SpDeviceInterfaceData^ Devices::Detail::GetAlias(
277                 Interop::Guiddef::Guid subCategory
278         )
279         {
280                 #ifdef _DEBUG
281                         System::Console::WriteLine("[{0}][{1}]",__FUNCTION__, subCategory);
282                 #endif
283                 auto data = Interop::Setupapi::SpDeviceInterfaceData();
284                 data.cbSize = safe_cast<System::UInt32>(InteropServices::Marshal::SizeOf(data));
285
286                 if (
287                         !Interop::Setupapi::Function::SetupDiGetDeviceInterfaceAlias(
288                                 this->_devices->_handle,
289                                 this->_data,
290                                 subCategory,
291                                 data
292                         )
293                 )
294                 {
295                         #ifdef _DEBUG
296                                 auto error = InteropServices::Marshal::GetHRForLastWin32Error();
297                                 System::Console::WriteLine("[{0}] error [{1}]",__FUNCTION__, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
298                         #endif
299                         return nullptr;
300                 }
301
302                 #ifdef _DEBUG
303                         System::Console::WriteLine("[{0}] alias [{1}]", __FUNCTION__, data);
304                 #endif
305                 return data;
306         }
307
308         System::String^ Devices::Detail::GetDeviceRegistryProperty(
309                 Interop::Setupapi::SPDRP spdrp
310         )
311         {
312                 #ifdef _DEBUG
313                 //      System::Console::WriteLine("[{0}][{1}]",__FUNCTION__, spdrp);
314                 #endif
315                 System::UInt32 regDataType = 0;
316                 System::UInt32 reqired = 0;
317                 if (
318                         !Interop::Setupapi::Function::SetupDiGetDeviceRegistryProperty(
319                                 this->_devices->_handle,
320                                 this->_info,
321                                 spdrp,
322                                 regDataType,
323                                 nullptr,
324                                 0,
325                                 reqired
326                         )
327                 )
328                 {
329                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
330                         #ifdef _DEBUG
331                         //      System::Console::WriteLine("[{0}] error {1:X}",__FUNCTION__, error);
332                         #endif
333                         if (error != 0x8007007A)//ERROR_INSUFFICIENT_BUFFER
334                         {
335                                 #ifdef _DEBUG
336                                         System::Console::WriteLine("[{0}] {1} [{2}]",__FUNCTION__, spdrp, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
337                                 #endif
338                                 return nullptr;
339                         }
340                 }
341                 #ifdef _DEBUG
342                 //      System::Console::WriteLine("[{0}] reqired {1}",__FUNCTION__, reqired);
343                 #endif
344                 auto buf = gcnew System::Text::StringBuilder(safe_cast<System::Int32>(reqired));
345
346                 if (
347                         !Interop::Setupapi::Function::SetupDiGetDeviceRegistryProperty(
348                                 this->_devices->_handle,
349                                 this->_info,
350                                 spdrp,
351                                 regDataType,
352                                 buf,
353                                 reqired,
354                                 reqired
355                         )
356                 )
357                 {
358                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
359                         #ifdef _DEBUG
360                         //      System::Console::WriteLine("[{0}] error {1:X}",__FUNCTION__, error);
361                         #endif
362                         InteropServices::Marshal::ThrowExceptionForHR(error);
363                 }
364
365                 #ifdef _DEBUG
366                         System::Console::WriteLine("[{0}] {1} [{2}]",__FUNCTION__, spdrp, buf->ToString());
367                 #endif
368                 return buf->ToString();
369         }
370
371         System::String^ Devices::Detail::GetDeviceRegistryProperty(
372                 System::String^ name
373         )
374         {
375                 #ifdef _DEBUG
376                 //      System::Console::WriteLine("[{0}][{1}]",__FUNCTION__, name);
377                 #endif
378                 Interop::Setupapi::Function::RegKey^ regKey;
379                 
380                 {
381                         regKey =
382                                 Interop::Setupapi::Function::SetupDiOpenDeviceInterfaceRegKey(
383                                         this->_devices->_handle,
384                                         this->_data,
385                                         0,
386                                         Interop::Kernel32::ACCESS_TYPES::KEY_READ
387                                 );
388                         if (regKey->IsInvalid)
389                         {
390                                 #ifdef _DEBUG
391                                         auto error = InteropServices::Marshal::GetHRForLastWin32Error();
392                                         System::Console::WriteLine("[{0}] error {1:X}",__FUNCTION__, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
393                                 #endif
394                                 return nullptr;
395                         }
396                 }
397
398                 try
399                 {
400                         System::UInt32 type = 0;
401                         System::UInt32 size = 1024;
402                         auto data = InteropServices::Marshal::AllocHGlobal(size);
403                         try
404                         {
405                                 System::UInt32 error =
406                                         Interop::Setupapi::Function::RegQueryValueEx(
407                                                 regKey,
408                                                 name,
409                                                 System::IntPtr::Zero,
410                                                 type,
411                                                 data,
412                                                 size
413                                         );
414                                 #ifdef _DEBUG
415                                 //      System::Console::WriteLine("[{0}] error {1:X}",__FUNCTION__, error);
416                                 #endif
417                                 if (error != 0)
418                                 {
419                                         #ifdef _DEBUG
420                                                 System::Console::WriteLine("[{0}] msg {1}",__FUNCTION__, InteropServices::Marshal::GetExceptionForHR(error)->ToString());
421                                         #endif
422                                         return nullptr;
423                                 }
424
425                                 auto result = InteropServices::Marshal::PtrToStringAuto(data);
426                                 #ifdef _DEBUG
427                                         System::Console::WriteLine("[{0}] {1} [{2}]",__FUNCTION__, name, result);
428                                 #endif
429                                 return result;
430                         }
431                         finally
432                         {
433                                 InteropServices::Marshal::FreeHGlobal(data);
434                         }
435                 }
436                 finally
437                 {
438                         delete regKey;
439                 }
440         }
441
442
443
444         Devices::DetailEnum::DetailEnum(
445                 Devices^ devices
446         ):
447                 _devices(devices),
448                 _index(0) //\88ê\94Ê\93I\82È\97p\96@\82©\82ç\82Í\8aO\82µ\82Ä\81AMoveNext\8cã\82É+1\82µ\82Ä\82¢\82é
449         {
450                 #ifdef _DEBUG
451                         System::Console::WriteLine("[{0}]",__FUNCTION__);
452                 #endif
453         }
454
455         System::Boolean Devices::DetailEnum::MoveNext()
456         {
457                 auto detail =
458                         gcnew Detail(
459                                 this->_devices,
460                                 this->_index++
461                         );
462
463                 this->_detail =
464                         (detail->IsNoMoreItems)
465                                 ? nullptr
466                                 : detail
467                                 ;
468                 return !detail->IsNoMoreItems;
469         }
470
471         void Devices::DetailEnum::Reset()
472         {
473                 this->_detail = nullptr;
474                 this->_index = 0;
475         }
476         */
477 }
478 }
479 }