Dell Motherboard Troubles, Part II

It seems that the replacement motherboard that I got last month, for my Dell XPS m1210 laptop, had some problems… the system just died tonight, and Dell’s support line says that it looks like the motherboard again, with a different problem. I was an electronics technician for the USPS for many years before I turned professional software developer, and I’ve seen a number of replacement electronic parts that failed within minutes of installing them, so I’m not too surprised or upset by this — it lasted nearly six weeks, after all.

Fortunately, I’d finished the major troubleshooting on the new Project Badger code a few hours before it threw in the towel, because the only other system I have set up right now is Mini-mEee, and it doesn’t really have the horsepower to run Windows XP in VMware. It’ll be Wednesday before they can get the part (and the technician to install it) out here, because it was after 5pm when I called.

Oh well, I guess I’ll get a chance to do some other things for a bit. Maybe even mow the lawn, like my wife has been nagging me to do for a couple weeks now. 🙂

“How the Psystar lawsuit might go very, very wrong… for Apple”

I’ve been saying since April or so that Apple really wanted to avoid going to court over Psystar (the Hackintosh maker) because it would open up a huge can of legal worms for Apple, but apparently most legal people think that Apple will win the case without even trying. This post gives some good reasons why my take on it (which is presumably also Apple’s) has some merit.

Religious Battles and The Internet

GoddessJ and I have been watching, with a mixture of horror and incredulity, a web dustup between an outspoken atheist and a large religious group recently. Read the link if you want the gory details, but the upshot of it is that the more zealous people on the religious side are threatening to do physical harm against those who don’t agree with them.

It’s no wonder that violent and intolerant religions took over the world for several centuries. Irrational people have a definite advantage in a physical confrontation. Fortunately, the Internet puts potential combatants out of immediate physical reach of one another, and tempers irrationality by forcing people to think a little before doing something physically violent — they have to make plans to get to the object of their ire, and that gives them time for emotions to cool, and for them to consider what following through on it would cost them.

If for nothing else, that makes the Internet a wonderful thing.

ASCII, Unicode, and Windows

As mentioned previously, my company sold the rights to one of our previous Windows software products to a much larger company a few years ago. The much larger company keeps my company on retainer to advise them on the product’s continued development.

The product (let’s call it Project Badger) was originally written more than ten years ago now, with me as the sole original developer. At the time, I treated C++ as simply an improved version of C. Microsoft Visual C 6.0, my compiler of (reluctant) choice at the time, barely supported the newly-standardized C++ Standard Template Library (STL); the Boost library didn’t exist yet; and I hated the non-standard and non-portable Microsoft Foundation Classes with a passion. That didn’t leave much choice: I had to hand-code all the algorithms and data structures myself, and use the painfully primitive C string functions and the raw Win32 API.

(Yes, and walk barefoot in the snow to get to school everyday. Uphill. Both ways. 😉 But that’s another story.)

Project Badger has grown a great deal since then, but it was still using the hand-coded data structures and algorithms that I originally came up with, and the C string functions and raw Win32 API. Although they still worked, it was a very creaky and increasingly ugly infrastructure… grafting support for Unicode onto it (as our customers demanded) was a nightmare that required a lot of hand-crafted code, and it was only supported in certain places. And we couldn’t move to Unicode completely, because we still had to support Win9x (Windows 95, 98, and Millennium), for reasons I won’t go into, and they didn’t support Unicode. (Using the UNICOWS DLL, which is Microsoft’s way of retrofitting Unicode support into Win9x systems, was deemed unacceptable in this case, again for reasons I won’t go into.)

This all came to a head a few weeks ago, when a customer reported a problem that should have been easy to fix, but that our bastardized infrastructure made nearly impossible. For a few of its abilities, Project Badger has to open a copy of its EXE file and read some data from a table tacked onto the end; this customer reported that these features wouldn’t work if the EXE file were placed in a path with Unicode characters. The reason was easy to track down: we were using the GetModuleHandleA function to find the filename of the EXE, and CreateFileA to open it. (The ‘A’ on the end means that they’re the ASCII versions of those functions, rather than the Unicode versions, which would be denoted by a ‘W’ there.) But fixing it, in a way that wouldn’t break Win9x compatibility… that was more interesting.

After one of our developers spent a frustrating couple days trying to work around the problem using the “short filenames” (legacy of DOS and the FAT12/FAT16 file system) — to no avail — I proposed overhauling the entire program, replacing many hand-coded parts of the program with components from the STL and Boost libraries. Since I was the only one on the team that had much experience with both, I volunteered to do the initial conversion.

It was a large undertaking, even larger than I’d anticipated. It took me ten straight days, working twelve to sixteen hours a day, to finish it (I’d estimated seven days, for a broader scope of changes). But I think the result was worth the effort.

A key component to the overhaul was a way to support Unicode strings and functions similar to the way that the UNICOWS library does: on platforms where it’s available, dynamically load the Unicode version of the API function and pass the Unicode parameters directly to it. On Win9x platforms (where the Unicode functions aren’t available), fall back on the ASCII versions of the functions, translate all strings to ASCII before passing them in, and translate any results to Unicode when passing them back. To support this, I put together a specialized String class, using the Boost::Variant library. Here’s a simplified version of its declaration (the full version has conversion support for a few program-specific types as well):


namespace os {
    class String {
        public:
        String(const std::string& init): mData(init) { };
        String(const std::wstring& init): mData(init) { };
        String(const char* init);
        String(const wchar_t* init);

        std::string to_string() const;
        std::wstring to_wstring() const;
        const char* to_ptr() const;
        const wchar_t* to_wptr() const;

        bool isNull() const;
        bool isNativelyUnicode() const;
        bool isValidString() const;

        static std::string _toAscii(const std::wstring& str);
        static std::wstring _toUnicode(const std::string& str);

        private:
        typedef boost::variant<const void*, std::string, std::wstring> Data;

        Data mData;
    }
}

Note that the boost::variant typedef Data can accept a std::string (a standard ASCII string), a std::wstring (a Unicode string), or a raw ASCII or Unicode string pointer. The pointer option was necessary because some Win32 API functions allow you to pass in an invalid string pointer, encoding (usually via the MAKEINTRESOURCE macro) some specialized information instead of a standard string.

With that in place, and using a set of simple template classes I wrote to handle the dynamic loading, I could write functions that would take either ASCII or Unicode strings and pointers (or even a combination of different types) and do any necessary conversion on the fly:


namespace os {
    HANDLE CreateFile(const String& filename, DWORD acc,
        DWORD share, LPSECURITY_ATTRIBUTES sec,
        DWORD create, DWORD flags, HANDLE tpl)
    {
        static StdFn7<HANDLE, LPCWSTR, DWORD, DWORD,
            LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE>
            fn("CreateFileW", cKernel32);

        if (fn && filename.isUnicode()) {

            return fn(filename.to_wptr(), acc, share, sec, create,
                flags, tpl);

        } else {

            return ::CreateFileA(filename.to_ptr(), acc, share, sec,
                create, flags, tpl);

        }
    }
}

It’s a good solution, though not a perfect one. For one example, it’s not as fast as the raw calls. That doesn’t matter in our case, because most such calls are in user-interface code (where even the slowest machine is fast enough that much more inefficient code than that wouldn’t be noticeable), and the rest are in one-time operations where the speed isn’t critical.

Another limitation is that you can’t pass in a zero or NULL for one of the os::String parameters, even when it might be supported (as in the “title” parameter to the MessageBox function, which defaults to the localized “error” string if passed a NULL). I got around that by defining

const os::String NULLSTRING(static_cast<char*>(NULL));

in the source file, and then putting

extern const os::String NULLSTRING;

in the header. Then, whenever I needed to pass in a NULL, I just changed it to NULLSTRING, and everything worked as normal. I could probably have also defined an os::String constructor that accepted an int, but that seemed like overkill, and would have worked against type-safety.

The end result: minimal changes to the existing code, while adding maximum flexibility. I’m very happy with it. 🙂

Church Signs

There are two churches on a small stretch of a particular road we travel often. One of them usually has a Christian-oriented (but often humorous) saying on its sign. Recently it had a humorous saying that was somewhat… unexpected:

Forgive your enemies, nothing annoys them more.

Annoying people isn’t supposed to be a Christian attitude (despite what a couple of major sects seem to believe), but hey, it’s the action of forgiving that’s the point, right?

The other church, perhaps realizing that they can’t compete on the witty-saying front, just puts information about its upcoming events on its sign. At the same time as the above example of cognitive dissonance, they had an interesting menu up:

Muffins and Coffee, 9AM A Dysfunctional Family, 9:30

Thanks, but I think some muffins and coffee would suffice for me. I’d be too full to stuff in an entire family after that, dysfunctional or not. 😉

“Dr. Horrible’s Sing-Along Blog”

I like most of what Joss Whedon comes up with (the Buffy the Vampire Slayer series and Firefly, for instance), so when I heard that he was involved in this site, I had to check it out. I’m not sure who plays Dr. Horrible, though he looks very familiar (he might be one of the guys who played a pseudo-evil teenage geek in Buffy on occasion), but I instantly recognized “Captain Hammer” as Nathan Fillion (“Captain Mal” from Firefly, as well as the big bad guy from the last season of Buffy).

The first two “acts” are online now, with the third marked as coming tomorrow… very amusing, check it out. But hurry, it’s supposed to stop on Sunday, after that it’s only available on iTunes.

Spam Idiots

Maybe spammers don’t need to have even average intelligence to make money at it?

I’ve gotten a large number of spams recently (all caught by SpamBayes with no real difficulty) that have one sensationalistic headline in the subject line, and a completely different one in the body of the message. Case in point:

Subject: Facebook hacked into, millions of accounts lost Apple ipod sells one billion units [URL removed] — Using Opera’s revolutionary e-mail client: http://www.opera.com/mail/

(A large number of them also include that Opera line. It’s said that any publicity is good publicity, but I’m sure the people behind Opera view that kind of support as a decidedly mixed blessing.)

Maybe the spammers think that two headlines are better than one, or maybe they hope to get around some anti-spam defenses with that, I don’t know. To me, it just makes it obvious that it’s garbage. But it begs the question… if they’re still making money with that kind of thing, who’s stupider — the spammer, or the people that must still be clicking on the spam links?

(And yes, it’s a rhetorical question.)

“Apple files suit against Psystar”

The collective tech sphere (which has been holding its breath wondering what lawsuit-happy Apple was waiting for) can now breathe again.

The article says that this “pretty much spells the end for Psystar.” He’s probably right, because it’s not likely Psystar can afford to defend itself… but if it can take this all the way to a trial, there’s a very good chance that it would win. And if that happens, Apple can bend over and kiss its huge computer profit margins goodbye.

But, as I’m sure Apple’s management is counting on, there isn’t much chance of that.