Page 1 of 1
Function HB_PING
Posted: Thu Dec 25, 2025 12:58 pm
by acuellar
Estimado Antonio
Es posible incluir la función HB_PING en las LIBs de la nueva versión de FWH
HB_PING.PRG
Code: Select all | Expand
#pragma BEGINDUMP
#include <hbapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
int hb_Ping( const char * cp )
{
HANDLE hIcmpFile;
unsigned long ipaddr;
DWORD dwRetVal;
char SendData[32] = "Data Buffer";
LPVOID ReplyBuffer;
DWORD ReplySize;
ipaddr = inet_addr( cp );
if (ipaddr == INADDR_NONE)
return 1;
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE)
return 2;
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL)
return 3;
dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
NULL, ReplyBuffer, ReplySize, 1000);
if (dwRetVal == 0)
return 4;
return 0;
}
HB_FUNC( HB_PING )
{
hb_retni( hb_Ping( hb_parc( 1 ) ) );
}
#pragma ENDDUMP
Muchas gracias de antemano
Re: Function HB_PING
Posted: Thu Dec 25, 2025 7:27 pm
by Antonio Linares
Estimado Adhemar,
Función añadida a FWH, muchas gracias

* New: function HB_PING( cIP ) --> nResult. Ejemplo de uso:
Code: Select all | Expand
FUNCTION Main()
LOCAL nResultado
LOCAL cIP := "8.8.8.8" // Servidor DNS de Google
// Llamada correcta
nResultado := HB_PING( cIP )
IF nResultado == 0
? "Ping exitoso a " + cIP
ELSE
? "Error al hacer ping. Código:", nResultado
ENDIF
RETURN NIL
Valor Significado Causa en el código C
0 Exito El ping respondió correctamente (dwRetVal != 0).
1 Error de IP El formato de la IP es inválido o se pasó un nombre de dominio (inet_addr falló).
2 Error de Handle No se pudo abrir el archivo ICMP (IcmpCreateFile falló).
3 Error de Memoria No se pudo asignar memoria para la respuesta (malloc falló).
4 Fallo / Timeout Se envió el ping pero no hubo respuesta o hubo error en el envío (dwRetVal == 0).
Gracias a Adhemar Cuellar: viewtopic.php?p=283090#p283090
Re: Function HB_PING
Posted: Thu Dec 25, 2025 8:14 pm
by Jimmy
hi,
i have try it and got
HB_PING.prg(33): warning C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
- Application successfully built *
App was build and run, but how to fix the Warning ?
Re: Function HB_PING
Posted: Fri Dec 26, 2025 5:25 am
by Antonio Linares
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <hbapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
Re: Function HB_PING
Posted: Fri Dec 26, 2025 5:52 am
by Antonio Linares
Modificamos la función para que acepte dominios que se convierten a IPs:
Code: Select all | Expand
#pragma BEGINDUMP
#include <hbapi.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
// Nota: Asegúrate de enlazar con las librerías: ws2_32.lib e iphlpapi.lib
int hb_Ping( const char * cp )
{
HANDLE hIcmpFile;
unsigned long ipaddr;
DWORD dwRetVal;
char SendData[32] = "Data Buffer";
LPVOID ReplyBuffer;
DWORD ReplySize;
// Estructuras para manejo de DNS
WSADATA wsaData;
struct hostent *host;
// 1. Inicializar Winsock (Requerido para gethostbyname)
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
return 5; // Error: No se pudo iniciar Winsock
// 2. Intentar convertir cadena IP numérica directa
ipaddr = inet_addr( cp );
// 3. Si no es numérica, intentar resolver como dominio (DNS)
if (ipaddr == INADDR_NONE)
{
host = gethostbyname( cp );
if ( host == NULL )
{
WSACleanup();
return 1; // Error: Nombre de dominio no válido o no encontrado
}
ipaddr = *(unsigned long *) host->h_addr_list[0];
}
hIcmpFile = IcmpCreateFile();
if (hIcmpFile == INVALID_HANDLE_VALUE)
{
WSACleanup();
return 2;
}
ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
ReplyBuffer = (VOID*) malloc(ReplySize);
if (ReplyBuffer == NULL)
{
IcmpCloseHandle(hIcmpFile); // Cerrar handle antes de salir
WSACleanup();
return 3;
}
dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
NULL, ReplyBuffer, ReplySize, 1000); // 1000ms de timeout
// Limpieza de recursos
free(ReplyBuffer);
IcmpCloseHandle(hIcmpFile);
WSACleanup();
if (dwRetVal == 0)
return 4; // Ping fallido (Timeout o red inalcanzable)
return 0; // Éxito
}
HB_FUNC( HB_PING )
{
hb_retni( hb_Ping( hb_parc( 1 ) ) );
}
#pragma ENDDUMP
Cambios Clave Realizados
WSAStartup: Para usar funciones de DNS (nombres de dominio), Windows requiere que se inicie el subsistema de sockets primero. Si esto falla, devuelve el nuevo error 5.
gethostbyname: Si inet_addr dice que no es una IP numérica (ej. recibes "microsoft.com"), el código ahora entra en el if y pregunta al sistema por la IP de ese nombre.
WSACleanup: Es muy importante liberar los recursos de sockets antes de que la función termine (he agregado estas llamadas antes de cada return).
Limpieza de Memoria: Agregué free(ReplyBuffer) y IcmpCloseHandle antes de salir para evitar fugas de memoria si usas esta función muchas veces seguidas.
Code: Select all | Expand
// 1. Funciona con IPs
nRes := HB_PING( "8.8.8.8" )
// 2. Funciona con Dominios
nRes := HB_PING( "google.com" )
Re: Function HB_PING
Posted: Fri Dec 26, 2025 11:13 am
by acuellar
Excelente
Muchas gracias Estimado Antonio