title: "Unknown error (0x80005000)" trying to read remote IIS 6 Metabase with DirectoryEntry and Impersonation (C#)
body: <p>(EDIT) <strong>The plot thickens:</strong> The same code (with no need for impersonation!) runs successfully from a Windows 7 client, but NOT from a Windows 2008 R2 client! Here's the code in question. (Original message follows code below.)</p>
  
  <pre><code>var entry = new DirectoryEntry("IIS://" + tbHost.Text + "/W3SVC", tbUsername.Text, tbPassword.Password);
  foreach (DirectoryEntry site in entry.Children)
  {
      Console.Write("Site {0}\n", site.Name);
      foreach (PropertyValueCollection prop in site.Properties)
          Console.Write("{0}={1}\n", prop.PropertyName, prop.Value);
  }
  </code></pre>
  
  <p>I read <a href="http://www.ureader.com/msg/163387.aspx" rel="nofollow noreferrer">here</a> that, for the IIS provider, you can't pass credentials when creating the <a href="http://msdn.microsoft.com/en-us/library/system.directoryservices.directoryentry.aspx" rel="nofollow noreferrer"><code>DirectoryEntry</code></a> object. You have to do <a href="http://www.codeproject.com/KB/cs/cpimpersonation1.aspx" rel="nofollow noreferrer">impersonation</a>. So I tried the following code, but I still get a COMException with a text of "Unknown error (0x80005000)" when I try to read a property, just as I did when I previously tried to pass username and password for the <code>DirectoryEntry</code> constructor. Here's the rundown:</p>
  
  <ul>
  <li><a href="http://msdn.microsoft.com/en-us/library/aa378184%28v=vs.85%29.aspx" rel="nofollow noreferrer"><code>LogonUser()</code></a> succeeds, credentials are OK. I had banged by head a little before I found out I had to use <code>LOGON32_LOGON_NEW_CREDENTIALS</code> instead of <code>LOGON32_LOGON_INTERACTIVE</code>.</li>
  <li>The remote machine is not in the same domain. Actually, it isn't in a domain at all. In fact, I put its name in the client's <code>hosts</code> file so I could get to it by name.</li>
  <li>Running <a href="http://support.microsoft.com/kb/840671" rel="nofollow noreferrer">Metabase Explorer</a> in the target machine shows me the key I want to read does exist. (See picture at end of the post.)</li>
  </ul>
  
  <p>.</p>
  
  <pre><code>const int LOGON32_LOGON_INTERACTIVE = 2;
  const int LOGON32_LOGON_NETWORK = 3;
  const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
  
  const int LOGON32_PROVIDER_DEFAULT = 0;
  const int LOGON32_PROVIDER_WINNT50 = 3;
  const int LOGON32_PROVIDER_WINNT40 = 2;
  const int LOGON32_PROVIDER_WINNT35 = 1;
  
  [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
  public static extern int LogonUser(String lpszUserName, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
  
  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  public extern static bool CloseHandle(IntPtr handle);
  
  [DllImport("kernel32.dll")]
  extern static int GetLastError();
  
  (...)
  
  IntPtr myToken = IntPtr.Zero;
  if (LogonUser(tbUsername.Text, tbHost.Text, tbPassword.Password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref myToken) == 0)
  {
      int causingError = GetLastError();
      throw new System.ComponentModel.Win32Exception(causingError);
  }
  
  WindowsImpersonationContext myMission = WindowsIdentity.Impersonate(myToken);
  
  string mbUri = "IIS://" + tbHost.Text + "/MimeMap";
  DirectoryEntry myDirEntry = new DirectoryEntry(mbUri);
  Console.Write("{0}\n", myDirEntry.Properties["KeyType"]);
  
  myDirEntry.Close();
  myMission.Undo();
  if (myToken != IntPtr.Zero)
      CloseHandle(myToken);
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/lrBAy.png" alt="enter image description here"></p>