|
| Code Details |
| |
|
| 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 |
|
|
|
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
|
|
|
|