Tuesday, March 01, 2005

Another personality preview for those bored with the work they should be doing.

 

Cattell's 16 Factor Test Results
Warmth ||||||||||||||| 46%
Intellect |||||||||||||||||||||||||||| 90%
Emotional Stability ||||||||||||||| 50%
Aggressiveness |||||||||||||||||| 54%
Liveliness |||||||||||||||||| 58%
Dutifulness |||||||||||||||||| 58%
Social Assertiveness |||||||||||| 34%
Sensitivity ||||||||| 30%
Paranoia |||||||||||| 38%
Abstractness |||||||||||||||||| 58%
Introversion |||||||||||||||||||||||| 78%
Anxiety ||||||||| 26%
Openmindedness ||||||||||||||||||||| 70%
Independence |||||||||||||||||| 58%
Perfectionism ||||||||| 26%
Tension |||||||||||| 38%
Take Cattell 16 Factor Test (similar to 16pf)
personality tests by similarminds.com
3/1/2005 11:23:43 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, February 23, 2005
2/23/2005 10:06:23 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, February 21, 2005

I'm working on a fairly straightforward wrapper for a customer and it occurred to me that there are a distinct lack of simple working examples of the “more difficult” marshaling techniques in the CF. A classic example is a native struct that contains a pointer to a string. On the desktop it's simple (and in CF 2.0 it's pretty easy too), but in CF 1.0, it's not straightforward.

Personally I don't mind the code required to do the marshaling - in fact I think everyone using marshaling should be required to understand these fundamentals. While that's never going to happen, some people still are interested, or their project may necessitate being able to do it, and of course having a sample never hurts.

So consider the following very simple struct. A simgle 4-byte integer followed by a pointer to a string:

typedef struct
{
 INT IntMember,
 LPSTR StringMember
} MYSTRUCT, *PMYSTRUCT;

What appears to be rather simple in C - just a mere 5 lines of code - expands to the following not-so-small 80-line code base in C#:

public class EmbeddedStringPtrStruct
{
 // offsets used internally
 private const int intMemberOffset = 0;
 private const int stringMemberOffset = 4;
 // this is the actual struct data to be passed to native methods
 protected byte[] m_bytes = new byte[8];
 // private var to hold string data pointer
 private IntPtr m_pStringMember = IntPtr.Zero;
 // default public ctor
 public EmbeddedStringPtrStruct()
 {
 }
 // dtor - call Dispose if the consumer didn't
 ~EmbeddedStringPtrStruct()
 {
  this.Dispose();
 }
 // operator to get a byte array used for marshaling
 // this allows you to pass the EmbeddedStringPtrStruct directly
 public static implicit operator byte[](EmbeddedStringPtrStruct esps)
 {
  return esps.m_bytes;
 }
 // accessor for INT member
 public int IntMember
 {
  get
  {
   return BitConverter.ToInt32(m_bytes, intMemberOffset);
  }
  set
  {
   byte[] bytes = BitConverter.GetBytes(value);
   Buffer.BlockCopy( bytes, 0, m_bytes, intMemberOffset, 4 );
  }
 }
 public string StringMember
 {
  get
  {
   IntPtr ptr = (IntPtr)BitConverter.ToInt32( m_bytes, stringMemberOffset );
   return MarshalEx.PtrToStringUni(ptr);     
  }
  set
  {
   // first see if we already have one allocated
   if(! m_pStringMember.Equals(IntPtr.Zero))
   {
    MarshalEx.FreeHGlobal(m_pStringMember);
   }
   // alloc storage for the string so we can pass the ptr
   m_pStringMember = MarshalEx.StringToHGlobalUni(value);
   // convert to an Int32 and get the bytes
   byte[] bytes = BitConverter.GetBytes( m_pStringMember.ToInt32() );
   // stuff it into the global
   Buffer.BlockCopy( bytes, 0, m_bytes, stringMemberOffset, 4 );    
  }
 }
 public void Dispose()
 {
  // clean up native memory allocations
  if(! m_pStringMember.Equals(IntPtr.Zero))
  {
   MarshalEx.FreeHGlobal(m_pStringMember);
  }
 }
}

See, not so bad, is it?

2/21/2005 10:14:39 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Sunday, February 13, 2005

I see requests for CF encryption examples on a regular basis in the newsgroups and the Forums.  Well, here's one I used in an app for storing a password in the registry using the OpenNETCF Encryption stuff :

internal static byte[] GetIV(string keyString)
{
 byte[] bytes = Encoding.Unicode.GetBytes(keyString);
 byte[] iv = new byte[24];
 if(bytes.Length < 24)
 {
  for(int i = 0 ; i < 24 ; i++)
  {
   iv[i] = bytes[i % bytes.Length];
  }
 }
 else
 {
  Array.Copy(bytes, 0, iv, 0, 24);
 }
 return iv;
}
internal static byte[] Encrypt(string toEncrypt, byte[] iv)
{
 TripleDESCryptoServiceProvider des = null;
 try
 {
  des = new TripleDESCryptoServiceProvider();
 }
 catch(Exception)
 {
  MessageBox.Show("The high encryption pack must be installed.  Please install and try again.",
   "Crypto Failure",
   MessageBoxButtons.OK,
   MessageBoxIcon.Exclamation,
   MessageBoxDefaultButton.Button1);
  return null;
 }
 des.Key = PRIVATE_KEY;
 des.IV = iv;
 return des.EncryptValue(Encoding.Unicode.GetBytes(toEncrypt));
}
internal static string Decrypt(byte[] toDecrypt, byte[] iv)
{
 TripleDESCryptoServiceProvider des = null;
 try
 {
  des = new TripleDESCryptoServiceProvider();
 }
 catch(Exception)
 {
  MessageBox.Show("The high encryption pack must be installed.  Please install and try again.",
   "Crypto Failure",
   MessageBoxButtons.OK,
   MessageBoxIcon.Exclamation,
   MessageBoxDefaultButton.Button1);
  return null;
 }
 des.Key = PRIVATE_KEY;
 des.IV = iv;
 byte[] decBytes = des.DecryptValue(toDecrypt);
 return Encoding.Unicode.GetString(decBytes, 0, decBytes.Length);
}
Usage is simple:
byte[] encryptedPwd = AppGlobal.Encrypt(password, GetIV(PUBLIC_KEY));
string  previousPwd = Decrypt(encryptedPwd , GetIV(PUBLIC_KEY));
2/13/2005 7:13:36 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Wednesday, February 09, 2005

If you've done much with the CF, then you're likely aware that NDOC doen't much like any namespace that's outside of the standard FFW (like the Microsoft.WindowsCE stuff).  While that's been an annoyance for documenting parts of the SDF (leaving holes in the docs), I just ran into a place where it prevents me from generationg any docs - when targeting the TinyCLR.

So, has anyone found anything that can generate decent looking docs without exploding on stuff it doesn't see (or maybe asking for the reference)?  I know NDOC is open source and I could get it working, but I'd rather do actual work.

2/9/2005 11:18:19 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]  |