Files
sqltoolsservice/src/Microsoft.SqlTools.ServiceLayer/Credentials/Win32/CredentialSet.cs
Benjamin Russell 41198e9357 Adding sr.strings file and removing hard-coded strings (#52)
* Strings sweep for connection service

* String sweep for credentials service

* String sweep for hosting

* String sweep for query execution service

* String sweep for Workspace service

* Renaming utility namespace to match standards

Renaming Microsoft.SqlTools.EditorServices.Utility to
Microsoft.SqlTools.ServiceLayer.Utility to match the naming changes done a
while back. Also renaming them on the files that use them

* Namespace change on reliable connection

* Adding the new resx and designer files

* Final bug fixes for srgen

Fixing flakey moq package name

* Removing todo as per @kevcunnane

* Adding using statements as per @llali's comment

* Fixing issues from broken unit tests

Note: This feature contains changes that will break the contract for
saving as CSV and JSON. On success, null is returned as a message instead
of "Success". Changes will be made to the vscode component to handle this
change.
2016-09-16 16:18:25 -07:00

113 lines
3.2 KiB
C#

//
// Code originally from http://credentialmanagement.codeplex.com/,
// Licensed under the Apache License 2.0
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.SqlTools.ServiceLayer.Utility;
namespace Microsoft.SqlTools.ServiceLayer.Credentials.Win32
{
public class CredentialSet: List<Win32Credential>, IDisposable
{
bool _disposed;
public CredentialSet()
{
}
public CredentialSet(string target)
: this()
{
if (string.IsNullOrEmpty(target))
{
throw new ArgumentNullException(nameof(target));
}
Target = target;
}
public string Target { get; set; }
public void Dispose()
{
Dispose(true);
// Prevent GC Collection since we have already disposed of this object
GC.SuppressFinalize(this);
}
~CredentialSet()
{
Dispose(false);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
if (Count > 0)
{
ForEach(cred => cred.Dispose());
}
}
}
_disposed = true;
}
public CredentialSet Load()
{
LoadInternal();
return this;
}
private void LoadInternal()
{
uint count;
IntPtr pCredentials = IntPtr.Zero;
bool result = NativeMethods.CredEnumerateW(Target, 0, out count, out pCredentials);
if (!result)
{
Logger.Write(LogLevel.Error, string.Format("Win32Exception: {0}", new Win32Exception(Marshal.GetLastWin32Error()).ToString()));
return;
}
// Read in all of the pointers first
IntPtr[] ptrCredList = new IntPtr[count];
for (int i = 0; i < count; i++)
{
ptrCredList[i] = Marshal.ReadIntPtr(pCredentials, IntPtr.Size*i);
}
// Now let's go through all of the pointers in the list
// and create our Credential object(s)
List<NativeMethods.CriticalCredentialHandle> credentialHandles =
ptrCredList.Select(ptrCred => new NativeMethods.CriticalCredentialHandle(ptrCred)).ToList();
IEnumerable<Win32Credential> existingCredentials = credentialHandles
.Select(handle => handle.GetCredential())
.Select(nativeCredential =>
{
Win32Credential credential = new Win32Credential();
credential.LoadInternal(nativeCredential);
return credential;
});
AddRange(existingCredentials);
// The individual credentials should not be free'd
credentialHandles.ForEach(handle => handle.SetHandleAsInvalid());
// Clean up memory to the Enumeration pointer
NativeMethods.CredFree(pCredentials);
}
}
}