Index: base/applications/network/ping/ping.rc =================================================================== --- base/applications/network/ping/ping.rc (revision 49200) +++ base/applications/network/ping/ping.rc (working copy) @@ -1,7 +1,12 @@ /* $Id$ */ +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 Ping\0" +#define REACTOS_STR_INTERNAL_NAME "ping\0" +#define REACTOS_STR_ORIGINAL_FILENAME "ping.exe\0" +#define REACTOS_STR_ORIGINAL_COPYRIGHT "Casper S. Hornstrup (chorns@users.sourceforge.net)\0" +#include -#define REACTOS_STR_FILE_DESCRIPTION "ReactOS TCP/IPv4 Win32 Ping\0" -#define REACTOS_STR_INTERNAL_NAME "ping\0" -#define REACTOS_STR_ORIGINAL_FILENAME "ping.exe\0" -#define REACTOS_STR_ORIGINAL_COPYRIGHT "Casper S. Hornstrup (chorns@users.sourceforge.net)\0" -#include +#include "lang/en-US.rc" + Index: base/applications/network/ping/lang/en-US.rc =================================================================== --- base/applications/network/ping/lang/en-US.rc (revision 0) +++ base/applications/network/ping/lang/en-US.rc (revision 0) @@ -0,0 +1,35 @@ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +STRINGTABLE DISCARDABLE +BEGIN + IDS_USAGE "\nUsage: ping [-t] [-n count] [-l size] [-w timeout] destination-host\n\n" \ + "Options:\n" \ + " -t Ping the specified host until stopped.\n" \ + " To stop - type Control-C.\n" \ + " -n count Number of echo requests to send.\n" \ + " -l size Send buffer size.\n" \ + " -w timeout Timeout in milliseconds to wait for each reply.\n\n\0" + + IDS_PING_WITH_BYTES "\nPinging %1 [%2] with %3!d! bytes of data:\n\n\0" + IDS_PING_STATISTICS "\nPing statistics for %1:\n\0" + IDS_PACKETS_SENT_RECEIVED_LOST " Packets: Sent = %1!d!, Received = %2!d!, Lost = %3!d! (%4!d!%% loss),\n\0" + IDS_APPROXIMATE_ROUND_TRIP "Approximate round trip times in milli-seconds:\n\0" + IDS_MIN_MAX_AVERAGE " Minimum = %1, Maximum = %2, Average = %3\n\0" + IDS_NOT_ENOUGH_RESOURCES "Not enough free resources available.\n\0" + IDS_UNKNOWN_HOST "Unknown host %1.\n\0" + IDS_SETSOCKOPT_FAILED "setsockopt failed (%1!d!).\n\0" + IDS_COULD_NOT_CREATE_SOCKET "Could not create socket (#%1!d!).\n\0" + IDS_COULD_NOT_INIT_WINSOCK "Could not initialize winsock dll.\n\0" + IDS_DEST_MUST_BE_SPECIFIED "Name or IP address of destination host must be specified.\n\0" + IDS_BAD_PARAMETER "Bad parameter %1.\n\0" + IDS_BAD_OPTION_FORMAT "Bad option format %1.\n\0" + IDS_BAD_OPTION "Bad option %1.\n\0" + IDS_BAD_VALUE_OPTION_L "Bad value for option -l, valid range is from 0 to %1!d!.\n\0" + IDS_REPLY_FROM "Reply from %1: bytes=%2!d! time%3%4 TTL=%5!d!\n\0" + IDS_DEST_UNREACHABLE "Destination host unreachable.\n\0" + IDS_COULD_NOT_TRANSMIT "Could not transmit data (%1!d!).\n\0" + IDS_COULD_NOT_RECV "Could not receive data (%1!d!).\n\0" + IDS_REQUEST_TIMEOUT "Request timed out.\n\0" + IDS_MS "ms\0" + IDS_1MS "1ms\0" +END Index: base/applications/network/ping/ping.rbuild =================================================================== --- base/applications/network/ping/ping.rbuild (revision 49200) +++ base/applications/network/ping/ping.rbuild (working copy) @@ -1,9 +1,10 @@ - + . ws2_32 + user32 ping.c ping.rc Index: base/applications/network/ping/resource.h =================================================================== --- base/applications/network/ping/resource.h (revision 0) +++ base/applications/network/ping/resource.h (revision 0) @@ -0,0 +1,24 @@ +#define IDS_USAGE 0 +#define IDS_PING_WITH_BYTES 1 +#define IDS_PING_STATISTICS 2 +#define IDS_PACKETS_SENT_RECEIVED_LOST 3 +#define IDS_APPROXIMATE_ROUND_TRIP 4 +#define IDS_MIN_MAX_AVERAGE 5 +#define IDS_NOT_ENOUGH_RESOURCES 6 +#define IDS_UNKNOWN_HOST 7 +#define IDS_SETSOCKOPT_FAILED 8 +#define IDS_COULD_NOT_CREATE_SOCKET 9 +#define IDS_COULD_NOT_INIT_WINSOCK 10 +#define IDS_DEST_MUST_BE_SPECIFIED 11 +#define IDS_BAD_PARAMETER 12 +#define IDS_BAD_OPTION_FORMAT 13 +#define IDS_BAD_OPTION 14 +#define IDS_BAD_VALUE_OPTION_L 15 +#define IDS_REPLY_FROM 16 +#define IDS_DEST_UNREACHABLE 17 +#define IDS_COULD_NOT_TRANSMIT 18 +#define IDS_COULD_NOT_RECV 19 +#define IDS_REQUEST_TIMEOUT 20 +#define IDS_MS 21 +#define IDS_1MS 22 + Property changes on: resource.h ___________________________________________________________________ Added: svn:eol-style + native Index: base/applications/network/ping/ping.c =================================================================== --- base/applications/network/ping/ping.c (revision 49200) +++ base/applications/network/ping/ping.c (working copy) @@ -12,6 +12,7 @@ #include #include #include +#include "resource.h" #define NDEBUG @@ -67,10 +68,10 @@ ULONG TTLValue; ULONG TOSValue; ULONG Timeout; -CHAR TargetName[256]; +WCHAR TargetName[256]; SOCKET IcmpSock; SOCKADDR_IN Target; -LPSTR TargetIP; +WCHAR TargetIP[16]; FD_SET Fds; TIMEVAL Timeval; UINT CurrentSeqNum; @@ -85,6 +86,7 @@ LARGE_INTEGER TicksPerUs; /* Ticks per microsecond */ LARGE_INTEGER SentTime; BOOL UsePerformanceCounter; +HANDLE hStdOutput; #ifndef NDEBUG /* Display the contents of a buffer */ @@ -107,16 +109,47 @@ } #endif /* !NDEBUG */ +void FormatOutput(UINT uID, ...) +{ + va_list valist; + + WCHAR Buf[1024]; + LPWSTR pBuf = Buf; + LPWSTR Format; + DWORD written; + UINT DataLength; + + va_start(valist, uID); + + if(!LoadString(NULL, uID, (LPWSTR)&Format, 0)) + return; + + DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING, Format, 0, 0, Buf,\ + sizeof(Buf) / sizeof(WCHAR), &valist); + + if(!DataLength) + { + if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return; + + DataLength = FormatMessage(FORMAT_MESSAGE_FROM_STRING |\ + FORMAT_MESSAGE_ALLOCATE_BUFFER,\ + Format, 0, 0, (LPWSTR)&pBuf, 0, &valist); + + if(!DataLength) + return; + } + + WriteConsole(hStdOutput, pBuf, DataLength, &written, NULL); + + if(pBuf != Buf) + LocalFree(pBuf); +} + /* Display usage information on screen */ static VOID Usage(VOID) { - printf("\nUsage: ping [-t] [-n count] [-l size] [-w timeout] destination-host\n\n"); - printf("Options:\n"); - printf(" -t Ping the specified host until stopped.\n"); - printf(" To stop - type Control-C.\n"); - printf(" -n count Number of echo requests to send.\n"); - printf(" -l size Send buffer size.\n"); - printf(" -w timeout Timeout in milliseconds to wait for each reply.\n\n"); + FormatOutput(IDS_USAGE); } /* Reset configuration to default values */ @@ -157,26 +190,26 @@ } /* Return ULONG in a string */ -static ULONG GetULONG(LPSTR String) +static ULONG GetULONG(LPWSTR String) { UINT i, Length; ULONG Value; - LPSTR StopString; + LPWSTR StopString; i = 0; - Length = (UINT)_tcslen(String); - while ((i < Length) && ((String[i] < '0') || (String[i] > '9'))) i++; - if ((i >= Length) || ((String[i] < '0') || (String[i] > '9'))) + Length = (UINT)wcslen(String); + while ((i < Length) && ((String[i] < L'0') || (String[i] > L'9'))) i++; + if ((i >= Length) || ((String[i] < L'0') || (String[i] > L'9'))) { InvalidOption = TRUE; return 0; } - Value = strtoul(&String[i], &StopString, 10); + Value = wcstoul(&String[i], &StopString, 10); return Value; } /* Return ULONG in a string. Try next paramter if not successful */ -static ULONG GetULONG2(LPSTR String1, LPSTR String2, PINT i) +static ULONG GetULONG2(LPWSTR String1, LPWSTR String2, PINT i) { ULONG Value; @@ -184,7 +217,7 @@ if (InvalidOption) { InvalidOption = FALSE; - if (String2[0] != '-') + if (String2[0] != L'-') { Value = GetULONG(String2); if (!InvalidOption) @@ -196,7 +229,7 @@ } /* Parse command line parameters */ -static BOOL ParseCmdline(int argc, char* argv[]) +static BOOL ParseCmdline(int argc, LPWSTR argv[]) { INT i; BOOL ShowUsage; @@ -210,34 +243,35 @@ for (i = 1; i < argc; i++) { - if (argv[i][0] == '-') + if (argv[i][0] == L'-') { switch (argv[i][1]) { - case 't': NeverStop = TRUE; break; - case 'a': ResolveAddresses = TRUE; break; - case 'n': PingCount = GetULONG2(&argv[i][2], argv[i + 1], &i); break; - case 'l': + case L't': NeverStop = TRUE; break; + case L'a': ResolveAddresses = TRUE; break; + case L'n': PingCount = GetULONG2(&argv[i][2], argv[i + 1], &i); break; + case L'l': DataSize = GetULONG2(&argv[i][2], argv[i + 1], &i); if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER)) { - printf("Bad value for option -l, valid range is from 0 to %d.\n", - ICMP_MAXSIZE - (int)sizeof(ICMP_ECHO_PACKET) - (int)sizeof(IPv4_HEADER)); + FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \ + (int)sizeof(ICMP_ECHO_PACKET) - \ + (int)sizeof(IPv4_HEADER)); return FALSE; } break; - case 'f': DontFragment = TRUE; break; - case 'i': TTLValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; - case 'v': TOSValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; - case 'w': Timeout = GetULONG2(&argv[i][2], argv[i + 1], &i); break; + case L'f': DontFragment = TRUE; break; + case L'i': TTLValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; + case L'v': TOSValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; + case L'w': Timeout = GetULONG2(&argv[i][2], argv[i + 1], &i); break; default: - printf("Bad option %s.\n", argv[i]); + FormatOutput(IDS_BAD_OPTION, argv[i]); Usage(); return FALSE; } if (InvalidOption) { - printf("Bad option format %s.\n", argv[i]); + FormatOutput(IDS_BAD_OPTION_FORMAT, argv[i]); return FALSE; } } @@ -245,12 +279,12 @@ { if (FoundTarget) { - printf("Bad parameter %s.\n", argv[i]); + FormatOutput(IDS_BAD_PARAMETER, argv[i]); return FALSE; } else { - lstrcpy(TargetName, argv[i]); + wcscpy(TargetName, argv[i]); FoundTarget = TRUE; } } @@ -258,7 +292,7 @@ if ((!ShowUsage) && (!FoundTarget)) { - printf("Name or IP address of destination host must be specified.\n"); + FormatOutput(IDS_DEST_MUST_BE_SPECIFIED); return FALSE; } @@ -298,20 +332,21 @@ INT Status; ULONG Addr; PHOSTENT phe; + CHAR aTargetName[256]; wVersionRequested = MAKEWORD(2, 2); Status = WSAStartup(wVersionRequested, &WsaData); if (Status != 0) { - printf("Could not initialize winsock dll.\n"); + FormatOutput(IDS_COULD_NOT_INIT_WINSOCK); return FALSE; } IcmpSock = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0); if (IcmpSock == INVALID_SOCKET) { - printf("Could not create socket (#%d).\n", WSAGetLastError()); + FormatOutput(IDS_COULD_NOT_CREATE_SOCKET, WSAGetLastError()); return FALSE; } @@ -321,8 +356,8 @@ (const char *)&DontFragment, sizeof(DontFragment)) == SOCKET_ERROR) { - printf("setsockopt failed (%d).\n", WSAGetLastError()); - return FALSE; + FormatOutput(IDS_SETSOCKOPT_FAILED, WSAGetLastError()); + return FALSE; } if (setsockopt(IcmpSock, @@ -331,35 +366,44 @@ (const char *)&TTLValue, sizeof(TTLValue)) == SOCKET_ERROR) { - printf("setsockopt failed (%d).\n", WSAGetLastError()); - return FALSE; + FormatOutput(IDS_SETSOCKOPT_FAILED, WSAGetLastError()); + return FALSE; } + if(!WideCharToMultiByte(CP_ACP, 0, TargetName, -1, aTargetName,\ + sizeof(aTargetName), NULL, NULL)) + { + FormatOutput(IDS_UNKNOWN_HOST, TargetName); + return FALSE; + } + ZeroMemory(&Target, sizeof(Target)); phe = NULL; - Addr = inet_addr(TargetName); + Addr = inet_addr(aTargetName); if (Addr == INADDR_NONE) { - phe = gethostbyname(TargetName); + phe = gethostbyname(aTargetName); if (phe == NULL) { - printf("Unknown host %s.\n", TargetName); + FormatOutput(IDS_UNKNOWN_HOST, TargetName); return FALSE; } + + CopyMemory(&Target.sin_addr, phe->h_addr, phe->h_length); + Target.sin_family = phe->h_addrtype; } - - if (phe != NULL) - CopyMemory(&Target.sin_addr, phe->h_addr, phe->h_length); else + { Target.sin_addr.s_addr = Addr; - - if (phe != NULL) - Target.sin_family = phe->h_addrtype; - else Target.sin_family = AF_INET; + } - TargetIP = inet_ntoa(Target.sin_addr); + + swprintf(TargetIP, L"%d.%d.%d.%d", Target.sin_addr.S_un.S_un_b.s_b1,\ + Target.sin_addr.S_un.S_un_b.s_b2,\ + Target.sin_addr.S_un.S_un_b.s_b3,\ + Target.sin_addr.S_un.S_un_b.s_b4); CurrentSeqNum = 1; SentCount = 0; LostCount = 0; @@ -405,16 +449,18 @@ } } -static VOID TimeToMsString(LPSTR String, LARGE_INTEGER Time) +static VOID TimeToMsString(LPWSTR String, LARGE_INTEGER Time) { - CHAR Convstr[40]; + WCHAR Convstr[40]; LARGE_INTEGER LargeTime; + LPWSTR ms; LargeTime.QuadPart = Time.QuadPart / TicksPerMs.QuadPart; - _i64toa(LargeTime.QuadPart, Convstr, 10); - strcpy(String, Convstr); - strcat(String, "ms"); + _i64tow(LargeTime.QuadPart, Convstr, 10); + wcscpy(String, Convstr); + LoadString(NULL, IDS_MS, (LPWSTR)&ms, 0); + wcscat(String, ms); } /* Locate the ICMP data and print it. Returns TRUE if the packet was good, @@ -424,10 +470,11 @@ PIPv4_HEADER IpHeader; PICMP_ECHO_PACKET Icmp; UINT IphLength; - CHAR Time[100]; + WCHAR Time[100]; LARGE_INTEGER RelativeTime; LARGE_INTEGER LargeTime; - CHAR Sign[2]; + WCHAR Sign[2]; + WCHAR wfromIP[16]; IpHeader = (PIPv4_HEADER)buffer; @@ -473,18 +520,27 @@ if ((RelativeTime.QuadPart / TicksPerMs.QuadPart) < 1) { - strcpy(Sign, "<"); - strcpy(Time, "1ms"); + LPWSTR ms1; + + wcscpy(Sign, L"<"); + LoadString(NULL, IDS_1MS, (LPWSTR)&ms1, 0); + wcscpy(Time, ms1); } else { - strcpy(Sign, "="); + wcscpy(Sign, L"="); TimeToMsString(Time, RelativeTime); } - printf("Reply from %s: bytes=%d time%s%s TTL=%d\n", inet_ntoa(from->sin_addr), - size - IphLength - (int)sizeof(ICMP_ECHO_PACKET), Sign, Time, IpHeader->TTL); + swprintf(wfromIP, L"%d.%d.%d.%d", from->sin_addr.S_un.S_un_b.s_b1,\ + from->sin_addr.S_un.S_un_b.s_b2,\ + from->sin_addr.S_un.S_un_b.s_b3,\ + from->sin_addr.S_un.S_un_b.s_b4); + FormatOutput(IDS_REPLY_FROM, wfromIP,\ + size - IphLength - (int)sizeof(ICMP_ECHO_PACKET),\ + Sign, Time, IpHeader->TTL); + if (RelativeTime.QuadPart < MinRTT.QuadPart || !MinRTTSet) { MinRTT.QuadPart = RelativeTime.QuadPart; @@ -513,7 +569,7 @@ Buffer = GlobalAlloc(0, Size); if (!Buffer) { - printf("Not enough free resources available.\n"); + FormatOutput(IDS_NOT_ENOUGH_RESOURCES); return FALSE; } @@ -556,9 +612,9 @@ if (Status == SOCKET_ERROR) { if (WSAGetLastError() == WSAEHOSTUNREACH) - printf("Destination host unreachable.\n"); + FormatOutput(IDS_DEST_UNREACHABLE); else - printf("Could not transmit data (%d).\n", WSAGetLastError()); + FormatOutput(IDS_COULD_NOT_TRANSMIT, WSAGetLastError()); GlobalFree(Buffer); return FALSE; } @@ -588,7 +644,7 @@ { if (WSAGetLastError() != WSAETIMEDOUT) { - printf("Could not receive data (%d).\n", WSAGetLastError()); + FormatOutput(IDS_COULD_NOT_RECV, WSAGetLastError()); GlobalFree(Buffer); return FALSE; } @@ -597,7 +653,7 @@ if (Status == 0) { - printf("Request timed out.\n"); + FormatOutput(IDS_REQUEST_TIMEOUT); GlobalFree(Buffer); return TRUE; } @@ -610,20 +666,21 @@ /* Program entry point */ -int main(int argc, char* argv[]) +int wmain(int argc, LPWSTR argv[]) { UINT Count; - CHAR MinTime[20]; - CHAR MaxTime[20]; - CHAR AvgTime[20]; + WCHAR MinTime[20]; + WCHAR MaxTime[20]; + WCHAR AvgTime[20]; + + hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); Reset(); if ((ParseCmdline(argc, argv)) && (Setup())) { - printf("\nPinging %s [%s] with %d bytes of data:\n\n", - TargetName, TargetIP, DataSize); + FormatOutput(IDS_PING_WITH_BYTES, TargetName, TargetIP, DataSize); Count = 0; while ((NeverStop) || (Count < PingCount)) @@ -653,15 +710,15 @@ TimeToMsString(AvgTime, AvgRTT); /* Print statistics */ - printf("\nPing statistics for %s:\n", TargetIP); - printf(" Packets: Sent = %d, Received = %d, Lost = %d (%d%% loss),\n", - SentCount, SentCount - LostCount, LostCount, Count); + FormatOutput(IDS_PING_STATISTICS, TargetIP); + FormatOutput(IDS_PACKETS_SENT_RECEIVED_LOST,\ + SentCount, SentCount - LostCount, LostCount, Count); + /* Print approximate times or NO approximate times if 100% loss */ if ((SentCount - LostCount) > 0) { - printf("Approximate round trip times in milli-seconds:\n"); - printf(" Minimum = %s, Maximum = %s, Average = %s\n", - MinTime, MaxTime, AvgTime); + FormatOutput(IDS_APPROXIMATE_ROUND_TRIP); + FormatOutput(IDS_MIN_MAX_AVERAGE, MinTime, MaxTime, AvgTime); } } return 0;