HighTechTalks DotNet Forums  

Access Denied in method SetLocalTime

Dotnet Framework (Interop) microsoft.public.dotnet.framework.interop


Discuss Access Denied in method SetLocalTime in the Dotnet Framework (Interop) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Newsgroup Microsoft
 
Posts: n/a

Default Access Denied in method SetLocalTime - 07-03-2009 , 09:04 AM






I wrote an application for Windows Embedded with Windows Forms:
In the Application Start I must synchronize the date/time in offline mode so
I ask the date to the user in an input form and then I use the SetLocalTime
API (with the PInvoke) to update the system DateTime.
This call returns an error code 5 (Access Denied)
Since the current user is not a local administrator of the PC I first use
the AdjustTokenPrivileges call to give the proccess the SE_SYSTEMTIME_NAME
permission and then the Impersonation to have administrative rights.
Is there anyone who can help me?

This is the C# Code of my Impersonation class:
-------------------------------------------------------------
class Impersonation
{
// obtains user token
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string pszUsername, string
pszDomain, string pszPassword, int dwLogonType, int dwLogonProvider, ref
IntPtr phToken);

// closes open handes returned by LogonUser
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);

// creates duplicate token handle
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr
DuplicateTokenHandle);

private IntPtr pExistingTokenHandle = new IntPtr(0);
private IntPtr pDuplicateTokenHandle = new IntPtr(0);

public Impersonation()
{
// initialize tokens
pExistingTokenHandle = new IntPtr(0);
pDuplicateTokenHandle = new IntPtr(0);
pExistingTokenHandle = IntPtr.Zero;
pDuplicateTokenHandle = IntPtr.Zero;
}

public WindowsImpersonationContext ImpersonateUser(string sUsername,
string sDomain, string sPassword)
{
if (sDomain == "")
sDomain = System.Environment.MachineName;

string sResult = null;

const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_LOGON_INTERACTIVE = 2;

// get handle to token
bool bImpersonated = LogonUser(sUsername, sDomain, sPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
ref pExistingTokenHandle);

// did impersonation fail?
if (false == bImpersonated)
{
int nErrorCode = Marshal.GetLastWin32Error();
throw new Win32Exception(nErrorCode);
}

// Get identity before impersonation
bool bRetVal = DuplicateToken(pExistingTokenHandle,
(int)SECURITY_IMPERSONATION_LEVEL.SecurityImperson ation,
ref pDuplicateTokenHandle);

// did DuplicateToken fail?
if (false == bRetVal)
{
int nErrorCode = Marshal.GetLastWin32Error();
// close existing handle
CloseHandle(pExistingTokenHandle);

// show the reason why DuplicateToken failed
MessageBox.Show(sResult, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return null;
}
else
{
// create new identity using new primary token
WindowsIdentity newId = new
WindowsIdentity(pDuplicateTokenHandle);
WindowsImpersonationContext impersonatedUser =
newId.Impersonate();

return impersonatedUser;
}

}

public void CloseHandles()
{
if (pExistingTokenHandle != IntPtr.Zero)
CloseHandle(pExistingTokenHandle);
if (pDuplicateTokenHandle != IntPtr.Zero)
CloseHandle(pDuplicateTokenHandle);
}
}

// group type enum
public enum SECURITY_IMPERSONATION_LEVEL : int
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3
}
-------------------------------------------------------------

This is the code of my SystemDateTimeUtils class:

-------------------------------------------------------------
class SystemDateTimeUtils
{
#region pinvokes

[DllImport("kernel32.dll")]
private static extern bool SetLocalTime(ref SYSTEMTIME time);

[DllImport("kernel32.dll")]
private static extern bool SetSystemTime(ref SYSTEMTIME systime);

[DllImport("kernel32.dll")]
private static extern int GetLastError();

[DllImport("kernel32.dll")]
private static extern void GetLocalTime(out SYSTEMTIME time);

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool OpenProcessToken(int ProcessHandle,
int DesiredAccess, ref int TokenHandle);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetCurrentProcess();

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool LookupPrivilegeValue(string lpSystemName,
string lpName,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);

[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern bool AdjustTokenPrivileges(int TokenHandle, int
DisableAllPrivileges,
[MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES NewState,
int BufferLength,
[MarshalAs(UnmanagedType.Struct)] ref TOKEN_PRIVILEGES
PreviousState, ref int ReturnLength);

#endregion

#region Constants

private const int ANYSIZE_ARRAY = 1;
private const string SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege";
private const int SE_PRIVILEGE_ENABLED = 0x00000002;
private const int TOKEN_QUERY = 0x0008;
private const int TOKEN_ADJUST_PRIVILEGES = 0x0020;

#endregion

#region SetLocalTime

public static bool SetLocalTime(DateTime systemTime, out int
errorCode)
{
AdjustPrivileges();
SYSTEMTIME time = GetSystemTime(ref systemTime);

WindowsImpersonationContext newUser = null;
bool result = false;
Impersonation imp = new Impersonation();
try
{
newUser = imp.ImpersonateUser(<my_username>, ".",
<my_password>);
result = SetLocalTime(ref time);

if (result)
result = SetLocalTime(ref time);

if (!result)
errorCode = GetLastError();
else
errorCode = 0;
}
finally
{
imp.CloseHandles();
if (newUser != null)
newUser.Undo();
}

return result;
}

#endregion

#region GetSystemTime

private static SYSTEMTIME GetSystemTime(ref DateTime systemTime)
{

SYSTEMTIME time = new SYSTEMTIME();
time.wDay = (ushort)systemTime.Day;
time.wDayOfWeek = (ushort)(systemTime.DayOfWeek);
time.wHour = (ushort)systemTime.Hour;
time.wMilliseconds = (ushort)systemTime.Millisecond;
time.wMinute = (ushort)systemTime.Minute;
time.wMonth = (ushort)systemTime.Month;
time.wSecond = (ushort)systemTime.Second;
time.wYear = (ushort)systemTime.Year;
return time;
}

#endregion

public static bool AdjustPrivileges()
{
TOKEN_PRIVILEGES tkNew = new TOKEN_PRIVILEGES();
tkNew.Privileges = new LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY];
TOKEN_PRIVILEGES tkOld = new TOKEN_PRIVILEGES();
tkOld.Privileges = new LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY];

LUID luid = new LUID();
int token = -1;
int oldluidSize = 0;

if (LookupPrivilegeValue(null, SE_SYSTEMTIME_NAME, ref luid))
{
if (OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token))
{
tkNew.PrivilegeCount = 1;
tkNew.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkNew.Privileges[0].Luid = luid;
int luidSize = Marshal.SizeOf(typeof(TOKEN_PRIVILEGES));
if (AdjustTokenPrivileges(token, 0, ref tkNew, luidSize,
ref tkOld, ref oldluidSize))
{
return true;
}
}
}
return false;
}


#region Strutture

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public ushort wYear, wMonth, wDayOfWeek, wDay,
wHour, wMinute, wSecond, wMilliseconds;
}

[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public int LowPart;
public int HighPart;
}

[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public int Attributes;
}

[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = ANYSIZE_ARRAY)]
public LUID_AND_ATTRIBUTES[] Privileges;
}

#endregion
}
-------------------------------------------------------------

and this is my code to call the datetime update
-------------------------------------------------------------
int errorCode = 0;
SystemDateTimeUtils.SetLocalTime(currentDate, out errorCode);
if (errorCode != 0)
MessageBox.Show("Error setting local system time to desired value: " +
"error code " + errorCode, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
-------------------------------------------------------------

Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.