|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name: net\sockets\tcpcmd\iphlpapi\internal.c
Abstract: Contains the private APIs exported by IPHLPAP.DLL These are exposed because of the MIB-II subagent, and to allow more flexible use of the dll
Revision History:
Amritansh Raghav
--*/
#include "inc.h"
#pragma hdrstop
HANDLE AddressChangeNotification = NULL; HANDLE RouteChangeNotification = NULL;
HANDLE ChangeNotificationHandle = INVALID_HANDLE_VALUE;
extern HANDLE g_hIPDriverHandle; extern HANDLE g_hIPGetDriverHandle;
HANDLE Change6NotificationHandle = INVALID_HANDLE_VALUE;
extern HANDLE g_hIP6DriverHandle; extern HANDLE g_hIP6GetDriverHandle;
#define ROUTE_CHANGE 0
#define ADDRESS_CHANGE 1
#define TERMINATE_EVENT 2
int ThreadCreated=0;
typedef VOID (*PFNChangeHandler)(PVOID pContext);
typedef VOID (*PFNChangeHandler)(PVOID pContext);
DWORD NotifyRouteChangeEx( PHANDLE pHandle, LPOVERLAPPED pOverLapped, BOOL bExQueue );
typedef struct { LIST_ENTRY ListEntry; PVOID context; PFNChangeHandler Proc;
}NotifyContext;
DWORD WINAPI GetNumberOfInterfaces( PDWORD pdwNumIf );
LIST_ENTRY AddrNotifyListHead; LIST_ENTRY RouteNotifyListHead;
int TCPSendIoctl( HANDLE hHandle, ulong Ioctl, void *InBuf, ulong *InBufLen, void *OutBuf, ulong *OutBufLen );
BOOL IsRouterRunning(VOID);
BOOL IsRouterSettingRoutes(VOID);
extern DWORD IPv4ToMibOperStatus[]; #define NUM_IPV4_OPER_STATUSES (IF_OPER_STATUS_OPERATIONAL+1)
DWORD InternalGetIfTable( OUT MIB_IFTABLE **ppIfTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { MIB_OPAQUE_QUERY mqQuery; PMIB_OPAQUE_INFO pInfo; PMIB_IFTABLE pTable; DWORD dwResult, dwOutEntrySize, i;
TraceEnter("InternalGetIfTable");
*ppIfTable = NULL;
#ifndef CHICAGO
if(IsRouterRunning()) { mqQuery.dwVarId = IF_TABLE;
dwResult = MprAdminMIBEntryGet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)&mqQuery, sizeof(MIB_OPAQUE_QUERY), (PVOID)&pInfo, &dwOutEntrySize);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"InternalGetIfTable: MprAdminMIBEntryGet failed with error %x", dwResult);
TraceLeave("InternalGetIfTable");
return dwResult; }
*ppIfTable = HeapAlloc(hHeap, dwAllocFlags, dwOutEntrySize);
if(*ppIfTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR,"InternalGetIfTable: Allocation failed with error %d", dwResult);
TraceLeave("InternalGetIfTable");
MprAdminMIBBufferFree((PVOID)pInfo);
return dwResult; }
CAST_MIB_INFO(pInfo, PMIB_IFTABLE, pTable);
Trace3(ERR, "**pTable %x pInfo %x rgdata %x\n", pTable, pInfo, pInfo->rgbyData);
CopyMemory((PVOID)(*ppIfTable), (PVOID)pTable, SIZEOF_IFTABLE(pTable->dwNumEntries));
MprAdminMIBBufferFree((PVOID)pInfo); } else { #endif
dwResult = AllocateAndGetIfTableFromStack(ppIfTable, TRUE, hHeap, dwAllocFlags, TRUE);
if(dwResult isnot NO_ERROR) { Trace1(ERR, "InternalGetIfTable: AllocateAndGetIfTableFromStack failed with error %x", dwResult);
TraceLeave("InternalGetIfTable");
return dwResult; } #ifndef CHICAGO
} #endif
//
// Convert operational status to the numbering space used in the
// MIB RFC's.
//
for (i = 0; i < (*ppIfTable)->dwNumEntries; i++) { (*ppIfTable)->table[i].dwOperStatus = ((*ppIfTable)->table[i].dwOperStatus < NUM_IPV4_OPER_STATUSES) ? IPv4ToMibOperStatus[(*ppIfTable)->table[i].dwOperStatus] : IF_STATUS_UNKNOWN; }
TraceLeave("InternalGetIfTable");
return NO_ERROR; }
DWORD InternalGetIpAddrTable( OUT MIB_IPADDRTABLE **ppIpAddrTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { PMIB_OPAQUE_INFO pInfo; MIB_OPAQUE_QUERY mqQuery; DWORD dwResult, dwOutEntrySize; PMIB_IPADDRTABLE pTable;
TraceEnter("InternalGetIpAddrTable");
*ppIpAddrTable = NULL;
#ifndef CHICAGO
if(IsRouterRunning()) { mqQuery.dwVarId = IP_ADDRTABLE;
dwResult = MprAdminMIBEntryGet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)&mqQuery, sizeof(MIB_OPAQUE_QUERY), (PVOID)&pInfo, &dwOutEntrySize);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryGet failed with error %x", dwResult); TraceLeave("InternalGetIpAddrTable");
return dwResult; }
*ppIpAddrTable = HeapAlloc(hHeap, dwAllocFlags, dwOutEntrySize);
if(*ppIpAddrTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR,"Allocation failed with error %d", dwResult); TraceLeave("InternalGetIpAddrTable");
MprAdminMIBBufferFree((PVOID)pInfo);
return dwResult; }
CAST_MIB_INFO(pInfo, PMIB_IPADDRTABLE, pTable);
CopyMemory((PVOID)(*ppIpAddrTable), (PVOID)pTable, SIZEOF_IPADDRTABLE(pTable->dwNumEntries));
MprAdminMIBBufferFree((PVOID)pInfo); } else { #endif
dwResult = AllocateAndGetIpAddrTableFromStack(ppIpAddrTable, TRUE, hHeap, dwAllocFlags);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"InternalGetIpAddrTableFromStack failed with error %x", dwResult); TraceLeave("InternalGetIpAddrTable");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("InternalGetIpAddrTable");
return NO_ERROR; }
DWORD InternalGetIpNetTable( OUT MIB_IPNETTABLE **ppIpNetTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { PMIB_OPAQUE_INFO pInfo; MIB_OPAQUE_QUERY mqQuery; DWORD dwResult, dwOutEntrySize; PMIB_IPNETTABLE pTable;
TraceEnter("InternalGetIpNetTable");
*ppIpNetTable = NULL;
#ifndef CHICAGO
if(IsRouterRunning()) { mqQuery.dwVarId = IP_NETTABLE;
dwResult = MprAdminMIBEntryGet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)&mqQuery, sizeof(MIB_OPAQUE_QUERY), (PVOID)&pInfo, &dwOutEntrySize);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryGet failed with error %x", dwResult); TraceLeave("InternalGetIpNetTable");
return dwResult; }
*ppIpNetTable = HeapAlloc(hHeap, dwAllocFlags, dwOutEntrySize);
if(*ppIpNetTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR,"Allocation failed with error %d", dwResult); TraceLeave("InternalGetIpNetTable");
MprAdminMIBBufferFree((PVOID)pInfo);
return dwResult; }
CAST_MIB_INFO(pInfo, PMIB_IPNETTABLE, pTable);
CopyMemory((PVOID)(*ppIpNetTable), (PVOID)pTable, SIZEOF_IPNETTABLE(pTable->dwNumEntries));
MprAdminMIBBufferFree((PVOID)pInfo); } else { #endif
dwResult = AllocateAndGetIpNetTableFromStack(ppIpNetTable, TRUE, hHeap, dwAllocFlags, FALSE);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"AllocateAndGetIpNetTableFromStack failed with error %x", dwResult); TraceLeave("InternalGetIpNetTable");
return dwResult; } #ifndef CHICAGO
} #endif
TraceLeave("InternalGetIpNetTable");
return NO_ERROR; }
DWORD InternalGetIpForwardTable( OUT MIB_IPFORWARDTABLE **ppIpForwardTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { PMIB_OPAQUE_INFO pInfo; MIB_OPAQUE_QUERY mqQuery; DWORD dwResult, dwOutEntrySize; PMIB_IPFORWARDTABLE pTable;
TraceEnter("InternalGetIpForwardTable");
*ppIpForwardTable = NULL;
#ifndef CHICAGO
if(IsRouterRunning() && IsRouterSettingRoutes()) { mqQuery.dwVarId = IP_FORWARDTABLE;
dwResult = MprAdminMIBEntryGet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)&mqQuery, sizeof(MIB_OPAQUE_QUERY), (PVOID)&pInfo, &dwOutEntrySize);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryGet failed with error %x", dwResult); TraceLeave("InternalGetIpForwardTable");
return dwResult; }
*ppIpForwardTable = HeapAlloc(hHeap, dwAllocFlags, dwOutEntrySize);
if(*ppIpForwardTable is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR,"Allocation failed with error %d", dwResult); TraceLeave("InternalGetIpForwardTable");
MprAdminMIBBufferFree((PVOID)pInfo);
return dwResult; }
CAST_MIB_INFO(pInfo, PMIB_IPFORWARDTABLE, pTable);
CopyMemory((PVOID)(*ppIpForwardTable), (PVOID)pTable, SIZEOF_IPFORWARDTABLE(pTable->dwNumEntries));
MprAdminMIBBufferFree((PVOID)pInfo); } else { #endif
dwResult = AllocateAndGetIpForwardTableFromStack(ppIpForwardTable, TRUE, hHeap, dwAllocFlags);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"InternalGetIpForwardTableFromStack failed with error %x", dwResult); TraceLeave("InternalGetIpForwardTable");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("InternalGetIpForwardTable");
return NO_ERROR; }
DWORD InternalGetTcpTable( OUT MIB_TCPTABLE **ppTcpTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { DWORD dwResult;
TraceEnter("InternalGetTcpTable");
*ppTcpTable = NULL;
dwResult = AllocateAndGetTcpTableFromStack(ppTcpTable, TRUE, hHeap, dwAllocFlags);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"InternalGetTcpTableFromStack failed with error %x", dwResult); TraceLeave("InternalGetTcpTable");
return dwResult; }
TraceLeave("InternalGetTcpTable");
return NO_ERROR; }
DWORD InternalGetUdpTable( OUT MIB_UDPTABLE **ppUdpTable, IN HANDLE hHeap, IN DWORD dwAllocFlags ) { DWORD dwResult;
TraceEnter("InternalGetUdpTable");
*ppUdpTable = NULL;
dwResult = AllocateAndGetUdpTableFromStack(ppUdpTable, TRUE, hHeap, dwAllocFlags);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"InternalGetUdpTableFromStack failed with error %x", dwResult); TraceLeave("InternalGetUdpTable");
return dwResult; }
TraceLeave("InternalGetUdpTable");
return NO_ERROR; }
DWORD InternalSetIfEntry( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IFROW pIfRow = (PMIB_IFROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("SetIfEntry");
#ifndef CHICAGO
if(IsRouterRunning()) { pInfoRow->dwId = IF_ROW;
dwResult = MprAdminMIBEntrySet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IFROW));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntrySet failed with error %x", dwResult); TraceLeave("SetIfEntry");
return dwResult; } } else { #endif
dwResult = SetIfEntryToStack(pIfRow, FALSE);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIfEntryToStack failed with error %d", dwResult);
TraceLeave("SetIfEntry");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("SetIfEntry");
return NO_ERROR; }
DWORD InternalCreateIpForwardEntry( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("CreateIpForwardEntry");
#ifndef CHICAGO
if(IsRouterRunning() && IsRouterSettingRoutes()) { pInfoRow->dwId = IP_FORWARDROW;
dwResult = MprAdminMIBEntryCreate(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IPFORWARDROW));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x", dwResult); TraceLeave("CreateIpForwardEntry");
return dwResult; } } else { #endif
dwResult = SetIpForwardEntryToStack(pIpForwardRow);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpForwarEntryToStack failed with error %d", dwResult);
TraceLeave("CreateIpForwardEntry");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("CreateIpForwardEntry"); return NO_ERROR; }
DWORD InternalSetIpForwardEntry( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("SetIpForwardEntry");
#ifndef CHICAGO
if(IsRouterRunning() && IsRouterSettingRoutes()) { pInfoRow->dwId = IP_FORWARDROW;
dwResult = MprAdminMIBEntrySet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IPFORWARDROW));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntrySet failed with error %x", dwResult); TraceLeave("SetIpForwardEntry");
return dwResult; } } else { #endif
dwResult = SetIpForwardEntryToStack(pIpForwardRow);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpForwarEntryToStack failed with error %d", dwResult);
TraceLeave("SetIpForwardEntry");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("SetIpForwardEntry"); return NO_ERROR; }
DWORD InternalDeleteIpForwardEntry( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPFORWARDROW pIpForwardRow = (PMIB_IPFORWARDROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("DeleteIpForwardEntry");
pIpForwardRow->dwForwardType = MIB_IPROUTE_TYPE_INVALID;
#ifndef CHICAGO
if(IsRouterRunning() && IsRouterSettingRoutes()) { DWORD rgdwInfo[5]; PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
pIndex->dwVarId = IP_FORWARDROW;
pIndex->rgdwVarIndex[0] = pIpForwardRow->dwForwardDest; pIndex->rgdwVarIndex[1] = pIpForwardRow->dwForwardProto; pIndex->rgdwVarIndex[2] = pIpForwardRow->dwForwardPolicy; pIndex->rgdwVarIndex[3] = pIpForwardRow->dwForwardNextHop;
dwResult = MprAdminMIBEntryDelete(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pIndex, sizeof(rgdwInfo));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x", dwResult); TraceLeave("DeleteIpForwardEntry");
return dwResult; } } else { #endif
dwResult = SetIpForwardEntryToStack(pIpForwardRow);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpForwarEntryToStack failed with error %d", dwResult);
TraceLeave("CreateIpForwardEntry");
return dwResult; } #ifndef CHICAGO
} #endif
TraceLeave("CreateIpForwardEntry"); return NO_ERROR; }
DWORD InternalSetIpStats( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPSTATS pIpStats = (PMIB_IPSTATS)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("SetIpStats");
#ifndef CHICAGO
if(IsRouterRunning()) { pInfoRow->dwId = IP_STATS;
dwResult = MprAdminMIBEntrySet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IPSTATS));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntrySet failed with error %x", dwResult); TraceLeave("SetIpStats");
return dwResult; } } else { #endif
dwResult = SetIpStatsToStack(pIpStats);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpStatsToStack failed with error %d", dwResult);
TraceLeave("SetIpStats");
return dwResult; } #ifndef CHICAGO
} #endif
TraceLeave("SetIpStats"); return NO_ERROR; }
DWORD InternalCreateIpNetEntry( IN PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("CreateIpNetEntry");
#ifndef CHICAGO
if(IsRouterRunning()) { pInfoRow->dwId = IP_NETROW;
dwResult = MprAdminMIBEntryCreate(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IPNETROW));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryCreate failed with error %x", dwResult); TraceLeave("CreateIpNetEntry");
return dwResult; } } else { #endif
dwResult = SetIpNetEntryToStack(pIpNetRow, FALSE);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpNetEntryToStack failed with error %d", dwResult);
TraceLeave("CreateIpNetEntry");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("CreateIpNetEntry"); return NO_ERROR; }
DWORD InternalSetIpNetEntry( PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("SetIpNetEntry");
#ifndef CHICAGO
if(IsRouterRunning()) { pInfoRow->dwId = IP_NETROW;
dwResult = MprAdminMIBEntrySet(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pInfoRow, MIB_INFO_SIZE(MIB_IPNETROW));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntrySet failed with error %x", dwResult); TraceLeave("SetIpNetEntry");
return dwResult; } } else { #endif
dwResult = SetIpNetEntryToStack(pIpNetRow, FALSE);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpNetEntryToStack failed with error %d", dwResult);
TraceLeave("SetIpNetEntry");
return dwResult; } #ifndef CHICAGO
} #endif
TraceLeave("SetIpNetEntry"); return NO_ERROR; }
DWORD InternalDeleteIpNetEntry( PMIB_OPAQUE_INFO pInfoRow ) { PMIB_IPNETROW pIpNetRow = (PMIB_IPNETROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("DeleteIpNetEntry");
pIpNetRow->dwType = MIB_IPNET_TYPE_INVALID;
#ifndef CHICAGO
if(IsRouterRunning()) { DWORD rgdwInfo[3]; PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
pIndex->dwVarId = IP_NETROW;
pIndex->rgdwVarIndex[0] = pIpNetRow->dwIndex; pIndex->rgdwVarIndex[1] = pIpNetRow->dwAddr;
dwResult = MprAdminMIBEntryDelete(g_hMIBServer, PID_IP, IPRTRMGR_PID, (PVOID)pIndex, sizeof(rgdwInfo));
if(dwResult isnot NO_ERROR) { Trace1(ERR,"MprAdminMIBEntryDelete failed with error %x", dwResult); TraceLeave("DeleteIpNetEntry");
return dwResult; } } else { #endif
dwResult = SetIpNetEntryToStack(pIpNetRow, FALSE);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetIpNetEntryToStack failed with error %d", dwResult);
TraceLeave("DeleteIpNetEntry");
return dwResult; }
#ifndef CHICAGO
} #endif
TraceLeave("DeleteIpNetEntry"); return NO_ERROR; }
DWORD InternalSetTcpEntry( PMIB_OPAQUE_INFO pInfoRow ) { PMIB_TCPROW pTcpRow = (PMIB_TCPROW)(pInfoRow->rgbyData); DWORD dwResult;
TraceEnter("SetTcpEntry");
dwResult = SetTcpEntryToStack(pTcpRow);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"SetTcpEntryToStack failed with error %d", dwResult); TraceLeave("SetTcpEntry"); return dwResult; }
TraceLeave("SetTcpEntry"); return NO_ERROR; }
//#define MAX_ADAPTER_NAME_LENGTH 256
DWORD OpenAdapterKey( LPSTR Name, PHKEY Key ) { DWORD dwResult; CHAR keyName[MAX_ADAPTER_NAME_LENGTH + sizeof("\\Parameters\\Tcpip") + sizeof("SYSTEM\\CurrentControlSet\\Services\\")];
//
// open the handle to this adapter's TCPIP parameter key
//
strcpy(keyName, "SYSTEM\\CurrentControlSet\\Services\\"); lstrcpyn(keyName + lstrlen(keyName), Name, MAX_ADAPTER_NAME_LENGTH); strcat(keyName, "\\Parameters\\Tcpip");
Trace1(ERR,"OpenAdapterKey: %s", keyName);
dwResult = RegOpenKey(HKEY_LOCAL_MACHINE, keyName, Key); return dwResult;
}
DWORD ReadRegistryDword(HKEY Key, LPSTR ParameterName, PULONG Value) { DWORD dwResult, valueLength, valueType;
valueLength = sizeof(*Value);
dwResult = RegQueryValueEx(Key, ParameterName, NULL, // reserved
&valueType, (LPBYTE)Value, &valueLength);
return dwResult; }
DWORD GetAdapterIPInterfaceContext(LPSTR AdapterName, PULONG Context) { HKEY key; DWORD dwResult;
if ((dwResult = OpenAdapterKey(AdapterName, &key)) != NO_ERROR) { return(dwResult); }
dwResult = ReadRegistryDword(key, "IPInterfaceContext", Context);
RegCloseKey(key);
return(dwResult); }
DWORD GetInterfaceInfo(PIP_INTERFACE_INFO pIPIfInfo, PULONG dwOutBufLen) { #if defined(NT4) || defined(_WIN95_)
return ERROR_NOT_SUPPORTED; #else
DWORD status=0; DWORD dwNumIf; DWORD dwResult; MIB_IPSTATS IpSnmpInfo;
if (IsBadWritePtr(dwOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pIPIfInfo, *dwOutBufLen)) { return ERROR_INVALID_PARAMETER; }
dwResult = GetIpStatsFromStack(&IpSnmpInfo);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"GetInterfaceInfo: GetIpStatsFromStack returned error %d", dwResult); return dwResult; }
dwNumIf = IpSnmpInfo.dwNumIf;
if(dwNumIf is 0) { Trace0(ERR,"GetInterfaceInfo: No interfaces"); return ERROR_NO_DATA; }
if (dwOutBufLen == NULL) { return ERROR_INVALID_PARAMETER; }
if (!pIPIfInfo || (*dwOutBufLen < (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*dwNumIf)) {
*dwOutBufLen = (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
return ERROR_INSUFFICIENT_BUFFER; }
Trace1(ERR, "GetInterfaceInfo: outbuflen %d", *dwOutBufLen);
return TCPSendIoctl(g_hIPGetDriverHandle, IOCTL_IP_INTERFACE_INFO, NULL, &status, pIPIfInfo, dwOutBufLen); #endif
}
DWORD GetUniDirectionalAdapterInfo(PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS pIPIfInfo, PULONG dwOutBufLen) { DWORD status=0; if (dwOutBufLen == NULL) { return ERROR_INVALID_PARAMETER; }
return TCPSendIoctl(g_hIPGetDriverHandle, IOCTL_IP_UNIDIRECTIONAL_ADAPTER_ADDRESS, NULL, &status, pIPIfInfo, dwOutBufLen);
}
DWORD GetIgmpList(IPAddr NTEAddr, IPAddr *pIgmpList, PULONG pdwOutBufLen)
/*++
Routine Description:
When pIgmpList is NULL, get the amount of space necessary to hold the group addresses joined on a given interface address.
When pIgmpList is non-NULL and *pdwOutBufLen is more than 4 bytes, get the actual group addresses.
Arguments:
NTEAddr - Supplies the address of an interface whose multicast group information is being requested.
pIgmpList - Supplies a buffer in which to put group addresses, or NULL to just request amount of space desired.
pdwOutBufLen - When pIgmpList is NULL, returns the amount of space the caller should allocate to get all groups.
When pIgmpList is non-NULL, supplies the size of the buffer supplied, and returns the amount of space actually used.
Return Value:
NO_ERROR ERROR_INVALID_PARAMETER if the arguments don't meet the requirements. ERROR_INSUFFICIENT_BUFFER if more groups are available than fit.
--*/
{ DWORD inlen = sizeof(IPAddr); DWORD dwStatus;
if (pdwOutBufLen == NULL) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pdwOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (pIgmpList == NULL) { DWORD dwSize;
//
// When pIgmpList is NULL, the caller is just asking for the
// amount of space needed, so use pdwOutBufLen as the buffer.
//
dwSize = sizeof(*pdwOutBufLen); dwStatus = TCPSendIoctl(g_hIPGetDriverHandle, IOCTL_IP_GET_IGMPLIST, &NTEAddr, &inlen, pdwOutBufLen, &dwSize); } else { //
// Otherwise the caller wants the list of groups.
//
if (IsBadWritePtr(pIgmpList, *pdwOutBufLen)) { return ERROR_INVALID_PARAMETER; } if (*pdwOutBufLen <= sizeof(ULONG)) { //
// Make sure the buffer is bigger than a ULONG or we'll get
// the size back, not group data. The IOCTL insures that
// when the caller requests the size needed, the amount
// returned will be bigger than a ULONG.
//
return ERROR_INVALID_PARAMETER; }
dwStatus = TCPSendIoctl(g_hIPGetDriverHandle, IOCTL_IP_GET_IGMPLIST, &NTEAddr, &inlen, pIgmpList, pdwOutBufLen); }
if (dwStatus == ERROR_MORE_DATA) { //
// Callers expect ERROR_INSUFFICIENT_BUFFER when *pdwOutBufLen is
// too small. However, the stack actually generates a warning
// (ERROR_MORE_DATA), rather than an error (ERROR_INSUFFICIENT_BUFFER)
// so that the data gets passed back to the caller.
//
dwStatus = ERROR_INSUFFICIENT_BUFFER; }
return dwStatus; }
DWORD SetBlockRoutes(IPRouteBlock *RouteBlock, PULONG poutbuflen, PULONG statusblock) { DWORD inlen;
if (IsRouterRunning()) { return ERROR_NOT_SUPPORTED; }
if (poutbuflen == NULL) { // Null pointers ?
return ERROR_INVALID_PARAMETER; }
if (IsBadReadPtr(poutbuflen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadReadPtr(RouteBlock, sizeof(IPRouteBlock))) { return ERROR_INVALID_PARAMETER; }
inlen = (RouteBlock->numofroutes * sizeof(IPRouteEntry)) + sizeof(ulong);
if (IsBadReadPtr(RouteBlock, inlen)) { return ERROR_INVALID_PARAMETER; }
return TCPSendIoctl(g_hIPDriverHandle, IOCTL_IP_SET_BLOCKOFROUTES, RouteBlock, &inlen, statusblock, poutbuflen); }
DWORD SetRouteWithRef(IN IPRouteEntry *RouteEntry ) { DWORD inlen = sizeof(IPRouteEntry); ULONG outbuflen;
if (IsRouterRunning()) { return ERROR_NOT_SUPPORTED; }
if (IsBadReadPtr(RouteEntry, inlen)) { return ERROR_INVALID_PARAMETER; }
return TCPSendIoctl(g_hIPDriverHandle, IOCTL_IP_SET_ROUTEWITHREF, RouteEntry, &inlen, NULL, &outbuflen); }
DWORD GetAdapterIndex( IN LPWSTR AdapterName, OUT PULONG IfIndex ) /*++
Routine Description:
Gets the target IP interface given the name of the adapter associated with it.
Arguments:
AdapterName - A unicode string identifying the adapter/interface to which to add the new NTE. ifIndex - Interface index associated with the adapter name.
Return Value:
ERROR_SUCCESS or windows error --*/
{ #ifdef CHICAGO
return ERROR_NOT_SUPPORTED; #else
int i;
DWORD dwResult; IP_INTERFACE_INFO *pIPIfInfo=NULL; DWORD dwNumIf, NumAdapters; ULONG dwOutBufLen;
if (AdapterName == NULL || IfIndex == NULL) { return(ERROR_INVALID_PARAMETER); }
dwResult = GetNumberOfInterfaces(&dwNumIf);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"GetAdapterIndex: GetNumberOfInterfaces returned error %d", dwResult);
return dwResult; }
if(dwNumIf is 0) { Trace0(ERR,"GetAdapterIndex: No interfaces"); return ERROR_NO_DATA; }
dwOutBufLen = (ULONG)sizeof(IP_ADAPTER_INDEX_MAP)*(dwNumIf + OVERFLOW_COUNT);
pIPIfInfo = HeapAlloc(g_hPrivateHeap, FALSE, dwOutBufLen);
if(pIPIfInfo is NULL) { dwResult = ERROR_NOT_ENOUGH_MEMORY;
Trace1(ERR, "GetAdapterIndex: Couldnt allocate memory. Error %d", dwResult);
return dwResult; }
dwResult = GetInterfaceInfo(pIPIfInfo, &dwOutBufLen);
if (dwResult isnot NO_ERROR) { Trace1(ERR, "GetAdapterIndex: Error %d calling GetInterfaceInfo", dwResult); HeapFree(g_hPrivateHeap, 0, pIPIfInfo); return dwResult; }
// search for the adaptername within this info and return the index.
NumAdapters = pIPIfInfo->NumAdapters;
for (i = 0; i < (int)pIPIfInfo->NumAdapters; i++) { if (lstrcmpiW(AdapterName, pIPIfInfo->Adapter[i].Name) == 0) { break; } }
if (i < (int)pIPIfInfo->NumAdapters) {
*IfIndex = pIPIfInfo->Adapter[i].Index;
HeapFree(g_hPrivateHeap, 0, pIPIfInfo); return(NO_ERROR); }
HeapFree(g_hPrivateHeap, 0, pIPIfInfo); return(ERROR_DEV_NOT_EXIST); #endif
}
DWORD AddIPAddress(IPAddr Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance) { #ifdef CHICAGO
return ERROR_NOT_SUPPORTED; #else
IP_ADD_NTE_REQUEST requestBuffer; PIP_ADD_NTE_RESPONSE responseBuffer = (PIP_ADD_NTE_RESPONSE) &requestBuffer; DWORD requestBufferSize = sizeof(requestBuffer); DWORD responseBufferSize = sizeof(requestBuffer); DWORD status;
//
// Validate the IP address to be added. Check for
// * broadcast address,
// * loopback address,
// * zero address,
// * Class D address,
// * zero subnet-broadcast address
// * all-ones subnet-broadcast address
// * non-contiguous mask (which we test by negating the host-order mask
// and verifying that all the bits change when we add 1, i.e. that
// the negation is of the form 2^n-1).
//
if ((Address == INADDR_BROADCAST) || ((ntohl(Address) & IN_CLASSA_NET) == (INADDR_LOOPBACK & IN_CLASSA_NET)) || (Address == 0) || (IN_CLASSD(ntohl(Address))) || ((Address & ~IpMask) == 0) || ((Address & ~IpMask) == ~IpMask) || ((~ntohl(IpMask) + 1) & ~ntohl(IpMask))) { return ERROR_INVALID_PARAMETER; }
if ( (NTEContext == NULL) || (NTEInstance == NULL) ) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(NTEContext, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(NTEInstance, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
requestBuffer.InterfaceContext = (unsigned long) IfIndex; requestBuffer.Address = Address; requestBuffer.SubnetMask = IpMask;
status = TCPSendIoctl(g_hIPDriverHandle, IOCTL_IP_ADD_NTE, &requestBuffer, &requestBufferSize, responseBuffer, &responseBufferSize);
if (status == NO_ERROR) { *NTEContext = (ULONG) responseBuffer->Context; *NTEInstance = responseBuffer->Instance; } else if (status == STATUS_DUPLICATE_OBJECTID) { status = ERROR_DUP_DOMAINNAME; }
return(status); #endif
}
DWORD DeleteIPAddress(ULONG NTEContext) { #ifdef CHICAGO
return ERROR_NOT_SUPPORTED; #else
IP_DELETE_NTE_REQUEST requestBuffer; DWORD requestBufferSize = sizeof(requestBuffer); DWORD responseBufferSize = 0; DWORD status;
requestBuffer.Context = (unsigned short) NTEContext;
status = TCPSendIoctl(g_hIPDriverHandle, IOCTL_IP_DELETE_NTE, &requestBuffer, &requestBufferSize, NULL, &responseBufferSize); return(status); #endif
}
#define DEFAULT_TTL 32
#define DEFAULT_TOS 0
#define DEFAULT_TIMEOUT 5000L
#include <icmpapi.h>
#ifndef CHICAGO
#include <ntddip.h>
#endif
BOOL GetRTT(IPAddr DestIpAddress, PULONG Rtt) { uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
uint OptLength = 0; uchar Flags = 0; ulong Timeout = DEFAULT_TIMEOUT; IP_OPTION_INFORMATION SendOpts; HANDLE IcmpHandle; PICMP_ECHO_REPLY reply; char SendBuffer[32], *RcvBuffer; uint RcvSize=4096; uint SendSize = 32; uint i; DWORD numberOfReplies;
if (IsBadWritePtr(Rtt, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
IcmpHandle = IcmpCreateFile();
if (IcmpHandle == INVALID_HANDLE_VALUE) { return(FALSE); }
//
// Allocate space for the response.
//
RcvBuffer = HeapAlloc(g_hPrivateHeap, 0, RcvSize); if (RcvBuffer == NULL) { IcmpCloseHandle(IcmpHandle); return(FALSE); }
//
// Initialize the send buffer pattern.
//
for (i = 0; i < SendSize; i++) { SendBuffer[i] = (char) ('a' + (i % 23)); }
//
// Initialize the send options
//
SendOpts.OptionsData = Opt; SendOpts.OptionsSize = (UCHAR) OptLength; SendOpts.Ttl = DEFAULT_TTL; SendOpts.Tos = DEFAULT_TOS; SendOpts.Flags = Flags;
numberOfReplies = IcmpSendEcho(IcmpHandle, DestIpAddress, SendBuffer, (unsigned short) SendSize, &SendOpts, RcvBuffer, RcvSize, DEFAULT_TIMEOUT); if (numberOfReplies) { numberOfReplies = IcmpSendEcho(IcmpHandle, DestIpAddress, SendBuffer, (unsigned short) SendSize, &SendOpts, RcvBuffer, RcvSize, Timeout); if (numberOfReplies) { reply = (PICMP_ECHO_REPLY) RcvBuffer; *Rtt = reply->RoundTripTime; HeapFree(g_hPrivateHeap, 0, RcvBuffer); IcmpCloseHandle(IcmpHandle); return(TRUE); } }
HeapFree(g_hPrivateHeap, 0, RcvBuffer); IcmpCloseHandle(IcmpHandle); return(FALSE); }
BOOL GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHops, PULONG RTT) { DWORD numberOfReplies; uchar FAR *Opt = (uchar FAR *)0; // Pointer to send options
uint OptLength = 0; uchar Flags = 0; ulong Timeout = DEFAULT_TIMEOUT; IP_OPTION_INFORMATION SendOpts; HANDLE IcmpHandle; PICMP_ECHO_REPLY reply; char SendBuffer[32], *RcvBuffer; uint RcvSize=4096; uint SendSize = 32; uint i,status; ULONG RTT1;
if (!HopCount || !RTT) { return (FALSE); }
if (DestIpAddress == -1L) { return(FALSE); }
if (IsBadWritePtr(RTT, sizeof(ULONG))) { return (FALSE); }
if (IsBadWritePtr(HopCount, sizeof(ULONG))) { return (FALSE); }
IcmpHandle = IcmpCreateFile();
if (IcmpHandle == INVALID_HANDLE_VALUE) { return(FALSE); }
//
// Allocate space for the response.
//
RcvBuffer = HeapAlloc(g_hPrivateHeap, 0, RcvSize); if (RcvBuffer == NULL) { IcmpCloseHandle(IcmpHandle); return(FALSE); }
//
// Initialize the send buffer pattern.
//
for (i = 0; i < SendSize; i++) { SendBuffer[i] = (char) ('a' + (i % 23)); } //
// Initialize the send options
//
SendOpts.OptionsData = Opt; SendOpts.OptionsSize = (UCHAR) OptLength; SendOpts.Ttl = 1; SendOpts.Tos = DEFAULT_TOS; SendOpts.Flags = Flags;
while (SendOpts.Ttl <= MaxHops) {
numberOfReplies = IcmpSendEcho(IcmpHandle, DestIpAddress, SendBuffer, (unsigned short) SendSize, &SendOpts, RcvBuffer, RcvSize, Timeout); if (numberOfReplies == 0) { status = GetLastError(); reply = NULL; } else { reply = (PICMP_ECHO_REPLY)RcvBuffer; status = reply->Status; }
if (status == IP_SUCCESS) {
*HopCount = SendOpts.Ttl;
HeapFree(g_hPrivateHeap, 0, RcvBuffer); IcmpCloseHandle(IcmpHandle);
if (GetRTT(DestIpAddress, &RTT1)) { *RTT = RTT1; return TRUE; } else { return FALSE; }
} else if (status == IP_TTL_EXPIRED_TRANSIT || status == IP_REQ_TIMED_OUT) { SendOpts.Ttl++; } else { HeapFree(g_hPrivateHeap, 0, RcvBuffer); IcmpCloseHandle(IcmpHandle); return FALSE; } }
HeapFree(g_hPrivateHeap, 0, RcvBuffer); IcmpCloseHandle(IcmpHandle); return FALSE; }
#define LOOPBACK_ADDR 0x0100007f
DWORD IsLocalAddress(IPAddr InAddress) { int i; DWORD dwResult; int NumEntries;
PMIB_IPADDRTABLE pIpAddrTable; PMIB_IPADDRROW pIpAddrEntry;
dwResult = AllocateAndGetIpAddrTableFromStack(&pIpAddrTable, FALSE, g_hPrivateHeap, 0);
if(dwResult isnot NO_ERROR) { Trace1(ERR,"GetIpAddrTableFromStack failed with error %x",dwResult); TraceLeave("IsLocalAddress"); return dwResult; }
if (InAddress == LOOPBACK_ADDR) { HeapFree(g_hPrivateHeap, 0, pIpAddrTable); return(NO_ERROR); }
NumEntries = (*pIpAddrTable).dwNumEntries;
Trace2(ERR,"IsLocalAddress number of addresses %d chking %x", NumEntries,InAddress);
for (i = 0; i < NumEntries; i++) { pIpAddrEntry = &(*pIpAddrTable).table[i]; Trace1(ERR,"IsLocalAddress cmparing %x",pIpAddrEntry->dwAddr); if (pIpAddrEntry->dwAddr == (DWORD)InAddress) { HeapFree(g_hPrivateHeap, 0, pIpAddrTable); return(NO_ERROR); } }
HeapFree(g_hPrivateHeap, 0, pIpAddrTable); return(ERROR_INVALID_ADDRESS); }
DWORD NotifyAddrChange(HANDLE *pHandle, OVERLAPPED *pOverLapped) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD dwResult; DWORD temp;
if ((pHandle != NULL) && (pOverLapped != NULL)) {
Trace0(ERR, "NotifyAddressChange: overlapped request");
if (IsBadWritePtr(pHandle, sizeof(HANDLE))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) { return ERROR_INVALID_PARAMETER; }
*pHandle = ChangeNotificationHandle;
if (*pHandle == INVALID_HANDLE_VALUE){ Trace1(ERR, "NotifyAddressChange: CreateFile=%d", GetLastError()); return ERROR_OPEN_FAILED; }
b = DeviceIoControl(*pHandle, IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST, NULL, 0, NULL, 0, &temp, pOverLapped);
if (!b) { dwResult = GetLastError(); Trace1(ERR, "NotifyAddrChange: DeviceIoControl=%d", dwResult); return dwResult; }
} else {
// Synchronous change notification
// This call will block
Trace0(ERR, "NotifyAddrChange: synchronous request");
b = DeviceIoControl(g_hIPGetDriverHandle, IOCTL_IP_ADDCHANGE_NOTIFY_REQUEST, NULL, 0, NULL, 0, &temp, NULL);
if (!b) { dwResult = GetLastError(); Trace1(ERR, "NotifyAddressChange: DeviceIoControl=%d", dwResult); return dwResult; } }
return NO_ERROR; #endif
}
DWORD NotifyRouteChange(HANDLE *pHandle, OVERLAPPED *pOverLapped) { return NotifyRouteChangeEx(pHandle, pOverLapped, FALSE); }
DWORD NotifyRouteChangeEx( PHANDLE pHandle, LPOVERLAPPED pOverLapped, BOOL bExQueue ) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD dwResult; DWORD temp; DWORD dwIoctl;
if(bExQueue) { dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST_EX; } else { dwIoctl = IOCTL_IP_RTCHANGE_NOTIFY_REQUEST; }
if ((pHandle != NULL) && (pOverLapped != NULL)) {
Trace0(ERR, "NotifyRouteChange: overlapped request");
if (IsBadWritePtr(pHandle, sizeof(HANDLE))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) { return ERROR_INVALID_PARAMETER; }
*pHandle = ChangeNotificationHandle;
if(*pHandle == INVALID_HANDLE_VALUE){ Trace1(ERR, "NotifyRouteChange: CreateFile=%d", GetLastError()); return ERROR_OPEN_FAILED; }
b = DeviceIoControl(*pHandle, dwIoctl, NULL, 0, NULL, 0, &temp, pOverLapped);
if (!b) { dwResult = GetLastError(); Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult); return dwResult; }
} else {
// Synchronous change notification
// This call will block
Trace0(ERR, "NotifyRouteChange: synchronous request");
b = DeviceIoControl(g_hIPGetDriverHandle, dwIoctl, NULL, 0, NULL, 0, &temp, NULL);
if (!b) {
dwResult = GetLastError(); Trace1(ERR, "NotifyRouteChange: DeviceIoControl=%d", dwResult); return dwResult; } }
return NO_ERROR; #endif
}
BOOL WINAPI CancelIPChangeNotify(LPOVERLAPPED notifyOverlapped) { BOOL b; DWORD temp, dwResult = NO_ERROR; b = DeviceIoControl(ChangeNotificationHandle, IOCTL_IP_CANCEL_CHANGE_NOTIFY, ¬ifyOverlapped, sizeof(notifyOverlapped), NULL, 0, &temp, NULL); if (!b) { dwResult = GetLastError(); } return (BOOL)(dwResult == NO_ERROR); }
DWORD WINAPI EnableRouter(HANDLE *pHandle, OVERLAPPED *pOverLapped) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD dwResult; DWORD temp;
if ((pHandle != NULL) && (pOverLapped != NULL)) {
Trace0(ERR,"EnableRouter: overlapped request");
if (IsBadWritePtr(pHandle, sizeof(HANDLE)) || IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) { return ERROR_INVALID_PARAMETER; }
*pHandle = g_hIPDriverHandle;
if (*pHandle == INVALID_HANDLE_VALUE) { return ERROR_OPEN_FAILED; }
b = DeviceIoControl( *pHandle, IOCTL_IP_ENABLE_ROUTER_REQUEST, NULL, 0, NULL, 0, &temp, pOverLapped );
if (!b) { return GetLastError(); }
} else {
Trace0(ERR,"EnableRouter: synchronous request");
b = DeviceIoControl( g_hIPDriverHandle, IOCTL_IP_ENABLE_ROUTER_REQUEST, NULL, 0, NULL, 0, &temp, NULL );
if (!b) { dwResult = GetLastError(); Trace1(ERR,"EnableRouter: DeviceIoControl=%d", dwResult); return dwResult; } }
return NO_ERROR; #endif
}
DWORD WINAPI UnenableRouter(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD EnableCount; DWORD temp; if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) { return ERROR_INVALID_PARAMETER; } if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) { return ERROR_OPEN_FAILED; } b = DeviceIoControl( g_hIPDriverHandle, IOCTL_IP_UNENABLE_ROUTER_REQUEST, (PVOID)&pOverlapped, sizeof(PVOID), &EnableCount, sizeof(DWORD), &temp, NULL ); if (!b) { return GetLastError(); } if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; } return NO_ERROR; #endif
}
DWORD WINAPI DisableMediaSense(HANDLE *pHandle, OVERLAPPED *pOverLapped) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD dwResult; DWORD temp;
if ((pHandle != NULL) && (pOverLapped != NULL)) {
Trace0(ERR,"DisableMediaSense: overlapped request");
if (IsBadWritePtr(pHandle, sizeof(HANDLE)) || IsBadWritePtr(pOverLapped, sizeof(OVERLAPPED))) { return ERROR_INVALID_PARAMETER; }
*pHandle = g_hIPDriverHandle;
if (*pHandle == INVALID_HANDLE_VALUE) { return ERROR_OPEN_FAILED; }
b = DeviceIoControl( *pHandle, IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST, NULL, 0, NULL, 0, &temp, pOverLapped );
if (!b) { return GetLastError(); }
} else {
Trace0(ERR,"DisableMediaSense: synchronous request");
b = DeviceIoControl( g_hIPDriverHandle, IOCTL_IP_DISABLE_MEDIA_SENSE_REQUEST, NULL, 0, NULL, 0, &temp, NULL );
if (!b) { dwResult = GetLastError(); Trace1(ERR,"DisableMediaSense: DeviceIoControl=%d", dwResult); return dwResult; } }
return NO_ERROR; #endif
}
DWORD WINAPI RestoreMediaSense(OVERLAPPED* pOverlapped, LPDWORD lpdwEnableCount OPTIONAL) { #if defined(NT4) || defined(CHICAGO)
return ERROR_NOT_SUPPORTED; #else
BOOL b; DWORD EnableCount; DWORD temp; if (lpdwEnableCount && IsBadWritePtr(lpdwEnableCount, sizeof(DWORD))) { return ERROR_INVALID_PARAMETER; } if (g_hIPDriverHandle == INVALID_HANDLE_VALUE) { return ERROR_OPEN_FAILED; } b = DeviceIoControl( g_hIPDriverHandle, IOCTL_IP_ENABLE_MEDIA_SENSE_REQUEST, (PVOID)&pOverlapped, sizeof(PVOID), &EnableCount, sizeof(DWORD), &temp, NULL ); if (!b) { return GetLastError(); } if (lpdwEnableCount) { *lpdwEnableCount = EnableCount; } return NO_ERROR; #endif
}
#if !defined(NT4) && !defined(_WIN95_)
extern DWORD GetFixedInfoEx(PFIXED_INFO pFixedInfo, PULONG pOutBufLen); extern DWORD GetAdapterInfoEx(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen); extern DWORD GetAdapterAddressesEx(ULONG Family, DWORD Flags, PIP_ADAPTER_ADDRESSES pAdapterInfo, PULONG pOutBufLen); #endif
#if !defined(NT4) && !defined(CHICAGO)
extern DWORD GetPerAdapterInfoEx(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen); #endif
DWORD GetNetworkParams(PFIXED_INFO pFixedInfo, PULONG pOutBufLen) { #if !defined(NT4) && !defined(_WIN95_)
CheckTcpipState();
if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (pFixedInfo != NULL && IsBadWritePtr(pFixedInfo, sizeof(FIXED_INFO))) { return ERROR_INVALID_PARAMETER; }
return GetFixedInfoEx(pFixedInfo, pOutBufLen); #else
return ERROR_NOT_SUPPORTED; #endif
}
DWORD GetAdaptersAddresses(ULONG Family, DWORD Flags, PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen) { #if !defined(NT4) && !defined(_WIN95_)
CheckTcpipState();
if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (Reserved != NULL) { return ERROR_INVALID_PARAMETER; }
if (pAdapterAddresses != NULL && IsBadWritePtr(pAdapterAddresses, sizeof(IP_ADAPTER_ADDRESSES))) { return ERROR_INVALID_PARAMETER; }
return GetAdapterAddressesEx(Family, Flags, pAdapterAddresses, pOutBufLen); #else
return ERROR_NOT_SUPPORTED; #endif
}
DWORD GetAdaptersInfo(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen) { #if !defined(NT4) && !defined(_WIN95_)
// call the init
CheckTcpipState();
if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (pAdapterInfo != NULL && IsBadWritePtr(pAdapterInfo, sizeof(IP_ADAPTER_INFO))) { return ERROR_INVALID_PARAMETER; }
return GetAdapterInfoEx(pAdapterInfo, pOutBufLen); #else
return ERROR_NOT_SUPPORTED; #endif
}
DWORD GetPerAdapterInfo(ULONG IfIndex, PIP_PER_ADAPTER_INFO pPerAdapterInfo, PULONG pOutBufLen) { #if !defined(NT4) && !defined(CHICAGO)
CheckTcpipState();
if (IsBadReadPtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(pOutBufLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (pPerAdapterInfo != NULL && IsBadWritePtr(pPerAdapterInfo, sizeof(IP_PER_ADAPTER_INFO))) { return ERROR_INVALID_PARAMETER; }
return GetPerAdapterInfoEx(IfIndex, pPerAdapterInfo, pOutBufLen); #else
return ERROR_NOT_SUPPORTED; #endif
}
extern DWORD DhcpReleaseParameters( LPWSTR AdapterName );
extern DWORD DhcpAcquireParameters( LPWSTR AdapterName);
#define TCP_EXPORT_STRING_PREFIX L"\\DEVICE\\TCPIP_"
DWORD IpReleaseAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo) { #if defined(NT4) || defined(_WIN95_)
return ERROR_NOT_SUPPORTED; #else
DWORD status;
if (!AdapterInfo) { return ERROR_INVALID_PARAMETER; }
if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) { return ERROR_INVALID_PARAMETER; }
#ifdef CHICAGO
{ // Convert the string to a widechar name
WCHAR Name[11]; uint i; uint Index = AdapterInfo->Index;
i = sizeof(Name)/sizeof(Name[0]); Name[--i] = L'\0'; while (i > 0 ) { Name[--i] = L'0' + (Index%10); Index /= 10; } status = DhcpReleaseParameters(Name); } #else
{ LPWSTR tmpstr;
if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) { return ERROR_INVALID_PARAMETER; }
tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
__try { status = DhcpReleaseParameters(tmpstr); } __except(EXCEPTION_EXECUTE_HANDLER) { status = ERROR_PROC_NOT_FOUND; } } #endif
return(status); #endif
}
DWORD IpRenewAddress(PIP_ADAPTER_INDEX_MAP AdapterInfo) { #if defined(NT4) || defined(_WIN95_)
return ERROR_NOT_SUPPORTED; #else
DWORD status;
if (!AdapterInfo) { return ERROR_INVALID_PARAMETER; }
if (IsBadReadPtr(AdapterInfo, sizeof(IP_ADAPTER_INDEX_MAP))) { return ERROR_INVALID_PARAMETER; }
#ifdef CHICAGO
{ // Convert the string to a widechar name
WCHAR Name[11]; uint i; uint Index = AdapterInfo->Index;
i = sizeof(Name)/sizeof(Name[0]); Name[--i] = L'\0'; while (i > 0 ) { Name[--i] = L'0' + (Index%10); Index /= 10; } status = DhcpAcquireParameters(Name); } #else
{ LPWSTR tmpstr;
if (wcslen(AdapterInfo->Name) <= wcslen(TCP_EXPORT_STRING_PREFIX)) { return ERROR_INVALID_PARAMETER; }
tmpstr = AdapterInfo->Name + wcslen(TCP_EXPORT_STRING_PREFIX);
__try { status = DhcpAcquireParameters(tmpstr); } __except(EXCEPTION_EXECUTE_HANDLER) { status = ERROR_PROC_NOT_FOUND; } } #endif
return(status); #endif
}
DWORD SendARP(IPAddr DestIP, IPAddr SrcIP, PULONG pMacAddr, PULONG PhyAddrLen) { #if defined(NT4) || defined(_WIN95_)
return ERROR_NOT_SUPPORTED; #else
ARP_SEND_REPLY requestBuffer; DWORD requestBufferSize = sizeof(requestBuffer); DWORD status;
requestBuffer.DestAddress = DestIP; requestBuffer.SrcAddress = SrcIP;
if (IsBadWritePtr(pMacAddr, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
if (IsBadWritePtr(PhyAddrLen, sizeof(ULONG))) { return ERROR_INVALID_PARAMETER; }
status = TCPSendIoctl(g_hIPGetDriverHandle, IOCTL_ARP_SEND_REQUEST, &requestBuffer, &requestBufferSize, pMacAddr, PhyAddrLen); return(status); #endif
}
|