1 // Licensed under the Apache License, Version 2.0
2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
4 // All files in the project carrying such notice may not be copied, modified, or distributed
5 // except according to those terms.
6 //! The DeviceTopology API gives clients control over a variety of internal functions of audio
7 //! adapters that they cannot access through the MMDevice API, WASAPI, or the EndpointVolume API.
8 use ctypes::{c_float, c_void};
9 use shared::guiddef::{GUID, LPCGUID, REFGUID, REFIID};
10 use shared::minwindef::{BOOL, DWORD, UCHAR, UINT, ULONG, WORD};
11 use shared::windef::COLORREF;
12 use shared::wtypes::VARTYPE;
13 use um::unknwnbase::{IUnknown, IUnknownVtbl};
14 use um::winnt::{HRESULT, LONG, LONGLONG, LPWSTR, WCHAR};
15 DEFINE_GUID!{EVENTCONTEXT_VOLUMESLIDER,
16     0xe2c2e9de, 0x09b1, 0x4b04, 0x84, 0xe5, 0x07, 0x93, 0x12, 0x25, 0xee, 0x04}
17 STRUCT!{struct KSDATAFORMAT {
18     FormatSize: ULONG,
19     Flags: ULONG,
20     SampleSize: ULONG,
21     Reserved: ULONG,
22     MajorFormat: GUID,
23     SubFormat: GUID,
24     Specifier: GUID,
25 }}
26 pub type PKSDATAFORMAT = *mut KSDATAFORMAT;
27 STRUCT!{struct KSIDENTIFIER_s {
28     Set: GUID,
29     Id: ULONG,
30     Flags: ULONG,
31 }}
32 UNION!{union KSIDENTIFIER {
33     [u64; 3],
34     s s_mut: KSIDENTIFIER_s,
35     Alignment Alignment_mut: LONGLONG,
36 }}
37 pub type KSPROPERTY = KSIDENTIFIER;
38 pub type PKSPROPERTY = *mut KSIDENTIFIER;
39 pub type KSMETHOD = KSIDENTIFIER;
40 pub type PKSMETHOD = *mut KSIDENTIFIER;
41 pub type KSEVENT = KSIDENTIFIER;
42 pub type PKSEVENT = *mut KSIDENTIFIER;
43 ENUM!{enum EPcxConnectionType {
44     eConnTypeUnknown = 0,
45     eConnType3Point5mm = 1,
46     eConnTypeQuarter = 2,
47     eConnTypeAtapiInternal = 3,
48     eConnTypeRCA = 4,
49     eConnTypeOptical = 5,
50     eConnTypeOtherDigital = 6,
51     eConnTypeOtherAnalog = 7,
52     eConnTypeMultichannelAnalogDIN = 8,
53     eConnTypeXlrProfessional = 9,
54     eConnTypeRJ11Modem = 10,
55     eConnTypeCombination = 11,
56 }}
57 ENUM!{enum EPcxGeoLocation {
58     eGeoLocRear = 1,
59     eGeoLocFront = 2,
60     eGeoLocLeft = 3,
61     eGeoLocRight = 4,
62     eGeoLocTop = 5,
63     eGeoLocBottom = 6,
64     eGeoLocRearPanel = 7,
65     eGeoLocRiser = 8,
66     eGeoLocInsideMobileLid = 9,
67     eGeoLocDrivebay = 10,
68     eGeoLocHDMI = 11,
69     eGeoLocOutsideMobileLid = 12,
70     eGeoLocATAPI = 13,
71     eGeoLocNotApplicable = 14,
72     eGeoLocReserved6 = 15,
73 }}
74 ENUM!{enum EPcxGenLocation {
75     eGenLocPrimaryBox = 0,
76     eGenLocInternal = 1,
77     eGenLocSeparate = 2,
78     eGenLocOther = 3,
79 }}
80 ENUM!{enum EPxcPortConnection {
81     ePortConnJack = 0,
82     ePortConnIntegratedDevice = 1,
83     ePortConnBothIntegratedAndJack = 2,
84     ePortConnUnknown = 3,
85 }}
86 STRUCT!{struct KSJACK_DESCRIPTION {
87     ChannelMapping: DWORD,
88     Color: COLORREF,
89     ConnectionType: EPcxConnectionType,
90     GeoLocation: EPcxGeoLocation,
91     GenLocation: EPcxGenLocation,
92     PortConnection: EPxcPortConnection,
93     IsConnected: BOOL,
94 }}
95 pub type PKSJACK_DESCRIPTION = *mut KSJACK_DESCRIPTION;
96 STRUCT!{struct LUID {
97     LowPart: DWORD,
98     HighPart: LONG,
99 }}
100 pub type PLUID = *mut LUID;
101 ENUM!{enum KSJACK_SINK_CONNECTIONTYPE {
102     KSJACK_SINK_CONNECTIONTYPE_HDMI = 0,
103     KSJACK_SINK_CONNECTIONTYPE_DISPLAYPORT = 1,
104 }}
105 STRUCT!{struct KSJACK_SINK_INFORMATION {
106     ConnType: KSJACK_SINK_CONNECTIONTYPE,
107     ManufacturerId: WORD,
108     ProductId: WORD,
109     AudioLatency: WORD,
110     HDCPCapable: BOOL,
111     AICapable: BOOL,
112     SinkDescriptionLength: UCHAR,
113     SinkDescription: [WCHAR; 32],
114     PortId: LUID,
115 }}
116 STRUCT!{struct KSJACK_DESCRIPTION2 {
117     DeviceStateInfo: DWORD,
118     JackCapabilities: DWORD,
119 }}
120 pub type PKSJACK_DESCRIPTION2 = *mut KSJACK_DESCRIPTION2;
121 ENUM!{enum DataFlow {
122     In = 0,
123     Out = 1,
124 }}
125 ENUM!{enum PartType {
126     Connector = 0,
127     Subunit = 1,
128 }}
129 ENUM!{enum ConnectorType {
130     Unknown_Connector = 0,
131     Physical_Internal = 1,
132     Physical_External = 2,
133     Software_IO = 3,
134     Software_Fixed = 4,
135     Network = 5,
136 }}
137 RIDL!{#[uuid(0x28f54685, 0x06fd, 0x11d2, 0xb2, 0x7a, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96)]
138 interface IKsControl(IKsControlVtbl): IUnknown(IUnknownVtbl) {
139     fn KsProperty(
140         Property: PKSPROPERTY,
141         PropertyLength: ULONG,
142         PropertyData: *mut c_void,
143         DataLength: ULONG,
144         BytesReturned: *mut ULONG,
145     ) -> HRESULT,
146     fn KsMethod(
147         Method: PKSMETHOD,
148         MethodLength: ULONG,
149         MethodData: *mut c_void,
150         DataLength: ULONG,
151         BytesReturned: *mut ULONG,
152     ) -> HRESULT,
153     fn KsEvent(
154         Event: PKSEVENT,
155         EventLength: ULONG,
156         EventData: *mut c_void,
157         DataLength: ULONG,
158         BytesReturned: *mut ULONG,
159     ) -> HRESULT,
160 }}
161 RIDL!{#[uuid(0xc2f8e001, 0xf205, 0x4bc9, 0x99, 0xbc, 0xc1, 0x3b, 0x1e, 0x04, 0x8c, 0xcb)]
162 interface IPerChannelDbLevel(IPerChannelDbLevelVtbl): IUnknown(IUnknownVtbl) {
163     fn GetChannelCount(
164         pcChannels: *mut UINT,
165     ) -> HRESULT,
166     fn GetLevelRange(
167         nChannel: UINT,
168         pfMinLevelDB: *mut c_float,
169         pfMaxLevelDB: *mut c_float,
170         pfStepping: *mut c_float,
171     ) -> HRESULT,
172     fn GetLevel(
173         nChannel: UINT,
174         pfLevelDB: *mut c_float,
175     ) -> HRESULT,
176     fn SetLevel(
177         nChannel: UINT,
178         fLevelDB: c_float,
179         pguidEventContext: LPCGUID,
180     ) -> HRESULT,
181     fn SetLevelUniform(
182         fLevelDB: c_float,
183         pguidEventContext: LPCGUID,
184     ) -> HRESULT,
185     fn SetLevelAllChannels(
186         aLevelsDB: *mut c_float,
187         cChannels: ULONG,
188         pguidEventContext: LPCGUID,
189     ) -> HRESULT,
190 }}
191 RIDL!{#[uuid(0x7fb7b48f, 0x531d, 0x44a2, 0xbc, 0xb3, 0x5a, 0xd5, 0xa1, 0x34, 0xb3, 0xdc)]
192 interface IAudioVolumeLevel(IAudioVolumeLevelVtbl): IPerChannelDbLevel(IPerChannelDbLevelVtbl) {}}
193 RIDL!{#[uuid(0xbb11c46f, 0xec28, 0x493c, 0xb8, 0x8a, 0x5d, 0xb8, 0x80, 0x62, 0xce, 0x98)]
194 interface IAudioChannelConfig(IAudioChannelConfigVtbl): IUnknown(IUnknownVtbl) {
195     fn SetChannelConfig(
196         dwConfig: DWORD,
197         pguidEventContext: LPCGUID,
198     ) -> HRESULT,
199     fn GetChannelConfig(
200         pdwConfig: *mut DWORD,
201     ) -> HRESULT,
202 }}
203 RIDL!{#[uuid(0x7d8b1437, 0xdd53, 0x4350, 0x9c, 0x1b, 0x1e, 0xe2, 0x89, 0x0b, 0xd9, 0x38)]
204 interface IAudioLoudness(IAudioLoudnessVtbl): IUnknown(IUnknownVtbl) {
205     fn GetEnabled(
206         pbEnabled: *mut BOOL,
207     ) -> HRESULT,
208     fn SetEnabled(
209         bEnable: BOOL,
210         pguidEventContext: LPCGUID,
211     ) -> HRESULT,
212 }}
213 RIDL!{#[uuid(0x4f03dc02, 0x5e6e, 0x4653, 0x8f, 0x72, 0xa0, 0x30, 0xc1, 0x23, 0xd5, 0x98)]
214 interface IAudioInputSelector(IAudioInputSelectorVtbl): IUnknown(IUnknownVtbl) {
215     fn GetSelection(
216         pnIdSelected: *mut UINT,
217     ) -> HRESULT,
218     fn SetSelection(
219         nIdSelect: UINT,
220         pguidEventContext: LPCGUID,
221     ) -> HRESULT,
222 }}
223 RIDL!{#[uuid(0xbb515f69, 0x94a7, 0x429e, 0x8b, 0x9c, 0x27, 0x1b, 0x3f, 0x11, 0xa3, 0xab)]
224 interface IAudioOutputSelector(IAudioOutputSelectorVtbl): IUnknown(IUnknownVtbl) {
225     fn GetSelection(
226         pnIdSelected: *mut UINT,
227     ) -> HRESULT,
228     fn SetSelection(
229         nIdSelect: UINT,
230         pguidEventContext: LPCGUID,
231     ) -> HRESULT,
232 }}
233 RIDL!{#[uuid(0xdf45aeea, 0xb74a, 0x4b6b, 0xaf, 0xad, 0x23, 0x66, 0xb6, 0xaa, 0x01, 0x2e)]
234 interface IAudioMute(IAudioMuteVtbl): IUnknown(IUnknownVtbl) {
235     fn SetMute(
236         bMuted: BOOL,
237         pguidEventContext: LPCGUID,
238     ) -> HRESULT,
239     fn GetMute(
240         pbMuted: *mut BOOL,
241     ) -> HRESULT,
242 }}
243 RIDL!{#[uuid(0xa2b1a1d9, 0x4db3, 0x425d, 0xa2, 0xb2, 0xbd, 0x33, 0x5c, 0xb3, 0xe2, 0xe5)]
244 interface IAudioBass(IAudioBassVtbl): IPerChannelDbLevel(IPerChannelDbLevelVtbl) {}}
245 RIDL!{#[uuid(0x5e54b6d7, 0xb44b, 0x40d9, 0x9a, 0x9e, 0xe6, 0x91, 0xd9, 0xce, 0x6e, 0xdf)]
246 interface IAudioMidrange(IAudioMidrangeVtbl): IPerChannelDbLevel(IPerChannelDbLevelVtbl) {}}
247 RIDL!{#[uuid(0x0a717812, 0x694e, 0x4907, 0xb7, 0x4b, 0xba, 0xfa, 0x5c, 0xfd, 0xca, 0x7b)]
248 interface IAudioTreble(IAudioTrebleVtbl): IPerChannelDbLevel(IPerChannelDbLevelVtbl) {}}
249 RIDL!{#[uuid(0x85401fd4, 0x6de4, 0x4b9d, 0x98, 0x69, 0x2d, 0x67, 0x53, 0xa8, 0x2f, 0x3c)]
250 interface IAudioAutoGainControl(IAudioAutoGainControlVtbl): IUnknown(IUnknownVtbl) {
251     fn GetEnabled(
252         pbEnabled: *mut BOOL,
253     ) -> HRESULT,
254     fn SetEnabled(
255         bEnable: BOOL,
256         pguidEventContext: LPCGUID,
257     ) -> HRESULT,
258 }}
259 RIDL!{#[uuid(0xdd79923c, 0x0599, 0x45e0, 0xb8, 0xb6, 0xc8, 0xdf, 0x7d, 0xb6, 0xe7, 0x96)]
260 interface IAudioPeakMeter(IAudioPeakMeterVtbl): IUnknown(IUnknownVtbl) {
261     fn GetChannelCount(
262         pcChannels: *mut UINT,
263     ) -> HRESULT,
264     fn GetLevel(
265         nChannel: UINT,
266         pfLevel: *mut c_float,
267     ) -> HRESULT,
268 }}
269 RIDL!{#[uuid(0x3b22bcbf, 0x2586, 0x4af0, 0x85, 0x83, 0x20, 0x5d, 0x39, 0x1b, 0x80, 0x7c)]
270 interface IDeviceSpecificProperty(IDeviceSpecificPropertyVtbl): IUnknown(IUnknownVtbl) {
271     fn GetType(
272         pVType: *mut VARTYPE,
273     ) -> HRESULT,
274     fn GetValue(
275         pvValue: *mut c_void,
276         pcbValue: *mut DWORD,
277     ) -> HRESULT,
278     fn SetValue(
279         pvValue: *mut c_void,
280         cbValue: DWORD,
281         pguidEventContext: LPCGUID,
282     ) -> HRESULT,
283     fn Get4BRange(
284         plMin: *mut LONG,
285         plMax: *mut LONG,
286         plStepping: *mut LONG,
287     ) -> HRESULT,
288 }}
289 RIDL!{#[uuid(0x3cb4a69d, 0xbb6f, 0x4d2b, 0x95, 0xb7, 0x45, 0x2d, 0x2c, 0x15, 0x5d, 0xb5)]
290 interface IKsFormatSupport(IKsFormatSupportVtbl): IUnknown(IUnknownVtbl) {
291     fn IsFormatSupported(
292         pKsFormat: PKSDATAFORMAT,
293         cbFormat: DWORD,
294         pbSupported: *mut BOOL,
295     ) -> HRESULT,
296     fn GetDevicePreferredFormat(
297         ppKsFormat: *mut PKSDATAFORMAT,
298     ) -> HRESULT,
299 }}
300 RIDL!{#[uuid(0x4509f757, 0x2d46, 0x4637, 0x8e, 0x62, 0xce, 0x7d, 0xb9, 0x44, 0xf5, 0x7b)]
301 interface IKsJackDescription(IKsJackDescriptionVtbl): IUnknown(IUnknownVtbl) {
302     fn GetJackCount(
303         pcJacks: *mut UINT,
304     ) -> HRESULT,
305     fn GetJackDescription(
306         nJack: UINT,
307         pDescription: *mut KSJACK_DESCRIPTION,
308     ) -> HRESULT,
309 }}
310 RIDL!{#[uuid(0x478f3a9b, 0xe0c9, 0x4827, 0x92, 0x28, 0x6f, 0x55, 0x05, 0xff, 0xe7, 0x6a)]
311 interface IKsJackDescription2(IKsJackDescription2Vtbl): IUnknown(IUnknownVtbl) {
312     fn GetJackCount(
313         pcJacks: *mut UINT,
314     ) -> HRESULT,
315     fn GetJackDescription2(
316         nJack: UINT,
317         pDescription2: *mut KSJACK_DESCRIPTION2,
318     ) -> HRESULT,
319 }}
320 RIDL!{#[uuid(0xd9bd72ed, 0x290f, 0x4581, 0x9f, 0xf3, 0x61, 0x02, 0x7a, 0x8f, 0xe5, 0x32)]
321 interface IKsJackSinkInformation(IKsJackSinkInformationVtbl): IUnknown(IUnknownVtbl) {
322     fn GetJackSinkInformation(
323         pJackSinkInformation: *mut KSJACK_SINK_INFORMATION,
324     ) -> HRESULT,
325 }}
326 RIDL!{#[uuid(0xc99af463, 0xd629, 0x4ec4, 0x8c, 0x00, 0xe5, 0x4d, 0x68, 0x15, 0x42, 0x48)]
327 interface IKsJackContainerId(IKsJackContainerIdVtbl): IUnknown(IUnknownVtbl) {
328     fn GetJackContainerId(
329         pJackContainerId: *mut GUID,
330     ) -> HRESULT,
331 }}
332 RIDL!{#[uuid(0x6daa848c, 0x5eb0, 0x45cc, 0xae, 0xa5, 0x99, 0x8a, 0x2c, 0xda, 0x1f, 0xfb)]
333 interface IPartsList(IPartsListVtbl): IUnknown(IUnknownVtbl) {
334     fn GetCount(
335         pCount: *mut UINT,
336     ) -> HRESULT,
337     fn GetPart(
338         nIndex: UINT,
339         ppPart: *mut *mut IPart,
340     ) -> HRESULT,
341 }}
342 RIDL!{#[uuid(0xae2de0e4, 0x5bca, 0x4f2d, 0xaa, 0x46, 0x5d, 0x13, 0xf8, 0xfd, 0xb3, 0xa9)]
343 interface IPart(IPartVtbl): IUnknown(IUnknownVtbl) {
344     fn GetName(
345         ppwstrName: *mut LPWSTR,
346     ) -> HRESULT,
347     fn GetLocalId(
348         pnId: *mut UINT,
349     ) -> HRESULT,
350     fn GetGlobalId(
351         ppwstrGlobalId: *mut LPWSTR,
352     ) -> HRESULT,
353     fn GetPartType(
354         pPartType: *mut PartType,
355     ) -> HRESULT,
356     fn GetSubType(
357         pSubType: *mut GUID,
358     ) -> HRESULT,
359     fn GetControlInterfaceCount(
360         pCount: *mut UINT,
361     ) -> HRESULT,
362     fn GetControlInterface(
363         nIndex: UINT,
364         ppInterfaceDesc: *mut *mut IControlInterface,
365     ) -> HRESULT,
366     fn EnumPartsIncoming(
367         ppParts: *mut *mut IPartsList,
368     ) -> HRESULT,
369     fn EnumPartsOutgoing(
370         ppParts: *mut *mut IPartsList,
371     ) -> HRESULT,
372     fn GetTopologyObject(
373         ppTopology: *mut *mut IDeviceTopology,
374     ) -> HRESULT,
375     fn Activate(
376         dwClsContext: DWORD,
377         refiid: REFIID,
378         ppvObject: *mut *mut c_void,
379     ) -> HRESULT,
380     fn RegisterControlChangeCallback(
381         riid: REFGUID,
382         pNotify: *mut IControlChangeNotify,
383     ) -> HRESULT,
384     fn UnregisterControlChangeCallback(
385         pNotify: *mut IControlChangeNotify,
386     ) -> HRESULT,
387 }}
388 RIDL!{#[uuid(0x9c2c4058, 0x23f5, 0x41de, 0x87, 0x7a, 0xdf, 0x3a, 0xf2, 0x36, 0xa0, 0x9e)]
389 interface IConnector(IConnectorVtbl): IUnknown(IUnknownVtbl) {
390     fn GetType(
391         pType: *mut ConnectorType,
392     ) -> HRESULT,
393     fn GetDataFlow(
394         pFlow: *mut DataFlow,
395     ) -> HRESULT,
396     fn ConnectTo(
397         pConnectTo: *mut IConnector,
398     ) -> HRESULT,
399     fn Disconnect() -> HRESULT,
400     fn IsConnected(
401         pbConnected: *mut BOOL,
402     ) -> HRESULT,
403     fn GetConnectedTo(
404         ppConTo: *mut *mut IConnector,
405     ) -> HRESULT,
406     fn GetConnectorIdConnectedTo(
407         ppwstrConnectorId: *mut LPWSTR,
408     ) -> HRESULT,
409     fn GetDeviceIdConnectedTo(
410         ppwstrDeviceId: *mut LPWSTR,
411     ) -> HRESULT,
412 }}
413 RIDL!{#[uuid(0x82149a85, 0xdba6, 0x4487, 0x86, 0xbb, 0xea, 0x8f, 0x7f, 0xef, 0xcc, 0x71)]
414 interface ISubunit(ISubunitVtbl): IUnknown(IUnknownVtbl) {}}
415 RIDL!{#[uuid(0x45d37c3f, 0x5140, 0x444a, 0xae, 0x24, 0x40, 0x07, 0x89, 0xf3, 0xcb, 0xf3)]
416 interface IControlInterface(IControlInterfaceVtbl): IUnknown(IUnknownVtbl) {
417     fn GetName(
418         ppwstrName: *mut LPWSTR,
419     ) -> HRESULT,
420     fn GetIID(
421         pIID: *mut GUID,
422     ) -> HRESULT,
423 }}
424 RIDL!{#[uuid(0xa09513ed, 0xc709, 0x4d21, 0xbd, 0x7b, 0x5f, 0x34, 0xc4, 0x7f, 0x39, 0x47)]
425 interface IControlChangeNotify(IControlChangeNotifyVtbl): IUnknown(IUnknownVtbl) {
426     fn OnNotify(
427         dwSenderProcessId: DWORD,
428         pguidEventContext: LPCGUID,
429     ) -> HRESULT,
430 }}
431 RIDL!{#[uuid(0x2a07407e, 0x6497, 0x4a18, 0x97, 0x87, 0x32, 0xf7, 0x9b, 0xd0, 0xd9, 0x8f)]
432 interface IDeviceTopology(IDeviceTopologyVtbl): IUnknown(IUnknownVtbl) {
433     fn GetConnectorCount(
434         pCount: *mut UINT,
435     ) -> HRESULT,
436     fn GetConnector(
437         nIndex: UINT,
438         ppConnector: *mut *mut IConnector,
439     ) -> HRESULT,
440     fn GetSubunitCount(
441         pCount: *mut UINT,
442     ) -> HRESULT,
443     fn GetSubunit(
444         nIndex: UINT,
445         ppSubunit: *mut *mut ISubunit,
446     ) -> HRESULT,
447     fn GetPartById(
448         nId: UINT,
449         ppPart: *mut *mut IPart,
450     ) -> HRESULT,
451     fn GetDeviceId(
452         ppwstrDeviceId: *mut LPWSTR,
453     ) -> HRESULT,
454     fn GetSignalPath(
455         pIPartFrom: *mut IPart,
456         pIPartTo: *mut IPart,
457         bRejectMixedPaths: BOOL,
458         ppParts: *mut *mut IPartsList,
459     ) -> HRESULT,
460 }}
461 RIDL!{#[uuid(0x1df639d0, 0x5ec1, 0x47aa, 0x93, 0x79, 0x82, 0x8d, 0xc1, 0xaa, 0x8c, 0x59)]
462 class DeviceTopology;}
463