Marzo 2010
L M X J V S D
« Feb    
1234567
891011121314
15161718192021
22232425262728
293031  

WMI Code Creator

Unas de las entradas más populares del blog son, dejando de lado aquellas que cuentan la falacia de intentar descubrir quiénes nos han excluido de su lista de amigos en el Messenger, las que creé intentando explicar el modo de conseguir el número de serie “físico” de una unidad USB, o del disco duro del equipo. Fundamentalmente, el uso que le vienen dando a este código los visitantes que llegan al blog es la protección de nuestro software frente a la piratería. Bien distribuyendo el software con una asociación a un dispositivo USB, bien vinculándolo en su instalación a una determinada máquina, obteniendo de ella información difícilmente sustituible (como el número de serie del disco duro donde se instaló, o el de la placa base o el procesador). Sin ser métodos del todo fiables para proteger el software, sí que pueden servir para evitar una copia masiva del mismo, especialmente entre usuarios poco avanzados, y en tanto no sea tan popular como para que surja un crack o un método de romper nuestra protección de forma masiva.

Recientemente, otro lector del blog me consultaba sobre este aspecto, así que he querido subrayar los dos artículos mencionados con el uso de WMI (Windows Management Instrumentation) para conseguir información del sistema, de una forma clara y sencilla. Pero como no quiero profundizar en el conocimiento de las librerías WMI más allá de lo que ya explica de por sí la MSDN de una forma bastante más profunda de la que podemos tratar aquí, sí que me gustaría dejaros con una herramienta, cortesía de Microsoft, que permite automatizar la creación de código para el manejo de estos dispositivos. Se trata de WMI Code Creator, y consiste en un simple formulario que nos permite examinar la jerarquía de objetos, clases y métodos que podemos consultar mediante WMI, podemos llegar a ejecutar consultas y, para mayor gloria suya, nos genera código de forma automática en tres lenguajes: C#, VB.NET y VBScript. Una gozada con la que os dejo jugando durante el fin de semana.

¡Feliz descanso!


Entradas relacionadas:
  • Protección ante XSRF
  • Control de acceso de un usuario en ASP.NET
  • Encriptación de una unidad USB mediante TrueCrypt
  • TrueCrypt
  • Soy ciudadano americano
  • Etiquetas: , , ,

    Obtener el número de serie de un dispositivo USB mediante clases WMI

    En el ejemplo de ayer veíamos cómo crear un sistema de protección del software frente a copias ilegales del mismo, y nos basábamos para ello en una sencilla clase que consultaba el número de serie de los dispositivos USB. Al no tener acceso inicialmente al código interno de la misma, íbamos recorriendo todas las unidades del sistema, obteniendo su número de serie y comparándolo con el de referencia, que debería ser, claro está, el de la llave USB que habíamos proporcionado con el programa. Su uso era francamente sencillo, y bastaba con llamar al método GetSerialNumber() para obtener el número de serie de la unidad cuya letra pasáramos como argumento al mismo. Un ejemplo simple de su uso en un WinForm podría ser:

    C#:
    1. private void btnObtenerNumSerie_Click(object sender, EventArgs e)
    2. {
    3. USBDrives usbsn = new USBDrives();
    4. txtSN.Text = usbsn.GetSerialNumber(txtDrive.Text);
    5. }

    Ya advertimos que no se trataba de una aplicación totalmente segura (aunque podría usarse con éxito en pequeños proyectos, o conjuntamente con otras medidas de seguridad),y su función era ver una utilidad práctica para los conceptos que introduciré hoy: una introducción al manejo de dispositivos USB a través de las consultas sobre WMI (Windows Management Instrumentation, la implementación de Microsoft de WBEM, una iniciativa que pretende establecer una serie de estándares para permitir el acceso y compartir información de administración a través de una red empresarial).

    La clase USBDrives contiene varios métodos privados, que se encargan fundamentalmente de parsear la información del dispositivo, tanto a la entrada del método GetSerialNumber () , que recibe la letra del dispositivo a examinar, tanto internamente, eliminando diversos caracteres innecesarios en los identificadores y nombres del mismo. El método que lleva todo el peso de la conversión es GetDriveSerialNumber(), cuyo código veremos a continuación:

    C#:
    1. /// <summary>
    2. /// Consulta el ManagementObjectSearcher para obtener el número de serie.
    3. /// </summary>
    4. private void GetDriveSerialNumber()
    5. {
    6. string[] disks;
    7. string drvNumber = string.Empty;
    8. string drvLetter = string.Empty;
    9.  
    10. ManagementObjectSearcher objSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_LogicalDiskToPartition");
    11. foreach (ManagementObject diskManagement in objSearcher.Get())
    12. {
    13. disks = null;
    14. drvLetter = ParserValue(diskManagement["Dependent"].ToString());
    15. if (drvLetter == this._driveLetter)
    16. {
    17. disks = ParserValue(diskManagement["Antecedent"].ToString()).Split(',');
    18. drvNumber = disks[0].Remove(0, 6).Trim();
    19.  
    20. ManagementObjectSearcher disks = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive");
    21. foreach (ManagementObject disk in disks.Get())
    22. if (disk["Name"].ToString() == ("\\\\.\\PHYSICALDRIVE" + drvNumber) &amp; disk["InterfaceType"].ToString() == "USB")
    23. this._serialNumber = ParserSerial(disk["PNPDeviceID"].ToString());
    24. }
    25. }
    26. }

    Para poder usar el código, debemos importar el ensamblado System.Management, que permite el uso de WMI, y su lenguaje de consulta WQL. Veamos qué hace este código.

    Tras un bloque de declaración e inicialización de variables, instancia un objeto de la clase ManagementObjectSearcher, que será el encargado de ejecutar una consulta a algunas clases WMI Win32 para obtener las particiones lógicas y las unidades del sistema. Tras esto, iremos recorriéndolas, recuperando el árbol de unidades existentes en el equipo. Establecemos una comparación entre la letra de dispositivo (a partir de su ID correspondiente) y la que nos pasaron para obtener, y examinamos el valor del InterfaceType para saber si se trata de un dispositivo USB. Si en algún momento coincide todo ello, tenemos nuestra unidad localizada. El número de serie se obtiene a partir del PNPDeviceID, eliminando caracteres como "\" y "&".

    Tal y como hemos visto, se trata de un método cómodo, elegante y organizado de obtener información de un dispositivo a partir de WMI, en lugar de tener que hacerlo mediante llamadas directas a la API de Windows (librería win32.dll en este caso) o usando código no manejado.

    Para saber más:


    Entradas relacionadas:
  • Obtener el número de serie del disco duro en .NET
  • Un microgestor de descargas casero
  • Evitando fallos de carga dinámica de ensamblados
  • Examinando los ADS
  • Ironías de la vida
  • Etiquetas: , , ,

    |