Objective: Attempt to retrieve and set the status of wireless devices (bluetooth, phone, wifi) on Windows Mobile device.
There is no documented API on Windows Mobile device to get/set the wireless device status. However, we can achieve this by calling the following 2 secret functions hidden under ossvcs.dll:
[DllImport("ossvcs.dll", EntryPoint = "#276")]
private static extern int GetWirelessDevices(ref RadioDevice RDD, int dwFlags);
[DllImport("ossvcs.dll", EntryPoint = "#273")]
private static extern int ChangeRadioState(RadioDevice RDD, RADIODEVSTATE dwFlags, SAVEACTION action);
RDD indicates which device to control and its corresponding status. RDD is a C++ class and needs to be converted into C# accordingly for P/Invoke to work. RDD declaration is as follows:
class RDD {
RDD() : pszDeviceName(NULL), pNext(NULL), pszDisplayName(NULL) {}
~RDD() { LocalFree(pszDeviceName); LocalFree(pszDisplayName); }
public:
LPTSTR pszDeviceName;
LPTSTR pszDisplayName;
DWORD dwState;
DWORD dwDesired;
RADIODEVTYPE DeviceType;
RDD * pNext; //pointer to next available device.
} ;
typedef enum _RADIODEVTYPE {
POWER_MANAGED = 1,
POWER_PHONE,
POWER_BLUETOOTH,
}RADIODEVTYPE;
typedef enum _SAVEACTION {
POWER_DONT_SAVE = 0,
POWER_PRE_SAVE,
POWER_POST_SAVE,
} SAVEACTION;
To control a wireless device, GetWirelessDevices must first be called to enumerate all available wireless devices to locate the desired device (either via its name or via its type, which should be enough in most cases, since most phones only don't have more than 1 bluetooth or wifi devices). After which ChangeRadioState will be called on this device to change the status.
Converting the code to C# is straightforward except that RDD needs to be in a separate class and [MarshalAs(UnmanagedType.LPTStr)] needs to prefix each of the LPTSTR declaration.
public class RadioDevice
{
[MarshalAs(UnmanagedType.LPTStr)]
public string pszDeviceName;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszDisplayName;
public RADIODEVSTATE dwState;
public int dwDesired;
public RADIODEVTYPE DeviceType;
public IntPtr pNext;
public RadioDevice()
{
pszDeviceName = null;
pszDisplayName = null;
pNext = IntPtr.Zero;
}
~RadioDevice()
{
}
}
The code needs to be signed (or the device security model needs to be set accordingly) for the above functions to work.
Download C# source code here
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.