Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1854 lines
44 KiB

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
net\rtm\rtmdlg.c
Abstract:
Interactive test code for RTM dll
Author:
Vadim Eydelman
Revision History:
--*/
#ifndef NT_INCLUDED
#include <nt.h>
#endif
#ifndef _NTRTL_
#include <ntrtl.h>
#endif
#ifndef _NTURTL_
#include <nturtl.h>
#endif
#include <windows.h>
#ifndef _WINSOCKAPI_
#include <winsock.h>
#endif
#ifndef _WSIPX_
#include <wsipx.h>
#endif
#ifndef _WSNWLINK_
#include <wsnwlink.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#ifndef _ROUTING_RTM_
#include "RTM.h"
#endif
#ifndef _ROUTING_RMRTM_
#include "RMRTM.h"
#endif
#include "cldlg.h"
#include "enumdlg.h"
#if DBG
#define ASSERTERR(exp) \
if (!(exp)) { \
DbgPrint("Get last error= %d\n", GetLastError ()); \
RtlAssert( #exp, __FILE__, __LINE__, NULL ); \
}
#define ASSERTERRMSG(msg,exp) \
if (!(exp)) { \
DbgPrint("Get last error= %d\n", GetLastError ()); \
RtlAssert( #exp, __FILE__, __LINE__, msg ); \
}
#else
#define ASSERTERR(exp)
#define ASSERTERRMSG(msg,exp)
#endif
// Basic route info, present in routes of all types
typedef struct {
ROUTE_HEADER;
} RTM_XX_ROUTE, *PRTM_XX_ROUTE;
typedef union _RTM_ROUTE {
RTM_XX_ROUTE XX;
RTM_IP_ROUTE IP;
RTM_IPX_ROUTE IPX;
} RTM_ROUTE, *PRTM_ROUTE;
#define XX_INTERFACE XX.RR_InterfaceID
#define XX_PROTOCOL XX.RR_RoutingProtocol
#define XX_TIMESTAMP XX.RR_TimeStamp
#define IP_PROTOCOL IP.RR_RoutingProtocol
#define IP_INTERFACE IP.RR_InterfaceID
#define IP_METRIC IP.RR_FamilySpecificData.FSD_Metric1
#define IP_TIMESTAMP IP.RR_TimeStamp
#define IP_NET_NUM IP.RR_Network.N_NetNumber
#define IP_NET_MSK IP.RR_Network.N_NetMask
#define IP_NEXT_HOP_NUM IP.RR_NextHopAddress.N_NetNumber
#define IP_NEXT_HOP_MSK IP.RR_NextHopAddress.N_NetMask
#define IP_ADPTER_INDEX IP.RR_FamilySpecificData.FSD_AdapterIndex
#define IP_PROTOCOL_METRIC IP.RR_FamilySpecificData.FSD_ProtocolMetric
#define IP_PSD IP.RR_ProtocolSpecificData
#define IPX_PROTOCOL IPX.RR_RoutingProtocol
#define IPX_INTERFACE IPX.RR_InterfaceID
#define IPX_METRIC IPX.RR_FamilySpecificData.FSD_Ticks
#define IPX_TIMESTAMP IPX.RR_TimeStamp
#define IPX_NET_NUM IPX.RR_Network.N_NetNumber
#define IPX_NEXT_HOP_MAC IPX.RR_NextHopAddress.NHA_Mac
#define IPX_HOP_COUNT IPX.RR_FamilySpecificData.FSD_HopCount
#define IPX_PSD IPX.RR_ProtocolSpecificData
typedef struct _ENABLE_DLG_GROUP_PARAM {
HWND hCtlFirst;
BOOLEAN foundFirst;
BOOLEAN enableFlag;
} ENABLE_DLG_GROUP_PARAM, *PENABLE_DLG_GROUP_PARAM;
HANDLE *Clients;
HANDLE *Events;
HANDLE hDLLInstance;
HANDLE *InteractiveThreads;
HANDLE *IPXRIPThreads;
SOCKET *Sockets;
HANDLE *Enums;
DWORD WINAPI
ClientThread (
LPVOID param
);
BOOL CALLBACK
ClientDlgProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
BOOL CALLBACK
DoEnable (
HWND hwnd, // handle of child window
LPARAM lParam // application-defined value
);
VOID
EnableDlgGroup (
HWND hDlg,
HWND hCtlFirst,
BOOLEAN enable
);
VOID
DoRegister (
HWND hDlg,
LONG idx
);
VOID
DoDeregister (
HWND hDlg,
LONG idx
);
VOID
SetupAdd (
HWND hDlg
);
VOID
SetupDelete (
HWND hDlg
);
VOID
SetupDequeue (
HWND hDlg
);
VOID
SetupSetEnable (
HWND hDlg
);
VOID
SetupConvert (
HWND hDlg
);
VOID
DoOperation (
HWND hDlg,
LONG idx
);
DWORD WINAPI
IPXRIPListenThread (
LPVOID param
);
DWORD WINAPI
EnumThread (
LPVOID param
);
BOOL CALLBACK
EnumDlgProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
VOID
GetCriteria (
HWND hDlg,
DWORD *ProtocolFamily,
DWORD *flags,
PRTM_ROUTE Route
);
VOID
GetLastRoute (
HWND hDlg,
DWORD ProtocolFamily,
PRTM_ROUTE Route
);
VOID
DisplayRoute (
HWND hDlg,
DWORD ProtocolFamily,
PRTM_ROUTE Route
);
INT
IPNetCmp (
PVOID Net1,
PVOID Net2
) {
#define IPNet1 ((PIP_NETWORK)Net1)
#define IPNet2 ((PIP_NETWORK)Net2)
if (IPNet1->N_NetNumber>IPNet2->N_NetNumber)
return 1;
else if (IPNet1->N_NetNumber<IPNet2->N_NetNumber)
return -1;
else if (IPNet1->N_NetMask==IPNet2->N_NetMask)
return 0;
else if (IPNet1->N_NetMask>IPNet2->N_NetMask)
return 1;
else /*if (IPNet1->N_NetMask<IPNet2->N_NetMask)*/
return -1;
#undef IPNet2
#undef IPNet1
}
INT
IPNhaCmp (
PVOID Route1,
PVOID Route2
) {
#define IPRoute1 ((PRTM_ROUTE)Route1)
#define IPRoute2 ((PRTM_ROUTE)Route2)
if (IPRoute1->IP_NET_NUM>IPRoute2->IP_NET_NUM)
return 1;
else if (IPRoute1->IP_NET_NUM<IPRoute2->IP_NET_NUM)
return -1;
else if (IPRoute1->IP_NET_MSK==IPRoute2->IP_NET_MSK)
return 0;
else if (IPRoute1->IP_NET_MSK>IPRoute2->IP_NET_MSK)
return 1;
else /*if (IPNet1->IP_NET_MSK<IPNet2->IP_NET_MSK)*/
return -1;
#undef IPRoute2
#undef IPRoute1
}
INT
IPMetricCmp (
PVOID Route1,
PVOID Route2
) {
#define IPRoute1 ((PRTM_ROUTE)Route1)
#define IPRoute2 ((PRTM_ROUTE)Route2)
if (IPRoute1->IP_METRIC>IPRoute2->IP_METRIC)
return 1;
else if (IPRoute1->IP_METRIC<IPRoute2->IP_METRIC)
return -1;
else
return 0;
#undef IPRoute2
#undef IPRoute1
}
BOOL
IPFsdCmp (
PVOID Route1,
PVOID Route2
) {
#define IPRoute1 ((PRTM_ROUTE)Route1)
#define IPRoute2 ((PRTM_ROUTE)Route2)
return memcmp (&IPRoute1->IP.RR_FamilySpecificData,
&IPRoute2->IP.RR_FamilySpecificData,
sizeof (IPRoute1->IP.RR_FamilySpecificData))==0;
#undef IPRoute2
#undef IPRoute1
}
INT
IPHash (
PVOID Net
) {
return (*((PULONG)Net))%257;
}
VOID
IPChange (
DWORD Flags,
PVOID CurBestRoute,
PVOID PrevBestRoute
) {
fprintf (stderr, "IPRouteChange: Flags=%d, CurBest: %08x, PrevBest: %08x\n",
Flags, CurBestRoute, PrevBestRoute);
}
INT
IPXNetCmp (
PVOID Net1,
PVOID Net2
) {
#define IPXNet1 ((PIPX_NETWORK)Net1)
#define IPXNet2 ((PIPX_NETWORK)Net2)
if (IPXNet1->N_NetNumber>IPXNet2->N_NetNumber)
return 1;
else if (IPXNet1->N_NetNumber<IPXNet2->N_NetNumber)
return -1;
else
return 0;
#undef IPXNet2
#undef IPXNet1
}
INT
IPXNhaCmp (
PVOID Route1,
PVOID Route2
) {
#define IPXRoute1 ((PRTM_ROUTE)Route1)
#define IPXRoute2 ((PRTM_ROUTE)Route2)
return memcmp (IPXRoute1->IPX_NEXT_HOP_MAC,
IPXRoute2->IPX_NEXT_HOP_MAC,
sizeof (IPXRoute1->IPX_NEXT_HOP_MAC));
#undef IPXRoute2
#undef IPXRoute1
}
INT
IPXMetricCmp (
PVOID Route1,
PVOID Route2
) {
#define IPXRoute1 ((PRTM_ROUTE)Route1)
#define IPXRoute2 ((PRTM_ROUTE)Route2)
if (IPXRoute1->IPX_METRIC>IPXRoute2->IPX_METRIC)
return 1;
else if (IPXRoute1->IPX_METRIC<IPXRoute2->IPX_METRIC)
return -1;
else
return 0;
#undef IPXRoute2
#undef IPXRoute1
}
BOOL
IPXFsdCmp (
PVOID Route1,
PVOID Route2
) {
#define IPXRoute1 ((PRTM_ROUTE)Route1)
#define IPXRoute2 ((PRTM_ROUTE)Route2)
return IPXRoute1->IPX_HOP_COUNT==IPXRoute1->IPX_HOP_COUNT;
#undef IPXRoute2
#undef IPXRoute1
}
INT
IPXHash (
PVOID Net
) {
return (*((PULONG)Net))%257;
}
VOID
IPXChange (
DWORD Flags,
PVOID CurBestRoute,
PVOID PrevBestRoute
) {
fprintf (stderr, "IPXRouteChange: Flags=%d, CurBest: %08x, PrevBest: %08x\n",
Flags, CurBestRoute, PrevBestRoute);
}
DWORD
Validate (
PVOID Route
) {
return NO_ERROR;
}
int _cdecl
main (
int argc,
char **argv
) {
INT i, n, m, p;
INT id;
DWORD status;
static RTM_PROTOCOL_FAMILY_CONFIG IPXConfig = {
8*1024*1024,
257,
sizeof (RTM_IPX_ROUTE),
IPXNetCmp,
IPXNhaCmp,
IPXMetricCmp,
IPXFsdCmp,
IPHash,
Validate,
IPXChange };
static RTM_PROTOCOL_FAMILY_CONFIG IPConfig = {
8*1024*1024,
257,
sizeof (RTM_IP_ROUTE),
IPNetCmp,
IPNhaCmp,
IPXMetricCmp,
IPFsdCmp,
IPHash,
Validate,
IPChange };
status = RtmCreateRouteTable (RTM_PROTOCOL_FAMILY_IPX,
&IPXConfig);
ASSERTMSG ("Could not create IPX Route Table ", status == NO_ERROR);
status = RtmCreateRouteTable (RTM_PROTOCOL_FAMILY_IP,
&IPConfig);
ASSERTMSG ("Could not create IPX Route Table ", status == NO_ERROR);
if (argc>=4) {
n = atoi (argv[1]);
p = atoi (argv[2]);
m = atoi (argv[3]);
Clients = (HANDLE *)GlobalAlloc (GMEM_FIXED, n*sizeof (HANDLE));
ASSERTERR (Clients!=NULL);
Events = (HANDLE *)GlobalAlloc (GMEM_FIXED, n*sizeof (HANDLE));
ASSERTERR (Events!=NULL);
Enums = (HANDLE *)GlobalAlloc (GMEM_FIXED, p*sizeof (HANDLE));
ASSERTERR (Events!=NULL);
InteractiveThreads = (HANDLE *)GlobalAlloc (GMEM_FIXED, (n+p)*sizeof (HANDLE));
ASSERTERR (InteractiveThreads!=NULL);
hDLLInstance = LoadLibrary ("rtm.dll");
ASSERTERR (hDLLInstance!=NULL);
if (m>0) {
INT m1;
WORD wVersionRequested;
WSADATA wsaData;
INT err, length;
SOCKADDR_IPX addr;
SOCKET s;
IPX_ADDRESS_DATA adptData;
BOOL flag;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
ASSERT (err==NO_ERROR);
s = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
ASSERTERR (s!=INVALID_SOCKET);
memset (&addr, 0, sizeof (addr));
addr.sa_family = AF_IPX;
status = bind (s, (PSOCKADDR)&addr, sizeof (addr));
ASSERTERRMSG ("Can't bind to default address.\n", status==0);
// Get number of available adapters
length = sizeof (INT);
status = getsockopt (s,
NSPROTO_IPX,
IPX_MAX_ADAPTER_NUM,
(PUCHAR)&m1,
&length);
ASSERTERRMSG ("Can't get number of adapters.", status==0);
ASSERTMSG ("No adapters available", m1>0);
if (m>m1)
m = m1;
IPXRIPThreads = (HANDLE *)GlobalAlloc (GMEM_FIXED, m*sizeof(HANDLE));
ASSERTERR (IPXRIPThreads!=NULL);
Sockets = (SOCKET *)GlobalAlloc (GMEM_FIXED, m*sizeof (SOCKET));
ASSERTERR (Sockets!=NULL);
for (i=0; i<m; i++) {
Sockets[i] = socket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
ASSERTERR (Sockets[i]!=INVALID_SOCKET);
flag = TRUE;
status = setsockopt (Sockets[i],
SOL_SOCKET,
SO_BROADCAST,
(PCHAR)&flag,
sizeof (BOOL));
ASSERTERRMSG ("Can't set socket broadcast option.", status==0);
flag = TRUE;
status = setsockopt (Sockets[i],
NSPROTO_IPX,
IPX_RECEIVE_BROADCAST,
(PCHAR)&flag,
sizeof (BOOL));
ASSERTERRMSG ("Can't set IPX broadcast option.", status==0);
flag = TRUE;
status = setsockopt (Sockets[i],
NSPROTO_IPX,
IPX_RECVHDR,
(PCHAR)&flag,
sizeof (BOOL));
ASSERTERRMSG ("Can't set receive header option.", status==0);
length = sizeof (adptData);
adptData.adapternum = i;
status = getsockopt (s,
NSPROTO_IPX,
IPX_ADDRESS,
(PCHAR)&adptData,
&length);
ASSERTERRMSG ("Can't get adapter parameters.", status==0);
memcpy (&addr.sa_netnum, &adptData.netnum, sizeof (addr.sa_netnum));
fprintf (stderr,
"IPX RIP Listener # %d: Net=%02x%02x%02x%02x\n",
i, (UCHAR)addr.sa_netnum[0],
(UCHAR)addr.sa_netnum[1],
(UCHAR)addr.sa_netnum[2],
(UCHAR)addr.sa_netnum[3]);
memcpy (&addr.sa_nodenum, &adptData.nodenum, sizeof (addr.sa_nodenum));
fprintf (stderr,
"IPX RIP Listener # %d: Node=%02x%02x%02x%02x%02x%02x\n",
i, (UCHAR)addr.sa_nodenum[0],
(UCHAR)addr.sa_nodenum[1],
(UCHAR)addr.sa_nodenum[2],
(UCHAR)addr.sa_nodenum[3],
(UCHAR)addr.sa_nodenum[4],
(UCHAR)addr.sa_nodenum[5]);
addr.sa_family = AF_IPX;
addr.sa_socket = htons (0x452);
status = bind (Sockets[i], (PSOCKADDR)&addr, sizeof(addr));
ASSERTERRMSG ("Can't bind to adapter's address.", status==0);
IPXRIPThreads[i] = CreateThread (NULL,
0,
&IPXRIPListenThread,
(LPVOID)i,
0,
&id);
ASSERTERR (IPXRIPThreads[i]!=NULL);
}
closesocket (s);
}
for (i=0; i<n; i++) {
InteractiveThreads[i] = CreateThread (NULL,
0,
&ClientThread,
(LPVOID)i,
0,
&id);
ASSERTERR (InteractiveThreads[i]!=NULL);
}
for (i=0; i<p ; i++) {
InteractiveThreads[n+i] = CreateThread (NULL,
0,
&EnumThread,
(LPVOID)i,
0,
&id);
ASSERTERR (InteractiveThreads[n+i]!=NULL);
}
WaitForMultipleObjects (n+p, InteractiveThreads, TRUE, INFINITE);
if (m>0) {
for (i=0; i<m; i++)
closesocket (Sockets[i]);
status = WaitForMultipleObjects (m, IPXRIPThreads, TRUE, 5*1000);
if (status==WAIT_TIMEOUT) {
for (i=0; i<m; i++)
TerminateThread (IPXRIPThreads[i], 0);
}
for (i=0; i<m; i++)
CloseHandle (IPXRIPThreads[i]);
}
for (i=0; i<=n; i++)
CloseHandle (InteractiveThreads[i]);
FreeLibrary (hDLLInstance);
WSACleanup ();
}
else
fprintf (stderr,
"Usage: %s <n_of_clients> <n_of_enumerators> <max_rip_listeners>\n",
argv[0]);
RtmDeleteRouteTable (RTM_PROTOCOL_FAMILY_IP);
RtmDeleteRouteTable (RTM_PROTOCOL_FAMILY_IPX);
return 0;
}
#define idx ((LONG)param)
DWORD WINAPI
ClientThread (
LPVOID param
) {
MSG msg;
DWORD status;
HWND ClientDlg;
char buf[16];
BOOLEAN done = FALSE;
Clients[idx] = NULL;
Events[idx] = CreateEvent (NULL, FALSE, FALSE, NULL);
ASSERTERR (Events[idx]!=NULL);
// Create dialog window
ClientDlg = CreateDialogParam (hDLLInstance,
MAKEINTRESOURCE(IDD_RTM_CLIENT),
NULL,
&ClientDlgProc,
(LPARAM)idx);
ASSERTERR (ClientDlg!=NULL);
sprintf (buf, "Client # %d", idx+1);
SetWindowText (ClientDlg, buf);
while (!done) {
status = MsgWaitForMultipleObjects (
1,
&Events[idx],
FALSE,
1000,
QS_ALLINPUT
);
ASSERTERR (status!=0xFFFFFFFF);
if (status==WAIT_OBJECT_0) {
if (IsWindow (ClientDlg) && (Clients[idx]!=NULL))
EnableWindow (GetDlgItem (ClientDlg, IDR_DEQUEUE_C), TRUE);
else
ASSERTMSG ("Event signalled to dead client or closed window ", FALSE);
}
while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message!=WM_QUIT) {
if (!IsWindow(ClientDlg)
|| !IsDialogMessage(ClientDlg, &msg)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
done = TRUE;
}
}
if (IsWindow (ClientDlg)) {
DestroyWindow (ClientDlg);
ClientDlg = NULL;
}
CloseHandle (Events[idx]);
return msg.wParam;
}
#undef idx
BOOL CALLBACK
ClientDlgProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
BOOL res = FALSE;
LONG idx;
idx = GetWindowLong (hDlg, DWL_USER)-1;
switch (uMsg) {
case WM_INITDIALOG: // Dialog is being created
idx = lParam+1;
SetWindowLong (hDlg, DWL_USER, idx);
ASSERTERR (GetLastError ()==NO_ERROR);
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), FALSE);
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), FALSE);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_C,
CB_INSERTSTRING,
RTM_PROTOCOL_FAMILY_IPX,
(LPARAM)"IPX"
);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_C,
CB_INSERTSTRING,
RTM_PROTOCOL_FAMILY_IP,
(LPARAM)"IP"
);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_C,
CB_SETCURSEL,
0,
0
);
SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Register");
res = TRUE;
break;
case WM_COMMAND: // Process child window messages only
switch (LOWORD(wParam)) {
case IDCANCEL:
PostQuitMessage (0);
res = TRUE;
break;
case IDB_REGISTER_OP_C:
if (Clients[idx]==NULL)
DoRegister (hDlg, idx);
else
DoDeregister (hDlg, idx);
res = TRUE;
break;
case IDR_ADD_C:
SetupAdd (hDlg);
res = TRUE;
break;
case IDR_DELETE_C:
SetupDelete (hDlg);
res = TRUE;
break;
case IDR_DEQUEUE_C:
if (GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C,
NULL, FALSE)!=0)
SetupDequeue (hDlg);
else
SetupConvert (hDlg);
res = TRUE;
break;
case IDR_DISABLE_C:
case IDR_ENABLE_C:
SetupSetEnable (hDlg);
res = TRUE;
break;
case IDB_DO_IT_C:
DoOperation (hDlg, idx);
res = TRUE;
break;
}
break;
case WM_DESTROY:
if (Clients[idx]!=NULL) {
if (RtmDeregisterClient (Clients[idx])!=NO_ERROR)
MessageBox (hDlg, "Deregister failed!", NULL, MB_OK|MB_ICONSTOP);
Clients[idx] = NULL;
}
break;
}
return res;
}
VOID
DoRegister (
HWND hDlg,
LONG idx
) {
DWORD ProtocolFamily;
DWORD RoutingProtocol;
ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_C,
CB_GETCURSEL, 0, 0);
RoutingProtocol = GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
SetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, RoutingProtocol, FALSE);
Clients[idx] = RtmRegisterClient (ProtocolFamily,
RoutingProtocol,
(RoutingProtocol!=0)
? Events[idx]
: NULL,
(RoutingProtocol!=0)
? 0
: RTM_PROTOCOL_SINGLE_ROUTE);
if (Clients[idx]!=NULL) {
RECT rectScr, rectDlg;
EnableWindow (GetDlgItem (hDlg, IDC_PROTOCOL_FAMILY_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_ROUTING_PROTOCOL_C), FALSE);
SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Deregister");
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), TRUE);
if (RoutingProtocol!=0) {
SetDlgItemText (hDlg, IDR_DEQUEUE_C, "Dequeue");
EnableWindow (GetDlgItem (hDlg, IDR_DEQUEUE_C), FALSE);
}
else
SetDlgItemText (hDlg, IDR_DEQUEUE_C, "Convert");
GetWindowRect (GetDlgItem (hDlg, IDE_NET_NUMBER_C), &rectScr);
MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
rectDlg.right = 8*4+5;
break;
case RTM_PROTOCOL_FAMILY_IP:
rectDlg.right = 16*4+5;
break;
}
MapDialogRect (hDlg, &rectDlg);
MoveWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C),
rectScr.left,
rectScr.top,
rectDlg.right,
rectScr.bottom-rectScr.top,
TRUE);
GetWindowRect (GetDlgItem (hDlg, IDE_NEXT_HOP_C), &rectScr);
MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
rectDlg.right = 12*4+5;
break;
case RTM_PROTOCOL_FAMILY_IP:
rectDlg.right = 16*4+5;
break;
}
MapDialogRect (hDlg, &rectDlg);
MoveWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C),
rectScr.left,
rectScr.top,
rectDlg.right,
rectScr.bottom-rectScr.top,
TRUE);
SendDlgItemMessage (hDlg, IDR_ADD_C, BM_SETCHECK, (WPARAM)1, 0);
SetupAdd (hDlg);
}
else
MessageBox (hDlg, "Registration failed!", NULL, MB_OK|MB_ICONSTOP);
}
VOID
DoDeregister (
HWND hDlg,
LONG idx
) {
if (RtmDeregisterClient (Clients[idx])!=NO_ERROR)
MessageBox (hDlg, "Deregister failed!", NULL, MB_OK|MB_ICONSTOP);
Clients[idx] = NULL;
ResetEvent (Events[idx]);
EnableWindow (GetDlgItem (hDlg, IDC_PROTOCOL_FAMILY_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_ROUTING_PROTOCOL_C), TRUE);
SetDlgItemText (hDlg, IDB_REGISTER_OP_C, "Register");
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), FALSE);
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_REQUEST_C), FALSE);
}
VOID
SetupAdd (
HWND hDlg
) {
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
}
VOID
SetupDelete (
HWND hDlg
) {
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
}
VOID
SetupDequeue (
HWND hDlg
) {
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
}
VOID
SetupSetEnable (
HWND hDlg
) {
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
}
VOID
SetupConvert (
HWND hDlg
) {
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CLIENT_OPERATION_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_NET_NUMBER_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_NEXT_HOP_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_C), TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_METRIC_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDE_TIMEOUT_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), TRUE);
}
VOID
DoOperation (
HWND hDlg,
LONG idx
) {
char buf[32];
LONG TimeToLive;
RTM_ROUTE Route;
DWORD status;
DWORD ProtocolFamily;
INT i,n,val;
DWORD Flags;
char *p;
memset (&Route, 0 , sizeof (RTM_ROUTE));
ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_C,
CB_GETCURSEL, 0, 0);
if (IsDlgButtonChecked (hDlg, IDR_ADD_C)
|| IsDlgButtonChecked (hDlg, IDR_DELETE_C)) {
Route.XX_PROTOCOL
= GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
GetDlgItemText (hDlg, IDE_NET_NUMBER_C, buf, sizeof (buf)-1);
p = buf;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route.IPX_NET_NUM = val;
else
Route.IPX_NET_NUM = 0;
p += n;
break;
case RTM_PROTOCOL_FAMILY_IP:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route.IP_NET_NUM = val;
else
Route.IP_NET_NUM = 0;
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route.IP_NET_MSK = val;
else
Route.IP_NET_MSK = 0;
p += n;
break;
}
GetDlgItemText (hDlg, IDE_NEXT_HOP_C, buf, sizeof (buf)-1);
p = buf;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
for (i=0; i<sizeof(Route.IPX_NEXT_HOP_MAC); i++, p+=n) {
if (sscanf (p, "%2X%n", &val, &n)==1)
Route.IPX_NEXT_HOP_MAC[i] = (BYTE)val;
else
Route.IPX_NEXT_HOP_MAC[i] = 0;
}
break;
case RTM_PROTOCOL_FAMILY_IP:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route.IP_NEXT_HOP_NUM = val;
else
Route.IP_NEXT_HOP_NUM = 0;
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route.IP_NEXT_HOP_MSK = val;
else
Route.IP_NEXT_HOP_MSK = 0;
p += n;
break;
}
Route.XX_INTERFACE
= GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
if (IsDlgButtonChecked (hDlg, IDR_ADD_C)) {
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
Route.IPX_METRIC = (USHORT)GetDlgItemInt
(hDlg, IDE_METRIC_C, NULL, FALSE);
break;
case RTM_PROTOCOL_FAMILY_IP:
Route.IP_METRIC = (USHORT)GetDlgItemInt
(hDlg, IDE_METRIC_C, NULL, FALSE);
break;
}
TimeToLive = GetDlgItemInt (hDlg, IDE_TIMEOUT_C, NULL, FALSE);
SetDlgItemInt (hDlg, IDE_TIMEOUT_C, TimeToLive, FALSE);
GetDlgItemText (hDlg, IDR_ADD_C, buf, sizeof (buf)-1);
status = RtmAddRoute (Clients[idx], &Route,
TimeToLive,
&Flags, NULL, NULL);
}
else {
status = RtmDeleteRoute (Clients[idx], &Route,
&Flags, NULL);
SetDlgItemText (hDlg, IDE_TIMEOUT_C, "");
}
if (status!=NO_ERROR) {
sprintf (buf, "Rtm returned error: %ld", status);
MessageBox (hDlg, buf, "Error", MB_OK|MB_ICONEXCLAMATION);
}
SetDlgItemText (hDlg, IDL_ROUTING_PROTOCOL_C, "");
}
else if (IsDlgButtonChecked (hDlg, IDR_DEQUEUE_C)) {
RTM_ROUTE Route1;
Route.XX_PROTOCOL
= GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
if (Route.XX_PROTOCOL!=0) {
status = RtmDequeueRouteChangeMessage (Clients[idx],
&Flags,
&Route,
&Route1);
if (status==NO_ERROR) {
SendDlgItemMessage (hDlg, IDR_DEQUEUE_C, BM_SETCHECK, (WPARAM)0, 0);
EnableWindow (GetDlgItem (hDlg, IDR_DEQUEUE_C), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_DO_IT_C), FALSE);
}
else if (status!=ERROR_MORE_MESSAGES) {
sprintf (buf, "Rtm returned error: %ld", status);
MessageBox (hDlg, buf, "Error", MB_OK|MB_ICONEXCLAMATION);
}
if (!(Flags & RTM_CURRENT_BEST_ROUTE))
memcpy (&Route, &Route1, sizeof (Route));
SetDlgItemInt (hDlg, IDL_ROUTING_PROTOCOL_C, (UINT)Route.XX_PROTOCOL, FALSE);
SetDlgItemText (hDlg, IDE_TIMEOUT_C, "");
}
else {
Route.XX_INTERFACE
= GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
status = RtmBlockConvertRoutesToStatic (
Clients[idx],
RTM_ONLY_THIS_INTERFACE,
&Route);
goto OpDone;
}
}
else if (IsDlgButtonChecked (hDlg, IDR_DISABLE_C)
|| IsDlgButtonChecked (hDlg, IDR_ENABLE_C)) {
Route.XX_PROTOCOL
= GetDlgItemInt (hDlg, IDE_ROUTING_PROTOCOL_C, NULL, FALSE);
Route.XX_INTERFACE
= GetDlgItemInt (hDlg, IDE_INTERFACE_C, NULL, FALSE);
status = RtmBlockSetRouteEnable (Clients[idx],
RTM_ONLY_THIS_INTERFACE,
&Route,
IsDlgButtonChecked (hDlg, IDR_ENABLE_C));
goto OpDone;
}
SetDlgItemInt (hDlg, IDL_MESSAGE_FLAGS_C, (UINT)Flags, FALSE);
SetDlgItemInt (hDlg, IDE_INTERFACE_C, (UINT)Route.XX_INTERFACE, FALSE);
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
sprintf (buf,
"%08X",
Route.IPX_NET_NUM);
SetDlgItemInt (hDlg, IDE_METRIC_C, (UINT)Route.IPX_METRIC, FALSE);
break;
case RTM_PROTOCOL_FAMILY_IP:
sprintf (buf,
"%08X%08X",
Route.IP_NET_NUM,
Route.IP_NET_MSK);
SetDlgItemInt (hDlg, IDE_METRIC_C, (UINT)Route.IP_METRIC, FALSE);
break;
}
SetDlgItemText (hDlg, IDE_NET_NUMBER_C, buf);
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
sprintf (buf,
"%02X%02X%02X%02X%02X%02X",
Route.IPX_NEXT_HOP_MAC[0],
Route.IPX_NEXT_HOP_MAC[1],
Route.IPX_NEXT_HOP_MAC[2],
Route.IPX_NEXT_HOP_MAC[3],
Route.IPX_NEXT_HOP_MAC[4],
Route.IPX_NEXT_HOP_MAC[5]);
break;
case RTM_PROTOCOL_FAMILY_IP:
sprintf (buf,
"%08X%08X",
Route.IP_NEXT_HOP_NUM,
Route.IP_NEXT_HOP_MSK);
break;
}
SetDlgItemText (hDlg, IDE_NEXT_HOP_C, buf);
OpDone:
;
}
#define pParam ((PENABLE_DLG_GROUP_PARAM)lParam)
BOOL CALLBACK
DoEnable (
HWND hwnd, // handle of child window
LPARAM lParam // application-defined value
) {
if (!pParam->foundFirst) {
if (pParam->hCtlFirst != hwnd)
return TRUE;
else
pParam->foundFirst = TRUE;
}
else if (GetWindowLong (hwnd, GWL_STYLE) & WS_GROUP)
return FALSE;
EnableWindow (hwnd, pParam->enableFlag);
return TRUE;
}
#undef pParam
VOID
EnableDlgGroup (
HWND hDlg,
HWND hCtlFirst,
BOOLEAN enable
) {
ENABLE_DLG_GROUP_PARAM param;
param.hCtlFirst = hCtlFirst;
param.foundFirst = FALSE;
param.enableFlag = enable;
EnumChildWindows (hDlg, DoEnable, (LPARAM)&param);
}
typedef USHORT IPX_SOCKETNUM, *PIPX_SOCKETNUM;
typedef UCHAR IPX_NETNUM[4], *PIPX_NETNUM;
typedef UCHAR IPX_NODENUM[6], *PIPX_NODENUM;
typedef struct _IPX_ADDRESS_BLOCK {
IPX_NETNUM net;
IPX_NODENUM node;
IPX_SOCKETNUM socket;
} IPX_ADDRESS_BLOCK, *PIPX_ADDRESS_BLOCK;
// IPX Net Number copy macro
#define IPX_NETNUM_CPY(dst,src) memcpy(dst,src,sizeof(IPX_NETNUM))
// IPX Net Number comparison
#define IPX_NETNUM_CMP(addr1,addr2) memcmp(net1,net2,sizeof(IPX_NETNUM))
// IPX Node Number copy macro
#define IPX_NODENUM_CPY(dst,src) memcpy(dst,src,sizeof(IPX_NODENUM))
// IPX Node Number comparison
#define IPX_NODENUM_CMP(node1,node2) memcmp(node1,node2,sizeof(IPX_NODENUM))
// IPX Address copy macro
#define IPX_ADDR_CPY(dst,src) memcpy(dst,src,sizeof(IPX_ADDRESS_BLOCK))
// IPX Address comparison
#define IPX_ADDR_CMP(addr1,addr2) memcmp(addr1,addr2,sizeof(IPX_ADDRESS_BLOCK))
// Header of IPX packet
typedef struct _IPX_HEADER {
USHORT checksum;
USHORT length;
UCHAR transportctl;
UCHAR pkttype;
IPX_ADDRESS_BLOCK dst;
IPX_ADDRESS_BLOCK src;
} IPX_HEADER, *PIPX_HEADER;
typedef struct _IPX_SAP_PACKET {
IPX_HEADER hdr;
USHORT operation;
struct {
USHORT type;
UCHAR name[48];
IPX_ADDRESS_BLOCK addr;
USHORT hops;
} entry[7];
} IPX_SAP_PACKET, *PIPX_SAP_PACKET;
DWORD WINAPI
IPXRIPListenThread (
LPVOID param
) {
#define adptIdx ((INT)param)
INT status;
IPX_SAP_PACKET packet;
HANDLE hClient;
RTM_IPX_ROUTE Route;
DWORD flags;
IPX_NETNUM_DATA netData;
INT length;
fprintf (stderr, "IXP RIP Listener # %d: Started.\n", adptIdx);
hClient = RtmRegisterClient (RTM_PROTOCOL_FAMILY_IPX, 1000+adptIdx, NULL, 0);
ASSERT (hClient!=NULL);
while (((status=recvfrom (Sockets[adptIdx],
(PCHAR)&packet,
sizeof (packet),
0, NULL, NULL)) != 0)
&& (status!=SOCKET_ERROR)) {
// fprintf (stderr, "IXP RIP Listener # %d: Packet received.\n", adptIdx);
if (status>=sizeof (IPX_HEADER)) {
packet.hdr.length = (USHORT)ntohs (packet.hdr.length);
if (packet.hdr.length>status)
packet.hdr.length = (USHORT)status;
if (packet.hdr.length>=FIELD_OFFSET (IPX_SAP_PACKET, entry[0])) {
if ((packet.hdr.pkttype==4)
&& (ntohs(packet.operation)==2)) {
if (FIELD_OFFSET(IPX_SAP_PACKET,entry[1])
<= packet.hdr.length) {
IPX_NETNUM_CPY (&netData.netnum, &packet.entry[0].addr.net);
length = sizeof (netData);
status = getsockopt (Sockets[adptIdx],
NSPROTO_IPX,
IPX_GETNETINFO,
(PCHAR)&netData,
&length);
if (status==0) {
Route.RR_InterfaceID = (1000+adptIdx);
Route.RR_RoutingProtocol = 0;
Route.RR_FamilySpecificData.FSD_Ticks =
(USHORT)netData.netdelay;
RtlRetrieveUlong (&Route.RR_Network.N_NetNumber,
netData.netnum);
Route.RR_Network.N_NetNumber =
ntohl (Route.RR_Network.N_NetNumber);
IPX_NODENUM_CPY (&Route.RR_NextHopAddress.NHA_Mac,
&netData.router);
Route.RR_FamilySpecificData.FSD_HopCount = netData.hopcount;
if (Route.RR_FamilySpecificData.FSD_HopCount<16)
status = RtmAddRoute (hClient, &Route, 200, &flags, NULL, NULL);
else
status = RtmDeleteRoute (hClient, &Route, &flags, NULL);
if (status!=0) {
fprintf (stderr,
"IPX RIP Listener # %d: %s failed with status %d\n",
adptIdx,
Route.RR_FamilySpecificData.FSD_HopCount<16 ? "AddRoute" : "DeleteRoute",
status);
}
}
else
fprintf (stderr,
"IPX RIP Listener # %d:"
" Can't get info about net # %02x%02x%02x%02x\n",
adptIdx,
netData.netnum[0],
netData.netnum[1],
netData.netnum[2],
netData.netnum[3]);
}
else
fprintf (stderr,
"IPX RIP Listener # %d:"
" Invalid packet length %d.\n",
adptIdx,
packet.hdr.length);
}
// else
// fprintf (stderr,
// "IPX RIP Listener # %d:"
// " Packet type %d, operation %d ignored.\n",
// adptIdx,
// packet.hdr.pkttype,
// ntohs (packet.operation));
}
else
fprintf (stderr, "IPX RIP Listener # %d: Short packet: %d\n",
adptIdx,
packet.hdr.length);
}
else
fprintf (stderr, "IPX RIP Listener # %d: Invalid packet: %d\n",
adptIdx,
status);
// Sleep (5*1000);
}
fprintf (stderr,
"IPX RIP Listener # %d: Terminating loop. Status: %d, err: %d\n",
adptIdx, status, GetLastError ());
if (RtmDeregisterClient (hClient)!=NO_ERROR)
fprintf (stderr, "Deregister client failed.\n");
fprintf (stderr, "IXP RIP Listener # %d exited.\n", adptIdx);
return 0;
#undef adptIdx
}
#define idx ((LONG)param)
DWORD WINAPI
EnumThread (
LPVOID param
) {
MSG msg;
HWND EnumDlg;
char buf[16];
Enums[idx] = NULL;
// Create dialog window
EnumDlg = CreateDialogParam (hDLLInstance,
MAKEINTRESOURCE(IDD_ENUMERATION),
NULL,
&EnumDlgProc,
(LPARAM)idx);
ASSERTERR (EnumDlg!=NULL);
sprintf (buf, "Enumerator # %d", idx+1);
SetWindowText (EnumDlg, buf);
while (GetMessage (&msg, NULL, 0, 0)) {
if (!IsWindow(EnumDlg)
|| !IsDialogMessage(EnumDlg, &msg)) {
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
if (IsWindow (EnumDlg)) {
DestroyWindow (EnumDlg);
EnumDlg = NULL;
}
if (Enums[idx]!=NULL) {
if (Enums[idx]!=INVALID_HANDLE_VALUE) {
if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
MessageBox (NULL, "Close handle failed!", NULL, MB_OK|MB_ICONSTOP);
}
Enums[idx] = NULL;
}
return msg.wParam;
}
#undef idx
BOOL CALLBACK
EnumDlgProc (
HWND hDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
) {
BOOL res = FALSE;
LONG idx;
RTM_ROUTE Route;
DWORD ProtocolFamily;
DWORD flags;
DWORD status;
RECT rectDlg, rectScr;
idx = GetWindowLong (hDlg, DWL_USER)-1;
switch (uMsg) {
case WM_INITDIALOG: // Dialog is being created
idx = lParam+1;
SetWindowLong (hDlg, DWL_USER, idx);
ASSERTERR (GetLastError ()==NO_ERROR);
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
EnableDlgGroup (hDlg, GetDlgItem (hDlg, IDG_BUTTONS_E), TRUE);
EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_E,
CB_INSERTSTRING,
RTM_PROTOCOL_FAMILY_IPX,
(LPARAM)"IPX"
);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_E,
CB_INSERTSTRING,
RTM_PROTOCOL_FAMILY_IP,
(LPARAM)"IP"
);
SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_E,
CB_SETCURSEL,
0,
0
);
GetWindowRect (GetDlgItem (hDlg, IDE_NETWORK_E), &rectScr);
MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
rectDlg.right = 8*4+5;
MapDialogRect (hDlg, &rectDlg);
EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E), TRUE);
MoveWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
rectScr.left,
rectScr.top,
rectDlg.right,
rectScr.bottom-rectScr.top,
TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_INTERFACE_E),
IsDlgButtonChecked (hDlg, IDC_INTERFACE_E));
EnableWindow (GetDlgItem (hDlg, IDE_PROTOCOL_E),
IsDlgButtonChecked (hDlg, IDC_PROTOCOL_E));
EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
SetDlgItemText (hDlg, IDB_CREATEDELETE_E, "Create Handle");
SetDlgItemText (hDlg, IDB_GETFIRST_E, "Get First");
res = TRUE;
break;
case WM_COMMAND: // Process child window messages only
switch (LOWORD(wParam)) {
case IDCANCEL:
PostQuitMessage (0);
res = TRUE;
break;
case IDC_PROTOCOL_FAMILY_E:
if (HIWORD(wParam)==CBN_SELENDOK) {
ProtocolFamily = SendMessage (
(HWND)lParam,
CB_GETCURSEL,
0, 0);
GetWindowRect (GetDlgItem (hDlg, IDE_NETWORK_E), &rectScr);
MapWindowPoints (HWND_DESKTOP, hDlg, (LPPOINT)&rectScr, 2);
rectDlg.left = rectDlg.top = rectDlg.bottom = 0;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
rectDlg.right = 8*4+5;
break;
case RTM_PROTOCOL_FAMILY_IP:
rectDlg.right = 16*4+5;
break;
}
MapDialogRect (hDlg, &rectDlg);
EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E), TRUE);
MoveWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
rectScr.left,
rectScr.top,
rectDlg.right,
rectScr.bottom-rectScr.top,
TRUE);
EnableWindow (GetDlgItem (hDlg, IDE_NETWORK_E),
IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
}
break;
case IDC_NETWORK_E:
if (HIWORD(wParam)==BN_CLICKED)
EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
IsDlgButtonChecked (hDlg, LOWORD(wParam)));
break;
case IDC_INTERFACE_E:
case IDC_PROTOCOL_E:
if (HIWORD(wParam)==BN_CLICKED)
EnableWindow (GetDlgItem (hDlg, LOWORD(wParam)+1),
IsDlgButtonChecked (hDlg, LOWORD(wParam)));
break;
case IDB_CREATEDELETE_E:
if (Enums[idx]==NULL) {
GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
Enums[idx] = RtmCreateEnumerationHandle (
ProtocolFamily,
flags,
&Route);
if (Enums[idx]!=NULL) {
EnableDlgGroup (hDlg,
GetDlgItem (hDlg, IDG_CRITERIA_E), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_GETFIRST_E),
FALSE);
SetWindowText ((HWND)lParam, "Close Handle");
EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E),
TRUE);
}
else
MessageBox (hDlg, "Create Handle failed!",
NULL, MB_OK|MB_ICONSTOP);
}
else {
if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
MessageBox (hDlg, "Close handle failed!",
NULL, MB_OK|MB_ICONSTOP);
Enums[idx] = NULL;
EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
SetWindowText ((HWND)lParam, "Create Handle");
EnableWindow (GetDlgItem (hDlg, IDB_GETFIRST_E), TRUE);
EnableDlgGroup (hDlg,
GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
}
res = TRUE;
break;
case IDB_GETFIRST_E:
if (Enums[idx]==NULL) {
GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
status = RtmGetFirstRoute (
ProtocolFamily,
flags,
&Route);
if (status==NO_ERROR) {
DisplayRoute (hDlg, ProtocolFamily, &Route);
Enums[idx] = INVALID_HANDLE_VALUE;
EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E), FALSE);
EnableDlgGroup (hDlg,
GetDlgItem (hDlg, IDG_CRITERIA_E), FALSE);
EnableWindow (GetDlgItem (hDlg, IDB_CREATEDELETE_E),
FALSE);
SetWindowText ((HWND)lParam, "Stop Scan");
EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E),
TRUE);
}
else if (status==ERROR_NO_ROUTES)
MessageBox (hDlg, "ERROR_NO_ROUTES!",
NULL, MB_OK|MB_ICONSTOP);
else
MessageBox (hDlg, "ERROR!",
NULL, MB_OK|MB_ICONSTOP);
}
else {
Enums[idx] = NULL;
EnableWindow (GetDlgItem (hDlg, IDB_GETNEXT_E), FALSE);
SetWindowText ((HWND)lParam, "Get First");
EnableWindow (GetDlgItem (hDlg, IDB_CREATEDELETE_E), TRUE);
EnableDlgGroup (hDlg,
GetDlgItem (hDlg, IDG_CRITERIA_E), TRUE);
EnableWindow (GetDlgItem (hDlg, IDB_GETBEST_E),
IsDlgButtonChecked (hDlg, IDC_NETWORK_E));
}
res = TRUE;
break;
case IDB_GETNEXT_E:
if (Enums[idx]==INVALID_HANDLE_VALUE) {
GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
GetLastRoute (hDlg, ProtocolFamily, &Route);
status = RtmGetNextRoute (ProtocolFamily, flags, &Route);
}
else {
status = RtmEnumerateGetNextRoute (Enums[idx], &Route);
ProtocolFamily = SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_E,
CB_GETCURSEL, 0, 0);
}
if (status==NO_ERROR)
DisplayRoute (hDlg, ProtocolFamily, &Route);
else if (status==ERROR_NO_MORE_ROUTES)
MessageBox (hDlg, "ERROR_NO_MORE_ROUTES!",
NULL, MB_OK|MB_ICONSTOP);
else
MessageBox (hDlg, "ERROR!",
NULL, MB_OK|MB_ICONSTOP);
res = TRUE;
break;
case IDB_GETBEST_E:
GetCriteria (hDlg, &ProtocolFamily, &flags, &Route);
res = RtmIsRoute (ProtocolFamily, ((char *)&Route)+sizeof(RTM_XX_ROUTE), &Route);
if (res)
DisplayRoute (hDlg, ProtocolFamily, &Route);
else
MessageBox (hDlg, "NO_ROUTES!",
NULL, MB_OK|MB_ICONSTOP);
res = TRUE;
break;
case IDB_GETAGE_E:
ProtocolFamily = SendDlgItemMessage (hDlg,
IDC_PROTOCOL_FAMILY_E,
CB_GETCURSEL, 0, 0);
GetLastRoute (hDlg, ProtocolFamily, &Route);
status = RtmGetSpecificRoute (ProtocolFamily, &Route);
if (status==NO_ERROR) {
DisplayRoute (hDlg, ProtocolFamily, &Route);
SetDlgItemInt (hDlg, IDL_AGESEC_E,
RtmGetRouteAge (&Route), FALSE);
}
else
MessageBox (hDlg, "NO_ROUTES!",
NULL, MB_OK|MB_ICONSTOP);
res = TRUE;
break;
}
break;
case WM_DESTROY:
if (Enums[idx]!=NULL) {
if (Enums[idx]!=INVALID_HANDLE_VALUE) {
if (RtmCloseEnumerationHandle (Enums[idx])!=NO_ERROR)
MessageBox (hDlg, "Close handle failed!",
NULL, MB_OK|MB_ICONSTOP);
}
Enums[idx] = NULL;
}
break;
}
return res;
}
VOID
GetCriteria (
HWND hDlg,
DWORD *ProtocolFamily,
DWORD *flags,
PRTM_ROUTE Route
) {
char buf[32];
char *p;
INT val,i,n;
*ProtocolFamily = SendDlgItemMessage (hDlg, IDC_PROTOCOL_FAMILY_E,
CB_GETCURSEL, 0, 0);
if (IsDlgButtonChecked (hDlg, IDC_BESTROUTES_E)) {
*flags = RTM_ONLY_BEST_ROUTES;
}
else
*flags = 0;
if (IsDlgButtonChecked (hDlg, IDC_INTERFACE_E)) {
*flags |= RTM_ONLY_THIS_INTERFACE;
Route->XX_INTERFACE = GetDlgItemInt (hDlg,
IDE_INTERFACE_E, NULL, FALSE);
}
if (IsDlgButtonChecked (hDlg, IDC_PROTOCOL_E)) {
*flags |= RTM_ONLY_THIS_PROTOCOL;
Route->XX.RR_RoutingProtocol = GetDlgItemInt (hDlg,
IDE_PROTOCOL_E, NULL, FALSE);
}
if (IsDlgButtonChecked (hDlg, IDC_NETWORK_E)) {
*flags |= RTM_ONLY_THIS_NETWORK;
GetDlgItemText (hDlg, IDE_NETWORK_E, buf, sizeof (buf)-1);
p = buf;
switch (*ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IPX_NET_NUM = val;
else
Route->IPX_NET_NUM = 0;
p += n;
sprintf (buf,
"%08X",
Route->IPX_NET_NUM);
break;
case RTM_PROTOCOL_FAMILY_IP:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NET_NUM = val;
else
Route->IP_NET_NUM = 0;
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NET_MSK = val;
else
Route->IP_NET_MSK = 0;
p += n;
sprintf (buf,
"%08X%08X",
Route->IP_NET_NUM,
Route->IP_NET_MSK);
break;
}
SetDlgItemText (hDlg, IDE_NETWORK_E, buf);
}
}
VOID
GetLastRoute (
HWND hDlg,
DWORD ProtocolFamily,
PRTM_ROUTE Route
) {
char buf[128];
char *p;
INT i,n,val;
GetDlgItemText (hDlg, IDL_ROUTE_E, buf, sizeof (buf)-1);
p = buf;
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IPX_NET_NUM = val;
else
Route->IPX_NET_NUM = 0;
p += n;
sscanf (p,
" %d %d %n",
&Route->XX_INTERFACE,
&Route->XX_PROTOCOL,
&n);
p += n;
for (i=0; i<sizeof(Route->IPX_NEXT_HOP_MAC); i++, p+=n) {
if (sscanf (p, "%2X%n", &val, &n)==1)
Route->IPX_NEXT_HOP_MAC[i] = (BYTE)val;
else
Route->IPX_NEXT_HOP_MAC[i] = 0;
}
break;
case RTM_PROTOCOL_FAMILY_IP:
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NET_NUM = val;
else
Route->IP_NET_NUM = 0;
p += n;
sscanf (p, "-%n", &n);
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NET_MSK = val;
else
Route->IP_NET_MSK = 0;
p += n;
sscanf (p,
" %d %d %n",
&Route->XX_INTERFACE,
&Route->XX_PROTOCOL,
&n);
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NEXT_HOP_NUM = val;
else
Route->IP_NEXT_HOP_NUM = 0;
p += n;
sscanf (p, "-%n", &n);
p += n;
if (sscanf (p, "%8X%n", &val, &n)==1)
Route->IP_NEXT_HOP_MSK = val;
else
Route->IP_NEXT_HOP_MSK = 0;
p += n;
break;
}
}
VOID
DisplayRoute (
HWND hDlg,
DWORD ProtocolFamily,
PRTM_ROUTE Route
) {
char buf[128];
switch (ProtocolFamily) {
case RTM_PROTOCOL_FAMILY_IPX:
sprintf (buf,
" %08X "
" %4d %4d"
" %02X%02X%02X%02X%02X%02X "
" %4d",
Route->IPX_NET_NUM,
Route->XX_INTERFACE,
Route->XX_PROTOCOL,
Route->IPX_NEXT_HOP_MAC[0],
Route->IPX_NEXT_HOP_MAC[1],
Route->IPX_NEXT_HOP_MAC[2],
Route->IPX_NEXT_HOP_MAC[3],
Route->IPX_NEXT_HOP_MAC[4],
Route->IPX_NEXT_HOP_MAC[5],
Route->IPX_METRIC);
break;
case RTM_PROTOCOL_FAMILY_IP:
sprintf (buf,
"%08X-%08X"
" %4d %4d"
" %08X-%08X"
" %4d",
Route->IP_NET_NUM,
Route->IP_NET_MSK,
Route->XX_INTERFACE,
Route->XX_PROTOCOL,
Route->IP_NEXT_HOP_NUM,
Route->IP_NEXT_HOP_MSK,
Route->IP_METRIC);
break;
}
SetDlgItemText (hDlg, IDL_ROUTE_E, buf);
sprintf (buf, "%08X", Route->XX_TIMESTAMP.dwHighDateTime);
SetDlgItemText (hDlg, IDL_TIMEHIGH_E, buf);
sprintf (buf, "%08X", Route->XX_TIMESTAMP.dwLowDateTime);
SetDlgItemText (hDlg, IDL_TIMELOW_E, buf);
}