Wierd error - 1306

  • Thread starter Thread starter B Vidyadhar Joshi
  • Start date Start date
B

B Vidyadhar Joshi

I was writing an Bluetooth Application which makes calls to Windows APIs. I
feel I'm doing something wrong with the structure. Could somebody help me?
The code that I'm using is pasted below:

using System;
using System.Runtime.InteropServices;
namespace System.Net.Bluetooth
{
[StructLayout(LayoutKind.Sequential)]
public class BLUETOOTH_FIND_RADIO_PARAMS
{
/* typedef struct {
* DWORD dwSize;
* } BLUETOOTH_FIND_RADIO_PARAMS; */

public UInt32 dwSize;
public BLUETOOTH_FIND_RADIO_PARAMS()
{
dwSize = (UInt32)Marshal.SizeOf(this);
}
}

/*######## API Declaration
#######################################################################################
HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
BLUETOOTH_FIND_RADIO_PARAMS* pbtfrp, HANDLE* phRadio);
#############################################################################################################*/
[DllImport("bthprops.cpl")]
public static extern IntPtr BluetoothFindFirstRadio(ref
BLUETOOTH_FIND_RADIO_PARAMS pbtfrp, IntPtr phRadio);

/*######## API Declaration
#######################################################################################
DWORD GetLastError(void);
#############################################################################################################*/
[DllImport("kernel32.dll")]
private static extern uint GetLastError();

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp = new BLUETOOTH_FIND_RADIO_PARAMS();
IntPtr phRadio = new IntPtr(0);
BluetoothFindFirstRadio(ref frp,phRadio);
uint y = GetLastError();
}
}

When I run this code, I get an error 1306 (y == 1306). The string message
for this error is "Indicates two revision levels are incompatible."

The above API declarations can be found in BluetoothAPIs.h (Platform SDK on
WinXP SP2).

Thanks in advance.

B Vidyadhar Joshi.
 
B Vidyadhar Joshi,

First, you should not be declaring GetLastError. To perform interop,
the framework has to call a number of windows APIs, both before and after
the call, which could affect the error state for the current thread.
Because of this, the Marshal class has a static method, GetLastWin32Error,
which you should call to get the error code.

I also think that you are not making the correct declarations. Because
you define BLUETOOTH_FIND_RADIO_PARAMS as a class, your definition in the
API should not be ref, but just as it is (because it is a reference that is
being passed already). Either that, or you could redefine the structure
like this:

[StructLayout(LayoutKind.Sequential)]
public struct BLUETOOTH_FIND_RADIO_PARAMS
{
[MarshalAs(UnmanagedType.U4)]
public int dwSize;

// Factory to initialize instances, since you can't override default
constructors on
// structs.
public static BLUETOOTH_FIND_RADIO_PARAMS Create()
{
// Create the instance.
BLUETOOTH_FIND_RADIO_PARAMS retVal = new
BLUETOOTH_FIND_RADIO_PARAMS();

// Set the length parameter.
retVal.dwSize = Marshal.SizeOf(typeof(BLUETOOTH_FIND_RADIO_PARAMS));

// Return.
return retVal;
}
}

Your declaration of BluetoothFindFirstRadio is also wrong. The second
parameter should be ref. It should be:

[DllImport("bthprops.cpl", SetLastError=true)]
public static extern IntPtr BluetoothFindFirstRadio(
ref BLUETOOTH_FIND_RADIO_PARAMS pbtfrp,
ref IntPtr phRadio);

The SetLastError property on the attribute indicates that interop should
store the value of GetLastError in case you want it later.

Your code ends up looking like this:

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp =
BLUETOOTH_FIND_RADIO_PARAMS.Create();
IntPtr phRadio = new IntPtr();
BluetoothFindFirstRadio(ref frp, ref phRadio);
int y = Marshal.GetLastWin32Error();
}

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)



B Vidyadhar Joshi said:
I was writing an Bluetooth Application which makes calls to Windows APIs. I
feel I'm doing something wrong with the structure. Could somebody help me?
The code that I'm using is pasted below:

using System;
using System.Runtime.InteropServices;
namespace System.Net.Bluetooth
{
[StructLayout(LayoutKind.Sequential)]
public class BLUETOOTH_FIND_RADIO_PARAMS
{
/* typedef struct {
* DWORD dwSize;
* } BLUETOOTH_FIND_RADIO_PARAMS; */

public UInt32 dwSize;
public BLUETOOTH_FIND_RADIO_PARAMS()
{
dwSize = (UInt32)Marshal.SizeOf(this);
}
}

/*######## API Declaration
#######################################################################################
HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
BLUETOOTH_FIND_RADIO_PARAMS* pbtfrp, HANDLE* phRadio);
#############################################################################################################*/
[DllImport("bthprops.cpl")]
public static extern IntPtr BluetoothFindFirstRadio(ref
BLUETOOTH_FIND_RADIO_PARAMS pbtfrp, IntPtr phRadio);

/*######## API Declaration
#######################################################################################
DWORD GetLastError(void);
#############################################################################################################*/
[DllImport("kernel32.dll")]
private static extern uint GetLastError();

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp = new
BLUETOOTH_FIND_RADIO_PARAMS();
IntPtr phRadio = new IntPtr(0);
BluetoothFindFirstRadio(ref frp,phRadio);
uint y = GetLastError();
}
}

When I run this code, I get an error 1306 (y == 1306). The string message
for this error is "Indicates two revision levels are incompatible."

The above API declarations can be found in BluetoothAPIs.h (Platform SDK
on WinXP SP2).

Thanks in advance.

B Vidyadhar Joshi.
 
Hi Nicholas,

That was great. You pointed precisely to where I was erring. Thanks a ton.

Regards,

B Vidyadhar Joshi.

Nicholas Paldino said:
B Vidyadhar Joshi,

First, you should not be declaring GetLastError. To perform interop,
the framework has to call a number of windows APIs, both before and after
the call, which could affect the error state for the current thread.
Because of this, the Marshal class has a static method, GetLastWin32Error,
which you should call to get the error code.

I also think that you are not making the correct declarations. Because
you define BLUETOOTH_FIND_RADIO_PARAMS as a class, your definition in the
API should not be ref, but just as it is (because it is a reference that
is being passed already). Either that, or you could redefine the
structure like this:

[StructLayout(LayoutKind.Sequential)]
public struct BLUETOOTH_FIND_RADIO_PARAMS
{
[MarshalAs(UnmanagedType.U4)]
public int dwSize;

// Factory to initialize instances, since you can't override default
constructors on
// structs.
public static BLUETOOTH_FIND_RADIO_PARAMS Create()
{
// Create the instance.
BLUETOOTH_FIND_RADIO_PARAMS retVal = new
BLUETOOTH_FIND_RADIO_PARAMS();

// Set the length parameter.
retVal.dwSize =
Marshal.SizeOf(typeof(BLUETOOTH_FIND_RADIO_PARAMS));

// Return.
return retVal;
}
}

Your declaration of BluetoothFindFirstRadio is also wrong. The second
parameter should be ref. It should be:

[DllImport("bthprops.cpl", SetLastError=true)]
public static extern IntPtr BluetoothFindFirstRadio(
ref BLUETOOTH_FIND_RADIO_PARAMS pbtfrp,
ref IntPtr phRadio);

The SetLastError property on the attribute indicates that interop
should store the value of GetLastError in case you want it later.

Your code ends up looking like this:

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp =
BLUETOOTH_FIND_RADIO_PARAMS.Create();
IntPtr phRadio = new IntPtr();
BluetoothFindFirstRadio(ref frp, ref phRadio);
int y = Marshal.GetLastWin32Error();
}

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)



B Vidyadhar Joshi said:
I was writing an Bluetooth Application which makes calls to Windows APIs.
I feel I'm doing something wrong with the structure. Could somebody help
me? The code that I'm using is pasted below:

using System;
using System.Runtime.InteropServices;
namespace System.Net.Bluetooth
{
[StructLayout(LayoutKind.Sequential)]
public class BLUETOOTH_FIND_RADIO_PARAMS
{
/* typedef struct {
* DWORD dwSize;
* } BLUETOOTH_FIND_RADIO_PARAMS; */

public UInt32 dwSize;
public BLUETOOTH_FIND_RADIO_PARAMS()
{
dwSize = (UInt32)Marshal.SizeOf(this);
}
}

/*######## API Declaration
#######################################################################################
HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
BLUETOOTH_FIND_RADIO_PARAMS* pbtfrp, HANDLE* phRadio);
#############################################################################################################*/
[DllImport("bthprops.cpl")]
public static extern IntPtr BluetoothFindFirstRadio(ref
BLUETOOTH_FIND_RADIO_PARAMS pbtfrp, IntPtr phRadio);

/*######## API Declaration
#######################################################################################
DWORD GetLastError(void);
#############################################################################################################*/
[DllImport("kernel32.dll")]
private static extern uint GetLastError();

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp = new
BLUETOOTH_FIND_RADIO_PARAMS();
IntPtr phRadio = new IntPtr(0);
BluetoothFindFirstRadio(ref frp,phRadio);
uint y = GetLastError();
}
}

When I run this code, I get an error 1306 (y == 1306). The string message
for this error is "Indicates two revision levels are incompatible."

The above API declarations can be found in BluetoothAPIs.h (Platform SDK
on WinXP SP2).

Thanks in advance.

B Vidyadhar Joshi.
 
Hi Nicholas,

I finished a couple of more calls to APIs but got struck with this one. I
feel I'm again erring on some structure conversion. Could you please take a
look at the code and advise?

/*
typedef ULONGLONG BTH_ADDR;
typedef struct _BLUETOOTH_ADDRESS {
union {
BTH_ADDR ullLong; // easier to compare again BLUETOOTH_NULL_ADDRESS
BYTE rgBytes[ 6 ]; // easier to format when broken out
};
} BLUETOOTH_ADDRESS_STRUCT;
#define BLUETOOTH_ADDRESS BLUETOOTH_ADDRESS_STRUCT
#define BLUETOOTH_NULL_ADDRESS ( (ULONGLONG) 0x0 )
*/
[StructLayout(LayoutKind.Explicit)]
internal class BluetoothAddress
{
[MarshalAs(UnmanagedType.U8)]
[FieldOffset(0)] internal ulong ullLong;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=6)]
[FieldOffset(0)] internal byte[] rgBytes;

internal BluetoothAddress()
{
ullLong = 0;
rgBytes = new byte[6];
}
}


/*
typedef struct _BLUETOOTH_DEVICE_INFO {
DWORD dwSize; // size, in bytes, of this structure - must be the
sizeof(BLUETOOTH_DEVICE_INFO)
BLUETOOTH_ADDRESS Address; // Bluetooth address
ULONG ulClassofDevice; // Bluetooth "Class of Device"
BOOL fConnected; // Device connected/in use
BOOL fRemembered; // Device remembered
BOOL fAuthenticated; // Device authenticated/paired/bonded
SYSTEMTIME stLastSeen; // Last time the device was seen
SYSTEMTIME stLastUsed; // Last time the device was used for other than
RNR, inquiry, or SDP
WCHAR szName[ BLUETOOTH_MAX_NAME_SIZE ]; // Name of the device
} BLUETOOTH_DEVICE_INFO_STRUCT;
#define BLUETOOTH_DEVICE_INFO BLUETOOTH_DEVICE_INFO_STRUCT
typedef BLUETOOTH_DEVICE_INFO * PBLUETOOTH_DEVICE_INFO;
*/
internal struct SystemTime
{
public short wYear;
public short wMonth;
public short wDayOfWeek;
public short wDay;
public short wHour;
public short wMinute;
public short wSecond;
public short wMilliseconds;
}

[StructLayout(LayoutKind.Sequential)]
internal struct BluetoothDeviceInfo
{
[MarshalAs(UnmanagedType.U4)]
internal int dwSize;
[MarshalAs(UnmanagedType.Struct)]
internal BluetoothAddress Address;
internal ulong ulClassOfDevice;
internal bool fConnected;
internal bool fRemembered;
internal bool fAuthenticated;
internal SystemTime stLastSeen;
internal SystemTime stLastUsed;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=32)]
internal char[] szName;

internal static BluetoothDeviceInfo Create()
{
BluetoothDeviceInfo bdi = new BluetoothDeviceInfo();
//Throws an error on the next line
//"Type System.Net.Bluetooth.BluetoothDeviceInfo can not be
marshaled as an unmanaged structure; no meaningful size or offset can be
computed."
bdi.dwSize = Marshal.SizeOf(typeof(BluetoothDeviceInfo));
bdi.szName = new char[32];
return bdi;
}
}


/*
typedef struct _BLUETOOTH_DEVICE_SEARCH_PARAMS {
DWORD dwSize; // IN sizeof this structure
BOOL fReturnAuthenticated; // IN return authenticated devices
BOOL fReturnRemembered; // IN return remembered devices
BOOL fReturnUnknown; // IN return unknown devices
BOOL fReturnConnected; // IN return connected devices
BOOL fIssueInquiry; // IN issue a new inquiry
UCHAR cTimeoutMultiplier; // IN timeout for the inquiry
HANDLE hRadio; // IN handle to radio to enumerate - NULL == all radios
will be searched
} BLUETOOTH_DEVICE_SEARCH_PARAMS;
*/
[StructLayout(LayoutKind.Sequential)]
internal struct BluetoothDeviceSearchParams
{
[MarshalAs(UnmanagedType.U4)]
internal int dwSize;
internal bool fReturnAuthenticated;
internal bool fReturnRemembered;
internal bool fReturnUnknown;
internal bool fReturnConnected;
internal bool fIssueInquiry;
internal ushort cTimeoutMultiplier;
internal IntPtr hRadio;

internal static BluetoothDeviceSearchParams Create(IntPtr hRadio)
{
BluetoothDeviceSearchParams dsp = new BluetoothDeviceSearchParams();
dsp.dwSize = Marshal.SizeOf(typeof(BluetoothDeviceSearchParams));
dsp.hRadio = hRadio;
return dsp;
}
}


/*
BluetoothFindFirstDevice(
BLUETOOTH_DEVICE_SEARCH_PARAMS * pbtsp,
BLUETOOTH_DEVICE_INFO * pbtdi
);
*/
[DllImport("bthprops.cpl")]
private static extern IntPtr BluetoothFindFirstDevice(ref
BluetoothDeviceSearchParams pbtsp, ref BluetoothDeviceInfo pbtdi);

/*
HBLUETOOTH_DEVICE_FIND hFind;
BLUETOOTH_DEVICE_SEARCH_PARAMS btsp = { sizeof(btsp) };
BLUETOOTH_DEVICE_INFO btdi = { sizeof(btdi) };
btsp.fReturnAuthenticated = TRUE;
btsp.fReturnRemembered = TRUE;
hFind = BluetoothFindFirstDevice( &btsp, &btdi );
*/
public void SearchDevices()
{
BluetoothDeviceSearchParams dsp =
BluetoothDeviceSearchParams.Create(phRadio);
BluetoothDeviceInfo bdi = BluetoothDeviceInfo.Create();
IntPtr x = BluetoothFindFirstDevice(ref dsp, ref bdi);
}

Thanks & Regards,

B Vidyadhar Joshi


Nicholas Paldino said:
B Vidyadhar Joshi,

First, you should not be declaring GetLastError. To perform interop,
the framework has to call a number of windows APIs, both before and after
the call, which could affect the error state for the current thread.
Because of this, the Marshal class has a static method, GetLastWin32Error,
which you should call to get the error code.

I also think that you are not making the correct declarations. Because
you define BLUETOOTH_FIND_RADIO_PARAMS as a class, your definition in the
API should not be ref, but just as it is (because it is a reference that
is being passed already). Either that, or you could redefine the
structure like this:

[StructLayout(LayoutKind.Sequential)]
public struct BLUETOOTH_FIND_RADIO_PARAMS
{
[MarshalAs(UnmanagedType.U4)]
public int dwSize;

// Factory to initialize instances, since you can't override default
constructors on
// structs.
public static BLUETOOTH_FIND_RADIO_PARAMS Create()
{
// Create the instance.
BLUETOOTH_FIND_RADIO_PARAMS retVal = new
BLUETOOTH_FIND_RADIO_PARAMS();

// Set the length parameter.
retVal.dwSize =
Marshal.SizeOf(typeof(BLUETOOTH_FIND_RADIO_PARAMS));

// Return.
return retVal;
}
}

Your declaration of BluetoothFindFirstRadio is also wrong. The second
parameter should be ref. It should be:

[DllImport("bthprops.cpl", SetLastError=true)]
public static extern IntPtr BluetoothFindFirstRadio(
ref BLUETOOTH_FIND_RADIO_PARAMS pbtfrp,
ref IntPtr phRadio);

The SetLastError property on the attribute indicates that interop
should store the value of GetLastError in case you want it later.

Your code ends up looking like this:

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp =
BLUETOOTH_FIND_RADIO_PARAMS.Create();
IntPtr phRadio = new IntPtr();
BluetoothFindFirstRadio(ref frp, ref phRadio);
int y = Marshal.GetLastWin32Error();
}

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)



B Vidyadhar Joshi said:
I was writing an Bluetooth Application which makes calls to Windows APIs.
I feel I'm doing something wrong with the structure. Could somebody help
me? The code that I'm using is pasted below:

using System;
using System.Runtime.InteropServices;
namespace System.Net.Bluetooth
{
[StructLayout(LayoutKind.Sequential)]
public class BLUETOOTH_FIND_RADIO_PARAMS
{
/* typedef struct {
* DWORD dwSize;
* } BLUETOOTH_FIND_RADIO_PARAMS; */

public UInt32 dwSize;
public BLUETOOTH_FIND_RADIO_PARAMS()
{
dwSize = (UInt32)Marshal.SizeOf(this);
}
}

/*######## API Declaration
#######################################################################################
HBLUETOOTH_RADIO_FIND BluetoothFindFirstRadio(
BLUETOOTH_FIND_RADIO_PARAMS* pbtfrp, HANDLE* phRadio);
#############################################################################################################*/
[DllImport("bthprops.cpl")]
public static extern IntPtr BluetoothFindFirstRadio(ref
BLUETOOTH_FIND_RADIO_PARAMS pbtfrp, IntPtr phRadio);

/*######## API Declaration
#######################################################################################
DWORD GetLastError(void);
#############################################################################################################*/
[DllImport("kernel32.dll")]
private static extern uint GetLastError();

public void DiscoverDevices()
{
BLUETOOTH_FIND_RADIO_PARAMS frp = new
BLUETOOTH_FIND_RADIO_PARAMS();
IntPtr phRadio = new IntPtr(0);
BluetoothFindFirstRadio(ref frp,phRadio);
uint y = GetLastError();
}
}

When I run this code, I get an error 1306 (y == 1306). The string message
for this error is "Indicates two revision levels are incompatible."

The above API declarations can be found in BluetoothAPIs.h (Platform SDK
on WinXP SP2).

Thanks in advance.

B Vidyadhar Joshi.
 
Back
Top