title: Proper way of implementing IParentAndItem COM Interface
body: <p>I'm implementing an object model based on the <code>IShellItem/IShellItem2</code> COM interfaces in C# and am currently working on item enumeration. I want to avoid using <code>BindToHandler</code> as it is considered to have a notable impact on performance, this is why i want to use the <code>IParentAndItem</code> interface and its underlying caching mechanisms.</p>
  
  <p>According to MSDN the methods of the <code>IParentAndItem</code> interface are defined as follows:</p>
  
  <pre><code>HRESULT GetParentAndItem(
    [out, optional]  PIDLIST_ABSOLUTE *ppidlParent,
    [out, optional]  IShellFolder **ppsf,
    [out, optional]  PITEMID_CHILD *ppidlChild
  );
  
  HRESULT SetParentAndItem(
    [in]  PCIDLIST_ABSOLUTE pidlParent,
    [in]  IShellFolder *psf,
    [in]  PCUITEMID_CHILD pidlChild
  );
  </code></pre>
  
  <p>However the following translation into a C# COM Interop interface results in an <code>AccessViolationException</code>:</p>
  
  <pre><code>[ComImport,
   Guid("B3A4B685-B685-4805-99D9-5DEAD2873236"), 
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  public interface IParentAndItem
  {
      void GetParentAndItem(out IntPtr ppidlParent, out IShellFolder ppsf, out IntPtr ppidlChild);
  
      void SetParentAndItem(IntPtr pidlParent, ref IShellFolder psf, IntPtr pidlChild);
  }
  </code></pre>
  
  <p>I'm using the interface to cast from an <code>IShellItem2</code> to get the <code>IShellFolder</code> representation using its <code>GetParentAndItem</code> method:</p>
  
  <pre><code>IParentAndItem pni = si as IParentAndItem; // 'si' is the IShellItem2
  if(pni != null)
  {
     IntPtr ppidlParent, ppidlChild;
     IShellFolder ppsf;
     pni.GetParentAndItem(out ppidlParent, out ppsf, out ppidlChild); // &lt;-- throws AccessViolationException
     // Work with ppsf, e.g. EnumObjects
  }
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>The correct declaration of <code>IParentAndItem</code> as pointed out by Hans Passant:</p>
  
  <pre><code>[ComImport,
   Guid("B3A4B685-B685-4805-99D9-5DEAD2873236"), 
   InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
  public interface IParentAndItem
  {
      void SetParentAndItem(IntPtr pidlParent, IShellFolder psf, IntPtr pidlChild);
  
      void GetParentAndItem(out IntPtr ppidlParent, out IShellFolder ppsf, out IntPtr ppidlChild);
  }
  </code></pre>
  
  <p>After implementing <code>IParentAndItem</code> and replacing <code>BindToHandler</code> with <code>GetParentAndItem</code> all i can say it is really worth going this route performance wise.</p>
  
  <p>Be sure to free memory allocated in <code>GetParentAndItem</code> for the two PIDLs by calling <code>Marshal.FreeCoTaskMem</code> after you're done with those.</p>