Wednesday, September 12, 2007

I have been playing with the Blend August Preview and in particular the resource feature. This is an excellent feature that allows you to style your user interface from a single location much like CSS does for web pages.

I created a new project. I added a rectangle to the window and changed its color to a nice shade of blue:

 

I created another rectangle next to the original rectangle and removed the stroke from both of them:

 

Clicking on the original rectangle, I converted the color to a resource named MyColor and put it in a new resource dictionary:

 

Now, when I change MyColor in the resource dictionary, all instances of MyColor will change with it:

 

So far, so good. I would now like my second rectangle to be a linear gradient going from MyColor to black. When I change MyColor I want it to change the initial gradient color too.

Unfortunately, there doesn't seem to be a way to do this in the GUI. Fortunately, there is a very simple way to do this in the XAML.

Click on the second rectangle and change its fill to a gradient. Change the first gradient color to red and the second gradient color to black:

 

Now, convert the gradient brush to a resource. Call it MyBrush and put it in the same resource dictionary.

 

Save all of your files and click on the resource dictionary file. Open it in XAML view. You should see the following:

 

Change the first gradient stop from "#FFFF0000" (red) to "{DynamicResource MyColor}":

 

Now, when you change MyColor, the first color in the MyBrush resource will also change:

Saturday, June 02, 2007

I just noticed something very strange when opening an Excel document that is in Excel 97-2003 format.

This is the file system before I open the file:

Then I open the file using Excel 2007. I do nothing to the file. It is opened in compatibility mode. The file system now looks like this:

The last modified date changed! As strange as that is, it gets even stranger. Now if I close Excel, I don't get any warnings and the file system now looks like this:

I kid you not! That is a new screenshot, not a copy of the first one!

Strange!

Wednesday, May 30, 2007

Please see this previous post on how to get started using LINQ with Outlook. I will assume you have added the appropriate references to the Outlook object model.

In this post I am going to show you how to find emails from people that you don't have in your address book. We will achieve this by cross referencing the information in your contacts with the emails in your inbox.

Now, inside the Main method, we need to add the following code:

Outlook._Application outlookObject = new Outlook.Application();

This code references the Outlook application. We now need to specify which Outlook folders we wish to use:

Outlook.MAPIFolder contactsFolder = outlookObject.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);

Outlook.MAPIFolder inboxfolder = outlookObject.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);

The email addresses for contacts are contained in the Email1Address, Email2Address and Email3Address. These are three separate properties on a contact. We can get that information like so:

var contactsEmail = from contact in contactsFolder.Items.OfType<Outlook.ContactItem>()

select new List<string>() { contact.Email1Address, contact.Email2Address, contact.Email3Address };

This will give us a collection of a list of email addresses. Each contact may have up to three email addresses specified. This means that the list may contain null entries. In addition it is not very useful to have an embedded collection. If we kept it this way we would have to have two foreach loops to iterate through the data. Fortunately, LINQ provides the SelectMany operator:

var allContactEmails = contactsEmail.SelectMany(sel => sel.Where(e => e != null));

This single line of code transforms the collection of lists into a single collection of strings with no null entries. To help us compare the email addresses we now convert them to lower case using the Select operator and remove duplicates with the Distinct operator. Note that we could have done that on the previous line after the Where:

var allContactEmailsLower = allContactEmails.Select(sel => sel.ToLower()).Distinct();

Now, let's get the sender's email address from each email in the inbox:

var emailItems = (from email in inboxfolder.Items.OfType<Outlook.MailItem>()

where email.SenderEmailType == "SMTP"

select email.SenderEmailAddress.ToLower()).Distinct();

We now have a collection of sender email addresses and a collection of email addresses from our address book. We would like to find out the email addresses that are in the senders list but not in our address book. We do that with the Except operator:

var exceptions = emailItems.Except(allContactEmails);

The Except operator will return items in the first sequence that are not in the second. All that is left is to output our results:

foreach (string str in exceptions)

{

Console.WriteLine("{0}", str);

}

That's all there is to it. Now you can keep your address book up to date. It would be relatively trivial to update the program to update your address book J

 

As part of my job I am required to connect to a third party VPN. The security on that network requires, among other things, all major updates. So, when I tried to login today and could not I decided to force an update. That update took me 3 hours in all. The reason being that SvcHost decided to hog my computer. Steadily mocking me at 99% CPU utilization.

After some head banging I decided to try out my support options. Google was my first stop. I found this site. A very handy description about how to solve this "rare" problem where SvcHost pegs your CPU and Windows Update never gets anywhere. Worked like a charm for me. Thank you Ken!

This also gave me a chance to browse the web a little. A dangerous prospect as it can be hours before I resurface, trying to recall what I was doing in the first place. I came across two things of note.

ZoomIt

The ZoomIt utility from the sysinternals folks. Excellent utility for when you give presentations. A feature I particularly like is being able to wipe the screen blank and write text on it.

Microsoft Surface

The other site I came across was Microsoft Surface. Wow! I want one now! I do think they missed the boat a little with respect to Silverlight. Why not have 2 demonstrations? One done in Flash and another done with fancy interaction in Silverlight?

I like the idea of rotating photos, but seriously, can Microsoft Surface not detect where you are and orient the photos correctly the first time?

The drink demo with the bubbles was neat. What about the Surface detecting you are close to the end of your drink and asking if you would like another?

What about games? It would be cool to see a poker demo complete with digital playing cards and virtual chips.

I would also have liked to see integrated fingerprint/retina reading in the demo. That way, I would not feel so hesitant about putting my PDA or my credit card on one of these Surfaces.

Lastly, this opens up a whole new class of exploits. I love the idea of hacking my way to free desert at a restaurant! Yummmy!

Friday, May 25, 2007

Check out this article on using a freezer to recover data off broken hard drives.  I wonder if the freezer can also fix broken code?

 

Grab yourself a copy of Visual Studio code name "Orcas" and follow along as we create a program to access your data in Outlook.

 

Test Data

You will need to have some contacts in Outlook to test this program. Add at least 3 contacts, one with a home phone but no email, one with an email but no phone numbers, and one with no email and no phone numbers.

 

Getting Started

Start "Orcas" and click File->New->Project… Choose to create a Console Application in C# with the .NET Framework 3.5.

 

 

We need to add a reference to Outlook 2007. Right click on references in Solution Explorer and choose Add Reference…

 

 

Select the COM tab and choose the Microsoft Outlook 12.0 Object Library and press OK.

 

 

Two references will be added. Microsoft.Office.Core and Microsoft.Office.Interop.Outlook. Now add the following using statement to your Program.cs source file:

using Outlook = Microsoft.Office.Interop.Outlook;

We now need to get an instance of the Outlook Application object. Type the following code in the Main method:

    Outlook._Application outlookObject = new Outlook.Application();

We want to look at the contacts stored in Outlook so we now get the contacts folder:

    Outlook.MAPIFolder folder = outlookObject.ActiveExplorer().Session.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderContacts);

Now, let's define our LINQ query:

    var contactsNoEmail = from contact in folder.Items

where contact.Email1Address == null

select contact;

This query is going to get the contacts from the contacts folder where the Email1Address is not defined. Now we need to iterate through our results:

foreach (Outlook.ContactItem contact in contactsNoEmail)

{

    Console.WriteLine("{0} - {1} {2}", contact.LastFirstNoSpaceCompany, contact.FirstName, contact.LastName);

}

Lastly let's output that we have finished in case we get no results. Also we will request that the user press Enter so we can see our results when we run from the debugger:

    Console.WriteLine("The end");

    Console.ReadLine();

Now we need to build our project. Bo to the Build menu and choose Build Solution. The build should fail with the following error:

The type arguments for method 'System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Linq.Func<TSource,bool>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

To fix this we need to specify the type of the items in the folders Items collection. Change the first line of the LINQ query to:

    var contactsNoEmail = from contact in folder.Items.OfType<Outlook.ContactItem>()

Now you should be able to build and run the program. When you run your program you may get a warning dialog. Choose to allow access if this is in response to your program running.

 

 

You should see a list of contacts who don't have an Email1Address defined followed by the string "The End". You will need to press Enter to end the program.

 

Adding a Second Query

Now, let's make our program a little more useful. It is possible that we have contacts with phone numbers but no email address. If we have a contact without either we want to know. We could do this in the same query, but for demonstration purposes we are going to do it as a second query. Add the following query after the first query inside your Main function:

    var contactsNoPhone = from contact in folder.Items.OfType<Outlook.ContactItem>()

        where (contact.HomeTelephoneNumber == null) && (contact.BusinessTelephoneNumber == null) && (contact.MobileTelephoneNumber == null)

        select contact;

We check to see if the contact has a home, business or mobile number defined. If they don't we return that contact to the contactsNoPhone collection. To see the results of the second query we can change our iteration loop as follows:

    foreach (Outlook.ContactItem contact in contactsNoPhone)

When we build and run the program we get a list of contacts that don't have a home, business or mobile number defined in the contact information.

The next step is to combine the two queries so that we can find contacts without a phone and without an email address. To do this we are going to intersect the two queries giving us only the contacts that are in both queries and changing the iteration to use the new variable:

    var intersection = contactsNoEmail.Intersect(contactsNoPhone);

foreach (Outlook.ContactItem contact in intersection)

Build the program and run it. You will notice that you have no contacts listed even though you added some contacts that should match the query. The reason is that each query of Outlook returns new objects such that when they are compared, they appear different. This is due to there being a reference comparison rather than a value comparison. We can fix this with a couple of simple changes.

First we need to define a new class that implements IEqualityComparer for Outlook.ContactItem's. This class looks like this:

    class ContactItemComparer : IEqualityComparer<Outlook.ContactItem>

    {

        public bool Equals(Outlook.ContactItem a, Outlook.ContactItem b)

{

return (a.LastFirstNoSpaceCompany == b.LastFirstNoSpaceCompany);

}

public int GetHashCode(Outlook.ContactItem a)

{

    return a.Size;

}

}

This defines an Equals and a GetHashCode function. Note that these are by no means industrial strength implementations as they only compare the LastFirstNameNoSpaceCompany field and uses the size of the contact item as the hash. This will suffice for our example although checks for null will have to be done in production code. All that leaves is for us to specify the ContactItemComparer in the intersect function:

    var intersection = contactsNoEmail.Intersect(contactsNoPhone, new ContactItemComparer());

When you now build and run your program you should see contacts that have no email in addition to no home, business or mobile phone number specified.

 

Summary

This example shows how easy it is to access the Outlook object model from LINQ. Although you could write this program without LINQ, the query syntax becomes compelling when you start to use it to access all your data stores.

Friday, May 18, 2007

Two recent news articles related to computer forensics stood out recently.

The first article talks about a Filipino cybersleuth being awarded the world's best computer investigator for 2007. The winner, Alexander Ramos, has been a cybercrime investigator for 10 years. The prize of $10,000 goes to the charity of the winners choosing.

In the second article, a bogus computer expert pleads guilty of falsifying his credentials. The computer expert faces a maximum of 10 years in prison and a fine of $500,000.

An interesting comparison of the two ends of computer forensic investigations.

Thursday, May 03, 2007

In my first blog post on Shadow Copy, I said that Previous Versions is available in the Ultimate, Business and Enterprise versions of Vista. This means that the feature is not available in Home and Home Premium versions.

It is true, although there is a twist. You don't have the ability to access the Previous Versions of files in Home and Home Premium, but the Previous Versions are still being made. One of the students in my Computer Forensics class pointed out this article. The article says that if you upgrade from Home or Home Premium to Ultimate, Business or Enterprise versions of Vista, then you can get access to the Previous Versions of your files.

This is great news for the forensic examiner as they have even more evidence to look at and Previous Versions can provide some of the best evidence on a disk.

Wednesday, May 02, 2007

I have now been blogging using Word 2007 for a while. It really makes the blogging process about as painless as it can be. I don't have to worry about formatting and can include screenshots painlessly in my posts. Although I haven't done it yet, I also have the ability to create SmartArt and include that in my posts to illustrate a point (or not!):

Setting Word 2007 up for blogging with Subtext is not entirely intuitive and also required a small code change to get image posting to work.

Go to the Office menu, choose Publish and select Blog:

You will be presented with a new Word document that looks like this:

You can title your post by replacing the text "Enter Post Title here".

To set up Word 2007 to work with Subtext for the first time, you need to click on manage accounts:

Click New to create a new account. You will see the following dialog. Choose other for blog provider when using Subtext:

Then click Next. You will now see a dialog for specifying the blog API. Choose the following settings:

Click on the Picture Options button and make sure the dialog has the following options:


You are now set as far as Word 2007 is concerned. Posting of pictures will not work until you change Subtext. The problem stems from a misunderstanding of the MetaWeblog spec by Word 2007. Word 2007 is sending the blogid as an int rather than a string. The change we made was to create a duplicate method that took an int and converted it to a string in the call to the other method. The method is the metaWeblog.newMediaObject. A quick recompile later and everything works just great!

Friday, April 27, 2007

I recently saw a post on the Visual Business Intelligence blog about representing 360 data points. The discussion in the forum was interesting as people demonstrated ways to represent these data points on a single image.

I wanted to see what I could come up with. Representing information in effective ways is a good skill for the forensic analyst. I also wanted to try out the conditional formatting feature of Excel 2007 to see what it was capable of.

First step was to download the data. Here is what the spreadsheet looks like:

Looking at some of the other submissions, I decided to order the columns similarly. Housing was the biggest expenditure down through education. This would make the formatting easier to see later. You also need to do this step first otherwise your formatting may get "confused" when you start moving columns.

On the Home tab on Excel 2007, there is a conditional formatting button. Selecting this button gives the following choices:

There are some powerful options under this area and I encourage you to experiment with them. Today I am going to look specifically at Data Bars and Color Scales.

Data Bars

If I select all of the data and choose the blue Data Bar, I get the following:

Notice how the bars are relative to the biggest data item in the selection. If I was to instead select each column individually and assign the blue data bar we would get the following:

Which style you want comes down to what you are trying to show with your data. For our purposes, we would like to see the data bars relative to the largest value, so we will use the first method.

There are some issues with the data bars:

First, you will notice that there is a gradient on the data bar. This can make the end of the data bar hard to see. Unfortunately, this is not something that can be changed.

Second, you may also notice that the smaller values still have a considerable size data bar. Should the data bar for 0.3 really be that big? Turns out that the data bar has a minimum size. Fortunately this can be changed.

The change can be made by going into the Visual Basic editor (ALT-F11), bringing up the immediate window (CTRL-G) and typing the following:

Range("B2:M31").FormatConditions(1).PercentMin = 1

After pressing the enter key, this will change the minimum size of the data bar to its smallest value for the range specified:

One thing that would be nice is to have the data bars be different colors depending on their value. Through the UI there really is no way to do this. Thanks to the Excel 2007 Blog, there is a way to achieve this. This "trick" uses a little VBA code to achieve its goal.

With Excel 2007, you can apply multiple data bar conditional formats to the same data, one over the top of the other. Then, once you have created your multiple data bar layers, you can selectively show the ones you want. There is a "trick" to the "trick" though. Each successive data bar format needs to be on a different selection. This was not explained in the blog entry, but I couldn't find a way to overlay formats on the same data selection.

So, starting with the original Excel spreadsheet, select all of the data and apply the blue data bar format and then change the PercentMin to 1:

Now, select all of the data AND an extra column and apply the orange data bar format:

The blue data bar format will be underneath the orange. Now, select all of the data AND 2 extra columns and apply the red data bar format:

Now we can selectively display the data bars. Select the data from B3 through M31 – This selects all data except for the EU25 data. Now bring up the Visual Basic editor and type the following in the immediate window:

selection.FormatConditions(1).formula = "=if(b3<b$2, true, false)"

selection.FormatConditions(2).formula = "=if(b3=b$2, true, false)"

selection.FormatConditions(3).formula = "=if(b3>b$2, true, false)"

Now, each line of VBA code will only be executed when you press enter on that line. You will therefore need to press enter 3 times to execute each line of VBA code.

The first line specifies the visibility of the red data bar (the last format added is at index 1). We specify that the red data bars indicate values less than the EU25 average. The second line indicates in orange the values equal to the EU25 average. The third line of code indicates in blue the values greater than the EU25 average.

You should end up with the following:

Looking at this you can clearly see that the countries are listed in order of percentage spent on food. To change it to housing we can sort the data. To do that, select all of the data except for EU25 (as that cell is used in our formula). Now click on the Z-A sort button on the Data tab:

There appears to be an artifact in the housing column where some red shows up. We can remove that by executing the 3 lines of VBA code again.

It is important to note that above I used data bars on the whole data set. If you wanted the data bars to be specific to an expenditure, you would have to repeat the procedure above for each column. This is shown in the final chart in the blog.

Now, let's turn our attention over to the Color Scales.

Color Scales

Starting out with the original data, we can select all of the data and apply the Red, Yellow, Blue color scale. The result will be something like this:

You can clearly see that there is more expenditure on housing and less on education. You can also see that restaurants have quite a range of values and Romania spends a lot more than the other countries on food.

You can customize the colors using "More Rules…"

There's not really much more to say about color scales, so we will move on to combining the data bar and color scales in the finished spreadsheet.

Finished Spreadsheet

Here is the finished spreadsheet combining the 2 conditional formatting methods discussed in this post:

I chose to use shades of grey for the data bars to prevent clashing with the color scales. The color scales represent values across the whole data set, whereas the data bars represent values for the particular expenditure.

In addition, I was able to remove the text for the values. I did this by making the data values font very big (409pt) and sizing the cells as before. You then need to align the countries text to the top of the cell.

The task was to create a single image that had all of the data set represented. That proves to be quite a challenge. Typically you would highlight the data you wanted to showcase.

I have posted a better image of the finished spreadsheet to the original discussion.