Tuesday, April 29, 2008

I just installed the PowerCommands for Visual Studio 2008

I just installed the PowerCommands 1.1 for Visual Studio 2008.  This is a set of extensions to the VS 2008 IDE that provide some additional functionality.  The available commands are listed here.  The Collapse Projects command sounds pretty basic, but it's something I've always wanted and it's great for large solutions. 

The best part of PowerCommands?  You get the source code, which would be handy if you ever want to write your own VS extension.

My "Windows Feedback" copy of Office 2007 Ultimate just came in

I just received a NFR copy of Microsoft Office 2007 Ultimate in the mail.  Last December, I signed up for the 2008 Microsoft Windows Feedback Program Sweepstakes.  This was a three month program run out of the Windows Feedback Program.  As part of the program, I installed some software on one of my home PC's that recorded some basic metrics such as Windows settings, hardware details, how the common document folders are being used, changes to the system, and problems that may occur.

This information was sent back to Microsoft to provide information on how our PC was being used.  In return for allowing MS to collect this data for 3 months, I was given a choice of several different products from Microsoft (Vista Ultimate, Office Ultimate, Money Plus Premium, Encarta Premium, or Streets and Trips).  I opted for Office 2007 Ultimate.  I didn't need another copy of Office right now, but it would handy the next time I get a new machine.   Apparently the response to this offer was so huge that Microsoft closed the program to new entrants after only a day or so.

In addition to the monitoring software, I was required to answer at least one survey during that time period.  Oddly enough, I was only prompted once during the 3 month period to answer a survey.  At this point, I'm no longer obligated to run the monitoring software and I haven't decided whether or not to uninstall it.  I'm not a big fan of monitoring software, but I'm not seeing any performance impact and I'm satisfied with the privacy issues with the data being sent back.  I know some people roaming the series of tubes were calling this spyware, but technically the WFP software isn't spyware.  Most definitions of spware define it as software that collects data or controls a computer surreptitiously and was installed without informed concept.  I knew what it was doing and I opted in, which means it's not spyware.  At most, Microsoft now knows how much time my kids spend at Webkinz World.

It would be nice to see what data was being sent back to the mothership, but if MS is following their own Terms of Use for this program, my privacy concerns have been satisfied.  This is in strong contrast to a program launched by Sears Holding Corp (SHC). at roughly the same time, where they wanted to install some software that would be a lot closer to the definition of spyware.  The software that Sears wanted to install was a web proxy from ComScore (never identified as such by Sears) that would track all of your web usage and sent that data to Sears.

The software used by SHC is a web proxy program supplied by Comscore.  It redirects all of your web browser activity through the Comscore software and that data can be sent to Sears.  SHC notifies the user that the user is about to install some software, but it does not go into full detail about what data is being collected and what is being sent to Sears.  At no point during the installation process or preliminary email is the software identified or it's functionality  described.  A person with computer security experience would realize what is going on, but the average computer user would have no idea what they just installed.

With the security breaches on Sears web site earlier this year, I would be very hesitant with letting Sears have access to my personal information.  I understand why Sears would want to know what I shop for online, and I don't mind sharing that information.   Sears has no business knowing how I pay for those items and has no business viewing my email.  Comscore's tracking software would monitor all of that.  All privacy issues aside, that's a horribly inefficient means of tracking online shopping.

It also looks a little funny that the guy in charge of this program, Rob Harles, was a former senior vice president at Comscore.  Comscore is the vendor for the tracking software that the SHC wants to install. Ben Edelman, assistant professor at the Harvard Business School who focuses on spyware practices, did a great write up about the SHC sofware.  He documented in clear detail (with screenshots and video) that the installation steps violate FTC guidelines.  If you Google for Sears & spyware, you'll get close to a quarter of million hits.  That's not what you call good publicity, but I digress.  When I participate any sort of consumer feedback program, I take a close look at what would be installed and what will be collected.  I also check to make sure that the company collecting the data is collecting the right data and will respect my privacy.  Microsoft met those concerns.

Friday, April 25, 2008

How to identify who has a terminal session and how to kill it

Having the ability to use a terminal service (aka Remote Desktop) session to manage a Windows Server (2000, 2003, and 2008) is very useful.  If you don't have a Terminal Services license installed, you are limited to to two active sessions (plus a bonus connection that I'll get to in a minute).  If a person disconnects from a session without logging out, it can leave that session running.  That allows you to start a long running task and come back to it later, but it does use up one of the available connections.  If both sessions are being used, you will not be able to create a new terminal service connection to the server.  At this point, you have three options:

Yell down the hallway and ask "Who has a connection to server XYZ".  This never works because either the person who left the connect forgot about it or didn't realize that he (or she) was supposed to logout.  The other problem is that you could be working from home and the only thing that the yelling accomplishes will be to attract your dog and your child, both of which will be looking for cookies.

Use the command line tools to identify the open sessions and kill one of them.  There are two tools, qwinsta and rwinsta.  If you run "qwinsta /?" from a command shell, you will get the following:

qwinsta /?
Display information about Terminal Sessions.
QUERY SESSION [sessionname | username | sessionid]
              [/SERVER:servername] [/MODE] [/FLOW] [/CONNECT] [/COUNTER]
  sessionname         Identifies the session named sessionname.
  username            Identifies the session with user username.
  sessionid           Identifies the session with ID sessionid.
  /SERVER:servername  The server to be queried (default is current).
  /MODE               Display current line settings.
  /FLOW               Display current flow control settings.
  /CONNECT            Display current connect settings.
  /COUNTER            Display current Terminal Services counters information.

                                


If you run "rwinsta /?", you get the following:


rwinsta /?
Reset the session subsytem hardware and software to known initial values.

RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]

  sessionname         Identifies the session with name sessionname.
  sessionid           Identifies the session with ID sessionid.
  /SERVER:servername  The server containing the session (default is current).
  /V                  Display additional information.



For the sample server XYZ, you would run "qwinsta /server:xyz"  That will return something like:


 SESSIONNAME       USERNAME                 ID  STATE   TYPE        DEVICE
console                                     0  Conn    wdcon
rdp-tcp                                 65536  Listen  rdpwd
                   gatesb                    1  Disc    rdpwd
rdp-tcp#93        jobss                    3  Active  rdpwd


From that output, we can take one of the IDs that was returned for the remote sessions and use rwinsta to kill that session.  You would use something like:


rwinsta 1 /SERVER:xyz


And that will terminate that session, allowing you to open a new session.  You will need admin rights to run that command, but if you are using the admin terminal service connections to the server, then you would already have the necessary access rights to the server.


There is a third option, you can connect to the console session.  This is the bonus option that I had referred to earlier.  This is the session that you would get if you were physically in front of the server and were logging in on the server's mouse and keyboard.  You can specify the console session as a command line parameter to the remote desktop client, mstsc.exe.  The following syntax can be used to connect to the console session of a server:


mstsc /console

That feature will work with Server 2003 and later.  On some machines, qwinsta and rwinsta may have been renamed to query.exe and reset.exe, respectively.


[Updated at 2:42 pm]
Steve listed an alternative to qwinsta and rwinsta on his blog.  He uses quser.exe and logoff.exe, which provide pretty much the same functionality.  On my machine, quser.exe was buried in c:\windows\system32\dllcache, which was odd.  I wonder why it wasn't in system32?  quser has an advantage over qwinsta, it lists the logon time and idle time for each session.  That gives you a little more data when you have to kill someone session and you can't determine which one must die.

Saturday, April 19, 2008

System Restore and Vista

After reading the comments posted to my blog entries for USB issues caused by KB938371, I can't over emphasis how valuable it is to have System Restore enabled.  While trying to find a work around for the mouse problems that I reported here, here, here, and starting at here; I noted that a few of the people who had posted responses or had sent private email did not have System Restore available.

I was surprised by that as System Restore is enabled in all SKU's of Vista by default and it's greatly improved over the System Restore feature in XP.  If you are not familiar with System Restore, I'm going to borrow the following from the Wikipedia entry

it's a feature that periodically takes a snaphot of the current state of the operating system, typically referred to as a restore point.  Windows uses Shadow Copy (aka Volume Snapshot Service or Previous version) to create a file that contains system files, registry settings, drivers, installed programs and stores the data in a single compressed file.  User settings and files are typically not covered.

This restore point will be generated under the following conditions:

  • when a piece of software is installed
  • when Windows Update installs new updates to Windows
  • when the user installs a driver that is not digitally signed by Windows Hardware Quality Labs
  • every 24 hours of computer use , or every 24 hours of calendar time, whichever happens first
  • when the operating system starts after being off for more than 24 hours
  • when the user requests it.

When Windows Update pushed KB983371 down to my machine, System Restore created a restore point of the current state of the OS just prior to the installation.  This allowed me to easily roll back the installation of the update.  Since 938371 does not allow itself to be uninstalled, roll back the system via System Update was the only documented way of removing 938371, short of reinstalling Vista.

If for some reason you have disabled System Restore, you really should consider turning it back on.  I have seen a few sites mention how to turn it off (but for the most part they do warn you of the consequences), but you really want to leave it on.  I have had to use System Restore a couple of times and it really got me out of jam.  If you need to re-enable System Restore, the following steps should work for you:

  1. Click on the Start button.
  2. Right click on "Computer" ,and then select Properties. (Also reachable as the "System" applet on the Control Panel.
  3. On the left hand side of the Control panel->System dialog, click Advanced Settings.  If the User Access Control dialog rears it's ugly head and propmtps you to permit the action, click on Continue (or OK) to allow you to continue.
  4. Click on the System Protection tab.
  5. In the group box labeled "Automatic Restore Points", check the checkboxes listed for your hard drives.  Some PC's come with special partitions used for vendor specific diagnostic and restore functionality (Dell PC's typically have a special partition labeled "RECOVERY", leave those partitions unchecked.
  6. Press OK to save the changes.

There's rarely a free lunch in this business, and there is a cost to using System Restore.  This cost is pretty simple, it will use up to 15% of the space on the drive, with 300MB as a minimum.  You also need to have a drive larger than 1GB to use System Restore.  With the huge drives now available to today, the benefit clearly out weighs the cost.

Friday, April 18, 2008

Dealing with the "Cannot generate SSPI context" error message

One of our sales engineers came up to me with with a problem that I had not come across before.  He was getting the error "Cannot generate SSPI context" when he tried to back up a database. Before getting too deep into the problem, I'll lay out the background of how the problem occurred.

Our applications work with SQL Server 2000 and 2005.  Our desktop applications have the ability to back up the SQL Server database and store the backup on the local machine.  The backup command is issued to the database server, typically on it's own server.  The account that SQL Server runs under typically can only access the local file systems.  You can get around that by running SQL Server under an account with network access, but as a shrink wrapped application, we want to under the default installation of SQL Server.

To get around the file system access, I wrote a win32 service that runs on the same machine as SQL Server.  Our applications back up the database through my agent service.  When the agent receives a backup request from a client, it does the following:

  1. Performs some preventative maintenance on the database
  2. Defragments the log file
  3. Backs up the database to local path
  4. Compresses the database backup to a .zip file
  5. Sends the compressed backup to the client
  6. Deletes the backup and compressed backup from the server.

It does a few other things, but those steps are the highlights of the backup process.  Our engineer was getting the "Cannot generate SSPI context" error right at step one.  I have never come across that error so it was time to fire up Google and go searching.  One of the top hits for goggling that error message was a KB article, 811889.  It was informative, but not especially helpful for me.  The top hit was much more helpful, “Cannot generate SSPI context” error message, when connect to local SQL Server outside domain, on the SQL Protocols blog.  Who knew that SQL Protocols had it's own blog.  This post had all of the good details of what was happening and suggestions on how to resolve it.  I like that.

In short that error can occur when all of the following are true:

  1. The hosting machine of SQL Server is connected to a network, including home network or dialup connection, but it is disconnected from its domain.
  2. The OS of the hosting machine is Windows XP or 2000. Not windows 2003.
  3. The connection is to a local SQL Server.
  4. Connection configuration causes network library to choose TCP/IP provider.

The root cause is that agent service is using integrated security to connect to the local server over TCP/IP.  The SSPI in the error message stands for Security Support Provider Interface.  SSPI is a set of Windows API that handle delegation and authentication over data transport layers (TCP, Named Pipes, etc).  With TCP/IP and SSPI, the Kerberos protocol is used to authenticate the user account.  This will attempt to access the Active Directory services of the domain that the user is logged into.  If that domain is not accessible, the authentication attempt will fail.  This check will only occur if SSPI detects that it is on a network.  If it's not on a network, it will use NTLM, which for our situation will work just fine.

In our case, the engineer has a laptop and he logs into it with a domain account.  If he's demoing the products at a clients site, he may have a network connection, but not be connected to our domain.  The immediate work around was for him to close his network connection and do his backup.  Literally all he needed to do was to press a button on his laptop to turn off his wireless adapter.

The long term solution will be for me to change conditions #3 or #4.  The code is currently hard coded to connect to a sever named "(local)", I may try replacing that with the TCP/IP loopback address 127.0.0.1.  If that doesn't work, I add a setting that allows the agent service to connect with the Shared Memory or Named Pipes providers.

Looking forward to stackoverflow

Not an actual stack overflow, but the new site, stackoverflow.com, run by Jeff Atwood and Joel Spolsky.  Their aim is to provide some sort of programming Q&A site.  Accurate and up to date information that's easy to find by having programmers ask questions and other programmers answer them.  I hope that they can pull it off.  My usual method of learning something programming related is by what Joel referred to as "page-fault" learning.  I start out with a Google or forum search, get the basics, and start implementing until I hit an error or a mental block.  Then I jump back on the Intertubes to research a little deeper.

I'm so tired of hitting Experts-exchange when I google a topic.  So much that I'll specifically exclude it from my Google searches by tacking on  "-site:www.experts-exchange.com" to the search string.  There's something about that site that just rubs me the wrong way.  it's like "We'll tease you with the question, now pay up for the answer".  And you'll have no way of knowing if the answer is correct or applicable to your need until after you have paid them.  No sir, I don't like it.

Right now, the only thing up on the site is a podcast of a conversation between Jeff and Joel.  I've been listening to it and it's pretty good.  I can't wait for the site to take form and I hope to be able to contribute to it in some small form.

Thursday, April 17, 2008

There's no privacy with infant video monitors

We still have a video baby monitor on our youngest, Laura.  She's 5, but we never got around to taking it down.  At bedtime, Laura and her older sister Kathryn will perform for each other in front of the camera while the other one is watching the monitor.

Last night when the girls went to bed, I turned on the monitor.  All I could see was static and some form of interference. The camera to monitor connection is wireless.  You can pick one of two channels and fiddle around with the antenna, but that's about it.  It's very much like watching TV on a B&W portable, circa 1976.

As I fiddled around with the antenna, the view on Laura's room disappeared and I could see an infant lying in a bed with a pacifier in his mouth.  I called out to my wife, "Look, they canceled the Laura Show and replaced it with a new one."  We think this baby is our next door neighbor's baby.  They just had a baby boy a couple of months ago.  I'm going to over and talk to them on the weekend and let him know that we are picking up their video signal.

For now, we have stopped using the monitor.  Laura is will past the age of needing a monitor, and it feels too much like voyeurism to be watching and listening to someone else's baby.  

Wednesday, April 16, 2008

Handy tip for debugging a Windows Service

Debugging a Windows Service is always a pain. You can't run a service like a regular application, you have to run it from Windows Service Control Manager (SCM) and then have your debugger attach to the process while it's running. The problem is that it's difficult to debug problems with the service startup as the debugger can't attach to the service in time.

I came across a tip on the .NET Tip of The Day site, "How to debug Windows Service startup". Basically, you just add a line that calls Debugger.Launch() or Debugger.Break() in your startup code. When your code hits one of those lines, the Visual Studio Just-In-Time Debugger dialog will be invoked and you can select your debugger to handle the error. That will allow you to continue along in the code and debug until the cows come home.

That works better than a service debugging tip I posted a couple of years back, calling the Sleep API in your startup code to allow enough time to attach a debugger to the service. That was a hack, this is much cleaner.

All in all, I still prefer to separate the functional code from the service specific code. I can then run that code from a desktop app, making it much easier to debug. That works about 99.9% of time. Every now and then, I do need to run the actual service code and the Debugger.XXXX() calls will make that task much easier.

Microsoft admits that KB 938371 kills USB Devices

Various reports on the Intertubes are reporting that Microsoft has acknowledge that last weeks Vista Update, 938371, has been causing "problems" with USB devices.  The money quote:

“We are aware of concerns that a recent Microsoft update may be causing problems with USB devices. We are investigating the matter, and at this time, do not have any information to share.”

Supposedly this was an update to fix a security hole in Windows Defender.  Read about more people hit by 938371 in MS's own forums.

This is starting to feel like an endless series of misadventures with 938371.  See Work around for KB938371 disabling HID-compliant input devices , KB 938371 woes continue and the first post, Vista update KB938371 disabled my mouse.

I just want to know when a permanent fix will be available.  Come on Microsoft, there is enough people reporting this problem that you should be able to reach out for more information to help diagnose and fix this problem.

Know your SQL Server version

There are times where you need to know what version of SQL Server is installed.  Usually you want to know which version and which service pack has been applied.  There have been a few isolated cases over the years where we saw bugs go away or significant performance boosts by merely installing the latest service pack.  It's less of an issue with 2005, but with SQL Server 2000, we wanted to make sure the user installed the latest service packs to block against stuff like the "Slammer" worm.

The following bit of T-SQL will send back the version information in easy to process pieces

SELECT SERVERPROPERTY('productversion') AS ProductVersion, SERVERPROPERTY ('productlevel') AS ProductLevel, SERVERPROPERTY ('edition') AS Edition

For SQL Server 2005, you could get back something like this:

ProductVersion  ProductLevel  Edition
--------------- ------------- ----------------
9.00.2047.00    SP1           Standard Edition

Which indicates the Standard Edition of SQL Server 2005, with Service Pack 1 installed.  You can also get most of that information with


select @@version


But you would have to parse out the version from a block of text like this:

----------------------------------------------------------------------
Microsoft SQL Server 2005 - 9.00.2047.00 (Intel X86)
Apr 14 2006 01:12:25
Copyright (c) 1988-2005 Microsoft Corporation
Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)

Using SERVERPROPERTY (2000, 2005 or 2008) is much easier than parsing that block of text.  To determine which version is running based just on the version number, Microsoft has a KB article that lists all of the releases under KB321185.

Sunday, April 13, 2008

Work around for KB938371 disabling HID-compliant input devices

After a few days of non-working mice, someone found a work around for KB938371. As I noted here and here, Vista Update 938371 disabled two the three mice I have I on my main home machine. Here's the work around that actually worked for me:

  • Just go to device manager -> HID-devices -> Unknown Device and search for drivers.
  • When prompted for how to search for driver software, select "Browse my computer for driver software"
  • Enter "C:\windows\winsxs" for the driver location and press the "Next" button.
  • If you get a popup saying "this is an unsigned driver...", just allow Windows to install the driver.

At this point, Windows should select the appropriate driver and your mouse will start working again.  When I tried this, only had one of the non-working mice plugged in.  When I followed those steps, the mouse started working.  I plugged the other mouse in and Windows enabled it without any prompting.

I went in to Device Manage and both mice were listed as "HID-compliant mouse" under "Mice and other pointing devices".  Just to be safe, I selected one the mice, right-clicked into "Properties, selected the "Driver" tab on the dialog that opened up.  I clicked the "Driver Details" button and the mouse was using mouclass.sys and mouhid.sys drivers, located in c:\windows\system32\drivers, which is what they were supposed to be using.

This tip was originally posted here and I came across it here.  I'm happy that I have my mouse functionality back, but how did this get past Microsoft's testing?  I saw too many people reporting this, it's not an isolated case.  I have a mouse that comes with my Wacom table that wasn't affected by this snafu, but what about the people who just had regular USB mice?  They were/are pretty much screwed by an update that can't be uninstalled with running System Restore. 

I still want to know what happened and why 938371 toasted my HID-compliant hardware.  Was there something broken already with my Vista installation and 938371 was just a symptom of the problem, or did 938371 actually break something?

I'm not allowing MS to automatically update my PC anymore.  That requires a certain level of trust that MS is going to push down updates that will be beneficial.  They just blew that trust.  I'll take the updates, but I'm going to decide if and when they get installed.

I was asked offline why I have three mice.  It's pretty simple (almost makes sense).  My day to day mouse is a Logitech MX™700.  It's a cordless mouse that uses rechargeable batteries.  It's been the best mouse that I have ever used and I continue to use it under Vista even though Logitech never ported the MX700 drivers to Vista.  It has a little dock that charges the batteries.  I almost always forget to put the mouse back in it's dock and a every few days, the batteries give out.  When that happens, I place it back in it's dock and use a Dell USB optical mouse while the MX700 is charging.   The third mouse is a digitizer mouse that comes with my Wacom Bamboo Fun tablet.  That mouse works, but only on it's little pad.  It was OK enough to use while tracking down this problem, but I wouldn't want it to be my everyday mouse.

Update: 2/22/2010
I repaved this machine with Windows 7 about 6 months ago and replaced the MX700 with a Logitech mouse that is supported under Windows 7.  For anyone that is still having this problem, consider Windows 7.  It’s much nicer than Vista.

Friday, April 11, 2008

KB 938371 woes continue

I still haven't been able to fix the problem that I reported yesterday.  After blogging about how Vista update KB 938371 disabled the mouse on my PC, I have found other people reporting the same problem.  The mouse shows up in the Device Manage as "unknown device".  If I try to install a device driver for it, it fails with the error dialog "Found New Hardware - Unknown Device) and displaying the following text:


Windows encountered a problem installing the driver software for your device

Windows found driver software for your device but encountered an error while attempting to install it.

     HID-compliant device


An error occurred during the installation of the device

The driver installation file for this device is missing a necessary entry.  This may because the INF was written for Windows 95 or later.  Contact your hardware vendor.

This occurs with any USB port on my machine and with both of my mice.  I have a Logitech wireless mouse and a basic Dell USB Optical mouse.  I have a mouse with my Wacom tablet that still works.  It has it's own drivers and MS didn't touch them.  I even took the Microsoft Optical mouse off my wife's Vista machine (which is working fine with 938371) and plugged into my machine.  It didn't work either.

If I do a System Restore and rollback to the point just before 938371 was installed, the mice work.  As soon as I install 938371, I lose the mice. This is really frustrating as 938371 is a prerequisite for SP1.

I've been posting this tale on a new message boards and blogs.  I'm not the only person having the problem, but we have yet to identify what we have in common that is triggering this.  My machine is running Vista Home Premium, 32-bit, on an ASUS M2N-SLI Deluxe motherboard. The M2N is NVidia NForce based and I have an AMD Athlon X2 processor in it.  You can read about other peoples symptoms in this MSDN Forum thread,  this thread I started on an NVidia fan site, and a message that I posed in the Windows Vista Blog.

Thursday, April 10, 2008

Vista update KB938371 disabled my mouse

Windows Update just pushed down an update, KB938371 on to my main home PC, as a prerequisite for Vista Service Pack 1.  After that update was installed and Vista rebooted, I lost all mouse functionality.  The only way I could get mouse functionality back was to run System Restore and restore the OS to the point to just before 938371 was installed.  For me, selecting the recommended restore point was as far back as I needed to go.

I have installed 938371 twice now by itself, each time I lose mouse function.  My machine was custom built for Visa Home Premium, but it uses a pretty standard motherboard, an ASUS M2N-SLI Deluxe, which uses the NVidia NForce chipset.  I have a Logitech MX™700, which uses the Vista input drivers and mouse that comes with the Wacom Bamboo Fun tablet, which has it's own Vista drivers.  I also have Dell USB mouse which I use when I'm recharging the batteries in the MX700.  None of them worked after 938371 was installed.  I think it would be a fair assumption that other features are broken, but I didn't bother to check.  The machine was unusable without a working pointing device, I concentrated my efforts on rolling back 938371.

938371 is an non-removable update.  It wont show up in the "Uninstall or change a program" list under "Control Panel\Programs and Features".  System Restore is the only way that I know to yank it out.  I don't think I'm only one having this problem.  I posted a message about this on an NVidia enthusiasts board and saw an immediate reply on this blog as a comment to a non-related post.

Service Pack 1 for Vista is out now and it requires 938371 as a  prerequisite.  Which means I can't install SP1 without running a mouse killing update.  I'm trying to decide if I can install SP1 and hope for the best.  If it fails, I'm without a pointing device and makes Windows somewhat less than usuable.  I would prefer to resolve 938371 before installing anything else.  The advantage of trying SP1 would be that Microsoft is providing free support for SP1 and this is definitely a SP1 support issue.

This could be the final straw that pushes me back Windows XP.  After using Vista for nearly a year, I'm tempted to repave with XP.  I have another Vista box at home that the family shares.  It's a Dell and while it has less functionality (my box has RAID 5), it has had any of the weird Vista problems that this machine has had.  I do wonder how many other people have had their mice disabled by this update.  If we can discover what we have in common, we get closer to determining what the root cause is and what fix there may be.

[Updated on 4/17/08]
If this is your first visit to my blog, please read this post for a work around that may work for you.

Monday, April 07, 2008

Fun with CoInitialize

I was tracking down a error in one of the command line apps that I use to save web.config settings over upgrades.  It was a strange error, If I stepped through the code, everything executed correctly, but I would get an access violation when I left a specific method call.  The fun part was that all of the code in that method call executed normally.  The app is written in Delphi 2007 and is Win32 unmanaged code.  The code looked something like this:

function TSaveConfig.UpdateWebConfig(const srcfile, destfile: string): boolean;
var
fsrcDoc, fDestDoc: IXMLDocument;
begin
CoInitialize(nil);

result := true;

fsrcDoc := LoadXMLDocument(srcFile);
fDestDoc := LoadXMLDocument(DestFile);

UpdateNode(fsrcDoc, fDestDoc, 'configuration\system.web\httpRuntime', 'executionTimeout', '', '');
UpdateNode(fsrcDoc, fDestDoc, 'configuration\system.web\sessionState', 'timeout', '', '');

if fDestdoc.Modified then begin
fDestdoc.SaveToFile(DestFile);
end;

CoUninitialize;
end;



Not much to it.  My Spidey sense started tingling at the calls to CoInitialize/CoUninitialize.  CoInitialize is needed to initialize the COM library on the current thread.  And COM is needed because I am using MS XML COM objects to work with the web.config files.  I was initializing COM, using COM, then uninitializing COM.  The problem was that I was using interfaces to the COM objects and Delphi is managing the lifetime of interfaces.  At the end of the method call, those objects go out of scope and Delphi calls their cleanup code.  In my case this happens after the the call to CoUninitialize.  My IXMLDocument interfaces were being garbage collected by the Delphi runtime and they were referencing a COM library that had been already closed.


In this case, the fix was easy.  I just moved the calls to CoInitialize/CoUninitialize to the code that calls UpdateWebConfig.  Once I did that, my odd little access violation was fixed.  That's one of those bugs that seems obvious after you fix it.  What clued me in to what was going on was a post by Chris Bensen that explained it all.  Thanks Chris!

Thursday, April 03, 2008

Wireshark reaches 1.0

Image:Wireshark Icon.svg

It looks like Wireshark has made it to version 1.0.  Wireshark has been my favorite tool for diagnosing TCP problems in the socket code that I have worked on.  I've been using it since it used to be called Ethereal®.  Wireshark is a free an open source packet sniffer.  If you are trying to see what is coming over the wire, you want this tool whether you are running Windows, Unix, Linux. or Mac.

Tuesday, April 01, 2008

Saving application settings over installs

We have been using Windows Installer (WI) based setups for all of our newer applications.  I used to use Wise, but I have migrated our installers to InstallAware.  Why I made that change will be another blog post, but needless to say I had very good reasons to make the switch.  When we release a new version or upgrade for one of our applications, we do full installs.  We don't do patches.

WI technology supports the distribution of patch files.  If you are only updating one or two files, the patch file will only contain what has changed, greatly reducing the size of the installable bits needed to be distributed.  I did use patch files when I first started doing WI based setups, but I abandoned the practice early on.  Patches were hard to automate as part of the build process and they had to account for cumulative changes.  The other drawback was that they could add files, but not remove them.  Another drawback was that it yet another file extension, .msp instead of .msi, to explain to the users.

I decide to have the installers upgrade in place. When a new version was installed over a previous version, the previous version would be silently uninstalled, then the new version would be installed.  This basically gives you a clean slate per install, which is great because you only install the files that are needed and the dependant objects will be up to date.  The bad part is that the user settings will be removed as part of the previous versions uninstall.

What I needed to do was to persist the user defined settings.  Consider a web application, if all of the settings are in the web.config file, then you just need to keep that web.config file around.  The simple solution is to tell the installer not to delete that file on the uninstall.  There's a couple of problems with that approach.  The first one is that the new install is a full install and the user gets to pick the destination.  They may want to put the web application in a different folder or drive and I didn't want to take that option away just to make my job easier.

The other drawback was far more serious.  I could keep the web.config around between installs, but what if the new version added content to the web.config file?  You don't want to save the old settings and lose the new settings.  That could cause hard to diagnose bad things to happen.   What was needed was the ability to merge selected content from the old web.confile and into the new web.config.  You can do many things with WI technology and InstallAware provides powerful functions, but this is a task best left outside the installer code.

I decided to write a Win32 command line app that would be able to save the old web.config and merge selected values from that file into the new one.  The installer would be include that file and be able to run it without permanently installing it.  I could have used C# with .NET (and I even had most of the code already written), but I didn't want to deal with .NET security issues or make the .NET Framework a prerequisite for non .NET based installs.  Delphi 2007 provided everything that I needed.

From the installer, I call this app just before the previous version is uninstalled with a command line parameter to designate which app is being installed.  It will locate the current web.config file for that application and copy it to a folder in the user's temp directory.  I always have our installers write the location of the install folder to the registry, it makes tasks like this much simpler.  After the new version has been installed, I run the app one more time, with a "-restore" command line parameter.  It locates the cached copy of the old web.config and the new web.config and updates the new web.config file with the settings that need to be persisted across installs.  Once that task is complete, it removes that temporary folder.

The app knows what settings to use from rules encoded into the source code.  I could have used a file to store a list of settings to persist, but that would have made the installer a bit more complicated.  It's fairly easy to run an app from the installer without actually installing it, but if you want it to have it read an external file, then you need to make sure that file is in a place where it can be read from.  That comes one more part of the installer to be tested and the mechanism for handling that would be specific to installer tool used.  By making the app contain the rules it needed to follow, running it from the installer becomes a trivial task.

The other advantage of having a separate app to handle to the saving of the user settings is that the code is much easier to test and debug.   It becomes a modular piece of the install and can even be unit tested in a scriptable manner.  This type of code can be easily adapted to the types of application.  I use a similar type of program to persist settings and current run start for some of our Win32 service applications.

Sunday, March 30, 2008

Playing with Firefox 3 Beta 4

I've pretty much standardized on Firefox as my default browser (but not the default Windows browser).  I had been an Opera bigot for years, but the tipping point was when Google released their browser sync addin that made it easy to keep my bookmarks and other settigns in sync between work and home.

I've been hearing good things about the latest beta (beta 4) of Firefox 3, so I have decided to give it a shot.  I found a good article for running Firefox 3 in tandem with Firefox 2 on the Hack-A-Day site, so it seemed safe to run them together.  My first impression is that it's fast, much faster than Firefox 2 and probably faster than Opera.  Faster is good, I look for things to make me go and this is one of them.

Our Google Overlords have not updated the Google Browser Sync addin to work with Firefox 3.  There have been quite a few requests for Firefox 3 support, I'm surprised that company known for keeping products in beta for years isn't supporting the Firefox 3 beta.

I decided to take a look to see if anyone else had a browse sync that supported Firefox 3.  As it turns out, Foxmarks has a beta that supports the Firefox 3 beta.  I installed into my Firefox 2 and Firefox 3 installations and synced my Firefox 2 bookmarks up to the Foxmarks server.  I then tried to sync up from Firefox 3 and it repeatedly crashed.

I assumed that it was a fault of the Foxmarks plugin, so I took a look around their site.  On their wiki, I read the following:

On initial sync (or regular sync of large change sets), Firefox sometimes crashes. (We believe this is a Firefox bug; if you experience this, please make sure you allow Firefox to submit a crash report to Mozilla.) [This is an open bug in Firefox being investigated by Mozilla.]

It indicates that it's a Firefox bug and I have a work around.  Since Firefox 3 is puking on large change sets, the solution is to reduce the size of the change set.  I synced up Firefox 2 and then exported the bookmarks to a file.  I then imported that file into Firefox 3 and it was able to sync up changes after that.

Another addin that I like is GMail Manager, and it too doesn't support Firefox 3.

Friday, March 28, 2008

When will the Visual Studio IDE catchup to the Delphi IDE?

Sometimes it just the little things that annoy you.  If I add a button to a Delphi form, by default it is named Button1.  If I double click on Button1, a Click event handler is added and is named Button1Click and wires it up to the button's OnClick event.  Visual Studio does pretty much the same thing.  Where they is differ is when you edit the button's name.

If I renamed Button1 to something more meaningful like DestroyAllMonsters, the Delphi IDE will rename the event handler to DestroyAllMonstersClick.  When you rename the button in the Visual Studio IDE, it doesn't touch the event handler.  That's annoying.

Another difference is how Delphi handles event handlers when your delete the code or never add the code.  When you double click on the button and get the new event handler automagically created and wired up to the control, that event handler has no code.  If you save that file, Delphi removes the event handler.  it does under the assumption that you didn't mean to have that event handler and it will clean up the code for you.  Like wise, if you delete the code out of the handler and save the file, Delphi will remove the handler. 

This makes it easy to cleanup code when you remove a control that you didn't really want or need any more.  Visual Studio doesn't do that for you, or least not in C#.  When you spend your day working in both IDE's at the same time, those types of annoyances really can be annoying.

Wednesday, March 26, 2008

Miss Bimbo is not welcome in my house

There have been a few articles posted on the Internet about a web site called www.missbimbo.com.  It's supposed to be fashion game for young girls, but it sounds pretty trashy.  It's aimed at girls between the ages of 9 to 16 and it purports to be a virtual fashion games.  It's widely condemned as the users are encouraged to compete against each other to become the "hottest, coolest, most famous bimbo in the whole world." by buy chest implants.  CNN had a good write up of it and here's a direct quote:

The provocatively named "Miss Bimbo" Web site launched in the UK last month and is described as a "virtual fashion game for girls."

Girls are encouraged to compete against each other to become the "hottest, coolest, most famous bimbo in the whole world."

When a girl signs up, they are given a naked virtual character to look after and pitted against other girls to earn "bimbo" dollars so they can dress her in sexy outfits and take her clubbing.

They are told "stop at nothing," even "meds or plastic surgery," to ensure their dolls win.

Users are given missions, including securing plastic surgery at the game's clinic to give their dolls bigger breasts, and they have to keep her at her target weight with diet pills, which cost 100 bimbo dollars.

Breast implants sell at 11,500 bimbo dollars and net the buyer 2,000 bimbo attitudes, making her more popular on the site.

And bagging a billionaire boyfriend is the most desirable way to earn the all important "mula" or bimbo dollars.

As the father of two girls aged 7 and 5, I'm appalled by the site and I'm not going to let them anywhere near it.  We have a family PC that girls can use and we do let them visit certain sites on the Internet.  I've already taken steps to prevent them from seeing that site in our household.  I've been a fan of OpenDNS.org for a couple of years for their speedy DNS lookups.  OpenDNS has the ability to do some basic filtering and it's trivial to get it to block entire domains.  I just logged into my OpenDNS account and added missbimbo.com as a blocked domain. 

If you have never heard of OpenDNS, it's a free service that does speedy DNS lookups.  When you type in www.cnn.com into your web browser, a DNS server takes that domain name and converts it to the actual IP address of the site so that it can loaded into your browser.  Your Internet provider usually provides their own DNS servers, but OpenDNS has faster ones.

I'm probably overreacting and my girls will never even hear of that site, but it doesn't hurt to be safe.

Tuesday, March 25, 2008

Enabling users with ESX 3.5.0

I've been playing admin on our shiny new ESX server and it's been a struggle trying to get the user accounts configured.  I wanted to give our QA staff enough rights to login through the VMware Web Access portal so that they could start and stop their virtual machines.  I figured I would just set up their accounts and put them in the "Virtual Machine User" role.  No of the accounts could login in.  They kept getting the dreaded "Login failed due to a bad username or password."

I dug around a bit and started searching the VMware forums.  Apparently everyone was using AD to authenticate their user accounts.  I wasn't planning using AD because we are going to be changing domains in the near future, but I figured nothing else was working, it couldn't hurt.  This message led me to a very useful post by Geert Baeke on how to integrate Active Directory with ESX 3.   There was a lot of useful stuff in that post, but the part that I needed came down to this:

esxcfg-auth --enablead --addomain=domain.com --addc=domain.com


The VMware document uses the FQDN of a domain controller for the --addc parameter, but you can use the FQDN of the domain. That way, DNS is used to find domain controllers and use one of those. The command above modifies a few files like /etc/krb5.conf and also the system-auth file in /etc/pam.d. The ESX firewall is also automatically configured to open the needed ports for AD authentication.

Before you can logon with an AD account, you need to create a console user on the ESX box that has the same name as your AD account. For example, if you have an AD account domain\esxadmin, you need to add a user to the ESX console called esxadmin. The command to use is useradd esxadmin. You can also use VI Client to create the user. You can now logon with the account and use the AD password. I tested this with ESX 3.0.1 servers against Windows 2000 and Windows 2003 domains and it worked as advertised.

I did it and it worked like a charm.  Life is good.

Monday, March 17, 2008

Link rot and the ascendance of Wikipedia

As usual, Steve Tibbets hits the nail directly on the head with his post about link rot and Wikipedia.  I would have to say that the domain that I link to the most would have to be Wikipedia.  Most of the time I dot it because it's convenient, but link rot (there!  I just did it) happens a lot. 

Microsoft is pretty bad at this.  There have been too many times where I tried to follow a link into the MSDN, only to find that the MSDN has been reorganized and all of the links have changed.

If I link to another blog, I look for the permalink.  That usually indicates that the link will be around for a while.  I also try to find links on multiple domains.  That way, the odds are less likely that you will get the dreaded 404 page when you follow a link that has rotted away.

Steve posting his rules for linking and they just make sense:

    • If what I’m linking to has a top-level domain, then I will link to it.
    • If I’m linking to someone’s words (say, a blog post or magazine article), then I will link to that.
    • Otherwise, I’m linking to Wikipedia.

Friday, March 14, 2008

Two of my favorite geek toys (PowerShell and VMWare) playing together

I can't wait to get the VI Toolkit for Windows.  It's PowerShell cmdlets that let you manage VMWare.  To get an idea of what you can do with PowerShell and ESX Server, check out the Automating VMware with PowerShell Lab Manual, from the VMworld Europe 2008 conference.  You will be able monitor the status of VM's on the ESX server and be able to control the VM's remotely.  I'm curious to see of you would be able to take a running VM offline and move it to a storage volume.  That would make my life easier.

The VI PowerShell Blog mentioned that the VI Toolkit will be Beta this month, I can't wait to get a hold of it.

Tuesday, March 11, 2008

The Lost Art of TSR Programming

Scott Allen had a amusing post, "Talks You Won’t See At the Local Code Camp", on his blog.  One of the talks was "The Lost Art of TSR Programming".   That shook some memories out of the cranial storage device.  I used to write TSR programs, more formerly known as Terminate and Stay Resident.

This takes back to the days of DOS, when giants like dBase and Lotus walked the land.  Your network was Novell and you feared the Bindery.  You could only run one program at a time and the 640K limitation was real and not just a saying commonly misattributed to Bill Gates.

When I was at Stochos, we wrote software to do statistical process control (SPC) in the manufacturing industry.  We would collect data from measurement devices or from the manufacturing hardware to monitor the process of making whatever was running.  Back in the late '80s, we had hardened PC's running DOS and our software right on the factory floor.  One of my tasks was to write the code to collect the data from the machines and get it into the PC.

Early on, I had decided that the data collection code would run separately from the SPC application.  This allowed the user to exit our app to run other apps while still collecting data.  The way I did that was to write the data collector as a TSR.

The whole TSR section of DOS programming was pretty much an accident.  The DOS print spooler gave DOS the ability to print in the background while your application was running.  The print spooler was the first TSR.  A TSR would load itself using INT 27H to make itself as a TSR type of programming.  Once loaded, the TSR would typically insert itself into the chain of the applications that would receive hardware and/or software events.  If the TSR wasn't careful, it could wreck havoc with the interrupt chain.

I would write TSR's that would hook into the serial port or parallel port events.   Some of the time, all I needed to do was to capture data as it came in and write it to a file.  Usually, the hardware would have some sort of protocol and I would have implement it in my code.  One of the odder ones was for a machine that printed foil packets, the kind used for condiments at fast food restaurants.  This machine did not support the logging of it's data.  But I found a way in.  It had a PC that functioned as operator console with a color screen and keyboard.  Usually the screen would be displaying the current process settings and readings from it's own measuring devices, but not always.  The PC was connected to the machine over the serial port and was basically being used as a terminal.

I wrote a TSR that would periodically scan the screen in memory.  Since it was running in text mode, it's fairly easy to ready the screen from memory.  If I saw a certain sequence of characters at a specific location, I knew that I had the main console screen.  I then scanned different locations on the screen and wrote out a text file, logging each set of values as an attribute for our SPC application.

The TSR would read a template file that listed what attributes to look for and at what locations on the screen to expect the attributes at.  The setup of the template was done by trial and error, but once it was set the client never had to touch it.  It even allowed for character translation.  For some odd reason, the console display didn't use the number "0", they used the letter "O".  That took more time to track down then you would have expected.

To keep the size of the TSR down, I used a library named CodeRunner with Microsoft C.  The Coderunner library had the housekeeping code for doing the INT 27h stuff and interrupt managing.  It also took many of the standard routines and replaced them with hard coded assembler optimized for space over performance.  It also had the ability to run most of the TSR out of EMS memory, greatly reducing the footprint in the lower 640K space.  This particuliar TSR took about 6000 bytes of conventional memory.  I remember talking to Ratko Tomic, the engineer who wrote the CodeRunner libraries.  He was genius at squeezing every extra byte of the TSR code.  It's a lost art.

Monday, March 10, 2008

I like having a build box

This morning I came across a blog by Landon Dyer called Dadhacker.  He got linked by BoingBoing for a entertaining post that he wrote about working on the Donkey Kong cartridge for Atari.  I started reading his other posts and it turns out that I agree with nearly all of his opinions.  Except for build boxes. He wrote:

The best thing you can do for your productivity when you’re tempted to set up that spare machine to do extra work for you is to ditch the thing.

If you are the person only using that build machine, I can see that point.  Almost.  I would argue that it's worth the time to have a 2nd machine in case the first one goes to the land whre DOS is eternally blessed.  For a team of programmers, having a dedicated build box is a must have feature.  No more guessing which program set which option to build which executable, they always get built the same way.  Plus it offloads the build process processing from your development environment and that is always a good thing.

The other advantage to having a dedicated build box is that you have have it do everything.  We use FinalBuilder and it's the kitchen sink of automated build tools.  We build about a half dozen or so shrink wrap ready applications on our build box and they all pretty much follow the same pattern:

  1. Get the latest code from source control
  2. Read an .ini to get the version number and other test resources, the build tool will bake the version number into the compiler and install builder.
  3. Compile the application
  4. Collect all of the bits and put them in a folder for the install builder
  5. Authenticode anything remotely executable that we compiled
  6. Create the installer from all bits that were compiled in the last step and add the necessary required bits (CaptiveX controls, Assemblies, help files, etc).
  7. Copy the installer to a deployment folder for QA to test
  8. Send an email to QA and other interested parties that a new build was available and include a change list in the email.

There are other minor tasks that get performed, but that's the gist of it.  And it works for for Delphi Win32 and .NET assemblies, with error handling.  The time our department saves that level of build automation clearly outweighs the the maintenance time on the build box.

Thursday, February 28, 2008

Fun with changing the IP address of ESX Server 3.5

We (our IT manager and myself) have been having some fun with out shiny new VMWare ESX 3.5 server.  We have had it running for about two weeks now and we decided to change it's IP address.  The ESX server was on the same subnet as our LAN.  This meant that it the virtual machines were taking IP addresses out of a pool that was needed for our physical computers.  There were some other security issues, so we decided to put it on it's own subnet.

It was fairly easy to change the IP address address via the command line (this site helped a lot), the fun started with the NFS connection.  We are using NFS to mount a folder located on a Windows file server to add some offline storage for the ESX box.  To mount with NFS, you have to create a VMKernel in the ESX networking and the VMKernel gets it's own IP address.  That IP address must be on the same subnet as the NFS server.

When we moved the ESX to it's own subnet, we put it on it's own physical network and that broke the NFS connection.  We tried a few things and then we checked the Windows box that was running the NFS server.  It had two network cards.  The second one was not enabled, but fully functional.  We enabled it and set it's IP address to the subnet of the ESX box.  I had to drop and recreate the NFS mount, but it all worked.

While testing the networking, the IT manager was running one of the virtual machines (XP 64-bit) and set the network adapter in the VM to a static IP address.   It turned out he set it to the IP address of the ESX server.  That's when the fun started.  When you connected to the VM, ESX would lose it's connection and you lost control over ESX and the VM.  After a minute or two, you could access ESX through the VMWare Infrastructure Client, but you couldn't access the VM to change it's IP address.

We racked our brains trying to figure out how to get control of the VM to reset it's IP address.  The fix turned out to be really simple.  I powered down the VM from VIC and edited it's hardware settings.  I added a second network adapter (it's all virtual) and set the first one to be disconnected.  I powered the VM back up and the new adapter had a safe IP address.  I connected to the VM's console and opened up "Network Connections" in Windows.  The first adapter was enabled, but not connected.  I opened up it's properties and set it to grab an IP through DHCP.

I powered down the VM, removed the second adapter, and reconnected the first one.  I rebooted the VM and it had a new IP address.  Peace and harmony reigned through my virtual kingdom.

Tuesday, February 26, 2008

Just when I thought my SmugMug plugin was finished...

After tackling the Wix learning curve, I have an installer for my SmugMug plugin does usual things: check for .NET 2.0, install the files, add the registry key to register the plugin, and support upgrading in place.  One step closer to releasing this plugin for Windows Live Writer.

Meanwhile, over at SmugMug, a security issue of sorts popped up.  Don MacAskill, the CEO of SmugMug, blogged about it with great detail and openness and I'm not going into it here.  At any rate, in response to what was perceived to be a security, SmugMug is implementing some changes to their API.  The changes were fairly trivial to implement so it made sense to augment my plugin's code to be compliant with the updated API.

With their recent changes, I saw that my plugin was no longer displaying images for one of my test galleries, where it had worked before.  I spent a hour or so trying to track it down in my code, when the clue light finally flickered above my head.  I logged into my SmugMug account and examined the properties of that gallery. 

Sure enough, for that gallery, the "allow external links" option was set to "No".  This meant that even though my plugin would return valid URL's for the images in that gallery, SmugMug would send back a blank page for those URL's.  I augmented my call to get the gallery list to check the properties for each gallery and filter out the ones that did not allow external linking.

I thought that there would be performance hit for making a web service call for each gallery.  It wasn't really noticeable at all.  That's what I love about SmugMug, their API performance is damn fast.

At any rate, I was hoping to finally push this plugin out the door by now, but I'm going to take a few more days and beat on the code.

Thursday, February 21, 2008

I hate spam that comes in under my own name

For the last few weeks, I've been getting spam email addressed to my work account with the "from:" field set to my work address.  That allows it past our companies spam filters.  The subject line is usually something liken "January 79% OFF" and the message body contains a few images, some oddly worded links, and some boiler plate text about receiving this mailing because I am "subscribed to MSN Featured Offers".

The images are blocked by our central spam filter, which means they are being hosted on a known site for spamming.  I haven't verified that with our IT manager, but it's a safe assumption. 

I'm going to block this message at my email client (Outlook 2007), but first I'm going to send a message to the ISP that is hosting the machine that sent the email.  The first thing to do is to see where the images and links are pointing to.  With Outlook, if you right click in the body of the message and select "View Source", Outlook will create a file named email.txt and launches it with the app registered to handle text files.  That's usually notepad, but YMMV.

For this message, I saw something that looked very much like the spam that was reported to the new.admin.net-abuse.sightings newsgroup in this post.

Most of the links were junk, but there was a link to "s y l l a b l e h e a v y . c o m" (I added spaces to prevent it from being a live link and inflating it's Google ranking).

A quick search in the Internic registry brings up the following results:

   Domain Name: SYLLABLEHEAVY.COM
Registrar: XIN NET TECHNOLOGY CORPORATION
Whois Server: whois.paycenter.com.cn
Referral URL: http://www.xinnet.com
Name Server: NS.XINNETDNS.COM
Name Server: NS.XINNET.CN
Name Server: NS2.XINNETDNS.COM
Name Server: NS2.XINNET.CN
Status: ok
Updated Date: 19-feb-2008
Creation Date: 16-jan-2008
Expiration Date: 16-jan-2009

That tells us a couple of things.  One, the website is registered by a Chinese registrar.  Two, it was created about a month ago.  The next step is to track down the Registrar, Xin Net.  A quick search on Xin Net, gives us some more information:


Registrar Name: XIN NET TECHNOLOGY CORPORATION
   Address: 1st Floor,2nd Building Section A,BDA BeiGongD, Beijing, China 100176, CN
   Phone Number: 86.1058022118
   Email: domainadmin@xinnet.com
   Whois Server: whois.paycenter.com.cn
   Referral URL: www.xinnet.com
   Admin Contact: cody zhou
   Phone Number: +86.10.58.22266-551
   Email: tech@xinnet.com
   Admin Contact: xiaorui wang
   Phone Number: +86.1058022118-205
   Email: admin2@xinnet.com
   Admin Contact: Baosheng Jiang
   Phone Number: +86.1058022118-623
   Email: admin1@xinnet.com


 


This gives a whole bunch of email addresses to complain to.  What I did was to send a polite message to all of the addresses listed above.  I sent the following:



Hello,


Please excuse this unsolicited message, but I have been receiving numerous spam emails and they link to a site, syllableheavy.com, that you are listed as the registrar of.   This site probably violates your terms of service and I am sure that you do not want to be associated with it.    The message did not originate from that site, but it is using that site.


I then included the message header and the message source.  I doubt that they will do anything, but if they do take action, it takes a spam site offline.


The next thing to do is block additional messages like that. 



  • From the Outlook menu, I selected "Tools->Rules and Alerts" to create a new junk mail filter. 

  • In the "Rules and Alerts" dialog, I clicked "New Rule...". 

  • Under "Start from a blank rule", I selected "Check messages when they arrive", and then clicked the "Next" button.

  • Under "Which condition(s) do you want to check?", I selected "with specific words in the sender's address"

  • For the "with specific words in the sender's address", I entered my address.  I rarely send myself email from my work account.  When I do, Exchange just uses my first and last name, not the SMTP address.  Then I clicked "Next"

  • Under "What do you want to do with this message", I selected "move it to the specified folder" and "mark it as read".  I selected "Junk E-mail" as the selected folder.  I then clicked the "Next" button.

  • I clicked the "Next" again to skip over the exceptions to this rule.

  • I gave it a name and set the checkboxes to run it on messages already in the inbox and to enable the rule and clicked finish.

  • Clicked "Apply" and then"OK" and we are done.

That will permanently take that style of junk mail out of my in box.  I didn't permanently delete the message.  About once a week, I take a quick peek in the junk e-mail folder just in case a false positive hit grabs a legitimate email.

Saturday, February 09, 2008

Nvidia nForce network driver problem under Vista

On my home machine, I rarely reboot it. If a software update requires a reboot, then I do it. otherwise it stays running for weeks at a time. Vista (32-bit) has been stable enough for me, where I don't have to start the system or suffer system crashes.

But when I reboot, about 10% of the time (just a wildly inaccurate guess), the machine comes up without any network connectivity. In the past, I have associated it with Windows Update installing a wonky driver for the network card and I System Restore the machine back to normal. It happened today and the list of the usual suspects did not include any hardware updates. Time to dig deeper.

This machine has a NVidia nForce motherboard (Asus M2N-SLI Deluxe) and it has built-in dual Gigabit LAN controllers. I had an Ethernet cable hooked up to the first port and had disabled the 2nd one through Vista's "Network Connections" utility. My dead Windows Home Server box was next to my PC, so I unplugged it's Ethernet cable and plugged it into the second port on my machine. I enabled the network adapter and after a few seconds, it was live and had grabbed a IP address from router.

That was interesting. Since the working adapter used the same driver as the non-working one, that pretty much ruled out Windows Update nuking one of the drivers. I peeked at the driver settings for both adapter, they were both set to the defaults. I also checked the device status of the adapter, Windows reported that "This device is working properly." That was a pretty good indicator that the problem was not a fried controller on the motherboard.

The next thing to check was the ethernet cable. I swapped cables and there was no change. I decided to do the Nintendo fix. That's when you pull out the cartridge, blow on the connectors and ram it back in again. In this case, I disabled the adapter, waited 30 seconds, and re-enabled it. As Emeril says, Bam! The adapter started working. Time to start googleing and see if anyone else is having this problem.

And the number one hit for "nforce network adapter fails" in Google was a long thread in the Nvidia message forums. A sizeable number of people were having the same problem and they were all running Vista. It may be a timing issue during boot-up. Two workarounds were suggested. One was to change the duplex setting from "Full Autonegotiation" to "100 Mbps Full Duplex". The other was to change the priority order of the network adapter priority. I didn't want to mess with the driver settings, so I opted for changing the priority order. I'm not confident that it will fix the issue, but it wont hurt anything. Right now this is more of an annoyance than anything else, but I would like to resolve it permanently.

Sunday, February 03, 2008

Using Wix for my Live Writer Plug-in

I finally have version 1 of my Smugmug gallery plug-in completed. The next step is to do the installer. To get a plug-in up on the Windows Live Gallery, it must have an installer that meets the requirements on the Gallery Developer Center page. A content plug-in has to meet these requirements:

  1. Content Plugins must be built using either the .NET 1.1 or .NET 2.0 frameworks.
  2. Content Plugins must be packaged and submitted as a Microsoft Installer (*.msi).
  3. If you use the .NET 2.0 framework, the installer must link to the .NET 2.0 download site or use the Visual Studio 2005 Bootstrapper. The Bootstrapper detects and downloads the correct .NET 2.0 framework.
  4. Your installer must copy the assembly to the "Plug -ins" sub-directory of the Windows Live Writer installation directory.

I have #1, my plug-in uses the .NET 2.0 framework. Number 2 is that it must be packaged using a Windows Installer .msi setup. I'm still figuring out the best way how to implement #3, but I'm not sweating it. With #4, I'm not doing it that way. The alternative method is to install the plug-in in your own folder and write a registry key to Software\Windows Live Writer\PluginAssemblies (HKLM or HKCU) with the name of your plugin and the path to it. That way you don't have to worry about where Live Writer was installed to. In fact that page is probably obsolete, there is an MSDN article that covers the registry method.

Let's start with the .msi requirement.

I looked that the "Setup Project" template in VS 2008. Um, no thanks. After 30 minutes of playing with it, I started getting annoyed. It felt awkward and non-intuitive. Granted, most things with Windows Installer are awkward and non-intuitive, but I couldn't get fast handle on "Setup Project" template. It was easy enough to get the files installed, but getting the registry written correctly was a task I just couldn't figure out. After two years of doing .msi with Wise For Windows and now InstallAware, I have a pretty good idea of an .msi is supposed to work.

I decided to knock out an setup with InstallAware. It took about 5 minutes and worked perfectly. But it was 1.2 MB in size. That seemed excessive to deploy 45K for two assemblies. Frankly any installer will be excessive, but I have to follow requirement #2. I have lots of love for InstallAware and it's my tool of choice for application installs, but it still bothers me to have a setup that 26 times larger than the files being deployed.

With VS's "Setup Project" and InstallAware out of the picture, I decided to check out WiX. WiX stands for WIndows Installer XML and is an open source toolkit for building .msi setups from an XML source file. The current version, 3, installs nicely into VS 2008. It installed so nicely, I didn't need to be concerned with how to run the Candle (the WiX compiler) or Light (the WiX linker). There is also a .msi decompiler, named Dark. It will emit Wix source code from a .MSI or .MSM file.

WiX source code is pretty intimidating when you first look at it. if you have no experience with authoring Windows Installer, it will be hard to grasp at first. The WiX site has a nice tutorial, but it's for version 2 and uses syntax that's deprecated in version 3. Fortunately, I was able to google the differences and I was able to get a working installer in about an hour. It's not handling step 3 completely, but it is terminating the install if .NET 2.0 is not available.

The size of the .msi is much smaller, about 220k. Still way too large, but it's as about as small as I'm going to get for a .msi file. So far, I'm very impressed with WiX. Once you start getting the hang of the syntax, it's very clear on how to setup a proper .msi file. There's even a open source editor called WixEdit. I didn't need it for this task, but I think I make take at peek at it at another timer.

Enough people are using it so that I was able to google for the bits I needed. Morten Lyhr had a great post on how to detect the .NET Framework. I figured out how to write the registry key from a post by Chris Jackson. Bonnie (one of the Live Writer developers) had a good sample WiX file for installing a plug-in. While I didn't follow her pattern, it did give me a tour of the neighborhood. Mike Stall has a good post that covers the basics. I think I need to spend some time reading the blogs of the WiX developers, they have a build a really cool tool.