請參考我的 sample Head File...
//--------------------------------------------------------------------------- #ifndef UnitMainH
#define UnitMainH
//---------------------------------------------------------------------------
#include
#include
#include
#include <Forms.hpp> // This program implements a subset of the Netstat program's
// functionality. Specifically, it enumerates and displays
// information about all UDP and TCP endpoints.
//
//------------------------------------------------------------
#include "windows.h"
#include "stdio.h"
#include "winsock.h"
#include "iprtrmib.h"
#include "tlhelp32.h"
#include "iphlpapi.h"
#include //---------------------------------------------------------------------------
class TfrmMain : public TForm
{
__published: // IDE-managed Components
TButton *cmdRefresh;
TGroupBox *GroupBox2;
TListView *ListView1;
TGroupBox *GroupBox1;
TListBox *ListBox1;
void __fastcall cmdRefreshClick(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
private: // User declarations #define LOCALADDRESS 0x0100007f
//
// Maximum string lengths for ASCII ip address and port names
//
#define HOSTNAMELEN 256
#define PORTNAMELEN 256
#define ADDRESSLEN HOSTNAMELEN PORTNAMELEN
#define ANY_SIZE 256
//
// Our option flags
//
#define FLAG_ALL_ENDPOINTS 1
#define FLAG_SHOW_NUMBERS 2 //
// Undocumented extended information structures available
// only on XP and higher
// typedef struct {
DWORD dwState; // state of the connection
DWORD dwLocalAddr; // address on local computer
DWORD dwLocalPort; // port number on local computer
DWORD dwRemoteAddr; // address on remote computer
DWORD dwRemotePort; // port number on remote computer
DWORD dwProcessId;
} MIB_TCPEXROW, *PMIB_TCPEXROW; typedef struct {
DWORD dwNumEntries;
MIB_TCPEXROW table[ANY_SIZE];
} MIB_TCPEXTABLE, *PMIB_TCPEXTABLE; typedef struct {
DWORD dwLocalAddr; // address on local computer
DWORD dwLocalPort; // port number on local computer
DWORD dwProcessId;
} MIB_UDPEXROW, *PMIB_UDPEXROW; typedef struct {
DWORD dwNumEntries;
MIB_UDPEXROW table[ANY_SIZE];
} MIB_UDPEXTABLE, *PMIB_UDPEXTABLE; //
// APIs that we link against dynamically in case they aren't
// present on the system we're running on.
//
typedef DWORD (WINAPI *pAllocateAndGetTcpExTableFromStack)(
PMIB_TCPEXTABLE *pTcpTable, // buffer for the connection table
BOOL bOrder, // sort the table?
HANDLE heap,
DWORD zero,
DWORD flags
); pAllocateAndGetTcpExTableFromStack pAllocateAndGetTcpExTableFromStackptr; typedef DWORD (WINAPI *pAllocateAndGetUdpExTableFromStack)(
PMIB_UDPEXTABLE *pTcpTable, // buffer for the connection table
BOOL bOrder, // sort the table?
HANDLE heap,
DWORD zero,
DWORD flags
); pAllocateAndGetUdpExTableFromStack pAllocateAndGetUdpExTableFromStackptr; typedef HANDLE (WINAPI *pCreateToolhelp32Snapshot)(
DWORD dwFlags,
DWORD th32ProcessID
); pCreateToolhelp32Snapshot pCreateToolhelp32Snapshotptr; typedef BOOL (WINAPI *pProcess32First)(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
); pProcess32First pProcess32Firstptr; typedef BOOL (WINAPI *pProcess32Next)(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
); pProcess32Next pProcess32Nextptr; //Variable
TListColumn *NewColumn;
TListItem *ListItem;
//Functions
bool ExApisArePresent();
void PrintError(DWORD ErrorCode);
PCHAR GetIpHostName(DWORD Flags,BOOL local,UINT ipaddr,PCHAR name,int namelen);
PCHAR GetPortName(DWORD Flags,UINT port,PCHAR proto,PCHAR name,int namelen);
PCHAR ProcessPidToName(HANDLE hProcessSnap,DWORD ProcessId,PCHAR ProcessName); public: // User declarations
__fastcall TfrmMain(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TfrmMain *frmMain;
//---------------------------------------------------------------------------
#endif
CPP File....
//--------------------------------------------------------------------------- #include
#pragma hdrstop #include "UnitMain.h" //---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TfrmMain *frmMain; //
// Possible TCP endpoint states
//
static char TcpState[][32] = {
"???",
"CLOSED",
"LISTENING",
"SYN_SENT",
"SYN_RCVD",
"ESTABLISHED",
"FIN_WAIT1",
"FIN_WAIT2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT",
"DELETE_TCB"
}; int ColumnToSort = 0; const char tTitle[][20]={"TCP/UDP","Process ID","File Name","State","Local","Remote","Port"};
const int tColWidth[]={80,80,150,150,300,300,100}; //---------------------------------------------------------------------------
__fastcall TfrmMain::TfrmMain(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::FormCreate(TObject *Sender)
{
//Define ListView
ListView1->GridLines = true;
ListView1->HotTrack = true;
ListView1->RowSelect = true;
ListView1->ViewStyle = vsReport;
ListView1->MultiSelect = false; ListView1->Columns->Clear();
//Add HeadColumns
for(int i=0; i <=6; i )
{
NewColumn = ListView1->Columns->Add();
NewColumn->Caption = tTitle[i];
NewColumn->Width = tColWidth[i];
NewColumn->Alignment=taLeftJustify;
}
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::cmdRefreshClick(TObject *Sender)
{
DWORD error, dwSize;
WORD wVersionRequested;
WSADATA wsaData;
HANDLE hProcessSnap;
PMIB_TCPEXTABLE tcpExTable;
PMIB_TCPTABLE tcpTable;
PMIB_UDPEXTABLE udpExTable;
PMIB_UDPTABLE udpTable;
BOOLEAN exPresent;
DWORD i, flags;
CHAR processName[MAX_PATH];
CHAR localname[HOSTNAMELEN], remotename[HOSTNAMELEN];
CHAR remoteport[PORTNAMELEN], localport[PORTNAMELEN];
CHAR localaddr[ADDRESSLEN], remoteaddr[ADDRESSLEN]; ListView1->Items->Clear(); //
// Check for NT
//
if(GetVersion() >= 0x80000000)
ListBox1->Items->Add("Requres Windows NT/2K/XP.");
else
ListBox1->Items->Add("Windows NT/2K/XP."); //
// Initialize winsock
//
wVersionRequested = MAKEWORD( 1, 1 );
if(WSAStartup(wVersionRequested, &wsaData))
ListBox1->Items->Add("Could not initialize Winsock.");
else
ListBox1->Items->Add("Initialize Winsock."); //
// Get options
//
exPresent = ExApisArePresent(); //
// Determine if extended query is available (it's only present
// on XP and higher).
//
if(exPresent)
{
//
// Get the tables of TCP and UDP endpoints with process IDs
//
error = pAllocateAndGetTcpExTableFromStackptr(&tcpExTable, true, GetProcessHeap(), 2, 2 ); if(error)
{
ListBox1->Items->Add("Failed to snapshot TCP endpoints.");
PrintError(error);
}
error = pAllocateAndGetUdpExTableFromStackptr(&udpExTable, true, GetProcessHeap(), 2, 2 );
if(error)
{
ListBox1->Items->Add("Failed to snapshot UDP endpoints.");
PrintError(error);
} //
// Get a process snapshot. Note that we won't be guaranteed to
// exactly match a PID against a process name because a process could have exited
// and the PID gotten reused between our endpoint and process snapshots.
//
hProcessSnap = pCreateToolhelp32Snapshotptr(TH32CS_SNAPPROCESS,0);
if( hProcessSnap == INVALID_HANDLE_VALUE )
{
ListBox1->Items->Add("Failed to take process snapshot. Process names will not be shown.");
} //
// Dump the TCP table
//
for( i = 0; i < tcpExTable->dwNumEntries; i )
{
if( flags & FLAG_ALL_ENDPOINTS || tcpExTable->table[i].dwState == MIB_TCP_STATE_ESTAB )
{
sprintf(localaddr, "%s:%s",
GetIpHostName( flags, TRUE, tcpExTable->table[i].dwLocalAddr, localname, HOSTNAMELEN),
GetPortName( flags, tcpExTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN )); sprintf( remoteaddr, "%s:%s",
GetIpHostName( flags, FALSE, tcpExTable->table[i].dwRemoteAddr, remotename, HOSTNAMELEN),
tcpExTable->table[i].dwRemoteAddr ?
GetPortName( flags, tcpExTable->table[i].dwRemotePort, "tcp", remoteport, PORTNAMELEN ):
"0" ); ListBox1->Items->Add("TCP");
ListBox1->Items->Add(ProcessPidToName(hProcessSnap,tcpExTable->table[i].dwProcessId,processName));
ListBox1->Items->Add(TcpState[tcpExTable->table[i].dwState]);
ListBox1->Items->Add(tcpExTable->table[i].dwProcessId);
ListBox1->Items->Add(localaddr);
ListBox1->Items->Add(remoteaddr);
ListBox1->Items->Add(localport); ListItem = ListView1->Items->Add();
ListItem->Caption = "TCP";
ListItem->SubItems->Add(tcpExTable->table[i].dwProcessId);
ListItem->SubItems->Add(ProcessPidToName(hProcessSnap,tcpExTable->table[i].dwProcessId,processName));
ListItem->SubItems->Add(TcpState[tcpExTable->table[i].dwState]);
ListItem->SubItems->Add(localaddr);
ListItem->SubItems->Add(remoteaddr);
ListItem->SubItems->Add(localport);
}
}
//
// Dump the UDP table
//
if( flags & FLAG_ALL_ENDPOINTS )
{
for( i = 0; i < udpExTable->dwNumEntries; i )
{
sprintf( localaddr, "%s:%s",
GetIpHostName( flags, TRUE, udpExTable->table[i].dwLocalAddr, localname, HOSTNAMELEN),
GetPortName( flags, udpExTable->table[i].dwLocalPort, "tcp", localport, PORTNAMELEN ));
ListBox1->Items->Add("DUP");
ListBox1->Items->Add(udpExTable->table[i].dwProcessId);
ListBox1->Items->Add(ProcessPidToName(hProcessSnap, udpExTable->table[i].dwProcessId, processName ));
ListBox1->Items->Add("");
ListBox1->Items->Add(localaddr);
ListBox1->Items->Add("*.*.*.*:*");
ListBox1->Items->Add(localport); ListItem = ListView1->Items->Add();
ListItem->Caption = "UDP";
ListItem->SubItems->Add(udpExTable->table[i].dwProcessId);
ListItem->SubItems->Add(ProcessPidToName(hProcessSnap, udpExTable->table[i].dwProcessId, processName ));
ListItem->SubItems->Add("");
ListItem->SubItems->Add(localaddr);
ListItem->SubItems->Add("*.*.*.*:*");
ListItem->SubItems->Add(localport);
}
}
}
}
//---------------------------------------------------------------------------
//--------- PRIVATE FUNCTIONS -----------------------------------------------
//---------------------------------------------------------------------------
bool TfrmMain::ExApisArePresent()
{
pAllocateAndGetTcpExTableFromStackptr =(pAllocateAndGetTcpExTableFromStack) GetProcAddress(LoadLibrary("iphlpapi.dll"),"AllocateAndGetTcpExTableFromStack"); if(!pAllocateAndGetTcpExTableFromStackptr ) return false; pAllocateAndGetUdpExTableFromStackptr = (pAllocateAndGetUdpExTableFromStack) GetProcAddress( LoadLibrary( "iphlpapi.dll"),"AllocateAndGetUdpExTableFromStack");
if(!pAllocateAndGetUdpExTableFromStackptr ) return false; pCreateToolhelp32Snapshotptr = (pCreateToolhelp32Snapshot) GetProcAddress(GetModuleHandle("kernel32.dll"),"CreateToolhelp32Snapshot");
if(!pCreateToolhelp32Snapshotptr ) return false; pProcess32Firstptr = (pProcess32First) GetProcAddress(GetModuleHandle( "kernel32.dll" ),"Process32First" );
if(!pProcess32Firstptr ) return false; pProcess32Nextptr = (pProcess32Next) GetProcAddress( GetModuleHandle( "kernel32.dll" ),"Process32Next" );
if(!pProcess32Nextptr ) return false; return true; /*
typedef BOOL (WINAPI* API_Win32NLSEnableIME)(HWND hWnd,BOOL Enable); API_Win32NLSEnableIME API_Win32NLSEnableIMEPtr=NULL;
HMODULE HModule=::GetModuleHandle("USER32.DLL");
if(NULL==HModule)
HModule=::LoadLibrary("USER32.DLL");
if(HModule)
API_Win32NLSEnableIMEPtr=(API_Win32NLSEnableIME)::GetProcAddress(HModule,"Win32NLSEnableIME");
if(NULL!=API_Win32NLSEnableIMEPtr)
return API_Win32NLSEnableIMEPtr(hWnd,Enable);
*/
}
//---------------------------------------------------------------------------
//
// PrintError
//
// Translates a Win32 error into a text equivalent
//
void TfrmMain::PrintError(DWORD ErrorCode)
{
LPTSTR lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL );
ListBox1->Items->Add(lpMsgBuf);
LocalFree(lpMsgBuf);
}
//---------------------------------------------------------------------------
//
// GetIpHostName
//
// Translate IP addresses into their name-resolved form
// if possible.
//
PCHAR TfrmMain::GetIpHostName(DWORD Flags,BOOL local,UINT ipaddr,PCHAR name,int namelen)
{
struct hostent *phostent;
UINT nipaddr; //
// Does the user want raw numbers?
//
nipaddr = htonl( ipaddr );
if( Flags & FLAG_SHOW_NUMBERS )
{
sprintf( name, "%d.%d.%d.%d",
(nipaddr >> 24) & 0xFF,
(nipaddr >> 16) & 0xFF,
(nipaddr >> 8) & 0xFF,
(nipaddr) & 0xFF); return name;
} //
// Try to translate to a name
//
if(!ipaddr)
{
if(!local)
{
sprintf(name, "%d.%d.%d.%d",
(nipaddr >> 24) & 0xFF,
(nipaddr >> 16) & 0xFF,
(nipaddr >> 8) & 0xFF,
(nipaddr) & 0xFF);
}
else
{
gethostname(name, namelen);
} }
else if( ipaddr == LOCALADDRESS )
{
if( local )
{
gethostname(name, namelen);
}
else
{
strcpy(name, "localhost" );
}
}
else if(phostent = gethostbyaddr( (char *) &ipaddr,sizeof( nipaddr ), PF_INET ))
{
strcpy( name, phostent->h_name );
}
else
{
sprintf( name, "%d.%d.%d.%d",
(nipaddr >> 24) & 0xFF,
(nipaddr >> 16) & 0xFF,
(nipaddr >> 8) & 0xFF,
(nipaddr) & 0xFF);
} return name;
}
//---------------------------------------------------------------------------
//
// GetPortName
//
// Translate port numbers into their text equivalent if
// there is one
//
PCHAR TfrmMain::GetPortName(DWORD Flags,UINT port,PCHAR proto,PCHAR name,int namelen)
{
struct servent *psrvent; if(Flags & FLAG_SHOW_NUMBERS )
{
sprintf( name, "%d", htons( (WORD) port));
return name;
} //
// Try to translate to a name
//
if( psrvent = getservbyport(port, proto))
{
strcpy(name, psrvent->s_name);
}
else
{
sprintf(name, "%d", htons((WORD) port));
}
return name;
}
//---------------------------------------------------------------------------
//
// ProcessPidToName
//
// Translates a PID to a name.
//
PCHAR TfrmMain::ProcessPidToName(HANDLE hProcessSnap,DWORD ProcessId,PCHAR ProcessName)
{
PROCESSENTRY32 processEntry; processEntry.dwSize = sizeof( processEntry );
strcpy( ProcessName, "???" ); if(!pProcess32Firstptr(hProcessSnap,&processEntry))
{
return ProcessName;
} do
{
if( processEntry.th32ProcessID == ProcessId )
{
strcpy( ProcessName, processEntry.szExeFile );
return ProcessName;
}
} while( pProcess32Nextptr( hProcessSnap, &processEntry )); return ProcessName;
}
//---------------------------------------------------------------------------
寫程式與攝影一樣重要