Page 2 of 3
Re: Ayuda Funciones a Bajo Nivel
Posted:
Mon Jun 09, 2014 5:35 pm
by Antonio Linares
Esta versión corrige un error de la anterior pero aún no está dando la información que buscamos:
- Code: Select all Expand view
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
HB_FUNC( TEST )
{
HANDLE disk0;
DWORD retCount, dwRet = 0;
// GETVERSIONINPARAMS versionInfo;
SENDCMDINPARAMS stCIP;
char szOutput[ 512 + 16 ]; // OUT_BUFFER_SIZE IDENTIFY_BUFFER_SIZE+16
/* get a handle for physical disk 0 (the C: drive) */
if ((disk0 = CreateFile (
L"\\\\.\\PhysicalDrive0",
GENERIC_READ,
NULL,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) == INVALID_HANDLE_VALUE)
{
MessageBox( 0, "1", "Info", 0 );
return;
}
memset( szOutput, 0, sizeof( szOutput ) );
#define DRIVE_HEAD_REG 0xA0
stCIP.cBufferSize=IDENTIFY_BUFFER_SIZE;
stCIP.bDriveNumber = 0; // ucDriveIndex;
stCIP.irDriveRegs.bFeaturesReg= 0;
stCIP.irDriveRegs.bSectorCountReg = 1;
stCIP.irDriveRegs.bSectorNumberReg = 1;
stCIP.irDriveRegs.bCylLowReg = 0;
stCIP.irDriveRegs.bCylHighReg = 0;
stCIP.irDriveRegs.bDriveHeadReg = DRIVE_HEAD_REG;
stCIP.irDriveRegs.bCommandReg = ID_CMD;
if ( DeviceIoControl( disk0, SMART_RCV_DRIVE_DATA, &stCIP, sizeof(stCIP), szOutput, 512 + 16,
&dwRet, NULL) )
{
MessageBox( 0, "pasa", "ok", 0 );
}
MessageBox( 0, szOutput, "buffer", 0 );
/* close everything & go home */
CloseHandle (disk0);
// hb_retclen( szOutput, dwRet );
}
#pragma ENDDUMP
Re: Ayuda Funciones a Bajo Nivel
Posted:
Mon Jun 09, 2014 5:39 pm
by Antonio Linares
Esta es la mejor versión que he encontrado hasta ahora para el uso del interface SMART.
Ahora se trata de buscar aqui los valores que necesitas:
http://munin-monitoring.org/browser/munin-node-win32/src/plugins/disk/SmartReader.cpp
Re: Ayuda Funciones a Bajo Nivel
Posted:
Mon Jun 09, 2014 6:28 pm
by Antonio Linares
Prueba con esta:
- Code: Select all Expand view
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
HB_FUNC( TEST )
{
char szVolumeLetter[32];
char szPhysicalDrive[64];
HANDLE hPhysicalDriveIOCTL = CreateFile(L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
DWORD dwBytesReturned = 0;
// Get Physical Drive Information
VOLUME_DISK_EXTENTS vdExtents;
GETVERSIONINPARAMS gvopVersionParams;
ZeroMemory(&vdExtents, sizeof(vdExtents));
if(!DeviceIoControl(hPhysicalDriveIOCTL, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0,
&vdExtents, sizeof(vdExtents), &dwBytesReturned, NULL)){
MessageBox( 0 , "Error volumes that span multiple disks are not supported!", "sorry", 0 );
CloseHandle(hPhysicalDriveIOCTL);
return 1;
}
// Get SMART version information
ZeroMemory(&gvopVersionParams, sizeof(gvopVersionParams));
if(!DeviceIoControl(hPhysicalDriveIOCTL, SMART_GET_VERSION, NULL, 0,
&gvopVersionParams , sizeof(gvopVersionParams), &dwBytesReturned, NULL)){
MessageBox( 0, "Error cannot get SMART version information from device!", "warning", 0 );
CloseHandle(hPhysicalDriveIOCTL);
return 1;
}
if(gvopVersionParams.bIDEDeviceMap > 0)
{
// Setup SMART request
SENDCMDINPARAMS InParams = {
IDENTIFY_BUFFER_SIZE, { 0, 1, 1, 0, 0, ((vdExtents.Extents[0].DiskNumber & 1) ? 0xB0 : 0xA0),
((gvopVersionParams.bIDEDeviceMap >> vdExtents.Extents[0].DiskNumber & 0x10) ? ATAPI_ID_CMD : ID_CMD) },
(BYTE)vdExtents.Extents [0].DiskNumber
};
DWORD dwBufSize = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE;
SENDCMDOUTPARAMS pbtIDOutCmd; // = (PSENDCMDOUTPARAMS) new BYTE[dwBufSize];
ZeroMemory(&pbtIDOutCmd, dwBufSize);
// Get SMART information
if(DeviceIoControl (hPhysicalDriveIOCTL, SMART_RCV_DRIVE_DATA, &InParams, sizeof(SENDCMDINPARAMS),
&pbtIDOutCmd, dwBufSize, &dwBytesReturned, NULL))
{
// Little Endian To Big Endian
USHORT *pIDSector = (USHORT*)pbtIDOutCmd.bBuffer;
int nShort;
char lpszSerialNumber1[ 21 ];
LPSTR lpszSerialNumber2;
for( nShort = 10; nShort < 21; nShort++)
pIDSector [nShort] = (((pIDSector[nShort] & 0x00FF) << 8) + ((pIDSector[nShort] & 0xFF00) >> 8));
// Get Drive Serial Number
ZeroMemory(lpszSerialNumber1, 21);
RtlCopyMemory(lpszSerialNumber1, &pIDSector[10], 20);
// Remove those horrible spaces caused because of endianess
// and print out the serial
lpszSerialNumber2 = lpszSerialNumber1;
while(*lpszSerialNumber2 == ' ') lpszSerialNumber2++;
MessageBox( 0, "Physical Serial:", lpszSerialNumber2, 0);
// delete lpszSerialNumber1;
}
// delete pbtIDOutCmd;
}else{
printf ("Error !\n");
CloseHandle(hPhysicalDriveIOCTL);
return 1;
}
CloseHandle (hPhysicalDriveIOCTL);
}
}
#pragma ENDDUMP
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 12:23 am
by cuatecatl82
Probando y compilando,
Resultados:
El primer código que me sugirio al llmarlo comoTEST() no hace nada, no aparece nada, si lo invoco como MSGINFO(TEST()) aparece "nil"
El segundo código solo muestra un msgbox con "Info 1"
El tercer código no compila salen errores y warnings:
Warning W8075 hardDsk.c 13: Suspicious pointer conversion in function HB_FUN_TEST
Warning W8081 hardDsk.c 39: void functions may not return a value in function HB_FUN_TEST
Warning W8081 hardDsk.c 57: void functions may not return a value in function HB_FUN_TEST
Error E2063 hardDsk.c 71: Illegal initialization in function HB_FUN_TEST
Warning W8081 hardDsk.c 142: void functions may not return a value in function HB_FUN_TEST
Warning W8067 hardDsk.c 148: Both return and return with a value used in function HB_FUN_TEST
Aqui le dejo los fuentes del programa CrystalDiskInfo, que es en lo que me estoy basando.. Mis conocimientos en C son escasos para el nivel de programación de estos codigos..
https://www.mediafire.com/?vcwmzmfypgbv7lfSaludos..
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 7:59 am
by Antonio Linares
Este código fuenciona correctamente compilando con Visual Studio, pero falla con Borland (aún no he encontrado por que no funciona con Borland):
serial.prg
- Code: Select all Expand view
#include "FiveWin.ch"
//----------------------------------------------------------------------------//
function Main()
MsgInfo( SerialNumber() )
return nil
//----------------------------------------------------------------------------//
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
HB_FUNC(SERIALNUMBER)
{
HANDLE hPhysicalDriveIOCTL = 0;
hPhysicalDriveIOCTL = (HANDLE)CreateFile(L"\\\\.\\PhysicalDrive0", 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)
{
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
char buffer[10000];
memset((void *)&query, 0, sizeof(query));
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
memset(buffer, 0, sizeof(buffer));
if (DeviceIoControl(hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof(query),
&buffer,
sizeof(buffer),
&cbBytesReturned, NULL))
{
hb_retclen(buffer + 126, 20);
}
}
}
#pragma ENDDUMP
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 8:13 am
by Antonio Linares
Funcionando con Borland
serial.prg
- Code: Select all Expand view
#include "FiveWin.ch"
//----------------------------------------------------------------------------//
function Main()
MsgInfo( SerialNumber() )
return nil
//----------------------------------------------------------------------------//
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
#define IOCTL_STORAGE_QUERY_PROPERTY 0x2D1400
typedef struct _STORAGE_PROPERTY_QUERY {
int PropertyId;
int QueryType;
BYTE AdditionalParameters[ 1 ];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
HB_FUNC( SERIALNUMBER )
{
HANDLE hPhysicalDriveIOCTL = ( HANDLE ) CreateFile( "\\\\.\\PhysicalDrive0", 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, 0, NULL);
if( hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE )
{
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
char buffer[ 10000 ];
memset( ( void * ) &query, 0, sizeof( query ) );
query.PropertyId = 0; // StorageDeviceProperty;
query.QueryType = 0; // PropertyStandardQuery;
memset( buffer, 0, sizeof( buffer ) );
if( DeviceIoControl( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof( query ),
&buffer,
sizeof( buffer ),
&cbBytesReturned, NULL ) )
{
hb_retclen( buffer + 126, 20 );
}
else
hb_retc( "can't read it" );
}
else
hb_retc( "can't read it" );
}
#pragma ENDDUMP
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 12:49 pm
by cuatecatl82
Maestro Buen día, me levante de madrugada emocionado por probar, pero en mi caso no funciona, talvez el sistema operativo me limita pues lo estoy probando bajo Xp, instale W7 en una máquina virtual y ahí si funciona, no entiendo porque no funciona, es bastante estresante no poder avanzar..
Ooh Oohh y al parecer mi disco duro voló, al reiniciar mi equipo ya no lo hizo, ojala y no pierda todo otra vez.. Veré que puedo hacer.. Me indica error partition table
Saludos
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 1:05 pm
by Antonio Linares
Victor,
Pruébalo así:
serial.prg
- Code: Select all Expand view
#include "FiveWin.ch"
//----------------------------------------------------------------------------//
function Main()
MsgInfo( SerialNumber() )
return nil
//----------------------------------------------------------------------------//
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
#define IOCTL_STORAGE_QUERY_PROPERTY 0x2D1400
typedef struct _STORAGE_PROPERTY_QUERY {
int PropertyId;
int QueryType;
BYTE AdditionalParameters[ 1 ];
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
HB_FUNC( SERIALNUMBER )
{
HANDLE hPhysicalDriveIOCTL = ( HANDLE ) CreateFile( "\\\\.\\PhysicalDrive0", 0,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if( hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE )
{
STORAGE_PROPERTY_QUERY query;
DWORD cbBytesReturned = 0;
char buffer[ 10000 ];
memset( ( void * ) &query, 0, sizeof( query ) );
query.PropertyId = 0; // StorageDeviceProperty;
query.QueryType = 0; // PropertyStandardQuery;
memset( buffer, 0, sizeof( buffer ) );
if( DeviceIoControl( hPhysicalDriveIOCTL, IOCTL_STORAGE_QUERY_PROPERTY,
&query,
sizeof( query ),
&buffer,
sizeof( buffer ),
&cbBytesReturned, NULL ) )
{
hb_retclen( buffer + 126, 20 );
}
else
hb_retc( "can't read it" );
CloseHandle( hPhysicalDriveIOCTL );
}
else
hb_retc( "can't read it" );
}
#pragma ENDDUMP
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 1:06 pm
by Antonio Linares
Victor,
La aplicación GetSerialDiskDemo.exe funciona bien en XP ?
En los códigos fuente que he revisado todos usan los flags FILE_SHARE_READ | FILE_SHARE_WRITE pero pudiera ser que ese flag FILE_SHARE_WRITE sea el culpable de dañar el disco duro. Ante la duda, lo quitamos y ademas faltaba la llamada a CloseHandle().
En la última versión que acabo de poner incluye estos cambios.
No puedes probar en XP en maquina virtual ? Asi te evitas el peligro de que pueda dañar el disco duro, aunque si ya no usamos FILE_SHARE_WRITE no veo como pudiese resultar dañado. Y si se dañó, lo siento de veras. Usar esta tecnología (SMART) que habla directamente con el controlador del disco es muy potente pero obviamente tiene tambien sus riesgos por lo que comentas.
Yo lo he probado en Windows 8 64 bits y funciona correctamente.
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 1:24 pm
by cuatecatl82
Fiu.. Gracias por ser tan amable de comentar Maestro..
Bueno el disco duro volvio con trabajos pero volvio, lo revise con Hirens Boot Cd y me indicaban los programas de recuperacion que mis particiones desaparecienron, volvi a reiniciar y tardo pero arranco XP, de hecho hace rato escribi desde mi movil, y ahora lo hago desde mi maquina.. No hay problema no hay de que disculparse es parte de trabajar con este tipo de funciones, se que es muy peligroso pues trabajamos a muy bajo nivel del disco duro y entiendo los riesgos, lo bueno es que pude reiniciarlo y estoy respaladando datos porque vi que quedo tocado..
Bueno a lo que vamos, el archivo GetSerialDiskDemo.exe si corre perfectamente en XP, de hecho tambien CrystalDiskInfo del cual tengo los fuentes tambien corre perfecto en XP, por eso no entiendo porque estas pruebas no dan resultados,
Voy a instalar XP en Virtual para hacer pruebas, de hecho tengo W/ corriendo en Virtual Pc, la verdad me resisto como muchos a cambiar a W7 o W8 porque es demasiado restrictivo hasta para trabajar con Fivewin..
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 1:48 pm
by Antonio Linares
Victor,
Que problemas tienes con W7 ó W8 ? Yo actualmente programo y desarrollo FWH en Windows 8 (tanto 32 bits como 64 bits) y funcionan correctamente. De hecho en mi opinión W7 es bastante mejor que XP, pues usa mucho más eficientemente la memoria.
La última versión que he publicado de la función que necesitas no debería ya ser peligrosa, de todas formas, ten la precaución de realizar tus backups y para mayor seguridad aún pruébala desde un XP virtual. En Windows 8 64 bits funciona bien.
Si otros usuarios se atreven a usarla, cuidado, no sabemos si lo que le ha ocurrido a Victor pueda estar relacionado con esta función. Asi que ojo, no vayais a estropear el arranque del disco (a nivel software). Y si a alguien le funciona bien en XP por favor que lo comente para que asi sepamos con certeza que el problema de Victor no está relacionado con el uso de esta función.
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 4:01 pm
by cuatecatl82
Después del susto he regresado a probarlo, quite las particiones de mi disco duro y las volví a crear, en una con XP y la otra con W7, el resultado funciona pero con W7 en XP solo lanza el msginfo vacío, maestro Antonio ha podido revisar los fuentes de Crystaldiskinfo que le envie? En Xp funciona bien.
W7 es muy latoso, no puedo borrar carpetas dentro de mi disco de proyectos con un simple archivo. bat siempre me sale con que necesito permisos cuando soy Administrador, quita tiempo estar abriendo programas y te ptegunte si es seguro, me estresa un tanto su entorno lo siento muy limitante.. Además de que muchos equipos no migran a W7 o W8 por lo mismo
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 4:25 pm
by Antonio Linares
Victor,
Es que los fuentes que he revisado en relación a la tecnología SMART son bastante complicados, más que nada porque es una forma de programar que principalmente usan los desarrolladores de drivers, de ahi que no me es familiar en absoluto.
Las mayoría de los fuentes estan en C++ y no permiten una portabilidad a C tal cual. Ayer hice muchas pruebas y el código que he publicado es realmente el único que he conseguido que funcione bien.
Lo has vuelto a probar en XP ? Te funciona ? Me interesa saber si funciona y si vuelve a ocurrirte algo en el disco duro, gracias
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 7:02 pm
by cnavarro
Antonio
En el hd del equipo que lo has desarrollado y probado, tienes más de una partición?
Re: Ayuda Funciones a Bajo Nivel
Posted:
Tue Jun 10, 2014 7:46 pm
by Antonio Linares
Cristobal,
Si, pero lo que está obteniendo es el número de serie del disco (grabado en hardware), no el serial que le da Windows al formatear (grabado en software), si no me equivoco.