PDA

Ver la Versión Completa : Ayuda con Fecha de Bios


Novatin
21-05-2013, 18:13:34
Hola...

Aqui voy de nuevo... intento obtener la fecha de Bios de la Pc y para ello pude averiguar que se puede obtener el mismo desde el debug con

FFFF:5 l 8

Pero no me figuro como implementarlo en builder c++ 6... alquien podría darme algun consejo de como implementarlo??

un saludo

ecfisa
21-05-2013, 18:59:14
Hola Novatin.

Bajo DOS podías obtener esos datos en la dirección 0xFFFF5, pero en win32/64 ya no es posible por que el espacio de direcciones de la bios está protegido por el S.O.

Podes obtener esa información desde el registro de windows:

#include <registry.hpp>

AnsiString __fastcall GetBiosDate()
{
char *RegPath = "\\HARDWARE\\DESCRIPTION\\System";
AnsiString BiosDate = "";


TRegistry *reg = new TRegistry(KEY_ALL_ACCESS);
reg->RootKey = HKEY_LOCAL_MACHINE;
__try {
if(reg->KeyExists(RegPath)) {
reg->OpenKey(RegPath, false);
BiosDate = reg->ReadString("SystemBiosDate");
}
}
__finally {
reg->CloseKey();
}
delete reg;
return BiosDate;
}



Llamada:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ShowMessage("BIOS Date: " + GetBiosDate());
}


Saludos :)

Novatin
21-05-2013, 21:51:12
Gracias por la respuesta ecfisa...

Y, debo decir que el codigo me funciona correctamente para windowsXP pero no me funciona para Windows Millenium... :(, es decir el código lo quiero usar indistintamente con winxp o con millenium.. o win98... había probado el debug con d FFFF:5 l 8 con winxp, winme y win98 y me funcionan correctamente...

Asi que fui naufragando con google en busca de una solución "generica" ... hasta que di con esta pagina:
http://www.dailyfreecode.com/code/read-display-date-bios-machine-1768.aspx

Como podría insertarlo en una función en builder?? ... les aviso que de asm no se casi nada.. :( espero puedan ayudarme...

saludos.

ecfisa
22-05-2013, 04:20:57
Hola Novatin.

Otra opción es verificar sobre que OS esta corriendo la aplicación y de acuerdo a eso ejecutar una u otra función. En este hilo vas a poder encontrar algo al respecto: Cómo saber qué tipo de SO es (http://www.clubdelphi.com/foros/showthread.php?t=59866).


Sobre el código assembler, sin ser gran entendido en el tema veo que está llamando a la función INT 21H (http://spike.scu.edu.au/~barry/interrupts.html), que es una función multipropósito del DOS y no vas a poder usarla en aplicaciones de 32 bits.

Saludos. :)

Novatin
22-05-2013, 17:44:05
Bueno en parte creo que eso solucionaría mi problema, aunque se me agrandaría el código por tener que definir funciones para cada tipo de S.O :eek:.... Pero ahora me quedé con muchas más dudas... (y como todo "buen programador" :rolleyes: me gustaría que me ayudaran aclararlas)

Disculpas si mis preguntas son tontas... :o

* Porqué el debug si puede acceder a la captura del bios y porque builder no puede... :confused:
* Otra Más... Encontré este pequeño fragmento de código que esta escrito en TurboC, y funciona correctamente en winxp , winmillenium y msdos...

#include <dos.h>
#include <stdio.h>

void main()
{
int foo, i;

printf("\n");
for(i=0;i<8;i++)
{
foo = peekb(0xf000, 0xFFF5+i);
printf("%c", foo);
}
printf("\n");
}

Pero no puedo hacer que funcione en builder... porque no me reconoce la función "peekb", .. alguna idea para implementarla en builder?? .

Porque TurboC++ si puede acceder a obtener la fecha de bios de esta manera y Builder c++ No? (aun estando en winxp donde se supone que no debería funcionar... pos.. funciona..!)

Cualquier idea bienvenida...

gracias de antemano.

ecfisa
23-05-2013, 02:13:57
Hola Novatin.

Porque TurboC++ si puede acceder a obtener la fecha de bios de esta manera y Builder c++ No?

Es que como te comenté anteriormente, Turbo C fue desarrollado para trabajar en entorno DOS y genera aplicaciones de 16 bits por lo que no tendrá problemas con acceder a esas direcciones.


ncontré este pequeño fragmento de código que esta escrito en TurboC, y funciona correctamente en winxp , winmillenium y msdos...

#include <dos.h>
#include <stdio.h>

void main()
{
int foo, i;

printf("\n");
for(i=0;i<8;i++)
{
foo = peekb(0xf000, 0xFFF5+i);
printf("%c", foo);
}
printf("\n");
}

Pero no puedo hacer que funcione en builder... porque no me reconoce la función "peekb", .. alguna idea para implementarla en builder?? .


El código anterior (sin utilizar peekb) puede implementarse como:

#include <stdio.h>

int main(void)
{
unsigned char far *p = (unsigned char far *)0xF000FFF5; // (*)
int i;

for(i=0; i<8; i++)
printf("%c",(unsigned char far) *(p+i));

getchar();
return 0;
}


Funcionará bíen con Turbo C, pero no será así en el compilador de 32 bits de Builder C++.

(*) Builder c++ no necesita far pointers por lo antedicho, es decir que si deseas probarlo en Builder C++ para salir de dudas, debes quitar "far" del código.

Saludos. :)

Novatin
23-05-2013, 17:41:04
Lamento ser tan incisivo ecfisa... (dejar de ser novato requiere mucho de esto en los días actuales.. :D )

Probé el código siguiente en Builder con los consejos que me diste.. (sin los far):

int main(int argc, char* argv[])
{
unsigned char *p = (unsigned char *)0xF000FFF5;
int i;

for(i=0; i<8; i++)
printf("%c",(unsigned char) *(p+i));

getchar();
return 0;
}

Pero me salta un error... "... raised exception class EAccessViolation with message 'Access Violation at address 0040137A. Read of Address F000FFF5'. Process stopped...."

Entiendo que dice que hubo un error al leer la direccion F0000FFF5 pero de ahí a mas... voy perdido, me faltaría activar alguna otra opción en builder o debo volver al turboC?... :eek:

PD: Es decir se me ocurre que podría hacer una pequeña aplicación en turboC a la que luego llamaría desde Builder con el valor de retorno de la fecha de Bios.. o quiza hasta formar una dll en TurboC y luego invocarla desde el programa de Builder... (aunque al hacer esto siento que soy infiel a Builder... :))

ecfisa
23-05-2013, 18:22:48
Probé el código siguiente en Builder con los consejos que me diste.. (sin los far):

int main(int argc, char* argv[])
{
unsigned char *p = (unsigned char *)0xF000FFF5;
int i;

for(i=0; i<8; i++)
printf("%c",(unsigned char) *(p+i));

getchar();
return 0;
}

Pero me salta un error... "... raised exception class EAccessViolation with message 'Access Violation at address 0040137A. Read of Address F000FFF5'. Process stopped...."


Es por eso que te dije: "Funcionará bíen con Turbo C, pero no será así en el compilador de 32 bits de Builder C++." ;)

Sólo por curiosidad: ¿ Por que motivo deseas tomar la fecha de confección de la BIOS ?

Saludos. :)

Novatin
23-05-2013, 19:33:34
Otra voz...

Yo te había entendido que con los modificadores "far" funcionaba en turboC++ y que sin ellos podría funcionar en BuilderC++ ... a veces uno entiende solo lo que quiere de cada cosa que lee... :D

Ah bueno, lo de la fecha del bios lo quiero para proteger programas... es decir me pareció más confiable tomar la fecha de bios de la tarjeta madre que tomar el numero de serie del disco duro... puesto que el numero de serie del disco duro puede cambiarse muy facilmente o modificarse en caso de formateo del disco; en cambio la fecha de bios de la tarjeta madre se recarga automaticamente con cada reinicio del pc, y los formateos de disco duro no le afectan...:p en este caso también la idea ademas es aprovechar que el cambio de Sistema Operativo no le afecte...

Pero como dicen recorrer un camino de 1000 kms, enpieza siempre con 1 primer paso... y como voy aun no puedo completar el primer paso... :o

ecfisa
23-05-2013, 20:13:48
Hola Novatin.

El problema se presenta cuando se quiere leer desde el espacio del usuario, en el modo virtual protegido, una dirección física. La solución sería ejecutar el código desde el espacio del núcleo.

Y hasta aquí llego yo...:o Si te interesa adentrarte en el tema, busca por "windows kernel mode programming"

Saludos. :)

Novatin
24-05-2013, 18:02:58
Tomaré una nota mental de esto "windows kernel mode programming"... :D

Igual te agradezco por todas las ideas que me diste... no pensé que me complicaría tanto el intentar obtener la fechita esa... yo creo que optare por escribir una *.dll compilada con Borland C 3.1 (creo que este podia generar dlls, aunque nunca hice una.. )... ahora el asunto será si puedo hacer que Builder C++ 6.0 me reconozca una libreria de Borland C++ 3.1... pero con ese asunto creo que me leereís en otro tema... :rolleyes:

Un Saludo.

Novatin
28-05-2013, 19:51:38
Bueno, no quise abrir otro hilo con el mismo tema... asi que decidi usar este.. porque sería "más de lo mismo"..

Estuve probando la opción de intentar crear una libreria con TurboC++ (que me parecía lo más razonable), pero no pude hacerlo... hay muy poca ayuda-guia sobre ello. v\||/

Asi que decidí usar el comando "spawnl" de C++ y que esta soportado por "Builder" y la llame así:

long result;
result = spawnl(P_WAIT, "Bios.exe","Bios.exe", NULL);
return(result);


Donde "Bios.exe" es la aplicación compilada en TurboC con la funcion peek de uno de los anteriores mensajes...

Y sucede que funciona pero con algunas limitantes spwanl solo me devuelve una variable de tipo "unsigned int" en winXP y en winMe solo una variable tipo "unsigned char", aún asi creo que funcionaría codificando la fecha.. en un char; sin embargo tiene un problema mayor (visualmente hablando) puesto que a cada llamada a "spawnl" en builder c++ le antencede una horrible pantalla negra "command"... y eso no me cayo bien para nada.. v\||/

Y bueno, hasta ahora me vengo a enterar de que existen componentes - muchos :p - para Delphi... que se podrían usar en Builder... y luego de "googlear" una buena tarde di con esta solución, esta hecha para delphi... y probé la aplicación ejecutable en winXP y WinMe, donde funciona correctamente... obtiene la fecha de bios aun cambiando esta fecha en el registro de windows xp y winme, lo cual me indica que la debe obtener desde la memoria Rom de la pc...

Pero yo aun voy aprendiendo sobre programacion y la verdad no se como usarlo en builder.. solo se que esta desarrollado para delphi pero no veo la manera de usarlo en builder.. si pudieran orientarme al respecto les quedaria muy agradecido..

Les adjunto el archivo.

un saludo.