Friday
26Feb2010

How to cancel the CreditInform service

I realize this isn't exactly the kind of content that belongs on a blog primarily about programming, but I thought it still might be useful to some people.

If you got a CapitalOne credit card, then you were mostly likely given the opportunity to sign up for the CreditInform service, which charges you $5.99 every month to send you a credit report three times a year. Now, I know what you're saying: "You know you can already get your credit report three times a year for FREE, right?"

Yes, I knew that. However, in my specific situation, I was speaking to a someone whose primary language is not English, so by the time she had finished reading the terms and conditions, I was so lost that I just went ahead and said "Yes, I agree".

So, the damage is done. How do you undo it?

You can call CreditInform, which is what they tell you to do on their website. However, most people get the run-around and sometimes they'll just flat out hang up on you. If you do manage to get a real person, they'll ask you for a ton of information (like your SSN) that they don't actually need. I didn't feel like dealing with this, so I sent them a letter instead. The only information you need to provide is your name, address, member number, and PIN. The last two can be found in your "welcome package" (which you hopefully saved). Here's a template that worked for me:

[Your name]
[Your address]
[Date]

Dear Sir or Madam:

Please let this letter serve as notice that I am terminating my CreditInform account effective immediately. My account information is:

Member Number: [Member #]
PIN: [PIN]

Please send me written confirmation that my account has been closed.

Sincerely,


[Your name]

Fire up your favorite word processor, paste that in, and fill in the fields. When you're done, print it out and send it (preferably via Certified Mail) to:

CreditInform Customer Service
PO Box 222455
Chantilly, VA 20153-2455

After a couple of weeks, you should receive a rather lengthy letter confirming that your account has been cancelled. They'll also beg you to come back and throw some "facts" about identity theft in there to try to scare you.

Now, enjoy your freedom!

Sunday
24Jan2010

Enable Visual Studio Intellisense for DocBook

You can easily plug in XML Schemas to enable Intellisense for certain XML namespaces and file extensions. DocBook includes all of the necessary schemas, so all that's required is a schema catalog.

To make it a little easier, I put together a ZIP file that contains everything you need.

Just unzip it to one of the following locations, depending on your version of Visual Studio:

  • Visual Studio 2005
    C:\Program Files\Visual Studio 8\Xml\Schemas
  • Visual Studio 2008
    C:\Program Files\Visual Studio 9.0\Xml\Schemas
  • Visual Studio 2010
    C:\Program Files\Visual Studio 10.0\Xml\Schemas

DocBook Intellisense will be enabled for files with the docbook extension. If your solution contains DocBook files, you can simply right-click and choose “Open With…” then select “XML Editor”.

Enjoy!

Sunday
27Dec2009

Valve Map Format Utility Library v1.0 Released

Valve Software's Source Engine uses a level editor called Hammer. The files produced by Hammer are in the Valve Map Format (VMF), which are simply text files that define the structure of a map. This file gets passed to a BSP (Binary Space Partitioning) compiler that builds the final product.

A little side project of mine called for a library that could parse VMF files and read the interactive parts of a Source Engine map. So, I built one. The result is the VMF Utility Library. It includes a complete parser, writer, object graph, and special classes for common VMF data types (such as color and vertex). The library is open source and includes documentation, along with a Getting Started tutorial.

I haven't put this one up on CodePlex yet, but you can download it directly (ZIP, 200kb).

Thursday
24Dec2009

Rendering an in-memory Graphviz image with C#

I've been working on a little side-project that involves a lot of graphing. Graphviz has been the most complete solution, but existing options for using it with .NET were rather scarce. WinGraphviz is based on an older version of Graphviz and hasn't been improved since 2004. Plus, it's a COM component, which is yet another thing you have to install on the end-user's machine.

It turns out, however, that the Graphviz library is fairly simple to understand. Once I got the correct DLL configuration copied to my application's directory, the rest of the P/Invoke stuff was easy. On top of it all, Graphviz includes the ability to render an image in-memory, so there's no need to write to the disk and read the result back again. Writing to the disk was the biggest performance bottleneck for my application, so the in-memory rendering feature was a huge relief.

To get started, we need a class to hold our P/Invoke methods and a few helper constants.

public class Graphviz {
    public const string LIB_GVC = "gvc.dll";
    public const string LIB_GRAPH = "graph.dll";
    public const int SUCCESS = 0;
}

To use Graphviz as a library, we first have to create a Graphviz context, which the other methods will use. Add these to our Graphviz class.

/// <summary>
/// Creates a new Graphviz context.
/// </summary>
[DllImport(LIB_GVC)]
public static extern IntPtr gvContext();

/// <summary>
/// Releases a context's resources.
/// </summary>
[DllImport(LIB_GVC)]
public static extern int gvFreeContext(IntPtr gvc);

Now we need some methods to load and close a graph. These are found in graph.dll.

/// <summary>
/// Reads a graph from a string.
/// </summary>
[DllImport(LIB_GRAPH)]
public static extern IntPtr agmemread(string data);

/// <summary>
/// Releases the resources used by a graph.
/// </summary>
[DllImport(LIB_GRAPH)]
public static extern void agclose(IntPtr g);

Once we have our graph loaded, we need to apply a layout.

/// <summary>
/// Applies a layout to a graph using the given engine.
/// </summary>
[DllImport(LIB_GVC)]
public static extern int gvLayout(IntPtr gvc, IntPtr g, string engine);

/// <summary>
/// Releases the resources used by a layout.
/// </summary>
[DllImport(LIB_GVC)]
public static extern int gvFreeLayout(IntPtr gvc, IntPtr g);

Once the graph has a layout, we can render it.

/// <summary>
/// Renders a graph to a file.
/// </summary>
[DllImport(LIB_GVC)]
public static extern int gvRenderFilename(IntPtr gvc, IntPtr g,
    string format, string fileName);

/// <summary>
/// Renders a graph in memory.
/// </summary>
[DllImport(LIB_GVC)]
public static extern int gvRenderData(IntPtr gvc, IntPtr g,
    string format, out IntPtr result, out int length);

Now, you may be thinking that you can just copy gvc.dll and graph.dll over and all will be well. But, sadly, that's not the case. Those DLLs have a few dependencies. You'll need all of the following from your Graphviz installation's /bin directory:

Graphviz loads layout and rendering plugins dynamically using a configuration file, which must also be included alongside your application. If you installed Graphviz using the MSI, there should already be a configuration file in the /bin directory. Mine was called config6, but I'm not sure if the name varies. If you don't have a configuration file, you can generate one with dot -c.

Now that we have the necessary DLLs, we can actually do some rendering!

/// <summary>
/// Renders a DOT string to the specified image format.
/// </summary>
public static byte[] RenderDot(string dot, string format) {
    // Create a Graphviz context
    IntPtr gvc = gvContext();

    // Load the DOT data into a graph
    IntPtr g = agmemread(dot);

    // Apply a layout
    gvLayout(gvc, g, "dot");

    IntPtr result;
    int length;

    // Render the graph
    gvRender(gvc, g, format, out result, out length);

    // Create an array to hold the image
    byte[] image = new byte[length];

    // Copy the image from the IntPtr
    Marshal.Copy(result, image, 0, length);

    // Free up the resources
    gvFreeLayout(gvc, g);
    agclose(g);
    gvFreeContext(gvc);

    return image;
}

Here's the code in action, rendering a graph of the Graphviz DLL dependencies:

string dot = @"digraph Graphviz {
    cdt -> msvcr80, cdt -> kernel32,
    graph -> cdt, graph -> msvcr80, graph -> kernel32,
    gvc -> libexpat, gvc -> ltdl, gvc -> zlib1, gvc -> cdt,
    gvc -> pathplan, gvc -> graph, gvc -> msvcr80, gvc -> kernel32,
    ltdl -> msvcrt, ltdl -> kernel32,
    pathplan -> msvcr80, pathplan -> kernel32,
    zlib1 -> msvcrt, zlib1 -> kernel32,
    libexpat -> kernel32
}";

byte[] image = Graphviz.RenderDot(dot, "png");

And the result:

Wednesday
16Dec2009

Managed NovaCore SDK is up on CodePlex!

There seems to be a lot of interest in a managed version of Novatel Wireless' NovaCore SDK (on the Developer Forums, at least). I've been working on one off and on for a couple of weeks and decided to upload what I have so far to CodePlex.

It's not much, really. So far, the Core module is the most complete of the six and even it is far from done. Everything is basically a 1-to-1 port, so you should just be able to follow along in the NovaCore SDK documentation. The only major change is session management. Instead of releasing sessions manually with a module's ReleaseSession function, the library uses SafeHandles that automatically handle session cleanup during garbage collection. There's also a helper class (NovaCoreSdk) that makes error handling easier.

As the project page says, I'm looking for contributors. To be honest, P/Invoke is definitely not my strong point. The library wouldn't even exist without the good folks over at StackOverflow (especially the P/Invoke master, Jared Par). Preferably, contributors should own a Novatel Wireless device for testing. I have an EVDO device, so it would be great if someone with a HSPA device would come on board to test the HSPA-only features of the SDK.