Tuesday, February 13, 2007

Public Service Announcement: Back up Your Data

When a disk management or partition editing utility says you should back up your data before performing this operation, it's probably not joking. There's a pretty decent chance that this application will encounter error 1562 somewhere in the midst of merging your D and E partitions, leaving you with an unformatted drive and 135 GB of corrupt and unrecoverable data. Hypothetically.

If you're like me my overconfident friend, you might be somewhat lucky and only lose non-critical data like downloaded software, ISO images, and MP3s that you also have copies of on your portable MP3 player.

Should you find yourself in this unfortunate situation, I've had some success recovering data using the FindPart and FindNTFS utilities by Svend Olaf Mikkelsen. I've used those in the past to recover an entire partition from a hard disk with a corrupted partition table. These utilities were able to list and copy "my friend's" lost 135 GB of data yesterday, but unfortunately in this case, almost all the data was corrupt. At least the filenames tell which software/ISOs need to be downloaded again.

Sunday, February 11, 2007

Wake On LAN

I've recently upgraded both my home theater (media center) PCs to Windows Vista. The default power management settings put the HTPCs to sleep after some period of inactivity -- a feature I had disabled when I was running XP MCE on those machines. I usually don't let my machines "sleep" because I often access them remotely over the network.

Apparently I'm easily distracted, because my immediate need to copy a file to my sleeping HTPC sent me off on a 2-hour mission to write a little app that would utilize my PCs' Wake On LAN (WOL) capabilities. This started out as a simple WinForms app with a TextBox for input (MAC address) and a "Wake Up" button. That took about fifteen minutes, because I had to research how WOL works, and the "Magic Packet" that tells the PC to wake up (in a nutshell: the packet consists of 6 bytes of 0xFF followed by the remote PC's MAC address repeated 16 times, for a total of 102 bytes).

By then I was excited about how easy and cool WOL is, and what else I could do with the app. Anyway, a couple hours later, I ended up with a simple app that can be run from the command line or as a GUI app. I don't want to have to remember or lookup MAC addresses every time I want to wake up a PC, so the app can store MAC/hostname combinations. When run from the command line, I can pass in either the MAC address, or the hostname (which looks up the MAC stored in the file).

User Interface:



Command Line:
(Note that I'm using a MessageBox to confirm that the WOL packet has been sent. At one point I was doing the confirmation via the Console, but having the WinForms .exe switch gears to run as a console app, grabbing the current console for I/O, etc. was messy, and ended up doing weird things to the command prompt when it was done. One of these days I might try to get the console output working the way I want it to.)



The actual WOL process is very straightforward in .NET (I used C#); I just tacked on some other bells and whistles like associating hostnames to MACs, automatically saving the list to a file, and allowing it to be run as a GUI or command line app. I plan to clean up the code and release it at some point. In the meantime, let me know if you're interested.

...

I'm a bit behind on my blog reading, and I just saw Jeff Atwood's post from Friday: Remotely Waking Up Your PC. He posted about this very same subject, and apparently he got into it for the same reason (he wanted to wake up his Vista HTPC) -- just a day earlier. Weird. As expected, Atwood has some good stuff to say about WOL (refer to his post for how to set up the PC to respond to the WOL Magic Packet), but I enjoyed writing the app myself, so I guess I'm glad I didn't see his post until today.

Atwood's closing statement is perfect:

"You know, I think there's an inspiring moral to this story: why get out of your chair and walk 20 feet when you can spend two hours figuring out how to do it without moving at all? It's a symbolic victory for lazy people everywhere."

Wednesday, February 07, 2007

Building Directory Paths Dynamically

It's been a hellacious week year at the office so far.

<tangent>
Firefox's spiffy spellchecker thinks that 'hellacious' isn't a real word. It is. I was using the word instead of the less elegant alternative, 'helluva', but now that I've actually looked it up, I see that the definitions fit even better than I had intended. Particularly "formidably difficult" and "distasteful and repellant." We now return you to the blog post in progress.
</tangent>

Today's major issues revolved around a web application update that was deployed last night. The point of this post is to focus on just one of the specific issues and how it could have very easily been prevented. For the record, I'm not involved in the development or deployment of this application; I just stepped in today when SHTF.

The issue was that the application (an ASP.NET site written in C#) was looking for client-specific uploaded files in directories such as:

D:\application\uploadsClientA

As you can probably guess, the ACTUAL paths were like this:

D:\application\uploads\ClientA

This path was built dynamically in code by concatenating the upload destination (D:\application\uploads) stored in a configuration file with the name of the client currently logged in to the application (ClientA). This was done using basic string concatenation, and since the path in the config file didn't have a trailing slash, the resulting path did not exist.

The .NET Framework provides a very handy method in the System.IO namespace for building directory paths dynamically: Path.Combine(string path1, string path2). This method handles the insertion of slashes where needed, idiot-proofing the path concatenation without any extra code on your part. The developer's code SHOULD have looked something like this:

string path = Path.Combine( Config["UploadDirectory"], clientname );

Then it wouldn't matter whether the UploadDirectory value in the config file had a trailing slash or not.

I guess the moral of the story is that the Framework is full of handy methods that handle many common scenarios and take out a lot of the guesswork (and reduce the amount of code YOU have to write and maintain). The trick is to find these methods and use them.