Here is a ping utility I wrote for work.
I tested it out and compared it to Windows ping command, and it's almost identical in functionality. Enjoy!

PingTool.h

#include <stdlib.h>
#include <iostream>
#include <winsock2.h>


//Disable Warnings
#pragma warning(disable: 4005)


//
// IP_STATUS codes returned from IP APIs
//


#define IP_STATUS_BASE 11000


#define IP_SUCCESS 0
#define IP_BUF_TOO_SMALL (IP_STATUS_BASE + 1)
#define IP_DEST_NET_UNREACHABLE (IP_STATUS_BASE + 2)
#define IP_DEST_HOST_UNREACHABLE (IP_STATUS_BASE + 3)
#define IP_DEST_PROT_UNREACHABLE (IP_STATUS_BASE + 4)
#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
#define IP_NO_RESOURCES (IP_STATUS_BASE + 6)
#define IP_BAD_OPTION (IP_STATUS_BASE + 7)
#define IP_HW_ERROR (IP_STATUS_BASE + 8)
#define IP_PACKET_TOO_BIG (IP_STATUS_BASE + 9)
#define IP_REQ_TIMED_OUT (IP_STATUS_BASE + 10)
#define IP_BAD_REQ (IP_STATUS_BASE + 11)
#define IP_BAD_ROUTE (IP_STATUS_BASE + 12)
#define IP_TTL_EXPIRED_TRANSIT (IP_STATUS_BASE + 13)
#define IP_TTL_EXPIRED_REASSEM (IP_STATUS_BASE + 14)
#define IP_PARAM_PROBLEM (IP_STATUS_BASE + 15)
#define IP_SOURCE_QUENCH (IP_STATUS_BASE + 16)
#define IP_OPTION_TOO_BIG (IP_STATUS_BASE + 17)
#define IP_BAD_DESTINATION (IP_STATUS_BASE + 18)


//
// Variants of the above using IPv6 terminology, where different
//


#define IP_DEST_NO_ROUTE (IP_STATUS_BASE + 2)
#define IP_DEST_ADDR_UNREACHABLE (IP_STATUS_BASE + 3)
#define IP_DEST_PROHIBITED (IP_STATUS_BASE + 4)
#define IP_DEST_PORT_UNREACHABLE (IP_STATUS_BASE + 5)
#define IP_HOP_LIMIT_EXCEEDED (IP_STATUS_BASE + 13)
#define IP_REASSEMBLY_TIME_EXCEEDED (IP_STATUS_BASE + 14)
#define IP_PARAMETER_PROBLEM (IP_STATUS_BASE + 15)


//
// IPv6-only status codes
//


#define IP_DEST_UNREACHABLE (IP_STATUS_BASE + 40)
#define IP_TIME_EXCEEDED (IP_STATUS_BASE + 41)
#define IP_BAD_HEADER (IP_STATUS_BASE + 42)
#define IP_UNRECOGNIZED_NEXT_HEADER (IP_STATUS_BASE + 43)
#define IP_ICMP_ERROR (IP_STATUS_BASE + 44)
#define IP_DEST_SCOPE_MISMATCH (IP_STATUS_BASE + 45)


#define IP_GENERAL_FAILURE (IP_STATUS_BASE + 50)


//---------------------------Functions to find Window and Class Name---------------------------
struct result_stru
{
char* text;
UINT (__stdcall*GET)(HWND,LPSTR,UINT);
HWND hRet;
};


BOOL WINAPI StruEnumProc( HWND hwnd, result_stru* stru )
{
char loc_buf[128];
stru->GET( hwnd, loc_buf, 127 );
if( strstr( loc_buf, stru->text ) ) {
stru->hRet = hwnd;
return FALSE;
}
return TRUE;
}


//case sensitive!
HWND FindWindowTitleContains( char* text )
{
result_stru res = { text, (UINT (__stdcall *)(HWND,LPSTR,UINT))GetWindowTextA, 0 };
EnumWindows( (WNDENUMPROC)StruEnumProc, (LPARAM)&res );
return res.hRet;
}


//case sensitive!
HWND FindWindowClassContains( char* text )
{
result_stru res = { text, RealGetWindowClassA, 0 };
EnumWindows( (WNDENUMPROC)StruEnumProc, (LPARAM)&res );
return res.hRet;
}
//---------------------------End of Finding Window and Class Name---------------------------


//---------------------------Network Stuff---------------------------


typedef struct
{
unsigned char Ttl; // Time To Live
unsigned char Tos; // Type Of Service
unsigned char Flags; // IP header flags
unsigned char OptionsSize; // Size in bytes of options data
unsigned char *OptionsData; // Pointer to options data


} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;


typedef struct
{
DWORD Address; // Replying address
unsigned long Status; // Reply status
unsigned long RoundTripTime; // RTT in milliseconds
unsigned short DataSize; // Echo data size
unsigned short Reserved; // Reserved for system use
void *Data; // Pointer to the echo data
IP_OPTION_INFORMATION Options; // Reply options


} IP_ECHO_REPLY, * PIP_ECHO_REPLY;




PingTool.cpp

/*
Ping Utility
*/
#include "stdafx.h"
#include <fstream>
#include "PingTool.h"


//Used for pinging
#include <ws2tcpip.h>


//Used for timestamp
#include <time.h>


//Used for CSIDL_DESKTOPDIRECTORY and SHGetFolderPath()
#include <Shlobj.h>


#pragma comment(lib, "ws2_32.lib")


using namespace std;


/*
Global variables
*/
char * host = "jones";
char acPingBuffer[32];
struct hostent * phe;


string convertToIP(const char * filename)
{
char buffer[MAX_PATH];
phe = gethostbyname(host);
ofstream myfile;

myfile.open (filename, ofstream::out | ofstream::app);


if(phe == NULL)
{
sprintf_s(buffer, "%d", WSAGetLastError()); //WSAGetLastError
myfile << "Ping request could not find host " << host << ". Please check the name and try again. " << "Error Code1: " << buffer << endl;


exit(1);
}


in_addr * address = (in_addr * )phe->h_addr;
string ip_address = inet_ntoa(* address);


myfile.close();


return ip_address;
}


void timeStamp(const char * filename)
{
ofstream myfile;
myfile.open (filename, ofstream::out | ofstream::app);


// current date/time based on current system
time_t now = time(0);

// convert now to string form
char* dt = ctime(&now);


myfile << "\n" << dt << endl;
myfile.close();
}


void pingCheck(const char * filename)
{
char timeBuff[MAX_PATH];
char buffer[MAX_PATH];


//File Output
ofstream myfile;


myfile.open (filename, ofstream::out | ofstream::app);


// Load the ICMP.DLL
HINSTANCE hIcmp = LoadLibrary("ICMP.DLL");


if (hIcmp == 0)
{
sprintf_s(buffer, "%d", GetLastError());
myfile << "Unable to locate ICMP.DLL!" << buffer << endl;
}


// Look up an IP address for the given host name
if(phe == NULL)
{
sprintf_s(buffer, "%d", WSAGetLastError());
//myfile << "Could not find IP address for " << host << ". Other Info: " << buffer << endl;
myfile << "Ping request could not find host " << host << ". Please check the name and try again. " << "Error Code: " << buffer << endl;
}


// Get handles to the functions inside ICMP.DLL that we'll need
typedef HANDLE (WINAPI* pfnHV)(VOID);
typedef BOOL (WINAPI* pfnBH)(HANDLE);
typedef DWORD (WINAPI* pfnDHDPWPipPDD)(HANDLE, DWORD, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD);
pfnHV pIcmpCreateFile;
pfnBH pIcmpCloseHandle;
pfnDHDPWPipPDD pIcmpSendEcho;


pIcmpCreateFile = (pfnHV)GetProcAddress(hIcmp, "IcmpCreateFile");
pIcmpCloseHandle = (pfnBH)GetProcAddress(hIcmp, "IcmpCloseHandle");
pIcmpSendEcho = (pfnDHDPWPipPDD)GetProcAddress(hIcmp, "IcmpSendEcho");


if ((pIcmpCreateFile == 0) || (pIcmpCloseHandle == 0) || (pIcmpSendEcho == 0))
{
sprintf_s(buffer, "%d", GetLastError());
myfile << "Failed to get proc addr for function. Error: " << buffer << endl;
}


// Open the ping service
HANDLE hIP = pIcmpCreateFile();


if (hIP == INVALID_HANDLE_VALUE)
{
sprintf_s(buffer, "%d", GetLastError());
myfile << "Unable to open ping service. Error: " << buffer << endl;
}

// Build ping packet
memset(acPingBuffer, '\xAA', sizeof(acPingBuffer));


PIP_ECHO_REPLY pIpe = (PIP_ECHO_REPLY)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer));


if (pIpe == 0)
{
sprintf_s(buffer, "%d", GetLastError());
myfile << "Failed to allocate global ping packet buffer. Error: " << buffer << endl;
}


pIpe->Data = acPingBuffer;
pIpe->DataSize = sizeof(acPingBuffer);


// Send the ping packet
DWORD dwStatus = pIcmpSendEcho(hIP, *((DWORD*)phe->h_addr_list[0]), acPingBuffer, sizeof(acPingBuffer), NULL, pIpe, sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer), 5000);

if (dwStatus != 0)
{
if(pIpe->RoundTripTime < 1)
sprintf_s(timeBuff,"time<%ldms", pIpe->RoundTripTime);
else
sprintf_s(timeBuff,"time=%ldms", pIpe->RoundTripTime);


myfile << "Reply from " <<
int(LOBYTE(LOWORD(pIpe->Address))) << "." <<
int(HIBYTE(LOWORD(pIpe->Address))) << "." <<
int(LOBYTE(HIWORD(pIpe->Address))) << "." <<
int(HIBYTE(HIWORD(pIpe->Address))) << ": " <<
"bytes=" << int(pIpe->DataSize) << " " <<
timeBuff << " " <<
"TTL=" << int(pIpe->Options.Ttl) << endl;


switch (pIpe->Status)
{
case IP_BUF_TOO_SMALL:
{
myfile << "The reply buffer was too small." << endl;
break;
}


case IP_DEST_HOST_UNREACHABLE:
{
myfile << "Destination host was unreachable" << endl;
break;
}


case IP_DEST_NET_UNREACHABLE:
{
myfile << "Destination network was unreachable" << endl;
break;
}


case IP_DEST_PROT_UNREACHABLE:
{
myfile << "Destination protocol was unreachable" << endl;
break;
}


case IP_DEST_PORT_UNREACHABLE:
{
myfile << "Destination port was unreachable" << endl;
break;
}


case IP_NO_RESOURCES:
{
myfile << "Insufficient IP resources were available." << endl;
break;
}


case IP_BAD_DESTINATION:
{
myfile << "A bad destination." << endl;
break;
}


case IP_GENERAL_FAILURE:
{
myfile << "A general failure. This error can be returned for some malformed ICMP packets." << endl;
break;
}


case IP_TTL_EXPIRED_REASSEM:
{
myfile << "The time to live expired during fragment reassembly." << endl;
break;
}


case IP_TTL_EXPIRED_TRANSIT:
{
myfile << "The time to live (TTL) expired in transit." << endl;
break;
}


case IP_BAD_REQ:
{
myfile << "A bad request." << endl;
break;
}


case IP_REQ_TIMED_OUT:
{
myfile << "Request timed out" << endl;
break;
}


default:
{
//If there aren't any errors, then we don't need to print anything
break;
}
}
}
else
{
sprintf_s(buffer, "%d", GetLastError());


DWORD dwError = GetLastError();
switch(dwError)
{
case IP_BUF_TOO_SMALL:
{
myfile << "Reply Buffer Size too small" << endl;
break;
}


case IP_REQ_TIMED_OUT:
{
myfile << "Request timed out" << endl;
break;
}


default:
{
myfile << "Error obtaining info from ping packet. Error: " << buffer << endl;
break;
}
}
}
Sleep(1000);

// Shut down...
myfile.close();
GlobalFree(pIpe);
FreeLibrary(hIcmp);
}


bool isRunning(LPCSTR lpName)
{
//This checks if the process is already running so you don't have multiple instances running.
HANDLE handle = CreateMutex(NULL, true, lpName);


if(GetLastError() != ERROR_SUCCESS)
{
MessageBox(0, "Process is already running", "Warning", MB_ICONWARNING);
return false;
}
else
return true;
}

int _tmain(int argc, _TCHAR* argv[])
{
WSAData wsaData;
char userDesktop[MAX_PATH];
TCHAR szPath[MAX_PATH];


//Check if this process is running
if(isRunning("PingTool") == false)
return 0;


//Minimize this Window
ShowWindow((FindWindowTitleContains("PingTool.exe")), SW_FORCEMINIMIZE);


//File Operation
ofstream myfile;


//Initiate Winsock
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
{
return 255;
}


if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, szPath)))
{
sprintf_s(userDesktop, "%s\\PingTest.txt", szPath);
myfile.open (userDesktop, ofstream::out | ofstream::app);
timeStamp(userDesktop);


string tempIPAddress = convertToIP(userDesktop);
char ipAddress[MAX_PATH];


TCHAR local[MAX_PATH];
DWORD hstSize = sizeof(local);


GetComputerNameEx((COMPUTER_NAME_FORMAT)2,local, &hstSize);


sprintf_s(ipAddress, "%s", tempIPAddress.c_str());


myfile << "Pinging " << host << "." << local << " [" << ipAddress << "] " << "with " << sizeof(acPingBuffer) << " bytes of data:" << endl;
}


//Run until we stop the program
while(1)
{
pingCheck(userDesktop);
}


//Close Winsock
WSACleanup();


return 0;
}