BluetoothAPIs.h Broken in Windows SDK

Summary

The Microsoft Windows SDK versions 7.0 and 7.1 appear to have broken BluetoothAPIs.h header files.

Update:  Microsoft has fixed the errors in the Bluetooth header as of SDK version 8.0 for Windows 8.

Details

So far, I have uncovered two types of errors in this header file:

    • The use of

#pragma deprecate

      instead of

#pragma deprecated

      , causing compiler warnings.

    • Several callback function pointer type definitions omit the

CALLBACK

      (

__stdcall

    ) calling convention, causing a crash.

The first error simply results in compiler warnings.

warning C4068: unknown pragma

The second type of error results in dereferencing of an invalid memory location when using BluetoothRegisterForAuthenticationEx and BluetoothAuthenticateDeviceEx. This is because the standard calling convention (__cdecl) assumes that the caller will clean up the stack. Since the caller in this case is assuming that the callback function minded its own stack, it immediately pops ESI, placing zero into the register:

5EBCFFE2  mov         ecx,dword ptr [ebp-4]  
5EBCFFE5  pop         esi  
5EBCFFE6  xor         ecx,ebp  
5EBCFFE8  pop         ebx  
5EBCFFE9  call        @__security_check_cookie@4 (5EBDBBBBh)

Later, ntdll.dll dereferences memory at ESI + 4, triggering an access violation:

774A8301  test        byte ptr [esi+4],4

“Unhandled exception at 0x774a8301 (ntdll.dll) in [Application]: 0xC0000005: Access violation reading location 0x00000004.

Solution

To the compiler warnings, I replaced all instances of

#pragma deprecate

with

#pragma deprecated

To fix the crash bug, I added the CALLBACK calling convention keyword to PFN_AUTHENTICATION_CALLBACK and PFN_AUTHENTICATION_CALLBACK_EX. They now appear as follows:

typedef BOOL (CALLBACK *PFN_AUTHENTICATION_CALLBACK)(LPVOID pvParam, PBLUETOOTH_DEVICE_INFO pDevice);

typedef BOOL (CALLBACK *PFN_AUTHENTICATION_CALLBACK_EX)(__in_opt LPVOID pvParam, __in PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams);

Interestingly, the function pointer type definitions for the attribute-enumeration and device-selection callbacks (PFN_BLUETOOTH_ENUM_ATTRIBUTES_CALLBACK and PFN_DEVICE_CALLBACK, respectively) are defined correctly, using CALLBACK or WINAPI. I suspect that the inconsistency is because someone at Microsoft was using the /Gz compiler switch, making __stdcall the default calling convention.

About Jeff Fitzsimons

Jeff Fitzsimons is a software engineer in the California Bay Area. Technical specialties include C++, Win32, and multithreading. Personal interests include rock climbing, cycling, motorcycles, and photography.
This entry was posted in Technology, Win32, Windows. Bookmark the permalink.

2 Responses to BluetoothAPIs.h Broken in Windows SDK

  1. Azamat says:

    Thanks!! Helped))

  2. Klaus says:

    Great, thank you!

Leave a Reply

Your email address will not be published. Required fields are marked *