iTunes web site and Google Chrome on Microsoft Windows – Part II

Ok, my first attempt (see my previous post on this) at this was a little “programmy” and “hacky“. It also appears that Apple changed the itmsCheck.js JavaScript code and no longer set the iTunesPresent cookie as they did before. Apple still doesn’t recognize Google Chrome as one of the browsers or platforms on which they will automatically attempt to load iTunes from web pages. To overcome this issue I searched for a Google Chrome extension that could be configured to use a Safari Macintosh User-Agent string whenever browsing a web page in the domain. I found User-Agent Switcher for Chrome which did the trick! Below is a screenshot of the configuration screen for User-Agent Switcher. I added a setting telling the software to use the pre-configured Mac Safari user-agent string for any web page in the domain.

I am now able to automatically have Chrome load iTunes whenever I click on iTunes Preview link such as the one below.

iTunes web site and Google Chrome on Microsoft Windows

Here’s proof that Apple’s iTunes web site doesn’t natively recognize Google Chrome for automatically launching the iTunes application from the iTunes web site. Below is a screen capture of the source code used by the iTunes web site to detect the presence of the iTunes software on the PC accessing the iTunes web site. The JavaScript function used to detect iTunes is called “iTunesDetected” and will only return TRUE if any of the following are true:

  • the browser’s user agent string contains the word “Macintosh”
  • the browser is Internet Explorer and the iTunes ActiveX component installed
  • the browser is Firefox and the iTunes Mozilla plugin is installed
  • an iTunes cookie named “iTunesPresent” set to true in the domain of the Apple web site visiting or in “”

iTunes web site JavaScript that excludes Google Chrome

The $64 question now is what’s the best way to get the “iTunesPresent” cookie set in domain “”.

My first thought was to configure Chrome to use a user agent string containing “Macintosh” and then launch iTunes from the iTunes web site once thereby setting the cookie.

Chrome using Macintosh/Safari User Agent String

I was perplexed when this didn’t work. Using the built-in debugger in Chrome I proceeded to set a break point in the iTunesDetected function and then single stepped through the function to see what was happening. Even thought I had set my user agent string to “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_3; en-us) AppleWebKit/525.19 (KHTML, like Gecko) Version/3.2.1 Safari/525.19” using the Chrome command line switch “–user-agent=” debugging showed me that “navigator.agentString” was still set to the default Chrome UAS.


At this point I decided to take the sledgehammer approach. I navigated Chrome to the following url: and after receiving the error that iTunes wasn’t installed I set a break-point in the JavaScript that tested whether iTunes was “installed”.


I then reloaded the page and after the breakpoint triggered, I changed “iTunesDetected()” to “true” and began to single step through the code. Once I entered function “its.cookies.setUnescaped” I proceeded to change “if (domain)” to “if (true)” and hard-coded the setting of domainString to ”” (see lines 216 and 217 below).

How to force creation of iTunesPresent cookie in domain

I then let the script continue by pressing the run pause-run buttonbutton.

My PC now contains the iTunesPresent cookie in the “” domain which now allows me to automatically launch iTunes from web pages on the iTunes web site using Google Chrome.

iTunesPresent cookie

Why Apple doesn’t directly support Google Chrome remains a mystery to me. I understand that Google Chrome is a competing product to Apple’s Safari browser, however, I am confident that Apple will make far more revenue from the iTunes store by making the user experience of iTunes best-in-class using any platform or browser.

Using WinDBG to troubleshoot Windows BugCheck 9F – DRIVER_POWER_STATE_FAILURE

Microsoft (R) Windows Debugger Version 6.11.0001.404 X86
Copyright (c) Microsoft Corporation. All rights reserved.Loading Dump File [C:WindowsMEMORY.DMP]
Kernel Summary Dump File: Only kernel address space is available

Symbol search path is: SRV*c:websymbols*
Executable search path is:
Windows Server 2008/Windows Vista Kernel Version 6002 (Service Pack 2) MP (2 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 6002.18267.x86fre.vistasp2_gdr.100608-0458
Machine Name:
Kernel base = 0x82036000 PsLoadedModuleList = 0x8214dc70
Debug session time: Wed Aug 11 18:35:44.648 2010 (GMT-4)
System Uptime: 0 days 4:19:37.181
Loading Kernel Symbols
Loading User Symbols

Loading unloaded module list
* *
* Bugcheck Analysis *
* *

Use !analyze -v to get detailed debugging information.

BugCheck 9F, {3, 8491b970, 86a02030, 8556dbf8}

*** ERROR: Module load completed but symbols could not be loaded for appliand.sys
Probably caused by : appliand.sys

Followup: MachineOwner

0: kd> !analyze -v
* *
* Bugcheck Analysis *
* *

A driver is causing an inconsistent power state.
Arg1: 00000003, A device object has been blocking an Irp for too long a time
Arg2: 8491b970, Physical Device Object of the stack
Arg3: 86a02030, Functional Device Object of the stack
Arg4: 8556dbf8, The blocked IRP

Debugging Details:


IRP_ADDRESS: 8556dbf8



IMAGE_NAME: appliand.sys


MODULE_NAME: appliand

FAULTING_MODULE: 8f585000 appliand





LAST_CONTROL_TRANSFER: from 820673fb to 82103b8d

8212bacc 820673fb 0000009f 00000003 8491b970 nt!KeBugCheckEx+0x1e
8212bb28 82067018 8212bb94 8212bc50 82144401 nt!PopCheckIrpWatchdog+0x1ad
8212bb68 820e030b 821444e0 00000000 8952e4aa nt!PopCheckForIdleness+0x343
8212bc88 820dff41 8212bcd0 44b95302 8212bcd8 nt!KiTimerListExpire+0x367
8212bce8 820e0635 00000000 00000000 000f3c82 nt!KiTimerExpiration+0x2a0
8212bd50 820de89d 00000000 0000000e 00000000 nt!KiRetireDpcList+0xba
8212bd54 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x49



FAILURE_BUCKET_ID: 0x9F_IMAGE_appliand.sys

BUCKET_ID: 0x9F_IMAGE_appliand.sys

Followup: MachineOwner

0: kd> !devobj ffffffff86a02030 f
Device object (86a02030) is for:
NDMP24 DriverappliandMP DriverObject 86cf4e08
Current Irp 00000000 RefCount 0 Type 00000017 Flags 00002050
Dacl 8b65d048 DevExt 86a020e8 DevObjExt 86a02c70
ExtensionFlags (0x00000800)
Unknown flags 0x00000800
AttachedTo (Lower) 8491b970 DriverPnpManager
Device queue is not busy.

0: kd> !drvobj ffffffff86cf4e08 f
Driver object (86cf4e08) is for:
Driver Extension List: (id , addr)
(4e4d4944 86d07010)
Device Object list:
8659e030 869f7360 868d3030 868d2030
86a02030 86a01030 87055030

DriverEntry: 8f58c2d3 appliand
DriverStartIo: 00000000
DriverUnload: 8275ca0e ndis!ndisMUnload
AddDevice: 8275605a ndis!ndisPnPAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE 8267ce79 ndis!ndisCreateIrpHandler
[01] IRP_MJ_CREATE_NAMED_PIPE 8274a78c ndis!ndisDummyIrpHandler
[02] IRP_MJ_CLOSE 8267d309 ndis!ndisCloseIrpHandler
[03] IRP_MJ_READ 8274a78c ndis!ndisDummyIrpHandler
[04] IRP_MJ_WRITE 8274a78c ndis!ndisDummyIrpHandler
[05] IRP_MJ_QUERY_INFORMATION 8274a78c ndis!ndisDummyIrpHandler
[06] IRP_MJ_SET_INFORMATION 8274a78c ndis!ndisDummyIrpHandler
[07] IRP_MJ_QUERY_EA 8274a78c ndis!ndisDummyIrpHandler
[08] IRP_MJ_SET_EA 8274a78c ndis!ndisDummyIrpHandler
[09] IRP_MJ_FLUSH_BUFFERS 8274a78c ndis!ndisDummyIrpHandler
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION 8274a78c ndis!ndisDummyIrpHandler
[0b] IRP_MJ_SET_VOLUME_INFORMATION 8274a78c ndis!ndisDummyIrpHandler
[0c] IRP_MJ_DIRECTORY_CONTROL 8274a78c ndis!ndisDummyIrpHandler
[0d] IRP_MJ_FILE_SYSTEM_CONTROL 8274a78c ndis!ndisDummyIrpHandler
[0e] IRP_MJ_DEVICE_CONTROL 8274b0a7 ndis!ndisDeviceControlIrpHandler
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL 8274a78c ndis!ndisDummyIrpHandler
[10] IRP_MJ_SHUTDOWN 8274a78c ndis!ndisDummyIrpHandler
[11] IRP_MJ_LOCK_CONTROL 8274a78c ndis!ndisDummyIrpHandler
[12] IRP_MJ_CLEANUP 8274a78c ndis!ndisDummyIrpHandler
[13] IRP_MJ_CREATE_MAILSLOT 8274a78c ndis!ndisDummyIrpHandler
[14] IRP_MJ_QUERY_SECURITY 8274a78c ndis!ndisDummyIrpHandler
[15] IRP_MJ_SET_SECURITY 8274a78c ndis!ndisDummyIrpHandler
[16] IRP_MJ_POWER 82762e1f ndis!ndisPowerDispatch
[17] IRP_MJ_SYSTEM_CONTROL 8274d172 ndis!ndisWMIDispatch
[18] IRP_MJ_DEVICE_CHANGE 8274a78c ndis!ndisDummyIrpHandler
[19] IRP_MJ_QUERY_QUOTA 8274a78c ndis!ndisDummyIrpHandler
[1a] IRP_MJ_SET_QUOTA 8274a78c ndis!ndisDummyIrpHandler

0: kd> !irp 8556dbf8 7
Irp is active with 3 stacks 2 is current (= 0x8556dc8c)
No Mdl: No System Buffer: Thread 00000000: Irp stack trace.
Flags = 00000000
ThreadListEntry.Flink = 8556dc08
ThreadListEntry.Blink = 8556dc08
IoStatus.Status = c00000bb
IoStatus.Information = 00000000
RequestorMode = 00000000
Cancel = 00
CancelIrql = 0
ApcEnvironment = 00
UserIosb = 00000000
UserEvent = 00000000
Overlay.AsynchronousParameters.UserApcRoutine = 00000000
Overlay.AsynchronousParameters.UserApcContext = 00000000
Overlay.AllocationSize = 00000000 – 00000000
CancelRoutine = 00000000
UserBuffer = 00000000
&Tail.Overlay.DeviceQueueEntry = 8556dc38
Tail.Overlay.Thread = 00000000
Tail.Overlay.AuxiliaryBuffer = 00000000
Tail.Overlay.ListEntry.Flink = 85147860
Tail.Overlay.ListEntry.Blink = 82143f98
Tail.Overlay.CurrentStackLocation = 8556dc8c
Tail.Overlay.OriginalFileObject = 00000000
Tail.Apc = 00000000
Tail.CompletionKey = 00000000
cmd flg cl Device File Completion-Context
[ 0, 0] 0 0 00000000 00000000 00000000-00000000

Args: 00000000 00000000 00000000 00000000
>[ 16, 2] 0 e1 86a02030 00000000 8230ebf3-8655dba0 Success Error Cancel pending
DriverappliandMP nt!PopSystemIrpCompletion
Args: 00014400 00000000 00000004 00000002
[ 0, 0] 0 0 00000000 00000000 00000000-8655dba0

Args: 00000000 00000000 00000000 00000000
IO verifier information:
No information available – the verifier is probably disabled

0: kd> !locks
KD: Scanning for held locks..

Resource @ nt!IopDeviceTreeLock (0x8216a680) Shared 1 owning threads
Threads: 8494d2d8-01<*>
KD: Scanning for held locks.

Resource @ nt!PiEngineLock (0x8216a600) Exclusively owned
Contention Count = 28
NumberOfExclusiveWaiters = 2
Threads: 8494d2d8-01<*>
Threads Waiting On Exclusive Access:
8494d828 8494e020

KD: Scanning for held





16572 total locks, 2 locks currently held

0: kd> !thread 8494d2d8
THREAD 8494d2d8 Cid 0004.0044 Teb: 00000000 Win32Thread: 00000000 WAIT: (Executive) KernelMode Non-Alertable
8b96ba04 Semaphore Limit 0x24
Not impersonating
DeviceMap 8b608728
Owning Process 8490f910 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 959990 Ticks: 38540 (0:00:10:01.227)
Context Switch Count 56424 NoStackSwap
UserTime 00:00:00.000
KernelTime 00:00:08.424
Win32 Start Address nt!ExpWorkerThread (0x820dbd25)
Stack Init 8b96c000 Current 8b96b910 Base 8b96c000 Limit 8b969000 Call 0
Priority 14 BasePriority 12 PriorityDecrement 1 IoPriority 2 PagePriority 5
ChildEBP RetAddr Args to Child
8b96b928 820e2352 8494d2d8 8494d360 8213813c nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
8b96b96c 8207df28 8494d2d8 00000000 87072450 nt!KiSwapThread+0x44f
8b96b9c4 8230e9de 8b96ba04 00000000 00000000 nt!KeWaitForSingleObject+0x492
8b96ba44 8230e674 00000002 8b96bad8 8b96baf0 nt!PopSleepDeviceList+0x12a
8b96baa4 8230e413 8b96bab8 00000002 00000000 nt!PoBroadcastSystemState+0x251
8b96bad8 8230f55f 9f1a9366 8b96bc10 8b96bc94 nt!PopSetDevicesSystemState+0x7b
8b96bbfc 82080c7a 00000002 00000000 00000000 nt!NtSetSystemPowerState+0x4b4
8b96bbfc 8207fb8d 00000002 00000000 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8b96bc10)
8b96bc80 822c3f45 00000002 00000004 a0000000 nt!ZwSetSystemPowerState+0x11 (FPO: [3,0,0])
8b96bccc 822c38d8 00000000 00000002 00000004 nt!PopIssueActionRequest+0x352
8b96bd08 8206691e 9f1a95de 8213813c 8494d2d8 nt!PopPolicyWorkerAction+0x45
8b96bd44 820dbe22 0000000c 00000000 8494d2d8 nt!PopPolicyWorkerThread+0x6e
8b96bd7c 8220bc42 80000000 9f1a955a 00000000 nt!ExpWorkerThread+0xfd
8b96bdc0 82074f4e 820dbd25 00000001 00000000 nt!PspSystemThreadStartup+0x9d
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16

0: kd> !locks -v 8216a680

Resource @ nt!IopDeviceTreeLock (0x8216a680) Shared 1 owning threads
Threads: 8494d2d8-01<*>

THREAD 8494d2d8 Cid 0004.0044 Teb: 00000000 Win32Thread: 00000000 WAIT: (Executive) KernelMode Non-Alertable
8b96ba04 Semaphore Limit 0x24
Not impersonating
DeviceMap 8b608728
Owning Process 8490f910 Image: System
Attached Process N/A Image: N/A
Wait Start TickCount 959990 Ticks: 38540 (0:00:10:01.227)
Context Switch Count 56424 NoStackSwap
UserTime 00:00:00.000
KernelTime 00:00:08.424
Win32 Start Address nt!ExpWorkerThread (0x820dbd25)
Stack Init 8b96c000 Current 8b96b910 Base 8b96c000 Limit 8b969000 Call 0
Priority 14 BasePriority 12 PriorityDecrement 1 IoPriority 2 PagePriority 5
ChildEBP RetAddr
8b96b928 820e2352 nt!KiSwapContext+0x26 (FPO: [Uses EBP] [0,0,4])
8b96b96c 8207df28 nt!KiSwapThread+0x44f
8b96b9c4 8230e9de nt!KeWaitForSingleObject+0x492
8b96ba44 8230e674 nt!PopSleepDeviceList+0x12a
8b96baa4 8230e413 nt!PoBroadcastSystemState+0x251
8b96bad8 8230f55f nt!PopSetDevicesSystemState+0x7b
8b96bbfc 82080c7a nt!NtSetSystemPowerState+0x4b4
8b96bbfc 8207fb8d nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8b96bc10)
8b96bc80 822c3f45 nt!ZwSetSystemPowerState+0x11 (FPO: [3,0,0])
8b96bccc 822c38d8 nt!PopIssueActionRequest+0x352
8b96bd08 8206691e nt!PopPolicyWorkerAction+0x45
8b96bd44 820dbe22 nt!PopPolicyWorkerThread+0x6e
8b96bd7c 8220bc42 nt!ExpWorkerThread+0xfd
8b96bdc0 82074f4e nt!PspSystemThreadStartup+0x9d
00000000 00000000 nt!KiThreadStartup+0x16

1 total locks, 1 locks currently held

Twitter tip – How to remove a saved search that returns no results

If you have a saved search in Twitter that returns no results Twitter doesn’t allow you to remove or delete the saved search. To resolve the problem, all you have to do is to send a new tweet that contains the item that the saved search is looking for. If the saved search is for some hash tag that isn’t popular any more, just include that hash tag in a new tweet. Give Twitter a few minutes after you send the tweet for them to update all of their indexes and when you rerun the search your new tweet should appear in the results and Twitter will then allow you to delete the saved search.

This worked for me today. Here are the specifics of what I did. I had three saved searches that I couldn’t remove. I had the hash tag #amexgiftcard, the word “ch9live” and a search for all tweets to me “to:HeatFanJohn” (I guess I not a very popular recipient of tweets!). I therefore generated a tweet containing all of these items. My new tweet was “@HeatFanJohn Test tweet with #amexgiftcard & ch9live to allow me to delete these saved searches & to:HeatFanJohn – this worked @support !”.

Below is a screenshot of running the saved search “to:HeatFanJohn” right after I sent the tweet. As you can see Twitter hadn’t updated their indexes yet so my search returned no results and as a result Twitter didn’t include the link to remove the saved search.

After waiting a couple of minutes I reran the search and as you can see my new tweet showed up and I was then able to click on the link to remove the saved search.

Voil√°! After clicking on “Remove this saved search”, my saved search was deleted!

Again, this method worked for me. I hope that it helps you. Perhaps Twitter will correct this problem soon to eliminate the need for this easy workaround.

Happy Tweeting!

This blog is carbon neutral

“My blog is carbon neutral” is an initiative started in Germany by the “Make it Green!” program. By creating this post about the initiative and emailing them the link to this post, they will plant one tree in the Plumas National Forest in California.

carbon neutral coupons and shopping with

The text below was copied from planet green, a Discovery Company web site.

On their website, Make It Green! explains that a study out of Harvard University shows that the average website is responsible for 0.02 grams of carbon dioxide emissions for every visitor. They then calculated that a blog with 15,000 visitors each month produces 8 pounds of emissions each year. Given that the UN Framework Convention on Climate Change estimates a tree absorbs about 20 pounds of emissions each year — though it is important to note that fewer emissions are absorbed in the tree’s first few years of life — even a blog with thousands of visitors a month can be carbon neutral by planting just one tree.

To date, Make It Green! has helped the Arbor Day Foundation plant about 350 trees in Plumas National Forest, a 1-million-acre forest in northern California that was devastated by forest fires in 2007 (88,000 acres of the forest was destroyed). The 350 trees is a good start, but eco-conscious bloggers can do their part.

How to Take Your Blog Carbon Neutral

  1. Write a blog post about this initiative and insert one of the buttons from Make It Green! in the post.
  2. Email the post’s link to Make It Green! at

That’s all it takes on your part. Once Make It Green! receives the link, they will plant a tree in Plumas National Park.

It’s important to note that Make It Green! will plant one tree for each domain. But if you’ve got a very popular blog with more than 15,000 viewers per month, you can e-mail Make It Green! to make sure your blog is indeed carbon neutral.

For more information on the project please visit the “What we do page” on Mach’s web site.

Who’s participating?

If you want to see which blogs we made carbon neutral you can browse through our participant list. Your blog is missing? Then let us know and we will make your blog carbon neutral too!

Who's participating?

No AT&T uVerse for you today!!!

Seinfeld's Soup NaziTuesday, March 30th, 2010 was supposed to be the big day for AT&T to install their new uVerse service in my home.

Well sadly, as the “Soup Nazi” on Seinfeld would say, “No soup for you!!!”. For me is was AT&T saying “No uVerse for you” … at least not today, we’ll try again next week.

About a week ago I signed up for AT&T’s triple pack bundle which includes digital TV, internet and phone service. I received several email confirmations from AT&T confirming that my service would be installed today. This morning I received phone calls from two different AT&T installers, one for the inside the home work and the other for the outside of the home work. At least AT&T is organized enough to coordinate having two installers perform the required work at the same time.

My problem started when the inside technician showed up at my home within the agreed to time window and told me that my voice service had been canceled! I asked him why and he said that his work order didn’t show why it just showed that it had been canceled. At my urging he called into AT&T’s support center to find out why my voice uVerse service had been canceled. On his second call into the support center (the first time the support center hung up on him) he found out from the VOIP support group that my voice service had been canceled because my current AT&T voice service has RingMaster¬†enabled and RingMaster isn’t compatible with uVerse voice. I then said that this was no big deal, just cancel my RingMaster service (which I had enabled to receive faxes on my fax machine using a different phone number with unique ring pattern), but unfortunately this could not be done immediately. AT&T needs 48 hours to cancel the RingMaster service.

Fortunately the inside premise installer was very friendly and helpful. He took the time to schedule a new appointment for installation next week.

So at least, unlike Ellen who was banned from having soup for one year, I only have to wait one week.

My real issue with AT&T is why didn’t they notify me earlier that there was an issue that prevented a smooth conversion to uVerse voice. All it would have taken was a simple call or email alerting me to the issue and the problem would have been resolved prior to my scheduled installation time.

University of Miami Computer Room Nostalgia

Joey Vossen and Barry Miller in UM computer room

Joey Vossen and Barry Miller in UM computer room
Photo courtesy of Edward P. White © All rights reserved

This is a picture of Joey Vossen and Barry Miller (two of the best programmers that I know – Barry wrote a standalone bootable operating system for the 1106 that played Mozart through the system’s maintenance speaker and Joey wrote a program that transparently removed deleted items from every program file on the system) in the University of Miami computer room. In the background you can see two Sperry Univac 770 line printers. In the foreground in front of Joey (who is sitting) is a Sperry Univac U300 console terminal. The U300 was the console device for the University’s Sperry Univac 1106. As I recall the 1106 @ UM had eight U16 tape drives (seven 1600 BPI 9-Track drives and one 7-Track drive for use with the University’s Calcomp plotter), several 8440 and 8430 disk drives, two FH-432 drums and one FH-1782 drum.

The University of Miami had a Sperry Univac 1106 computer when I started there as a student in August 1976. My first full time job was as a systems programmer for the University. When I left the University in 1982 to work at Eastern Air Lines the University had a Sperry Univac 1100/80A computer system.

My guess is that this picture was taken sometime between 1976 and 1978.

Trademarks Unisys, UNIVAC, FASTRAND, and UNISERVO are registered trademarks of Unisys Corporation.