https://git.reactos.org/?p=reactos.git;a=commitdiff;h=344f3672110c467cbb97055b86cf798ff19ec211

commit 344f3672110c467cbb97055b86cf798ff19ec211
Author: Ged Murphy <[email protected]>
AuthorDate: Tue Jan 2 09:43:14 2018 +0000

    [TRACERT] Rewrite tracert
    
    - Full rewrite. This commit replaces the old utility.
    - Use the new ICMP APIs instead of manually crafting ping requests using 
raw sockets.
    - Add support for additional languages (the previous utility was hardcoded)
    - Add support for IPv6
    - Make the icmpapi header C++ compatible. (we don't appear to sync this 
with wine anymore.)
    - Now runs on Win10, is much more reliable, and brings the code somewhat 
into the 21st century.
    (It's currently missing source routing (-j), but as most routers disable 
this anyway, I'm not sure that it's worth adding)
---
 base/applications/network/tracert/CMakeLists.txt |  12 +-
 base/applications/network/tracert/lang/bg-BG.rc  |  32 ++
 base/applications/network/tracert/lang/cs-CZ.rc  |  32 ++
 base/applications/network/tracert/lang/de-DE.rc  |  32 ++
 base/applications/network/tracert/lang/en-US.rc  |  32 ++
 base/applications/network/tracert/lang/es-ES.rc  |  32 ++
 base/applications/network/tracert/lang/fr-FR.rc  |  32 ++
 base/applications/network/tracert/lang/it-IT.rc  |  32 ++
 base/applications/network/tracert/lang/pl-PL.rc  |  32 ++
 base/applications/network/tracert/lang/ro-RO.rc  |  32 ++
 base/applications/network/tracert/lang/ru-RU.rc  |  32 ++
 base/applications/network/tracert/lang/sq-AL.rc  |  32 ++
 base/applications/network/tracert/lang/sv-SE.rc  |  32 ++
 base/applications/network/tracert/lang/tr-TR.rc  |  32 ++
 base/applications/network/tracert/lang/uk-UA.rc  |  32 ++
 base/applications/network/tracert/lang/zh-CN.rc  |  32 ++
 base/applications/network/tracert/lang/zh-TW.rc  |  32 ++
 base/applications/network/tracert/resource.h     |  16 +
 base/applications/network/tracert/tracert.c      | 657 -----------------------
 base/applications/network/tracert/tracert.cpp    | 566 +++++++++++++++++++
 base/applications/network/tracert/tracert.h      |  81 ---
 base/applications/network/tracert/tracert.rc     |  60 ++-
 sdk/include/psdk/icmpapi.h                       |   9 +
 23 files changed, 1164 insertions(+), 749 deletions(-)

diff --git a/base/applications/network/tracert/CMakeLists.txt 
b/base/applications/network/tracert/CMakeLists.txt
index ec605ed89a..132f7fc6de 100644
--- a/base/applications/network/tracert/CMakeLists.txt
+++ b/base/applications/network/tracert/CMakeLists.txt
@@ -1,11 +1,5 @@
 
-add_definitions(-D__USE_W32_SOCKETS)
-add_executable(tracert tracert.c tracert.rc)
-set_module_type(tracert win32cui)
-add_importlibs(tracert ws2_32 msvcrt kernel32)
-
-if(MSVC)
-    add_importlibs(tracert ntdll)
-endif()
-
+add_executable(tracert tracert.cpp tracert.rc)
+set_module_type(tracert win32cui UNICODE)
+add_importlibs(tracert ws2_32 iphlpapi user32 msvcrt kernel32 ntdll)
 add_cd_file(TARGET tracert DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/network/tracert/lang/bg-BG.rc 
b/base/applications/network/tracert/lang/bg-BG.rc
new file mode 100644
index 0000000000..bf99e280f8
--- /dev/null
+++ b/base/applications/network/tracert/lang/bg-BG.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/cs-CZ.rc 
b/base/applications/network/tracert/lang/cs-CZ.rc
new file mode 100644
index 0000000000..1c82fc5dc3
--- /dev/null
+++ b/base/applications/network/tracert/lang/cs-CZ.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/de-DE.rc 
b/base/applications/network/tracert/lang/de-DE.rc
new file mode 100644
index 0000000000..bbe5e4dbec
--- /dev/null
+++ b/base/applications/network/tracert/lang/de-DE.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/en-US.rc 
b/base/applications/network/tracert/lang/en-US.rc
new file mode 100644
index 0000000000..27b5961ca9
--- /dev/null
+++ b/base/applications/network/tracert/lang/en-US.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/es-ES.rc 
b/base/applications/network/tracert/lang/es-ES.rc
new file mode 100644
index 0000000000..8c69db16ac
--- /dev/null
+++ b/base/applications/network/tracert/lang/es-ES.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/fr-FR.rc 
b/base/applications/network/tracert/lang/fr-FR.rc
new file mode 100644
index 0000000000..611a56490d
--- /dev/null
+++ b/base/applications/network/tracert/lang/fr-FR.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/it-IT.rc 
b/base/applications/network/tracert/lang/it-IT.rc
new file mode 100644
index 0000000000..15b0ba30bf
--- /dev/null
+++ b/base/applications/network/tracert/lang/it-IT.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/pl-PL.rc 
b/base/applications/network/tracert/lang/pl-PL.rc
new file mode 100644
index 0000000000..94e5ba6ceb
--- /dev/null
+++ b/base/applications/network/tracert/lang/pl-PL.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/ro-RO.rc 
b/base/applications/network/tracert/lang/ro-RO.rc
new file mode 100644
index 0000000000..d5f2a88910
--- /dev/null
+++ b/base/applications/network/tracert/lang/ro-RO.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/ru-RU.rc 
b/base/applications/network/tracert/lang/ru-RU.rc
new file mode 100644
index 0000000000..1a000627a1
--- /dev/null
+++ b/base/applications/network/tracert/lang/ru-RU.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/sq-AL.rc 
b/base/applications/network/tracert/lang/sq-AL.rc
new file mode 100644
index 0000000000..d3dc494035
--- /dev/null
+++ b/base/applications/network/tracert/lang/sq-AL.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_ALBANIAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/sv-SE.rc 
b/base/applications/network/tracert/lang/sv-SE.rc
new file mode 100644
index 0000000000..6579325bdf
--- /dev/null
+++ b/base/applications/network/tracert/lang/sv-SE.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/tr-TR.rc 
b/base/applications/network/tracert/lang/tr-TR.rc
new file mode 100644
index 0000000000..0ee1a09845
--- /dev/null
+++ b/base/applications/network/tracert/lang/tr-TR.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/uk-UA.rc 
b/base/applications/network/tracert/lang/uk-UA.rc
new file mode 100644
index 0000000000..9a2903c251
--- /dev/null
+++ b/base/applications/network/tracert/lang/uk-UA.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/zh-CN.rc 
b/base/applications/network/tracert/lang/zh-CN.rc
new file mode 100644
index 0000000000..61966e02b8
--- /dev/null
+++ b/base/applications/network/tracert/lang/zh-CN.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/lang/zh-TW.rc 
b/base/applications/network/tracert/lang/zh-TW.rc
new file mode 100644
index 0000000000..86ecc1c9f8
--- /dev/null
+++ b/base/applications/network/tracert/lang/zh-TW.rc
@@ -0,0 +1,32 @@
+
+LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
+
+STRINGTABLE
+BEGIN
+    IDS_USAGE "\r\n\
+Usage: tracert [-d] [-h maximum_hops] [-j host-list] [-w timeout] target_name 
\r\n\r\n\
+Options:\r\n\
+    -d                 Do not resolve addresses to hostnames.\r\n\
+    -h maximum_hops    Maximum number of hops to search for target.\r\n\
+    -j host-list       Loose source route along host-list.\r\n\
+    -w timeout         Wait timeout milliseconds for each reply.\r\n\
+    -4                 Force using IPv4.\r\n\
+    -6                 Force using IPv6.\r\n\
+\r\n"
+
+    IDS_INVALID_OPTION  "%1 is not a valid command option.\r\n"
+    IDS_TRACE_INFO      "\r\nTracing route to %1 [%2]\r\nover a maximum of 
%3!u! hops:\r\n\r\n"
+    IDS_TRACE_COMPLETE  "\r\nTrace complete.\r\n"
+    IDS_UNABLE_RESOLVE  "Unable to resolve target system name %1.\r\n"
+
+    IDS_GEN_FAILURE     "General failure.\r\n"
+
+    IDS_HOP_COUNT       "%1!3lu!  %0\r\n"
+    IDS_HOP_TIME        "%1!4lu! ms  %0\r\n"
+    IDS_HOP_ZERO,       "  <1 ms  %0\r\n"
+    IDS_TIMEOUT         "   *     %0\r\n"
+    IDS_HOP_RES_INFO    "%1 [%2]\r\n"
+    IDS_HOP_IP_INFO     "%1\r\n"
+    IDS_REQ_TIMED_OUT   "Request timed out.\r\n"
+
+END
diff --git a/base/applications/network/tracert/resource.h 
b/base/applications/network/tracert/resource.h
new file mode 100644
index 0000000000..5bb07ecd6e
--- /dev/null
+++ b/base/applications/network/tracert/resource.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#define IDS_USAGE                   100
+#define IDS_INVALID_OPTION          101
+#define IDS_TRACE_INFO              102
+#define IDS_TRACE_COMPLETE          103
+#define IDS_UNABLE_RESOLVE          104
+#define IDS_GEN_FAILURE             105
+
+#define IDS_HOP_COUNT               107
+#define IDS_HOP_TIME                108
+#define IDS_HOP_ZERO                109
+#define IDS_TIMEOUT                 110
+#define IDS_HOP_RES_INFO            111
+#define IDS_HOP_IP_INFO             112
+#define IDS_REQ_TIMED_OUT           113
diff --git a/base/applications/network/tracert/tracert.c 
b/base/applications/network/tracert/tracert.c
deleted file mode 100644
index 2a7fce0157..0000000000
--- a/base/applications/network/tracert/tracert.c
+++ /dev/null
@@ -1,657 +0,0 @@
- /*
- * PROJECT:     ReactOS trace route utility
- * LICENSE:     GPL - See COPYING in the top level directory
- * FILE:        base/applications/network/tracert/tracert.c
- * PURPOSE:     Trace network paths through networks
- * COPYRIGHT:   Copyright 2006 - 2007 Ged Murphy <[email protected]>
- *
- */
-
-#include "tracert.h"
-
-//#define TRACERT_DBG
-
-CHAR cHostname[256];            // target hostname
-CHAR cDestIP[18];               // target IP
-
-static VOID
-DebugPrint(LPTSTR lpString, ...)
-{
-#ifdef TRACERT_DBG
-    va_list args;
-    va_start(args, lpString);
-    _vtprintf(lpString, args);
-    va_end(args);
-#else
-    UNREFERENCED_PARAMETER(lpString);
-#endif
-}
-
-static VOID
-Usage(VOID)
-{
-    _tprintf(_T("\nUsage: tracert [-d] [-h maximum_hops] [-j host-list] [-w 
timeout] target_name\n\n"
-                "Options:\n"
-                "    -d                 Do not resolve addresses to 
hostnames.\n"
-                "    -h maximum_hops    Maximum number of hops to search for 
target.\n"
-                "    -j host-list       Loose source route along host-list.\n"
-                "    -w timeout         Wait timeout milliseconds for each 
reply.\n\n"));
-
-    _tprintf(_T("NOTES\n-----\n"
-           "- Setting TTL values is not currently supported in ReactOS, so the 
trace will\n"
-           "  jump straight to the destination. This feature will be 
implemented soon.\n"
-           "- Host info is not currently available in ReactOS and will fail 
with strange\n"
-           "  results. Use -d to force it not to resolve IP's.\n"
-           "- For testing purposes, all should work as normal in a Windows 
environment\n\n"));
-}
-
-static BOOL
-ParseCmdline(int argc,
-             LPCTSTR argv[],
-             PAPPINFO pInfo)
-{
-    INT i;
-
-    if (argc < 2)
-    {
-       Usage();
-       return FALSE;
-    }
-    else
-    {
-        for (i = 1; i < argc; i++)
-        {
-            if (argv[i][0] == _T('-'))
-            {
-                switch (argv[i][1])
-                {
-                    case _T('d'):
-                        pInfo->bResolveAddresses = FALSE;
-                    break;
-
-                    case _T('h'):
-                        _stscanf(argv[i+1], _T("%d"), &pInfo->iMaxHops);
-                    break;
-
-                    case _T('j'):
-                        _tprintf(_T("-j is not yet implemented.\n"));
-                    break;
-
-                    case _T('w'):
-                        _stscanf(argv[i+1], _T("%d"), &pInfo->iTimeOut);
-                    break;
-
-                    default:
-                    {
-                        _tprintf(_T("%s is not a valid option.\n"), argv[i]);
-                        Usage();
-                        return FALSE;
-                    }
-                }
-            }
-            else
-               /* copy target address */
-               _tcsncpy(cHostname, argv[i], 255);
-        }
-    }
-
-    return TRUE;
-}
-
-static WORD
-CheckSum(PUSHORT data,
-         UINT size)
-{
-    DWORD dwSum = 0;
-
-    while (size > 1)
-    {
-        dwSum += *data++;
-        size -= sizeof(USHORT);
-    }
-
-    if (size)
-        dwSum += *(UCHAR*)data;
-
-    dwSum = (dwSum >> 16) + (dwSum & 0xFFFF);
-    dwSum += (dwSum >> 16);
-
-    return (USHORT)(~dwSum);
-}
-
-static VOID
-SetupTimingMethod(PAPPINFO pInfo)
-{
-    LARGE_INTEGER PerformanceCounterFrequency;
-
-    /* check if performance counters are available */
-    pInfo->bUsePerformanceCounter = 
QueryPerformanceFrequency(&PerformanceCounterFrequency);
-
-    if (pInfo->bUsePerformanceCounter)
-    {
-        /* restrict execution to first processor on SMP systems */
-        if (SetThreadAffinityMask(GetCurrentThread(), 1) == 0)
-            pInfo->bUsePerformanceCounter = FALSE;
-
-        pInfo->TicksPerMs.QuadPart  = PerformanceCounterFrequency.QuadPart / 
1000;
-        pInfo->TicksPerUs.QuadPart  = PerformanceCounterFrequency.QuadPart / 
1000000;
-    }
-    else
-    {
-        pInfo->TicksPerMs.QuadPart = 1;
-        pInfo->TicksPerUs.QuadPart = 1;
-    }
-}
-
-static BOOL
-ResolveHostname(PAPPINFO pInfo)
-{
-    HOSTENT *hp;
-    ULONG addr;
-
-    ZeroMemory(&pInfo->dest, sizeof(pInfo->dest));
-
-    /* if address is not a dotted decimal */
-    if ((addr = inet_addr(cHostname))== INADDR_NONE)
-    {
-       if ((hp = gethostbyname(cHostname)) != 0)
-       {
-          //CopyMemory(&pInfo->dest.sin_addr, hp->h_addr, hp->h_length);
-          pInfo->dest.sin_addr = *((struct in_addr *)hp->h_addr);
-          pInfo->dest.sin_family = hp->h_addrtype;
-       }
-       else
-       {
-          _tprintf(_T("Unable to resolve target system name %s.\n"), 
cHostname);
-          return FALSE;
-       }
-    }
-    else
-    {
-        pInfo->dest.sin_addr.s_addr = addr;
-        pInfo->dest.sin_family = AF_INET;
-    }
-
-    _tcscpy(cDestIP, inet_ntoa(pInfo->dest.sin_addr));
-
-    return TRUE;
-}
-
-static LONGLONG
-GetTime(PAPPINFO pInfo)
-{
-    LARGE_INTEGER Time;
-
-    /* Get the system time using performance counters if available */
-    if (pInfo->bUsePerformanceCounter)
-    {
-        if (QueryPerformanceCounter(&Time))
-        {
-            return Time.QuadPart;
-        }
-    }
-
-    /* otherwise fall back to GetTickCount */
-    Time.u.LowPart = (DWORD)GetTickCount();
-    Time.u.HighPart = 0;
-
-    return (LONGLONG)Time.u.LowPart;
-}
-
-static BOOL
-SetTTL(SOCKET sock,
-       INT iTTL)
-{
-    if (setsockopt(sock,
-                   IPPROTO_IP,
-                   IP_TTL,
-                   (const char *)&iTTL,
-                   sizeof(iTTL)) == SOCKET_ERROR)
-    {
-       DebugPrint(_T("TTL setsockopt failed : %d. \n"), WSAGetLastError());
-       return FALSE;
-    }
-
-    return TRUE;
-}
-
-static BOOL
-CreateSocket(PAPPINFO pInfo)
-{
-    pInfo->icmpSock = WSASocket(AF_INET,
-                                SOCK_RAW,
-                                IPPROTO_ICMP,
-                                0,
-                                0,
-                                0);
-
-    if (pInfo->icmpSock == INVALID_SOCKET)
-    {
-        INT err = WSAGetLastError();
-        DebugPrint(_T("Could not create socket : %d.\n"), err);
-
-        if (err == WSAEACCES)
-        {
-            _tprintf(_T("\n\nYou must have access to raw sockets (admin) to 
run this program!\n\n"));
-        }
-
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static VOID
-PreparePacket(PAPPINFO pInfo,
-              USHORT iSeqNum)
-{
-    /* assemble ICMP echo request packet */
-    pInfo->SendPacket->icmpheader.type     = ECHO_REQUEST;
-    pInfo->SendPacket->icmpheader.code     = 0;
-    pInfo->SendPacket->icmpheader.checksum = 0;
-    pInfo->SendPacket->icmpheader.id       = (USHORT)GetCurrentProcessId();
-    pInfo->SendPacket->icmpheader.seq      = htons((USHORT)iSeqNum);
-
-    /* calculate checksum of packet */
-    pInfo->SendPacket->icmpheader.checksum  = 
CheckSum((PUSHORT)&pInfo->SendPacket->icmpheader,
-                                                       sizeof(ICMP_HEADER) + 
PACKET_SIZE);
-}
-
-static INT
-SendPacket(PAPPINFO pInfo)
-{
-    INT iSockRet;
-
-    DebugPrint(_T("\nsending packet of %d bytes... "), PACKET_SIZE);
-
-    /* get time packet was sent */
-    pInfo->lTimeStart = GetTime(pInfo);
-
-    iSockRet = sendto(pInfo->icmpSock,              //socket
-                      (char *)&pInfo->SendPacket->icmpheader,//buffer
-                      sizeof(ICMP_HEADER) + PACKET_SIZE,//size of buffer
-                      0,                            //flags
-                      (SOCKADDR *)&pInfo->dest,     //destination
-                      sizeof(pInfo->dest));         //address length
-
-    if (iSockRet == SOCKET_ERROR)
-    {
-        if (WSAGetLastError() == WSAEACCES)
-        {
-            /* FIXME: Is this correct? */
-            _tprintf(_T("\n\nYou must be an administrator to run this 
program!\n\n"));
-            WSACleanup();
-            HeapFree(GetProcessHeap(), 0, pInfo);
-            exit(-1);
-        }
-        else
-        {
-            DebugPrint(_T("sendto failed %d\n"), WSAGetLastError());
-        }
-    }
-    else
-    {
-        DebugPrint(_T("sent %d bytes\n"), iSockRet);
-    }
-
-    return iSockRet;
-}
-
-static BOOL
-ReceivePacket(PAPPINFO pInfo)
-{
-    TIMEVAL timeVal;
-    FD_SET readFDS;
-    INT iSockRet = 0, iSelRet;
-    INT iFromLen;
-    BOOL bRet = FALSE;
-
-    iFromLen = sizeof(pInfo->source);
-
-    DebugPrint(_T("Receiving packet. Available buffer, %d bytes... "), 
MAX_PING_PACKET_SIZE);
-
-    /* monitor icmpSock for incoming connections */
-    FD_ZERO(&readFDS);
-    FD_SET(pInfo->icmpSock, &readFDS);
-
-    /* set timeout values */
-    timeVal.tv_sec  = pInfo->iTimeOut / 1000;
-    timeVal.tv_usec = pInfo->iTimeOut % 1000;
-
-    iSelRet = select(0,
-                     &readFDS,
-                     NULL,
-                     NULL,
-                     &timeVal);
-
-    if (iSelRet == SOCKET_ERROR)
-    {
-        DebugPrint(_T("select() failed in sendPacket() %d\n"), 
WSAGetLastError());
-    }
-    else if (iSelRet == 0) /* if socket timed out */
-    {
-        _tprintf(_T("   *  "));
-    }
-    else if ((iSelRet != SOCKET_ERROR) && (iSelRet != 0))
-    {
-        iSockRet = recvfrom(pInfo->icmpSock,            // socket
-                           (char *)pInfo->RecvPacket,  // buffer
-                           MAX_PING_PACKET_SIZE,        // size of buffer
-                           0,                           // flags
-                           (SOCKADDR *)&pInfo->source,  // source address
-                           &iFromLen);                  // address length
-
-        if (iSockRet != SOCKET_ERROR)
-        {
-            /* get time packet was received */
-            pInfo->lTimeEnd = GetTime(pInfo);
-            DebugPrint(_T("received %d bytes\n"), iSockRet);
-            bRet = TRUE;
-        }
-        else
-        {
-            DebugPrint(_T("recvfrom failed: %d\n"), WSAGetLastError());
-        }
-    }
-
-    return bRet;
-}
-
-static INT
-DecodeResponse(PAPPINFO pInfo)
-{
-    unsigned short header_len = pInfo->RecvPacket->h_len * 4;
-
-    /* cast the received packet into an ECHO reply and a TTL Exceed and check 
the ID*/
-    ECHO_REPLY_HEADER *IcmpHdr = (ECHO_REPLY_HEADER 
*)((char*)pInfo->RecvPacket + header_len);
-
-    /* Make sure the reply is ok */
-    if (PACKET_SIZE < header_len + ICMP_MIN_SIZE)
-    {
-        DebugPrint(_T("too few bytes from %s\n"), 
inet_ntoa(pInfo->dest.sin_addr));
-        return -2;
-    }
-
-    switch (IcmpHdr->icmpheader.type)
-    {
-           case TTL_EXCEEDED :
-                _tprintf(_T("%3ld ms"), (ULONG)((pInfo->lTimeEnd - 
pInfo->lTimeStart) / pInfo->TicksPerMs.QuadPart));
-                return 0;
-
-           case ECHO_REPLY :
-                if (IcmpHdr->icmpheader.id != (USHORT)GetCurrentProcessId())
-                {
-                /* FIXME: our network stack shouldn't allow this... */
-                /* we've picked up a packet not related to this process 
probably from another local program. We ignore it */
-                    DebugPrint(_T("Rouge packet: header id %d, process id  
%d"), IcmpHdr->icmpheader.id, GetCurrentProcessId());
-                    return -1;
-                }
-                _tprintf(_T("%3ld ms"), (ULONG)((pInfo->lTimeEnd - 
pInfo->lTimeStart) / pInfo->TicksPerMs.QuadPart));
-                return 1;
-
-           case DEST_UNREACHABLE :
-                _tprintf(_T("  *  "));
-                return 2;
-    }
-
-    return -3;
-}
-
-static BOOL
-AllocateBuffers(PAPPINFO pInfo)
-{
-    pInfo->SendPacket = (PECHO_REPLY_HEADER)HeapAlloc(GetProcessHeap(),
-                                                      0,
-                                                      
sizeof(ECHO_REPLY_HEADER) + PACKET_SIZE);
-    if (!pInfo->SendPacket)
-        return FALSE;
-
-    pInfo->RecvPacket = (PIPv4_HEADER)HeapAlloc(GetProcessHeap(),
-                                                0,
-                                                MAX_PING_PACKET_SIZE);
-    if (!pInfo->RecvPacket)
-    {
-        HeapFree(GetProcessHeap(),
-                 0,
-                 pInfo->SendPacket);
-
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static INT
-Driver(PAPPINFO pInfo)
-{
-    INT iHopCount = 1;              // hop counter. default max is 30
-    BOOL bFoundTarget = FALSE;      // Have we reached our destination yet
-    INT iReceiveReturn;             // ReceiveReturn return value
-    PECHO_REPLY_HEADER icmphdr;
-    INT iTTL = 1;
-
-    INT ret = -1;
-
-    //temps for getting host name
-    CHAR cHost[256];
-    CHAR cServ[256];
-    CHAR *ip;
-
-    SetupTimingMethod(pInfo);
-
-    if (AllocateBuffers(pInfo) &&
-        ResolveHostname(pInfo) &&
-        CreateSocket(pInfo))
-    {
-        /* print tracing info to screen */
-        _tprintf(_T("\nTracing route to %s [%s]\n"), cHostname, cDestIP);
-        _tprintf(_T("over a maximum of %d hop"), pInfo->iMaxHops);
-        pInfo->iMaxHops > 1 ? _tprintf(_T("s:\n\n")) : _tprintf(_T(":\n\n"));
-
-        /* run until we hit either max hops, or find the target */
-        while ((iHopCount <= pInfo->iMaxHops) &&
-               (bFoundTarget == FALSE))
-        {
-            USHORT iSeqNum = 0;
-            INT i;
-
-            _tprintf(_T("%3d   "), iHopCount);
-
-            /* run 3 pings for each hop */
-            for (i = 0; i < 3; i++)
-            {
-                if (SetTTL(pInfo->icmpSock, iTTL) == FALSE)
-                {
-                    DebugPrint(_T("error in Setup()\n"));
-                    return ret;
-                }
-
-                PreparePacket(pInfo, iSeqNum);
-
-                if (SendPacket(pInfo) != SOCKET_ERROR)
-                {
-                    BOOL bAwaitPacket = FALSE; // indicates whether we have 
received a good packet
-
-                    do
-                    {
-                        /* Receive replies until we get a successful read, or 
a fatal error */
-                        if ((iReceiveReturn = ReceivePacket(pInfo)) < 0)
-                        {
-                            /* FIXME: consider moving this into ReceivePacket 
*/
-                            /* check the seq num in the packet, if it's bad 
wait for another */
-                            WORD hdrLen = pInfo->RecvPacket->h_len * 4;
-                            icmphdr = (ECHO_REPLY_HEADER 
*)((char*)&pInfo->RecvPacket + hdrLen);
-                            if (icmphdr->icmpheader.seq != iSeqNum)
-                            {
-                                _tprintf(_T("bad sequence number!\n"));
-                                continue;
-                            }
-                        }
-
-                        if (iReceiveReturn)
-                        {
-                            if (DecodeResponse(pInfo) < 0)
-                                bAwaitPacket = TRUE;
-                        }
-
-                    } while (bAwaitPacket);
-                }
-
-                iSeqNum++;
-                _tprintf(_T("   "));
-            }
-
-            if(pInfo->bResolveAddresses)
-            {
-                INT iNameInfoRet;               // getnameinfo return value
-               /* gethostbyaddr() and getnameinfo() are
-                * unimplemented in ROS at present.
-                * Alex has advised he will be implementing getnameinfo.
-                * I've used that for the time being for testing in Windows*/
-
-                  //ip = inet_addr(inet_ntoa(source.sin_addr));
-                  //host = gethostbyaddr((char *)&ip, 4, 0);
-
-                  ip = inet_ntoa(pInfo->source.sin_addr);
-
-                  iNameInfoRet = getnameinfo((SOCKADDR *)&pInfo->source,
-                                             sizeof(SOCKADDR),
-                                             cHost,
-                                             256,
-                                             cServ,
-                                             256,
-                                             NI_NUMERICSERV);
-                  if (iNameInfoRet == 0)
-                  {
-                     /* if IP address resolved to a hostname,
-                      * print the IP address after it */
-                      if (lstrcmpA(cHost, ip) != 0)
-                          _tprintf(_T("%s [%s]"), cHost, ip);
-                      else
-                          _tprintf(_T("%s"), cHost);
-                  }
-                  else
-                  {
-                      DebugPrint(_T("error: %d"), WSAGetLastError());
-                      DebugPrint(_T(" getnameinfo failed: %d"), iNameInfoRet);
-                      _tprintf(_T("%s"), inet_ntoa(pInfo->source.sin_addr));
-                  }
-
-            }
-            else
-               _tprintf(_T("%s"), inet_ntoa(pInfo->source.sin_addr));
-
-            _tprintf(_T("\n"));
-
-            /* check if we've arrived at the target */
-            if (strcmp(cDestIP, inet_ntoa(pInfo->source.sin_addr)) == 0)
-                bFoundTarget = TRUE;
-            else
-            {
-                iTTL++;
-                iHopCount++;
-                Sleep(500);
-            }
-        }
-        _tprintf(_T("\nTrace complete.\n"));
-        ret = 0;
-    }
-
-    return ret;
-}
-
-static VOID
-Cleanup(PAPPINFO pInfo)
-{
-    if (pInfo->icmpSock)
-        closesocket(pInfo->icmpSock);
-
-    WSACleanup();
-
-    if (pInfo->SendPacket)
-        HeapFree(GetProcessHeap(),
-                 0,
-                 pInfo->SendPacket);
-
-    if (pInfo->RecvPacket)
-        HeapFree(GetProcessHeap(),
-                 0,
-                 pInfo->RecvPacket);
-}
-
-#if defined(_UNICODE) && defined(__GNUC__)
-static
-#endif
-int _tmain(int argc, LPCTSTR argv[])
-{
-    PAPPINFO pInfo;
-    WSADATA wsaData;
-    int ret = -1;
-
-    pInfo = (PAPPINFO)HeapAlloc(GetProcessHeap(),
-                                HEAP_ZERO_MEMORY,
-                                sizeof(APPINFO));
-    if (pInfo)
-    {
-        pInfo->bResolveAddresses = TRUE;
-        pInfo->iMaxHops = 30;
-        pInfo->iTimeOut = 1000;
-
-        if (ParseCmdline(argc, argv, pInfo))
-        {
-            if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
-            {
-                DebugPrint(_T("WSAStartup failed.\n"));
-            }
-            else
-            {
-                ret = Driver(pInfo);
-                Cleanup(pInfo);
-            }
-        }
-
-        HeapFree(GetProcessHeap(),
-                 0,
-                 pInfo);
-    }
-
-    return ret;
-}
-
-#if defined(_UNICODE) && defined(__GNUC__)
-/* HACK - MINGW HAS NO OFFICIAL SUPPORT FOR wmain()!!! */
-int main( int argc, char **argv )
-{
-    WCHAR **argvW;
-    int i, j, Ret = 1;
-
-    if ((argvW = malloc(argc * sizeof(WCHAR*))))
-    {
-        /* convert the arguments */
-        for (i = 0, j = 0; i < argc; i++)
-        {
-            if (!(argvW[i] = malloc((strlen(argv[i]) + 1) * sizeof(WCHAR))))
-            {
-                j++;
-            }
-            swprintf(argvW[i], L"%hs", argv[i]);
-        }
-
-        if (j == 0)
-        {
-            /* no error converting the parameters, call wmain() */
-            Ret = wmain(argc, (LPCTSTR *)argvW);
-        }
-
-        /* free the arguments */
-        for (i = 0; i < argc; i++)
-        {
-            if (argvW[i])
-                free(argvW[i]);
-        }
-        free(argvW);
-    }
-
-    return Ret;
-}
-#endif
diff --git a/base/applications/network/tracert/tracert.cpp 
b/base/applications/network/tracert/tracert.cpp
new file mode 100644
index 0000000000..ca14cc5345
--- /dev/null
+++ b/base/applications/network/tracert/tracert.cpp
@@ -0,0 +1,566 @@
+/*
+ * PROJECT:     ReactOS trace route utility
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        base/applications/network/tracert/tracert.cpp
+ * PURPOSE:     Trace network paths through networks
+ * COPYRIGHT:   Copyright 2018 Ged Murphy <[email protected]>
+ *
+ */
+
+#ifdef __REACTOS__
+#define WIN32_NO_STATUS
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <winuser.h>
+#define _INC_WINDOWS
+#include <stdio.h>
+#include <stdlib.h>
+#include <winsock2.h>
+#else
+#include <winsock2.h>
+#include <Windows.h>
+#endif
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <icmpapi.h>
+#include <strsafe.h>
+#include "resource.h"
+
+#define SIZEOF_ICMP_ERROR       8
+#define SIZEOF_IO_STATUS_BLOCK  8
+#define PACKET_SIZE             32
+#define MAX_IPADDRESS           32
+#define NUM_OF_PINGS            3
+
+struct TraceInfo
+{
+    bool ResolveAddresses;
+    ULONG MaxHops;
+    ULONG Timeout;
+    WCHAR HostName[NI_MAXHOST];
+    WCHAR TargetIP[MAX_IPADDRESS];
+    int Family;
+
+    HANDLE hIcmpFile;
+    PADDRINFOW Target;
+
+} Info = { 0 };
+
+
+
+#ifndef USE_CONUTILS
+static
+INT
+LengthOfStrResource(
+    _In_ HINSTANCE hInst,
+    _In_ UINT uID
+)
+{
+    HRSRC hrSrc;
+    HGLOBAL hRes;
+    LPWSTR lpName, lpStr;
+
+    if (hInst == NULL) return -1;
+
+    lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
+
+    if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
+        (hRes = LoadResource(hInst, hrSrc)) &&
+        (lpStr = (WCHAR*)LockResource(hRes)))
+    {
+        UINT x;
+        uID &= 0xF;
+        for (x = 0; x < uID; x++)
+        {
+            lpStr += (*lpStr) + 1;
+        }
+        return (int)(*lpStr);
+    }
+    return -1;
+}
+
+static
+INT
+AllocAndLoadString(
+    _In_ UINT uID,
+    _Out_ LPWSTR *lpTarget
+)
+{
+    HMODULE hInst;
+    INT Length;
+
+    hInst = GetModuleHandleW(NULL);
+    Length = LengthOfStrResource(hInst, uID);
+    if (Length++ > 0)
+    {
+        (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED,
+                                         Length * sizeof(WCHAR));
+        if ((*lpTarget) != NULL)
+        {
+            INT Ret;
+            if (!(Ret = LoadStringW(hInst, uID, *lpTarget, Length)))
+            {
+                LocalFree((HLOCAL)(*lpTarget));
+            }
+            return Ret;
+        }
+    }
+    return 0;
+}
+
+static
+INT
+OutputText(
+    _In_ UINT uID,
+    ...)
+{
+    LPWSTR Format;
+    DWORD Ret = 0;
+    va_list lArgs;
+
+    if (AllocAndLoadString(uID, &Format) > 0)
+    {
+        va_start(lArgs, uID);
+
+        LPWSTR Buffer;
+        Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 
FORMAT_MESSAGE_FROM_STRING,
+                             Format,
+                             0,
+                             0,
+                             (LPWSTR)&Buffer,
+                             0,
+                             &lArgs);
+        va_end(lArgs);
+
+        if (Ret)
+        {
+            wprintf(Buffer);
+            LocalFree(Buffer);
+        }
+        LocalFree((HLOCAL)Format);
+    }
+
+    return Ret;
+}
+#else
+#define OutputText(Id, ...) ConResPrintf(StdOut, Id, __VA_ARGS__)
+#endif //USE_CONUTILS
+
+static
+VOID
+Usage()
+{
+    OutputText(IDS_USAGE);
+}
+
+static ULONG
+GetULONG(
+    _In_z_ LPWSTR String
+)
+{
+    ULONG Length;
+    Length = wcslen(String);
+
+    ULONG i = 0;
+    while ((i < Length) && ((String[i] < L'0') || (String[i] > L'9'))) i++;
+    if ((i >= Length) || ((String[i] < L'0') || (String[i] > L'9')))
+    {
+        return (ULONG)-1;
+    }
+
+    LPWSTR StopString;
+    return wcstoul(&String[i], &StopString, 10);
+}
+
+static bool
+ResolveTarget()
+{
+    ADDRINFOW Hints;
+    ZeroMemory(&Hints, sizeof(Hints));
+    Hints.ai_family = Info.Family;
+    Hints.ai_flags = AI_CANONNAME;
+
+    int Status;
+    Status = GetAddrInfoW(Info.HostName,
+                          NULL,
+                          &Hints,
+                          &Info.Target);
+    if (Status != 0)
+    {
+        return false;
+    }
+
+    Status = GetNameInfoW(Info.Target->ai_addr,
+                          Info.Target->ai_addrlen,
+                          Info.TargetIP,
+                          MAX_IPADDRESS,
+                          NULL,
+                          0,
+                          NI_NUMERICHOST);
+    if (Status != 0)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+static bool
+PrintHopInfo(_In_ PVOID Buffer)
+{
+    SOCKADDR_IN6 SockAddrIn6 = { 0 };
+    SOCKADDR_IN SockAddrIn = { 0 };
+    PSOCKADDR SockAddr;
+    socklen_t Size;
+
+    if (Info.Family == AF_INET6)
+    {
+        PIPV6_ADDRESS_EX Ipv6Addr = (PIPV6_ADDRESS_EX)Buffer;
+        SockAddrIn6.sin6_family = AF_INET6;
+        CopyMemory(SockAddrIn6.sin6_addr.u.Word, Ipv6Addr->sin6_addr, 
sizeof(SockAddrIn6.sin6_addr));
+        //SockAddrIn6.sin6_addr = Ipv6Addr->sin6_addr;
+        SockAddr = (PSOCKADDR)&SockAddrIn6;
+        Size = sizeof(SOCKADDR_IN6);
+
+    }
+    else
+    {
+        IPAddr *Address = (IPAddr *)Buffer;
+        SockAddrIn.sin_family = AF_INET;
+        SockAddrIn.sin_addr.S_un.S_addr = *Address;
+        SockAddr = (PSOCKADDR)&SockAddrIn;
+        Size = sizeof(SOCKADDR_IN);
+    }
+
+    INT Status;
+    bool Resolved = false;
+    WCHAR HostName[NI_MAXHOST];
+    if (Info.ResolveAddresses)
+    {
+        Status = GetNameInfoW(SockAddr,
+                              Size,
+                              HostName,
+                              NI_MAXHOST,
+                              NULL,
+                              0,
+                              NI_NAMEREQD);
+        if (Status == 0)
+        {
+            Resolved = true;
+        }
+    }
+
+    WCHAR IpAddress[MAX_IPADDRESS];
+    Status = GetNameInfoW(SockAddr,
+                          Size,
+                          IpAddress,
+                          NI_MAXHOST,
+                          NULL,
+                          0,
+                          NI_NUMERICHOST);
+    if (Status == 0)
+    {
+        if (Resolved)
+        {
+            OutputText(IDS_HOP_RES_INFO, HostName, IpAddress);
+        }
+        else
+        {
+            OutputText(IDS_HOP_IP_INFO, IpAddress);
+        }
+    }
+
+    return (Status == 0);
+}
+
+static bool
+DecodeResponse(
+    _In_ PVOID ReplyBuffer,
+    _In_ bool OutputHopAddress,
+    _Out_ bool& FoundTarget
+)
+{
+    ULONG RoundTripTime;
+    PVOID AddressInfo;
+    ULONG Status;
+
+    if (Info.Family == AF_INET6)
+    {
+        PICMPV6_ECHO_REPLY EchoReplyV6;
+        EchoReplyV6 = (PICMPV6_ECHO_REPLY)ReplyBuffer;
+        Status = EchoReplyV6->Status;
+        RoundTripTime = EchoReplyV6->RoundTripTime;
+        AddressInfo = &EchoReplyV6->Address;
+    }
+    else
+    {
+        PICMP_ECHO_REPLY EchoReplyV4;
+        EchoReplyV4 = (PICMP_ECHO_REPLY)ReplyBuffer;
+        Status = EchoReplyV4->Status;
+        RoundTripTime = EchoReplyV4->RoundTripTime;
+        AddressInfo = &EchoReplyV4->Address;
+    }
+
+    switch (Status)
+    {
+    case IP_SUCCESS:
+    case IP_TTL_EXPIRED_TRANSIT:
+        if (RoundTripTime)
+        {
+            OutputText(IDS_HOP_TIME, RoundTripTime);
+        }
+        else
+        {
+            OutputText(IDS_HOP_ZERO);
+        }
+        break;
+
+    case IP_DEST_HOST_UNREACHABLE:
+        OutputText(IDS_TIMEOUT);
+        break;
+
+    case IP_REQ_TIMED_OUT:
+        OutputText(IDS_TIMEOUT);
+        break;
+
+    case IP_GENERAL_FAILURE:
+        OutputText(IDS_GEN_FAILURE);
+        return false;
+
+    default:
+        return false;
+    }
+
+    if (OutputHopAddress)
+    {
+        if (Status == IP_SUCCESS)
+        {
+            FoundTarget = true;
+        }
+        if (Status == IP_TTL_EXPIRED_TRANSIT || Status == IP_SUCCESS)
+        {
+            PrintHopInfo(AddressInfo);
+        }
+        else if (Status == IP_REQ_TIMED_OUT)
+        {
+            OutputText(IDS_REQ_TIMED_OUT);
+        }
+    }
+
+    return true;
+}
+
+static bool
+RunTraceRoute()
+{
+    bool Success = false;
+    Success = ResolveTarget();
+    if (!Success)
+    {
+        OutputText(IDS_UNABLE_RESOLVE, Info.HostName);
+        return false;
+    }
+
+    BYTE SendBuffer[PACKET_SIZE];
+    ICMPV6_ECHO_REPLY ReplyBufferv6;
+#ifdef _WIN64
+    ICMP_ECHO_REPLY32 ReplyBufferv432;
+#else
+    ICMP_ECHO_REPLY ReplyBufferv4;
+#endif
+    PVOID ReplyBuffer;
+
+    DWORD ReplySize = PACKET_SIZE + SIZEOF_ICMP_ERROR + SIZEOF_IO_STATUS_BLOCK;
+    if (Info.Family == AF_INET6)
+    {
+        ReplyBuffer = &ReplyBufferv6;
+        ReplySize += sizeof(ICMPV6_ECHO_REPLY);
+    }
+    else
+    {
+#ifdef _WIN64
+        ReplyBuffer = &ReplyBufferv432;
+        ReplySize += sizeof(ICMP_ECHO_REPLY32);
+#else
+        ReplyBuffer = &ReplyBufferv4;
+        ReplySize += sizeof(ICMP_ECHO_REPLY);
+#endif
+    }
+
+    if (Info.Family == AF_INET6)
+    {
+        Info.hIcmpFile = Icmp6CreateFile();
+    }
+    else
+    {
+        Info.hIcmpFile = IcmpCreateFile();
+    }
+    if (Info.hIcmpFile == INVALID_HANDLE_VALUE)
+    {
+        FreeAddrInfoW(Info.Target);
+        return false;
+    }
+
+    OutputText(IDS_TRACE_INFO, Info.HostName, Info.TargetIP, Info.MaxHops);
+
+    IP_OPTION_INFORMATION IpOptionInfo;
+    ZeroMemory(&IpOptionInfo, sizeof(IpOptionInfo));
+
+    bool Quit = false;
+    ULONG HopCount = 1;
+    bool FoundTarget = false;
+    while ((HopCount <= Info.MaxHops) && (FoundTarget == false) && (Quit == 
false))
+    {
+        OutputText(IDS_HOP_COUNT, HopCount);
+
+        for (int Ping = 1; Ping <= NUM_OF_PINGS; Ping++)
+        {
+            IpOptionInfo.Ttl = static_cast<UCHAR>(HopCount);
+
+            if (Info.Family == AF_INET6)
+            {
+                struct sockaddr_in6 Source;
+
+                ZeroMemory(&Source, sizeof(Source));
+                Source.sin6_family = AF_INET6;
+
+                (void)Icmp6SendEcho2(Info.hIcmpFile,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     &Source,
+                                     (struct sockaddr_in6 
*)Info.Target->ai_addr,
+                                     SendBuffer,
+                                     (USHORT)PACKET_SIZE,
+                                     &IpOptionInfo,
+                                     ReplyBuffer,
+                                     ReplySize,
+                                     Info.Timeout);
+            }
+            else
+            {
+                (void)IcmpSendEcho2(Info.hIcmpFile,
+                                     NULL,
+                                     NULL,
+                                     NULL,
+                                     
((PSOCKADDR_IN)Info.Target->ai_addr)->sin_addr.s_addr,
+                                     SendBuffer,
+                                     (USHORT)PACKET_SIZE,
+                                     &IpOptionInfo,
+                                     ReplyBuffer,
+                                     ReplySize,
+                                     Info.Timeout);
+            }
+
+            if (DecodeResponse(ReplyBuffer, (Ping == NUM_OF_PINGS), 
FoundTarget) == false)
+            {
+                Quit = true;
+                break;
+            }
+
+            if (FoundTarget)
+            {
+                Success = true;
+                break;
+            }
+        }
+
+        HopCount++;
+        Sleep(100);
+    }
+
+    OutputText(IDS_TRACE_COMPLETE);
+
+    FreeAddrInfoW(Info.Target);
+    if (Info.hIcmpFile)
+    {
+        IcmpCloseHandle(Info.hIcmpFile);
+    }
+
+    return Success;
+}
+
+static bool
+ParseCmdline(int argc, wchar_t *argv[])
+{
+    if (argc < 2)
+    {
+        Usage();
+        return false;
+    }
+
+    for (int i = 1; i < argc; i++)
+    {
+        if (argv[i][0] == '-')
+        {
+            switch (argv[i][1])
+            {
+            case 'd':
+                Info.ResolveAddresses = FALSE;
+                break;
+
+            case 'h':
+                Info.MaxHops = GetULONG(argv[++i]);
+                break;
+
+            case 'j':
+                printf("-j is not yet implemented.\n");
+                return false;
+
+            case 'w':
+                Info.Timeout = GetULONG(argv[++i]);
+                break;
+
+            case '4':
+                Info.Family = AF_INET;
+                break;
+
+            case '6':
+                Info.Family = AF_INET6;
+                break;
+
+            default:
+            {
+                OutputText(IDS_INVALID_OPTION, argv[i]);
+                Usage();
+                return false;
+            }
+            }
+        }
+        else
+        {
+            StringCchCopyW(Info.HostName, NI_MAXHOST, argv[i]);
+            break;
+        }
+    }
+
+    return true;
+}
+
+EXTERN_C
+int wmain(int argc, wchar_t *argv[])
+{
+    Info.ResolveAddresses = true;
+    Info.MaxHops = 30;
+    Info.Timeout = 4000;
+    Info.Family = AF_UNSPEC;
+
+    if (!ParseCmdline(argc, argv))
+    {
+        return 1;
+    }
+
+    WSADATA WsaData;
+    if (WSAStartup(MAKEWORD(2, 2), &WsaData))
+    {
+        return 1;
+    }
+
+    bool Success;
+    Success = RunTraceRoute();
+
+    WSACleanup();
+
+    return Success ? 0 : 1;
+}
diff --git a/base/applications/network/tracert/tracert.h 
b/base/applications/network/tracert/tracert.h
deleted file mode 100644
index 9026ae3a62..0000000000
--- a/base/applications/network/tracert/tracert.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#define WIN32_NO_STATUS
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#define _INC_WINDOWS
-#include <winsock2.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ws2tcpip.h>
-
-#define ECHO_REPLY 0
-#define DEST_UNREACHABLE 3
-#define ECHO_REQUEST 8
-#define TTL_EXCEEDED 11
-
-#define MAX_PING_PACKET_SIZE 1024
-#define MAX_PING_DATA_SIZE (MAX_PING_PACKET_SIZE + sizeof(IPv4Header))
-#define PACKET_SIZE 32
-#define ICMP_MIN_SIZE 8
-
-/* we need this for packets which have the 'dont fragment'
- * bit set, as they can get quite large otherwise */
-#define MAX_REC_SIZE 200
-
-/* pack the structures */
-#include <pshpack1.h>
-
-/* IPv4 Header, 20 bytes */
-typedef struct IPv4Header
-{
-    BYTE h_len:4;
-    BYTE version:4;
-    BYTE tos;
-    USHORT length;
-    USHORT id;
-    USHORT flag_frag;
-    BYTE ttl;
-    BYTE proto;
-    USHORT checksum;
-    ULONG source;
-    ULONG dest;
-} IPv4_HEADER, *PIPv4_HEADER;
-
-/* ICMP Header, 8 bytes */
-typedef struct ICMPHeader
-{
-    BYTE type;
-    BYTE code;
-    USHORT checksum;
-    USHORT id; // not used in time exceeded
-    USHORT seq; // not used in time exceeded
-} ICMP_HEADER, *PICMP_HEADER;
-
-/* ICMP Echo Reply Header */
-typedef struct EchoReplyHeader
-{
-    struct ICMPHeader icmpheader;
-} ECHO_REPLY_HEADER, *PECHO_REPLY_HEADER;
-
-#include <poppack.h>
-
-typedef struct _APPINFO
-{
-    SOCKET icmpSock;                // socket descriptor
-    SOCKADDR_IN source, dest;       // source and destination address info
-    PECHO_REPLY_HEADER SendPacket;   // ICMP echo packet
-    PIPv4_HEADER RecvPacket;         // return receive packet
-
-    BOOL bUsePerformanceCounter;    // whether to use the high res performance 
counter
-    LARGE_INTEGER TicksPerMs;       // number of millisecs in relation to proc 
freq
-    LARGE_INTEGER TicksPerUs;       // number of microsecs in relation to proc 
freq
-    LONGLONG lTimeStart;            // send packet, timer start
-    LONGLONG lTimeEnd;              // receive packet, timer end
-
-    BOOL bResolveAddresses;         // -d  MS ping defaults to true.
-    INT iMaxHops;                   // -h  Max number of hops before trace ends
-    INT iHostList;                  // -j  Source route
-    INT iTimeOut;                   // -w  time before packet times out
-
-} APPINFO, *PAPPINFO;
diff --git a/base/applications/network/tracert/tracert.rc 
b/base/applications/network/tracert/tracert.rc
index 96a08196b5..a39998756f 100644
--- a/base/applications/network/tracert/tracert.rc
+++ b/base/applications/network/tracert/tracert.rc
@@ -1,5 +1,61 @@
-#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS TCP/IPv4 Win32 Traceroute"
+#include <windef.h>
+#include "resource.h"
+
+#define REACTOS_STR_FILE_DESCRIPTION   "ReactOS TCP/IP Traceroute"
 #define REACTOS_STR_INTERNAL_NAME      "tracert"
 #define REACTOS_STR_ORIGINAL_FILENAME  "tracert.exe"
-#define REACTOS_STR_ORIGINAL_COPYRIGHT "Ged Murphy ([email protected])"
+#define REACTOS_STR_ORIGINAL_COPYRIGHT "Ged Murphy ([email protected])"
 #include <reactos/version.rc>
+
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_BG_BG
+    #include "lang/bg-BG.rc"
+#endif
+#ifdef LANGUAGE_CS_CZ
+    #include "lang/cs-CZ.rc"
+#endif
+#ifdef LANGUAGE_DE_DE
+    #include "lang/de-DE.rc"
+#endif
+#ifdef LANGUAGE_EN_US
+    #include "lang/en-US.rc"
+#endif
+#ifdef LANGUAGE_ES_ES
+    #include "lang/es-ES.rc"
+#endif
+#ifdef LANGUAGE_FR_FR
+    #include "lang/fr-FR.rc"
+#endif
+#ifdef LANGUAGE_IT_IT
+    #include "lang/it-IT.rc"
+#endif
+#ifdef LANGUAGE_PL_PL
+    #include "lang/pl-PL.rc"
+#endif
+#ifdef LANGUAGE_RO_RO
+    #include "lang/ro-RO.rc"
+#endif
+#ifdef LANGUAGE_RU_RU
+    #include "lang/ru-RU.rc"
+#endif
+#ifdef LANGUAGE_SV_SE
+    #include "lang/sv-SE.rc"
+#endif
+#ifdef LANGUAGE_SQ_AL
+    #include "lang/sq-AL.rc"
+#endif
+#ifdef LANGUAGE_TR_TR
+    #include "lang/tr-TR.rc"
+#endif
+#ifdef LANGUAGE_UK_UA
+    #include "lang/uk-UA.rc"
+#endif
+#ifdef LANGUAGE_ZH_CN
+    #include "lang/zh-CN.rc"
+#endif
+#ifdef LANGUAGE_ZH_TW
+    #include "lang/zh-TW.rc"
+#endif
diff --git a/sdk/include/psdk/icmpapi.h b/sdk/include/psdk/icmpapi.h
index c8aae44aa3..8c6bcbd92a 100644
--- a/sdk/include/psdk/icmpapi.h
+++ b/sdk/include/psdk/icmpapi.h
@@ -21,6 +21,10 @@
 #ifndef __WINE_ICMPAPI_H
 #define __WINE_ICMPAPI_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 HANDLE WINAPI  IcmpCreateFile(
     VOID
     );
@@ -91,4 +95,9 @@ Icmp6ParseReplies(
     DWORD                    ReplySize
     );
 
+#ifdef __cplusplus
+}
+#endif
+
+
 #endif /* __WINE_ICMPAPI_H */

Reply via email to