Modificamos la funci贸n para que acepte dominios que se convierten a IPs:
#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.
// 1. Funciona con IPs
nRes := HB_PING( "8.8.8.8" )
// 2. Funciona con Dominios
nRes := HB_PING( "google.com" )