//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef UNDER_CE
#include <time.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#endif
#include <snmp.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <ntddip6.h>
#ifndef UNDER_CE
#include <winnlsp.h>
#endif
#include <iphlpapi.h>
#ifndef UNDER_CE
#include "llinfo.h"
#include "tcpcmd.h"
#endif
#include "ipexport.h"
#include "icmpapi.h"
#ifndef UNDER_CE
#include "nlstxt.h"
#endif
#ifdef UNDER_CE
#include "celocalmsg.h"
#endif
#define DEFAULT_MAXIMUM_HOPS 30
#define DEFAULT_TOS 0
#define DEFAULT_FLAGS 0
#define DEFAULT_SEND_SIZE 64
#define DEFAULT_RECEIVE_SIZE ( (sizeof(ICMP_ECHO_REPLY) + \
DEFAULT_SEND_SIZE + \
MAX_OPT_SIZE))
#define DEFAULT_TOS 0
#define DEFAULT_TIMEOUT 4000L
#define MIN_INTERVAL 1000L
#define STDOUT 1
#define ODS_CHUNK_SIZE 250
char SendBuffer[DEFAULT_SEND_SIZE];
char RcvBuffer[DEFAULT_RECEIVE_SIZE];
WSADATA WsaData;
#ifdef UNDER_CE
BOOL g_bOutputToConsole = TRUE;
#endif
struct IPErrorTable {
IP_STATUS Error; // The IP Error
#ifdef UNDER_CE
char* ErrorNlsString;
#else
DWORD ErrorNlsID; // The corresponding NLS string ID.
#endif
} ErrorTable[] =
{
{ IP_BUF_TOO_SMALL, TRACERT_BUF_TOO_SMALL },
{ IP_DEST_NET_UNREACHABLE, TRACERT_DEST_NET_UNREACHABLE },
{ IP_DEST_HOST_UNREACHABLE, TRACERT_DEST_HOST_UNREACHABLE },
{ IP_DEST_PROT_UNREACHABLE, TRACERT_DEST_PROT_UNREACHABLE },
{ IP_DEST_PORT_UNREACHABLE, TRACERT_DEST_PORT_UNREACHABLE },
{ IP_NO_RESOURCES, TRACERT_NO_RESOURCES },
{ IP_BAD_OPTION, TRACERT_BAD_OPTION },
{ IP_HW_ERROR, TRACERT_HW_ERROR },
{ IP_PACKET_TOO_BIG, TRACERT_PACKET_TOO_BIG },
{ IP_REQ_TIMED_OUT, TRACERT_REQ_TIMED_OUT },
{ IP_BAD_REQ, TRACERT_BAD_REQ },
{ IP_BAD_ROUTE, TRACERT_BAD_ROUTE },
{ IP_TTL_EXPIRED_TRANSIT, TRACERT_TTL_EXPIRED_TRANSIT },
{ IP_TTL_EXPIRED_REASSEM, TRACERT_TTL_EXPIRED_REASSEM },
{ IP_PARAM_PROBLEM, TRACERT_PARAM_PROBLEM },
{ IP_SOURCE_QUENCH, TRACERT_SOURCE_QUENCH },
{ IP_OPTION_TOO_BIG, TRACERT_OPTION_TOO_BIG },
{ IP_BAD_DESTINATION, TRACERT_BAD_DESTINATION },
{ IP_NEGOTIATING_IPSEC, TRACERT_NEGOTIATING_IPSEC },
{ IP_GENERAL_FAILURE, TRACERT_GENERAL_FAILURE }
};
#ifdef UNDER_CE
typedef int (__cdecl *PFN_wprintf)(const wchar_t *, ...);
extern BOOL g_bOutputToConsole;
PFN_wprintf v_pfn_wprintf;
HMODULE v_hCoreDLL;
BOOL
ConvertOemToUnicode(
IN LPSTR OemString,
OUT LPWSTR UnicodeString,
IN int UnicodeLen)
{
return (MultiByteToWideChar(CP_OEMCP, 0, OemString, (int)(strlen(OemString)+1),
UnicodeString, UnicodeLen) != 0);
} // ConvertOemToUnicode()
BOOL
ConvertUnicodeToOem(
IN LPWSTR UnicodeString,
OUT LPSTR OemString,
IN int OemLen)
{
return (WideCharToMultiByte(CP_OEMCP, 0, UnicodeString,
(int)(wcslen(UnicodeString)+1), OemString, OemLen, NULL, NULL) != 0);
} // ConvertUnicodeToOem()
#define MAX_STRING_LENGTH 2048
TCHAR ptcFormat[MAX_STRING_LENGTH];
TCHAR ptcBuffer[MAX_STRING_LENGTH];
void
NlsPutMsg (
IN UINT Handle, // Not used.
char *pFormat,
IN ...)
{
int iStrLen;
int iChunkCount;
boolean fLastChunk;
TCHAR cSaveChar;
int i;
va_list ArgList;
va_start (ArgList, pFormat);
//
// CE supports only UNICODE, so convert it to unicode..
//
if (!ConvertOemToUnicode(
pFormat,
ptcFormat,
sizeof(ptcFormat)/sizeof(ptcFormat[0])))
{
//
// What to do? Skip it..
//
RETAILMSG (1, (
TEXT("TRACERT.EXE:: Warning! Message too long [%d]\r\n"),
strlen(pFormat)));
return;
}
wvsprintf (ptcBuffer, ptcFormat, ArgList);
if (g_bOutputToConsole)
{
if (v_pfn_wprintf == NULL)
{
//
// Since not all configs contain the wprintf function we'll
// try to find it. If it's not there we'll default to using
// OutputDebugString.
//
v_hCoreDLL = LoadLibrary(TEXT("coredll.dll"));
if (v_hCoreDLL)
{
v_pfn_wprintf =
(PFN_wprintf)GetProcAddress(v_hCoreDLL, TEXT("wprintf"));
}
}
if (v_pfn_wprintf != NULL)
(v_pfn_wprintf) (TEXT("%s"), ptcBuffer);
else
{
//
// Couldn't find the entry point, revert to OutputDebugString()
//
g_bOutputToConsole = FALSE;
}
}
else
{
// OutputDebugString seems to have a limit of 255 characters
// that it can output at a time, so feed 250 at a time (just to
// be on the safer side).
iStrLen = wcslen (ptcBuffer);
iChunkCount = iStrLen/ODS_CHUNK_SIZE;
fLastChunk = ((iStrLen % ODS_CHUNK_SIZE) != 0);
for (i = iChunkCount;i > 0;i--)
{
cSaveChar = ptcBuffer[(iChunkCount-i+1)*ODS_CHUNK_SIZE];
ptcBuffer[(iChunkCount-i+1)*ODS_CHUNK_SIZE] = _T('\0');
OutputDebugString(&ptcBuffer[(iChunkCount-i)*ODS_CHUNK_SIZE]);
ptcBuffer[(iChunkCount-i+1)*ODS_CHUNK_SIZE] = cSaveChar;
}
if (fLastChunk)
OutputDebugString(&ptcBuffer[iChunkCount*ODS_CHUNK_SIZE]);
}
va_end(ArgList);
} // NlsPutMsg()
#else
PWCHAR
GetErrorString(int ErrorCode)
{
DWORD Status;
DWORD Length;
static WCHAR ErrorString[2048]; // a 2K static buffer should suffice
Length = 2048;
Status = GetIpErrorString(ErrorCode, ErrorString, &Length);
if (Status == NO_ERROR) {
return ErrorString; // success
}
return L""; // return a null string
}
unsigned
NlsPutMsg(unsigned Handle, unsigned usMsgNum, ... )
{
unsigned msglen;
VOID * vp;
va_list arglist;
DWORD StrLen;
va_start(arglist, usMsgNum);
if ((msglen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_HMODULE,
NULL,
usMsgNum,
0L, // Default country ID.
(LPTSTR)&vp,
0,
&arglist)) == 0)
return(0);
// Convert vp to oem
StrLen=strlen(vp);
CharToOemBuff((LPCTSTR)vp,(LPSTR)vp,StrLen);
msglen = _write(Handle, vp, StrLen);
LocalFree(vp);
return(msglen);
}
unsigned long
str2ip(char *addr)
{
char *endptr;
int i; // Counter variable.
unsigned long curaddr = 0;
unsigned long temp;
for (i = 0; i < 4; i++) {
temp = strtoul(addr, &endptr, 10);
if (temp > 255)
return 0L;
if (endptr[0] != '.')
if (i != 3)
return 0L;
else
if (endptr[0] != '\0' && endptr[0] != ' ')
return 0L;
addr = endptr+1;
curaddr = (curaddr << 8) + temp;
}
return net_long(curaddr);
}
#endif
void
print_addr(SOCKADDR *sa, socklen_t salen, BOO
- 1
- 2
前往页