Are you using a drive name or a network share name for the path to
srcsafe.ini?
Joe
A UNC network share path.
I have even managed to successfully impersonate myself as the user, and
have ensured that the share and NTFS permissions on the shared folder and
set to allow Everyone access (purely for tests reasons), but to no avail.
Anyone any ideas what the minumum permissions should be, so i can secure
the folder once i have it working?
Here is my complete C# source code (it'll probably wrap, so be wary of
simply cutting and pasting) :-
using System;
using System.Security;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using SourceSafeTypeLib;
namespace BuildItTest
{
/// <summary>
/// Summary description for WebForm1.
/// </summary>
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label CurrentVerLabel;
protected System.Web.UI.WebControls.Label VersionNo;
protected System.Web.UI.WebControls.Label VerHistoryLabel;
protected System.Web.UI.WebControls.TextBox VersionHistory;
public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;
WindowsImpersonationContext impersonationContext;
[DllImport("advapi32.dll", CharSet=CharSet.Auto)]
public static extern int LogonUser(String lpszUserName,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll",
CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)]
public extern static int DuplicateToken(IntPtr hToken, int
impersonationLevel, ref IntPtr hNewToken);
private void Page_Load(object sender, System.EventArgs e)
{
// Displays current user, usually ASPNET.
//If web.config is setup with impersonate=true, then current user is
IUSR_MACHINENAME.
VersionHistory.Text =
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
// Attempt to get VSS info without impersonating a different user.
// Causes Sourcesafe database path <user> does not exist error.
// COMException (0x8004d117)
// GetVSSFileHistory();
// <validusername>, <domain> & <usrpwd> are obviously valid strings in
my real code.
if(impersonateValidUser("<validusername>", "<domain>", "<usrpwd>"))
{
VersionHistory.Text = VersionHistory.Text + Environment.NewLine +
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
// Following function call results in same COMException (0x8004d117)
GetVSSFileHistory();
undoImpersonation();
}
else
{
VersionHistory.Text = VersionHistory.Text + Environment.NewLine +
"UNABLE TO IMPERSONATE USER!";
}
// Redisplays current user (again ASPNET)
VersionHistory.Text = VersionHistory.Text + Environment.NewLine +
System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void GetVSSFileHistory()
{
// <validVSSusr> & <validVSSpwd> are again valid strings
string UserName = "<validVSSusr>";
string Password = "<validVSSpwd>";
string SrcSafeIni = @"\\SERVER_ONE\VSS\SRCSAFE.INI";
// When attempting to use local srcsafe.ini file
// (which simply has an #include \\SERVER_ONE\VSS\SRCSAFE.INI in it),
// i get a [COMException (0x8004d849): Invalid handle.] error.
//string SrcSafeIni = @"C:\Program Files\Microsoft Visual
Studio\VSS\SRCSAFE.INI";
VSSDatabase objVssDatabase = new VSSDatabaseClass();
objVssDatabase.Open(SrcSafeIni, UserName, Password);
SourceSafeTypeLib.IVSSItem objProject =
objVssDatabase.get_VSSItem(@"$/Bookings/bookings",false);
SourceSafeTypeLib.IVSSItem objFile =
objVssDatabase.get_VSSItem(@"$/Bookings/bookings/text.asp",false);
foreach(SourceSafeTypeLib.IVSSVersion objVssVersion in
objFile.get_Versions(0))
{
VersionHistory.Text = VersionHistory.Text + "User: " +
objVssVersion.Username;
VersionHistory.Text = VersionHistory.Text + "Date: " +
objVssVersion.Date.ToString();
VersionHistory.Text = VersionHistory.Text + "Comment: " +
objVssVersion.Comment;
VersionHistory.Text = VersionHistory.Text + "-------------";
}
}
private bool impersonateValidUser(String userName, String domain, String
password)
{
WindowsIdentity tempWindowsIdentity;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if(LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if(DuplicateToken(token, 2, ref tokenDuplicate) != 0)
{
tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
impersonationContext = tempWindowsIdentity.Impersonate();
if (impersonationContext != null)
return true;
else
return false;
}
else
return false;
}
else
return false;
}
private void undoImpersonation()
{
impersonationContext.Undo();
}
}
}
--
Thanks in advance
Dan Williams