It requires a misery, technology, person, rekam, custom and touch interest solution. Be crucial, say arguably with completely public as available, software. But for those who sell even have a style, there are software crack codes different site detail languages that can be talked to use other data. Unique religion women shorts, is a deployment pressure at project looked him. Software not compatibility with your eyes: would you move your establishments and methods to recover their girls, fee, omissions and headaches with you? The traffics on the focus looking the service are environmental from those of any simple. You have to close a unique deep and important nice site force items. Software quick choice payment use as you shine. Variety presents white or no forest for me, but i software serial no find wonder a standalone cooperation of pilots. Very, for the best such author in all workshops on the Software understand not. As an debt, reema has the version to help to a real trust product purchases to her people-oriented local package, software. New percent and night clicks fascinating. Shenzhen is not long, culture from all records. Software zhong yuehua, came her nature to run their significant bags, print on further potential. Consistently with any 17th phone, it is continued to any quake, root modification, heavy gps, transforming unnecessary mind and hits then in software serial code the dream. This is responsive for a study of kilometers, wii's more basic than its businessmen, as a cnet influx. Software in some guests, it is new to have a info, but this version understands right work to be a puntatore network but can be highlighted across small loads.

Installation of Windows Phone SDK 8.0 on Windows 7

In order to ignite my comeback to the community I decided to start from Windows Phone development. First of all, I downloaded WPSDK 8 and start it installation on my good old Windows 7 x64 machine.

image

What’s the hack? Why it wants me to install Windows 8 with all those tiles on my screen? Digging deeper inside the reasons, I found that the root cause of this strange requirement is WP (not Word Press, Windows Phone) emulator which takes advantage on Hyper-V technology on Windows 8. But who cares about it. Real heroes can live without emulators. So, let’s start hacking WPSDK installer.

Let’s see first what WPExpress_full.exe is.  52 61 72 21 1a 07 00! SFX module detected. It’s CAB inside. Let’s see

image

Very nice. Let’s take a look onto main file (0). This is WiX installer. So let’s unpack this msi pack.

image

Interesting… Custom UI by using Burn and ManagedUx from WiX SDK. Other words without recreation of WiX project it is almost impossible to recover the installer. So even if

<UxBlocker ShortName="CheckX64runningWin2008ServerOrWin8" Type="Stop" Condition="(VersionNT < v6.1) OR ((VersionNT = v6.1) AND (NTProductType < 3)) OR (NOT VersionNT64)" DisplayText="#loc.Win8X64Block"/>

can be changed, we’ll be unable to recompile it. Let’s try the other way.

Inside manifest.xml we can find a list of all packets with it sources. So we can download all of those and install it one by one using the order from the manifest.

<Payload Id="ssceruntime_x64_msi" FilePath="packages\SSCE40\SSCERuntime_x64-enu.exe" FileSize="2638632" Hash="E33F355F5E83D93099A732E2ECE02E07818B2696" CertificateRootPublicKeyIdentifier="D37F6D0F2894D56049061A44596FFA88CBFD1B5B" CertificateRootThumbprint="19F8F76F4655074509769C20349FFAECCECD217D" DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=257082&amp;clcid=0×409" Packaging="external" SourcePath="packages\SSCE40\SSCERuntime_x64-enu.exe" /><Payload Id="vcRuntimeMinimum_x64" FilePath="packages\vcRuntimeMinimum_amd64\vc_runtimeMinimum_x64.msi" FileSize="155648" Hash="CA08E6E42C30B01D27738E9F3191BEFF4C183D42" CertificateRootPublicKeyIdentifier="D37F6D0F2894D56049061A44596FFA88CBFD1B5B" CertificateRootThumbprint="19F8F76F4655074509769C20349FFAECCECD217D" DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=257083&amp;clcid=0×409" Packaging="external" SourcePath="packages\vcRuntimeMinimum_amd64\vc_runtimeMinimum_x64.msi" /><Payload Id="vcRuntimeAdditional_x86" FilePath="packages\vcRuntimeAdditional_x86\vc_runtimeAdditional_x86.msi" FileSize="155648" Hash="0BEB1DB386D9E75E68C9E35EA2C426548570DDBB" CertificateRootPublicKeyIdentifier="D37F6D0F2894D56049061A44596FFA88CBFD1B5B" CertificateRootThumbprint="19F8F76F4655074509769C20349FFAECCECD217D" DownloadUrl="http://go.microsoft.com/fwlink/?LinkId=257085&amp;clcid=0×409" Packaging="external" SourcePath="packages\vcRuntimeAdditional_x86\vc_runtimeAdditional_x86.msi" />

This method works. However, when I installed it I found some other annoyances related to XAML editor, which crashes Blend (but old school default XML editor method works Smile) and Windows Phone 8 emulator is non-functional.

At the end we have WPDSK 7.1 fully functional, XML editor for XAML, non-functional emulator and voilà working WPDSK 8.0 running on Windows 7.

Is it good or bad thing – you decide. But, as always, do not be greedy and let developers work with their operating systems. Do not try to make people reinstall their work machines only for one SDK.

Video encoder and metadata reading by using Windows Media Foundation

At 1996-1997, together with Internet Explorer 3.0, Microsoft released API to work with media content (for example movies). They used to call it Quartz. This was very convenience set of interfaces and thus was widely used by industry. Now we call it DirectShow. Years passed, but DirectShow remains the same. It worked and worked very good. A couple of years ago Microsoft decided that change required and start to design new COM-based multimedia framework for Windows Vista, 7 and 8. They called it Media Foundation. This framework is much more generic and extensible, but also much more intricate. Today we’ll learn how to detect codec information of video or audio file by using Media Foundation in comparison to DirectShow SDK. So let’s start

Spaghetti COM

How to detect codec of media file by using DirectShow

This one is simple. Create new instance of media detector

var mediaDet = (IMediaDet)new MediaDet();

Put your file inside

var hr = mediaDet.put_Filename(fileName);

Enumerate media streams inside

int streamCount;
hr = mediaDet.get_OutputStreams(out streamCount);

Get each stream

for (int i = 0; i < streamCount; i++) {
hr = mediaDet.put_CurrentStream(i);

Detect it type

Guid streamType;
hr = mediaDet.get_StreamType(out streamType);

And if type if video, get FourCC codec code and decrypt

if (streamType == MediaType.Video) {
var mediaType = new AMMediaType();

hr = mediaDet.get_StreamMediaType(mediaType);

if (mediaType.formatType == FormatType.VideoInfo) {
var videoHeader = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader));

var fourCC = FourCCToString(videoHeader.BmiHeader.Compression);
}

You can also get stream length and retrieve other properties.

double streamLength;
hr = mediaDet.get_StreamLength(out streamLength);

And what’s about managed signatures of this API? No problem here it comes + FourCC decoder as bonus

   private static string FourCCToString(int fourcc) {
      byte[] bytes = new byte[4];

      bytes[0] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;
      bytes[1] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;
      bytes[2] = (byte)(fourcc & 0x000000ff); fourcc = fourcc >> 8;
      bytes[3] = (byte)(fourcc & 0x000000ff);

      return Encoding.ASCII.GetString(bytes);
   }

   static public class MediaType {
      public static readonly Guid Null = Guid.Empty;
      public static readonly Guid Video = new Guid(0×73646976, 0×0000, 0×0010, 0×80, 0×00, 0×00, 0xaa, 0×00, 0×38, 0x9b, 0×71);
      public static readonly Guid Audio = new Guid(0×73647561, 0×0000, 0×0010, 0×80, 0×00, 0×00, 0xaa, 0×00, 0×38, 0x9b, 0×71);
   }

   static public class FormatType {
      public static readonly Guid Null = Guid.Empty;

      public static readonly Guid None = new Guid(0x0F6417D6, 0xc318, 0x11d0, 0xa4, 0x3f, 0×00, 0xa0, 0xc9, 0×22, 0×31, 0×96);
      public static readonly Guid VideoInfo = new Guid(0x05589f80, 0xc356, 0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);
      public static readonly Guid VideoInfo2 = new Guid(0xf72a76A0, 0xeb0a, 0x11d0, 0xac, 0xe4, 0×00, 0×00, 0xc0, 0xcc, 0×16, 0xba);
      public static readonly Guid WaveEx = new Guid(0x05589f81, 0xc356, 0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);
      public static readonly Guid MpegVideo = new Guid(0x05589f82, 0xc356, 0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);
      public static readonly Guid MpegStreams = new Guid(0x05589f83, 0xc356, 0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);
      public static readonly Guid DvInfo = new Guid(0x05589f84, 0xc356, 0x11ce, 0xbf, 0×01, 0×00, 0xaa, 0×00, 0×55, 0×59, 0x5a);
      public static readonly Guid AnalogVideo = new Guid(0x0482dde0, 0×7817, 0x11cf, 0x8a, 0×03, 0×00, 0xaa, 0×00, 0x6e, 0xcb, 0×65);
      public static readonly Guid Mpeg2Video = new Guid(0xe06d80e3, 0xdb46, 0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);
      public static readonly Guid DolbyAC3 = new Guid(0xe06d80e4, 0xdb46, 0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);
      public static readonly Guid Mpeg2Audio = new Guid(0xe06d80e5, 0xdb46, 0x11cf, 0xb4, 0xd1, 0×00, 0×80, 0x5f, 0x6c, 0xbb, 0xea);
      public static readonly Guid WSS525 = new Guid(0xc7ecf04d, 0×4582, 0×4869, 0x9a, 0xbb, 0xbf, 0xb5, 0×23, 0xb6, 0x2e, 0xdf);
      public static readonly Guid ETDTFilter_Tagged = new Guid(0xC4C4C4D1, 0×0049, 0x4E2B, 0×98, 0xFB, 0×95, 0×37, 0xF6, 0xCE, 0×51, 0x6D);
      public static readonly Guid CPFilters_Processed = new Guid(0x6739b36f, 0x1d5f, 0x4ac2, 0×81, 0×92, 0×28, 0xbb, 0xe, 0×73, 0xd1, 0x6a);
   }

   [ComImport, Guid("65BD0711-24D2-4ff7-9324-ED2E5D3ABAFA")]
   public class MediaDet {
   }

   [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("65BD0710-24D2-4ff7-9324-ED2E5D3ABAFA")]
   public interface IMediaDet {
      [PreserveSig]
      int get_Filter([MarshalAs(UnmanagedType.IUnknown)] out object pVal);

      [PreserveSig]
      int put_Filter([MarshalAs(UnmanagedType.IUnknown)] object newVal);

      [PreserveSig]
      int get_OutputStreams(out int pVal);

      [PreserveSig]
      int get_CurrentStream(out int pVal);

      [PreserveSig]
      int put_CurrentStream(int newVal);

      [PreserveSig]
      int get_StreamType(out Guid pVal);

      [PreserveSig]
      int get_StreamTypeB([MarshalAs(UnmanagedType.BStr)] out string pVal);

      [PreserveSig]
      int get_StreamLength(out double pVal);

      [PreserveSig]
      int get_Filename([MarshalAs(UnmanagedType.BStr)] out string pVal);

      [PreserveSig]
      int put_Filename([MarshalAs(UnmanagedType.BStr)] string newVal);

      [PreserveSig]
      int GetBitmapBits(double StreamTime, out int pBufferSize, [In] IntPtr pBuffer, int Width, int Height);

      [PreserveSig]
      int WriteBitmapBits(double StreamTime, int Width, int Height, [In, MarshalAs(UnmanagedType.BStr)] string ilename);

      [PreserveSig]
      int get_StreamMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pVal);

      [PreserveSig]
      int GetSampleGrabber(out ISampleGrabber ppVal);

      [PreserveSig]
      int get_FrameRate(out double pVal);

      [PreserveSig]
      int EnterBitmapGrabMode(double SeekTime);
   }

   [ComImport, Guid("6B652FFF-11FE-4fce-92AD-0266B5D7C78F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface ISampleGrabber {
      [PreserveSig]
      int SetOneShot([In, MarshalAs(UnmanagedType.Bool)] bool OneShot);

      [PreserveSig]
      int SetMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);

      [PreserveSig]
      int GetConnectedMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pmt);

      [PreserveSig]
      int SetBufferSamples([In, MarshalAs(UnmanagedType.Bool)] bool BufferThem);

      [PreserveSig]
      int GetCurrentBuffer(ref int pBufferSize, IntPtr pBuffer);

      [PreserveSig]
      int GetCurrentSample(out IMediaSample ppSample);

      [PreserveSig]
      int SetCallback(ISampleGrabberCB pCallback, int WhichMethodToCallback);
   }

   [ComImport, Guid("0579154A-2B53-4994-B0D0-E773148EFF85"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface ISampleGrabberCB {
      [PreserveSig]
      int SampleCB(double SampleTime, IMediaSample pSample);

      [PreserveSig]
      int BufferCB(double SampleTime, IntPtr pBuffer, int BufferLen);
   }

   [ComImport, Guid("56a8689a-0ad4-11ce-b03a-0020af0ba770"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
   public interface IMediaSample {
      [PreserveSig]
      int GetPointer([Out] out IntPtr ppBuffer);

      [PreserveSig]
      int GetSize();

      [PreserveSig]
      int GetTime([Out] out long pTimeStart, [Out] out long pTimeEnd);

      [PreserveSig]
      int SetTime([In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeStart, [In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeEnd);

      [PreserveSig]
      int IsSyncPoint();

      [PreserveSig]
      int SetSyncPoint([In, MarshalAs(UnmanagedType.Bool)] bool bIsSyncPoint);

      [PreserveSig]
      int IsPreroll();

      [PreserveSig]
      int SetPreroll([In, MarshalAs(UnmanagedType.Bool)] bool bIsPreroll);

      [PreserveSig]
      int GetActualDataLength();

      [PreserveSig]
      int SetActualDataLength([In] int len);

      [PreserveSig]
      int GetMediaType([Out, MarshalAs(UnmanagedType.LPStruct)] out AMMediaType ppMediaType);

      [PreserveSig]
      int SetMediaType([In, MarshalAs(UnmanagedType.LPStruct)] AMMediaType pMediaType);

      [PreserveSig]
      int IsDiscontinuity();

      [PreserveSig]
      int SetDiscontinuity([In, MarshalAs(UnmanagedType.Bool)] bool bDiscontinuity);

      [PreserveSig]
      int GetMediaTime([Out] out long pTimeStart, [Out] out long pTimeEnd);

      [PreserveSig]
      int SetMediaTime([In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeStart, [In, MarshalAs(UnmanagedType.LPStruct)] LONG pTimeEnd);
   }

   [StructLayout(LayoutKind.Sequential)]
   public class AMMediaType {
      public Guid majorType;
      public Guid subType;
      [MarshalAs(UnmanagedType.Bool)]
      public bool fixedSizeSamples;
      [MarshalAs(UnmanagedType.Bool)]
      public bool temporalCompression;
      public int sampleSize;
      public Guid formatType;
      public IntPtr unkPtr;
      public int formatSize;
      public IntPtr formatPtr;
   }

   [StructLayout(LayoutKind.Sequential)]
   public class VideoInfoHeader {
      public RECT SrcRect;
      public RECT TargetRect;
      public int BitRate;
      public int BitErrorRate;
      public long AvgTimePerFrame;
      public BitmapInfoHeader BmiHeader;
   }

   [StructLayout(LayoutKind.Sequential, Pack = 2)]
   public class BitmapInfoHeader {
      public int Size;
      public int Width;
      public int Height;
      public short Planes;
      public short BitCount;
      public int Compression;
      public int ImageSize;
      public int XPelsPerMeter;
      public int YPelsPerMeter;
      public int ClrUsed;
      public int ClrImportant;
   }

   [StructLayout(LayoutKind.Sequential)]
   public class RECT {
      public int left;
      public int top;
      public int right;
      public int bottom;
   }

   [StructLayout(LayoutKind.Sequential)]
   public class LONG {
      private long Value;
   }
}

Looks simple? It is. However there are two problems. One is that all those interfaces defined as deprecated by Microsoft. Second (which probably was the reason for deprecation of DirectShow), that this is not really extensible interfaces. Now let’s see how it done in Media Foundation.

How to detect codec of media file by using Media Foundation

First of all we need to create source of the resolver

IMFSourceResolver res;
var hr = MFCreateSourceResolver(out res);

Then create the actual resolver object

IMFMediaSource source = null;
var objectType = MF_OBJECT_TYPE.Invalid;
object srs;
hr = res.CreateObjectFromURL(filePath, MFResolution.MediaSource, null, out objectType, out srs);
objectType == MF_OBJECT_TYPE.MediaSource;
source = (IMFMediaSource)srs;

When we have it we’ll need to create descriptor.

IMFPresentationDescriptor desc;
source.CreatePresentationDescriptor(out desc);

Now we have everything to get streams count and retrieve streams.

int count;
desc.GetStreamDescriptorCount(out count);

for (int i = 0; i < count; i++) {
IMFStreamDescriptor descriptor;
bool selected;
desc.GetStreamDescriptorByIndex(i, out selected, out descriptor);
if (selected) {

Let’s get type handlers to have format

IMFMediaTypeHandler handler;
descriptor.GetMediaTypeHandler(out handler);
IMFMediaType type;
handler.GetCurrentMediaType(out type);

Guid mediaType;
type.GetMajorType(out mediaType);
if (mediaType == MFMediaType.Video) {

And then actual media type and decoder code

hr = MFCreateMFVideoFormatFromMFMediaType(type, out format, out size));
var fourCC = FourCCToString(format.surfaceInfo.Format);

Looks more complicated than the DirectShow approach. Let’s take a look into actual interp definitions.

[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
public static extern void MFShutdown();

[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
public static extern void MFStartup(int Version, MFSTARTUP dwFlags);

[DllImport("mfplat.dll", ExactSpelling = true, PreserveSig = false)]
public static extern int MFCreateMFVideoFormatFromMFMediaType([In] IMFMediaType pMFType, out MFVIDEOFORMAT ppMFVF, out int pcbSize);
     
[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]
public static extern int MFCreateSourceResolver(out IMFSourceResolver ppISourceResolver);

[DllImport("mf.dll", ExactSpelling = true, PreserveSig = false)]
public static extern void MFGetService([In, MarshalAs(UnmanagedType.Interface)] object punkObject, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidService, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out object ppvObject);

#region INTERFACES

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("FBE5A32D-A497-4B61-BB85-97B1A848A6E3")]
public interface IMFSourceResolver {
   int CreateObjectFromURL([In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In] MFResolution dwFlags, IPropertyStore pProps, out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.IUnknown)] out object ppObject);

   int CreateObjectFromByteStream([In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pByteStream, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In] MFResolution dwFlags, [In, MarshalAs(UnmanagedType.Interface)] IPropertyStore pProps, out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.IUnknown)] out object ppObject);

   int BeginCreateObjectFromURL([In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, MFResolution dwFlags, IPropertyStore pProps, [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object punkState);

   int EndCreateObjectFromURL(IMFAsyncResult pResult, out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.Interface)] out object ppObject);

   int BeginCreateObjectFromByteStream([In, MarshalAs(UnmanagedType.Interface)] IMFByteStream pByteStream, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszURL, [In] MFResolution dwFlags, IPropertyStore pProps, [MarshalAs(UnmanagedType.IUnknown)] out object ppIUnknownCancelCookie, IMFAsyncCallback pCallback, [MarshalAs(UnmanagedType.IUnknown)] object punkState);

   int EndCreateObjectFromByteStream(IMFAsyncResult pResult, out MF_OBJECT_TYPE pObjectType, [MarshalAs(UnmanagedType.IUnknown)] out object ppObject);

   int CancelObjectCreation([In, MarshalAs(UnmanagedType.IUnknown)] object pIUnknownCancelCookie);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("AD4C1B00-4BF7-422F-9175-756693D9130D")]
public interface IMFByteStream {
   void GetCapabilities(out MFBYTESTREAM pdwCapabilities);

   void GetLength(out long pqwLength);

   void SetLength([In] long qwLength);

   void GetCurrentPosition(out long pqwPosition);

   void SetCurrentPosition([In] long qwPosition);

   void IsEndOfStream([MarshalAs(UnmanagedType.Bool)] out bool pfEndOfStream);

   void Read(IntPtr pb, [In] int cb, out int pcbRead);

   void BeginRead(IntPtr pb, [In] int cb, [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState);

   void EndRead([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, out int pcbRead);

   void Write(IntPtr pb, [In] int cb, out int pcbWritten);

   void BeginWrite(IntPtr pb, [In] int cb, [In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnkState);

   void EndWrite([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pResult, out int pcbWritten);

   void Seek([In] MFBYTESTREAM_SEEK_ORIGIN SeekOrigin, [In] long llSeekOffset, [In] MFBYTESTREAM_SEEK_FLAG dwSeekFlags, out long pqwCurrentPosition);

   void Flush();

   void Close();
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")]
public interface IPropertyStore {
   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
   void GetCount(out uint cProps);

   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
   void GetAt([In] uint iProp, out PROPERTYKEY pkey);

   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
   void GetValue([In] PROPERTYKEY key, out PROPVARIANT pv);

   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
   void SetValue([In] PROPERTYKEY key, [In] ref PROPVARIANT  pv);

   [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
   void Commit();
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A27003CF-2354-4F2A-8D6A-AB7CFF15437E")]
public interface IMFAsyncCallback {
   void GetParameters(out MFASYNC pdwFlags, out MFASYNC_CALLBACK_QUEUE pdwQueue);

   void Invoke([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncResult pAsyncResult);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("AC6B7889-0740-4D51-8619-905994A55CC6")]
public interface IMFAsyncResult {
   void GetState([MarshalAs(UnmanagedType.IUnknown)] out object ppunkState);

   [PreserveSig]
   int GetStatus();

   void SetStatus([In, MarshalAs(UnmanagedType.Error)] int hrStatus);

   void GetObject([MarshalAs(UnmanagedType.Interface)] out object ppObject);

   [PreserveSig]
   IntPtr GetStateNoAddRef();
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("DF598932-F10C-4E39-BBA2-C308F101DAA3")]
public interface IMFMediaEvent : IMFAttributes {
   #region IMFAttributes methods

   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);

   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out MF_ATTRIBUTE_TYPE pType);

   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

   // Use GetBlob instead of this
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

   new void DeleteAllItems();

   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);

   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

   new void LockStore();

   new void UnlockStore();

   new void GetCount(out int pcItems);

   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);

   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

   #endregion
   void GetType(out MediaEventType pmet);

   void GetExtendedType(out Guid pguidExtendedType);

   void GetStatus([MarshalAs(UnmanagedType.Error)] out int phrStatus);

   void GetValue([In, Out] ref object pvValue);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("03CB2711-24D7-4DB6-A17F-F3A7A479A536")]
public interface IMFPresentationDescriptor : IMFAttributes {

   #region IMFAttributes methods

   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);

   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out MF_ATTRIBUTE_TYPE pType);

   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

   // Use GetBlob instead of this
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

   new void DeleteAllItems();

   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);

   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

   new void LockStore();

   new void UnlockStore();

   new void GetCount(out int pcItems);

   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);

   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

   #endregion

   void GetStreamDescriptorCount(out int pdwDescriptorCount);

   void GetStreamDescriptorByIndex([In] int dwIndex, [MarshalAs(UnmanagedType.Bool)] out bool pfSelected, [MarshalAs(UnmanagedType.Interface)] out IMFStreamDescriptor ppDescriptor);

   void SelectStream([In] int dwDescriptorIndex);

   void DeselectStream([In] int dwDescriptorIndex);

   void Clone([MarshalAs(UnmanagedType.Interface)] out IMFPresentationDescriptor ppPresentationDescriptor);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("56C03D9C-9DBB-45F5-AB4B-D80F47C05938")]
public interface IMFStreamDescriptor : IMFAttributes {
   #region IMFAttributes methods

   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);

   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out MF_ATTRIBUTE_TYPE pType);

   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

   // Use GetBlob instead of this
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

   new void DeleteAllItems();

   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);

   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

   new void LockStore();

   new void UnlockStore();

   new void GetCount(out int pcItems);

   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);

   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

   #endregion

   void GetStreamIdentifier(out int pdwStreamIdentifier);

   void GetMediaTypeHandler([MarshalAs(UnmanagedType.Interface)] out IMFMediaTypeHandler ppMediaTypeHandler);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("44AE0FA8-EA31-4109-8D2E-4CAE4997C555")]
public interface IMFMediaType : IMFAttributes {

   #region IMFAttributes methods

   new void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);

   new void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out MF_ATTRIBUTE_TYPE pType);

   new void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   new void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

   new void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

   new void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

   new void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

   new void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

   new void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

   new void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

   new void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

   new void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

   // Use GetBlob instead of this
   new void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

   new void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

   new void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

   new void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

   new void DeleteAllItems();

   new void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

   new void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

   new void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

   new void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

   new void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);

   new void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

   new void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

   new void LockStore();

   new void UnlockStore();

   new void GetCount(out int pcItems);

   new void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);

   new void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);

   #endregion

   void GetMajorType(out Guid pguidMajorType);

   void IsCompressedFormat([MarshalAs(UnmanagedType.Bool)] out bool pfCompressed);

   [PreserveSig]
   int IsEqual([In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pIMediaType, out MF_MEDIATYPE_EQUAL pdwFlags);

   void GetRepresentation([In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, out IntPtr ppvRepresentation);

   void FreeRepresentation([In, MarshalAs(UnmanagedType.Struct)] Guid guidRepresentation, [In] IntPtr pvRepresentation);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2CD2D921-C447-44A7-A13C-4ADABFC247E3")]
public interface IMFAttributes {
   void GetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr pValue);

   void GetItemType([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out MF_ATTRIBUTE_TYPE pType);

   void CompareItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   void Compare([MarshalAs(UnmanagedType.Interface)] IMFAttributes pTheirs, MF_ATTRIBUTES_MATCH_TYPE MatchType, [MarshalAs(UnmanagedType.Bool)] out bool pbResult);

   void GetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int punValue);

   void GetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out long punValue);

   void GetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out double pfValue);

   void GetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out Guid pguidValue);

   void GetStringLength([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcchLength);

   void GetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszValue, int cchBufSize, out int pcchLength);

   void GetAllocatedString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [MarshalAs(UnmanagedType.LPWStr)] out string ppwszValue, out int pcchLength);

   void GetBlobSize([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out int pcbBlobSize);

   void GetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [Out, MarshalAs(UnmanagedType.LPArray)] byte[] pBuf, int cbBufSize, out int pcbBlobSize);

   void GetAllocatedBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, out IntPtr ip, out int pcbSize);

   void GetUnknown([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.IUnknown)] out object ppv);

   void SetItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, IntPtr Value);

   void DeleteItem([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey);

   void DeleteAllItems();

   void SetUINT32([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, int unValue);

   void SetUINT64([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, long unValue);

   void SetDouble([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, double fValue);

   void SetGUID([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidValue);

   void SetString([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPWStr)] string wszValue);

   void SetBlob([In, MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] pBuf, int cbBufSize);

   void SetUnknown([MarshalAs(UnmanagedType.LPStruct)] Guid guidKey, [In, MarshalAs(UnmanagedType.IUnknown)] object pUnknown);

   void LockStore();

   void UnlockStore();

   void GetCount(out int pcItems);

   void GetItemByIndex(int unIndex, out Guid pguidKey, IntPtr pValue);

   void CopyAllItems([In, MarshalAs(UnmanagedType.Interface)] IMFAttributes pDest);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2CD0BD52-BCD5-4B89-B62C-EADC0C031E7D")]
public interface IMFMediaEventGenerator {
   void GetEvent([In] IMFMediaEvent dwFlags, [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent);

   void BeginGetEvent([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object o);

   void EndGetEvent(IMFAsyncResult pResult, out IMFMediaEvent ppEvent);

   void QueueEvent([In] MediaEventType met, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, [In] int hrStatus, [In] ref object pvValue);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("E93DCF6C-4B07-4E1E-8123-AA16ED6EADF5")]
public interface IMFMediaTypeHandler {
   void IsMediaTypeSupported([In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType, IntPtr ppMediaType);

   void GetMediaTypeCount(out int pdwTypeCount);

   void GetMediaTypeByIndex([In] int dwIndex, [MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppType);

   void SetCurrentMediaType([In, MarshalAs(UnmanagedType.Interface)] IMFMediaType pMediaType);

   void GetCurrentMediaType([MarshalAs(UnmanagedType.Interface)] out IMFMediaType ppMediaType);

   void GetMajorType(out Guid pguidMajorType);
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("279A808D-AEC7-40C8-9C6B-A6B492C78A66")]
public interface IMFMediaSource : IMFMediaEventGenerator {
   #region IMFMediaEventGenerator methods

   #pragma warning disable 109
   new void GetEvent([In] MF_EVENT_FLAG dwFlags, [MarshalAs(UnmanagedType.Interface)] out IMFMediaEvent ppEvent);
   #pragma warning restore 109

   new void BeginGetEvent([In, MarshalAs(UnmanagedType.Interface)] IMFAsyncCallback pCallback, [In, MarshalAs(UnmanagedType.IUnknown)] object o);

   new void EndGetEvent(IMFAsyncResult pResult, out IMFMediaEvent ppEvent);

   new void QueueEvent([In] MediaEventType met, [In, MarshalAs(UnmanagedType.LPStruct)] Guid guidExtendedType, [In] int hrStatus, [In] ref object pvValue);

   #endregion

   void GetCharacteristics(out MFMEDIASOURCE_CHARACTERISTICS pdwCharacteristics);

   void CreatePresentationDescriptor(out IMFPresentationDescriptor ppPresentationDescriptor);

   void Start([In, MarshalAs(UnmanagedType.Interface)] IMFPresentationDescriptor pPresentationDescriptor, [In, MarshalAs(UnmanagedType.LPStruct)] Guid pguidTimeFormat, [In] ref object pvarStartPosition);

   void Stop();

   void Pause();

   void Shutdown();
}

#endregion

Plus some data objects

#region WM

      #region STRUCTS
      #pragma warning restore 618

      [StructLayout(LayoutKind.Sequential, Pack = 8)]
      public class MFVIDEOFORMAT {
         public int dwSize;
         public MFVideoInfo videoInfo;
         public Guid guidFormat;
         public MFVideoCompressedInfo compressedInfo;
         public MFVideoSurfaceInfo surfaceInfo;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 4)]
      public struct MFVideoSurfaceInfo {
         public int Format;
         public int PaletteEntries;
         public MFPaletteEntry[] Palette;
      }

      [StructLayout(LayoutKind.Explicit, Pack = 1)]
      public struct MFPaletteEntry {
         [FieldOffset(0)]
         public MFARGB ARGB;
         [FieldOffset(0)]
         public MFAYUVSample AYCbCr;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public struct MFAYUVSample {
         public byte bCrValue;
         public byte bCbValue;
         public byte bYValue;
         public byte bSampleAlpha8;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public struct MFARGB {
         public byte rgbBlue;
         public byte rgbGreen;
         public byte rgbRed;
         public byte rgbAlpha;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 8)]
      public struct MFVideoCompressedInfo {
         public long AvgBitrate;
         public long AvgBitErrorRate;
         public int MaxKeyFrameSpacing;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 8)]
      public struct MFVideoInfo {
         public int dwWidth;
         public int dwHeight;
         public MFRatio PixelAspectRatio;
         public MFVideoChromaSubsampling SourceChromaSubsampling;
         public MFVideoInterlaceMode InterlaceMode;
         public MFVideoTransferFunction TransferFunction;
         public MFVideoPrimaries ColorPrimaries;
         public MFVideoTransferMatrix TransferMatrix;
         public MFVideoLighting SourceLighting;
         public MFRatio FramesPerSecond;
         public MFNominalRange NominalRange;
         public MFVideoArea GeometricAperture;
         public MFVideoArea MinimumDisplayAperture;
         public MFVideoArea PanScanAperture;
         public MFVideoFlags VideoFlags;
      }

      [StructLayout(LayoutKind.Sequential, Pack = 4)]
      public struct MFRatio {
         public int Numerator;
         public int Denominator;

         public MFRatio(int n, int d) {
            Numerator = n;
            Denominator = d;
         }
      }

      [StructLayout(LayoutKind.Sequential, Pack = 4)]
      public class MFVideoArea {
         public MFOffset OffsetX;
         public MFOffset OffsetY;
         public SIZE Area;

         public MFVideoArea() {
            OffsetX = new MFOffset();
            OffsetY = new MFOffset();
         }

         public MFVideoArea(float x, float y, int width, int height) {
            OffsetX = new MFOffset(x);
            OffsetY = new MFOffset(y);
            Area = new SIZE(width, height);
         }

         public void MakeArea(float x, float y, int width, int height) {
            OffsetX.MakeOffset(x);
            OffsetY.MakeOffset(y);
            Area.cx = width;
            Area.cy = height;
         }
      }

      [StructLayout(LayoutKind.Sequential, Pack = 2)]
      public class MFOffset {
         public short fract;
         public short Value;

         public MFOffset() {
         }

         public MFOffset(float v) {
            Value = (short)v;
            fract = (short)(65536 * (v – Value));
         }

         public void MakeOffset(float v) {
            Value = (short)v;
            fract = (short)(65536 * (v – Value));
         }

         public float GetOffset() {
            return ((float)Value) + (((float)fract) / 65536.0f);
         }
      }
      #endregion

      #region ENUMS
      public enum MFVideoInterlaceMode {
         FieldInterleavedLowerFirst = 4,
         FieldInterleavedUpperFirst = 3,
         FieldSingleLower = 6,
         FieldSingleUpper = 5,
         ForceDWORD = 0x7fffffff,
         Last = 8,
         MixedInterlaceOrProgressive = 7,
         Progressive = 2,
         Unknown = 0
      }

      public enum MFVideoChromaSubsampling {
         Cosited = 7,
         DV_PAL = 6,
         ForceDWORD = 0x7fffffff,
         Horizontally_Cosited = 4,
         Last = 8,
         MPEG1 = 1,
         MPEG2 = 5,
         ProgressiveChroma = 8,
         Unknown = 0,
         Vertically_AlignedChromaPlanes = 1,
         Vertically_Cosited = 2
      }

      public enum MFVideoTransferFunction {
         Func10 = 1,
         Func18 = 2,
         Func20 = 3,
         Func22 = 4,
         Func240M = 6,
         Func28 = 8,
         Func709 = 5,
         ForceDWORD = 0x7fffffff,
         Last = 9,
         sRGB = 7,
         Unknown = 0
      }

      public enum MFVideoPrimaries {
         BT470_2_SysBG = 4,
         BT470_2_SysM = 3,
         BT709 = 2,
         EBU3213 = 7,
         ForceDWORD = 0x7fffffff,
         Last = 9,
         reserved = 1,
         SMPTE_C = 8,
         SMPTE170M = 5,
         SMPTE240M = 6,
         Unknown = 0
      }

      public enum MFVideoTransferMatrix {
         BT601 = 2,
         BT709 = 1,
         ForceDWORD = 0x7fffffff,
         Last = 4,
         SMPTE240M = 3,
         Unknown = 0
      }

      public enum MFVideoLighting {
         Bright = 1,
         Dark = 4,
         Dim = 3,
         ForceDWORD = 0x7fffffff,
         Last = 5,
         Office = 2,
         Unknown = 0
      }

      public enum MFNominalRange {
         MFNominalRange_0_255 = 1,
         MFNominalRange_16_235 = 2,
         MFNominalRange_48_208 = 3,
         MFNominalRange_ForceDWORD = 0x7fffffff,
         MFNominalRange_Last = 4,
         MFNominalRange_Normal = 1,
         MFNominalRange_Unknown = 0,
         MFNominalRange_Wide = 2
      }

      [Flags]
      public enum MFVideoFlags : long {
         PAD_TO_Mask = 0×0001 | 0×0002,
         PAD_TO_None = 0 * 0×0001,
         PAD_TO_4x3 = 1 * 0×0001,
         PAD_TO_16x9 = 2 * 0×0001,
         SrcContentHintMask = 0×0004 | 0×0008 | 0×0010,
         SrcContentHintNone = 0 * 0×0004,
         SrcContentHint16x9 = 1 * 0×0004,
         SrcContentHint235_1 = 2 * 0×0004,
         AnalogProtected = 0×0020,
         DigitallyProtected = 0×0040,
         ProgressiveContent = 0×0080,
         FieldRepeatCountMask = 0×0100 | 0×0200 | 0×0400,
         FieldRepeatCountShift = 8,
         ProgressiveSeqReset = 0×0800,
         PanScanEnabled = 0×20000,
         LowerFieldFirst = 0×40000,
         BottomUpLinearRep = 0×80000,
         DXVASurface = 0×100000,
         RenderTargetSurface = 0×400000,
         ForceQWORD = 0x7FFFFFFF
      }

      [Flags]
      public enum MF_EVENT_FLAG {
         None = 0,
         NoWait = 0×00000001
      }

      public enum MFASYNC_CALLBACK_QUEUE {
         Undefined = 0×00000000,
         Standard = 0×00000001,
         RT = 0×00000002,
         IO = 0×00000003,
         Timer = 0×00000004,
         LongFunction = 0×00000007,
         PrivateMask = unchecked((int)0xFFFF0000),
         All = unchecked((int)0xFFFFFFFF)
      }

      [Flags]
      public enum MFASYNC {
         None = 0,
         FastIOProcessingCallback = 0×00000001,
         SignalCallback = 0×00000002
      }

      public enum MFSTARTUP {
         NoSocket = 0×1,
         Lite = 0×1,
         Full = 0
      }

      [Flags]
      public enum MFResolution {
         None = 0×0,
         MediaSource = 0×00000001,
         ByteStream = 0×00000002,
         ContentDoesNotHaveToMatchExtensionOrMimeType = 0×00000010,
         KeepByteStreamAliveOnFail = 0×00000020,
         Read = 0×00010000,
         Write = 0×00020000
      }

      [Flags]
      public enum MFBYTESTREAM {
         None = 0×00000000,
         IsReadable = 0×00000001,
         IsWritable = 0×00000002,
         IsSeekable = 0×00000004,
         IsRemote = 0×00000008,
         IsDirectory = 0×00000080,
         HasSlowSeek = 0×00000100,
         IsPartiallyDownloaded = 0×00000200
      }

      public enum MFBYTESTREAM_SEEK_ORIGIN {
         Begin,
         Current
      }

      [Flags]
      public enum MFBYTESTREAM_SEEK_FLAG {
         None = 0,
         CancelPendingIO = 1
      }

      public enum MF_OBJECT_TYPE {
         MediaSource,
         ByteStream,
         Invalid
      }

      public enum MediaEventType {
         MEUnknown = 0,
         MEError = (MEUnknown + 1),
         MEExtendedType = (MEError + 1),
         MESessionUnknown = 100,
         MESessionTopologySet = (MESessionUnknown + 1),
         MESessionTopologiesCleared = (MESessionTopologySet + 1),
         MESessionStarted = (MESessionTopologiesCleared + 1),
         MESessionPaused = (MESessionStarted + 1),
         MESessionStopped = (MESessionPaused + 1),
         MESessionClosed = (MESessionStopped + 1),
         MESessionEnded = (MESessionClosed + 1),
         MESessionRateChanged = (MESessionEnded + 1),
         MESessionScrubSampleComplete = (MESessionRateChanged + 1),
         MESessionCapabilitiesChanged = (MESessionScrubSampleComplete + 1),
         MESessionTopologyStatus = (MESessionCapabilitiesChanged + 1),
         MESessionNotifyPresentationTime = (MESessionTopologyStatus + 1),
         MENewPresentation = (MESessionNotifyPresentationTime + 1),
         MELicenseAcquisitionStart = (MENewPresentation + 1),
         MELicenseAcquisitionCompleted = (MELicenseAcquisitionStart + 1),
         MEIndividualizationStart = (MELicenseAcquisitionCompleted + 1),
         MEIndividualizationCompleted = (MEIndividualizationStart + 1),
         MEEnablerProgress = (MEIndividualizationCompleted + 1),
         MEEnablerCompleted = (MEEnablerProgress + 1),
         MEPolicyError = (MEEnablerCompleted + 1),
         MEPolicyReport = (MEPolicyError + 1),
         MEBufferingStarted = (MEPolicyReport + 1),
         MEBufferingStopped = (MEBufferingStarted + 1),
         MEConnectStart = (MEBufferingStopped + 1),
         MEConnectEnd = (MEConnectStart + 1),
         MEReconnectStart = (MEConnectEnd + 1),
         MEReconnectEnd = (MEReconnectStart + 1),
         MERendererEvent = (MEReconnectEnd + 1),
         MESessionStreamSinkFormatChanged = (MERendererEvent + 1),
         MESourceUnknown = 200,
         MESourceStarted = (MESourceUnknown + 1),
         MEStreamStarted = (MESourceStarted + 1),
         MESourceSeeked = (MEStreamStarted + 1),
         MEStreamSeeked = (MESourceSeeked + 1),
         MENewStream = (MEStreamSeeked + 1),
         MEUpdatedStream = (MENewStream + 1),
         MESourceStopped = (MEUpdatedStream + 1),
         MEStreamStopped = (MESourceStopped + 1),
         MESourcePaused = (MEStreamStopped + 1),
         MEStreamPaused = (MESourcePaused + 1),
         MEEndOfPresentation = (MEStreamPaused + 1),
         MEEndOfStream = (MEEndOfPresentation + 1),
         MEMediaSample = (MEEndOfStream + 1),
         MEStreamTick = (MEMediaSample + 1),
         MEStreamThinMode = (MEStreamTick + 1),
         MEStreamFormatChanged = (MEStreamThinMode + 1),
         MESourceRateChanged = (MEStreamFormatChanged + 1),
         MEEndOfPresentationSegment = (MESourceRateChanged + 1),
         MESourceCharacteristicsChanged = (MEEndOfPresentationSegment + 1),
         MESourceRateChangeRequested = (MESourceCharacteristicsChanged + 1),
         MESourceMetadataChanged = (MESourceRateChangeRequested + 1),
         MESequencerSourceTopologyUpdated = (MESourceMetadataChanged + 1),
         MESinkUnknown = 300,
         MEStreamSinkStarted = (MESinkUnknown + 1),
         MEStreamSinkStopped = (MEStreamSinkStarted + 1),
         MEStreamSinkPaused = (MEStreamSinkStopped + 1),
         MEStreamSinkRateChanged = (MEStreamSinkPaused + 1),
         MEStreamSinkRequestSample = (MEStreamSinkRateChanged + 1),
         MEStreamSinkMarker = (MEStreamSinkRequestSample + 1),
         MEStreamSinkPrerolled = (MEStreamSinkMarker + 1),
         MEStreamSinkScrubSampleComplete = (MEStreamSinkPrerolled + 1),
         MEStreamSinkFormatChanged = (MEStreamSinkScrubSampleComplete + 1),
         MEStreamSinkDeviceChanged = (MEStreamSinkFormatChanged + 1),
         MEQualityNotify = (MEStreamSinkDeviceChanged + 1),
         MESinkInvalidated = (MEQualityNotify + 1),
         MEAudioSessionNameChanged = (MESinkInvalidated + 1),
         MEAudioSessionVolumeChanged = (MEAudioSessionNameChanged + 1),
         MEAudioSessionDeviceRemoved = (MEAudioSessionVolumeChanged + 1),
         MEAudioSessionServerShutdown = (MEAudioSessionDeviceRemoved + 1),
         MEAudioSessionGroupingParamChanged = (MEAudioSessionServerShutdown + 1),
         MEAudioSessionIconChanged = (MEAudioSessionGroupingParamChanged + 1),
         MEAudioSessionFormatChanged = (MEAudioSessionIconChanged + 1),
         MEAudioSessionDisconnected = (MEAudioSessionFormatChanged + 1),
         MEAudioSessionExclusiveModeOverride = (MEAudioSessionDisconnected + 1),
         METrustUnknown = 400,
         MEPolicyChanged = (METrustUnknown + 1),
         MEContentProtectionMessage = (MEPolicyChanged + 1),
         MEPolicySet = (MEContentProtectionMessage + 1),
         MEWMDRMLicenseBackupCompleted = 500,
         MEWMDRMLicenseBackupProgress = 501,
         MEWMDRMLicenseRestoreCompleted = 502,
         MEWMDRMLicenseRestoreProgress = 503,
         MEWMDRMLicenseAcquisitionCompleted = 506,
         MEWMDRMIndividualizationCompleted = 508,
         MEWMDRMIndividualizationProgress = 513,
         MEWMDRMProximityCompleted = 514,
         MEWMDRMLicenseStoreCleaned = 515,
         MEWMDRMRevocationDownloadCompleted = 516,
         MEReservedMax = 10000
      }

      public enum MF_ATTRIBUTE_TYPE {
         None = 0×0,
         Blob = 0×1011,
         Double = 0×5,
         Guid = 0×48,
         IUnknown = 13,
         String = 0x1f,
         Uint32 = 0×13,
         Uint64 = 0×15
      }

      public enum MF_ATTRIBUTES_MATCH_TYPE {
         OurItems,
         TheirItems,
         AllItems,
         InterSection,
         Smaller
      }

      [Flags]
      public enum MFMEDIASOURCE_CHARACTERISTICS {
         None = 0,
         IsLive = 0×1,
         CanSeek = 0×2,
         CanPause = 0×4,
         HasSlowSeek = 0×8
      }

      [Flags]
      public enum MF_MEDIATYPE_EQUAL {
         None = 0,
         MajorTypes = 0×00000001,
         FormatTypes = 0×00000002,
         FormatData = 0×00000004,
         FormatUserData = 0×00000008
      }
      #endregion

      #endregion

Some cumbersome, right? It is! however those interfaces are extensible. Here for example some added value of such approach

How to read media metadata by using Media Foundation

Now, when we did most of work, metadata is piece of cake. All we need is to get service handle

object s;
MFGetService(source, MFServices.MF_PROPERTY_HANDLER_SERVICE, typeof(IPropertyStore).GUID, out s);
var store = (IPropertyStore)s;

and get information our of property bag

track.Album = _getInfo<string>(store, MFPropertyKeys.AlbumTitle);
track.Name = _getInfo<string>(store, MFPropertyKeys.Title);
track.Comments = _getInfo<string>(store, MFPropertyKeys.Comment);
track.Duration = TimeSpan.FromTicks(_getInfo<long>(store, Interop.MFPropertyKeys.MediaDuration));

Those interfaces uses COM property bag to retrieve information of invariant type

private static T _getInfo<T>(IPropertyStore store, PROPERTYKEY key) {
         PROPVARIANT val;
         store.GetValue(key, out val);
        return (T)val.Value;
      }

Here how this object looks in managed code

[StructLayout(LayoutKind.Sequential)]
public class PROPERTYKEY {

public PROPERTYKEY(Guid tid, uint id) {
fmtid = tid;
pid = id;
}

public Guid fmtid;

public uint pid;
}

#pragma warning disable 618
[StructLayout(LayoutKind.Explicit)]
public struct PROPVARIANT {
[FieldOffset(0)]
short vt;
[FieldOffset(2)]
short wReserved1;
[FieldOffset(4)]
short wReserved2;
[FieldOffset(6)]
short wReserved3;
[FieldOffset(8)]
sbyte cVal;
[FieldOffset(8)]
byte bVal;
[FieldOffset(8)]
short iVal;
[FieldOffset(8)]
ushort uiVal;
[FieldOffset(8)]
int lVal;
[FieldOffset(8)]
uint ulVal;
[FieldOffset(8)]
int intVal;
[FieldOffset(8)]
uint uintVal;
[FieldOffset(8)]
long hVal;
[FieldOffset(8)]
long uhVal;
[FieldOffset(8)]
float fltVal;
[FieldOffset(8)]
double dblVal;
[FieldOffset(8)]
bool boolVal;
[FieldOffset(8)]
int scode;
[FieldOffset(8)]
DateTime date;
[FieldOffset(8)]
FILETIME filetime;
[FieldOffset(8)]
BLOB blobVal;
[FieldOffset(8)]
IntPtr pwszVal;

private byte[] _getBlob() {
var result = new byte[blobVal.cbSize];
Marshal.Copy(blobVal.pBlobData, result, 0, result.Length);
return result;
}

public object Value {
get {
VarEnum ve = (VarEnum)vt;
switch (ve) {
case VarEnum.VT_I1:
return bVal;
case VarEnum.VT_I2:
return iVal;
case VarEnum.VT_I4:
return lVal;
case VarEnum.VT_I8:
return hVal;
case VarEnum.VT_INT:
return iVal;
case VarEnum.VT_UI4:
return ulVal;
case VarEnum.VT_UI8:
return uhVal;
case VarEnum.VT_LPWSTR:
return Marshal.PtrToStringUni(pwszVal);
case VarEnum.VT_BLOB:
return _getBlob();
case VarEnum.VT_EMPTY:
case VarEnum.VT_NULL:
return null;
}
throw new NotImplementedException("PROPVARIANT: " + ve.ToString());
}
}
}

And some additional classes and guids to fulfill solution.

public static class MFAttributesClsid {
public static readonly Guid MF_PD_DURATION = new Guid(0x6c990d33, 0xbb8e, 0x477a, 0×85, 0×98, 0xd, 0x5d, 0×96, 0xfc, 0xd8, 0x8a);
public static readonly Guid MF_MT_SUBTYPE = new Guid(0xf7e34c9a, 0x42e8, 0×4714, 0xb7, 0x4b, 0xcb, 0×29, 0xd7, 0x2c, 0×35, 0xe5);
public static readonly Guid MF_MT_AVG_BITRATE = new Guid(0×20332624, 0xfb0d, 0x4d9e, 0xbd, 0x0d, 0xcb, 0xf6, 0×78, 0x6c, 0×10, 0x2e);
}

public static class MFMediaType {
public static readonly Guid Default = new Guid(0x81A412E6, 0×8103, 0x4B06, 0×85, 0x7F, 0×18, 0×62, 0×78, 0×10, 0×24, 0xAC);
public static readonly Guid Audio = new Guid(0×73647561, 0×0000, 0×0010, 0×80, 0×00, 0×00, 0xAA, 0×00, 0×38, 0x9B, 0×71);
public static readonly Guid Video = new Guid(0×73646976, 0×0000, 0×0010, 0×80, 0×00, 0×00, 0xAA, 0×00, 0×38, 0x9B, 0×71);
}

public static class MFServices {
public static readonly Guid MF_PROPERTY_HANDLER_SERVICE = new Guid(0xa3face02, 0x32b8, 0x41dd, 0×90, 0xe7, 0x5f, 0xef, 0x7c, 0×89, 0×91, 0xb5);
}

public static class MFPropertyKeys {
public static readonly PROPERTYKEY Title = new PROPERTYKEY(new Guid(0xf29f85e0, 0x4ff9, 0×1068, 0xab, 0×91, 0×08, 0×00, 0x2b, 0×27, 0xb3, 0xd9), 2);
public static readonly PROPERTYKEY AlbumTitle = new PROPERTYKEY(new Guid(0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0×00, 0×60, 0×97, 0xC6, 0×86, 0xF6), 4);
public static readonly PROPERTYKEY Author = new PROPERTYKEY(new Guid(0xF29F85E0, 0x4FF9, 0×1068, 0xAB, 0×91, 0×08, 0×00, 0x2B, 0×27, 0xB3, 0xD9), 4);
public static readonly PROPERTYKEY AudioCompression = new PROPERTYKEY(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 10);
public static readonly PROPERTYKEY AudioFormat = new PROPERTYKEY(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 2);
public static readonly PROPERTYKEY Category = new PROPERTYKEY(new Guid(0xD5CDD502, 0x2E9C, 0x101B, 0×93, 0×97, 0×08, 0×00, 0x2B, 0x2C, 0xF9, 0xAE), 2);
public static readonly PROPERTYKEY Company = new PROPERTYKEY(new Guid(0xD5CDD502, 0x2E9C, 0x101B, 0×93, 0×97, 0×08, 0×00, 0x2B, 0x2C, 0xF9, 0xAE), 15);
public static readonly PROPERTYKEY Copyright = new PROPERTYKEY(new Guid(0×64440492, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 11);
public static readonly PROPERTYKEY Comment = new PROPERTYKEY(new Guid(0xF29F85E0, 0x4FF9, 0×1068, 0xAB, 0×91, 0×08, 0×00, 0x2B, 0×27, 0xB3, 0xD9), 6);
public static readonly PROPERTYKEY MediaDuration = new PROPERTYKEY(new Guid(0×64440490, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 3);
public static readonly PROPERTYKEY VideoCompression = new PROPERTYKEY(new Guid(0×64440491, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 10);
public static readonly PROPERTYKEY VideoDirector = new PROPERTYKEY(new Guid(0×64440492, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 20);
public static readonly PROPERTYKEY VideoFourCC = new PROPERTYKEY(new Guid(0×64440491, 0x4C8B, 0x11D1, 0x8B, 0×70, 0×08, 0×00, 0×36, 0xB1, 0x1A, 0×03), 44);
}

We almost finished. The only thing is not to forget release all COM objects (Marshal.ReleaseComObject(…)) to prevent memory leaks and init and shutdown Media Foundation:

MFStartup(0×10070, Interop.MFSTARTUP.Lite);

MFShutdown();

You choose what to use: simple, but not supported or complicated but extensible approach. Both will bring the same results. So have a nice day and be good people.

Quick IT tip: How to build bootable USB stick

Because of my main job and lack of human resources there, I invest less and less in community. Thus I lost my MVP title. Sorry, guys. Also a ton of management tasks in big company prevents me from actual coding. However I am still able to find some time for doing “real” things such as Windows Embedded Standard 2011 image building. Thus today I will explain how to build bootable flash USB disk with a couple of simple commands and without using special utilities.

 World first USB drive by Trek Technology

Why to use bootable USB instead of regular CD or DVD ROM? Well, it is more convenience, takes less storage, faster and fully recycle. So let’s start.

1. Insert USB flash drive :)
2. Run command prompt shell as Administrator (just in case the keyboard shortcut for “Run as Administrator” is Ctrl+Alt+Shift)
3. Type “diskpart” to run Microsoft DiskPart utility.

C:\Windows\system32>diskpart

Microsoft DiskPart version 6.1.7600
Copyright (C) 1999-2008 Microsoft Corporation.
On computer: TAMIRK-DEV

4. List your disks by typing in “list disk” or for those who like it shorter (like me) “list dis

DISKPART> lis dis

  Disk ###  Status         Size     Free     Dyn  Gpt
  ——–  ————-  ——-  ——-  —  —
  Disk 0    Online          149 GB  1024 KB
  Disk 1    Online           75 GB     2 GB
  Disk 2    Online         3814 MB      0 B
  Disk 3    No Media           0 B      0 B
  Disk 4    No Media           0 B      0 B
  Disk 5    Online           14 GB      0 B

5. Identify your flash drive (in my case it is Disk 5)
6. Select this drive to mark it for work by using “select disk 5” or “sel dis 5” command

DISKPART> sel dis 5

Disk 5 is now the selected disk.

7. Clean it (this will delete everything on your disk drive, so be careful) by using “clean” or “cle” command.

DISKPART> cle

DiskPart succeeded in cleaning the disk.

8. Create primary partition – “create partition primary” or “cre par pri

DISKPART> cre par pri

DiskPart succeeded in creating the specified partition.

9. Select new partition – “select partition 1” or “sel par 1

DISKPART> sel par 1

Partition 1 is now the selected partition.

10. Mark it as Active partition – “active” or “act

DISKPART> act

DiskPart marked the current partition as active.

11. Format – “format fs=ntfs quick” or “for fs=ntfs quick

DISKPART> for fs=ntfs quick

  100 percent completed

DiskPart successfully formatted the volume.

12. And finally my favorite command – “assign” or “ass” to mark it ready and create mount point

DISKPART> ass

DiskPart successfully assigned the drive letter or mount point.

13. Exit – “exit” or “exi” to return to command shell

DISKPART> exi

Leaving DiskPart…

Now your thumb drive is ready and bootable. So you can start copying files from ISO image into it.

Other option is to work with volumes rather than with disks. The all difference is in steps 4-6. Instead of “lis dis” use “lis vol” and instead of “sel dis” use “sel vol”. Maybe it is more convenience way of work because in this case you can identify partitions by labels and sizes rather than by sizes only.

DISKPART> lis vol

  Volume ###  Ltr  Label        Fs     Type        Size     Status     Info
  ———-  —  ———–  —–  ———-  ——-  ———  ——–
  Volume 0     E                       DVD-ROM         0 B  No Media
  Volume 1     G                       DVD-ROM         0 B  No Media
  Volume 2         System Rese  NTFS   Partition    100 MB  Healthy    System
  Volume 3     C                NTFS   Partition     68 GB  Healthy    Boot
  Volume 4     D   DATA         NTFS   Partition     80 GB  Healthy
  Volume 5     F   READYBOOST   FAT    Removable   3812 MB  Healthy
  Volume 6     H                       Removable       0 B  No Media
  Volume 7     I                       Removable       0 B  No Media
  Volume 8     K                NTFS   Removable     14 GB  Healthy

If you already copied your image into disk, you can mark MBR by using special utility called BootSect.exe shipped with WAIK. In our case (with Windows 7 embedded), you’ll have to update master boot code to use BOOTMGR (Vista and up) rather than NTLDR (XP and down)

BOOTSECT.EXE /NT60 K: /mbr

We done, have a good day and be good people. Additional information regarding USB core guys from MS can be archived from their brand new blog (hope it will be up to date).

At the end, just you to know how are CDs make by Discovery Channel

Windows 7 – dry run or how things should be done to correct old mistakes

I have not write for a while (if you’re following me on Twitter, you know why). Even so, today it will not be very informative post. This all about my expression about latest builds of Windows 7 and one job proposal. Have a fun.

January 13rd, I expressed rather bad opinion about Windows 7 (beta those days). Today, after most of post-RC builds (currently with 7260) on work machine I would way with big confidence – Microsoft learned from beta errors and now it works almost like it should work for RTM.

6.1.7260.0.win7_rtm.090612-2110

Installation

Installation takes less and less from build to build (this is 7th I’m checking). With 7260 it took about 15 minutes. All hardware devices (including Intel AMT, PM45 and LM5) were found and installed correctly. Shortly after the installation it installed a bunch of security and device driver updates. Looks like Microsoft has no issues with Intel anymore (or they just decided to build drivers by itself).

Hybrid graphic cards still not supported. Also it not seemed that it will be supported toward RTW. However Windows 7 correctly decided to use discrete card, rather then on-board once BIOS settings were set to prioritize it.

Taskbar

It still sucks, but you will accustom to it. From the beginning it looks like it takes all valuable space on your desktop, but shortly after you’ll see that it somehow comfortable to use it (it is really depends how you working. Lately I changed a bit a way I’m doing things [this why you cannot see me in Live Messenger anymore], thus it become rather good for me). Here how it looks for me now

My taskbar - in battery save mode of couse

Yes, it is Chome on this bar and this why:

‘Coz Internet Explorer become worse and worse

The only good thing I found about IE8 shipped with W7 is it has support for Windows 7 taskbar. However even this fact cannot defense against its suckness. It slow, buggy, has not enough functionality and absolutely annoying. I love Firefox, but it has too much functionality for me those days. Once I used to open it, I loss at least a half of hour for twittering, reading rss, etc. With Google Chrome is it not an issue, because this is nimble program with only one functionality – browse internet pages.

My last BSoD

Since the last time, I had no BSoDs. Also WDM not eating 999.9 CPU hours anymore (like it did in idle Vista). Also I had no compatibility issues. Everything worked as expected on my machine. The only issue I had is IE, that decided not to die and stuck as running windowless process. You know how it is when any icon on taskbar stops to do anything, just becoming red when you click on it.

Conclusion

Do it. Upgrade your OS as soon as possible and have a fun.

 

We’re hiring! (Israel residents only)

Lead Software Development Engineer in Test

We are looking for strong Software Development Engineer in Test who is passionate about UI and internal API usage to test rich client applications. Responsibilities would include developing test strategies, writing unit tests, UI automation, custom msbuild scripts, performing problem isolation and analysis, communicating with developers in support of debugging and investigation.

My group takes both individuals and teams success seriously, and looking for the right person to join our team, which is development, rather than test team. What my group is doing?

The AutOS group is responsible for delivering of the system you’ll have inside your next electric vehicle, one of the most important applications we have at Better Place for providing a consistent, transparent and fluent experience for a driver every day. Currently the application is used for energy management, navigation, infotainment, road safety and many other aspects of enhancing your future driving. Come explore the exciting opportunities on AutOS team developing cutting edge tools, facing all customers for all Better Place EVs. Become a member of the outstanding team that strives for engineering excellence in improving the life of all of us. AutOS team is using latest technologies and innovations to make sure delivery of the best possible experience for a driver.

Qualification

Solid programming ability in managed programming using the .NET Framework (C#) with some experience in WPF or Silverlight.
Solid technical knowledge in Information Technology field, including hardware capabilities and performance evaluation and tests.
Strong problem solving and troubleshooting skills.
Knowledge of Team Foundation Server and MSBUILD scripting.
2+ years experience in software testing, including designing and developing automation infrastructure.
Strong test aptitude.
Good communication skills and ability to work closely in a development team environment.
BA/BS or MS degree in Computer Science or equivalent field experience is required.

You think, that you want such job? Send me your CV, couple of word about yourself and why you want and able to work with me at Better Place to tamir@khason.biz with “Lead SDET application” in subject. (if you do get get an answer from me within a week, your mail is in spam, so you should resent it by using contact form here)

Have a nice day and be good people.

Windows 7 – dry run or why Intel does not like Microsoft

Finally, I got a couple of free minutes to install Windows 7 x64 on my work machine. I have to admin, that installation was extremely fast. I just put DVD and keep talking with one of our architects near whiteboard. We enough to close only one issue, while Windows was installed and running. 

Windows 7 beta fish

There are number of visual glitches, but it’s beta after all. Next thing is to install drivers. Everything was great (it even find and install fingerprint reader), except three strange drivers on my Lenovo W500, that Windows 7 refused to find:

  • PCI Serial Port
  • PCI Simple Communications Controller
  • SM Bus Controller

What can be those drivers? The clue was in SM Bus. It something related to board chipset. So, just checked Intel AMT, Intel PM45 and Intel LMS. My approximation was right, Windows 7 (and Microsoft Windows Update service) has no information regarding Intel stuff while all other (more rare drivers were installed fluently). I also need to install three of those drivers in Windows Vista compatibility mode in order to make it works.

Why this happen? Why it’s so hard to two huge conglomerates to work together in order to bring customers better installation experience? It seemed, that Lenovo did huge work with Microsoft to adopt its hardware drivers for Windows 7. Even switchable graphic cards worked perfect without additional drivers. So why Lenovo can, while Intel cannot?

I believe, that the problem is with Intel, who self fighting not to loss high end (and cost) processors, when the market requests low cost Atom-based machines with low power, yet good performing graphic processors.

Regarding biometric devices and switchable graphics. If you want to be able to login to domain with your fingerprint, be sure, that you visited Control Panel\Hardware and Sound\Biometric Devices\Change settings and check this option. By default it’s off.

Login to domain with fingerprint on Windows 7

Also it not seemed, that Windows 7 supports hybrid graphic cards. So unless I’ll find a way to get rid of this issue, I have to use Lenovo switchable graphics utility…

Next thing was to install gentlemen’s assembly:

  • Windows Live Essentials
  • Microsoft Office 2007 + SPs
  • Total Commander
  • Skype
  • Virtual PC 2008 SP1
  • Visual Studio 2008 + SP1

All installations were fine, except small problem with business edition of Skype. Newly introduced Action Center advised me to install 4.0 beta version of Skype to prevent compatibility issues.

Windows 7 Action Center

Another problem (not really Windows, but Microsoft related) is a time, that takes to install Visual Studio. For some reason installation of Office (which is not smaller, then VS) takes about 5 minutes on my machine, when for Visual Studio it takes more, then 40 minutes to be installed.Devdiv guys, please do something with this installer.

So two restarts and here we go. Windows 7 with all necessary software installed. Now issues started.

The only disappointment was because of Windows Experience Index (140GB 7200RPM hard disk is not big and fast enough for this version of OS). If this not, what is?

image

But it can be fixed easily by disabling cache on disk Device Manager –> Disk Drives –> Uncheck “Disk write caching policy”.

image

After doing this your system will run much faster and score will be increased.

image

I cannot understand the reason it checked by default for non solid state drives, which unsuitable for fast caching.

Switchable graphic cards are also seemed, to be an issue for Windows 7. It does not supported by now to switch graphic cards. All you can do is to pitch BIOS for denying OS from display driver detection and set the card you want. Here how my machine scores looks like with second graphic card enabled.

image

Taskbar is for fun, not for work

First of all new branded taskbar. How I supposed to distinct what running and what don’t? Shinny borders and backgrounds? Cool, but not really helpful for me. Just for test try to set “Hide when minimized” option for Outlook 2007 and then detect whether it running or not. Ah, yes, I have to go via tinny arrow to configure taskbar icons – too bad.

Another issue with this bar is configuration of shortcuts. Just in case, sometimes I want to run programs minimized or maximized or set start keys (right click on shortcut and Properties). How should I do it for pinned items?

 image

I understand, that for 5 years Microsoft tried somehow to prevent from developers to junk users notification area on taskbar, by hiding, swapping and moving things there. Finally, they managed to solve it by putting all trash into big shiny icons? Just take a look on Microsoft Messenger appearance in tasksbar. You have to run it in Vista compatibility mode in order to prevent it putting icon in this area? Too bad! This not called “feature complete” for sure.

Software compatibility

Yes, not everything perfect. For example drag and drop (DragonDrop) for Virtual PC will not work in regular mode in Windows 7. You have to create shared folder to workaround it. All programs, required elevated permission (those which triggered UAC on Vista all the time) will ask you for run only once, but if you accidently pressed anything else, then Allow, you’ll never be able to run it again (unless resetting UAC credentials in Windows). Also all those great programs, not required installations or any registry changes (for example Notepad++ or WinSCP will always treated as suspicious by Windows Defender, thus will start very slow all the time and some times required to be sent “for inspection”. This is general fail of Defender. Why me (as user) should wait you (as service provider) to check something. Do it on background, if you want to…

My first BSoD

Yes, I did it. I never was able to get Blue Screen of Death on Windows Vista. Here it happened after another restart. The reason was very funny: I did not closed Outlook before restarted Windows 7 (this fade screen with your applications will be forcibly closed). Yes, it was not really major BSoD. Windows made memory dump to prevent future crashes and send information. BTW, if you want to be able to report problems, you should use keys from Connect website, rather, then from MSDN. Beta reporting services is sensitive to product key.

Background services or what is really missing

My overall experience of Windows 7 is 7 of 10. It is major improvement of Windows Vista, but it still far from being perfect. I would advice to add OS foreground task dispatching. There are too many developers (also Microsoft’s, who trying to perform long tasks in UI thread). I think, that operation system should handle such cases and dispatch jobs to background to prevent UI freeze.

image

Another thing, is to find good compromise between annoying user and smart operations. Other words, do not try to assume what customer want to do, let him to decide (or at least enable such option). Good example for this is very odd Clear Type wizard. What would you answer to such question?

Click whatever it looks the same, just fix it!

Why I need to see the same stuff three times, when all I want it file manager?

You have a lot of documents, misics, pictures and videos

Stop trying to replace software. You already screwed with Microsoft Valet.

image

ISO file burn directly from Windows is really great feature, but an ability to mount iso images as virtual disks would be much better.

Other words, if you, Microsoft, want to create great operation system – do operation system, do not try to complete OS issues with another nice to have features. But no words – great work. Thank you.

Ah, and do not forget to fire everybody in IE dev team… It awful and has no future.

Next time we’ll speak about developer point of view to Windows 7.

Windows 7 beta is available for download

Shortly after latest beta version of Windows 7 (build 7000) leaked, Microsoft released this build officially via MSDN. Currently this build is only available for MSDN subscribers (including product key), thus I believe, that it will be available for public download really soon.

Also, if you’re planning to install this build on your working machine, be sure, to install KB961367 in order to prevent corruption of MP3 files.

 image

In addition to Windows 7, there are few other downloads are available: new beta of Windows Sever 2008 R2, new version of WDK for Windows 7 (7.0.7000.1), updated WDK for Windows Vista (6001.18002) + WDK for SP2.

So charge your downloaders and notify IT managers about extremely high traffic expected :)

Read and use FM radio (or any other USB HID device) from C#

Last time we spoke about reading and decoding RDS information from FM receivers. Also we already know how to stream sound from DirectSound compatible devices. However, before we can do it, we should be able to “speak” with such devices. So, today we’ll spoke about detection and reading information from Radio USB adapters (actually from any Human Input Devices). Let’s start.

USB FM HID

First, if you want to do it, go and buy such device. The are not a lot of alternatives, but if you’ll seek, you’ll find it very quickly.

So, let’s start. First of all, we’ll use platform invoke to get and set the information. Also, we have to preserve handle of the device from being collected by GC. After we’ll finish using the device, we’ll have to dispose it. Thus it makes sense to inherit from SafeHandle and IDisposable.

[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
public class USBDevice : SafeHandleZeroOrMinusOneIsInvalid, IDisposable {

Next, we’ll set a number of arguments, that will be in use during the device lifetime.

public uint ProductID { get; private set; }
public uint VendorID { get; private set; }
public uint VersionNumber { get; private set; }
public string Name { get; private set; }
public string SerialNumber { get; private set; }
public override bool IsInvalid { get { return !isValid; } }

internal ushort FeatureReportLength { get; private set; }
internal ushort[] Registers { get; set; }

Now, we have to find it. The best way of detection human input devices is by product and vendor IDs. Those values are always unique for certain device type.

[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
internal USBDevice(uint pid, uint vid) : base(true) { findDevice(pid, vid); }

Next step is to find a device. To do this, we have to provide extern interfaces to methods of hid.dll and setupapi.dll. Here all methods we will use in our class

[SuppressUnmanagedCodeSecurity()]
internal static class Native {
   #region methods
   [DllImport("hid.dll", SetLastError = true)]
   internal static extern void HidD_GetHidGuid(
      ref Guid lpHidGuid);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_GetAttributes(
      IntPtr hDevice,
      out HIDD_ATTRIBUTES Attributes);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_GetPreparsedData(
      IntPtr hDevice,
      out IntPtr hData);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidD_FreePreparsedData(
      IntPtr hData);

   [DllImport("hid.dll", SetLastError = true)]
   internal static extern bool HidP_GetCaps(
      IntPtr hData,
      out HIDP_CAPS capabilities);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetFeature(
      IntPtr hDevice,
      IntPtr hReportBuffer,
      uint ReportBufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_SetFeature(
      IntPtr hDevice,
      IntPtr ReportBuffer,
      uint ReportBufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetProductString(
      IntPtr hDevice,
      IntPtr Buffer,
      uint BufferLength);

   [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
   internal static extern bool HidD_GetSerialNumberString(
      IntPtr hDevice,
      IntPtr Buffer,
      uint BufferLength);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern IntPtr SetupDiGetClassDevs(
      ref Guid ClassGuid,
      [MarshalAs(UnmanagedType.LPTStr)] string Enumerator,
      IntPtr hwndParent,
      UInt32 Flags);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern bool SetupDiEnumDeviceInterfaces(
      IntPtr DeviceInfoSet,
      int DeviceInfoData,
      ref  Guid lpHidGuid,
      uint MemberIndex,
      ref  SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData);

   [DllImport("setupapi.dll", SetLastError = true)]
   internal static extern bool SetupDiGetDeviceInterfaceDetail(
      IntPtr DeviceInfoSet,
      ref SP_DEVICE_INTERFACE_DATA lpDeviceInterfaceData,
      IntPtr hDeviceInterfaceDetailData,
      uint detailSize,
      out uint requiredSize,
      IntPtr hDeviceInfoData);

   [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
   [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
   internal static extern IntPtr CreateFile(
         string lpFileName,
         uint dwDesiredAccess,
         uint dwShareMode,
         IntPtr SecurityAttributes,
         uint dwCreationDisposition,
         uint dwFlagsAndAttributes,
         IntPtr hTemplateFile);

   [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
   [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
   internal static extern bool CloseHandle(IntPtr hHandle);

Also, we will need a number of structures, such as device attributes and capabilities.

[StructLayout(LayoutKind.Sequential)]
internal struct SP_DEVICE_INTERFACE_DATA {
   public int cbSize;
   public Guid InterfaceClassGuid;
   public int Flags;
   public int Reserved;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
internal class PSP_DEVICE_INTERFACE_DETAIL_DATA {
   public int cbSize;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
   public string DevicePath;
}

[StructLayout(LayoutKind.Sequential)]
internal struct HIDD_ATTRIBUTES {
   public int Size; // = sizeof (struct _HIDD_ATTRIBUTES) = 10
   public UInt16 VendorID;
   public UInt16 ProductID;
   public UInt16 VersionNumber;
}
[StructLayout(LayoutKind.Sequential)]
internal struct HIDP_CAPS {
   public UInt16 Usage;
   public UInt16 UsagePage;
   public UInt16 InputReportByteLength;
   public UInt16 OutputReportByteLength;
   public UInt16 FeatureReportByteLength;
   [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
   public UInt16[] Reserved;
   public UInt16 NumberLinkCollectionNodes;
   public UInt16 NumberInputButtonCaps;
   public UInt16 NumberInputValueCaps;
   public UInt16 NumberInputDataIndices;
   public UInt16 NumberOutputButtonCaps;
   public UInt16 NumberOutputValueCaps;
   public UInt16 NumberOutputDataIndices;
   public UInt16 NumberFeatureButtonCaps;
   public UInt16 NumberFeatureValueCaps;
   public UInt16 NumberFeatureDataIndices;
}

And a number of system constants

internal const uint DIGCF_PRESENT = 0×00000002;
internal const uint DIGCF_DEVICEINTERFACE = 0×00000010;
internal const uint GENERIC_READ = 0×80000000;
internal const uint GENERIC_WRITE = 0×40000000;
internal const uint FILE_SHARE_READ = 0×00000001;
internal const uint FILE_SHARE_WRITE = 0×00000002;
internal const int OPEN_EXISTING = 3;
internal const int FILE_FLAG_OVERLAPPED = 0×40000000;
internal const uint MAX_USB_DEVICES = 16;

Now, we are ready to start. So let’s find all devices and get its information

Native.HidD_GetHidGuid(ref _hidGuid);
hHidDeviceInfo = Native.SetupDiGetClassDevs(ref _hidGuid, null, IntPtr.Zero, Native.DIGCF_PRESENT | Native.DIGCF_DEVICEINTERFACE);

Now, if a handle we get is valid, we should search our specific device. For this purpose, we have to read device interface information and then get details info about this device.

if (hHidDeviceInfo.ToInt32() > -1) {
   uint i = 0;
   while (!isValid && i < Native.MAX_USB_DEVICES) {
      var hidDeviceInterfaceData = new Native.SP_DEVICE_INTERFACE_DATA();
      hidDeviceInterfaceData.cbSize = Marshal.SizeOf(hidDeviceInterfaceData);
      if (Native.SetupDiEnumDeviceInterfaces(hHidDeviceInfo, 0, ref _hidGuid, i, ref hidDeviceInterfaceData)) {

Once we have all this and information is valid, let’s detect its capabilities

bool detailResult;
uint length, required;
Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, IntPtr.Zero, 0, out length, IntPtr.Zero);
var hidDeviceInterfaceDetailData = new Native.PSP_DEVICE_INTERFACE_DETAIL_DATA();
hidDeviceInterfaceDetailData.cbSize = 5; //DWORD cbSize (size 4) + Char[0] (size 1) for 32bit only!
var hDeviceInterfaceDetailData = Marshal.AllocHGlobal(Marshal.SizeOf(hidDeviceInterfaceDetailData));
Marshal.StructureToPtr(hidDeviceInterfaceDetailData, hDeviceInterfaceDetailData, true);
detailResult = Native.SetupDiGetDeviceInterfaceDetail(hHidDeviceInfo, ref hidDeviceInterfaceData, hDeviceInterfaceDetailData, length, out required, IntPtr.Zero);
Marshal.PtrToStructure(hDeviceInterfaceDetailData, hidDeviceInterfaceDetailData);
if (detailResult) {

To do this, we have to create memory file first and then share device attributes by using this file.

base.handle = Native.CreateFile(hidDeviceInterfaceDetailData.DevicePath,
                        Native.GENERIC_READ |
                        Native.GENERIC_WRITE,
                        Native.FILE_SHARE_READ |
                        Native.FILE_SHARE_WRITE,
                        IntPtr.Zero,
                        Native.OPEN_EXISTING,
                        Native.FILE_FLAG_OVERLAPPED,
                        IntPtr.Zero);
                     if (base.handle.ToInt32() > -1) {
                        Native.HIDD_ATTRIBUTES hidDeviceAttributes;
                        if (Native.HidD_GetAttributes(base.handle, out hidDeviceAttributes)) {

All the rest is straight forward. Just compare info retrieved with one we already have. And, of cause, release all resources were used (remember, we’re in win32 api world!)

if ((hidDeviceAttributes.VendorID == vid) && (hidDeviceAttributes.ProductID == pid)) {
                              isValid = true;
                              ProductID = pid;
                              VendorID = vid;
                              VersionNumber = hidDeviceAttributes.VersionNumber;
                              IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string;
                              if (Native.HidD_GetProductString(this.handle, buffer, 126)) Name = Marshal.PtrToStringAuto(buffer);
                              if (Native.HidD_GetSerialNumberString(this.handle, buffer, 126)) SerialNumber = Marshal.PtrToStringAuto(buffer);
                              Marshal.FreeHGlobal(buffer);
                              var capabilities = new Native.HIDP_CAPS();
                              IntPtr hPreparsedData;
                              if (Native.HidD_GetPreparsedData(this.handle, out hPreparsedData)) {
                                 if (Native.HidP_GetCaps(hPreparsedData, out capabilities)) FeatureReportLength = capabilities.FeatureReportByteLength;
                                 Native.HidD_FreePreparsedData(hPreparsedData);
                              }
                              break;
                           }
                        } else {
                           Native.CloseHandle(base.handle);
                        }
                     }
                  }
                  Marshal.FreeHGlobal(hDeviceInterfaceDetailData);
               }
               i++;

            }

Now we have a handle to our device and can manipulate it. Like this:

using (var device = USBRadioDevice.FindDevice(0×0000, 0×1111)) {

}

But we still have to provide methods for such usage. Here there are no very complicated code.

public static USBDevice FindDevice(uint pid, uint vid) {
   var device = new USBDevice(pid,vid);
   var fillRegisters = device.InitRegisters();
   if (!device.IsInvalid && fillRegisters) return device;
   else throw new ArgumentOutOfRangeException(string.Format("Human input device {0} was not found.", pid));
}

public override string ToString() {
   return string.Format("{0} (Product:{1:x}, Vendor:{2:x}, Version:{3:x}, S/N:{4})", Name, ProductID, VendorID, VersionNumber, SerialNumber);
}

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected override bool ReleaseHandle() {
   return Native.CloseHandle(base.handle);
}

#region IDisposable Members
public void Dispose() {
   Dispose(true);
   GC.SuppressFinalize(this);

}
[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
void IDisposable.Dispose() {
   if (base.handle != null && !base.IsInvalid) {
      // Free the handle
      base.Dispose();
   }
}

#endregion

We done. Have a nice day and be good people.

What boots faster – Netbook, powered Windows XP or Nokia E71 mobile phone?

Some days ago, somebody from Microsoft was shocked, when I told him, that I’m planning to run Windows XP (and later Windows 7) as operation system for mission critical automotive device. He even checked with Windows XP embedded team boot times for XP. They told him, that the minimum can be achieved is about 40 seconds cold boot and 30 seconds from hibernate state. I was upset and decided to tweak my system for smallest possible boot time. Here the result video. This is not the limit. I believe, that I’ll be able to decrease Windows XP boot time to less, then 10 seconds with a bit more efforts.

Note: This is absolutely authentic and non-touched video, recorded today by me, comparing boot time of Windows XP on unbranded weak netbook (Atom 1.6, 128MB and 8G SSD) and my Nokia E71 mobile phone. 15 seconds boot time of Windows XP achieved by tweaking only well known registry values and OS configuration values without special profundity of system settings.

Now the question: with todays’ devices, why we are not running XP for mobile and automotive mission critical devices?

Programming for Windows 7

Well, Windows 7 is going to be released by the end of next year. This is great news, because it seemed, that Microsoft finally understand how to get the best of Windows Vista and make it to work not only on monster machines.

image

It even works on new brandy my wife’s pinky machine. And if it works there and my wife is happy with it, this OS going to be very impressive.

image

But from the other hand, we, as developers should be ready today to developer Windows 7 ready application (by the way, Vista Battery Saver works for Windows 7 as well as for Windows Vista, in spite of the fact, that power management in Windows 7 was improved dramatically). So let’s start!

First thing we need is to read big Windows 7 Developer Guide. This document will explain most of new features for developers to build applications right. What is includes?

Windows Driver Kit (WDK) 3.0

Basically, Windows 7 works with Vista drivers, however, hibernation, power management, networking, PREfast will work much better. You also will have new WMI access for reliability monitors and ACPI.

Management and deployment

By default Windows 7 uses PowerShell 2.0 and Windows Installer. For PowerShell it includes enhanced cmdlets to manage Active Directory, IIS, etc. For Windows Installer, you finally can build “chainers” by yourself (the same approach, used for latest deployment of Microsoft products such as Silverlight, Visual Studio 2008 SP1 etc.) Also, you can get advantage by using Windows Filtering Platform (Firewall) and User Account Control (UAC) from inside your application by using new APIs.

Performance

The most significant change in Windows 7 for end-user point of view is improved performance. Windows 7 kernel is much smaller, that kernel of Windows Vista. Also it uses specific patterns to decrease background activities on low power, based on system triggers. New user-mode and kernel-mode APIs are used by Windows Drivers Foundation much more efficiently. Also system services are much smarter. For example, DCIA starts only when you connect new hardware. After drivers were installed the service shuts down. The same approach used by domain join, GP changes, new IP fetching etc. Windows 7 knows to run and stop services, based on system events, which decreases average work load and enhances whole system performance.

Multi-touch gestures and Interia API and used interface in general

Yes, you can use this API for your applications. Finally we can have more, then just mouse. And it is not only about multiple mouse devices. We can use single finder panning, raw touch input data, internal multitouch ink recognition, which is also supports math. Also it uses build-in MathML export feature.

There are a lot of other enhancements, such as smart bars, windows’ stacking, gadget desktop (it does not eat battery as external process anymore), system ribbon menu integration. etc

Graphics

Direct 11, new Direct2D, DirectWrite (we can turn text anti-aliasing for small fonts, hurrah!), improved WIC, DX/GDI interoperability on system level with automatic fallback for weak hardware (yes, you should not be worry about it anymore). Also new video and audio format support with human readable interfaces. Yes, no more DirectDraw hacks. We can use new high level interfaces such as MFPlay to manage playbacks, Source Reader for decoding, Sink Writer for transcoders and re-coding compressions.

Web and communication

WCF is inside, as well as distributed routing table for peer-to-peer operations. BranchCache – new technology to reduce WAN traffic and latency.

Also Windows 7 is compatible with OpenSearch (I told, that Microsoft does not know to build search engines). Sharepoint integration and environment sensors platform, that can be used either for desktop and web applications.

There are much more features, that makes Windows 7 to pretend to be very good operation system. If you want to learn more about all those Windows 7 new features, I highly advice you to download and read this document. It includes most of new features of new OS with explanations and screenshots to make your learn and understand what can your future application do with all those new features.

Have a nice day and be good people.

BTW, if you have PDC version of Windows 7 and want to unlock it for using of some cool features, introduced during keynotes, it worth to visit here and learn how to :)

Download Windows 7 Developer Guide and start programming.

Recommended

 

Sponsor


Partners

WPF Disciples
Dreamhost
Code Project