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