Reputation: 1338
I am writing an app where I need to turn airplane mode on or off on windows. I have seen this question, but the answers only get the status, or say you cannot do such a thing for Metro apps. I am not making a modern/metro app, so I don't need to worry about application sandboxing.
Is there an api to turn Airplane mode on/off, and how should I use it?
EDIT: In my use case, I know I can control it, and the user is ok with that.
Also, I found this msdn question with the following excerpt:
Windows 8(build 8250), I can turn on / off airplane mode in Metro Style Network Setting UI.
How to do this programmatically?
Microsoft defined HID Usage code for Wireless Radio Button (Usage: 0xC6).
Question: Is there some virtual key code for Wireless Radio Button? If so, Application can send this keycode by Keybd_event.
WLANAPI.dll export the API WlanStoreRadioStateOnEnteringAirPlaneMode , but there are no any document for this API.
Question: Can you provide detail information? Is it used to control Air Plane Mode, How to call this API?
So apparently (to give a summery of the answer), one can check the state of Airplane mode using the MobileBroadbandRadioState
enum.
The HID route may be a possibility docs. Apparently it is a question of whether one can send the code 0xc6 to kbd_event.
EDIT2: Apparently there is a window called Network Flyout
and I was thinking of enumerating the children to find the switch, but I haven't had much success. I'll have to use Spy++ some more to find out.
Upvotes: 3
Views: 3864
Reputation: 151
All of the following I discovered myself via reverse engineering.
The internal API used internally by windows to get/set Airplane mode makes use of COM calls to "RMsvc" service (which is located in "RMApi.dll"). That service is exporting a factory and interface which contains functions to get/set flight mode:
#include <Windows.h>
#include <assert.h>
#include <stdio.h>
static GUID const CLSID_RadioManagementAPI = { 0x581333f6, 0x28db, 0x41be, { 0xbc, 0x7a, 0xff, 0x20, 0x1f, 0x12, 0xf3, 0xf6 } };
static GUID const CID_IRadioManager = { 0xdb3afbfb, 0x08e6, 0x46c6, { 0xaa, 0x70, 0xbf, 0x9a, 0x34, 0xc3, 0x0a, 0xb7 } };
typedef IUnknown IUIRadioInstanceCollection; /* Didn't bother rev-engineering this one... */
typedef DWORD _RADIO_CHANGE_REASON;
typedef struct IRadioManagerVtbl IRadioManagerVtbl;
typedef struct IRadioManager {
IRadioManagerVtbl *lpVtbl;
} IRadioManager;
struct IRadioManagerVtbl {
/* IUnknown */
HRESULT (STDMETHODCALLTYPE *QueryInterface)(IRadioManager *This, GUID const *riid, LPVOID *ppvObj);
ULONG (STDMETHODCALLTYPE *AddRef)(IRadioManager *This);
ULONG (STDMETHODCALLTYPE *Release)(IRadioManager *This);
/* IRadioManager (aka. `CUIRadioManager') */
HRESULT (STDMETHODCALLTYPE *IsRMSupported)(IRadioManager *This, DWORD *pdwState);
HRESULT (STDMETHODCALLTYPE *GetUIRadioInstances)(IRadioManager *This, IUIRadioInstanceCollection **param_1);
HRESULT (STDMETHODCALLTYPE *GetSystemRadioState)(IRadioManager *This, int *pbEnabled, int *param_2, _RADIO_CHANGE_REASON *param_3);
HRESULT (STDMETHODCALLTYPE *SetSystemRadioState)(IRadioManager *This, int bEnabled);
HRESULT (STDMETHODCALLTYPE *Refresh)(IRadioManager *This);
HRESULT (STDMETHODCALLTYPE *OnHardwareSliderChange)(IRadioManager *This, int param_1, int param_2);
};
int main() {
HRESULT hr;
IRadioManager *irm;
hr = CoInitialize(NULL);
assert(!FAILED(hr));
irm = NULL;
hr = CoCreateInstance(&CLSID_RadioManagementAPI, NULL, 4,
&CID_IRadioManager, (void **)&irm);
assert(!FAILED(hr) && irm);
int bOldMode, b;
_RADIO_CHANGE_REASON c;
hr = irm->lpVtbl->GetSystemRadioState(irm, &bOldMode, &b, &c);
assert(!FAILED(hr));
printf("Old flight-mode state was: %s\n", bOldMode == 0 ? "on" : "off");
/* Set flight mode to the opposite state. */
hr = irm->lpVtbl->SetSystemRadioState(irm, bOldMode == 0 ? 1 : 0);
assert(!FAILED(hr));
irm->lpVtbl->Release(irm);
CoUninitialize();
return 0;
}
Upvotes: 4