Warm reboot of a PocketPC/CE

To be able to reset a PocketPC/WindowsCE programmatically from within a managed application, it is necessary to send a IOCTL to the device using KernelIoControl. This API is not available directly in managed code, so we need to P/Invoke KernelIoControl, providing it with the correct IOCTL (IOCTL_HAL_REBOOT). To assure that IOCTL’s are unique, they can be created in native code using the CTL_CODE macro. To be able to create the same IOCTL from managed code, we make sure to define the IOCTL in a similar way as CTL_CODE does. Note that running the sample code from inside any Visual Studio 2003 or up resets the device, resulting in a lost connection to the device.

Code:

Complete C# sample. A Windows Form PocketPC application containing a button to reset the device:

namespace ResetDevice
{
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
 
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.Button button1;
private System.Windows.Forms.MainMenu mainMenu1;
internal static Int32 METHOD_BUFFERED = 0;
internal static Int32 FILE_ANY_ACCESS = 0;
internal static Int32 FILE_DEVICE_HAL = 0x00000101;
internal static Int32 IOCTL_HAL_REBOOT =
((FILE_DEVICE_HAL) < < 16)
((FILE_ANY_ACCESS) < < 14)
((15) < < 2)  (METHOD_BUFFERED);
 
[DllImport("coredll.dll", SetLastError=true)]
private static extern bool KernelIoControl(Int32 dwIoControlCode,
IntPtr lpInBuf,
Int32 nInBufSize,
byte[] lpOutBuf,
Int32 nOutBufSize,
ref Int32 lpBytesReturned);
public static void ResetDevice()
{
int cb = 0;
byte[] buffer = new byte[1];
KernelIoControl(IOCTL_HAL_REBOOT,
IntPtr.Zero,
0,
buffer,
0,
ref cb);
}
 
public Form1()
{
InitializeComponent();
}
 
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
}
 
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.button1 = new System.Windows.Forms.Button();
this.button1.Location = new System.Drawing.Point(64, 144);
this.button1.Size = new System.Drawing.Size(112, 48);
this.button1.Text = "Reset Device";
this.button1.Click += new System.EventHandler(this.button1_Click);
this.Controls.Add(this.button1);
this.Menu = this.mainMenu1; this.Text = "Form1";
}
 
static void Main()
{
Application.Run(new Form1());
}
 
private void button1_Click(object sender, System.EventArgs e)
{
ResetDevice();
}
}
}
 
Definition of the IOCTL, P/Invoke declaration to KernelIoControl and invocation of the IOCTL in VB.NET:
 
Imports System.Runtime.InteropServices
 
Public Class Form1 Inherits System.Windows.Forms.Form
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu
 
Private Shared METHOD_BUFFERED As Int32 = 0
Private Shared FILE_ANY_ACCESS As Int32 = 0
Private Shared FILE_DEVICE_HAL As Int32 = &H101
Private Shared IOCTL_HAL_REBOOT As Int32 = (&H10000 * FILE_DEVICE_HAL) Or _
(&H4000 * FILE_ANY_ACCESS) Or _
(&H4 * 15) Or METHOD_BUFFERED
Declare Function KernelIoControl _
Lib "CoreDll.dll" (ByVal dwIoControlCode As Int32, _
ByVal lpInBuf As IntPtr, _
ByVal nInBufSize As Int32, _
ByVal lpOutBuf() As Byte, _
ByVal nOutBufSize As Int32, _
ByRef lpBytesReturned As Int32) As Boolean
 
' Generated code, omitted in this example
 
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim outbuff(1) As Byte Dim dwOutBytes As Int32 = 0
If Not KernelIoControl(IOCTL_HAL_REBOOT, _
IntPtr.Zero, _
0, outbuff, 0, dwOutBytes) Then
MessageBox.Show("KernelIoControl failed")
End If
End Sub
End Class

Post to Twitter Post to Delicious Post to Facebook

Comments are closed.

Seek in here
Translator
Archive

Twitter links powered by Tweet This v1.7.3, a WordPress plugin for Twitter.