::::: : the wood : davidrobins.net

My name is David Robins: Christian, lead developer (resume), writer, photographer, runner, libertarian (voluntaryist), and student.

This is also my son David Geoffrey Robins' site.

Microsoft Word COM dispatch rewrite

News ·Wednesday February 7, 2007 @ 20:20 EST (link)

I came up with two major Office 14 M0 (milestone 0) projects: one to remove our use of C's setjmp and longjmp (which were used as a poor man's exception; Word was only converted to C++ early in version 12, aka 2007), and another to clean up the object model dispatch, including allowing direct dispatch to Word object methods. The setjmp cleanup could have been trivially done by changing the jumps to exceptions, but that's not the Word way; they were all laboriously changed to return codes, propagated as far up as needed.

Word's object model begins with the GOD structure, or Generic Object Descriptor, a structure of pointers to useful information: first of all, the vtbl (virtual method table, containing pointers to all of the methods implemented by the interface), various other tables, and then the Generic, a structure that naturally became an object during the C++ conversion. The Generic implements the standard IUnknown COM methods AddRef, Release, and QueryInterface, as well as IDispatch, and various internal bookkeeping (for example, keeping track of "advise lists" so, for example, parents can be notified of child deletion and vice versa). It also stores a void pointer which user data can be hung off of, usually a reference to some internal Word structure. Care is taken so that when the item referenced goes away (for example, a document is closed), the object is notified and can mark itself deleted so that it doesn't try to use invalid pointers and crash.

There are several ways to implement COM interfaces; in fact, I wrote a work report about some of them for school, which received a Microsoft-sponsored award. The most common is probably to simply define the interface an an IDL (Interface Definition Language) file, and generate a C or C++ header with MIDL, the Microsoft IDL compiler. Word does have an IDL-type file, but it's not IDL, probably because it had an object model before IDL existed (I don't know, I wasn't there, but we do use our own tools), and we have our own compiler, OAC (probably Office Automation Compiler). In it, one can specify a handler for each method: either a specific function, or a generic handler, which is called in much the same manner as IDispatch::Invoke, i.e. with an array of parameters and flags, as well as method-specific parameters. Handlers are useful for forwarding interfaces to internal classes implemented elsewhere, or for wrapping commands (e.g. one class of handler saves the old selection, selects the object called on, runs a command specified by a handler parameter, and restores the selection).

However, there's a lot of duplicated code in function handlers; many functions extract the previously mentioned void pointer from the generic and invoke a class method; the compiler should be able to generate this code. So, I added support for a class_handler directive to OAC, which would dispatch COM methods to a similarly-named method in a given class, automatically casting the generic's user pointer to an object of that class:

Old:
interface IDShape
{
...
   properties
   {
      VT_FLOAT Width
      dispid 999
      get proc HrOamShapeGetWidth
   }
}

...

STDMETHODIMPC HrOamShapeGetWidth(IDShape *pidsp, float *pflWidth) { int fIDispatch = vrf.fIDispatch; int fObjModelCall = vfObjModelCall;

Generic *pgen = PgenFromPunk(pidsp); OASO *poaso = (OASO *)LpvFromGenericInstanceData(

HRESULT hr = poaso->HrGetWidth(pflWidth);

vrf.fIDispatch = fIDispatch; vfObjModelCall = fObjModelCall;

return HrRaiseExcepHr(pidsp, hr); }
New:
interface IDShape
class_handler OASO
{
...
   properties
   {
      VT_FLOAT Width
      dispid 999
      read_only
   }
}
And both need:
HRESULT OASO::HrGetWidth(float *pflWidth)
{
   *pflWidth = PtFromEmu(PspInternal()->flWidth());
   return S_OK;
}
(Some code facts and names have been changed, but it's a representative sample.)

You won't believe how many times the save/restore of the object model flag code and call to HrRaiseExcepHr (or variants) are repeated. That's one of the things that this new dispatch solves, by going through a common function, the new HrOaDispatch, rather than dispatching directly to the function in question (which didn't always happen; the old code had wrappers too, to setup undo, for example; it was very crusty). True, it does add the overhead of an extra call, but the common entry point makes it easier to ensure that calls are safe (for example, avoiding reentrancy from event callbacks). But getting direct dispatch to C++ methods was decidedly nontrivial.

Fortunately, I started with a fairly pathological class: the shape class, which has virtual bases (there are four combinations: old or new shapes, and inline or floating shapes, all inheriting from a common virtual base, and, for example, there is a "new shape" mid-hierarchy class that provides functionality for both inline and floating new shapes; a new floating shape inherits from the new shape and the floating shape class, both of which derive from a common base). If I can dispatch to this guy, everything else is easy.

To start with, we have to know what method we're dispatching. The old code did this with #defined stubs, but now with C++ we can use templates. What exactly do we put into the object's vtbl? The functional case is easy: just store the function pointer, although to provide a little more information (such as the COM class and method index, for other lookups), a template function is used that accepts these all as template parameters and passes them on to HrOaDispatch. HrOaDispatch then uses the information to figure out how large the stack parameters are for the final function, copies them to the stack (yes Virginia, in assembly), and calls the function, which, in usual stdcall fashion, cleans up the stack for us before it returns.

However, I didn't know at first how complex object model calls can be, especially with virtual bases involved. My first plan was to store the method address and then set up the stack as for function dispatch, and somehow call the method with assembly. Bad idea; the assembly dispatch code generated by the compiler is varied and complex. Instead I wrote a template to do the call: HrOaCallMethodC, HRESULT (C::*)()(C* pC, void *pStack, size_t cbStack), and stored the address of that templated function to use to dispatch the call to the C++ method (letting the compiler do the work of setting it), using #pragma pointers_to_members to ensure all virtual pointers were the same size as well as turning off runtime stack checking for that code (the compiler gets upset when a method that says it takes no parameters has actually consumed parameters).

This took a lot longer to figure out than it takes to write; one of the snags I faced was having to build a separate version of the precompiled headers (PCH) with the runtime checks disabled (disabling them for all of Word wouldn't be looked on favorably); figuring out a way to dispatch to a general method was tough too; there was a lot of casting and gnashing of teeth. But it's worth it to have cleaned up and improved some very old object model dispatch code.

OACR almost whacked

News ·Tuesday February 6, 2007 @ 23:47 EST (link)

I've mentioned OACR1 before; we're still working on Office 11 sp3 (Office 2003 service pack 3 to the folks at home); OACR analyzes source code and points out vulnerabilities (or possible vulnerabilities), such as buffer overflows, and we fix the problem if there is one (usually not, but catching even one exploitable overrun makes much of the hassle worthwhile), or suppress the warning with a comment (OACR frequently isn't intelligent enough to understand how buffers are being managed), or add an annotation or OACR_ASSUME to help OACR understand. It's a massive pain in the behind; such things are the reason God invented interns, but we don't have any right now so we're all pitching in until the muck is raked and we can leave Office 11 alone forevermore (only to get into Office 12sp1, which won't be as bad). In these cases, it would be great to leave the past in the past; we make all these improvements to the product, including to the architecture and the source code, and then we have to abandon them (or copy them all over). Arggh! (For instance, Word 2003 isn't even in C++; it's straight C, the C++ port was done early in 12.)

There are quite a few people in the world that aren't aware that Washington Initiative 957 is just a ploy by gays and sympathizers in their continuing quest to validate and legalize gay marriage. In a nutshell, the Initiative proposes that marriages that don't produce children within three years be annulled; they're aiming at those that oppose gay marriage because it can't result in procreation. It's silly because that's a stupid reason to oppose gay marriage, but they're hoping that people will see the initiative, oppose it, and "throw the baby out with the bathwater" as someone on ChatMS so elegantly put it. One might hope that people aren't that stupid. Haha.

[1] Generally pronounced "whacker" (which makes the headline make more sense), but at least one person pronounces it "ochre".

Perl Office suite generates first document!

News ·Wednesday January 31, 2007 @ 20:09 EST (link)

Driving home today, around 1910 on Avondale Road: silver Mazda sedan, plate WA 092 VMW is weaving drunkenly back and forth onto the shoulder, and generally acting lethargic when it was time to go. Not quite sure what drug he was on.

The Office series of modules that I'm developing has generated its first valid Word document today; AB, a Word file format developer, helped me work through a minor hiccup (which also helped find a minor bug), and then everything worked as planned. The new .docx format (and .xlsx etc.) are actually zip files, although that's just the implementation of the package; you can easily look inside. LW, a recent ex-Word developer who moved into the web applications group, was also experimenting with generating new Word documents on the fly, but using C# he already had the System.IO.Packaging layer, whereas I had to write that from scratch. Well, not entirely; I drew on a host of existing CPAN modules: Archive::Zip for the physical package, XML::SAX and a host of filters (one of which, XML::Filter::NSNormalise (sic.) I sent in a patch for and the author got back to me the same day) for parsing and generating XML, DateTime (DateTime::Format::W3CDTF for xsi dates), Params::Validate, etc.

There are probably about 20 modules in the Office namespace (off the top of my head: Pkg, Pkg::Part, Pkg::Rels, Pkg::Rel, Pkg:ContentTypes, Pkg::CoreProps, Document, Document::AppProps, Word::Document (the abstract document), Word::Document::Document (represents the word/document.xml part), Word::Document::Para, Word::Document::Run, SAX::Writer, SAX::Parser (parser helpers, I've been using ExpatXS as my SAX parser of choice and Writer for output). And I've barely started—I can only write basic paragraphs with bold and italics. But this is a big step—adding other properties and part handlers will be incremental. Already it's a usable suite of modules, although I hope to get it to a somewhat more mature form before I make a release (I've registered the Office namespace in preparation). Sample working code, does what it says:
use Office::Word::Document;

my $docx = Office::Word::Document->new;

$docx->add_para('First paragraph.');

my $p = $docx->add_para('This second paragraph has some '); $p->add_run({ bold => 1 }, 'BOLD TEXT')->add_run(' in it.');

$docx->save('test.docx');
Doesn't do much yet, but watch this space, and watch for an alpha release coming soon. Note: This is not an officially supported Microsoft product; I'm doing it on my own using publicly available specifications. Right now I'm defaulting the Company property to Gippazoid Novelty; I'm debating leaving it in, and seeing how many documents show up with it set like that!

The pH (think acidity) markup language, an invention of mine which is basically just a more concise form of XML, which I use to write this log, among other things, has undergone the first change in a long time. Like perl, the definition of pH is in its single implementation, a perl XS C++ module called pH::Parser (no, it's not on CPAN, since it's not general enough, although that never stopped anyone else). pH is also my local wiki (here, it's a fairly old quick hack), which is about to get a big upgrade (for the Word development internal Wiki, but I'll port it back here).

To summarize, the pH markup language is XML without the close tags, or other unnecessary baggage, e.g. instead of <element attribute="value">some text</element>, it's <element attribute=value some text>. The equivalent of CDATA is << ... >>. Computer scientists have probably already noticed a few seeming flaw in it. What if your text begins with name=value? Well, you can escape the = as \= (and <, >, and & similarly), but that's annoying to check for in generated text (although it could be just auto-escaped along with the other markup characters). But the addition is to allow = as a lone pseudo-attribute which enforces the end of attributes for that element, e.g. <element a=b c=d = a=1 whenever b=2>. But, I also decided this was all somewhat silly (close tags are only a few bytes, and the expansion takes time, and there were other logistical problems getting pH expansion into the right place in the processing chain), and am primarily sticking with XHTML for the new wiki templates.

Back in reality-land, we're still waiting on the insurance (they're working on their estimate with the contractor, who thinks they're lowballing it a bit, and the contractor is getting more estimates to prove it). There may be some more (mainly cosmetic) damage downstairs&mdashlsome ripples in the ceiling and some nail pops. And I have a dental appointment (bi-annual clearning) tomorrow, fun.

Honey gave me a Leatherman tool and knife set for my birthday, and a nice card; we went out to eat on the day (yesterday), at a local Teriyaki-Sushi place (former for her, latter for me). One of the new GPM developers at Hilton wished me happy birthday—apparently I'd left my birthday in the code somewhere (in a test, I think, although I don't remember noting that it was my birthday; Honey's was there too). The spirit was nice, the English was a little broken. I don't remember Bob mentioning him, but apparently he's working out alright, which is nice after the hordes of idiots that have been paraded past them by the headhunters.

Next: designing the Office modules, and the new pH wiki (yes, I overloaded the name a little, it's short and succinct and fairly meaningless and I like it), and a little on the new Word COM dispatch. First, why I built my own: most of those out there are file-backed (ick, use a database, I'm using PostgreSQL but the layer is fairly flexible), or in PHP (a filthy language), or don't do revisions. It's definitely time for a good technical article.

15000% return on investment

News ·Tuesday January 23, 2007 @ 02:04 EST (link)

The snow finally left. Yay. Melted away to nothing. Our icy street, which some of the dimmer neighbors were sledding on, is clear again. And the tree at the back that got almost knocked over is still tied to the nearby rock and smaller tree and will probably recover. A smaller tree at the side also got knocked slantwise, but is being propped up by a log from the tree that fell (it's the least it could do). The rest of the tree has been removed from our yard; one of the trees near the fall point did have a main branch sheared right off, but another one right by the gap in the fence escaped almost unscathed. The rest of the tree remains for the neighbors to clean up; it's pretty huge in diameter, they're supposedly looking at some pretty whacked-out estimates and I don't think their insurance is covering it (since it didn't damage their house). To be honest, I don't really feel all that bad for them.

You're probably wondering about the title, or maybe you've figured it out by now: the ROI is for our homeowners insurance; we paid about $400, and the estimate for the tree removal, interior replacements, temporary repairs, and rebuilding work is about $60,000. The windstorm actually happened on our policy renewal date, so technically we'd been paying two years (and if you want to go that far, we'd also had a policy while living in our various apartments) so it probably comes to more like 5000%, which is still not too shabby.

However, to add insult to injury, our hot water went out last Thursday; we called Puget Sound Energy, they'll be sending someone out Tuesday (thanks). We showered in cold water (invigorating and then some), but I decided to hold off on shaving, although I suppose boiling water's not too much trouble. I took the cover off the heater Friday (when the stored water ran out; I'd noticed it being a little cool Thursday but not thought much of it); the pilot light was out; I re-lit it, but it didn't stay on; most sources seem to think the thermocouple's gone (or possibly dirty, but I tried to file it and no luck).

Snow stays in Duvall

News ·Sunday January 14, 2007 @ 15:10 EST (link)

I haven't seen snow stick around this long since Boston, or perhaps Canada; piles of the wretched stuff are all over the place. The roads, fortunately, are fairly navigable, with our street being the worst part of any trip.

I've been at work all week (remotely Wednesday, waiting for the no-show structural engineer), working on "OACR" bugs for Office 11; OACR is the Office Automated Code Review tool which finds things like potential buffer overflows or use of unsafe functions. Its error messages are cryptic and mercurial, but I'm plugging away through all 500 or so bugs that I've been assigned (others on the team will probably take some too). On Friday a few of us got together to talk about enhancing collaboration on Word documents—from making it easier to collaborate via email to Word as a wiki editor.

Speaking of wikis, I'm designing a new internal wiki for Word developers, based on my pH wiki: Apache 2, mod_perl (the wiki is structured as a response handler), Template Toolkit for formatting, and PostgreSQL for storage, and Subversion for (page) versioning (I'd use our Source Depot, but the layers of bureaucracy to get a wiki project added would be piled high and deep). Some criteria for it are on the NewWiki page on the old wiki. I may borrow some HTML templates from the MoinMoin wiki, since it looks pretty but unfortunately uses flat text storage (stupid, stupid, stupid!) so search is pathetic.

I was working on the new wiki remotely Saturday morning, installing some perl modules, when something caused a shutdown (not a reboot; it never came back). I drove into work at 0330 and restarted the machine, and then at around 0800 it happened again (I tried shutdown -a to abort it, but it was too fast), so I went to sleep and drove in when I woke up. I'd disabled the shutdown permissions for everyone except the local administrator account, but it didn't take effect until after a reboot. Also one of the perl modules was exec'ing ps in one of its tests, which lists processes under Unix but for us runs Product Studio, our bug database software. Finally, another module used variadic macros, which aren't supported on Visual C++ .NET (they are in 2005, but that machine needed to have .NET for compatibility), so I had to convert the macro into an inline function. Also, pH::Parser had to link msvcprt.lib rather than Unix's libstdc++.so to get non-inline C++ library code. But now things are looking good; database tables have been created; mod_auth_sspi is picking up the username; Template Toolkit is working, with a pH parser filter; soon people will be able to edit pages.

On Friday, I followed a white GMC Sierra truck most of the way home (Novelty Hill onward); A87522X; slowest driver I've ever seen, rode the brake all the way down Novelty Hill, never got above 5mph. It had snowed a few days before, but the road was pretty much clear. I started out in a long line of cars, but by the time this slowpoke got to the bottom of the hill, there wasn't a car to be seen in front of him.

Snow comes to Duvall

News ·Thursday January 11, 2007 @ 22:26 EST (link)

Off the wall: Catholic church is suing ICE for... doing their jobs (in this case, raiding a meat-packing plant looking for illegals). Unfortunately I can't find a link for it, so take with a grain of salt; however, if the Catholics are getting involved in politics, it's high time to take away their 501(c)(3) (charitable organization) status, especially since they're just doing it for the money and power (most Mexicans are Catholic, and are easily manipulated by Catholic priests since they've been brainwashed by that church all their lives). In searching, though, I did find this interesting blog and an article about the raids.

And then there was the illegal alien who claimed he only spoke Mayan so proceedings were halted to find him an interpreter. Time to make English the a national language, and you can get your own interpreter, and if you can't afford one, we can sentence as if it were in absentia.

January 3: Paid off the tree company (Alpine). I caught the Alpine "credit card guy" on the road, so he called back later to arrange payment.

January 4: Case Engineering called; Honey called back, arranged for him to be here on Wednesday at 1500. Called our mortgage company about the claim so they could fax me some forms that they'd need to release the bulk of the repair funds to us.

January 5: We heard we were going to get snow, so Jim Cameron came by again and strengthened the roof, putting up some beams and temporary trusses, and stacking some 1x4s on the roof to keep the tarps up. He also nailed the tarps down with 2x4s, since the last wind gusts had ripped the grommets out of the tied-down tarps. He also provided a heater for the room and removed most of the fans and dehumidifiers.

January 6: Watched the M*A*S*H original movie (MythTV, of course); not too bad, but Adam Alda is a much better Hawkeye than Donald Sutherland, especially with that annoying whistle. Honey worked today (got a job through a temp agency); might have gone longer (she was covering for someone that was trying to fly out for a funeral) but it was only to be the one day.

January 10: Cable (and hence Internet and phones) were out from 2130 until 0930 in the morning (I wrote a script with Net::Ping to beep when connectivity returned). The structural engineer from Case called about half an hour before he was due to arrive and canceled, rescheduling to next Tuesday. We wish we could've gone with Jim's engineer, but MetLife is forcing us to go with Case Engineering.

January 11: Saw some cracks in the kitchen/living room ceiling near the central supporting pillars; looks like just paint, tree damage further stressed by the weight of the snow. Doesn't look too serious. Thought I heard some snow and ice fall off the roof in the morning (loud rattle like someone dragging a ladder). A picture in a frame in the living room slipper down.

The adjuster stops by

News ·Tuesday January 2, 2007 @ 21:56 EST (link)

December 27: We called the City of Duvall planning department (425-788-3434) about a building permit, since we heard they're being fast-tracked, and they eventually got back to us but we need to know our contractor to apply. We've heard since that the contractor can handle permits and that's how it'll probably work out. We're living downstairs on our air mattress in the corner of the rec. room.

December 29: We heard from MetLife that they're changing our adjuster; they'd contracted out to an independent adjuster (James Davant), who had taken photographs and talked with us, but now they're taking it in-house and the case will be handled by a large-loss adjuster, James Feather. We left him a message and he eventually arranged to drop by on Wednesday January 2 and expected to be here for several hours.

New Year's: We spent a fairly quiet New Years, stayed up most of the night. We tried to go to Avondale Bible Church Sunday, but they'd changed their times and failed to advertise it on their site, so we were late.

Via The O'Reilly Factor: Wisconsin official gives illegal alien (alleged) child molester $5000 bail, surprisingly he skips town. He'd already been deported once; we need a fence with land mines, and for the Rio Grande, sharks with frickin' laser beams.

January 2: The adjuster stopped by just after 0930 as promised (I worked from home so I could talk with him); he was from Mississippi, just across from Memphis where we used to live, and seemed to be an upstanding guy (final report comes when all the claims are settled!) The contractor, Jim Cameron, stopped by while he was there and they talked about the work required. The adjuster reviewed our claims and took copies of receipts and an Excel spreadsheet I'd made at work, paid the contractor for temporary repair work done so far, gave us a bank card to pay for the tree removal, gave us a Home Depot card to compensate us for the work we'd done, and a check to cover our hotel stay. Which was all very relieving; the papers about potential construction liens that the contractor had been required to give us by state law were making us nervous.

The adjuster arranged for a structural engineer to come out from Case Engineering (he'll be here next Wednesday, January 10), which will let him and the contractor write up estimates; MetLife has a program they used for it, Xactimate, which calculates based on work required and local prices. We're pretty sure we'll go with Cameron Construction for the repairs; I emailed the MS home owners list and got a second good recommendation. So the engineer is the next thing we're waiting for.

The way we'll get paid is somewhat complex; first, the checks will have the mortgage holder's name on them too, so they'll get them and release them to us in various percentages, pending their inspections; MetLife pays full replacement cost, but will withhold depreciation until we demonstrate that we've made the repairs or obtained replacement items. We still have some claims to make—more items from the destroyed rooms, and we don't know how much the gas and electric overages will be due to the hole and running the fans and dehumidifiers. But we're feeling much better after the adjuster's visit; it's just going to take a long time to get everything back.

Intermezzo: betrayal and backstabbery

News ·Wednesday December 27, 2006 @ 10:11 EST (link)

While all this was going on with the house, there was some drama in the EFnet #c++ talk channel. Channels such as this have channel operators, or "ops", who maintain order in the channel; usually "op" status is given to experienced users with domain knowledge; evidently someone screwed up in this case. "ZorbaTHut" (an IRC nickname; on EFnet, nicknames are limited to 9 characters) and a few other disgruntled #c++ ops waited until they knew most of us would be away (for example, Lisa was out visiting her dying grandmother) and then took over the channel in mid-December, ejecting most of the other operators.

ZorbaTHut ("Zorba")'s betrayal was a spoiled child's tantrum; the act of an infant who wants to rule the sandbox, throwing feces at anyone who disagrees with him. I believe the main issue that caused him to attempt this takeover was the rejection of his badly-coded 'bot (automaton for information retrieval), which I ended up cleaning up (essentially a rewrite) and which had been installed in the channel. (As an aside: Zorba apparently used to work for Google, but one questions their interviewing standards if that code is typical; he'd have a much harder time getting a job as a Microsoft Office developer. He "quit" to start his own company, without funds or much of a plan.) I have logged a later (January 4) discussion about the takeover; here are some salient quotes:

<ZorbaTHut> symmetry, sorta, yeah. the current admins got tired of the previous admins. that's why we have notabot, not calcme :)
<ZorbaTHut> (and why it uses my codebase :P)
<czth_> if you'd've been brought up proper you'd've learned "thou shalt not steal"
<czth_> yeah, your stinking full-o-crap codebase


<_Stinger_> who was overthrown?
<czth> most of the existing ops, it seems
<ZorbaTHut> stinger, basically raph and mind, with a little collateral damage
<czth> the honorable thing to do would have been to step down as op, of course, rather than backstabbing the rest of us.


<xor_mind-> Where you abusing your power or something? Why have not been reopped czth?
<czth> xor_mind-: because i know some of the people zorba doesn't like
<czth> boy, that sounds really mature when it's put that way, doesn't it zorba me lad?


<czth> never have i abused ops
<ScratXP> do you need ops
<czth> do you need Internet connectivity?
<jey> czth: I agree that it sucks in your position


I think jey summed it up nicely, although he's part of the Vichy regimeproblem, rather than being part of the solution. Anyway: some Internet politics for y'all to enjoy.

A Risky Christmas in Pullman

News ·Tuesday December 26, 2006 @ 23:17 EST (link)


Pollocks
December 23-5: Since power was back and the house was somewhat secure, we took up Honey's uncle and aunt's kind invitation to spend Christmas with them in Pullman. Their kitchen and dining room was being remodelled (everything was out, from fixtures to cabinets, and they'd put in new wood flooring and wooden posts for the stairs to the basement, but no railings yet), so cooking was being done in the basement with a Crock-Pot™ and a microwave.

We played several games; to Honey's cousin Will's delight, Risk (uncle Dave and I beat Honey and Will, by managing to take over two continents (Indonesia and Asia), and then arranging our men so as to give one of us the troop bonus for each, and then noticing that we win by just taking out either one of the opposing team's armies, and focusing on Will). They introduced us to Guillotine, a fun card game where players are executioners and have to collect noble heads, and in turn we brought Stock Ticker, a Canadian game simulating a very simplified stock market. We didn't play Scotland Yard this time, but for Christmas they got the U.S. equivalent, New York Chase, upgraded to give detectives helicopters to aid in the search (kids these days have it so easy...).

They gave us a Canada provinces puzzle (logos and symbols in the shape of a Canadian flag); we were empty-handed, given the tree-in-roof crisis and all. We headed back Christmas day; we'd bought chains for Snoqualmie Pass on the I-90, but although the web site said they were required, the road signs did not, so we didn't use them.


Martins
December 26: We called my uncle Graham and aunt Wendy who had invited us up for a Christmas dinner on Boxing Day (December 26); we thought we wouldn't be able to make it, because we needed our contractor (Jim Cameron of Cameron Construction, who's been absolutely great so far in taking care of cleanup and temporary repairs) to come out and shore up the tarps against some leaks, but we were able to arrange to leave a key for him and head up to Abbotsford by 1100. We're grateful to our neighbors who called the contractor (we'd given him the number) when they thought the tarp was leaking; he put up a temporary tarp that night and then put up another tarp and set up some fans and dehumidifiers while we were gone. And he was as good as his word; things were drying nicely when we returned.

Honey hadn't been to the (many) Martins' place in Abbotsford before, so she got the tour (complete with THX sound in the games room); excellent dinner and conversation; Ashley and Sean (please excuse if you spell it another way) were there, and Jordan and Liz, and of course Graham, Wendy, Chris, and Vanessa, who is expecting an addition in May; we wish them best of luck. We left that night and got back by midnight.

Blind Assassin, Treasure Island, Pattern Recognition

News ·Friday December 22, 2006 @ 18:22 EST (link)

This I recall to my mind, therefore have I hope.
It is of the Lord's mercies that we are not consumed, because his compassions fail not. They are new every morning: great is thy faithfulness.
Lamentations 3:21-3

December 20: Went to work to check messages, then to the house, cleaned up more insulation and fished out more valuable prizes, which we moved to another bedroom. Thought we smelled gas outside by the gas line, near where the tree fell, so called Puget Sound Energy who promised to send a technician sometime that night; he didn't need us to be there, so we went back to the hotel. Power was restored to our place at about 1950; we'd been following the PSE status page (and the King County road alerts page), and called the neighbors a few times to check. We ate at Outback that evening; we'd only been eating about once a day. We stayed at the hotel overnight, since the house had no heat and we weren't sure if the power would remain on. But at least with power we could return the following day.

December 21: PSE had left us a note on the door that they had turned off the gas and would need to install a new regulator (no charge to us) but we needed to remove a tree that was leaning over the gas line. We called Alpine Tree Service, the same opportunists we'd been using (remember, we hadn't seen an invoice yet and they'd been very slippery about telling us their rates), and they came out and moved and cut up that section of the tree. Even though the tree was out of the house there's still piles of branches in the driveway, about 50' of (very thick) ivy-covered tree in the back yard, itself hidden by a veritable forest of still-connected branches. After Alpine came we called PSE from a neighbor's place and they installed a new regulator and relit our pilot lights and ensured all was well.

I booted up the computers—Internet wasn't up until later in the evening, which meant we had no phone until then either—and was skimming some CNN Money lists (via Fark, I think); I found an item about removing oneself from credit card junk mail lists and called 888-567-8688, 3 to be so removed (they need an SSN, but CNN's fairly reputable so I risked it). Writing on January 5, 2007, I don't think I've seen any credit card spam in the mail lately, so perhaps it's working. CNN Money also advises keeping six months income in savings (not just three as I'd heard previously) if we start relying on just one income.

December 22: Browsing Micronews today, the Microsoft internal weekly newsletter (which just renamed itself to something utterly forgettable and will be coming out daily, or not at all and it'll just update a site that nobody will ever read, or at least far less people than read the weekly digest): How Not to Come Home from the Christmas Party tells the woefully sad tale of a (presuming from the photo) faddish couple who—horrors—had no power in their house after they came back from a party, and then got locked out of Microsoft and had to sit in their car. Please. If you're going to cover the windstorm, don't pick a peripheral inconvenience.

Also in this issue, in the letters to the editor: "Can I Opt Out of Child Coverage?" [Regarding the Dec. 8 Micronews: Half-Million-Dollar Babies]: I'm glad the $500,000 babies are healthy and the parents were able to focus on taking care of them without stressing over the bills. But as a child-free employee, I will never incur the birth cost, parental leave or child-care expenses. I'd be thrilled to opt out of such coverage.

The response blathered a bit, failing to either get the point or to the point, and eventually vaguely said "this change is something our team is working on." I remember asking a similar question at athenaHealth in Boston, and the response being equally vague, because how can anyone (save baby-eating Satanists and terrorists) not worship the almighty baby?

Books: While without power, being mightily scarred by having to watch TV with commercials, I finished The Blind Assassin (Margaret Atwood) and the deservedly classic Treasure Island (Robert Louis Stevenson) and am now (January 2) starting on William Gibson's Pattern Recognition (yep, of Neuramancer fame).

<Previous 10 entries>