title: Accessing Files On Server By Specifying Credentials
body: <p>Our company has a share point document server where the UNC looks something like this: \\theserver.ourdomain.com\rootdirectory</p>
  
  <p>Currently this drive is mapped to the Z:\ on my local computer. To access the Z:\ you have to specify (each time you login) credentials (in our case is it our username and password we logged on with) to access the folders and files in the <strong>rootdirectory</strong>.</p>
  
  <p>I am in a situation where I need to copy files onto the share point server. I want to be able to copy files onto the server without using the mapped network drive (not have to specify Z:\ in the path). How can I supply credentials so that I can perform basic IO functions like GetDirectories(), GetFiles(), IO.File.Copy() etc...?</p>
  
  <p>I have looked into the following things but was unsuccessful in making them work:</p>
  
  <ol>
  <li><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v=vs.85%29.aspx" rel="nofollow">LogonUser</a> API call by specifying plain text user name and password, then taking the token from that call and impersonating that user using a new instance of the WindowsIdentity class. Was able to get the token, but the impersonation didn't seem to work. Kept getting access denied errors.</li>
  <li><p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa375177%28v=vs.85%29.aspx" rel="nofollow">CredUIPromptForCredentials</a>/<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa375178%28v=vs.85%29.aspx" rel="nofollow">CredUIPromptForWindowsCredentials</a> API calls, but I realize these are just for a fancy Windows UI where you can enter your credentials into and actually don't do anything.</p>
  
  <pre><code>&lt;DllImport("advapi32.dll", SetLastError:=True)&gt; _
  Private Shared Function LogonUser(lpszUsername As String, lpszDomain As String, _
                                            lpszPassword As String, dwLogonType As Integer, _
                                            dwLogonProvider As Integer, ByRef phToken As IntPtr) As Boolean
  End Function
  
  &lt;DllImport("kernel32.dll", CharSet:=CharSet.Auto)&gt; _
  Private Shared Function CloseHandle(handle As IntPtr) As Boolean
  End Function
  
  '// logon types
  Public Const LOGON32_LOGON_NETWORK As Integer = 3
  Public Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9
  
  '// logon providers
  Public Const LOGON32_PROVIDER_WINNT50 As Integer = 3
  Public Const LOGON32_PROVIDER_WINNT40 As Integer = 2
  Public Const LOGON32_PROVIDER_WINNT35 As Integer = 1
  Public Const LOGON32_PROVIDER_DEFAULT As Integer = 0
  
  Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      Dim token = IntPtr.Zero
      Dim success = LogonUser("username", "domain", "password", _
                              LOGON32_LOGON_NEW_CREDENTIALS, _
                              LOGON32_PROVIDER_DEFAULT, token)
  
      If Not success Then
          Me.RaiseLastWin32Error()
      End If
  
      Using identity = New WindowsIdentity(token)
          Using impersonated = identity.Impersonate()
              Try
                  Dim info = New DirectoryInfo("\\theserver.ourdomain.com\rootdirectory\")
                  Dim files = info.GetDirectories()
              Catch ex As Exception
              Finally
                  impersonated.Undo()
              End Try
              If Not CloseHandle(token) Then
                  Me.RaiseLastWin32Error()
              End If
          End Using
      End Using
  
  End Sub
  
  Private Sub RaiseLastWin32Error()
      Dim hr = Marshal.GetLastWin32Error()
      Dim ex = Marshal.GetExceptionForHR(hr)
  
      If ex IsNot Nothing Then
          Throw ex
      End If
      Throw New SystemException(String.Format("Call resulted in error code {0}", hr))
  End Sub
  </code></pre></li>
  </ol>