Windows兼容XP-Win10的CPing工具类
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>
//#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
class CPing {
typedef HANDLE(WINAPI*PFN_IcmpCreateFile)();
typedef DWORD(WINAPI*PFN_IcmpSendEcho)(
HANDLE IcmpHandle,
IPAddr DestinationAddress,
LPVOID RequestData,
WORD RequestSize,
PIP_OPTION_INFORMATION RequestOptions,
LPVOID ReplyBuffer,
DWORD ReplySize,
DWORD Timeout
);
typedef DWORD(WINAPI*PFN_IcmpParseReplies)(
LPVOID ReplyBuffer,
DWORD ReplySize
);
typedef BOOL(WINAPI*PFN_IcmpCloseHandle)(
HANDLE IcmpHandle
);
public:
CPing() {
hModule = GetModuleHandle(TEXT("IPHLPAPI"));
if (hModule == nullptr)
{
hModule = LoadLibrary(TEXT("IPHLPAPI"));
if (hModule != nullptr)
{
bLoad = true;
}
else
{
hModule = GetModuleHandle(TEXT("ICMP"));
if (hModule == nullptr)
{
hModule = LoadLibrary(TEXT("ICMP"));
if (hModule != nullptr)
{
bLoad = true;
}
}
}
}
if (hModule != nullptr)
{
fnIcmpCreateFile = (PFN_IcmpCreateFile)GetProcAddress(hModule, "IcmpCreateFile");
fnIcmpSendEcho = (PFN_IcmpSendEcho)GetProcAddress(hModule, "IcmpSendEcho");
fnIcmpParseReplies = (PFN_IcmpParseReplies)GetProcAddress(hModule, "IcmpParseReplies");
fnIcmpCloseHandle = (PFN_IcmpCloseHandle)GetProcAddress(hModule, "IcmpCloseHandle");
}
}
~CPing() {
if (bLoad == true)
{
fnIcmpCreateFile = nullptr;
fnIcmpSendEcho = nullptr;
fnIcmpParseReplies = nullptr;
fnIcmpCloseHandle = nullptr;
FreeLibrary(hModule);
hModule = nullptr;
bLoad = false;
}
}
private:
bool bLoad = false;
HMODULE hModule = nullptr;
PFN_IcmpCreateFile fnIcmpCreateFile = nullptr;
PFN_IcmpSendEcho fnIcmpSendEcho = nullptr;
PFN_IcmpParseReplies fnIcmpParseReplies = nullptr;
PFN_IcmpCloseHandle fnIcmpCloseHandle = nullptr;
bool IsAvailable()
{
return ((fnIcmpCreateFile != nullptr) && (fnIcmpSendEcho != nullptr) && (fnIcmpParseReplies != nullptr) && (fnIcmpCloseHandle != nullptr));
}
public:
static bool ping_main(const std::string& ip)
{
bool result = false;
DWORD dwRet = 0;
// Declare and initialize variables
HANDLE hIcmpFile = INVALID_HANDLE_VALUE;
unsigned long ipaddr = INADDR_NONE;
char SendData[4] = "ACK";
DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
BYTE ReplyBuffer[sizeof(ICMP_ECHO_REPLY) + sizeof(SendData)] = { 0 };
if (Inst()->IsAvailable())
{
// Validate the parameters
ipaddr = inet_addr(ip.c_str());
if (ipaddr == INADDR_NONE) {
return false;
}
hIcmpFile = Inst()->fnIcmpCreateFile();
if (hIcmpFile != INVALID_HANDLE_VALUE)
{
dwRet = Inst()->fnIcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData), NULL, ReplyBuffer, ReplySize, 1000);
if (dwRet != 0)
{
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
if (pEchoReply->Status == IP_SUCCESS)
{
result = true;
}
}
Inst()->fnIcmpCloseHandle(hIcmpFile);
}
}
return result;
}
public:
static CPing* Inst()
{
static CPing CPingInstance;
return &CPingInstance;
}
};