title: C# Access a local folder with admin account credentials
body: <p>I have two user accounts in my computer</p>
  
  <p><strong>User 1 (regular user)</strong></p>
  
  <p><strong>Admin</strong></p>
  
  <p>Now I have folder "<strong>e:\Folder1</strong>" for which only Admin account has full access. User ! cannot access the folder.</p>
  
  <p>I have a WPF Application Where It would run only within the <strong>User 1</strong> account. I want the user 1 to user the wpf application to access "<strong>Folder1</strong>".</p>
  
  <p>I want to know how to do it using C#. </p>
  
  <p>I tried the following it doesnt work.</p>
  
  <pre><code>NetworkCredential theNetworkCredential = new NetworkCredential(@"admin", "pass");
              CredentialCache theNetCache = new CredentialCache();
              theNetCache.Add(new Uri(@"E:\SDAVideo"), "Basic", theNetworkCredential);
              string[] theFolders = Directory.GetDirectories(@"E:\SDAVideo");
  </code></pre>
  
  <hr>
  
  <p>Here is what I have tried.
  Using following code I am able to get the Windows of Identity of Admin user account</p>
  
  <pre><code>SafeTokenHandle safeTokenHandle;
          try
          {
              const int LOGON32_PROVIDER_DEFAULT = 0;
              //This parameter causes LogonUser to create a primary token. 
              const int LOGON32_LOGON_INTERACTIVE = 2;
  
              // Call LogonUser to obtain a handle to an access token. 
              bool returnValue = LogonUser("admin", "", "pass",
                  LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                  out safeTokenHandle);
              if (false == returnValue)
              {
                  int ret = Marshal.GetLastWin32Error();
                  Debug.Write("\nLogonUser failed with error code : " + ret);
                  throw new System.ComponentModel.Win32Exception(ret);
              }
              using (safeTokenHandle)
              {
                  Debug.Write("\nDid LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
                  Debug.Write("\nValue of Windows NT token: " + safeTokenHandle);
  
                  // Check the identity.
                  Debug.Write("\nBefore impersonation: "
                      + WindowsIdentity.GetCurrent().Name);
                  Debug.Write("\nWriteAccess before: " + DirectoryHasPermission(@"E:\SDAVideo", WindowsIdentity.GetCurrent(), FileSystemRights.Write));
                  // Use the token handle returned by LogonUser. 
                  using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
                  {
  
                      // Check the identity.
                      Debug.Write("\nAfter impersonation: "
                          + WindowsIdentity.GetCurrent().Name);
                      AccessFolder(WindowsIdentity.GetCurrent(), @"E:\SDAVideo");
                      //Debug.Write("\nWriteAccess after: " + DirectoryHasPermission(@"E:\SDAVideo", WindowsIdentity.GetCurrent(), FileSystemRights.Write));
                  }
                  // Releasing the context object stops the impersonation 
                  // Check the identity.
                  Debug.Write("\nAfter closing the context: " + WindowsIdentity.GetCurrent().Name);
  
              }
  
          }
          catch (Exception ex)
          {
              Debug.Write("\n1" + ex.ToString());
          }
  
  public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
      {
          private SafeTokenHandle()
              : base(true)
          {
          }
  
          [DllImport("kernel32.dll")]
          [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
          [SuppressUnmanagedCodeSecurity]
          [return: MarshalAs(UnmanagedType.Bool)]
          private static extern bool CloseHandle(IntPtr handle);
  
          protected override bool ReleaseHandle()
          {
              return CloseHandle(handle);
          }
      }
  </code></pre>
  
  <hr>
  
  <pre><code>public static bool DirectoryHasPermission(string DirectoryPath,  WindowsIdentity identity, FileSystemRights AccessRight)
      {
          //if (string.IsNullOrEmpty(DirectoryPath)) return false;
  
          try
          {
              AuthorizationRuleCollection rules = Directory.GetAccessControl(DirectoryPath).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));
              //WindowsIdentity identity = WindowsIdentity.GetCurrent();
              Debug.Write("\nUSER: " + identity.Name);
              foreach (FileSystemAccessRule rule in rules)
              {
                  if (identity.Groups.Contains(rule.IdentityReference))
                  {
                      if ((AccessRight &amp; rule.FileSystemRights) == AccessRight)
                      {
                          if (rule.AccessControlType == AccessControlType.Allow)
                              return true;
                      }
                  }
              }
          }
          catch (Exception ex)
          {
              Debug.Write("\n2 " + ex.ToString());
          }
          return false;
      }
  </code></pre>
  
  <hr>
  
  <pre><code>public static void AccessFolder(WindowsIdentity identity, string DirectoryPath)
      {
          try
          {
              Debug.Write("\nUSER: " + identity.Name);
              DirectoryInfo myDirectoryInfo = new DirectoryInfo(DirectoryPath);
              DirectorySecurity myDirectorySecurity = myDirectoryInfo.GetAccessControl();
  
              myDirectorySecurity.AddAccessRule(new FileSystemAccessRule(identity.Name, FileSystemRights.Write, AccessControlType.Allow));
  
              myDirectoryInfo.SetAccessControl(myDirectorySecurity);
              string pathString = System.IO.Path.Combine(DirectoryPath, "test.txt");
              if (!System.IO.File.Exists(pathString))
              {
                  using (System.IO.FileStream fs = System.IO.File.Create(pathString))
                  {
                      for (byte i = 0; i &lt; 100; i++)
                      {
                          fs.WriteByte(i);
                      }
                  }
              }
          }
          catch (Exception ex)
          {
              Debug.Write("\n3 " + ex.ToString());
          }
      }
  </code></pre>
  
  <p><strong>Error I get as follows</strong>
  System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.</p>
  
  <p>System.InvalidOperationException: Method failed with unexpected error code 1346.</p>
  
  <hr>
  
  <p>All of these failed, Only thing I am able to do is successfully get the Admin user windows identity.
  Now with that I need to solve the two issues
  1. How to check if app has write access using the windows identity of the admin
  2. If so how to write something into the folder.</p>