📄 ethsock.cxx
字号:
BOOL InProgress() const { return status == Progressing; }
BOOL IsCompleted() const { return status == Completed; }
BOOL IsType(WORD type) const;
protected:
Statuses status;
PWin32Overlapped overlap;
DWORD count;
};
#define new PNEW
/////////////////////////////////////////////////////////////////////////////
PWin32AsnAny::PWin32AsnAny()
{
asnType = ASN_INTEGER;
asnValue.number = 0;
}
void PWin32AsnAny::MemFree()
{
switch (asnType) {
case ASN_OCTETSTRING :
SnmpUtilMemFree(asnValue.string.stream);
break;
#ifdef ASN_BITS
case ASN_BITS :
SnmpUtilMemFree(asnValue.bits.stream);
break;
#endif
case ASN_OBJECTIDENTIFIER :
SnmpUtilMemFree(asnValue.object.ids);
break;
case ASN_SEQUENCE :
SnmpUtilMemFree(asnValue.sequence.stream);
break;
case ASN_IPADDRESS :
SnmpUtilMemFree(asnValue.address.stream);
break;
#ifdef ASN_OPAQUE
case ASN_OPAQUE :
SnmpUtilMemFree(asnValue.arbitrary.stream);
break;
#endif
}
asnType = ASN_INTEGER;
}
BOOL PWin32AsnAny::GetInteger(AsnInteger & i)
{
if (asnType != ASN_INTEGER)
return FALSE;
i = asnValue.number;
return TRUE;
}
BOOL PWin32AsnAny::GetIpAddress(PIPSocket::Address & addr)
{
if (asnType != ASN_IPADDRESS || asnValue.address.stream == NULL)
return FALSE;
addr = PIPSocket::Address(asnValue.address.length, asnValue.address.stream);
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
PWin32AsnOid::PWin32AsnOid()
{
ids = NULL;
idLength = 0;
}
PWin32AsnOid::PWin32AsnOid(const char * str)
{
idLength = 0;
ids = NULL;
AsnObjectIdentifier oid;
oid.idLength = 0;
const char * dot = strchr(str, '.');
while (dot != NULL) {
oid.idLength++;
dot = strchr(dot+1, '.');
}
if (oid.idLength > 0) {
oid.ids = new UINT[++oid.idLength];
char * next = (char *)str;
for (UINT i = 0; i < oid.idLength; i++) {
oid.ids[i] = strtoul(next, &next, 10);
if (*next != '.')
break;
next++;
}
if (*next == '\0')
SnmpUtilOidCpy(this, &oid);
delete [] oid.ids;
}
}
PWin32AsnOid & PWin32AsnOid::operator=(const AsnObjectIdentifier & oid)
{
ids = oid.ids;
idLength = oid.idLength;
return *this;
}
///////////////////////////////////////////////////////////////////////////////
PWin32SnmpLibrary::PWin32SnmpLibrary()
#ifndef _WIN32_WCE
: PDynaLink("inetmib1.dll")
#endif
{
#ifndef _WIN32_WCE
HANDLE hEvent;
AsnObjectIdentifier baseOid;
if (!GetFunction("SnmpExtensionInit", (Function &)_Init) ||
!GetFunction("SnmpExtensionQuery", (Function &)_Query)) {
Close();
PTRACE(1, "PWlib\tInvalid DLL: inetmib1.dll");
}
else if (!Init(0, &hEvent, &baseOid)) {
PTRACE(1, "PWlib\tCould not initialise SNMP DLL: error=" << ::GetLastError());
Close();
}
#else
_Init = SnmpExtensionInit; // do not call Init as we dont'have Close
_Query = SnmpExtensionQuery;
#endif
}
BOOL PWin32SnmpLibrary::GetOid(AsnObjectIdentifier & oid, AsnInteger & value)
{
//if (!IsLoaded())
// return FALSE;
PWin32AsnAny any;
if (!GetOid(oid, any))
return FALSE;
return any.GetInteger(value);
}
BOOL PWin32SnmpLibrary::GetOid(AsnObjectIdentifier & oid, PIPSocket::Address & value)
{
//if (!IsLoaded())
// return FALSE;
PWin32AsnAny any;
if (!GetOid(oid, any))
return FALSE;
return any.GetIpAddress(value);
}
BOOL PWin32SnmpLibrary::GetOid(AsnObjectIdentifier & oid, PString & str)
{
//if (!IsLoaded())
// return FALSE;
PWin32AsnAny any;
if (!GetOid(oid, any))
return FALSE;
if (any.asnType != ASN_OCTETSTRING)
return FALSE;
str = PString((char *)any.asnValue.string.stream, any.asnValue.string.length);
return TRUE;
}
BOOL PWin32SnmpLibrary::GetOid(AsnObjectIdentifier & oid, void * value, UINT valSize, UINT * len)
{
//if (!IsLoaded())
// return FALSE;
PWin32AsnAny any;
if (!GetOid(oid, any))
return FALSE;
if (any.asnType != ASN_OCTETSTRING)
return FALSE;
if (len != NULL)
*len = any.asnValue.string.length;
if (any.asnValue.string.length > valSize)
return FALSE;
memcpy(value, any.asnValue.string.stream, any.asnValue.string.length);
if (valSize > any.asnValue.string.length)
((char *)value)[any.asnValue.string.length] = '\0';
return TRUE;
}
BOOL PWin32SnmpLibrary::QueryOid(BYTE cmd, AsnObjectIdentifier & oid, PWin32AsnAny & value)
{
//if (!IsLoaded())
// return FALSE;
value.MemFree();
SnmpVarBindList vars;
vars.len = 1;
vars.list = (SnmpVarBind*)SnmpUtilMemAlloc(sizeof(SnmpVarBind));
if (vars.list == NULL)
return FALSE;
vars.list->name = oid;
vars.list->value = value;
AsnInteger status, error;
if (Query(cmd, &vars, &status, &error) && status == SNMP_ERRORSTATUS_NOERROR) {
(AsnAny&)value = vars.list->value; // Use cast so does simple copy
oid = vars.list->name;
}
SnmpUtilMemFree(vars.list);
return status == SNMP_ERRORSTATUS_NOERROR;
}
PString PWin32SnmpLibrary::GetInterfaceName(int ifNum)
{
PIPSocket::Address gwAddr = 0;
gwAddr = GetInterfaceAddress(ifNum);
if (gwAddr == 0)
return PString::Empty();
PString name = GetInterfaceName(gwAddr);
if (name.IsEmpty()) {
PWin32AsnOid nameOid = "1.3.6.1.2.1.2.2.1.2.0";
nameOid[10] = ifNum;
if (GetOid(nameOid, name.GetPointer(100), 100))
name.MakeMinimumSize();
}
return name;
}
PString PWin32SnmpLibrary::GetInterfaceName(PIPSocket::Address ipAddr)
{
PString gatewayInterface, anInterface;
PWin32PacketDriver * tempDriver = PWin32PacketDriver::Create();
PINDEX ifIdx = 0;
while (gatewayInterface.IsEmpty() && tempDriver->EnumInterfaces(ifIdx++, anInterface)) {
if (tempDriver->BindInterface(anInterface)) {
PIPSocket::Address ifAddr, ifMask;
PINDEX ipIdx = 0;
if (tempDriver->EnumIpAddress(ipIdx++, ifAddr, ifMask) && ifAddr == ipAddr) {
gatewayInterface = anInterface;
break;
}
}
}
delete tempDriver;
return gatewayInterface;
}
PIPSocket::Address PWin32SnmpLibrary::GetInterfaceAddress(int ifNum)
{
PIPSocket::Address gwAddr = 0;
PWin32AsnOid baseOid = "1.3.6.1.2.1.4.20.1";
PWin32AsnOid oid = baseOid;
PWin32AsnAny value;
while (GetNextOid(oid, value)) {
if (!(baseOid *= oid))
break;
if (value.asnType != ASN_IPADDRESS)
break;
oid[9] = 2;
AsnInteger ifIndex = -1;
if (!GetOid(oid, ifIndex) || ifIndex < 0)
break;
if (ifIndex == ifNum) {
value.GetIpAddress(gwAddr);
break;
}
oid[9] = 1;
}
return gwAddr;
}
/*
PWin32SnmpLibrary & PWin32SnmpLibrary::Current()
{
static PWin32SnmpLibrary instance;
return instance;
}
*/
///////////////////////////////////////////////////////////////////////////////
PWin32OidBuffer::PWin32OidBuffer(UINT oid, UINT len, const BYTE * data)
{
size = sizeof(DWORD)*2 + len;
buffer = new DWORD[(size+sizeof(DWORD)-1)/sizeof(DWORD)];
buffer[0] = oid;
buffer[1] = len;
if (data != NULL)
memcpy(&buffer[2], data, len);
}
void PWin32OidBuffer::Move(BYTE * data, DWORD received)
{
memcpy(data, &buffer[2], received-sizeof(DWORD)*2);
}
///////////////////////////////////////////////////////////////////////////////
PWin32PacketDriver * PWin32PacketDriver::Create()
{
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
#ifndef _WIN32_WCE
if (info.dwPlatformId == VER_PLATFORM_WIN32_NT)
return new PWin32PacketSYS;
else
return new PWin32PacketVxD;
#else
return new PWin32PacketCe;
#endif
}
PWin32PacketDriver::PWin32PacketDriver()
{
hDriver = INVALID_HANDLE_VALUE;
dwError = ERROR_OPEN_FAILED;
}
PWin32PacketDriver::~PWin32PacketDriver()
{
Close();
}
void PWin32PacketDriver::Close()
{
if (hDriver != INVALID_HANDLE_VALUE) {
CloseHandle(hDriver);
hDriver = INVALID_HANDLE_VALUE;
}
}
BOOL PWin32PacketDriver::IsOpen() const
{
return hDriver != INVALID_HANDLE_VALUE;
}
DWORD PWin32PacketDriver::GetLastError() const
{
return dwError;
}
BOOL PWin32PacketDriver::IoControl(UINT func,
const void * input, DWORD inSize,
void * output, DWORD outSize, DWORD & received)
{
PWin32Overlapped overlap;
if (DeviceIoControl(hDriver, func,
(LPVOID)input, inSize, output, outSize,
&received, &overlap)) {
dwError = ERROR_SUCCESS;
return TRUE;
}
dwError = ::GetLastError();
if (dwError != ERROR_IO_PENDING)
return FALSE;
return CompleteIO(received, overlap);
}
BOOL PWin32PacketDriver::CompleteIO(DWORD & received, PWin32Overlapped & overlap)
{
#ifndef _WIN32_WCE
received = 0;
if (GetOverlappedResult(hDriver, &overlap, &received, TRUE)) {
dwError = ERROR_SUCCESS;
return TRUE;
}
dwError = ::GetLastError();
return FALSE;
#else
return TRUE;
#endif
}
BOOL PWin32PacketDriver::QueryOid(UINT oid, UINT len, BYTE * data)
{
PWin32OidBuffer buf(oid, len);
DWORD rxsize = 0;
if (!IoControl(GetQueryOidCommand(oid), buf, buf, buf, buf, rxsize))
return FALSE;
if (rxsize == 0)
return FALSE;
buf.Move(data, rxsize);
return TRUE;
}
BOOL PWin32PacketDriver::QueryOid(UINT oid, DWORD & data)
{
DWORD oidData[3];
oidData[0] = oid;
oidData[1] = sizeof(data);
oidData[2] = 0x12345678;
DWORD rxsize = 0;
if (!IoControl(GetQueryOidCommand(oid),
oidData, sizeof(oidData),
oidData, sizeof(oidData),
rxsize))
return FALSE;
if (rxsize == 0)
return FALSE;
data = oidData[2];
return TRUE;
}
BOOL PWin32PacketDriver::SetOid(UINT oid, UINT len, const BYTE * data)
{
DWORD rxsize = 0;
PWin32OidBuffer buf(oid, len, data);
return IoControl(IOCTL_EPACKET_SET_OID, buf, buf, buf, buf, rxsize);
}
BOOL PWin32PacketDriver::SetOid(UINT oid, DWORD data)
{
DWORD oidData[3];
oidData[0] = oid;
oidData[1] = sizeof(data);
oidData[2] = data;
DWORD rxsize;
return IoControl(IOCTL_EPACKET_SET_OID,
oidData, sizeof(oidData), oidData, sizeof(oidData), rxsize);
}
static BOOL RegistryQueryMultiSz(RegistryKey & registry,
const PString & variable,
PINDEX idx,
PString & value)
{
PString allValues;
if (!registry.QueryValue(variable, allValues))
return FALSE;
const char * ptr = allValues;
while (*ptr != '\0' && idx-- > 0)
ptr += strlen(ptr)+1;
if (*ptr == '\0')
return FALSE;
value = ptr;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
BOOL PWin32PacketVxD::EnumInterfaces(PINDEX idx, PString & name)
{
static const PString RegBase = SERVICES_REGISTRY_KEY "Class\\Net";
PString keyName;
RegistryKey registry(RegBase, RegistryKey::ReadOnly);
if (!registry.EnumKey(idx, keyName))
return FALSE;
PString description;
RegistryKey subkey(RegBase + "\\" + keyName, RegistryKey::ReadOnly);
if (subkey.QueryValue("DriverDesc", description))
name = keyName + ": " + description;
else
name = keyName;
return TRUE;
}
static PString SearchRegistryKeys(const PString & key,
const PString & variable,
const PString & value)
{
RegistryKey registry(key, RegistryKey::ReadOnly);
PString str;
if (registry.QueryValue(variable, str) && (str *= value))
return key;
for (PINDEX idx = 0; registry.EnumKey(idx, str); idx++) {
PString result = SearchRegistryKeys(key + str + '\\', variable, value);
if (!result)
return result;
}
return PString::Empty();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -