Monday, December 31, 2007

Zero! In!

While at DevConnections, I ran into a former co-worker, Dave Esposito.  Late one evening, we tossing back a few beverages and it turned out that 20+ years ago, we hung out on different edges of music scene in Albany.  I tossed out a few names of some musicians and it turned out that we both knew Billy Harrigan. 

I mentioned that Bill always detested me and what I did to his dog didn't help.  It turned out that Dave had heard that story but never knew that I was involved.  It's a fun story to share and n0 animals were harmed.  I briefly mentioned it once before, I think it's time to share the full story.

It's time to set the Wayback machine to 1983.  I was spending my free time hanging out with Jack Nemier.  Jack and his then fiance (and now wife) Judy were renting this tiny, one bedroom cottage in Colonie.  Jack had just joined the band "Operation Pluto" and the band rehearsed at Jack's house.

Operation Pluto consisted of the late Billy Harrigan, Richard Fuller, and Jack.  At best, Bill and Richard tolerated me.  Since it was Jack's house, they had to put up with me. 

Bill and his wife had a dog and a cat and one fine summer day, Bill dropped them off at Jack's house.  Bill's landlord wouldn't let him have pets so the animals had to go.  He asked Jack if they could stay there for a while, while Bill worked on convincing his landlord to let him have the pets.  Jack really didn't want someone else's animals, but he felt that he couldn't say no.

The dog was named "Zero" and was one of those little yappy dogs.  More enthusiasm than brains, if you know what I mean.  Jack pretty much ignored Zero and the cat, so Zero looked to me for attention.  At that point in time, I had no experience whatsoever with dogs, but I played with the dog and he got used to me.  Jack wasn't terribly diligent about feeding the dog or the cat, so I ended up doing it a good portion of the time.

By the time fall came around, Jack wanted the pets gone.  Bill didn't appear to be any particular hurry to retrieve his pets.  And I, not knowing anything about dog training, decided to see if I could teach Zero a trick.

Since Zero was always hungry, it turns out that he was quite amenable to learning new tricks, especially if food was involved.  I had discovered the basic rule of dog training, food.

After a remarkably short amount of time and dog biscuits, I had taught Zero to jump out the living room window on command.  The windows didn't have any screens and the season was warm enough that the windows were usually open.  The living room window was above a couch, and he would use the couch as a launch pad. A similar command would launch the hapless mutt back in through the window.

Zero was just big enough to reach the window sill from outside the house.  It was the funniest thing that we had seen in a long while.  Zero had lots of fun doing this trick and he basked in the attention it brought to him.

The next time Bill came over to the house for band rehearsal, I was already there.  He came in and the first thing he said was "Where's Zero?"  Zero was outside in the yard playing.  I innocently said, "I'll get him" and then yelled "Zero! In!".  About 5 seconds later, the dog comes flying in through the window.

Bill was stunned and more than just slightly pissed off at me.  He said "What just happened?"  I replied, "We've been teaching Zero new tricks.  Zero! Out!".  The dog ran to the couch and jumped out the window.   I then had Zero jump back in once more, so Bill could appreciate the sound of the dog's claws scrambling against the side of house as he jumped up to the window and pulled himself back in.  Needless to say, Bill took Zero and the cat home with him that day.

Bill left this mortal coil back in 2001, but the MySpace link attached to his name up above (and here) has some of his music recorded as "New Shiny Things" and as "Operation Pluto".

Sunday, December 30, 2007

Thoughts on trading the Town & Country for the Odyssey

I was reading Steve Tibbett's post about trading in his Dodge Caravan for a Toyota RAV4 and I started thinking about the last trade in I did.  Back in August, we traded in our '03 Chrysler Town & Country in for a new '07 Honda Odyssey.

We bought the Town & Country just before we adopted Laura.  It was a nice van, but four years later, it was out of warranty and it felt like every time I took it in a for an oil change, it needed a few hundred dollars worth of work for one idiot thing or another.

Anne and I talked about trading it in and we had narrowed it down to the Toyota Sienna and the Honda Odyssey.  Both are very good vehicles, and I was sure we would be happy with either one.  Late last summer, I started pricing both vans with the options we would want.  The Edwards site is great for that sort of thing.  I also checked the trade-in value of the Town & Country so I would have a good idea of what the final cost would be.

We had the luxury of not being in any kind of hurry to trade the Town & Country in.   We could wait for the end of model year sales and try to get the best deal.  We had the time to test drive different models and get a feel of what we liked and disliked.

Last fall, Rennsselaer Honda had a "Hail Sale".  They were hit with a major hail storm and almost all of the vehicles in their lot had suffered minor hail damage.  Because of the damage, they were taking an additional $1500 off their sales price.  We decided to go down an take a look.

The place was mobbed and people were buying cars left and right.  We had to wait nearly an hour just to see a salesman.   While we waited, we walked through the lot and saw that they had 6 Odysseys.  Two were the Touring edition, which was out of the price range that we were looking for.  Two of the others didn't have the options that we wanted.  That left two EX-L models that we would be happy with.  The hail damage was very slight.  A few little dings here and there, you had to look close up at the right angle just to see them.  None of the dings had gone through the clear coat finish, so we were not worried about long term rust issues.

We got one of the old school salesmen, the ones that use the sale tactics that make you hate buying a new car.  He wanted us to take a van for a test drive, while his people looked over my van.  He wouldn't proceed until I told him how much I wanted for my van.  I didn't want to play the numbers game that early, but he was persistent.

I gave him an absurdly high number, $10,000, and he smiled and said that was a  good starting point.  He gave us the keys to the Odyssey that we liked the most and Anne and I took it out for a drive.  While driving I told Anne that I was going to play hard ball with the salesman and to be prepared to walk out with out buying a vehicle.

When we got back and sat down with the salesman, he asked if we were ready to make an offer.  I said "yes" and he then presented to us a sheet with the four squares on it.  The "4-square"  is the how the dealer tries to get you to pay the highest price for the vehicle.

Each square has a number in it.  The first number has the purchase price of the new vehicle, the trade in value of the current vehicle, the down payment, and the monthly payment.  Basically they make it difficult to see how much you are actually paying until you agree the sign the paper work.

Having read the article on The Consumerist web site about how the 4-square works, I declined to play that game (and a similar article was hysterical).  I politely, but firmly, pushed the sheet back to the salesman and said that I didn't need to see that sheet.  I said that I wasn't going base the purchase around the monthly payment figure.  I was going to bring my own financing and we would only discuss the amount that I would be the final purchase price with all taxes and fees included.  The salesman started talking about the trade in value of y van and new van price and I politely (but firmly) cut him off.  I said that I didn't care how the numbers were sliced, the only number that mattered would be the amount on the check.  I told him that I knew what my car was worth, what his car cost, what wiggle room he had and that there was going to be $1500 off for the "Hail Sale"

Once he realized that I wasn't going to play the 4-square game, he asked me for my offer.  I knew that they would turn down any initial offer, so I deliberately low balled it.  I had already figured that $27K would be the fair and reasonable amount to pay.  So I came back with $26K.  The salesman told me that he would have to take it to the business manager and he would be right back.  That's the code phrase for he was going to have a cigarette and make us wait and break our resolve.

He came back with $29K and change and tried to explain why how they came up with those numbers.  I said that was way too high and I asked for the keys for my van back.  He asked for a counter offer and I said $27K and that was final.  He went back to the manager and came back with 28K.  I said that was still too high and I think we would call it a night.  He blinked and asked for a final offer.  I said $27,500 and we were not going to wait another 10-15  minutes for his manager and if they didn't meet that offer, then we were done.  He came back with $27,504 or something like that.  I guess he wanted to say that he picked the final price.  I could care less about that sort of detail, the 27.5 number was close enough that we were comfortable with deal.

They tried to play a few more games with arranging financing and buying all sorts of warrantees, but I declined all of that.

After going through that nonsense, we love the Odyssey.  It feels like a better built vehicle than the Town & Country.  We are getting better gas mileage, that was an unexpected bonus.  There are a few things that the Town & Country had that didn't come with Odyssey, pretty much like what Steve noted on his trade in. 

The big thing was not having a powered rear hatch.  It was one of the more useful luxuries with the  Town & Country.  You could only get that on the Touring model of the Odyssey, but that would have added about $6K to the price tag.  The handling of the Odyssey is much better, you get a real feel for the road.  The Town & Country pretty much insulates you from the road.

Friday, December 28, 2007

Citizens Bank Debit card security worries me

A few weeks ago (on December 9th), I was reviewing my Citizens Bank checking account history online when I saw two transactions that didn't belong to me.  They were debit card (MasterCard) charges from an online grocery store in another state, halfway across the country.  They were posted on 11/27 and 11/28 for about $260 and $11 respectively.  I'm going to be vague about the amounts and the identity of the online grocery.   The online grocery made an honest mistake and did everything they could to rectify the matter with in a day.

I immediately called the 800 number on the back of the debit card.  The customer service rep told me that I needed to file a fraud report.  We could do it over the phone, but since it would need to be notarized, it would be faster to go a local branch office and file the report there.  I then asked to have my debit cards reissued to prevent any additional transactions from going through.

The next day, I went to local branch of Citizens Bank and filled out the fraud report.  I was told that I would get a provisional credit for the amount that was taken out within 10 business days.  It would take 45 days for the fraud report to be processed.

On 12/17, my replacement debit card arrived in the mail.  There was no sign of my wife's debit card.  I called the 800 number again and I was told that only my card was reissued.  I explained why I needed both cards reissued and they said they would do a rush order on my wife's debit card and they would waive the rush order fee. 

On 12/20, my wife's card came in and I went online to verify that we were not being charged the additional fee.  I saw that fee had been applied and immediately afterwards a credit for the fee had been applied.   Then I saw another charge from the same online grocery store, dated on 12/18 for around another $250.  I called the 800 number and I was told that I would have to file a second fraud report.  Since it was in the evening, this would have to wait until the next day.

Since the fraud department at Citizens Bank was not acting fast enough, I decided to start my own investigation.  I found the home page for the grocery outfit and called their customer service number.  I left message that several fraudulent charges had been placed on my wife's debit card and I requested that someone from that company to call me.

A few hours later, I received a call from "Dan" (not his real name), the owner of the company.  He had received the message and wanted to make sure that his company had not charged the wrong person.  I gave him enough information to prove that he had indeed charged my wife's card for three separate amounts.  After some research on his part, we determined that the transactions occurred when his customer transposed two digits of his credit card number when he had placed the order.  The two subsequent charges occurred because the number had been stored in the grocer's system.

I had several conversations with the owner and the directory of finances for this company and they said that they were changing their credit card processing to apply additional checks to accidental or fraudulent use.  They immediately credited back the three transactions to my wife's canceled debit card number.  As of this date 12/28, they have not been contacted by Citizens Bank or Mastercard about these transactions

The next day (12/21), I went to the local Citizens Bank and explained what happened again.  They apologized for the problems with 800 department and called the fraud department while I was filling out the second fraud report.  They told me that the second report would be attached to the first report and I would get the provisional credit to my account that day.  The person at the fraud department had some of the more critical details wrong.  This did not leave me with a warm and fuzzy feeling.  The money was posted back to my account later that day.

I now check that account every day to see if any odd transactions will be posted.  On 12/26, the money returned by the grocery was posted to my account.  Now I had too much money in the account.  I called the local branch and they will reverse the transaction for the provisional credit.

Here's the part that really bugs me.   None of this should have happened.  The grocer should have validated the credit card number.  The name didn't match.  The shipping address didn't match.  And they didn't require the 3 digit Card Security Code from the back of the debit card.  Any of those checks would blocked the transaction from going through.  That was the first failure.

The next point of failure was when the credit card transaction was submitted.  My wife and I had used our debits on the same day the first transaction went through.  Mastercard or Citizens Bank should flagged the grocery transaction as suspicious and called me to verify the transaction.  We have never used our debit cards online and have never set foot in the state where the order was placed and shipped.

The last point of failure was with the customer service department at Citizens Bank that handles the debit cards.  When I made the first request to have the cards reissued, both cards should have been immediately reissued.  I had no way of knowing from my account history of which debit card number had been used, I wanted them both reset.

Right now my concern is that there is nothing in place with MasterCard or Citizens Bank to prevent something like this from happening again. 

Tuesday, December 18, 2007

Externally signing Wise Installation System generated executables

I had a problem with applying an Authenticode digital signature to installer that I had created with Wise Installation System 9.02.  Basically, it was failing with the lovely message:

Could not initialize installation. File size expected=3258503, size returned=3263976

The signature was being applied outside of Wise, through our build process.  We use FinalBuilder to build all of our applications and it has a handy Authenticode action for applying an Authenticode signature to the target you specify.  If I disabled that action, the installer worked.

Wise has the ability to sign it's executables, but that version is hard coded to use Microsoft's signcode executable to handle the actually signing.  Microsoft has deprecated signcode in favor of signtool and I didn't have a copy of signcode laying around.  In all likelihood, the current version of Wise's script based installer would be able to use signtool, but I can't use the current version because they broke other, more important things.

After a fair amount of googling, I found an old copy of signcode on Thawte's site on this page.  I downloaded the file set and extracted signcode and placed it in my \windows folder.  I fired up Wise and went to the "Digital Signature" page in the IDE.  That's when I saw the blindingly obvious setting that I needed to set:

 

On the “Digital Signature” in the Wise Installation System IDE, make sure that the radio button labeled “Add a digital signature externally” has been checked. Once I made that change, everything worked.

Monday, December 17, 2007

Just listened to a great interview with Dan Appleman over on Hanselminutes

That spring, I treated my self to an MP3 player, a Creative Zen Vision:M.  Why I picked a ZVM is food for another post, but it's opened up a new world to me.  The world of podcasts.  My podcast listening typically falls into two categories:  programming related and NPR shows.

One of the programming podcasts that I listen to on a regular basis is Scott Hanselman's Hanselminutes.  His stuff is very good.  He gets to interview a lot of cool people in our world.  I just listened to his 11/29th interview with Dan Appleman.  They talked about software architecture, but they concentrated on the human side of architecture. 

Dan talked about what should go in a software specification.  He mentioned something that I occasionally do and that is that the spec should clearly list what it doesn't do.  A good spec will cover what it will perform, but you usually don't see specs that clearly list what will not be performed.

That makes so much sense.  It's important to list the scope of the spec, but it's just as important to list the limits of the spec.  We all make assumptions, that's just human nature.  I've been in situations where code was delivered and people asked for feature "B".  "B" was never specified, but since the code included feature "A", they had just assumed that "B" came along with "A".  Then you have to go back to add "B" and hope it wasn't too expensive to add after the fact.

When you list what the spec wont do, it forces the client to think a little more about what they want.  If you want something additional, it's lot easier (and cheaper) to add that feature before the code has been written than after.

Tuesday, December 11, 2007

How can you give away a eight year old?

I came across a news article about the Dutch couple who gave up their eight year old daughter, who they had adopted as a baby from South Korea.  They claimed she didn't fit in their life style.  What on Earth is going through these people's minds?  She has been their daughter since she was four months old.  Since when did the disposal of second graders become a life style option?

This little girl has basically had her entire life shattered.  How does a eight year old come to terms with the fact her mommy and daddy don't want her anymore?   I can't imagine what she must be going through right now.  The family has been living in Hong Kong for the last few years, but the girl is still a South Korean citizen.  The Korean community in Hong Kong has stepped in to find her a new home,  but she's going to need some help.  So does that Dutch family.  It's just mind boggling that they could do this.

Friday, December 07, 2007

Converting Delphi enumerated values to strings

It's pretty easy to converted Delphi enumerated types to string and vice versa, but I can never remember the syntax.  The good thing about having your own blog is being able use it as an off-line cranial storage device.  I did the same thing a while back to do the same thing in .NET code.

To convert an enumerated type to a string:

uses typinfo;
function MyTypeToString( value: TMyType ): string;
begin
    result := GetEnumName(typeInfo(TMyType ), Ord(value));
end;

 

To convert a string back to an enumerated type, the following syntax can be used

uses typinfo;
function StringToMyType(const value: string): TMyType
begin
  result := TMyStyle(GetEnumValue(Typeinfo(TMyStyle), value);
end;

 

GetEnumName and GetEnumValue are defined in typinfo, you'll need to add that unit to the uses clause of your code.  This functionality is very useful if you ever need to implement your own object serialization routines in Delphi.

Thursday, December 06, 2007

Little Bobby Tables

Not too long ago, the online comic xkcd ran a strip that just killed me.


(thanks to Randall Munroe for providing the image link for hotlinking)

Our applications make extensive use of a table with a very similar name.  Most of our programmers got the joke and had a good laugh.  Our QA staff found it hysterical.  Had they been drinking milk, it would have sprayed out of their noses.

It does demonstrate quite effectively how easy it is to intentionally damage a database through a SQL injection attack.   The user enters in string literal characters into an entry field and alter the logic of the SQL statement being executed.  In the example displayed in the comic, the insert or update statement that would be been populated from the entry fields has been truncated.  A command to drop the students table would be executed immediately after the truncated insert/update had been executed.

This is an easy attack to block.  You have at least three ways to prevent this attack from going through.

Don't create your insert or update statements directly from the user editable entry fields.  If you use a parameterized SQL statement, that will block the attack.  The injection text will get written to the database as part of the entry field, but the injection SQL will not have been executed.  You get some additional benefits.  With SQL Server, the server will cache the execution plans of parameterized queries, providing a faster execution time when the next insert or update statement is execute.

Don't run the application with database login account that has enough rights to modify the database structure.  If you really want to lock down the access rights, block direct access to the tables and do everything through stored procedures.

"Sanitize your database inputs".  That usually involves the most amount of work, but a well designed application is usually doing some level of field validation.  Just filtering out the ";" from the entry field is enough to block the attack.

Monday, December 03, 2007

I used to use Yahoo...

Steve Trefethen's posting about Yahoo is pretty dead on.  I used to use the various Yahoo apps and services, but I have slowly replaced them with the various services from Google.  I think  the problem was the development team saw too many bright and shiny objects and decided to implement them.

Yahoo's email is an over-developed mess.  It's trying to be the web version of Outlook.  Even Microsoft's web version of Outlook isn't trying to be a clone of the desktop version of Outlook.  With web-based email, I want to get in and read it in as simple a manner as possible.  Thanks to the GMail Manager plugin, I have notifications when email comes into my various gmail and Google Apps email accounts get mail.

I don't want yet another proprietary IM client.  There's nothing wrong with Yahoo's IM, it's just that no one that I IM with uses it.  I prefer to use Trillian, one client to serve them all.

It's kind of sad.  I remember 10, 12 years ago when Yahoo was the only game in town for searching.  It got slower and slower to use and when Altavista came out, I dropped Yahoo for speed and simplicity of a fast search app.  And I stayed with Altavista until Google came out of nowhere and changed the search engine game as we know it. 

Tuesday, November 27, 2007

What happened after I emailed Sears

Earlier today, I posted about what I went through with ordering a vacuum cleaner from Sears.com.  My first inclination was to just call the store.   But I wanted to make sure that I got everything down and with as little emotion as possible.  I can do that better with email than over the phone.  I wasn't 100% successful with keeping my emotions out of the message, but I think I accurately conveyed the experience that I went through.

After a little bit of searching with Google, I found the email address of the CEO of Sears, Aylwin Lewis.  I figured if I sent it there, the executive assistant that would handle the email would send it the right person at the store.  That's not exactly what happened.  Mr. Lewis did read it and took action on it.

When I came home from work, I had a message from the district manager for Sears.  He called me back later in the evening and it was a very positive conversation.  He apologized for what happened with Sears.com and for what I went through with the salesman.  He told me that Mr. Lewis had forwarded my message to the nine regional vice-presidents.  They were concerned over the melt-down at Sears.com, and they wanted to address the problem with the sales staff.  They were well aware of the Sears.com melt-down, but having their own sales people bad mouth their Internet portal was something they were not aware of.

I was bit shocked by all of the attention, but I think it shows that they do care about the customer experience.  From what I saw and was told, the Sears.com site was unable to handle the load from the holiday shopping.  That's the easy problem to fix.  Their site just didn't scale.  You can fix that with more hardware or by tuning the existing hardware and/or software.

The other problem was the one that really bothered me and is why I sent out the email.  That was the experience that I went through when I tried to buy a vacuum out in the appliance department.  That's a harder problem to fix, but the district manager (Mark) made it clear that he was going to personally look into it.   I have to give credit to Mark, and the people he works for.  They did listen when I complained.  And he did offer me a small gift to make up for what I went through.  It wasn't necessary, but I do appreciate it.  I really think they intend on fixing the problem with the salesmen.

How not to handle Black Friday: Sears.com

On Saturday I was vacuuming when I noticed a burning smell coming from the vacuum cleaner.  It wasn't the burning rubber smell you get when the belt gets caught on something, this was coming from the motor.  This was the Saturday after Black Friday, so if an appliance is going to go, this would be a good day to replace it.

My wife wanted a Sears Kenmore canister vacuum, so I loaded up Sears.com and started searching.  They had the one she wanted for $100 off.  I had the option of ordering online with in-store pickup.  Great!  I could avoid the crowds and just show up at the merchandise pickup counter.  When I placed the order, they took 10% off the sales price for some on-line promotion that was due to expire in a few hours.

While placing the order, I was notified that I would receive an email within two hours.  The email would have a barcode that I could use at the automated station that Sears uses when you pick up an order.  I could also use my credit card to pick up the order.  Two hours seemed like an excessive amount of time, so I took the kids to Five Rivers (a local nature preserve) for a few hours.  On the way back from Five Rivers, I stopped at the house and checked my email, nothing from Sears.  I decided to head into Sears anyway to pickup the vacuum.  Before I left, I printed out the order confirmation page for the vacuum.  My daughters (5 & 7) came along for the ride.

Before I left my house, I dialed the 800 number for Sears.com to check on the status from my cell phone. I left the phone on speaker more and headed to Sears.  I was on hold for the 20 minutes it took to drive to Sears.  When I pulled into a parking space, I finally got a human being.  He asked me a couple of questions and put me back on hold into the general hold queue.  At that point, I hung up.

I went into the Merchandise Pickup area and waved my credit card into the scanner.  Nothing came up.  One of the employees came over and asked if I needed assistance.  I explained what I did and he took my printout over to Kevin, the Merchandise Pickup Manager.  Kevin explained that Sears.com was having problems and no one else who had place orders for pickup through Sears.com had received their confirmation email.

Kevin tried calling Sears.com to see if he could get order information, but he was unable to get through.  Since they had plenty of the vacuums in stock, he suggested that I buy one while I was in Sears and then cancel the order when the conformation email finally came in.  He gave me his direct cell phone number and promised to expedite the order cancellation.

We walked over to where they sell the vacuums and I saw the one that I wanted.  Within seconds a salesman came over and started telling how good that model was.  I explained that I had ordered that model through Sears.com and the order was stuck in the system.  I tole the salesman that I would like to buy another one for the same price and I would have the order cancelled.

At that point the salesman had a serious attitude change.  He told me that I had wasted my time on Sears.com and I should have bought the vacuum here at Sears.  He then told me that I would not get the 10% off because he didn't have the authority to do so.  I suggested (politely) that he should get someone with that authority.  He waved a manager over, all the while still telling me how wrong I was for buying the vacuum online.  Usually I tune that kind stuff out, but my kids were clearly bothered by it.

The manager came over and took my confirmation printout and started punching some buttons on the register.  While he did not say much to me, he was not cordial and I felt very uncomfortable.  The salesman made one more crack about my wasting time on Sears.com and I decided to end the process right there.

I told the manager and the salesman that I had had enough and I was not buying the vacuum.  The manager pretty much ignored me and continued to put the order into the register.  I walked up to him and asked for my printout back.  He made a dismissive comment that he was almost done.  I reached for the printout from his hand and he refused to let go.  At this point I said that I was leaving and please let go my printout.  At that point, he finally let go and I walked out of Sears with my young daughters in tow.

This Sears is one the anchor tenants of the Colonie Center mall and since we were already down here, I decided to make the most of it.  The girls had fun looking at the Christmas decorations and I bought them some hot pretzels.

The way back to our car was through Sears and we had to walk past the Merchandise Pickup department.  I figured I would give it another shot, since we were going by it.  I waved my card by the machine again, still no sign of my order.  Another employee came up and offered to look up my order on their computer.  I explained what I went through earlier and that it wasn't worth looking it up.  A manager came over and they mentioned that I could buy another one and then cancel the first order.

I then explained what happened with the salesman that they were shocked.  They said they could ring up the order right on the spot and at the price I paid online.  Then they asked for details on the salesman that I spoke to earlier.  They promised to look into that for me and I got my vacuum and went home.

The next day I called Sears.com and after 20 minutes on hold, I spoke to a representative.  I gave here my order number and she said that the order was now canceled and gave me an order cancellation number.  I figured that we were done.

The next day (2 days after the placing the order), I get an email from Sears.com notifying me that my vacuum was ready to be picked up.  I called Sears.com and after 15 minutes on hold, a representative took my order number and then hung up on me.  I called back and 10 minutes later, got yet another representative.  She explained that Sears.com could not cancel the order, it had to be done by the store where the pickup was scheduled.  I gave her my cancellation order number and she told me that it just means that I have requested an order cancellation, but they couldn't cancellation.  I asked her what the point was with the issuing of the cancellation number, and she told me that was to keep track of the cancellation request.  Basically, they could take and log the request, they just were not going to do anything about it.

I called the number that Kevin (the merchandise pickup manager) and within seconds I was speaking with Kevin.  I gave him the information from the confirmation email, and after a few minutes of struggling with the computers on his end, Kevin was able to cancel the original order.   While Kevin was trying to cancel the order, an email comes in from Sears.com.  It included the following text:

Thank you for shopping at Sears.com. We are experiencing a delay in sending order confirmations due to the volume of orders received during the Thanksgiving holiday. Please be assured we have received and are processing your order.

An hour later, I got another message stating that the order had been canceled.  I was amazed by what I went through.  I had placed the order for pickup through Sears.com because I thought it would save time.  It was Thanksgiving weekend and I though the salesmen would be very busy.  The staff working at the Merchandise Pickup counter were polite and helpful.  I can not say the same for the sales staff or the people who answer the phone at Sears.com.   I doubt that I will ever use Sears.com again.

[Update]

After posting this earlier, I decided to email this text Sears.  It did get a reaction, and it appears a positive one.  I wrote about it in the post that comes right after this one.

Tuesday, November 20, 2007

Digital versus paper books

Charles Petzold has a good point about the digital versus paper books debate.  Digital books are great when you first get them, but how are you going to read them 25 years from now?  How many people reading this have computer gadgets from 1982 that still work?  Can you read the disk from 1982 circa IBM PC?  I know I don't have any 5.25 in floppy drives anymore.

Even if you still have the e-book on a CD-ROM in 2052, good luck trying to read it.   The CD-ROM format should still be readable 25 years from now because the size of the disc seems to work for most people.  The problem will be that nothing will be able to handle the DRM encoded in the e-book.  Google pulled the plug on it's Internet-based DRM system last August, after a year of use.

There are times that I liked having an e-book reader.  A few years back, I got a Viewsonic V37 Pocket PC as part of a MSDN promotion.  One the applications that was pre-installed was Microsoft Reader.  I was able to find a large variety of books in the Microsoft LIT format and it was easy to create Reader files using a MS Word plugin.  When we went to China to adopt Laura, I had a bunch of books on my V37 to read and it took a lot less space to pack.  But that was the exception, not the norm.

On the other hand, you have to deal with battery life, not a problem historically associated with printed books.  Battery life on my V37 was pretty horrible, 3-5 hours of sustained Reader usage.  That's not very useful on a 9 hour plane ride.  I managed to find a little gadget that would power my V37 from a 9V battery, that basically tripled the battery life.

Reading at the beach is something I like to do.  You just can't do that with a digital book reader.  First of all, you can't read one of those screens in bright sunlight.  You also have to worry about dropping it into the sand (not a good idea) or into the ocean (warranty killer). 

How many times can you drop a paper book before it breaks?  I no longer use my V37 because it was not immune from the effects of gravity.  My daughter dropped it and the fall from the height of a three year old (at the time) was enough of a shock to permanently shut off my Pocket PC.

What would be a great use for an e-book reader would be being able to rent from one from the local library and fill it up with books from the library.  If I was going on vacation, I would pay $15 to $20 to rent one for a week with 5 to 10 books in it.  It's not much different than getting a bunch of books on cd audio from the library and ripping them to your iPod (except the e-book rental would be legal). 

Sony has been trying to play in this market for years with their Reader Digital Book.  I have yet to see one of the Sony devices out in the wild.  Amazon has the resources to sell a huge number of Kindles to libraries at greatly discounted prices.  They would make it over time with the e-book sales.  Plus it more people will use one if they can try it for a small fee.  They cost $400 now.  For that kind of money, you can get a cheap laptop and Adobe Acrobat Reader on it.  Come on Amazon, you know what you have to do. 

[thanks to Julie for her post about Petzold]

Sunday, November 18, 2007

When memes escape out of the series of tubes

It was only a matter of time before one of the candidates played the Chuck Norris card.

 

What's next?  LOLCats for Kucinich?  Oh wait, that one already happened.

Once you get past the wry amusement of the Chuck Norris "facts", does the apparent endorsement of Norris add anything to Mike Huckabees quest for the White House? 

Saturday, October 27, 2007

My doppelgänger is preventing me from giving blood

About two weeks ago, I went to give blood for the Red Cross.  It had been at least five years since I had last given blood and there was really no excuse for that.  The Red Cross had a few rooms in another building in our complex and I made an appointment to give some blood.

When I got there, they asked for my donor card.  I had no idea where it was, but that didn't faze them.  They could look me up in the computer.  I gave them my name, date of birth, and Social Security number.  And that's when the fun began.

After entering in that data into their computer, I was flagged as being in-eligible for giving blood.  Forever.  And forever is a mighty long time.  I was given a form letter that included an 800 number that would provide more details.  Due to HIPAA restrictions, the staff at the Red Cross station could not tell me why I had been banned.

So I called that 800 number and talked to a Red Cross representative.  It turns out that there is another Christopher Miller with the same date of birth as me, but living half way across the country.  He has an illness that has banned him from ever donating blood. 

Because we have the same name and birth date, when my data is entered in the local Red Cross database, they hit his record in the national registry.  And they don't look at the SSN number.

The fun continues.  Back at the 800 number, I was told that the only way I can give blood is to not use my Red Cross donor card and never give out my SSN.  Without the SSN, they don't check the national database.

That's the mind-boggling part.  They don't check the national database unless I provide a SSN, but if I provide a SSN they wont use it to filter out other people with the same name and birth date.  That's just wrong. 

Saturday, October 06, 2007

Technical Support: Verizon FiOS vs McAfee

It all started this morning when my wife went to check her email. She said that it wasn't working, so I took a quick look. She uses Thunderbird to check her Verizon FiOS email account. Thunderbird would connect to the POP3 server, incoming.verizon.net, but would time out after a minute or two with the message "Connection to server incoming.verizon.net timed out".

So I pinged incoming.verizon.net and it responded right back, so it didn't seem like a DNS resolution type of error. I logged into her email through Verizon's online webmail interface. That worked, so her account and password were still good. I went to the Verizon FiOS portal page and went through the various help topics. It didn't like Firefox so I fired up IE7. It didn't like Vista and complained that Windows 98 wasn't supported.

That ruled out online support, but it did surrender a toll-free tech support number: (888) 553-1555. (btw, if you ever need to find support number, try the gethuman database) I went down the automated phone tree until it got to the part where it said that I would need to speak a human. And then told that the wait time for a human would be 31 minutes.

Here's where Verizon goes the extra mile. I was given the choice between waiting on hold for the next available human or they would call me back in 31 minutes. I took the "call me back" option and went on with life. About 30 minutes later, Verizon called back and I got to talk with FiOS tech support rep. That's pretty cool.

Within 2 minutes, we determined that the email protection in the McAfee Security Center was blocking Thunderbird. I've only had to call FiOS tech support a couple of time and each time I got a person who knew his stuff and didn't blindly follow a script.

Basically, if you go into the McAfee Security Console and disable email protection, Thunderbird works. Enable it again and Thunderbird can't access the POP3 server. Pretty easy to duplicate and it was repeatable.

Yesterday, we saw a McAfee popup notifying that an update had been installed. Mentally, I had filed that under "Yeah, whatever". It seemed that the latest update was the culprit.

This was the free version of McAfee that you can get with FiOS, via MSN Premium. Getting the free McAfee is a story for another posting, they don't make it easy. Since the McAfee was more or less provided by FiOS, I figure there would be support, more or less. The FiOS guy told me that I would have to contact McAfee support and he gave me the number (800-337-6840) and offered to transfer me over.

I took the transfer and spent the next 25 minutes on hold, which was less far exciting than it sounds. After reaching a tech support specialist named "Terry", the real fun began.

The first thing Terry asked me was the email account that I had registered my copy of McAfee Security Center under. I tried explaining to Terry, that I never had to register my copy McAfee and that it was provided by MSN Premium via Verizon FiOS. Tery mulled thatover for a minute and then asked me for the asset code of my Dell computer. Apparently Terry thought I had eval version McAfee provided by Dell. The funny part is my wife's machine is new Dell desktop, but we had ordered it with the "no software pre-installed" option and her machine did not come with any preinstalled anti-virus application.

I told Terry that I did not have an asset code to give him and it was not relevant to this issue. At this point he finally grokked that I had the McAfee that comes with MSN Premium and I would not be his database. After walking through the steps that duplicate the problem, Terry told me that the solution would be uninstall McAfee Security Center and install a new version. Terry then gave me an issue number and started to wrap the call up. I had no confidence that this would work and requested for Terry to stay on the line. Terry agreed.

I asked Terry how that be different a version than the one that had just updated himself. He said that the currently installed copy had corrupted files. I asked how about he knew this and he said that other people were having this issue. I uninstalled McAfee Security Center and downloaded the latest version through MSN Explorer. You get a 500KB installer and it grabs the actual installable bits from the Internet. While it was downloading, it displayed the usual metrics of size, time, download speed. The download speed averaged around 45Kb/sec. I have the 20Mbps/5Mbps plan with FiOS, I should have been getting a much faster download. Terry told me that the was heavy demand on their servers with users having to manually download McAfee Security Center.

So after reinstalling McAfee Security Center, nothing was fixed. Thunderbird would only work if email protection was disable. Terry then asked me to turn off the PC and power it back up with the F8 key pressed down. I asked why, and he said that we would need to boot up in Safe Mode to see if the email would work without McAfee Security Center running. I made the point that it would be a waste of time since we already new that it work when email protection was disable. Terry made it clear that this step had to be followed. To make a short story long, that didn't work either.

Terry then put me on hold to talk to another support person. After a minute or two on hold, Terry came back to say that this was known issue and an updated would be issued through the McAfee update process within 24 to 48 hours. The work around is to disable email protection and try again in 2 days.

At this point, I have better than an hour and half sunk into this phone call. I told Terry that I was upset that I went through uninstalling, downloading, reinstalling, and rebooting into Safe Mode for an issue that they already knew about. Terry then told me that reinstall had fixed the problem all that reported it. There were a couple others that were not fixed and an update would be coming for them. I then asked Terry how he could use "all" in one sentence, but indicate "not all" in the next. Terry did not understand that question so we ended the call at that point.

At this point I have a lot of respect for Verizon FiOS tech support and almost none for McAfee. I pretty much got what I paid for, no question about that.

Monday, July 23, 2007

File sharing with Vista Home without passwords

After having several PC implosions, we now have two new Vista boxes at home. Both have Vista Home Premium installed. I'm used to the relative stability of XP Pro, but I figured I would give Vista a shot. For the most part it has gone very well, but I made sure that each machine was going to be able to run Vista.

My machine is a custom built box from MWave, my wife's is a Dell box. She has Intel, I have AMD, but they are both dual core machines with 2GB of RAM and decent video cards.

My wife and my kids have user accounts with out passwords. The machine has the usual security apps installed and is behind a router firewall. Their accounts are set as Standard User. I have a password protected admin account on each box. My wife has a Standard User account on each box.

We share a printer from my machine. I could print from my wife's PC, but she couldn't. She kept getting a login pass prompt and finally an error message about being able to validate credentials. It took a little while to figure out, but finally I remembered that out of the box, Vista wont let non-password protected accounts from remotely authenticating. That means that you need a password on your account to access network resources on another Vista box.

A fair amount of Googling kicked up a few suggestions to run gpedit.msc (Group Policy Editor). Most of the suggestions were of this type:

Run gpedit.msc
Go to Computer Configuration / Windows Settings / Security Settings / Local Policies / Security Options
Double click on Accounts: Limit local account use of blank passwords to console login only
Disable this option

One little problem. You only get gpedit.msc with XP Pro or Vista Business (or Ultimate). Thanks for playing the Home version of Windows, you don't get that useful little utility.

Fortunately for this setting all gpedit.msc is doing is writing to the registry. All you have to do is to edit the following key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa

and edit the value of LimitBlankPasswordUse from 1 to 0. After you do that, you can now share printers and folders across Vista (and XP) with accounts that do not have passwords.



Updated on 8/15/2008
If you install Service Pack 1 (SP1) after making this change, you'll need to do it again as SP1 restores this setting back to the default.


Friday, July 20, 2007

Allowing Comments on Blogs

I came across a posting by Dave Winer (via Joel) about blog comments.  Dave doesn't easily allow commenting because he thinks it takes away from message that the blogger is putting out.  The power of blogging is that anyone (outside of some 3rd world countries) can express their own message.  Allowing comments brings in other views that can dilute or contradict your own view.

Joel adds the astute observation that allowing comments and lead to childish flame wars and other useless craps.  His view is that if you want to express your own view of a blog entry, post in on your blog.  Like this very posting.  I liked the Penny Arcade reference illustrating his point that anonymous posters are not always desired.

99% of I read in the blogs is through Google Reader, so I miss most of the comments anyways.  Usually, the only time I see comments on a blog is when I add a comment to a blog.  My experiences with comments has been pretty positive, with some rare comment spam.  Of course this blog is on the z-list and any comment is a rare event.

I can see that point.  But there is another side to blog commenting.  It allows the blog reader to correct or enhance positions posted by the author.  I have also seen plenty of blog postings where the author invited comments.  He/She was trying to solve a problem and was soliciting feedbacks.  As long as you can reasonably block comment spam, I'm in favor of allowing comments.  No one is forcing you to read them.

Thursday, July 05, 2007

Implementing a sortable TCollection in Delphi

Delphi's TCollection class is very useful, but out of the box it lacks the ability to sort the items in the list.  Fortunately, this is easily addressable accessing some private properties of the TCollection class.  Internally, the items in a TCollection are stored in a private TList named FList. 

The trick is to get access to a private property.  The way to do this is by creating a shadow class.  A shadow class is a class that matches the private declaration of the class that you need to access.  The shadow needs to have the same field types in the same order, up to and including the field that you need access to.  This is the risky part, and cover that risk later.  The definition of the TCollection class starts out with:

TCollection = class(TPersistent)
private
FItemClass: TCollectionItemClass;
FItems: TList;
FUpdateCount: Integer;
FNextID: Integer;
FPropName: string;


To get at FItems, we need to shadow the top two members of the class.  Which provides this shadow class:



TShadowedCollection = class(TPersistent)
private
FItemClass: TCollectionItemClass;
FItems: TList;
end;


With access to the internal list, it becomes a simple task to provide the ability to the sort the list.  A public Sort method will call an internal method that runs a Quicksort across the list.  The Quicksort code will process the list obtained by casting itself as TShadowedCollection, allowing access to FItems and then call a Compare() function to compare items in the FItems list.  The collection will provide a "do nothing" Compare() function.  It will be up to the descendant class to override that function and implement the actual comparision code.  The full source code for the class would look something like this:


unit SortCollections;

interface

uses classes;

type
TSortableCollection
= class(TCollection)
protected
function Compare(Item1, Item2 : TCollectionItem) : integer; virtual;
procedure QuickSort(L, R: Integer);
public
procedure Sort;
end;

implementation

type
// Helper class to allow sorting of a TCollection
{$HINTS OFF}
TShadowedCollection
= class(TPersistent)
private
FItemClass: TCollectionItemClass;
FItems: TList;
end;
{$HINTS ON}


{ TSortableCollection }

function TSortableCollection.Compare(Item1, Item2: TCollectionItem): integer;
begin
(*

Descendant classes would override this method and cast Item1 and Item2 to the
decendant class's collection item type perform the field comparisions

if item1.MyField < item2.MyField
return -1
else if item1.MyField > item2.MyField
return 1
else return 0

*)
result :
= 0;
end;

procedure TSortableCollection.QuickSort(L, R: Integer);
var
I, J, p: Integer;
Save: TCollectionItem;
SortList: TList;
begin
//This cast allows us to get at the private elements in the base class
SortList := TShadowedCollection(Self).FItems;

repeat
I :
= L;
J :
= R;
P :
= (L + R) shr 1;
repeat
while Compare(Items[I], Items[P]) < 0 do
Inc(I);
while Compare(Items[J], Items[P]) > 0 do
Dec(J);
if I <= J then begin
Save :
= SortList.Items[I];
SortList.Items[I] :
= SortList.Items[J];
SortList.Items[J] :
= Save;
if P = I then
P :
= J
else if P = J then
P :
= I;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then
QuickSort(L, J);
L :
= I;
until I >= R;
end;

procedure TSortableCollection.Sort;
begin
if Count > 1 then
QuickSort(
0, pred(Count));
end;

end.

Tech Tags:

Tuesday, July 03, 2007

REST vs SOAP

In the weekly newsletter from TheServerSide.NET, there was a link to an article titled "REST versus SOAP - the REST story" by William Brogden.  It's a few months old, but talk about the recent rise in REST types of services over XML-RPC and SOAP.   Brogden briefly covers REST, but he doesn't talk about the advantages of REST and why you would ever want to use it over SOAP.  It's obvious that he prefers SOAP, but the reasoning was left out of the article.

Having done SOAP and REST for accessing web services, I can see the where it's advantageous to use SOAP as opposed to REST (or vice versa).  SOAP is very chatty, but you can send complex data structures to the web service.  Development tools like Visual Studio or Delphi can can read the WSDL from the web service and that gives you the "intellisense" autocompletion functionality that can save a lot of coding time.

With REST, you access the web service with just the basic HTTP GET and PUT commands.  You compose a URL for your web method request and the service sends back a response.  The response is usually in XML, but that is dependant on the functionality of the web service.

The drawback with SOAP is that there is more overhead in the construction of the method request and with the parsing of the request on the web service end.  When you have a web service that is serving thousands of requests a minute or second, that overheard may not be needed.

For web services that have relatively simple data types, using REST can provide the functionality that is needed.  You also get the advantage of testing individual method requests from a browser as the method request is basic URL. 

Blast from the past: Forth

I came across a link an online version to Leo Brodie's Forth tutorial, "Starting Forth" today.  I used to have a copy of that book eons ago.  I learned how to program on a Commodore VIC-20 and I bought (actually had to special order it) a Forth language cartridge.  This book has been out of print for decades, the online version is probably the only way to read it now.

Forth is an arcane language that allows you to program in interactive and iterative manner.   You would create words (what other languages would call functions or subroutines) from the language core keywords and created new words from existing words.

The operators worked in post-fix notation (aka reverse Polish notation) like the older HP calculators.  The language was stack oriented and post-fix works well when you are pulling items off the stack.

Since Forth programs were very small in size and typically do not access or require a traditional file system, Forth was used in embedded controllers and other hardware related projects.  NASA uses Forth to this day for spacecraft flight system controllers and other projects.

Needless to say Forth and the VIC-20 were not the best fit and I never did too much with it.  I wonder how many geek points do you get for programming in Forth on 5K (but only 3.5k were usable) machine that had a whopping 22 columns of text per line?

Thursday, June 14, 2007

I gots my favicon back

A while back, this blog was updated to the new Blogger and I was the custom icon that was displayed with my blog.  And of course, I forgot where I had hosted the icon.  I came across an blog posting for MyFavatar, a free site for hosting favicons for blogs.  I decided to give it a shot and it's one of those things that just plain works.

They made it pretty simple.  You register for an account, upload an image, and they create the .ico file from the image.  They even provide the html to enable favicons in your blog.

Enabling Database Diagrams in SQL Server 2005

I was working on a spec for a new feature in our flagship application, when I wanted to included some simple database diagrams.  I was adding some new schema and I wanted to reference them in the spec.  I figured I would just do the schema changes in a spare database and make a database diagram.

I opened up MS SQL Server Management Studio (SSMS)) and connected to the database on a box running SQL Server 2000.  I selected the database and then selected "Database Diagram".  SSMS got huffy about how the database diagrams in 2000 were nothing like the feature in 2005 and it wouldn't touch it.  Gee thanks,  Microsoft.  The SQL Server team should have borrowed Raymond Chen for a while.  That wouldn't have happened on his watch.

I connected to a SQL Server 2005 box and made my schema changes in a scrap database.  I selected database diagram and got a lovely error dialog with the following message:

Database diagram support objects cannot be installed because this database does not have a valid owner.  To continue, first use the Files page of the Database Properties dialog box or the ALTER AUTHORIZATION statement to set the database owner to a valid login, then add the database diagram support objects.

So I took the error message literally and took a peek at the owner.  I was the owner, and I have admin rights on that box. [Insert annoyed grunt here].  So I tried making sa to the owner, same error.  That obviously wasn't the problem.

After a wee bit of googling, I came across the root cause of the error.  It was not an ownership issue, it was a database version issue.  We support both SQL Server 2000 and 2005, all of our databases are version 2000 compatible.  You can't have 2005 database diagrams in a 2000 database, even it it's attached to a 2005 server. 

There are a couple of ways to change the database, I opted for the T-SQL method:

EXEC sp_dbcmptlevel 'MyDataBase', '90';

The sp_dbcmptlevel is documented here.  The value "90" corresponds to the version number of SQL Server 2005. I ran that command and I was able to add database diagram support to the database.  You can also make the change via SSMS with the following steps:

  1. Write click on database.
  2. Click on Properties.
  3. Click on Options.
  4. Change the Compatibility level to desired compatibility.
  5. Click OK.

After doing all of that, I really disliked the look of the tables in the database diagram.  It looked like the tabled editor from Access '97.  So I ended up doing what I should have done in the first place, created a database diagram in Visio and copied that into my spec document.

Tuesday, June 12, 2007

When other people host your data....

You are at the mercy of your hosts when they hold your data.  Using an online feed reader like Bloglines or Google Reader means that someone else is backing up your feed subscriptions.  This is usually a good thing, except for when they accidently delete all of your subscribed feeds.  That happened to Steve Tibbet today.  And not just Steve, it happened to a bunch of people.

It looks that problem has been fixed, but I immediately went and exported my subscription list to an OPML file.  I wonder if you can create a PowerShell script to automate that export.  The URL is a static link, http://www.google.com/reader/subscriptions/export.

I, for one, welcome our new Google overlords. Even so, things break and you can't rely on them to back up your data.

The $51 server.

It's been 6 months since I installed FreeNAS and it really has been like an appliance.  I back up my machine and my wife's machine with just a few batch files, based on robocopy.  I could get fancy with remote backup tools and so forth, but simple works.

I've been calling it $51 Server .  It started out as a white box pc that that I had custom built by MWave a few years back.  I had needed a Netware box for some Sybase Adaptive Server Anywhere testing and we bought a Dell Server with Novell Netware 5 on it.  It's an interesting story of how I ended up with that box, but if you want to skip the story, just jump here.

Netware was installed, but it needed to be configured.  The first thing it asked for was it's designation.  I considered naming it "One", but precious few would have caught the reference.   Usually when I get a server, I'll ask a random co-worker for the first one word that comes to mind.  I was talking to one our tech support staff and his word was "pumpkin". 

This bugged our IT manager to no end.  Normally, IT handles all of our server installs, and the server gets the name of some sort of predator.  Since I was the only one who knew Netware (which was a scary thought on many levels), the care and feeding of Netware box was my responsibility.

Getting back to Pumpkin.  After running it for a week, we had a somewhat urgent need for another Windows 2000 Server for a temporary remote access situation.  I wiped Pumpkin clean and IT installed Windows 2000 Server and named it Viper.

Temporary turned into permanent (about 6 years at this point) and I still needed a Netware box.  And of course, we did't have any more money in our budget for another server.  But we did have enough money to have a cheap whitebox built.  So for a couple of hundred, we got a Celaron 1ghz box with 256MB memory and a 20GB drive.  Video and sound were on the motherboard and we had a 3Com ethernet card that had outlived it's prior owner.  Using the usual method of selecting a server name, one of the QA people volunteered "moo" as the name.  She likes cows and it was short enough that you could easily type it with one hand with moving the hand.

Moo lasted 5 years without issues.   We used it test Sybase and it did was asked.  Our support for Sybase ended last fall and so ended our need for dedicated Netware Server.  The company sold it to me for $1.  I spent $50 on a 250GB hard drive and installed FreeNAS on it.

So for the whopping sum of $51, I have a NAS box that is completely managed by a simple web interface.

 

Technorati tags: , , , ,

Friday, June 08, 2007

User specific connection strings

Steve Harmon has a good tip on how to use ASP.NET 2.0's configSource to store connection strings in a file outside of the web.config.  You keep the user specific file out of source control and you eliminate conflicts when people use their own connection string settings.  He's not the only one to come up with that idea.

Shawn is dragged kicking and screaming into the year 2004

Shawn Gwin finally has a real blog.  As the president of the Tech Valley .Net Users Group (TVUG), it was about time that he started blogging.

Tuesday, June 05, 2007

TestDriven.NET and Visual Studio Express

There's been a lot of blog postings about Jamie Cansdale's legal issues with Microsoft in the last few days.  Jamie has a product called TestDriven.NET that integrates unit testing within the Visual Studio IDE.  The problem is that Jamie has integrated TestDriven.NET within Visual Studio Express and Microsoft would like him not to do that.

Visual Studio Express is the free version of Visual Studio 2005 intended for the hobbyist/student programmer.  Because it's free, Microsoft took a few steps to prevent VS Express from taking away sales from the other members of the Visual Studio product line.  Basically, you are not allowed to extend Visual Studio Express with additional functionality.

Jamie found to register TestDriven.NET so that it would work withing VS Express.  Jamie stated that he used published API calls, everything was above the board.  Information posted by Dan Fernandez (Lead Product Manager for Visual Studio Express) would indicate otherwise:

The TestDriven.NET product is implemented as a Visual Studio Add-In.  In the Visual Studio Standard, Professional, and Team System SKUs, TestDriven.NET is installed as an Add-In and gets loaded into the IDE through the Add-In Manager.  In the Visual Studio Express SKUs, because we disabled extensibility (macros, Add-ins, and VS Packages), the Add-In Manager is removed and therefore Add-Ins are not detected or loaded.  Jamie has created additional components specifically for the Express SKUs to work around this technical limitation.  He takes advantage of an extensibility point that allows user controls (such as a button class) to customize entries in the Properties window.  When his property extender gets called, he executes code that finds, loads and injects the TestDriven.Net assembly into the Express SKU’s running process, thus replacing the functionality of the removed Add-In Manager.  This explains why he instructs Visual Studio Express users to open the Properties window in order to enable TestDriven.NET.  Once his code is injected into the Express SKU’s running process it can add menu items, enable features that were disabled, and in general take over that instance of Express. These special loading mechanisms that Jamie has built exclusively for the Express SKUs are unauthorized workarounds to the SKUs’ technical limitations.

Right after VS 2005 was released, Microsoft contacted Jamie asked Jamie to remove support for VS Express from TestDriven.NET.  After many rounds of email and phone conferences, Jamie complied for a while.  Eventually he re-enabled support for VS Express and Microsoft is now using their lawyers to enforce their request.  You can read most of the emails and the legal correspondence here.

When I first read about this, my initial thought was Microsoft was sticking to the little guy.  That's really not the case here.  Microsoft spent a considerable amount of resources developing the Express line of Visual Studio products and it was clear from the start that you were not supposed to extend the architecture of the tool.  For that limitation, you have a powerful development environment that you could develop commercial applications with.

People have been making the argument that it's OK to extend the functionality because Microsoft is already doing it by releasing additional products (like Popfly) designed for VS Express.  That has nothing to with MS's requirement that third parties are prohibited from extending Express.  This isn't unique to Microsoft.  CodeGear does the same thing with Turbo Explorer lineup.  You can't install third party components into Turbo Delphi Explorer

Jamie appears to be stuck on the what specific part of the EULA is being violated.  I don't think it matters.  The request to pull VS Express from TestDriven.NET was a reasonable one and he should complied with it.

postscript...
It's entertaining to read the comments posted on Dan's blog, especially here.  While I'm not surprised by the number of people who just don't know the facts, there were many postings by people saying that MS vs Jamie was a reason to dump MS and only use open source tools. 

Give me a break!  If you are making decision on what tool to use over a clear cut EULA violation, you have rocks in your head.  You should be making that type of decision based on it being the right tool for the job.

Friday, May 18, 2007

Why is this man laughing?

 

There’s a story behind that picture and it’s pretty much what you would think it is.

Dave Anthony toasts his achievement after driving his truck on top of a Kent house he was demolishing. Anthony said "it was a hell of a way to kick off the Memorial Day weekend."

Somehow, it's not too surprising that alcohol was involved.  The full story can be read here.   I wonder how close he came to being a candidate for a Darwin Award?  At the very least, he should get an "Honorable Mention" for this stunt.

It gets better with the followup story:  Driving your pickup truck onto the roof of a house and getting your picture in the newspaper doesn't make a whole lot of sense when police want to talk to you about a $2,800 set of tires purchased with a stolen credit card.

Courtesy of Raymond Chen from The Old New Thing.

Tech Tags: