酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Mobile(.NET Compact Framework)でデバイスを工場出荷時状態に戻す(ハードリセットをおこなう)

id:tmyt にWindows Mobile端末を工場出荷状態に戻すハードリセットをソフトウェアから実行する方法があるのを教えてもらいました。ソフトリセットと違うので実行の際には気をつけてください……

再起動(ソフトリセット)に関しては、「Windows Mobile(.NET Compact Framework)でデバイスを再起動(ソフトリセット)する - 酢ろぐ!」にて紹介していますので必要であればご参照ください。

「.NET CFから強制的にデバイスをハードリセットする方法ってないのー?(超意訳)」の質問に対して、Windows Mobile開発者のBlogで回答されているのを見付けました。

Have you ever needed to write .NET CF code that forces a device to hard-reset?

Windows Mobile Team Blog : Hard Reset from .NET CF

Windows Mobileでは、手動で特定のキーを押下しながらバッテリを入れる等の操作を行うことで工場出荷状態に戻す事が可能です。「ハードリセット」と呼ばれます。

このハードリセットをプログラム上から実行してみましょう。P/Invokeを介して「SetCleanRebootFlag関数」を呼び出し、再起動すると工場出荷状態に戻ります。

下記のサンプルコードでは、「SetCleanRebootFlag関数」を実行した後に、「KernelIoControl関数」でリセットしていますが「ExitWindowsEx関数」でも再起動が出来れば次回の起動時にハードリセットがおこなわれます*1

デバイスを工場出荷時状態に戻す(ハードリセットをおこなう)

P/Invokeにて、KernelIoControl関数とSetCleanRebootFlag関数を使える状態にしておきます。

   [System.Runtime.InteropServices.DllImport("Coredll.dll")]
   extern static int KernelIoControl(int dwIoControlCode, 
                                     IntPtr lpInBuf, 
                                     int nInBufSize, 
                                     IntPtr lpOutBuf, 
                                     int nOutBufSize , 
                                     ref int lpBytesReturned );

   [System.Runtime.InteropServices.DllImport("Coredll.dll")]
   extern static void SetCleanRebootFlag();

次にアプリケーション内で以下のコードを実行すると、再起動されハードリセットされます。

   public void HardReset()
   {
      int IOCTL_HAL_REBOOT = 0x101003C;
      int bytesReturned = 0;

      // 起動時にハードリセットを行うフラグを立てる
      SetCleanRebootFlag();

      // 再起動する
      KernelIoControl(IOCTL_HAL_REBOOT, 
                      IntPtr.Zero, 0, 
                      IntPtr.Zero, 0, ref bytesReturned );
   }

*1:おそらくデバイスの起動時にフラグをチェックしていると思われるため