0

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?

  1. 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.

  2. 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.

IronManMark20
  • 1,298
  • 12
  • 28
  • 4
    I don't know whether there is an accessible API, but have you considered that messing with airplane mode is something that neither Microsoft nor most computer owners want your software *ever* to do? Airplane mode is about the physical safety of dozens of people per computer, and if I put my computer in airplane mode then I *damn well* don't want your software taking it back out. – John Bollinger Jun 13 '15 at 02:53
  • Well, there are api calls to connect and disconnect to/from a network, so I don't see what the difference is. – IronManMark20 Jun 13 '15 at 04:53
  • 3
    The user overrides all of that when putting a device into airplane mode. – David Heffernan Jun 13 '15 at 06:09
  • @ironmark 20 - get a good lawyer - got a feeling you may need one – Ed Heal Jun 14 '15 at 03:48
  • @JohnBollinger: That's absurd. If it were about safety, you can bet the crew would be inspecting every electronic device to make sure its radio is off. Or devices simply would not be allowed in the cabin. – Ben Voigt Jun 14 '15 at 05:56
  • @BenVoigt You are totally correct. Wifi signals don't interfere with planes. I just flew on JetBlue and they have wifi __while you're flying__! And anyway, it really on matters during takeoff and landing, when laptops and tablets are supposed to be __stowed and off__. – IronManMark20 Jun 14 '15 at 14:56
  • Airplane mode is not only for airplanes. It may be required in other places where wireless can cause problems, such as hospitals; or banned as a policy. – ddbug Sep 11 '18 at 19:03

1 Answers1

2

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;
}
user3296587
  • 101
  • 9
  • While compiling this code, I'm getting following error:- error: ';' expected (got "IUIRadioInstanceCollection") – maverick Feb 18 '22 at 14:18
  • 1
    @maverick I'm guessing your didn't define `IUnknown` for some reason (the error is probably referring to "typedef IUnknown IUIRadioInstanceCollection;", but next time please give more details). Go find out what's wrong with your system headers, because I can just copy+paste this into a new file and do `gcc -o out.exe file.c -lOle32`, and it works just fine. Oh: And if that doesn't work (which it should, and it not doing so means something is wrong with your build set-up), you can replace the line with `typedef void *IUIRadioInstanceCollection;` – user3296587 Feb 18 '22 at 17:15