Changing Time Zone using Interop

J

Jason soby

It appears Michael Murgolio of The Deployment Guys managed to produce some
good code about changing the Time Zone via PowerShell by using C# code.

http://blogs.technet.com/deployment...g-the-time-zone-using-windows-powershell.aspx

The zip file shown in that blog has the interop code in C#, but the
execution code in PowerShell. Now, i tried porting this over to C# and i'm
running into some issues. Namely, it won't work on Windows 7 .

Does anyone see an issue here?

INTEROP CODE

using System;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Windows.Forms;

namespace TimeZone
{
public class TimeZoneControl
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern int GetTimeZoneInformation(out
TIME_ZONE_INFORMATION lpTimeZoneInformation);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation([In] ref
TIME_ZONE_INFORMATION lpTimeZoneInformation);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError=true)]
private static extern int GetDynamicTimeZoneInformation(out
DYNAMIC_TIME_ZONE_INFORMATION lpTimeZoneInformation);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref
DYNAMIC_TIME_ZONE_INFORMATION lpTimeZoneInformation);

public static void SetTimeZone(TIME_ZONE_INFORMATION tzi)
{
SetTimeZoneInformation(ref tzi);
}

public static TIME_ZONE_INFORMATION GetTimeZone()
{
TIME_ZONE_INFORMATION tzi;

int currentTimeZone = GetTimeZoneInformation(out tzi);

return tzi;
}

public static void SetDynamicTimeZone(DYNAMIC_TIME_ZONE_INFORMATION
dtzi)
{
SetDynamicTimeZoneInformation(ref dtzi);
}

public static DYNAMIC_TIME_ZONE_INFORMATION GetDynamicTimeZone()
{
DYNAMIC_TIME_ZONE_INFORMATION dtzi;

int currentTimeZone = GetDynamicTimeZoneInformation(out dtzi);

return dtzi;
}

public static REG_TZI_FORMAT GetRegTziFormat(byte[] tziRegValue)
{
REG_TZI_FORMAT rtzi;

object varValue = tziRegValue;
byte[] baData = varValue as byte[];
int iSize = baData.Length;
IntPtr buffer = Marshal.AllocHGlobal(iSize);
Marshal.Copy(baData, 0, buffer, iSize);
rtzi = (REG_TZI_FORMAT)Marshal.PtrToStructure(buffer,
typeof(REG_TZI_FORMAT));
Marshal.FreeHGlobal(buffer);

return rtzi;
}
}

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SYSTEM_TIME
{
public short year;
public short month;
public short dayOfWeek;
public short day;
public short hour;
public short minute;
public short second;
public short milliseconds;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TIME_ZONE_INFORMATION
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
public SYSTEM_TIME standardDate;
public int standardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SYSTEM_TIME daylightDate;
public int daylightBias;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DYNAMIC_TIME_ZONE_INFORMATION
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
public SYSTEM_TIME standardDate;
public int standardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SYSTEM_TIME daylightDate;
public int daylightBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string timeZoneKeyName;
public bool dynamicDaylightTimeDisabled;
}

[StructLayout(LayoutKind.Sequential)]
public struct REG_TZI_FORMAT
{
public int bias;
public int standardBias;
public int daylightBias;
public SYSTEM_TIME standardDate;
public SYSTEM_TIME daylightDate;
}
}

namespace NSPrivs
{
public class TokenPrivileges
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError=
true)]
public static extern int OpenProcessToken(int ProcessHandle, int
DesiredAccess,
ref int tokenhandle);

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

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public static extern int LookupPrivilegeValue(string lpsystemname,
string lpname,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError =
true)]
public static extern int AdjustTokenPrivileges(int tokenhandle, int
disableprivs,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGES Newstate, int
bufferlength,
int PreivousState, int Returnlength);

public const int TOKEN_ASSIGN_PRIMARY = 0x00000001;
public const int TOKEN_DUPLICATE = 0x00000002;
public const int TOKEN_IMPERSONATE = 0x00000004;
public const int TOKEN_QUERY = 0x00000008;
public const int TOKEN_QUERY_SOURCE = 0x00000010;
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public const int TOKEN_ADJUST_GROUPS = 0x00000040;
public const int TOKEN_ADJUST_DEFAULT = 0x00000080;

public const UInt32 SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001;
public const UInt32 SE_PRIVILEGE_ENABLED = 0x00000002;
public const UInt32 SE_PRIVILEGE_REMOVED = 0x00000004;
public const UInt32 SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000;

public static bool EnablePrivilege(string privilege)
{
try
{

int token = 0;
int retVal = 0;

TOKEN_PRIVILEGES TP = new TOKEN_PRIVILEGES();
LUID LD = new LUID();

retVal = OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);


TP.PrivilegeCount = 1;
TP.Attributes = SE_PRIVILEGE_ENABLED;
TP.Luid = LD;

retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0,
0);

return true;
}
catch
{
return false;
}
}

public static bool DisablePrivilege(string privilege)
{
try
{
int token = 0;
int retVal = 0;

TOKEN_PRIVILEGES TP = new TOKEN_PRIVILEGES();
LUID LD = new LUID();

retVal = OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);
TP.PrivilegeCount = 1;
// TP.Attributes should be none (not set) to disable privilege
TP.Luid = LD;

retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0);
return true;
}
catch
{
return false;
}
}
}

[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public int LowPart;
public int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
public struct TOKEN_PRIVILEGES
{
public LUID Luid;
public UInt32 Attributes;
public UInt32 PrivilegeCount;
}
}

namespace NSMui
{
public class MuiString
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
public static extern int SHLoadIndirectString(string pszSource,
StringBuilder pszOutBuf, int cchOutBuf, string ppvReserved);

public static string GetIndirectString(string indirectString)
{
try
{
string stringRetVal = "";
int retval;

//NOTE: Build the output buffer reference
StringBuilder lptStr = new StringBuilder(1024);
//NOTE: indirectString contains the MUI formatted string
retval = SHLoadIndirectString(indirectString, lptStr, 1024,
null);
if (retval != 0)
{
stringRetVal = "SHLoadIndirectString failed with error "
+ retval;
return stringRetVal;
}
else
{
stringRetVal = lptStr.ToString();
return stringRetVal;
}
}
catch (Exception ex)
{
return "Exception: " + ex.Message;
}
}
}
}



EXECUTION CODE

using System;
using Microsoft.Win32;
using System.Text;

namespace TimeZone
{
class TimeZoneFunctions
{
const string SE_TIME_ZONE_NAME = "SeTimeZonePrivilege";

public void SetTimeZone(string TimeZone)
{
OperatingSystem os = Environment.OSVersion;
int osBuildNumber = os.Version.Build;

ASCIIEncoding encoding = new ASCIIEncoding();

RegistryKey key =
Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows
NT\\CurrentVersion\\Time Zones\\" + TimeZone);
byte[] regTziAsByteArray =
encoding.GetBytes(key.GetValue("TZI").ToString());

REG_TZI_FORMAT regTzi =
TimeZoneControl.GetRegTziFormat(regTziAsByteArray);

if (osBuildNumber >= 6000)
{
DYNAMIC_TIME_ZONE_INFORMATION info = new
DYNAMIC_TIME_ZONE_INFORMATION();
info.bias = regTzi.bias;
info.standardBias = regTzi.standardBias;
info.daylightBias = regTzi.daylightBias;

if (key.GetValue("MUI_Std").ToString() == String.Empty)
{
info.standardName = key.GetValue("Std").ToString();
}
else
{
info.standardName = key.GetValue("MUI_Std").ToString();
}

if (key.GetValue("MUI_Dlt").ToString() == String.Empty)
{
info.daylightName = key.GetValue("Dlt").ToString();
}
else
{
info.daylightName = key.GetValue("MUI_Dlt").ToString();
}

info.timeZoneKeyName = TimeZone;
info.standardDate = regTzi.standardDate;
info.daylightDate = regTzi.daylightDate;
info.dynamicDaylightTimeDisabled = false;

NSPrivs.TokenPrivileges.EnablePrivilege(SE_TIME_ZONE_NAME);
TimeZoneControl.SetDynamicTimeZone(info);
NSPrivs.TokenPrivileges.DisablePrivilege(SE_TIME_ZONE_NAME);
}
else
{
TIME_ZONE_INFORMATION info = new TIME_ZONE_INFORMATION();
info.bias = regTzi.bias;
info.standardBias = regTzi.standardBias;
info.daylightBias = regTzi.daylightBias;

info.standardDate = regTzi.standardDate;
info.daylightDate = regTzi.daylightDate;

info.standardName = key.GetValue("Std").ToString();
info.daylightName = key.GetValue("Dlt").ToString();

TimeZoneControl.SetTimeZone(info);
}
}
}
}


i hope someone can solve this. As far as i'm aware, i copied the interop
code right out of the zip file Mike Murgolio posted in that link.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top