//==========================================================================================
//
// OpenNETCF.GuidEx
// Copyright (C) 2003-2005, OpenNETCF.org
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the OpenNETCF.org Shared Source License.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License
// for more details.
//
// You should have received a copy of the OpenNETCF.org Shared Source License
// along with this library; if not, email licensing@opennetcf.org to request a copy.
//
// If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please
// email licensing@opennetcf.org.
//
// For general enquiries, email enquiries@opennetcf.org or visit our website at:
// http://www.opennetcf.org
//
// !!! A HUGE thank-you goes out to Casey Chesnut for supplying parts of this code !!!
// !!! You can contact Casey at http://www.brains-n-brawn.com
//
//==========================================================================================
#if(COMPACT_FRAMEWORK)
using System;
using System.Runtime.InteropServices;
//using OpenNETCF.Security.Cryptography;
// New for v1.3 - "The Guid to end all Guids" - Peter Foot
namespace OpenNETCF
{
///
/// Helper class for generating a globally unique identifier (GUID).
/// Revised in v1.3
///
///
public sealed class GuidEx
{
private GuidEx(){}
#region New Guid
///
/// Initializes a new instance of the class.
///
/// A new object.
/// On CE.NET 4.1 and higher this method uses the CoCreateGuid API call.
/// On CE 3.0 based Pocket PCs it uses the OpenNETCF.Security.Cryptography classes to generate a random Guid.
public static System.Guid NewGuid()
{
//cocreateguid supported on CE.NET 4.1 and above (4.0 not supported by .NETCF)
if(System.Environment.OSVersion.Version.Major > 3)
{
return NewOleGuid();
}
else
{
//check if target has crypto API support
// if(OpenNETCF.Security.Cryptography.NativeMethods.Context.IsCryptoApi)
// {
// return NewCryptoGuid();
// }
// else
{
//if not use random generator
return NewRandomGuid();
}
}
}
#endregion
#region Constants
// constants that are used in the class
private class Const
{
// guid variant types
public enum GuidVariant
{
ReservedNCS = 0x00,
Standard = 0x02,
ReservedMicrosoft = 0x06,
ReservedFuture = 0x07
}
// guid version types
public enum GuidVersion
{
TimeBased = 0x01,
Reserved = 0x02,
NameBased = 0x03,
Random = 0x04
}
// multiplex variant info
public const int VariantByte = 8;
public const int VariantByteMask = 0x3f;
public const int VariantByteShift = 6;
// multiplex version info
public const int VersionByte = 7;
public const int VersionByteMask = 0x0f;
public const int VersionByteShift = 4;
}
#endregion
#region Crypto
// ///
// /// Create a new Random Guid using Crypto APIs
// ///
// ///
// public static System.Guid NewCryptoGuid()
// {
// //create guid manually
// byte[] guidbytes = new byte[16];
//
// //use crypto apis to generate random bytes
// OpenNETCF.Security.Cryptography.RNGCryptoServiceProvider rng = new OpenNETCF.Security.Cryptography.RNGCryptoServiceProvider();
// rng.GetBytes(guidbytes);
//
// //set version etc
// MakeValidRandomGuid(guidbytes);
//
// // create the new System.Guid object
// return new System.Guid(guidbytes);
// }
#endregion
#region Random
///
/// Create a new Random Guid (For platforms without Crypto support).
///
///
public static System.Guid NewRandomGuid()
{
byte[] guidbytes = new byte[16];
(new Random()).NextBytes(guidbytes);
//set version etc
MakeValidRandomGuid(guidbytes);
// create the new System.Guid object
return new System.Guid(guidbytes);
}
#endregion
#region Helper Methods
private static void MakeValidRandomGuid(byte[] guidbytes)
{
// set the variant
guidbytes[Const.VariantByte] &= Const.VariantByteMask;
guidbytes[Const.VariantByte] |=
((int)Const.GuidVariant.Standard << Const.VariantByteShift);
// set the version
guidbytes[Const.VersionByte] &= Const.VersionByteMask;
guidbytes[Const.VersionByte] |=
((int)Const.GuidVersion.Random << Const.VersionByteShift);
}
#endregion
#region Ticks
///
/// Create a new only using TickCount and bit shifting.
///
public static System.Guid NewGuidTicks()
{
// Create a unique GUID
long fileTime = DateTime.Now.ToUniversalTime().ToFileTime();
UInt32 high32 = (UInt32)(fileTime >> 32)+0x146BF4;
int tick = System.Environment.TickCount;
byte[] guidBytes = new byte[8];
// load the byte array with random bits
Random rand = new Random((int)fileTime);
rand.NextBytes(guidBytes);
// use tick info in the middle of the array
guidBytes[2] = (byte)(tick >> 24);
guidBytes[3] = (byte)(tick >> 16);
guidBytes[4] = (byte)(tick >> 8);
guidBytes[5] = (byte)tick;
// Construct a Guid with our data
System.Guid guid = new System.Guid((int)fileTime, (short)high32, (short)((high32 | 0x10000000) >> 16), guidBytes);
return guid;
}
#endregion
#region Ole
///
/// Create a new using COM APIs
///
///
/// Requires Windows CE.NET 4.1 or higher.
public static System.Guid NewOleGuid()
{
System.Guid val = System.Guid.Empty;
int hresult = 0;
hresult = CoCreateGuid(ref val);
if(hresult != 0)
{
throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "Error creating new Guid");
}
return val;
}
[DllImport("ole32.dll", SetLastError=true)]
private static extern int CoCreateGuid(ref System.Guid pguid);
#endregion
}
}
#endif