Wireless HeadPhone Adventures

I wanted to get wireless headphones to listen to music.

At the office I have 3 desktops, with a range of power. The most powerful has 3 monitors connected. The next has 1, while a 3rd doesn’t have any (I Remote Desktop to it). I run various flavors of Windows Server 2012 and host many Hyper-V virtual machines on them. I also create many virtual machines hosted in Azure and Remote Desktop to them. For those who don’t know, Windows Server is basically like Windows 8, but with various performance tweaks and tools to make it into a server machine. What is a server machine? It’s like a machine that nobody is really going to sit in front of and type. It might be a web server, serving web pages, or a file server. There are dozens of server “roles” and “features” from which to choose.

I’ve been using Windows Server on my desktop machines for years: it used to be the only way to run HyperV, which allows hosting multiple virtual machines. To make it behave like a “client” machine, rather than a server, I have to enable things like User Interface, Desktop Experience, Sounds. I also disable IE Enhanced Security. Many features are locked down on a default server installation to minimize security risks.

I found some earbuds: Soundpeats Qy7 V4.1 Bluetooth Mini Lightweight Wireless Stereo Sports/running & Gym/exercise Bluetooth Earbuds Headphones Headsets W/microphone for $28. These sound good, and are able to block out ambient sounds pretty well. It’s tough to get the rubber covering off the USB micro charger port to charge them after their battery life of about 4 or 5 hours. It was tough to figure out which was left/right, especially from the pictures. Even when not connected, a voice tells me status, like “Power On”, “Connected”, “Pairing”

I paired the earbuds to my Surface Pro 3 just fine. The sound quality was great. When I’m at the office,  I’m often using Remote Desktop to the Surface Pro 3 from my main Desktop computer, using all 3 high resolution monitors to see  my SP3. I find this to be very productive, and when I go home, I can just disconnect the SP3 and use it at home, with my identical work environment (although on just 1 screen). The SP3 is so powerful, it rivals the speed of my newest desktop. I hit Windows Key-> Arrow to move the active window to different monitors, and Alt-Space X to maximize the window. Occasionally, I still type on the wrong keyboard or move the wrong mouse.  It’s great to put some of the myriad Visual Studio windows on other monitors.

Using Remote Desktop, I could choose to keep the sounds on the remote computer, and use the SP3 BlueTooth settings of the remote computer to broadcast to the earbuds. (In this case, “remote” was only a couple feet away.) This works fine. However, I thought that I could squeeze more power out of the SP3 if I reduced its load, so I wanted to add BlueTooth to my midrange desktop.

I found SoundBot® SB340 Bluetooth 4.0 USB Adapter Universal Plug and Play Dongle Class 2 Transmitter for $11, which seemed like it would work.

I plugged in the little USB dongle and had to download some drivers to enable BlueTooth. It seemed simple enough, I got it working fairly easily. The sound quality was quite good, although there were instances of pausing and static, which I thought might have to do with the load and or hardware on the machine.

So I was a happy camper for a few days, paying no mind to the machine. Eventually I noticed that some things didn’t quite work quite right, but I didn’t bother to check it out because it was not my primary machine. After about a week, I decided to investigate. (In the interim I had to change my password.)

Symptoms:

· When using Remote Desktop, typing in my password to connect to another machine, nothing would happen. (The dialog would go away, but nothing else happened.)

· Outlook asked for updated credentials. I’d type in my password, but Outlook would fail silently.

I thought hmmmm… what’s happening? How can I fix this? I thought maybe it had to do with my password change. I tried variations on the password dialogs of Remote Desktop (mstsc.exe) and Outlook. No luck.

I dreaded having to migrate my Virtual Machines hosted on from that machine and/or reinstalling the OS or doing a Repair or something.

Then I thought to look at the Window Event Log. Sure enough, it told me that Outlook and Mstsc.exe were crashing.

clip_image002

So I started MSTSC.exe, then started Visual Studio. I hit Ctrl-Alt-P(or Debug->Attach To Process), chose the mstsc.exe process. I made sure that the Debug Exceptions were set to catch exceptions. I switched to MSTSC.Exe and typed in my password and hit enter. Sure enough, Visual Studio caught the exception that was happening and showed me the call stack.

 ntdll.dll!RtlReportCriticalFailure(long StatusCode, void * FailureInfo
ntdll.dll!RtlpLogHeapFailure(_HEAP_FAILURE_TYPE FailureType, 
ntdll.dll!RtlFreeHeap(void * HeapHandle, unsigned long Flags, void * BaseAddress)         C
BLEtokenCredentialProvider.dll!000007fe44ebed84()     Unknown
BLEtokenCredentialProvider.dll!000007fe44eb6b46()      Unknown
BLEtokenCredentialProvider.dll!000007fe44eb8016()      Unknown
BLEtokenCredentialProvider.dll!000007fe44ebdc88()      Unknown
ntdll.dll!LdrpCallInitRoutine(unsigned char (void *, unsigned long, _CONTEXT *) 
ntdll.dll!LdrpProcessDetachNode(_LDR_DDAG_NODE * Node) Line 2324              C
ntdll.dll!LdrpUnloadNode(_LDR_DDAG_NODE * Node) Line 3352             C
ntdll.dll!LdrpDecrementNodeLoadCount(_LDR_DDAG_NODE * Node) Line 520 C
ntdll.dll!LdrUnloadDll(void * DllHandle) Line 1696              C
KernelBase.dll!FreeLibrary(HINSTANCE__ * hLibModule) Line 1327         C
combase.dll!CClassCache::CDllPathEntry::CFinishObject::Finish() Line 3953           C++
combase.dll!CClassCache::CleanUpDllsForApartment() Line 7025              C++
combase.dll!FinishShutdown() Line 2111              C++
combase.dll!ApartmentUninitialize(int fHostThread) Line 2384   C++
combase.dll!wCoUninitialize(COleTls & Tls, int fHostThread) Line 3715    C++
combase.dll!CoUninitialize() Line 3623   C++
combase.dll!DoThreadSpecificCleanup() Line 857             C++
ntdll.dll!RtlProcessFlsData(_FLS_DATA * FlsData) Line 1678          C
ntdll.dll!LdrShutdownThread() Line 5488               C
ntdll.dll!RtlExitUserThread(long ExitStatus) Line 1870      C
kernel32.dll!BaseThreadInitThunk(unsigned long RunProcessInit, 
ntdll.dll!RtlUserThreadStart(long (void *) * StartAddress, void * Argument) Line 1021     C

Reading the stack from the bottom up, I could see that a thread was started, and it was shutting down. It called CoUninitilize like a good citizen, which called FreeLibrary to unload a Dll. As part of unloading a Dll, the DLL’s main entry point DllMain is called with the parameter DLL_PROCESS_DETACH, so the DLL can do anything it might need to do. It looks like the Dll being freed is BLEtokenCredentialProvider.dll, which didn’t look familiar to me.

Also, that DLL was trying to free some heap memory by calling HeapFree which maps to  RtlFreeHeap. The heap noticed some inconsistency in the heap and tried to log and report a critical failure.

So it appears that something in that module corrupted some memory.

So I brought up the Debug->Windows->Modules window and looked at the information for BLEtokenCredentialProvider.dll:

BLEtokenCredentialProvider.dll C:\Program Files\CSR\CSR Harmony Wireless Software Stack\BLEtokenCredentialProvider.dll    N/A        N/A        Cannot find or open the PDB file.                             92                2.01.63.0              3/20/2012 4:38 AM          000007FE44EB0000-000007FE44F2D000   [9428] mstsc.exe                             

Now I could see very quickly that the “CSR Harmony Wireless Software Stack” had some sort of Credential Provider, which has a bug in the way it handles memory. Some possibilities:

· A buffer overrun or underrun: writing to memory before or beyond the allocated size, perhaps overwriting the heap’s internal data structures which the heap noticed, or, more insidiously, writing to someone else’s allocation, which might change a critical value (like your bank account balance) without anyone noticing.

· A double free: FreeHeap twice on the same location

I can’t tell from the stack if this is a private heap that has corrupt data, but it’s probably the process heap (every process gets a main Process Heap).

There are a few tools to try to find such programming errors, like AppVerifier and GFlags.

AppVerifier works by intercepting calls to heap APIs. (I wrote a tool called MemSpect that does this too) and monitors the memory before and after the allocation. One of its options is to allocate one 4k Page for each allocation, surrounding that page with guard pages and using the Virtual Memory Protection features. However that uses a LOT of virtual address space.

GFlags (“Global Flags”) works by enabling heap checking features in the heap software itself .

clip_image003

When you hit F5 in Visual Studio to start debugging the project you’re working on, the process you’re debugging is started with the heap in a slower Debug mode. See You can develop code faster

Thinking about it, it makes sense that BlueTooth has something to do with credentials, because it might have to verify connections to portable devices and things.

So it was a simple task to uninstall the drivers and that fixed the problem.

See also

Scan the Windows Event Log for your application crashes and hangs