using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.CompilerServices;
namespace com_test
{
class Native
{
[DllImport("ole32.Dll")]
static public extern uint CoCreateInstance(ref Guid clsid,
[MarshalAs(UnmanagedType.IUnknown)] object inner, uint context, ref Guid uuid,
[MarshalAs(UnmanagedType.IUnknown)] out object rReturnedComObject);
//************************************************************************
[DllImport("ole32.dll")]
private extern static int PropVariantClear(ref PropVariant pvar);
public const int DEVICE_STATE_ACTIVE = 0x00000001;
public const int DEVICE_STATE_DISABLE = 0x00000002;
public const int DEVICE_STATE_NOTPRESENT = 0x00000004;
public const int DEVICE_STATE_UNPLUGGED = 0x00000008;
public const int DEVICE_STATEMASK_ALL = 0x0000000f;
public static PROPERTYKEY PKEY_Device_FriendlyName =
new PROPERTYKEY(0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0, 14);
public static PROPERTYKEY PKEY_AudioEndpoint_FormFactor =
new PROPERTYKEY(0x1da5d803, 0xd492, 0x4edd, 0x8c, 0x23, 0xe0, 0xc0, 0xff, 0xee, 0x7f, 0x0e, 0);
}
enum EndpointFormFactor
{
RemoteNetworkDevice = 0,
Speakers = ( RemoteNetworkDevice + 1 ) ,
LineLevel = ( Speakers + 1 ) ,
Headphones = ( LineLevel + 1 ) ,
Microphone = ( Headphones + 1 ) ,
Headset = ( Microphone + 1 ) ,
Handset = ( Headset + 1 ) ,
UnknownDigitalPassthrough = ( Handset + 1 ) ,
SPDIF = ( UnknownDigitalPassthrough + 1 ) ,
DigitalAudioDisplayDevice = ( SPDIF + 1 ) ,
UnknownFormFactor = ( DigitalAudioDisplayDevice + 1 ) ,
EndpointFormFactor_enum_count = ( UnknownFormFactor + 1 )
};
enum EPcxConnectionType
{
eConnTypeUnknown=0,
eConnType3Point5mm,
eConnTypeQuarter,
eConnTypeAtapiInternal,
eConnTypeRCA,
eConnTypeOptical,
eConnTypeOtherDigital,
eConnTypeOtherAnalog,
eConnTypeMultichannelAnalogDIN,
eConnTypeXlrProfessional,
eConnTypeRJ11Modem,
eConnTypeCombination
} ;
enum EPcxGeoLocation
{
eGeoLocRear = 0x1,
eGeoLocFront,
eGeoLocLeft,
eGeoLocRight,
eGeoLocTop,
eGeoLocBottom,
eGeoLocRearPanel,
eGeoLocRiser,
eGeoLocInsideMobileLid,
eGeoLocDrivebay,
eGeoLocHDMI,
eGeoLocOutsideMobileLid,
eGeoLocATAPI,
eGeoLocNotApplicable,
eGeoLocReserved6,
EPcxGeoLocation_enum_count
} ;
public enum EDataFlow
{
eRender,
eCapture,
eAll,
EDataFlow_enum_count
}
public enum ERole
{
eConsole,
eMultimedia,
eCommunications,
ERole_enum_count
}
public enum CLSCTX : uint
{
CLSCTX_INPROC_SERVER = 0x1,
CLSCTX_INPROC_HANDLER = 0x2,
CLSCTX_LOCAL_SERVER = 0x4,
CLSCTX_REMOTE_SERVER = 0x10,
CLSCTX_SERVER = (CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER |
CLSCTX_REMOTE_SERVER),
CLSCTX_ALL = (CLSCTX_INPROC_HANDLER | CLSCTX_SERVER)
};
//Windows Core Audio API declarations
//Источник: http://www.java2s.com/Code/CSharp/Windows/SoundUtils.htm
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDeviceCollection
{
int GetCount(ref uint pcDevices);
int Item(uint nDevice, [Out, MarshalAs(UnmanagedType.Interface)] out object ppDevice);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDevice
{
int Activate(ref Guid iid, uint dwClsCtx, IntPtr pActivationParams,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppInterface);
int OpenPropertyStore(int stgmAccess, [Out, MarshalAs(UnmanagedType.Interface)] out object ppProperties);
int GetId(ref StringBuilder ppstrId);
int GetState(ref int pdwState);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
class MMDeviceEnumerator
{
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDeviceEnumerator
{
int EnumAudioEndpoints(EDataFlow dataFlow, int dwStateMask,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppDevices);
int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role,
[Out, MarshalAs(UnmanagedType.Interface)] out object ppEndpoint);
int GetDevice(string pwstrId, ref IntPtr ppDevice);
int RegisterEndpointNotificationCallback(IntPtr pClient);
int UnregisterEndpointNotificationCallback(IntPtr pClient);
}
//*********** Property store *****************************
//Источник: https://blogs.msdn.microsoft.com/adamroot/2008/04/11/interop-with-propvariants-in-net/
[ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IPropertyStore
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetCount([Out] out uint cProps);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void GetAt([In] uint iProp, out PROPERTYKEY pkey);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
int GetValue([In] ref PROPERTYKEY key, out PropVariant pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void SetValue([In] ref PROPERTYKEY key, [In] ref object pv);
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
void Commit();
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
struct PROPERTYKEY
{
public Guid fmtid;
public uint pid;
public PROPERTYKEY(Guid guid, int propertyId)
{
this.fmtid = guid;
this.pid = (uint)propertyId;
}
public PROPERTYKEY(string formatId, int propertyId)
: this(new Guid(formatId), propertyId)
{
}
public PROPERTYKEY(uint a, uint b, uint c, uint d, uint e, uint f,
uint g, uint h, uint i, uint j, uint k, int propertyId)
: this(new Guid((uint)a, (ushort)b, (ushort)c, (byte)d, (byte)e,
(byte)f, (byte)g, (byte)h, (byte)i, (byte)j, (byte)k), propertyId)
{
}
}
[StructLayout(LayoutKind.Sequential)]
public struct PropVariant
{
ushort vt;
ushort wReserved1;
ushort wReserved2;
ushort wReserved3;
IntPtr p;
int p2;
private byte[] GetDataBytes()
{
byte[] ret = new byte[IntPtr.Size + sizeof(int)];
if (IntPtr.Size == 4)
BitConverter.GetBytes(p.ToInt32()).CopyTo(ret, 0);
else if (IntPtr.Size == 8)
BitConverter.GetBytes(p.ToInt64()).CopyTo(ret, 0);
BitConverter.GetBytes(p2).CopyTo(ret, IntPtr.Size);
return ret;
}
sbyte cVal // CHAR cVal;
{
get { return (sbyte)GetDataBytes()[0]; }
}
short iVal // SHORT iVal;
{
get { return BitConverter.ToInt16(GetDataBytes(), 0); }
}
int lVal // LONG lVal;
{
get { return BitConverter.ToInt32(GetDataBytes(), 0); }
}
long hVal // LARGE_INTEGER hVal;
{
get { return BitConverter.ToInt64(GetDataBytes(), 0); }
}
float fltVal // FLOAT fltVal;
{
get { return BitConverter.ToSingle(GetDataBytes(), 0); }
}
public object Value
{
get
{
switch ((VarEnum)vt)
{
case VarEnum.VT_I1:
return cVal;
case VarEnum.VT_I2:
return iVal;
case VarEnum.VT_I4:
case VarEnum.VT_INT:
return lVal;
case VarEnum.VT_UI4:
case VarEnum.VT_I8:
return hVal;
case VarEnum.VT_R4:
return fltVal;
case VarEnum.VT_FILETIME: return DateTime.FromFileTime(hVal);
case VarEnum.VT_BSTR:
return Marshal.PtrToStringBSTR(p);
case VarEnum.VT_BLOB:
byte[] blobData = new byte[lVal];
IntPtr pBlobData;
if (IntPtr.Size == 4)
{
pBlobData = new IntPtr(p2);
}
else if (IntPtr.Size == 8)
{
pBlobData = new IntPtr(BitConverter.ToInt64(GetDataBytes(), sizeof(int)));
}
else
throw new NotSupportedException();
Marshal.Copy(pBlobData, blobData, 0, lVal);
return blobData;
case VarEnum.VT_LPSTR:
return Marshal.PtrToStringAnsi(p);
case VarEnum.VT_LPWSTR:
return Marshal.PtrToStringUni(p);
case VarEnum.VT_UNKNOWN:
return Marshal.GetObjectForIUnknown(p);
case VarEnum.VT_DISPATCH:
return p;
default:
throw new NotSupportedException("0x"+vt.ToString("X4") + " type not supported");
}
}
}
}
//*****************************************************
//Device Topology declarations
[Guid("2A07407E-6497-4A18-9787-32F79BD0D98F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDeviceTopology
{
int GetConnectorCount([Out] out int pConnectorCount);
int GetConnector(int nIndex, out IConnector ppConnector);
int GetSubunitCount([Out] out int pCount);
int GetSubunit(int nIndex, out /*ISubunit*/object ppSubunit);
int GetPartById(int nId, out IPart ppPart);
int GetDeviceId([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppwstrDeviceId);
int GetSignalPath(IPart pIPartFrom, IPart pIPartTo, bool bRejectMixedPaths, /*IPartsList*/object ppParts);
}
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("9c2c4058-23f5-41de-877a-df3af236a09e")]
public interface IConnector
{
int GetType(out int pType);
int GetDataFlow(out EDataFlow dataFlow);
int ConnectTo([In] IConnector connector);
int Disconnect();
int IsConnected(out bool pbConnected);
int GetConnectedTo([MarshalAs(UnmanagedType.Interface)] out object ppConTo);
int GetConnectorIdConnectedTo(out string ppwstrConnectorId);
int GetDeviceIdConnectedTo(out string ppwstrDeviceId);
}
[Guid("AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IPart
{
int GetName(out StringBuilder ppwstrName);
int GetLocalId(out int pnId);
int GetGlobalId(out StringBuilder ppwstrGlobalId);
int GetPartType(out int pPartType);
int GetSubType(out Guid pSubType);
int GetControlInterfaceCount(out uint pCount);
int GetControlInterface(int nIndex, out /*IControlInterface*/ object ppFunction);
int EnumPartsIncoming(out /*IPartsList[]*/object ppParts);
int EnumPartsOutgoing(out /*IPartsList[]*/object ppParts);
int GetTopologyObject([Out,MarshalAs(UnmanagedType.Interface)] out object ppTopology);
int Activate(UInt32 dwClsContext,
ref Guid refiid,
[MarshalAs(UnmanagedType.Interface)]
out object interfacePointer);
int RegisterControlChangeCallback(ref Guid riid, /*IControlChangeNotify*/object pNofity);
int UnregisterControlChangeCallback(/*IControlChangeNotify*/object pNotify);
}
[ComVisible(false)]
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("4509F757-2D46-4637-8E62-CE7DB944F57B")]
public interface IKsJackDescription
{
int GetJackCount(out uint jacks);
int GetJackDescription(uint jack, ref KSJACK_DESCRIPTION pDescription);
}
[StructLayout(LayoutKind.Sequential)]
public struct KSJACK_DESCRIPTION
{
public uint ChannelMapping;
public uint Color;
public uint ConnectionType;
public uint GeoLocation;
public uint GenLocation;
public uint PortConnection;
public uint IsConnected;
} ;
}