July 29 2010




 
Search Blog Entries:



What is this?

Code Details
 
Warm reboot of a PocketPC

Description: To be able to reset a PocketPC 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 application from inside Visual Studio.NET 2003 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







Send us your solutions, code, or advice. We might put it here on the site!
 
Back








SpiralFX Web Development
www.spiralfx.com


Do you want to learn developing a full blown Windows Mobile Application? This article and accompanying multimedia content will help you to do so. It will be extended over the upcoming weeks / months, so check back regularly.
 
Read Full Article