martes, 25 de diciembre de 2012

Punteros y Arrays en C

C es uno de los lenguajes de programación más utilizados por su portabilidad, potencia y rapidez, y con él se han escrito sistemas operativos, otros muchos lenguajes y aplicaciones críticas.

En general, el aprendizaje de C no difiere mucho de cualquier otro, pero hay un par de cosas que lo hacen característico: sólo tiene disponible tipos de datos básicos (entero, caracter, etc.) y es necesario tener un conocimiento profundo de punteros y arrays para desplegar toda su potencia.

Los punteros en C siempre han sido tema de discusión por su dificultad, pero eso depende de cómo se expliquen. Uno de los mejores tutoriales de punteros que existen por su simplicidad es el de Ted Jensen (disponible en este enlace), y he realizado la correspondiente traducción con su permiso (disponible en este enlace).

martes, 11 de diciembre de 2012

Información de un sistema Windows con WMI y C

Ya sabemos que WMI es la forma más sencilla de extraer información útil de un sistema Windows, ya sea para realizar diagnósticos, para registrar equipos o para realizar informes.

Buscando la forma más sencilla para conseguir esta información en cualquier máquina Windows, existe un comando de consola que extrae el dato directamente: wmic

Por ejemplo, si queremos ver el número de serie de la máquina local, podemos hacerlo así:

    wmic csproduct get identifyingnumber

de igual forma, si queremos ver el nombre del microprocesador, utilizamos:

    wmic cpu get name

Si con antelación sabemos la información que nos interesa de un sistema, podemos incluir todas
las sentencias que queramos en un archivo por lotes (.bat) y utilizarlo, pero si además nos interesa disponer de un archivo ejecutable que realice lo mismo, podemos hacerlo con un pequeño programa en C, llamado por ejemplo regsys.c de la siguiente forma:

#include <stdio.h>
#include <stdlib.h>

char *wmi();

int main()
{
// número de serie
char *nserie = "wmic csproduct get IdentifyingNumber";
char *pNserie = wmi( nserie );
printf("Numero de serie: %s", pNserie);

// fabricante
char *fabricante = "wmic computersystem get Manufacturer";
char *pFabricante = wmi( fabricante );
printf("Fabricante: %s", pFabricante);

// modelo placa
char *modeloPlaca = "wmic computersystem get model";
char *pModeloPlaca = wmi( modeloPlaca );
printf("Modelo placa: %s", pModeloPlaca);

// arquitectura
char *arq = "wmic computersystem get SystemType";
char *pArq = wmi( arq );
printf("Arquitectura: %s", pArq);

// procesador
char *cpu = "wmic cpu get name";
char *pCpu = wmi( cpu );
printf("Procesador: %s", pCpu);

return 0;
}

char *wmi( char *in )
{
FILE *fp;
char line[130];
char *line2;
line2 = malloc(130 * sizeof(char *));
 
fp = popen( in, "r" );

int x = 0;

while ( fgets( line, sizeof line, fp))
{
if ( x == 1 )
{
int z;

for ( z = 0 ; z < sizeof line ; z++ )
{
line2[z] = line[z];
}
}
x++;
}

pclose(fp);

return line2;
}

Podemos modificar el programa anterior e incluir todas las sentencias WMI que necesitemos mostrar. Además, con los conocimientos necesarios podemos ampliarlo para darle más funcionalidad como aceptar argumentos y escribir informes en un archivo HTML, por ejemplo.

El programa anterior se puede escribir en cualquier Windows, y compilarlo y enlazarlo con MinGW de la siguiente forma:

    cc regsys.c -o regsys.exe

y ya tendremos la herramienta regsys.exe lista para ejecutarlo.