Rilevare Identificativo del Device con VB.NET e C#

Articolo: Rilevare Identificativo del Device (Device ID ) tramite il linguaggio Visual Basic net e C# - ambiente Mobile compact framework 1.0 o 2.0.

il
Sviluppatore Microsoft .Net, Collaboratore di IProgrammatori

Articolo: Rilevare Identificativo del Device (Device ID ) tramite il linguaggio Visual Basic net e C# - ambiente Mobile compact framework 1.0 o 2.0
 
In questo articolo, vedremo come rilevare il codice identificativo del palmare tramite le api di windows, con i linguaggio Visual Basic Net e C#. Tale tecnica si può usare sia per il Compact Framwork versione 1.0 che 2.0
 
 
Inseriamo gli spazi namespace
Vb.Net
Imports System
Imports System.Drawing
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports System.Text
Imports Microsoft.VisualBasic
 
C#
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Text;
Nella classe inseriamo la dichiarazione di api, in particolare KernelIoControl e la funzione IOCTL_HAL_GET_DEVICEID Di seguito si riporta tale dichiarazione
Vb.Net
'dichiarazione di api
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
Private Shared METHOD_BUFFERED As Int32 = 0
Private Shared FILE_ANY_ACCESS As Int32 = 0
Private Shared FILE_DEVICE_HAL As Int32 = &H101
Private Const ERROR_NOT_SUPPORTED As Int32 = &H32
Private Const ERROR_INSUFFICIENT_BUFFER As Int32 = &H7A
Private Shared IOCTL_HAL_GET_DEVICEID As Int32 = _
(&H10000 * FILE_DEVICE_HAL) Or (&H4000 * FILE_ANY_ACCESS) _
Or (&H4 * 21) Or METHOD_BUFFERED
 
C#
//dichiarazione di api
private static Int32 METHOD_BUFFERED = 0;
private static Int32 FILE_ANY_ACCESS = 0;
private static Int32 FILE_DEVICE_HAL = 0x00000101;
private const Int32 ERROR_NOT_SUPPORTED = 0x32;
private const Int32 ERROR_INSUFFICIENT_BUFFER = 0x7A;
private static Int32 IOCTL_HAL_GET_DEVICEID =
((FILE_DEVICE_HAL) << 16) | ((FILE_ANY_ACCESS) << 14)
| ((21) << 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);
Fatto ciò dobbiamo creare una funzione che tramite cicli ottenga il valore identificativo del palmare. Di seguito si riporta la funzione per ottenere tale valore.
Vb.Net
'funzione per rilevare il codice id
Private Shared Function GetDeviceID() As String
' Inizializzo la dimensione per il buffer di output
Dim outbuff(19) As Byte
Dim dwOutBytes As Int32
Dim done As Boolean = False
Dim nBuffSize As Int32 = outbuff.Length
'effettuo le conversioni per la dimensione per il buffer di output
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0)
dwOutBytes = 0
' ciclo fino a quando no trovo l'id del device o un errore
While Not done
If KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero, _
0, outbuff, nBuffSize, dwOutBytes) Then
done = True
Else
Dim errnum As Integer = Marshal.GetLastWin32Error()
Select Case errnum
Case ERROR_NOT_SUPPORTED
Throw New NotSupportedException( _
"IOCTL_HAL_GET_DEVICEID non è supportato per questo device", _
New Win32Exception(errnum))
Case ERROR_INSUFFICIENT_BUFFER
' Il buffer non essendo abbansta grande verranno considerati i primi 4 bytes
nBuffSize = BitConverter.ToInt32(outbuff, 0)
outbuff = New Byte(nBuffSize) {}
' Si imposta la dimensione del DEVICEID.dwSize in ordine di grandezza
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0)
Case Else
Throw New Win32Exception(errnum, "Errore nel rilevamento dato ")
End Select
End If
End While
' Effettuo le dovute conversione ai valori ottenuti in precedenso, tali valori verrano gestiti nei successivi cicli
Dim dwPresetIDOffset As Int32 = BitConverter.ToInt32(outbuff, &H4)
Dim dwPresetIDSize As Int32 = BitConverter.ToInt32(outbuff, &H8)
Dim dwPlatformIDOffset As Int32 = BitConverter.ToInt32(outbuff, &HC)
Dim dwPlatformIDSize As Int32 = BitConverter.ToInt32(outbuff, &H10)
Dim sb As New StringBuilder
Dim i As Integer
'ciclo per il primo elemento del codice id
For i = dwPresetIDOffset To (dwPresetIDOffset + dwPresetIDSize) - 1
sb.Append(String.Format("{0:X2}", outbuff(i)))
Next i
'divido il codice tramite trattino
sb.Append("-")
'cicolo per il secondo elemento del codice id
For i = dwPlatformIDOffset To (dwPlatformIDOffset + dwPlatformIDSize) - 1
sb.Append(String.Format("{0:X2}", outbuff(i)))
Next i
Return sb.ToString()
End Function
 
C#
//funzione per rilevare il codice id
private static string GetDeviceID()
{
// Inizializzo la dimensione per il buffer di output
byte[] outbuff = new byte[20];
Int32 dwOutBytes;
bool done = false;
Int32 nBuffSize = outbuff.Length;
// effettuo le conversioni per la dimensione per il buffer di output
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0);
dwOutBytes = 0;
// ciclo fino a quando no trovo l'id del device o un errore
while (! done)
{
if (KernelIoControl(IOCTL_HAL_GET_DEVICEID, IntPtr.Zero,
0, outbuff, nBuffSize, ref dwOutBytes))
{
done = true;
}
else
{
int error = Marshal.GetLastWin32Error();
switch (error)
{
case ERROR_NOT_SUPPORTED:
throw new NotSupportedException(
"IOCTL_HAL_GET_DEVICEID non è supportato per questo device",
new Win32Exception(error));
case ERROR_INSUFFICIENT_BUFFER:
// Il buffer non essendo abbansta grande verranno considerati i primi 4 bytes
nBuffSize = BitConverter.ToInt32(outbuff, 0);
outbuff = new byte[nBuffSize];
// Si imposta la dimensione del DEVICEID.dwSize in ordine di grandezza
BitConverter.GetBytes(nBuffSize).CopyTo(outbuff, 0);
break;
default:
throw new Win32Exception(error, "Errore nel rilevamento dato");
}
}
}
// Effettuo le dovute conversione ai valori ottenuti in precedenso, tali valori verrano gestiti nei successivi cicli
Int32 dwPresetIDOffset = BitConverter.ToInt32(outbuff, 0x4);
Int32 dwPresetIDSize = BitConverter.ToInt32(outbuff, 0x8);
Int32 dwPlatformIDOffset = BitConverter.ToInt32(outbuff, 0xc);
Int32 dwPlatformIDSize = BitConverter.ToInt32(outbuff, 0x10);
StringBuilder sb = new StringBuilder();
//ciclo per il primo elemento del codice id
for (int i = dwPresetIDOffset;
i < dwPresetIDOffset + dwPresetIDSize; i++)
{
sb.Append(String.Format("{0:X2}", outbuff[i]));
}
//divido il codice tramite trattino
sb.Append("-");
//cicolo per il secondo elemento del codice id
for (int i = dwPlatformIDOffset;
i < dwPlatformIDOffset + dwPlatformIDSize; i ++ )
{
sb.Append( String.Format("{0:X2}", outbuff[i]));
}
return sb.ToString();
}
 
A questo punto non resta che eseguire tale funzione per esempio dall'evento click di un pulsnate, ottenendo così il codice del palmare.
Vb.Net
Private Sub BtnValore_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnValore.Click
Try
' Visualizzo l'id del device
Dim deviceID As String = GetDeviceID()
MsgBox("Device ID: " + deviceID)
Catch ex As Exception
MsgBox(ex.Message.ToString())
End Try
End Sub
 
C#
private void btnrileva_Click(object sender, EventArgs e)
{
try
{
// Visualizza Id
string strDeviceID = GetDeviceID();
MessageBox.Show("Device ID: " + strDeviceID);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
 
Conclusioni
In questo articolo, si è visto come che sfruttare le api di windows mobile per ottenere il codice identificativo del palmare,  tale codice può tornare utile, nel caso che vogliamo dotare le nostre applicazioni con una maggiore sicurezza in fatto di installazione limitate.
Tramite la parola Download è possibile scaricare il file di esempio di questo articolo.