C# / WPF: Get icons used by shell - c#

I'm trying to develop an application that can show you the content of directories like the Windows Explorer (with file name and icon). I'm currently using this code:
public class IconManager
{
public static ImageSource GetIcon(string path, bool smallIcon, bool isDirectory)
{
uint flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES;
if (smallIcon)
flags |= SHGFI_SMALLICON;
uint attributes = FILE_ATTRIBUTE_NORMAL;
if (isDirectory)
attributes |= FILE_ATTRIBUTE_DIRECTORY;
SHFILEINFO shfi;
if (0 != SHGetFileInfo(path, attributes, out shfi, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), flags))
{
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
}
return null;
}
[StructLayout(LayoutKind.Sequential)]
private struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[DllImport("shell32")]
private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags);
private const uint FILE_ATTRIBUTE_READONLY = 0x00000001;
private const uint FILE_ATTRIBUTE_HIDDEN = 0x00000002;
private const uint FILE_ATTRIBUTE_SYSTEM = 0x00000004;
private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
private const uint FILE_ATTRIBUTE_ARCHIVE = 0x00000020;
private const uint FILE_ATTRIBUTE_DEVICE = 0x00000040;
private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
private const uint FILE_ATTRIBUTE_TEMPORARY = 0x00000100;
private const uint FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200;
private const uint FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400;
private const uint FILE_ATTRIBUTE_COMPRESSED = 0x00000800;
private const uint FILE_ATTRIBUTE_OFFLINE = 0x00001000;
private const uint FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000;
private const uint FILE_ATTRIBUTE_ENCRYPTED = 0x00004000;
private const uint FILE_ATTRIBUTE_VIRTUAL = 0x00010000;
private const uint SHGFI_ICON = 0x000000100;
private const uint SHGFI_DISPLAYNAME = 0x000000200;
private const uint SHGFI_TYPENAME = 0x000000400;
private const uint SHGFI_ATTRIBUTES = 0x000000800;
private const uint SHGFI_ICONLOCATION = 0x000001000;
private const uint SHGFI_EXETYPE = 0x000002000;
private const uint SHGFI_SYSICONINDEX = 0x000004000;
private const uint SHGFI_LINKOVERLAY = 0x000008000;
private const uint SHGFI_SELECTED = 0x000010000;
private const uint SHGFI_ATTR_SPECIFIED = 0x000020000;
private const uint SHGFI_LARGEICON = 0x000000000;
private const uint SHGFI_SMALLICON = 0x000000001;
private const uint SHGFI_OPENICON = 0x000000002;
private const uint SHGFI_SHELLICONSIZE = 0x000000004;
private const uint SHGFI_PIDL = 0x000000008;
private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
}
I use this code to get the files and directories with their icons:
foreach (string d in Directory.GetDirectories(Path))
{
string name = "";
foreach (string p in d.Split('\\'))
name = p;
ImageSource icon = IconManager.GetIcon(d + "\\", false, true);
colDesktopItems.Add(new DesktopItem() { ItemName = name, ItemPath = d });
}
foreach (string f in Directory.GetFiles(Path))
{
if (File.GetAttributes(f) != FileAttributes.Hidden && File.GetAttributes(f) != FileAttributes.System)
{
string name = "";
foreach (string p in f.Split('\\'))
if (p.Contains("."))
name = p;
ImageSource icon = IconManager.GetIcon(f, false, false);
if (name != "desktop.ini" && name != "Thumbs.db")
colDesktopItems.Add(new DesktopItem() { ItemName = name.Split('.')[0], ItemPath = f, ItemIcon = icon });
}
}
I also use a DispatcherTimer for automatic refresh (interval = 5 seconds):
private void dpt_Tick(object sender, EventArgs e)
{
if (dPath != null)
{
if (GetContent(dPath).ToString() != diCollection.ToString())
{
diCollection.Clear();
foreach (DesktopItem i in GetContent(dPath))
diCollection.Add(i);
}
}
}
diCollection is the collection that contains the elements to display and dPath is the path of the directory from which the files will be displayed.
But there are two problems:
When I set isDirectory to true, it just returns an empty icon.
After a while, it throws an exception:
The value may not be NULL.
The exception happens in this line:
return System.Windows.Interop.Imaging.CreateBitmapSourceFromHIcon(shfi.hIcon, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

i use the same methodology. Here is how i have mine set up in my personal library.
public static class ImageUtilities
{
public static System.Drawing.Icon GetRegisteredIcon(string filePath)
{
var shinfo = new SHfileInfo();
Win32.SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);
return System.Drawing.Icon.FromHandle(shinfo.hIcon);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHfileInfo
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
internal sealed class Win32
{
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // large
public const uint SHGFI_SMALLICON = 0x1; // small
[System.Runtime.InteropServices.DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHfileInfo psfi, uint cbSizeFileInfo, uint uFlags);
}
Usage:
var icon = ImageUtilites.GetRegisteredIcon(string path)
the Extension method i use to make create an ImageSource for WPF:
public static System.Windows.Media.ImageSource ToImageSource(this System.Drawing.Bitmap bitmap, int width, int height)
{
var hBitmap = bitmap.GetHbitmap();
System.Windows.Media.ImageSource wpfBitmap = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(width, height));
if (!DeleteObject(hBitmap))
{
throw new System.ComponentModel.Win32Exception();
}
return wpfBitmap;
}
I forgot to add this, I don't know if you are utilizing it..
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);

Related

CertCreateSelfSignCertificate returning null with error code 87

I am facing issue while creating SSL certificate using crypt api in C#, CertCreateSelfSignCertificate is returning null with error code 87(Incorrect paramter).
Not sure what is missed.
Win32Native.CRYPTOAPI_BLOB SubjectIssuerBlob = new Win32Native.CRYPTOAPI_BLOB();
GCHandle asnNameHandle = GCHandle.Alloc(pbEncoded, GCHandleType.Pinned);
// SubjectIssuerBlob.pbData = Marshal.AllocHGlobal(pbEncoded.Length);
//Marshal.Copy(pbEncoded, 0, SubjectIssuerBlob.pbData, pbEncoded.Length);
SubjectIssuerBlob.pbData = asnNameHandle.AddrOfPinnedObject();
SubjectIssuerBlob.cbData = cbEncoded;
Win32Native.CRYPT_KEY_PROV_INFO providerInfo = new Win32Native.CRYPT_KEY_PROV_INFO();
providerInfo.pwszContainerName = hostname;
providerInfo.pwszProvName = null;
providerInfo.dwProvType = PROV_RSA_FULL;
providerInfo.dwFlags = CRYPT_MACHINE_KEYSET;
providerInfo.cProvParam = 0;
providerInfo.rgProvParam = IntPtr.Zero;
providerInfo.dwKeySpec = AT_SIGNATURE;
Win32Native.CRYPT_ALGORITHM_IDENTIFIER algorithmID = new Win32Native.CRYPT_ALGORITHM_IDENTIFIER();
algorithmID.pszObjId = "1.2.840.113549.1.1.5"; //szOID_RSA_SHA1RSA
pContext = Win32Native.CertCreateSelfSignCertificate(IntPtr.Zero, ref SubjectIssuerBlob, 0, ref providerInfo, ref algorithmID, null, endtime, IntPtr.Zero);
win32api call,
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true)]
internal static extern IntPtr CertCreateSelfSignCertificate(
IntPtr providerHandle,
ref CRYPTOAPI_BLOB subjectIssuerBlob,
uint flags,
ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
ref CRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
SystemTime startTime,
SystemTime endTime,
IntPtr extensions);
A test with CertCreateSelfSignCertificate on Windows 10, VS 2015 =>
Dialog box (french) :
//Guid guidContainerName = Guid.NewGuid();
Guid guidContainerName = Guid.Empty;
int nRet = UuidCreate(out guidContainerName);
if (nRet == 0)
{
IntPtr pContainerName = new IntPtr();
nRet = UuidToString(ref guidContainerName, ref pContainerName);
string sContainerName;
sContainerName = Marshal.PtrToStringUni(pContainerName);
string sProviderName = MS_DEF_PROV;
IntPtr hProv = IntPtr.Zero;
bool bRet = CryptAcquireContext(ref hProv, sContainerName, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET);
IntPtr hKey = IntPtr.Zero;
bRet = CryptGenKey(hProv, AT_KEYEXCHANGE, RSA1024BIT_KEY | CRYPT_EXPORTABLE, ref hKey);
string sSubject = "CN=TEST,OU=TESTOU";
byte[] encodedSubjectName = null;
uint nNameLenght = 0;
if (CertStrToName(X509_ASN_ENCODING, sSubject, CERT_X500_NAME_STR, IntPtr.Zero, null, ref nNameLenght, IntPtr.Zero))
{
encodedSubjectName = new byte[nNameLenght];
CertStrToName(X509_ASN_ENCODING, sSubject, CERT_X500_NAME_STR, IntPtr.Zero, encodedSubjectName, ref nNameLenght, IntPtr.Zero);
}
CERT_NAME_BLOB subjectblob = new CERT_NAME_BLOB();
subjectblob.pbData = Marshal.AllocHGlobal(encodedSubjectName.Length);
Marshal.Copy(encodedSubjectName, 0, subjectblob.pbData, encodedSubjectName.Length);
subjectblob.cbData = encodedSubjectName.Length;
CRYPT_KEY_PROV_INFO pKeyProvInfo = new CRYPT_KEY_PROV_INFO();
pKeyProvInfo.pwszContainerName = sContainerName;
pKeyProvInfo.pwszProvName = sProviderName;
pKeyProvInfo.dwProvType = PROV_RSA_FULL;
pKeyProvInfo.rgProvParam = IntPtr.Zero;
pKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
IntPtr pcCertContext = CertCreateSelfSignCertificate(hProv, ref subjectblob, 0, ref pKeyProvInfo, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
if (pcCertContext != IntPtr.Zero)
{
X509Certificate cert = new X509Certificate(pcCertContext);
// Add reference to System.Security
X509Certificate2UI.DisplayCertificate(new X509Certificate2(cert));
CertFreeCertificateContext(pcCertContext);
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
Marshal.FreeHGlobal(subjectblob.pbData);
CryptDestroyKey(hKey);
CryptReleaseContext(hProv, 0);
RpcStringFree(ref pContainerName);
}
with declarations =>
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr CertCreateSelfSignCertificate(IntPtr hCryptProvOrNCryptKey, ref CERT_NAME_BLOB pSubjectIssuerBlob, int dwFlags, ref CRYPT_KEY_PROV_INFO pKeyProvInfo,
IntPtr pSignatureAlgorithm, IntPtr pStartTime, IntPtr pEndTime, IntPtr pExtensions);
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CertFreeCertificateContext(IntPtr pCertContext);
[StructLayout(LayoutKind.Sequential)]
public struct CERT_NAME_BLOB
{
public int cbData;
public IntPtr pbData;
}
[DllImport("Rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int UuidCreate(out Guid Uuid);
[DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int UuidToString(ref Guid uuid, ref IntPtr str);
[DllImport("rpcrt4.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern int RpcStringFree(ref IntPtr str);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CryptAcquireContext(ref IntPtr phProv, string szContainer, string szProvider, int dwProvType, uint dwFlags);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CryptReleaseContext(IntPtr hProv, uint dwFlags);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CryptGenKey(IntPtr hProv, uint Algid, int dwFlags, ref IntPtr phKey);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CryptDestroyKey(IntPtr hKey);
public const int RSA1024BIT_KEY = 0x04000000;
public const int CRYPT_EXPORTABLE = 0x00000001;
[DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CertStrToName(uint dwCertEncodingType, string pszX500, uint dwStrType, IntPtr pvReserved,
[In, Out] byte[] pbEncoded, ref uint pcbEncoded, IntPtr ppszError);
public const int CRYPT_ASN_ENCODING = 0x00000001;
public const int CRYPT_NDR_ENCODING = 0x00000002;
public const int X509_ASN_ENCODING = 0x00000001;
public const int X509_NDR_ENCODING = 0x00000002;
public const int PKCS_7_ASN_ENCODING = 0x00010000;
public const int PKCS_7_NDR_ENCODING = 0x00020000;
public const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";
public const int PROV_RSA_FULL = 1;
public const uint CRYPT_VERIFYCONTEXT = 0xF0000000;
public const uint CRYPT_NEWKEYSET = 0x00000008;
public const uint CRYPT_DELETEKEYSET = 0x00000010;
public const uint CRYPT_MACHINE_KEYSET = 0x00000020;
public const uint CRYPT_SILENT = 0x00000040;
public const int CERT_SIMPLE_NAME_STR = 1;
public const int CERT_OID_NAME_STR = 2;
public const int CERT_X500_NAME_STR = 3;
public const int CERT_XML_NAME_STR = 4;
public const int CERT_NAME_STR_SEMICOLON_FLAG = 0x40000000;
public const int CERT_NAME_STR_NO_PLUS_FLAG = 0x20000000;
public const int CERT_NAME_STR_NO_QUOTING_FLAG = 0x10000000;
public const int CERT_NAME_STR_CRLF_FLAG = 0x08000000;
public const int CERT_NAME_STR_COMMA_FLAG = 0x04000000;
public const int CERT_NAME_STR_REVERSE_FLAG = 0x02000000;
public const int CERT_NAME_STR_FORWARD_FLAG = 0x01000000;
public const int CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG = 0x00010000;
public const int CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG = 0x00020000;
public const int CERT_NAME_STR_ENABLE_UTF8_UNICODE_FLAG = 0x00040000;
public const int CERT_NAME_STR_FORCE_UTF8_DIR_STR_FLAG = 0x00080000;
public const int CERT_NAME_STR_DISABLE_UTF8_DIR_STR_FLAG = 0x00100000;
public const int CERT_NAME_STR_ENABLE_PUNYCODE_FLAG = 0x00200000;
[StructLayout(LayoutKind.Sequential)]
public struct CRYPT_KEY_PROV_INFO
{
[MarshalAs(UnmanagedType.LPWStr)] public string pwszContainerName;
[MarshalAs(UnmanagedType.LPWStr)] public string pwszProvName;
public int dwProvType;
public int dwFlags;
public int cProvParam;
public IntPtr rgProvParam;
public int dwKeySpec;
}
public const int AT_KEYEXCHANGE = 1;
public const int AT_SIGNATURE = 2;

TreeView turn off checkboxes

I have very strange problem with hiding CheckBoxes in a TreeView. Everything works as it should when TreeView is on the first TabPage in the Window but when TreeView in on the second TabPage then the first TreeNode always has checkbox.
The code I'm using to hide some checkboxes looks like this:
private const int TVIF_STATE = 0x8;
private const int TVIS_STATEIMAGEMASK = 0xF000;
private const int TV_FIRST = 0x1100;
private const int TVM_SETITEM = TV_FIRST + 63;
public struct TVITEM {
public int mask;
public IntPtr hItem;
public int state;
public int stateMask;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpszText;
public int cchTextMax;
public int iImage;
public int iSelectedImage;
public int cChildren;
public IntPtr lParam;
}
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
private void TurnOff(TreeNode node) {
TVITEM tvi = new TVITEM();
tvi.hItem = node.Handle;
tvi.mask = TVIF_STATE;
tvi.stateMask = TVIS_STATEIMAGEMASK;
tvi.state = 0;
IntPtr lparam = Marshal.AllocHGlobal(Marshal.SizeOf(tvi));
Marshal.StructureToPtr(tvi, lparam, false);
SendMessage(this.Handle, TVM_SETITEM, IntPtr.Zero, lparam);
Marshal.FreeHGlobal(lparam);
}
If someone knows solution for this problem, please share.
Working solution can be found here: http://dotnetfollower.com/wordpress/2011/05/winforms-treeview-hide-checkbox-of-treenode/

How to create partition on hdd using IOCTL_DISK_SET_DRIVE_LAYOUT on C#

I need to implement an hdd partitioning program using c#.
Below is part of my code.
I think it works because it returns true value from DeviceIOcontrol with no errors, but the problem is my program doesn't show anything.
I got a lot of help from Medo's home page, MSDN, and pinvoke site.
public static bool partitionDisk(string path)
{
var signature = new byte[4];
System.Security.Cryptography.RandomNumberGenerator.Create().GetBytes(signature);
using (SafeFileHandle handle = NativeMethods2.CreateFile(path, (NativeMethods2.FILE_SHARE_READ|NativeMethods.GENERIC_READ ) | (NativeMethods.GENERIC_WRITE | NativeMethods2.FILE_SHARE_WRITE), 0, IntPtr.Zero, NativeMethods2.OPEN_EXISTING, 0, IntPtr.Zero))
{
if (handle.IsInvalid) { throw new Win32Exception(); }
var newdi = new NativeMethods2.DRIVE_LAYOUT_INFORMATION_EX();
newdi.PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
newdi.PartitionCount = 4;
newdi.DriveLayoutInformaiton.Mbr.Signature = BitConverter.ToInt32(signature, 0);
newdi.PartitionEntry = new NativeMethods2.PARTITION_INFORMATION_EX[0x16];
newdi.PartitionEntry[0] = new NativeMethods2.PARTITION_INFORMATION_EX();
newdi.PartitionEntry[0].PartitionStyle = NativeMethods2.PARTITION_STYLE.PARTITION_STYLE_MBR;
newdi.PartitionEntry[0].StartingOffset = 1048576; // check by diskpart
newdi.PartitionEntry[0].PartitionLength = 0xFFFFFFFFFFfffff; //int64 max
newdi.PartitionEntry[0].PartitionNumber = 1;
newdi.PartitionEntry[0].RewritePartition = true;
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.BootIndicator = false;
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.HiddenSectors = 0; //sector size
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.PartitionType = 0x07;// PARTITION_IFS (NTFS partition or logical drive)
newdi.PartitionEntry[0].DriveLayoutInformaiton.Mbr.RecognizedPartition = true;
for (int k = 2; k < newdi.PartitionCount; k++)
{
newdi.PartitionEntry[k] = new NativeMethods2.PARTITION_INFORMATION_EX();
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.BootIndicator = false;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.HiddenSectors = 0;
newdi.PartitionEntry[k].PartitionLength = 0;
newdi.PartitionEntry[k].PartitionNumber = k;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.PartitionType = 0;
newdi.PartitionEntry[k].DriveLayoutInformaiton.Mbr.RecognizedPartition = false;
newdi.PartitionEntry[k].RewritePartition = true;
newdi.PartitionEntry[k].StartingOffset = 0;
}
Int32 bytesOut = 0;
if (NativeMethods2.DeviceIoControl(handle, NativeMethods2.IOCTL_DISK_SET_DRIVE_LAYOUT, ref newdi, Marshal.SizeOf(newdi), IntPtr.Zero, 0, ref bytesOut, IntPtr.Zero) == false) { throw new Win32Exception(); }
}
}
private static class NativeMethods2
{
public const int GENERIC_READ = -2147483648;
public const int GENERIC_WRITE = 1073741824;
public const int OPEN_EXISTING = 3;
public const int FILE_SHARE_READ = 0x0000000001;
public const int FILE_SHARE_WRITE = 0x0000000002;
public const int IOCTL_DISK_UPDATE_PROPERTIES = 0x70140;
public const int IOCTL_DISK_SET_DRIVE_LAYOUT_EX = 0x7C054;
public enum PARTITION_STYLE
{
PARTITION_STYLE_MBR = 0,
PARTITION_STYLE_GPT = 1,
PARTITION_STYLE_RAW = 2,
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_EX
{
public PARTITION_STYLE PartitionStyle;
public int PartitionCount;
public DRIVE_LAYOUT_INFORMATION_UNION DriveLayoutInformaiton;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 0x16)]
public PARTITION_INFORMATION_EX[] PartitionEntry;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_EX
{
public PARTITION_STYLE PartitionStyle;
public long StartingOffset;
public long PartitionLength;
public int PartitionNumber;
public bool RewritePartition;
public PARTITION_INFORMATION_UNION DriveLayoutInformaiton;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_MBR
{
public byte PartitionType;
public bool BootIndicator;
public bool RecognizedPartition;
public Int32 HiddenSectors;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION_GPT
{
public Guid PartitionType; //GUID
public Guid PartitionId; //GUID
public Int64 Attributes;
public char[] Name;
}
[StructLayout(LayoutKind.Sequential)]
public struct PARTITION_INFORMATION
{
public long StartingOffset;
public long PartitionLength;
public int HiddenSectors;
public int PartitionNumber;
public byte PartitionType;
[MarshalAs(UnmanagedType.I1)]
public bool BootIndicator;
[MarshalAs(UnmanagedType.I1)]
public bool RecognizedPartition;
[MarshalAs(UnmanagedType.I1)]
public bool RewritePartition;
}
[StructLayout(LayoutKind.Explicit)]
public struct DRIVE_LAYOUT_INFORMATION_UNION
{
[FieldOffset(0)]
public DRIVE_LAYOUT_INFORMATION_MBR Mbr;
[FieldOffset(0)]
public DRIVE_LAYOUT_INFORMATION_GPT Gpt;
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_MBR
{
public Int32 Signature;
}
[StructLayout(LayoutKind.Sequential)]
public struct DRIVE_LAYOUT_INFORMATION_GPT
{
public Guid DiskId;
public Int64 StartingUsableOffset;
public Int64 UsableLength;
public ulong MaxPartitionCount;
}
[StructLayout(LayoutKind.Explicit)]
public struct PARTITION_INFORMATION_UNION
{
[FieldOffset(0)]
public PARTITION_INFORMATION_MBR Mbr;
[FieldOffset(0)]
public PARTITION_INFORMATION_GPT Gpt;
}
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref DRIVE_LAYOUT_INFORMATION_EX lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
}
private static class NativeMethods
{
public const int GENERIC_READ = -2147483648;
public const int GENERIC_WRITE = 1073741824;
public const int OPEN_EXISTING = 3;
public const int IOCTL_DISK_CREATE_DISK = 0x7C058;
public enum PARTITION_STYLE
{
PARTITION_STYLE_MBR = 0,
PARTITION_STYLE_GPT = 1,
PARTITION_STYLE_RAW = 2,
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK
{
public PARTITION_STYLE PartitionStyle;
public CREATE_DISK_UNION_MBR_GPT MbrGpt;
}
[StructLayoutAttribute(LayoutKind.Explicit)]
public struct CREATE_DISK_UNION_MBR_GPT
{
[FieldOffset(0)]
public CREATE_DISK_MBR Mbr;
[FieldOffset(0)]
public CREATE_DISK_GPT Gpt;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK_MBR
{
public Int32 Signature;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct CREATE_DISK_GPT
{
public Guid DiskId;
public Int32 MaxPartitionCount;
}
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true)]
public static extern SafeFileHandle CreateFile([MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, Int32 dwDesiredAccess, Int32 dwShareMode, IntPtr lpSecurityAttributes, Int32 dwCreationDisposition, Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);
[DllImportAttribute("kernel32.dll", EntryPoint = "DeviceIoControl", SetLastError = true)]
[return: MarshalAsAttribute(UnmanagedType.Bool)]
public static extern Boolean DeviceIoControl(SafeFileHandle hDevice, Int32 dwIoControlCode, ref CREATE_DISK lpInBuffer, int nInBufferSize, IntPtr lpOutBuffer, Int32 nOutBufferSize, ref Int32 lpBytesReturned, IntPtr lpOverlapped);
}
...and to call the function:
DiskIO.partitionDisk("//./PHYSICALDRIVE2")

How to get the file type name?

I want to get in my c# app the name of the file type, that is shown in file properties in windows... for example .log file has the type as LOG file (.log) or .bat has Batch file for Windows (.bat)(translated from my lang, so maybe not accurate).
Please, where can i find this info? or how to get to this?
i found Get-Registered-File-Types-and-Their-Associated-Ico article, where the autor shows how to get the icon, but not the type name of file that is showed in OS.
You have to call the respective Shell function SHGetFileInfo, which is a native Win32 API.
class NativeMethods
{
private const int FILE_ATTRIBUTE_NORMAL = 0x80;
private const int SHGFI_TYPENAME = 0x400;
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr SHGetFileInfo(
string pszPath,
int dwFileAttributes,
ref SHFILEINFO shinfo,
uint cbfileInfo,
int uFlags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
private struct SHFILEINFO
{
public SHFILEINFO(bool b)
{
hIcon = IntPtr.Zero;
iIcon = 0;
dwAttributes = 0;
szDisplayName = "";
szTypeName = "";
}
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
public static string GetShellFileType(string fileName)
{
var shinfo = new SHFILEINFO(true);
const int flags = SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES;
if (SHGetFileInfo(fileName, FILE_ATTRIBUTE_NORMAL, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags) == IntPtr.Zero)
{
return "File";
}
return shinfo.szTypeName;
}
}
Then, simply call NativeMethods.GetShellFileType("...").
You can read that info from the registry
use like GetDescription("cpp") or GetDescription(".xml")
public static string ReadDefaultValue(string regKey)
{
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(regKey, false))
{
if (key != null)
{
return key.GetValue("") as string;
}
}
return null;
}
public static string GetDescription(string ext)
{
if (ext.StartsWith(".") && ext.Length > 1) ext = ext.Substring(1);
var retVal = ReadDefaultValue(ext + "file");
if (!String.IsNullOrEmpty(retVal)) return retVal;
using (var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("." + ext, false))
{
if (key == null) return "";
using (var subkey = key.OpenSubKey("OpenWithProgids"))
{
if (subkey == null) return "";
var names = subkey.GetValueNames();
if (names == null || names.Length == 0) return "";
foreach (var name in names)
{
retVal = ReadDefaultValue(name);
if (!String.IsNullOrEmpty(retVal)) return retVal;
}
}
}
return "";
}
You can get this information using the SHGetFileInfo.
using System;
using System.Runtime.InteropServices;
namespace GetFileTypeAndDescription
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
SHFILEINFO shinfo = new SHFILEINFO();
IntPtr i = Win32.SHGetFileInfo(#"d:\temp\test.xls", 0, ref
shinfo,(uint)Marshal.SizeOf(shinfo),Win32.SHGFI_TY PENAME);
string s = Convert.ToString(shinfo.szTypeName.Trim());
Console.WriteLine(s);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public IntPtr iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
};
class Win32
{
public const uint SHGFI_DISPLAYNAME = 0x00000200;
public const uint SHGFI_TYPENAME = 0x400;
public const uint SHGFI_ICON = 0x100;
public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
public const uint SHGFI_SMALLICON = 0x1; // 'Small icon
[DllImport("shell32.dll")]
public static extern IntPtr SHGetFileInfo(string pszPath, uint
dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
}
}
you have to use the shgetfileinfo, see below link for some code:
http://www.pinvoke.net/default.aspx/shell32.shgetfileinfo

How to change the timezone setting of Windows2k8 with .net [duplicate]

This question already has answers here:
Set System Time Zone from .NET
(2 answers)
Closed 8 years ago.
I have tried to change the timezone of my system with c# code for a few days now and nothing I'm trying is making much sense or working at all. I started out trying to use the PInvoke syntax for SetTimeZoneInformation that I've seen on other questions here.
[DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern bool
SetTimeZoneInformation([In] ref TimeZoneInformation lpTimeZoneInformation);
I was looking into how I should create the TimeZoneInformation struct and got confused since my system obviously has a dynamic DST system. Turns out that ever since Vista Microsoft added a new way of handling Timezones. You now have to use SetDynamicTimeZoneInformation
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref DynamicTimeZoneInformation lpTimeZoneInformation);
I searched for help with this API on msdn and found something saying, "An application must have the SE_TIME_ZONE_NAME privilege for this function to succeed." Eventually I found this page with what seems like pretty good code for getting this done. The problem is that it's just not working.
Here is my non-working code:
[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;
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SystemTime
{
public ushort Year;
public ushort Month;
public ushort DayOfWeek;
public ushort Day;
public ushort Hour;
public ushort Minute;
public ushort Second;
public ushort Millisecond;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DynamicTimeZoneInformation
{
public int bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string standardName;
public SystemTime standardDate;
public int standardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string daylightName;
public SystemTime daylightDate;
public int daylightBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string timeZoneKeyName;
public bool dynamicDaylightTimeDisabled;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int GetDynamicTimeZoneInformation(out DynamicTimeZoneInformation lpTimeZoneInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref DynamicTimeZoneInformation lpTimeZoneInformation);
[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;
}
}
public bool SetSystemTimeZone(string timeZoneId)
{
//I'm using the TimeZoneInfo class to populate a list in the UI. This code to retrieve the correct timezone is working
TimeZoneInfo newTimeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
DynamicTimeZoneInformation dtzi = new DynamicTimeZoneInformation();
dtzi.bias = -(Convert.ToInt32(newTimeZone.BaseUtcOffset.TotalMinutes));
dtzi.standardBias = 0;
//Here's where I start to lose it. I don't know which adjustment rule to use from the GetAdjustmentRules call. I'm just using the last one as that seems to usually be the most recent, but it doesn't always have to be.
dtzi.daylightBias = Convert.ToInt32(newTimeZone.GetAdjustmentRules().Last().DaylightDelta.TotalMinutes);
dtzi.standardName = newTimeZone.StandardName;
dtzi.daylightName = newTimeZone.DaylightName;
//It would be nice if this key name would just look up the timezone from the registry and use its settings
dtzi.timeZoneKeyName = newTimeZone.Id;
//No idea if this is the right way to create the SystemTime object I need here.
SystemTime standardDate = new SystemTime();
standardDate.Year = 0;
standardDate.Hour = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionEnd.TimeOfDay.Hour;
standardDate.Minute = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionEnd.TimeOfDay.Minute;
standardDate.DayOfWeek = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionEnd.DayOfWeek;
standardDate.Month = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionEnd.Month;
standardDate.Day = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionEnd.Week;
dtzi.standardDate = standardDate;
SystemTime daylightDate = new SystemTime();
standardDate.Year = 0;
standardDate.Hour = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionStart.TimeOfDay.Hour;
standardDate.Minute = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionStart.TimeOfDay.Minute;
standardDate.DayOfWeek = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionStart.DayOfWeek;
standardDate.Month = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionStart.Month;
standardDate.Day = (ushort)newTimeZone.GetAdjustmentRules().Last().DaylightTransitionStart.Week;
dtzi.daylightDate = daylightDate;
dtzi.dynamicDaylightTimeDisabled = false;
EnablePrivilege("SeTimeZonePrivilege");
if (!SetDynamicTimeZoneInformation(ref dtzi))
returnVal = false;
DisablePrivilege("SeTimeZonePrivilege");
return returnVal;
}
Has anyone had any luck with this...setting the timezone in a post Vista system? Perhaps there is a better way altogether.
Thanks
TheCloudlessSky's answer works for windows XP: starting with Vista the function to call is SetDynamicTimeZoneInformation, otherwise "Your current time zone is not recognized. Please select a valid time zone using the link below." will be shown until the next reboot.
Bonus: calling SetDynamicTimeZoneInformation makes it unnecessary to manually edit the registry, and so it won't be necessary to start the program as administrator.
Here is TheCloudlessSky's snippet modified to work on Vista and higher
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace TimeZoneTest
{
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SystemTime
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string StandardName;
public SystemTime StandardDate;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string DaylightName;
public SystemTime DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct DynamicTimeZoneInformation
{
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string StandardName;
public SystemTime StandardDate;
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string DaylightName;
public SystemTime DaylightDate;
public int DaylightBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
public string TimeZoneKeyName;
[MarshalAs(UnmanagedType.U1)]
public bool DynamicDaylightTimeDisabled;
}
[StructLayout(LayoutKind.Sequential)]
public struct RegistryTimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
public SystemTime StandardDate;
public SystemTime DaylightDate;
public RegistryTimeZoneInformation(TimeZoneInformation tzi)
{
this.Bias = tzi.Bias;
this.StandardDate = tzi.StandardDate;
this.StandardBias = tzi.StandardBias;
this.DaylightDate = tzi.DaylightDate;
this.DaylightBias = tzi.DaylightBias;
}
public RegistryTimeZoneInformation(byte[] bytes)
{
if ((bytes == null) || (bytes.Length != 0x2c))
{
throw new ArgumentException("Argument_InvalidREG_TZI_FORMAT");
}
this.Bias = BitConverter.ToInt32(bytes, 0);
this.StandardBias = BitConverter.ToInt32(bytes, 4);
this.DaylightBias = BitConverter.ToInt32(bytes, 8);
this.StandardDate.Year = BitConverter.ToInt16(bytes, 12);
this.StandardDate.Month = BitConverter.ToInt16(bytes, 14);
this.StandardDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x10);
this.StandardDate.Day = BitConverter.ToInt16(bytes, 0x12);
this.StandardDate.Hour = BitConverter.ToInt16(bytes, 20);
this.StandardDate.Minute = BitConverter.ToInt16(bytes, 0x16);
this.StandardDate.Second = BitConverter.ToInt16(bytes, 0x18);
this.StandardDate.Milliseconds = BitConverter.ToInt16(bytes, 0x1a);
this.DaylightDate.Year = BitConverter.ToInt16(bytes, 0x1c);
this.DaylightDate.Month = BitConverter.ToInt16(bytes, 30);
this.DaylightDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x20);
this.DaylightDate.Day = BitConverter.ToInt16(bytes, 0x22);
this.DaylightDate.Hour = BitConverter.ToInt16(bytes, 0x24);
this.DaylightDate.Minute = BitConverter.ToInt16(bytes, 0x26);
this.DaylightDate.Second = BitConverter.ToInt16(bytes, 40);
this.DaylightDate.Milliseconds = BitConverter.ToInt16(bytes, 0x2a);
}
}
public class TokenPrivilegesAccess
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int 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 int LookupPrivilegeValue(string lpsystemname, string lpname,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int AdjustTokenPrivileges(int tokenhandle, int disableprivs,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGE 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_PRIVILEGE TP = new TOKEN_PRIVILEGE();
LUID LD = new LUID();
retVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);
TP.PrivilegeCount = 1;
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Attributes = SE_PRIVILEGE_ENABLED;
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
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_PRIVILEGE TP = new TOKEN_PRIVILEGE();
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
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0);
return true;
}
catch
{
return false;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID
{
internal uint LowPart;
internal uint HighPart;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID_AND_ATTRIBUTES
{
internal LUID Luid;
internal uint Attributes;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TOKEN_PRIVILEGE
{
internal uint PrivilegeCount;
internal LUID_AND_ATTRIBUTES Privilege;
}
public class Program
{
public const int ERROR_ACCESS_DENIED = 0x005;
public const int CORSEC_E_MISSING_STRONGNAME = -2146233317;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation([In] ref TimeZoneInformation lpTimeZoneInformation);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetDynamicTimeZoneInformation([In] ref DynamicTimeZoneInformation lpTimeZoneInformation);
public static void Main(string[] args)
{
var regTimeZones = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
// Print out all the possible time-zones.
//foreach(var subKey in regTimeZones.GetSubKeyNames())
//{
// Console.WriteLine(subKey);
//}
var subKey = regTimeZones.GetSubKeyNames().Where(s => s == "Atlantic Standard Time").First();
string daylightName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Dlt");
string standardName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Std");
byte[] tzi = (byte[])regTimeZones.OpenSubKey(subKey).GetValue("TZI");
var regTzi = new RegistryTimeZoneInformation(tzi);
TokenPrivilegesAccess.EnablePrivilege("SeTimeZonePrivilege");
bool didSet;
if (Environment.OSVersion.Version.Major < 6)
{
var tz = new TimeZoneInformation();
tz.Bias = regTzi.Bias;
tz.DaylightBias = regTzi.DaylightBias;
tz.StandardBias = regTzi.StandardBias;
tz.DaylightDate = regTzi.DaylightDate;
tz.StandardDate = regTzi.StandardDate;
tz.DaylightName = daylightName;
tz.StandardName = standardName;
didSet = Program.SetTimeZoneInformation(ref tz);
}
else
{
var tz = new DynamicTimeZoneInformation();
tz.Bias = regTzi.Bias;
tz.DaylightBias = regTzi.DaylightBias;
tz.StandardBias = regTzi.StandardBias;
tz.DaylightDate = regTzi.DaylightDate;
tz.StandardDate = regTzi.StandardDate;
tz.DaylightName = daylightName;
tz.StandardName = standardName;
tz.TimeZoneKeyName = subKey;
tz.DynamicDaylightTimeDisabled = false;
didSet = Program.SetDynamicTimeZoneInformation(ref tz);
}
int lastError = Marshal.GetLastWin32Error();
TokenPrivilegesAccess.DisablePrivilege("SeTimeZonePrivilege");
if (didSet)
{
Console.WriteLine("Success, TimeZone Set!");
}
else
{
if (lastError == Program.ERROR_ACCESS_DENIED)
{
Console.WriteLine("Error: Access denied... Try running application as administrator.");
}
else if (lastError == Program.CORSEC_E_MISSING_STRONGNAME)
{
Console.WriteLine("Error: Application is not signed ... Right click the project > Signing > Check 'Sign the assembly'.");
}
else
{
Console.WriteLine("Win32Error: " + lastError + "\nHRESULT: " + Marshal.GetHRForLastWin32Error());
}
}
Console.ReadLine();
}
}
}
I've done this before and here's how I did it.
The only problem is that when you check the DateTime in the task bar, it says Your current time zone is not recognized. Please select a valid time zone using the link below.. I've never been able to "fix" that... so yeah.
EDIT: I found a way to make the timezone "valid" (you must restart the machine to make it work). Be sure to read the NOTE that explains that app.manifest needs requireAdministrator. ^_^
Good luck!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace TimeZoneTest
{
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct SystemTime
{
[MarshalAs(UnmanagedType.U2)]
public short Year;
[MarshalAs(UnmanagedType.U2)]
public short Month;
[MarshalAs(UnmanagedType.U2)]
public short DayOfWeek;
[MarshalAs(UnmanagedType.U2)]
public short Day;
[MarshalAs(UnmanagedType.U2)]
public short Hour;
[MarshalAs(UnmanagedType.U2)]
public short Minute;
[MarshalAs(UnmanagedType.U2)]
public short Second;
[MarshalAs(UnmanagedType.U2)]
public short Milliseconds;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string StandardName;
public SystemTime StandardDate;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 0x20)]
public string DaylightName;
public SystemTime DaylightDate;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
}
[StructLayout(LayoutKind.Sequential)]
public struct RegistryTimeZoneInformation
{
[MarshalAs(UnmanagedType.I4)]
public int Bias;
[MarshalAs(UnmanagedType.I4)]
public int StandardBias;
[MarshalAs(UnmanagedType.I4)]
public int DaylightBias;
public SystemTime StandardDate;
public SystemTime DaylightDate;
public RegistryTimeZoneInformation(TimeZoneInformation tzi)
{
this.Bias = tzi.Bias;
this.StandardDate = tzi.StandardDate;
this.StandardBias = tzi.StandardBias;
this.DaylightDate = tzi.DaylightDate;
this.DaylightBias = tzi.DaylightBias;
}
public RegistryTimeZoneInformation(byte[] bytes)
{
if ((bytes == null) || (bytes.Length != 0x2c))
{
throw new ArgumentException("Argument_InvalidREG_TZI_FORMAT");
}
this.Bias = BitConverter.ToInt32(bytes, 0);
this.StandardBias = BitConverter.ToInt32(bytes, 4);
this.DaylightBias = BitConverter.ToInt32(bytes, 8);
this.StandardDate.Year = BitConverter.ToInt16(bytes, 12);
this.StandardDate.Month = BitConverter.ToInt16(bytes, 14);
this.StandardDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x10);
this.StandardDate.Day = BitConverter.ToInt16(bytes, 0x12);
this.StandardDate.Hour = BitConverter.ToInt16(bytes, 20);
this.StandardDate.Minute = BitConverter.ToInt16(bytes, 0x16);
this.StandardDate.Second = BitConverter.ToInt16(bytes, 0x18);
this.StandardDate.Milliseconds = BitConverter.ToInt16(bytes, 0x1a);
this.DaylightDate.Year = BitConverter.ToInt16(bytes, 0x1c);
this.DaylightDate.Month = BitConverter.ToInt16(bytes, 30);
this.DaylightDate.DayOfWeek = BitConverter.ToInt16(bytes, 0x20);
this.DaylightDate.Day = BitConverter.ToInt16(bytes, 0x22);
this.DaylightDate.Hour = BitConverter.ToInt16(bytes, 0x24);
this.DaylightDate.Minute = BitConverter.ToInt16(bytes, 0x26);
this.DaylightDate.Second = BitConverter.ToInt16(bytes, 40);
this.DaylightDate.Milliseconds = BitConverter.ToInt16(bytes, 0x2a);
}
}
public class TokenPrivilegesAccess
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int 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 int LookupPrivilegeValue(string lpsystemname, string lpname,
[MarshalAs(UnmanagedType.Struct)] ref LUID lpLuid);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
public static extern int AdjustTokenPrivileges(int tokenhandle, int disableprivs,
[MarshalAs(UnmanagedType.Struct)]ref TOKEN_PRIVILEGE 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_PRIVILEGE TP = new TOKEN_PRIVILEGE();
LUID LD = new LUID();
retVal = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref token);
retVal = LookupPrivilegeValue(null, privilege, ref LD);
TP.PrivilegeCount = 1;
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Attributes = SE_PRIVILEGE_ENABLED;
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
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_PRIVILEGE TP = new TOKEN_PRIVILEGE();
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
var luidAndAtt = new LUID_AND_ATTRIBUTES();
luidAndAtt.Luid = LD;
TP.Privilege = luidAndAtt;
retVal = AdjustTokenPrivileges(token, 0, ref TP, 1024, 0, 0);
return true;
}
catch
{
return false;
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID
{
internal uint LowPart;
internal uint HighPart;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct LUID_AND_ATTRIBUTES
{
internal LUID Luid;
internal uint Attributes;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TOKEN_PRIVILEGE
{
internal uint PrivilegeCount;
internal LUID_AND_ATTRIBUTES Privilege;
}
public class Program
{
public const int ERROR_ACCESS_DENIED = 0x005;
public const int CORSEC_E_MISSING_STRONGNAME = -2146233317;
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool SetTimeZoneInformation([In] ref TimeZoneInformation lpTimeZoneInformation);
public static void Main(string[] args)
{
var regTimeZones = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones");
// Print out all the possible time-zones.
//foreach(var subKey in regTimeZones.GetSubKeyNames())
//{
// Console.WriteLine(subKey);
//}
var subKey = regTimeZones.GetSubKeyNames().Where(s => s == "Atlantic Standard Time").First();
string daylightName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Dlt");
string standardName = (string)regTimeZones.OpenSubKey(subKey).GetValue("Std");
byte[] tzi = (byte[])regTimeZones.OpenSubKey(subKey).GetValue("TZI");
var regTzi = new RegistryTimeZoneInformation(tzi);
var tz = new TimeZoneInformation();
tz.Bias = regTzi.Bias;
tz.DaylightBias = regTzi.DaylightBias;
tz.StandardBias = regTzi.StandardBias;
tz.DaylightDate = regTzi.DaylightDate;
tz.StandardDate = regTzi.StandardDate;
tz.DaylightName = daylightName;
tz.StandardName = standardName;
TokenPrivilegesAccess.EnablePrivilege("SeTimeZonePrivilege");
bool didSet = Program.SetTimeZoneInformation(ref tz);
int lastError = Marshal.GetLastWin32Error();
TokenPrivilegesAccess.DisablePrivilege("SeTimeZonePrivilege");
// NOTE: This fixes the "Your current time zone is not recognized. Please select a valid time zone using the link below" error
// only when the machine is *restarted*.
//
// You must have the following set in your app.manifest to request admin rights to write to this key.
// <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
// <security>
// <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
// <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
// </requestedPrivileges>
// ...
var key = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", true);
key.SetValue("TimeZoneKeyName", key.GetValue("StandardName"));
if (didSet)
{
Console.WriteLine("Success, TimeZone Set!");
}
else
{
if (lastError == Program.ERROR_ACCESS_DENIED)
{
Console.WriteLine("Error: Access denied... Try running application as administrator.");
}
else if (lastError == Program.CORSEC_E_MISSING_STRONGNAME)
{
Console.WriteLine("Error: Application is not signed ... Right click the project > Signing > Check 'Sign the assembly'.");
}
else
{
Console.WriteLine("Win32Error: " + lastError + "\nHRESULT: " + Marshal.GetHRForLastWin32Error());
}
}
Console.ReadLine();
}
}
}

Categories

Resources